1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122import userEvent from '@testing-library/user-event';
import { axe, toHaveNoViolations } from 'jest-axe';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { SignupForm } from '~/components/forms';
import * as useAuthModule from '~/hooks/useAuth';
import { Signup } from '~/routes';
import { render, screen, waitFor } from '../../../customRender';
vi.mock('~/hooks/useAuth', () => ({
useAuth: vi.fn(),
}));
const mockUseAuth = (overrides = {}) => {
vi.mocked(useAuthModule.useAuth).mockReturnValue({
signUp: vi.fn(),
confirmSignUp: vi.fn(),
resendSignUpCode: vi.fn(),
signIn: vi.fn(),
signOut: vi.fn(),
deleteUser: vi.fn(),
user: null,
isAuthenticated: false,
needsConfirmation: false,
pendingUsername: null,
loading: false,
error: null,
...overrides,
});
};
expect.extend(toHaveNoViolations);
describe('Signup Page and Form', () => {
beforeEach(() => {
vi.clearAllMocks();
mockUseAuth({});
});
it('Page renders correctly and is accessible', async () => {
const { container } = render(<Signup />);
expect(
screen.getByRole('heading', { name: /Join Equalify/i }),
).toBeInTheDocument();
const results = await axe(container);
expect(results).toHaveNoViolations();
});
describe('Signup form functionality', () => {
beforeEach(() => {
mockUseAuth();
});
it('is accessible', async () => {
const { container } = render(<SignupForm />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
it('calls signUp with correct inputs', async () => {
const signUpMock = vi.fn().mockResolvedValueOnce({});
mockUseAuth({ signUp: signUpMock });
const user = userEvent.setup();
render(<Signup />);
await user.type(
screen.getByPlaceholderText(/E.g. johndoe@email.com/i),
'newuser@example.com',
);
await user.type(
screen.getByPlaceholderText('Your password'),
'newPassword123',
);
await user.type(
screen.getByPlaceholderText('Confirm your password'),
'newPassword123',
);
await user.click(screen.getByRole('button', { name: /continue/i }));
await waitFor(() => {
expect(signUpMock).toHaveBeenCalledWith({
email: 'newuser@example.com',
password: 'newPassword123',
});
});
});
it('displays error message on signUp failure', async () => {
const error = new Error('Signup failed');
mockUseAuth({ signUp: vi.fn().mockRejectedValueOnce(error), error });
const user = userEvent.setup();
render(<Signup />);
await user.type(screen.getByLabelText(/email/i), 'newuser@example.com');
await user.type(screen.getByLabelText('Password'), 'new');
await user.click(screen.getByRole('button', { name: /continue/i }));
await waitFor(() => {
expect(screen.getByText(error.message)).toBeInTheDocument();
});
});
it('toggles password visibility', async () => {
const user = userEvent.setup();
render(<Signup />);
const passwordInput = screen.getByPlaceholderText('Your password');
expect(passwordInput).toHaveAttribute('type', 'password');
const toggleVisibilityButton = screen.getByLabelText(/Show password/i);
await user.click(toggleVisibilityButton);
expect(passwordInput).toHaveAttribute('type', 'text');
await user.click(toggleVisibilityButton);
expect(passwordInput).toHaveAttribute('type', 'password');
});
});
});