Skip to content

Commit

Permalink
Improve Coverage for Auth Forms
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasCode92 committed Dec 25, 2024
1 parent bf959e5 commit a64e213
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 13 deletions.
86 changes: 80 additions & 6 deletions src/components/authentication/SignInForm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,40 @@ import userEvent from "@testing-library/user-event";

import SignInForm from "./SignInForm";

const mockedMethods = vi.hoisted(function () {
const mocks = vi.hoisted(function () {
const userCredentials = { id: "123" };
return {
userCredentials,
getRedirectResultFn: vi.fn().mockResolvedValue({ userCredentials }),
signInAuthUserFn: vi.fn(),
signInWithGooglePopupFn: vi.fn().mockResolvedValue({ userCredentials }),
createUserDocumentFromAuthFn: vi.fn(),
signInWithGoogleRedirectFn: vi.fn(),
};
});

vi.mock("@/utils/firebase", function () {
vi.mock("firebase/auth", async function () {
const auth = await vi.importActual("firebase/auth");
return { ...auth, getRedirectResult: mocks.getRedirectResultFn };
});

vi.mock("@/utils/firebase", async function () {
const firebase = await vi.importActual("@/utils/firebase");
return {
signInAuthUserWithEmailAndPassword: mockedMethods.signInAuthUserFn,
...firebase,
createUserDocumentFromAuth: mocks.createUserDocumentFromAuthFn,
signInAuthUserWithEmailAndPassword: mocks.signInAuthUserFn,
signInWithGooglePopup: mocks.signInWithGooglePopupFn,
signInWithGoogleRedirect: mocks.signInWithGoogleRedirectFn,
};
});

vi.spyOn(window, "alert").mockImplementation(() => {});

beforeEach(() => {
vi.clearAllMocks();
});

test("should render the correct titles", function () {
render(<SignInForm />);

Expand Down Expand Up @@ -55,14 +75,14 @@ test("should submit the form with the correct data", async function () {
await user.type(passwordInput, "password");
await user.click(submitButton);

expect(mockedMethods.signInAuthUserFn).toHaveBeenCalledWith(
expect(mocks.signInAuthUserFn).toHaveBeenCalledWith(
"[email protected]",
"password",
);
});

test("should show an alert if the password is incorrect", async function () {
mockedMethods.signInAuthUserFn.mockRejectedValue({
mocks.signInAuthUserFn.mockRejectedValue({
code: "auth/wrong-password",
});

Expand All @@ -82,7 +102,7 @@ test("should show an alert if the password is incorrect", async function () {
});

test("should show an alert if the user is not found", async function () {
mockedMethods.signInAuthUserFn.mockRejectedValue({
mocks.signInAuthUserFn.mockRejectedValue({
code: "auth/user-not-found",
});

Expand All @@ -100,3 +120,57 @@ test("should show an alert if the user is not found", async function () {

expect(window.alert).toHaveBeenCalledWith("Wrong email or password");
});

test("should log an error if signing in fails", async function () {
const consoleSpy = vi.spyOn(console, "error");
mocks.signInAuthUserFn.mockRejectedValue(new Error("Failed to sign in"));

render(<SignInForm />);

const emailInput = screen.getByLabelText(/email/i);
const passwordInput = screen.getByLabelText(/password/i);
const submitButton = screen.getByRole("button", { name: /^sign in$/i });

const user = userEvent.setup();

await user.type(emailInput, "[email protected]");
await user.type(passwordInput, "password");
await user.click(submitButton);

expect(consoleSpy).toHaveBeenCalledWith(
"Error signing in",
expect.any(Error),
);
});

test("should sign in with Google using popup successfully", async function () {
render(<SignInForm />);

await userEvent.click(
screen.getByRole("button", {
name: /google sign in/i,
}),
);

expect(mocks.signInAuthUserFn).not.toHaveBeenCalled();
expect(mocks.signInWithGooglePopupFn).toHaveBeenCalled();
expect(mocks.createUserDocumentFromAuthFn).not.toHaveBeenCalledWith(
mocks.userCredentials,
);
});

test("should sign in with Google redirect successfully", async function () {
render(<SignInForm useRedirect />);

await userEvent.click(
screen.getByRole("button", {
name: /google sign in/i,
}),
);

expect(mocks.signInAuthUserFn).not.toHaveBeenCalled();
expect(mocks.signInWithGoogleRedirectFn).toHaveBeenCalled();
expect(mocks.createUserDocumentFromAuthFn).not.toHaveBeenCalledWith(
mocks.userCredentials,
);
});
13 changes: 6 additions & 7 deletions src/components/authentication/SignInForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default function SignInForm({ useRedirect = false }: SignInFormProps) {
(error as AuthError).code === "auth/wrong-password" ||
(error as AuthError).code === "auth/user-not-found"
) {
alert("Wrong email or password");
return alert("Wrong email or password");
}
console.error("Error signing in", error);
}
Expand All @@ -66,6 +66,10 @@ export default function SignInForm({ useRedirect = false }: SignInFormProps) {
await signInWithGoogleRedirect();
}

const handleGoogleSignin = !useRedirect
? handleLoginWithGooglePopup
: handleRedirectWithGoogle;

return (
<section className="flex w-96 flex-col">
<span className="italic text-gray-600">Already have an account?</span>
Expand Down Expand Up @@ -94,15 +98,10 @@ export default function SignInForm({ useRedirect = false }: SignInFormProps) {
<Button
type="button"
buttonType="google-sign-in"
onClick={handleLoginWithGooglePopup}
onClick={handleGoogleSignin}
>
Google Sign In
</Button>
{useRedirect && (
<Button type="button" onClick={handleRedirectWithGoogle}>
Google Sign In
</Button>
)}
</div>
</form>
</section>
Expand Down
28 changes: 28 additions & 0 deletions src/components/authentication/SignUpForm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,31 @@ test("should show an alert if email is already in use", async function () {
"Cannot create user, email already in use!",
);
});

test("should log an error if sign up fails", async function () {
const consoleSpy = vi.spyOn(console, "error");
mockedMethods.createAuthUserFn.mockRejectedValue(
new Error("Failed to sign up"),
);

render(<SignUpForm />);

const displayNameInput = screen.getByLabelText(/display name/i);
const emailInput = screen.getByLabelText(/email/i);
const passwordInput = screen.getByLabelText(/^password/i);
const confirmPasswordInput = screen.getByLabelText(/^confirm password/i);
const submitButton = screen.getByRole("button", { name: /sign up/i });

const user = userEvent.setup();

await user.type(displayNameInput, "John Doe");
await user.type(emailInput, "[email protected]");
await user.type(passwordInput, "password");
await user.type(confirmPasswordInput, "password");
await user.click(submitButton);

expect(consoleSpy).toHaveBeenCalledWith(
"Error signing up",
expect.any(Error),
);
});

0 comments on commit a64e213

Please sign in to comment.