Skip to content

Commit

Permalink
Update usePasswordValidation tests
Browse files Browse the repository at this point in the history
  • Loading branch information
OKendigelyan committed Oct 3, 2024
1 parent 234f586 commit 9ff1492
Show file tree
Hide file tree
Showing 20 changed files with 80 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe("ChangePassword Form", () => {

await waitFor(() => {
expect(screen.getByTestId("new-password-error")).toHaveTextContent(
"Your password must be at least 12 characters long"
"Password must be at least 12 characters long"
);
});
});
Expand Down Expand Up @@ -104,8 +104,8 @@ describe("ChangePassword Form", () => {
const newPasswordConfirmationInput = screen.getByTestId("new-password-confirmation");

fireEvent.change(currentPasswordInput, { target: { value: "myOldPassword" } });
fireEvent.change(newPasswordInput, { target: { value: "myNewPassword" } });
fireEvent.change(newPasswordConfirmationInput, { target: { value: "myNewPassword" } });
fireEvent.change(newPasswordInput, { target: { value: "myNewPassword123L!" } });
fireEvent.change(newPasswordConfirmationInput, { target: { value: "myNewPassword123L!" } });

await waitFor(() => {
expect(screen.getByRole("button", { name: "Update Password" })).toBeEnabled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ export const ChangePasswordForm = () => {
data-testid="current-password"
inputName="currentPassword"
label="Current Password"
minLength={0}
placeholder="Enter your current password"
required="Current password is required"
/>
Expand All @@ -81,7 +80,7 @@ export const ChangePasswordForm = () => {
<PasswordInput
data-testid="new-password"
inputName="newPassword"
isCheckPasswordStrengthEnabled
isStrengthCheckEnabled
label="New Password"
placeholder="Enter new password"
required="New password is required"
Expand All @@ -101,7 +100,6 @@ export const ChangePasswordForm = () => {
data-testid="new-password-confirmation"
inputName="newPasswordConfirmation"
label="Confirm New Password"
minLength={0}
placeholder="Confirm new password"
required="Confirmation is required"
validate={(val: string) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ describe("<EnterAndConfirmPassword />", () => {
await checkPasswords(mockPassword, "password1", false);
});

test("Not meeting password policy", async () => {
render(fixture(false));
await checkPasswords("tes", "tes", false);
});

test("Form is loading", () => {
render(fixture(true));
const submit = screen.getByRole("button", { name: /submit/i });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const EnterAndConfirmPassword = ({
<PasswordInput
data-testid="password"
inputName="password"
isCheckPasswordStrengthEnabled
isStrengthCheckEnabled
placeholder="Enter master password"
/>
{errors.password && <FormErrorMessage>{errors.password.message}</FormErrorMessage>}
Expand All @@ -53,7 +53,6 @@ export const EnterAndConfirmPassword = ({
data-testid="confirmation"
inputName="confirm"
label="Confirm Password"
minLength={0}
placeholder="Confirm your password"
required="Confirmation is required"
validate={(val: string) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ describe("<EnterPassword />", () => {
await checkPasswords(mockPassword, true);
});

test("Not meeting password policy", async () => {
render(fixture(false));
await checkPasswords("tes", false);
});

test("Form is loading", () => {
render(fixture(true));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const RestoreSecretKey = ({ goToStep }: { goToStep: (step: OnboardingStep

{isEncrypted && (
<FormControl marginTop="20px" isInvalid={!!errors.password}>
<PasswordInput data-testid="password" inputName="password" minLength={0} />
<PasswordInput data-testid="password" inputName="password" />
{errors.password && <FormErrorMessage>{errors.password.message}</FormErrorMessage>}
</FormControl>
)}
Expand Down
24 changes: 8 additions & 16 deletions apps/desktop/src/components/PasswordInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,20 @@ import {
type InputProps,
InputRightElement,
} from "@chakra-ui/react";
import { usePasswordValidation } from "@umami/components";
import { DEFAULT_MIN_LENGTH, usePasswordValidation } from "@umami/components";
import { useState } from "react";
import { type FieldValues, type Path, type RegisterOptions, useFormContext } from "react-hook-form";

import { EyeIcon, EyeSlashIcon } from "../assets/icons";
import colors from "../style/colors";

const MIN_LENGTH = 12;

// <T extends FieldValues> is needed to be compatible with the useForm's type parameter (FormData)
// <U extends Path<T>> makes sure that we can pass in only valid inputName that exists in FormData
type PasswordInputProps<T extends FieldValues, U extends Path<T>> = {
inputName: U;
label?: string;
placeholder?: string;
isCheckPasswordStrengthEnabled?: boolean;
isStrengthCheckEnabled?: boolean;
required?: string | boolean;
minLength?: RegisterOptions<T, U>["minLength"];
validate?: (val: string) => string | boolean;
Expand All @@ -33,8 +31,8 @@ export const PasswordInput = <T extends FieldValues, U extends Path<T>>({
label = "Password",
placeholder = "Enter your password",
required = "Password is required",
isCheckPasswordStrengthEnabled = false,
minLength = MIN_LENGTH,
isStrengthCheckEnabled = false,
minLength = DEFAULT_MIN_LENGTH,
validate,
...rest
}: PasswordInputProps<T, U>) => {
Expand All @@ -43,18 +41,19 @@ export const PasswordInput = <T extends FieldValues, U extends Path<T>>({
const { validatePasswordStrength, PasswordStrengthBar } = usePasswordValidation({
color: colors.gray[500],
inputName,
minLength,
});

const handleValidate = (val: string) => {
if (validate) {
const validationResult = validate(val);

if (isCheckPasswordStrengthEnabled && validationResult === true) {
if (isStrengthCheckEnabled && validationResult === true) {
return validatePasswordStrength(val);
}

return validationResult;
} else if (isCheckPasswordStrengthEnabled) {
} else if (isStrengthCheckEnabled) {
return validatePasswordStrength(val);
}
};
Expand All @@ -70,13 +69,6 @@ export const PasswordInput = <T extends FieldValues, U extends Path<T>>({
type={showPassword ? "text" : "password"}
{...register(inputName, {
required,
minLength:
minLength && required
? {
value: minLength,
message: `Your password must be at least ${minLength} characters long`,
}
: undefined,
validate: handleValidate,
})}
{...rest}
Expand All @@ -91,7 +83,7 @@ export const PasswordInput = <T extends FieldValues, U extends Path<T>>({
</Button>
</InputRightElement>
</InputGroup>
{isCheckPasswordStrengthEnabled && PasswordStrengthBar}
{isStrengthCheckEnabled && PasswordStrengthBar}
</>
);
};
2 changes: 1 addition & 1 deletion apps/desktop/src/components/SendFlow/SignButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export const SignButton = ({
<Box width="100%">
<FormProvider {...form}>
<FormControl isInvalid={!!errors.password} marginY="16px">
<PasswordInput data-testid="password" inputName="password" minLength={0} />
<PasswordInput data-testid="password" inputName="password" />
{errors.password && <FormErrorMessage>{errors.password.message}</FormErrorMessage>}
</FormControl>
<Button
Expand Down
8 changes: 0 additions & 8 deletions apps/desktop/src/setupTests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@ MockDate.set("2023-03-27T14:15:09.760Z");

jest.mock("./env", () => ({ IS_DEV: false }));

jest.mock("@umami/components", () => ({
...jest.requireActual("@umami/components"),
usePasswordValidation: () => ({
validatePasswordStrength: () => true,
PasswordStrengthBar: <div>PasswordStrengthBar</div>,
}),
}));

beforeEach(() => {
// Add missing browser APIs
Object.defineProperties(global, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export const MasterPasswordModal = ({ onSubmit }: MasterPasswordModalProps) => {
data-testid="master-password"
inputName="password"
label="Password"
minLength={0}
placeholder="Enter your password"
/>
</ModalBody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe("<ChangePasswordMenu />", () => {

await waitFor(() => {
expect(screen.getByTestId("new-password-error")).toHaveTextContent(
"Your password must be at least 12 characters long"
"Password must be at least 12 characters long"
);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,14 @@ export const ChangePasswordMenu = () => {
data-testid="current-password"
inputName="currentPassword"
label="Current Password"
minLength={0}
placeholder="Your password"
required="Current password is required"
/>
<Divider />
<PasswordInput
data-testid="new-password"
inputName="newPassword"
isCheckPasswordStrengthEnabled
isStrengthCheckEnabled
label="New Password"
placeholder="New password"
required="New password is required"
Expand All @@ -57,7 +56,6 @@ export const ChangePasswordMenu = () => {
data-testid="new-password-confirmation"
inputName="newPasswordConfirmation"
label="Confirm password"
minLength={0}
placeholder="Confirm password"
required="Confirmation is required"
validate={(val: string) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export const ImportBackupTab = () => {
/>
{errors.file && <FormErrorMessage>{errors.file.message}</FormErrorMessage>}
</FormControl>
<PasswordInput inputName="password" minLength={0} required={false} />
<PasswordInput inputName="password" required={false} />
<Button width="full" isDisabled={!isValid} type="submit" variant="primary">
Import Wallet
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const SecretKeyTab = () => {
{errors.secretKey && <FormErrorMessage>{errors.secretKey.message}</FormErrorMessage>}
</FormControl>

{isEncrypted && <PasswordInput inputName="secretKeyPassword" minLength={0} />}
{isEncrypted && <PasswordInput inputName="secretKeyPassword" />}

<Button width="full" isDisabled={!isValid} type="submit" variant="primary">
Next
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,15 +199,14 @@ export const SetupPassword = ({ mode }: SetupPasswordProps) => {
<Flex flexDirection="column" gap="24px">
<PasswordInput
inputName="password"
isCheckPasswordStrengthEnabled={!isPasswordSet}
isStrengthCheckEnabled={!isPasswordSet}
label={isPasswordSet ? "Password" : "Set Password"}
required="Password is required"
/>
{!isPasswordSet && (
<PasswordInput
inputName="passwordConfirmation"
label="Confirm Password"
minLength={0}
required="Password confirmation is required"
validate={value => value === getValues("password") || "Passwords do not match"}
/>
Expand Down
28 changes: 10 additions & 18 deletions apps/web/src/components/PasswordInput/PasswordInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,21 @@ import {
type InputProps,
InputRightElement,
} from "@chakra-ui/react";
import { usePasswordValidation } from "@umami/components";
import { DEFAULT_MIN_LENGTH, usePasswordValidation } from "@umami/components";
import { useState } from "react";
import { type FieldValues, type Path, type RegisterOptions, useFormContext } from "react-hook-form";

import { EyeIcon, EyeOffIcon } from "../../assets/icons";
import { useColor } from "../../styles/useColor";

const MIN_LENGTH = 12;

// <T extends FieldValues> is needed to be compatible with the useForm's type parameter (FormData)
// <U extends Path<T>> makes sure that we can pass in only valid inputName that exists in FormData
type PasswordInputProps<T extends FieldValues, U extends Path<T>> = {
inputName: U;
label?: string;
placeholder?: string;
required?: string | boolean;
isCheckPasswordStrengthEnabled?: boolean;
isStrengthCheckEnabled?: boolean;
minLength?: RegisterOptions<T, U>["minLength"];
validate?: (val: string) => string | boolean;
} & InputProps & {
Expand All @@ -36,8 +34,8 @@ export const PasswordInput = <T extends FieldValues, U extends Path<T>>({
label = "Password",
placeholder = "Enter your password",
required = "Password is required",
minLength = MIN_LENGTH,
isCheckPasswordStrengthEnabled = false,
minLength = DEFAULT_MIN_LENGTH,
isStrengthCheckEnabled = false,
validate,
...rest
}: PasswordInputProps<T, U>) => {
Expand All @@ -49,6 +47,7 @@ export const PasswordInput = <T extends FieldValues, U extends Path<T>>({
const [showPassword, setShowPassword] = useState<boolean>(false);
const { validatePasswordStrength, PasswordStrengthBar } = usePasswordValidation({
inputName,
minLength,
});

const color = useColor();
Expand All @@ -58,27 +57,20 @@ export const PasswordInput = <T extends FieldValues, U extends Path<T>>({

const handleValidate = (val: string) => {
if (validate) {
const validateResult = validate(val);
const validationResult = validate(val);

if (isCheckPasswordStrengthEnabled && validateResult === true) {
if (isStrengthCheckEnabled && validationResult === true) {
return validatePasswordStrength(val);
}

return validateResult;
} else if (isCheckPasswordStrengthEnabled) {
return validationResult;
} else if (isStrengthCheckEnabled) {
return validatePasswordStrength(val);
}
};

const registerProps = register(inputName, {
required,
minLength:
minLength && required
? {
value: minLength,
message: `Your password must be at least ${minLength} characters long`,
}
: undefined,
validate: handleValidate,
});

Expand Down Expand Up @@ -111,7 +103,7 @@ export const PasswordInput = <T extends FieldValues, U extends Path<T>>({
/>
</InputRightElement>
</InputGroup>
{isCheckPasswordStrengthEnabled && PasswordStrengthBar}
{isStrengthCheckEnabled && PasswordStrengthBar}
{error && (
<FormErrorMessage data-testid={`${rest["data-testid"]}-error`}>
{errorMessage}
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/SendFlow/SignButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export const SignButton = ({
<Input
data-testid="password"
type="password"
{...form.register("password", { minLength: 8, required: "Password is required" })}
{...form.register("password", { required: "Password is required" })}
/>
{errors.password && <FormErrorMessage>{errors.password.message}</FormErrorMessage>}
</FormControl>
Expand Down
Loading

0 comments on commit 9ff1492

Please sign in to comment.