Skip to content

Commit eb89424

Browse files
test: navbar desktop coverage (#318)
* test(navbar): improve coverage for NavbarDesktop * test(navbar): improve NavbarDesktop testability and coverage * test: improve NavbarDesktop interaction coverage * test(navbar): update NavbarDesktop snapshot
1 parent a89f58c commit eb89424

File tree

3 files changed

+101
-9
lines changed

3 files changed

+101
-9
lines changed

frontend/src/components/HomeComponents/Navbar/NavbarDesktop.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ import {
1616
DropdownMenuLabel,
1717
DropdownMenuTrigger,
1818
} from '@/components/ui/dropdown-menu';
19-
import { Avatar, AvatarFallback, AvatarImage } from '../../ui/avatar';
20-
import { ModeToggle } from '../../utils/ThemeModeToggle';
19+
20+
import { ModeToggle } from '@/components/utils/ThemeModeToggle';
21+
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
22+
2123
import { buttonVariants } from '@/components/ui/button';
2224
import {
2325
routeList,
@@ -41,7 +43,7 @@ import {
4143
exportTasksAsTXT,
4244
} from '@/components/utils/ExportTasks';
4345
import { useState } from 'react';
44-
import { DevLogs } from '../DevLogs/DevLogs';
46+
import { DevLogs } from '@/components/HomeComponents/DevLogs/DevLogs';
4547
import { useTaskAutoSync } from '@/components/utils/TaskAutoSync';
4648
import { Label } from '@/components/ui/label';
4749

frontend/src/components/HomeComponents/Navbar/__tests__/NavbarDesktop.test.tsx

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,34 @@
1+
jest.mock('@/components/ui/slider', () => ({
2+
Slider: () => <div data-testid="sync-slider" />,
3+
}));
4+
jest.mock('@/components/ui/switch', () => ({
5+
Switch: ({ onCheckedChange }: any) => (
6+
<button onClick={() => onCheckedChange(true)}>toggle</button>
7+
),
8+
}));
9+
jest.mock('@/components/utils/ExportTasks', () => ({
10+
exportTasksAsJSON: jest.fn(),
11+
exportTasksAsTXT: jest.fn(),
12+
}));
13+
jest.mock('../navbar-utils', () => ({
14+
...jest.requireActual('../navbar-utils'),
15+
deleteAllTasks: jest.fn(),
16+
}));
17+
jest.mock('@/components/ui/dialog', () => ({
18+
Dialog: ({ children }: any) => <div>{children}</div>,
19+
DialogTrigger: ({ children }: any) => <div>{children}</div>,
20+
DialogContent: ({ children }: any) => (
21+
<div data-testid="export-dialog">{children}</div>
22+
),
23+
DialogHeader: ({ children }: any) => <div>{children}</div>,
24+
DialogTitle: ({ children }: any) => <h2>{children}</h2>,
25+
DialogDescription: ({ children }: any) => <p>{children}</p>,
26+
}));
127
import { render, screen } from '@testing-library/react';
28+
import userEvent from '@testing-library/user-event';
229
import { NavbarDesktop } from '../NavbarDesktop';
330
import { Props, routeList } from '../navbar-utils';
431

5-
// Mock external dependencies
632
jest.mock('../navbar-utils', () => ({
733
deleteAllTasks: jest.fn(),
834
handleLogout: jest.fn(),
@@ -13,8 +39,17 @@ jest.mock('../navbar-utils', () => ({
1339
{ href: '#faq', label: 'FAQ' },
1440
],
1541
}));
42+
jest.mock('@/components/HomeComponents/DevLogs/DevLogs', () => ({
43+
DevLogs: () => <div data-testid="dev-logs-dialog" />,
44+
}));
1645

46+
jest.mock('@/components/utils/URLs', () => ({
47+
url: {
48+
githubRepoURL: 'https://github.com/test/repo',
49+
},
50+
}));
1751
const mockSetIsLoading = jest.fn();
52+
1853
const mockProps: Props = {
1954
imgurl: 'http://example.com/image.png',
2055
email: 'test@example.com',
@@ -34,22 +69,77 @@ describe('NavbarDesktop', () => {
3469
afterEach(() => {
3570
jest.clearAllMocks();
3671
});
37-
3872
it('renders the navigation links correctly', () => {
3973
render(<NavbarDesktop {...extendedProps} />);
4074

4175
routeList.forEach((route) => {
4276
expect(screen.getByText(route.label)).toBeInTheDocument();
4377
});
4478
});
79+
it('opens user menu and displays email', async () => {
80+
render(<NavbarDesktop {...extendedProps} />);
4581

46-
it('displays user email and handles dropdown menu actions', () => {
82+
const avatarFallback = screen.getByText('CN');
83+
await userEvent.click(avatarFallback);
84+
85+
expect(screen.getAllByText('test@example.com')[0]).toBeInTheDocument();
86+
});
87+
88+
it('opens github link when clicked', async () => {
89+
const openSpy = jest.spyOn(window, 'open').mockImplementation(() => null);
90+
91+
const user = userEvent.setup();
4792
render(<NavbarDesktop {...extendedProps} />);
93+
94+
await user.click(screen.getByText('CN'));
95+
await user.click(screen.getByText('GitHub'));
96+
97+
expect(openSpy).toHaveBeenCalledWith(
98+
'https://github.com/test/repo',
99+
'_blank'
100+
);
101+
102+
openSpy.mockRestore();
103+
});
104+
it('exports tasks as TXT and triggers export handler', async () => {
105+
const user = userEvent.setup();
106+
const { exportTasksAsTXT } = require('@/components/utils/ExportTasks');
107+
108+
render(<NavbarDesktop {...extendedProps} />);
109+
110+
await user.click(screen.getByText('CN'));
111+
await user.click(screen.getByText('Export tasks'));
112+
113+
expect(screen.getByText(/Would you like to download/i)).toBeInTheDocument();
114+
115+
await user.click(screen.getByText('Download .txt'));
116+
117+
expect(exportTasksAsTXT).toHaveBeenCalledWith([]);
118+
});
119+
it('exports tasks as JSON', async () => {
120+
const { exportTasksAsJSON } = require('@/components/utils/ExportTasks');
121+
122+
render(<NavbarDesktop {...extendedProps} />);
123+
124+
await userEvent.click(screen.getByText('CN'));
125+
await userEvent.click(screen.getByText('Export tasks'));
126+
await userEvent.click(screen.getByText('Download .json'));
127+
128+
expect(exportTasksAsJSON).toHaveBeenCalledWith([]);
129+
});
130+
it('shows slider when auto sync is enabled', async () => {
131+
const user = userEvent.setup();
132+
render(<NavbarDesktop {...extendedProps} />);
133+
134+
await user.click(screen.getByText('CN'));
135+
await user.click(screen.getByText('toggle'));
136+
137+
expect(screen.getByTestId('sync-slider')).toBeInTheDocument();
48138
});
49139
});
50140

51-
describe('NavbarDesktop component using snapshot', () => {
52-
test('renders correctly', () => {
141+
describe('NavbarDesktop snapshot', () => {
142+
it('renders correctly', () => {
53143
const { asFragment } = render(<NavbarDesktop {...extendedProps} />);
54144
expect(asFragment()).toMatchSnapshot();
55145
});

frontend/src/components/HomeComponents/Navbar/__tests__/__snapshots__/NavbarDesktop.test.tsx.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`NavbarDesktop component using snapshot renders correctly 1`] = `
3+
exports[`NavbarDesktop snapshot renders correctly 1`] = `
44
<DocumentFragment>
55
<div
66
class="hidden md:flex items-center justify-between w-full"

0 commit comments

Comments
 (0)