Skip to content

Commit fcbbc8c

Browse files
committed
test: add withAuth hoc test
1 parent 890504d commit fcbbc8c

File tree

8 files changed

+171
-6
lines changed

8 files changed

+171
-6
lines changed

jest.setup.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ jest.mock('next/navigation', () => {
2525
};
2626
});
2727

28-
jest.mock('@/components/hoc/withAuth', () => {
29-
return jest.fn().mockImplementation((Component) => Component);
30-
});
31-
3228
jest.mock('next/headers', () => {
3329
return {
3430
cookies: () => ({

src/__mocks__/cookie.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const getCookie = jest.fn();
2+
export const deleteCookie = jest.fn();
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { render, renderHook, screen, waitFor } from '@testing-library/react';
2+
3+
import api from '@/lib/axios';
4+
import { getCookie } from '@/lib/cookie';
5+
6+
import withAuth from '@/components/hoc/withAuth';
7+
8+
import useAuthStore from '@/store/useAuthStore';
9+
10+
// Mock getCookie
11+
jest.mock('@/lib/cookie', () => ({
12+
getCookie: jest.fn(),
13+
deleteCookie: jest.requireActual('@/lib/cookie').deleteCookie,
14+
}));
15+
16+
describe('PrivatePage', () => {
17+
beforeEach(() => {
18+
const { result } = renderHook(() => useAuthStore());
19+
waitFor(() => result.current.reset());
20+
jest.restoreAllMocks();
21+
});
22+
23+
it('renders the component for admin role', async () => {
24+
// Set up the mock return value for getCookie
25+
const mockCookieValue = 'mockedTokenValue';
26+
(getCookie as jest.Mock).mockResolvedValue(mockCookieValue);
27+
28+
// Mock the Axios GET Profile request
29+
jest.spyOn(api, 'get').mockResolvedValue({
30+
data: {
31+
statusCode: 200,
32+
data: {
33+
id: '1',
34+
username: 'adminUser',
35+
email: 'admin@yopmail.com',
36+
roles: [{ id: '1', name: 'admin' }],
37+
createdAt: new Date().getTime().toString(),
38+
},
39+
},
40+
});
41+
42+
// Render the component and wait for loading to complete
43+
const Component = () => <h1>Admin Only</h1>;
44+
const WrappedComponent = withAuth(Component, 'all', ['admin']);
45+
render(<WrappedComponent />);
46+
await waitFor(() => {
47+
expect(screen.getByText('Admin Only')).toBeInTheDocument();
48+
});
49+
});
50+
51+
it('renders forbidden access for other role', async () => {
52+
// Set up the mock return value for getCookie
53+
const mockCookieValue = 'mockedTokenValue';
54+
(getCookie as jest.Mock).mockResolvedValue(mockCookieValue);
55+
56+
// Mock the Axios GET Profile request
57+
jest.spyOn(api, 'get').mockResolvedValue({
58+
data: {
59+
statusCode: 200,
60+
data: {
61+
id: '1',
62+
username: 'userUser',
63+
email: 'user@yopmail.com',
64+
roles: [{ id: '1', name: 'user' }],
65+
createdAt: new Date().getTime().toString(),
66+
},
67+
},
68+
});
69+
// Render the component and wait for loading to complete
70+
const Component = () => <h1>Admin Only</h1>;
71+
const WrappedComponent = withAuth(Component, 'all', ['admin']);
72+
render(<WrappedComponent />);
73+
await waitFor(() => {
74+
expect(screen.queryByText('Admin Only')).toBeNull();
75+
expect(screen.getByText('Forbidden Access')).toBeInTheDocument();
76+
});
77+
});
78+
});

src/__tests__/pages/DashboardPage.test.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import mockRouter from 'next-router-mock';
44
import useAuthStore from '@/store/useAuthStore';
55

66
import Dashboard from '@/app/dashboard/page';
7-
7+
jest.mock('@/components/hoc/withAuth', () => {
8+
return jest.fn().mockImplementation((Component) => Component);
9+
});
810
describe('Dashboard', () => {
911
it('renders the Components', () => {
1012
// Set the initial url:

src/__tests__/pages/HomePage.test.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import { render, screen } from '@testing-library/react';
44
import mockRouter from 'next-router-mock';
55

66
import HomePage from '@/app/page';
7+
jest.mock('@/components/hoc/withAuth', () => {
8+
return jest.fn().mockImplementation((Component) => Component);
9+
});
710
describe('Homepage', () => {
811
it('renders the Components', () => {
912
// Set the initial url:
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { render, renderHook, screen, waitFor } from '@testing-library/react';
2+
3+
import api from '@/lib/axios';
4+
import { getCookie } from '@/lib/cookie';
5+
6+
import useAuthStore from '@/store/useAuthStore';
7+
8+
import PrivatePage from '@/app/private/page';
9+
10+
// Mock getCookie
11+
jest.mock('@/lib/cookie', () => ({
12+
getCookie: jest.fn(),
13+
deleteCookie: jest.requireActual('@/lib/cookie').deleteCookie,
14+
}));
15+
16+
describe('PrivatePage', () => {
17+
beforeEach(() => {
18+
const { result } = renderHook(() => useAuthStore());
19+
waitFor(() => result.current.reset());
20+
jest.restoreAllMocks();
21+
});
22+
23+
it('renders the component for admin role', async () => {
24+
// Set up the mock return value for getCookie
25+
const mockCookieValue = 'mockedTokenValue';
26+
(getCookie as jest.Mock).mockResolvedValue(mockCookieValue);
27+
28+
// Mock the Axios GET Profile request
29+
jest.spyOn(api, 'get').mockResolvedValue({
30+
data: {
31+
statusCode: 200,
32+
data: {
33+
id: '1',
34+
username: 'adminUser',
35+
email: 'admin@yopmail.com',
36+
roles: [{ id: '1', name: 'admin' }],
37+
createdAt: new Date().getTime().toString(),
38+
},
39+
},
40+
});
41+
42+
// Render the component and wait for loading to complete
43+
render(<PrivatePage />);
44+
await waitFor(() => {
45+
expect(screen.getByText('This is private')).toBeInTheDocument();
46+
});
47+
});
48+
49+
it('renders forbidden access for other role', async () => {
50+
// Set up the mock return value for getCookie
51+
const mockCookieValue = 'mockedTokenValue';
52+
(getCookie as jest.Mock).mockResolvedValue(mockCookieValue);
53+
54+
// Mock the Axios GET Profile request
55+
jest.spyOn(api, 'get').mockResolvedValue({
56+
data: {
57+
statusCode: 200,
58+
data: {
59+
id: '1',
60+
username: 'userUser',
61+
email: 'user@yopmail.com',
62+
roles: [{ id: '1', name: 'user' }],
63+
createdAt: new Date().getTime().toString(),
64+
},
65+
},
66+
});
67+
68+
// Render the component and wait for loading to complete
69+
render(<PrivatePage />);
70+
await waitFor(() => {
71+
expect(screen.getByText('Forbidden Access')).toBeInTheDocument();
72+
});
73+
});
74+
});

src/__tests__/pages/ProfilePage.test.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ import useAuthStore from '@/store/useAuthStore';
1515

1616
import ProfilePage from '@/app/profile/page';
1717

18+
jest.mock('@/components/hoc/withAuth', () => {
19+
return jest.fn().mockImplementation((Component) => Component);
20+
});
1821
describe('Profile', () => {
1922
it('renders the Components', () => {
2023
const queryClient = new QueryClient();

src/store/useAuthStore.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@ type AuthStoreType = {
1717
logout: () => void;
1818
stopLoading: () => void;
1919
switchRole: (role: Role) => void;
20+
reset: () => void;
2021
};
2122

22-
const useAuthStoreBase = create<AuthStoreType>((set) => ({
23+
const initialState = {
2324
user: null,
2425
role: null,
2526
isAuthenticated: false,
2627
isLoading: true,
28+
};
29+
const useAuthStoreBase = create<AuthStoreType>((set) => ({
30+
...initialState,
2731
login: (user, preferedRole) => {
2832
let tempRole = user.roles[0];
2933
if (preferedRole) {
@@ -68,6 +72,9 @@ const useAuthStoreBase = create<AuthStoreType>((set) => ({
6872
})
6973
);
7074
},
75+
reset: () => {
76+
set({ ...initialState });
77+
},
7178
}));
7279

7380
const useAuthStore = createSelectorHooks(useAuthStoreBase);

0 commit comments

Comments
 (0)