diff --git a/frontend/locales/en.json b/frontend/locales/en.json index c16b77139..da0b553d9 100644 --- a/frontend/locales/en.json +++ b/frontend/locales/en.json @@ -258,6 +258,8 @@ "password_confirm_label": "Confirm password", "password_label": "Password", "passwordless_notice": "This account doesn't need a password. We'll send a verification code to your email address instead.", + "pinned_email_error": "This invite's email address can't be used to create an account. Let whoever invited you know.", + "pinned_username_error": "The account this invite is for can't be created. Let whoever invited you know.", "send_code": "Send code", "terms_of_service": "I agree to the Terms and Conditions", "username_available": "This username is available", diff --git a/frontend/src/components/RegisterForm/RegisterForm.tsx b/frontend/src/components/RegisterForm/RegisterForm.tsx index 321991532..1f58e154b 100644 --- a/frontend/src/components/RegisterForm/RegisterForm.tsx +++ b/frontend/src/components/RegisterForm/RegisterForm.tsx @@ -211,6 +211,15 @@ export const PasswordRegisterForm: React.FC<{ {t("frontend.register.invite_invalid")} )} + {/* The user never chose a pinned value, so its errors get their own words */} + {pinnedUsername && !!fields.username?.errors.length && ( + {t("frontend.register.pinned_username_error")} + )} + + {pinnedEmail && !!fields.email?.errors.length && ( + {t("frontend.register.pinned_email_error")} + )} + {formErrors.map((error, index) => (
{ ).toBeTruthy(); }); }); + + describe("with an invite pinning the username and email", () => { + const invite = { + valid: true, + username: "alice", + email: "alice@example.com", + passwordless: true, + }; + + it("explains an error on the username above the form", async () => { + await mountRegister({ + invite, + form: { + errors: [], + fields: { username: { value: "", errors: [{ kind: "exists" }] } }, + }, + }); + + const alert = screen.getByRole("alert"); + expect(alert).toHaveTextContent( + "The account this invite is for can't be created.", + ); + expect( + alert.compareDocumentPosition( + screen.getByRole("button", { name: "Send code" }), + ) & Node.DOCUMENT_POSITION_FOLLOWING, + ).toBeTruthy(); + }); + + it("explains an error on the email address above the form", async () => { + await mountRegister({ + invite, + form: { + errors: [], + fields: { + email: { + value: "alice@example.com", + errors: [ + { + kind: "policy", + code: "email-domain-banned", + message: "Email domain is banned", + }, + ], + }, + }, + }, + }); + + const alert = screen.getByRole("alert"); + expect(alert).toHaveTextContent( + "This invite's email address can't be used to create an account.", + ); + expect( + alert.compareDocumentPosition( + screen.getByRole("button", { name: "Send code" }), + ) & Node.DOCUMENT_POSITION_FOLLOWING, + ).toBeTruthy(); + }); + }); });