From 5d7e27c54c4dc5a810cc39d635016b4e2ce8ebc1 Mon Sep 17 00:00:00 2001 From: Anuj Singh Date: Sat, 3 Jan 2026 17:10:33 +0000 Subject: [PATCH] test: add tests for NavbarDesktop --- .../Navbar/__tests__/NavbarDesktop.test.tsx | 144 +++--- .../__snapshots__/NavbarDesktop.test.tsx.snap | 473 ++++++++++++++---- 2 files changed, 459 insertions(+), 158 deletions(-) diff --git a/frontend/src/components/HomeComponents/Navbar/__tests__/NavbarDesktop.test.tsx b/frontend/src/components/HomeComponents/Navbar/__tests__/NavbarDesktop.test.tsx index 7cca11b5..5f90174c 100644 --- a/frontend/src/components/HomeComponents/Navbar/__tests__/NavbarDesktop.test.tsx +++ b/frontend/src/components/HomeComponents/Navbar/__tests__/NavbarDesktop.test.tsx @@ -1,46 +1,63 @@ +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { NavbarDesktop } from '../NavbarDesktop'; +import { Props, routeList } from '../navbar-utils'; + +// Mock external dependencies jest.mock('@/components/ui/slider', () => ({ - Slider: () =>
, + Slider: () =>
slider
, })); + jest.mock('@/components/ui/switch', () => ({ Switch: ({ onCheckedChange }: any) => ( ), })); -jest.mock('@/components/utils/ExportTasks', () => ({ - exportTasksAsJSON: jest.fn(), - exportTasksAsTXT: jest.fn(), -})); -jest.mock('../navbar-utils', () => ({ - ...jest.requireActual('../navbar-utils'), - deleteAllTasks: jest.fn(), + +jest.mock('@/components/ui/dropdown-menu', () => ({ + DropdownMenu: ({ children }: any) =>
{children}
, + DropdownMenuTrigger: ({ children }: any) =>
{children}
, + DropdownMenuContent: ({ children }: any) =>
{children}
, + DropdownMenuItem: ({ children, onClick, onSelect }: any) => ( +
onSelect?.(e)}> + {children} +
+ ), + DropdownMenuLabel: ({ children }: any) =>
{children}
, })); + jest.mock('@/components/ui/dialog', () => ({ Dialog: ({ children }: any) =>
{children}
, DialogTrigger: ({ children }: any) =>
{children}
, DialogContent: ({ children }: any) => ( -
{children}
+
{children}
), DialogHeader: ({ children }: any) =>
{children}
, DialogTitle: ({ children }: any) =>

{children}

, DialogDescription: ({ children }: any) =>

{children}

, })); -import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import { NavbarDesktop } from '../NavbarDesktop'; -import { Props, routeList } from '../navbar-utils'; -jest.mock('../navbar-utils', () => ({ - deleteAllTasks: jest.fn(), - handleLogout: jest.fn(), - routeList: [ - { href: '#', label: 'Home' }, - { href: '#tasks', label: 'Tasks' }, - { href: '#setup-guide', label: 'Setup Guide' }, - { href: '#faq', label: 'FAQ' }, - ], +jest.mock('@/components/ui/avatar', () => ({ + Avatar: ({ children }: any) =>
{children}
, + AvatarImage: () => avatar, + AvatarFallback: ({ children }: any) => , +})); + +jest.mock('@/components/utils/ThemeModeToggle', () => ({ + ModeToggle: () =>
, })); + jest.mock('@/components/HomeComponents/DevLogs/DevLogs', () => ({ - DevLogs: () =>
, + DevLogs: () =>
, +})); + +jest.mock('@/components/utils/TaskAutoSync', () => ({ + useTaskAutoSync: jest.fn(), +})); + +jest.mock('@/components/utils/ExportTasks', () => ({ + exportTasksAsJSON: jest.fn(), + exportTasksAsTXT: jest.fn(), })); jest.mock('@/components/utils/URLs', () => ({ @@ -48,19 +65,30 @@ jest.mock('@/components/utils/URLs', () => ({ githubRepoURL: 'https://github.com/test/repo', }, })); + +jest.mock('../navbar-utils', () => ({ + routeList: [ + { href: '#', label: 'Home' }, + { href: '#tasks', label: 'Tasks' }, + { href: '#faq', label: 'FAQ' }, + ], + deleteAllTasks: jest.fn(), + handleLogout: jest.fn(), +})); + const mockSetIsLoading = jest.fn(); -const mockProps: Props = { - imgurl: 'http://example.com/image.png', +const baseProps: Props = { + imgurl: 'http://example.com/avatar.png', email: 'test@example.com', encryptionSecret: 'secret', origin: 'http://localhost:3000', - UUID: '1234-5678', + UUID: 'uuid', tasks: [], }; -const extendedProps = { - ...mockProps, +const props = { + ...baseProps, isLoading: false, setIsLoading: mockSetIsLoading, }; @@ -69,30 +97,28 @@ describe('NavbarDesktop', () => { afterEach(() => { jest.clearAllMocks(); }); - it('renders the navigation links correctly', () => { - render(); + + it('renders navigation links', () => { + render(); routeList.forEach((route) => { expect(screen.getByText(route.label)).toBeInTheDocument(); }); }); - it('opens user menu and displays email', async () => { - render(); - const avatarFallback = screen.getByText('CN'); - await userEvent.click(avatarFallback); + it('opens user menu and shows email', async () => { + render(); - expect(screen.getAllByText('test@example.com')[0]).toBeInTheDocument(); + await userEvent.click(screen.getByText('CN')); + expect(screen.getAllByText('test@example.com').length).toBeGreaterThan(0); }); - it('opens github link when clicked', async () => { + it('opens GitHub repo in new tab', async () => { const openSpy = jest.spyOn(window, 'open').mockImplementation(() => null); - const user = userEvent.setup(); - render(); - - await user.click(screen.getByText('CN')); - await user.click(screen.getByText('GitHub')); + render(); + await userEvent.click(screen.getByText('CN')); + await userEvent.click(screen.getByText('GitHub')); expect(openSpy).toHaveBeenCalledWith( 'https://github.com/test/repo', @@ -101,46 +127,40 @@ describe('NavbarDesktop', () => { openSpy.mockRestore(); }); - it('exports tasks as TXT and triggers export handler', async () => { - const user = userEvent.setup(); - const { exportTasksAsTXT } = require('@/components/utils/ExportTasks'); - - render(); - await user.click(screen.getByText('CN')); - await user.click(screen.getByText('Export tasks')); - - expect(screen.getByText(/Would you like to download/i)).toBeInTheDocument(); + it('exports tasks as TXT', async () => { + const { exportTasksAsTXT } = require('@/components/utils/ExportTasks'); - await user.click(screen.getByText('Download .txt')); + render(); + await userEvent.click(screen.getByText('CN')); + await userEvent.click(screen.getByText('Export tasks')); + await userEvent.click(screen.getByText('Download .txt')); expect(exportTasksAsTXT).toHaveBeenCalledWith([]); }); + it('exports tasks as JSON', async () => { const { exportTasksAsJSON } = require('@/components/utils/ExportTasks'); - render(); - + render(); await userEvent.click(screen.getByText('CN')); await userEvent.click(screen.getByText('Export tasks')); await userEvent.click(screen.getByText('Download .json')); expect(exportTasksAsJSON).toHaveBeenCalledWith([]); }); - it('shows slider when auto sync is enabled', async () => { - const user = userEvent.setup(); - render(); - await user.click(screen.getByText('CN')); - await user.click(screen.getByText('toggle')); + it('enables auto sync and shows slider', async () => { + render(); + + await userEvent.click(screen.getByText('CN')); + await userEvent.click(screen.getByText('toggle')); expect(screen.getByTestId('sync-slider')).toBeInTheDocument(); }); -}); -describe('NavbarDesktop snapshot', () => { - it('renders correctly', () => { - const { asFragment } = render(); + it('renders consistently (snapshot)', () => { + const { asFragment } = render(); expect(asFragment()).toMatchSnapshot(); }); }); diff --git a/frontend/src/components/HomeComponents/Navbar/__tests__/__snapshots__/NavbarDesktop.test.tsx.snap b/frontend/src/components/HomeComponents/Navbar/__tests__/__snapshots__/NavbarDesktop.test.tsx.snap index 72a1291c..4a8e3e30 100644 --- a/frontend/src/components/HomeComponents/Navbar/__tests__/__snapshots__/NavbarDesktop.test.tsx.snap +++ b/frontend/src/components/HomeComponents/Navbar/__tests__/__snapshots__/NavbarDesktop.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`NavbarDesktop snapshot renders correctly 1`] = ` +exports[`NavbarDesktop renders consistently (snapshot) 1`] = `