Feat/Add unit tests to RecoverPassword component (#445)

* test(RecoverPassword): add unit tests

* Returning a promise instead of using await (lint error) + fix build issues

* Test if updateUserMock was called in case of update failure
This commit is contained in:
Ziyad El Abid 2023-07-02 17:56:12 +01:00 committed by GitHub
parent ca0591d31c
commit 8bb8c21e04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 135 additions and 1 deletions

View File

@ -0,0 +1,131 @@
/* eslint-disable max-lines */
import { fireEvent, render } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import RecoverPassword from "../page";
const mockUsePathname = vi.fn(() => "/previous-page");
const mockRedirect = vi.fn((url: string) => ({ url }));
vi.mock("next/navigation", () => ({
redirect: (url: string) => mockRedirect(url),
usePathname: () => mockUsePathname(),
}));
const mockUseSupabase = vi.fn(() => ({
supabase: {
auth: {
updateUser: vi.fn(),
},
},
session: {
user: {},
},
}));
vi.mock("@/lib/context/SupabaseProvider", () => ({
useSupabase: () => mockUseSupabase(),
}));
const mockPublish = vi.fn();
vi.mock("@/lib/hooks/useToast", () => ({
useToast: () => ({
publish: mockPublish,
}),
}));
const mockTrack = vi.fn();
vi.mock("@/services/analytics/useEventTracking", () => ({
useEventTracking: () => ({
track: mockTrack,
}),
}));
describe("RecoverPassword component", () => {
it("should render the password update form", () => {
mockUseSupabase.mockReturnValue({
//@ts-expect-error doing this for testing purposes
session: { user: undefined },
});
const { getByTestId } = render(<RecoverPassword />);
const passwordField = getByTestId("password-field");
const updateButton = getByTestId("update-button");
expect(passwordField).toBeDefined();
expect(updateButton).toBeDefined();
});
it("should update the password and shows success toast", async () => {
const updateUserMock = vi.fn(() => ({
data: {},
}));
mockUseSupabase.mockReturnValue({
supabase: {
auth: {
updateUser: updateUserMock,
},
},
session: { user: {} },
});
const { getByTestId } = render(<RecoverPassword />);
const passwordField = getByTestId("password-field");
const updateButton = getByTestId("update-button");
const newPassword = "new-password";
fireEvent.change(passwordField, { target: { value: newPassword } });
fireEvent.click(updateButton);
expect(mockTrack).toHaveBeenCalledTimes(1);
expect(mockTrack).toHaveBeenCalledWith("UPDATE_PASSWORD");
return new Promise<void>((resolve) => {
setTimeout(() => {
expect(mockPublish).toHaveBeenCalledTimes(1);
expect(mockPublish).toHaveBeenCalledWith({
variant: "success",
text: "Password updated successfully!",
});
expect(updateUserMock).toHaveBeenCalledTimes(1);
expect(updateUserMock).toHaveBeenCalledWith({
password: newPassword,
});
resolve();
}, 0);
});
});
it("should show error toast when password update fails", async () => {
const errorMessage = "Password update failed";
const updateUserMock = vi.fn(() => ({
error: { message: errorMessage },
}));
mockUseSupabase.mockReturnValue({
supabase: {
auth: {
updateUser: updateUserMock,
},
},
session: { user: {} },
});
const { getByTestId } = render(<RecoverPassword />);
const passwordField = getByTestId("password-field");
const updateButton = getByTestId("update-button");
fireEvent.change(passwordField, { target: { value: "new-password" } });
fireEvent.click(updateButton);
expect(mockPublish).toHaveBeenCalledTimes(1);
return new Promise<void>((resolve) => {
setTimeout(() => {
expect(mockPublish).toHaveBeenCalledWith({
variant: "danger",
text: `Error: ${errorMessage}`,
});
resolve();
}, 0);
});
});
});

View File

@ -63,9 +63,12 @@ export default function RecoverPassword() {
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="New password"
data-testid="password-field"
/>
<div className="flex flex-col items-center justify-center mt-2 gap-2">
<Button isLoading={isPending}>Update</Button>
<Button isLoading={isPending} data-testid="update-button">
Update
</Button>
</div>
</form>
</Card>