Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/Buttons/FileInputButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ReactElement, ReactNode } from "react";
interface BrowseProps {
updateFile: (file: File) => void;
accept?: string;
buttonProps?: ButtonProps & { "data-testid"?: string };
buttonProps?: ButtonProps;
children?: ReactNode;
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/Buttons/LoadingDoneButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useTranslation } from "react-i18next";
import { themeColors } from "types/theme";

interface LoadingDoneButtonProps {
buttonProps?: ButtonProps & { "data-testid"?: string };
buttonProps?: ButtonProps;
children?: ReactNode;
disabled?: boolean;
done?: boolean;
Expand Down
3 changes: 1 addition & 2 deletions src/components/Dialogs/DeleteEditTextDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ export default function DeleteEditTextDialog(
value={text}
onChange={(event) => setText(event.target.value)}
onKeyPress={confirmIfEnter}
InputProps={{ endAdornment }}
inputProps={{ "data-testid": props.textFieldId }}
slotProps={{ input: { endAdornment } }}
id={props.textFieldId}
/>
</DialogContent>
Expand Down
3 changes: 1 addition & 2 deletions src/components/Dialogs/EditTextDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ export default function EditTextDialog(
value={text}
onChange={(event) => setText(event.target.value)}
onKeyPress={confirmIfEnter}
InputProps={{ endAdornment }}
inputProps={{ "data-testid": props.textFieldId }}
slotProps={{ input: { endAdornment } }}
id={props.textFieldId}
/>
</DialogContent>
Expand Down
3 changes: 1 addition & 2 deletions src/components/Dialogs/SubmitTextDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ export default function SubmitTextDialog(
value={text}
onChange={(event) => setText(event.target.value)}
onKeyPress={confirmIfEnter}
InputProps={{ endAdornment }}
inputProps={{ "data-testid": props.textFieldId }}
slotProps={{ input: { endAdornment } }}
id={props.textFieldId}
/>
</DialogContent>
Expand Down
6 changes: 1 addition & 5 deletions src/components/Dialogs/UploadImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,7 @@ export default function ImageUpload(props: ImageUploadProps): ReactElement {
{t("buttons.browse")}
</FileInputButton>

<LoadingDoneButton
loading={loading}
done={done}
buttonProps={{ type: "submit", id: "image-upload-save" }}
>
<LoadingDoneButton done={done} loading={loading}>
{t("buttons.save")}
</LoadingDoneButton>
</Grid2>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Login/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ export default function Login(): ReactElement {

const defaultTextFieldProps = (id?: string): TextFieldProps => ({
id,
inputProps: { "data-testid": id, maxLength: 100 },
margin: "normal",
required: true,
slotProps: { htmlInput: { maxLength: 100 } },
style: { width: "100%" },
variant: "outlined",
});
Expand Down
34 changes: 8 additions & 26 deletions src/components/Login/Signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,23 +70,12 @@ export const signupFieldTextId: SignupText = {
[SignupField.Username]: "login.username",
};

export enum SignupId {
ButtonLogIn = "signup-log-in-button",
ButtonSignUp = "signup-sign-up-button",
FieldEmail = "signup-email-field",
FieldName = "signup-name-field",
FieldPassword1 = "signup-password1-field",
FieldPassword2 = "signup-password2-field",
FieldUsername = "signup-username-field",
Form = "signup-form",
}

export const signupFieldId: Record<SignupField, SignupId> = {
[SignupField.Email]: SignupId.FieldEmail,
[SignupField.Name]: SignupId.FieldName,
[SignupField.Password1]: SignupId.FieldPassword1,
[SignupField.Password2]: SignupId.FieldPassword2,
[SignupField.Username]: SignupId.FieldUsername,
export const signupFieldId: SignupText = {
[SignupField.Email]: "signup-email-field",
[SignupField.Name]: "signup-name-field",
[SignupField.Password1]: "signup-password1-field",
[SignupField.Password2]: "signup-password2-field",
[SignupField.Username]: "signup-username-field",
};

interface SignupProps {
Expand Down Expand Up @@ -177,11 +166,11 @@ export default function Signup(props: SignupProps): ReactElement {
const defaultTextFieldProps = (field: SignupField): TextFieldProps => ({
error: fieldError[field],
id: signupFieldId[field],
inputProps: { "data-testid": signupFieldId[field], maxLength: 100 },
label: t(signupFieldTextId[field]),
margin: "normal",
onChange: (e) => updateField(e, field),
required: true,
slotProps: { htmlInput: { maxLength: 100 } },
style: { width: "100%" },
value: fieldText[field],
variant: "outlined",
Expand All @@ -200,7 +189,7 @@ export default function Signup(props: SignupProps): ReactElement {
/>

<CardContent>
<form id={SignupId.Form} onSubmit={signUp}>
<form onSubmit={signUp}>
<Stack spacing={2}>
{/* Name field */}
<NormalizedTextField
Expand Down Expand Up @@ -263,20 +252,13 @@ export default function Signup(props: SignupProps): ReactElement {
{/* Back-to-login and Sign-up buttons */}
<Stack direction="row" justifyContent="flex-end" spacing={2}>
<Button
data-testid={SignupId.ButtonLogIn}
id={SignupId.ButtonLogIn}
onClick={() => router.navigate(Path.Login)}
variant="outlined"
>
{t("login.backToLogin")}
</Button>

<LoadingDoneButton
buttonProps={{
"data-testid": SignupId.ButtonSignUp,
id: SignupId.ButtonSignUp,
type: "submit",
}}
disabled={!isVerified}
done={signupStatus === LoginStatus.Success}
doneText={t("login.signUpSuccess")}
Expand Down
16 changes: 8 additions & 8 deletions src/components/Login/tests/Login.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ const renderLogin = async (): Promise<void> => {
};

/** Type the given value into the field with the given ID. */
const typeInField = async (id: LoginId, value: string): Promise<void> => {
await userEvent.type(screen.getByTestId(id), value);
const typeInField = async (id: LoginTextId, value: string): Promise<void> => {
await userEvent.type(screen.getByLabelText(new RegExp(id)), value);
};

/** Click the Login button and confirm whether the field with the given ID has an error. */
Expand Down Expand Up @@ -84,22 +84,22 @@ describe("Login", () => {
// Don't test with empty username or password, because those prevent submission.

it("errors when username is whitespace", async () => {
await typeInField(LoginId.FieldUsername, " ");
await typeInField(LoginId.FieldPassword, "nonempty");
await typeInField(LoginTextId.LabelUsername, " ");
await typeInField(LoginTextId.LabelPassword, "nonempty");

await loginAndCheckError(LoginId.FieldUsername);
});

it("errors when password is whitespace", async () => {
await typeInField(LoginId.FieldUsername, "nonempty");
await typeInField(LoginId.FieldPassword, " ");
await typeInField(LoginTextId.LabelUsername, "nonempty");
await typeInField(LoginTextId.LabelPassword, " ");

await loginAndCheckError(LoginId.FieldPassword);
});

it("submits when username and password are valid", async () => {
await typeInField(LoginId.FieldUsername, "nonempty");
await typeInField(LoginId.FieldPassword, "nonempty");
await typeInField(LoginTextId.LabelUsername, "nonempty");
await typeInField(LoginTextId.LabelPassword, "nonempty");

await loginAndCheckError();
});
Expand Down
8 changes: 3 additions & 5 deletions src/components/Login/tests/Signup.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import configureMockStore from "redux-mock-store";
import { defaultState as loginState } from "components/Login/Redux/LoginReduxTypes";
import Signup, {
SignupField,
SignupId,
SignupText,
signupFieldId,
signupFieldTextId,
} from "components/Login/Signup";
import MockCaptcha from "components/Login/tests/MockCaptcha";
Expand Down Expand Up @@ -61,15 +59,15 @@ const typeInFields = async (textRecord: Partial<SignupText>): Promise<void> => {
if (!text) {
continue;
}
const id = signupFieldId[field as SignupField];
await userEvent.type(screen.getByTestId(id), text);
const id = signupFieldTextId[field as SignupField];
await userEvent.type(screen.getByLabelText(new RegExp(id)), text);
}
};

/** Clicks the submit button and checks that only the specified field errors. */
const submitAndCheckError = async (id?: SignupField): Promise<void> => {
// Submit the form.
await userEvent.click(screen.getByTestId(SignupId.ButtonSignUp));
await userEvent.click(screen.getByText("login.signUp"));

// Only the specified field should error.
Object.values(SignupField).forEach((val) => {
Expand Down
51 changes: 19 additions & 32 deletions src/components/PasswordReset/Request.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ import Captcha from "components/Login/Captcha";
import { Path } from "types/path";
import { NormalizedTextField } from "utilities/fontComponents";

export enum PasswordRequestIds {
ButtonLogin = "password-request-login",
ButtonSubmit = "password-request-submit",
FieldEmailOrUsername = "password-request-text",
export enum ResetRequestTextId {
ButtonSubmit = "passwordReset.submit",
ButtonLogin = "login.backToLogin",
Done = "passwordReset.resetDone",
FieldEmailOrUsername = "passwordReset.emailOrUsername",
FieldEmailOrUsernameError = "passwordReset.resetFail",
Instructions = "passwordReset.resetRequestInstructions",
Title = "passwordReset.resetRequestTitle",
}

export default function ResetRequest(): ReactElement {
Expand Down Expand Up @@ -53,40 +57,31 @@ export default function ResetRequest(): ReactElement {
<CardHeader
title={
<Typography align="center" variant="h5">
{t("passwordReset.resetRequestTitle")}
{t(ResetRequestTextId.Title)}
</Typography>
}
/>

<CardContent>
{isDone ? (
<Stack alignItems="flex-end" spacing={2}>
<Typography>{t("passwordReset.resetDone")}</Typography>
<Typography>{t(ResetRequestTextId.Done)}</Typography>

<Button
data-testid={PasswordRequestIds.ButtonLogin}
id={PasswordRequestIds.ButtonLogin}
onClick={() => navigate(Path.Login)}
variant="contained"
>
{t("login.backToLogin")}
<Button onClick={() => navigate(Path.Login)} variant="contained">
{t(ResetRequestTextId.ButtonLogin)}
</Button>
</Stack>
) : (
<form onSubmit={onSubmit}>
<Stack spacing={1}>
<Typography>
{t("passwordReset.resetRequestInstructions")}
</Typography>
<Typography>{t(ResetRequestTextId.Instructions)}</Typography>

<NormalizedTextField
fullWidth
helperText={isError && t("passwordReset.resetFail")}
id={PasswordRequestIds.FieldEmailOrUsername}
inputProps={{
"data-testid": PasswordRequestIds.FieldEmailOrUsername,
}}
label={t("passwordReset.emailOrUsername")}
helperText={
isError && t(ResetRequestTextId.FieldEmailOrUsernameError)
}
label={t(ResetRequestTextId.FieldEmailOrUsername)}
onChange={(e) => setEmailOrUsername(e.target.value)}
required
value={emailOrUsername}
Expand All @@ -97,25 +92,17 @@ export default function ResetRequest(): ReactElement {
{/* Back-to-login and Submit buttons */}
<Stack direction="row" justifyContent="flex-end" spacing={2}>
<Button
data-testid={PasswordRequestIds.ButtonLogin}
id={PasswordRequestIds.ButtonLogin}
onClick={() => navigate(Path.Login)}
variant="outlined"
>
{t("login.backToLogin")}
{t(ResetRequestTextId.ButtonLogin)}
</Button>

<LoadingDoneButton
buttonProps={{
"data-testid": PasswordRequestIds.ButtonSubmit,
id: PasswordRequestIds.ButtonSubmit,
type: "submit",
variant: "contained",
}}
disabled={!emailOrUsername || !isVerified}
loading={isLoading}
>
{t("passwordReset.submit")}
{t(ResetRequestTextId.ButtonSubmit)}
</LoadingDoneButton>
</Stack>
</Stack>
Expand Down
Loading
Loading