1+ import { render , screen } from '@testing-library/react' ;
2+ import userEvent from '@testing-library/user-event' ;
3+ import { NavbarDesktop } from '../NavbarDesktop' ;
4+ import { Props , routeList } from '../navbar-utils' ;
5+
6+ // Mock external dependencies
17jest . mock ( '@/components/ui/slider' , ( ) => ( {
2- Slider : ( ) => < div data-testid = "sync-slider" / >,
8+ Slider : ( ) => < div data-testid = "sync-slider" > slider </ div > ,
39} ) ) ;
10+
411jest . mock ( '@/components/ui/switch' , ( ) => ( {
512 Switch : ( { onCheckedChange } : any ) => (
613 < button onClick = { ( ) => onCheckedChange ( true ) } > toggle</ button >
714 ) ,
815} ) ) ;
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/dropdown-menu' , ( ) => ( {
18+ DropdownMenu : ( { children } : any ) => < div > { children } </ div > ,
19+ DropdownMenuTrigger : ( { children } : any ) => < div > { children } </ div > ,
20+ DropdownMenuContent : ( { children } : any ) => < div > { children } </ div > ,
21+ DropdownMenuItem : ( { children, onClick, onSelect } : any ) => (
22+ < div onClick = { onClick } onMouseDown = { ( e ) => onSelect ?.( e ) } >
23+ { children }
24+ </ div >
25+ ) ,
26+ DropdownMenuLabel : ( { children } : any ) => < div > { children } </ div > ,
1627} ) ) ;
28+
1729jest . mock ( '@/components/ui/dialog' , ( ) => ( {
1830 Dialog : ( { children } : any ) => < div > { children } </ div > ,
1931 DialogTrigger : ( { children } : any ) => < div > { children } </ div > ,
2032 DialogContent : ( { children } : any ) => (
21- < div data-testid = "export- dialog" > { children } </ div >
33+ < div data-testid = "dialog" > { children } </ div >
2234 ) ,
2335 DialogHeader : ( { children } : any ) => < div > { children } </ div > ,
2436 DialogTitle : ( { children } : any ) => < h2 > { children } </ h2 > ,
2537 DialogDescription : ( { children } : any ) => < p > { children } </ p > ,
2638} ) ) ;
27- import { render , screen } from '@testing-library/react' ;
28- import userEvent from '@testing-library/user-event' ;
29- import { NavbarDesktop } from '../NavbarDesktop' ;
30- import { Props , routeList } from '../navbar-utils' ;
3139
32- jest . mock ( '../navbar-utils' , ( ) => ( {
33- deleteAllTasks : jest . fn ( ) ,
34- handleLogout : jest . fn ( ) ,
35- routeList : [
36- { href : '#' , label : 'Home' } ,
37- { href : '#tasks' , label : 'Tasks' } ,
38- { href : '#setup-guide' , label : 'Setup Guide' } ,
39- { href : '#faq' , label : 'FAQ' } ,
40- ] ,
40+ jest . mock ( '@/components/ui/avatar' , ( ) => ( {
41+ Avatar : ( { children } : any ) => < div > { children } </ div > ,
42+ AvatarImage : ( ) => < img alt = "avatar" /> ,
43+ AvatarFallback : ( { children } : any ) => < button > { children } </ button > ,
44+ } ) ) ;
45+
46+ jest . mock ( '@/components/utils/ThemeModeToggle' , ( ) => ( {
47+ ModeToggle : ( ) => < div data-testid = "mode-toggle" /> ,
4148} ) ) ;
49+
4250jest . mock ( '@/components/HomeComponents/DevLogs/DevLogs' , ( ) => ( {
43- DevLogs : ( ) => < div data-testid = "dev-logs-dialog" /> ,
51+ DevLogs : ( ) => < div data-testid = "dev-logs" /> ,
52+ } ) ) ;
53+
54+ jest . mock ( '@/components/utils/TaskAutoSync' , ( ) => ( {
55+ useTaskAutoSync : jest . fn ( ) ,
56+ } ) ) ;
57+
58+ jest . mock ( '@/components/utils/ExportTasks' , ( ) => ( {
59+ exportTasksAsJSON : jest . fn ( ) ,
60+ exportTasksAsTXT : jest . fn ( ) ,
4461} ) ) ;
4562
4663jest . mock ( '@/components/utils/URLs' , ( ) => ( {
4764 url : {
4865 githubRepoURL : 'https://github.com/test/repo' ,
4966 } ,
5067} ) ) ;
68+
69+ jest . mock ( '../navbar-utils' , ( ) => ( {
70+ routeList : [
71+ { href : '#' , label : 'Home' } ,
72+ { href : '#tasks' , label : 'Tasks' } ,
73+ { href : '#faq' , label : 'FAQ' } ,
74+ ] ,
75+ deleteAllTasks : jest . fn ( ) ,
76+ handleLogout : jest . fn ( ) ,
77+ } ) ) ;
78+
5179const mockSetIsLoading = jest . fn ( ) ;
5280
53- const mockProps : Props = {
54- imgurl : 'http://example.com/image .png' ,
81+ const baseProps : Props = {
82+ imgurl : 'http://example.com/avatar .png' ,
5583 email : 'test@example.com' ,
5684 encryptionSecret : 'secret' ,
5785 origin : 'http://localhost:3000' ,
58- UUID : '1234-5678 ' ,
86+ UUID : 'uuid ' ,
5987 tasks : [ ] ,
6088} ;
6189
62- const extendedProps = {
63- ...mockProps ,
90+ const props = {
91+ ...baseProps ,
6492 isLoading : false ,
6593 setIsLoading : mockSetIsLoading ,
6694} ;
@@ -69,30 +97,28 @@ describe('NavbarDesktop', () => {
6997 afterEach ( ( ) => {
7098 jest . clearAllMocks ( ) ;
7199 } ) ;
72- it ( 'renders the navigation links correctly' , ( ) => {
73- render ( < NavbarDesktop { ...extendedProps } /> ) ;
100+
101+ it ( 'renders navigation links' , ( ) => {
102+ render ( < NavbarDesktop { ...props } /> ) ;
74103
75104 routeList . forEach ( ( route ) => {
76105 expect ( screen . getByText ( route . label ) ) . toBeInTheDocument ( ) ;
77106 } ) ;
78107 } ) ;
79- it ( 'opens user menu and displays email' , async ( ) => {
80- render ( < NavbarDesktop { ...extendedProps } /> ) ;
81108
82- const avatarFallback = screen . getByText ( 'CN' ) ;
83- await userEvent . click ( avatarFallback ) ;
109+ it ( 'opens user menu and shows email' , async ( ) => {
110+ render ( < NavbarDesktop { ... props } /> ) ;
84111
85- expect ( screen . getAllByText ( 'test@example.com' ) [ 0 ] ) . toBeInTheDocument ( ) ;
112+ await userEvent . click ( screen . getByText ( 'CN' ) ) ;
113+ expect ( screen . getAllByText ( 'test@example.com' ) . length ) . toBeGreaterThan ( 0 ) ;
86114 } ) ;
87115
88- it ( 'opens github link when clicked ' , async ( ) => {
116+ it ( 'opens GitHub repo in new tab ' , async ( ) => {
89117 const openSpy = jest . spyOn ( window , 'open' ) . mockImplementation ( ( ) => null ) ;
90118
91- const user = userEvent . setup ( ) ;
92- render ( < NavbarDesktop { ...extendedProps } /> ) ;
93-
94- await user . click ( screen . getByText ( 'CN' ) ) ;
95- await user . click ( screen . getByText ( 'GitHub' ) ) ;
119+ render ( < NavbarDesktop { ...props } /> ) ;
120+ await userEvent . click ( screen . getByText ( 'CN' ) ) ;
121+ await userEvent . click ( screen . getByText ( 'GitHub' ) ) ;
96122
97123 expect ( openSpy ) . toHaveBeenCalledWith (
98124 'https://github.com/test/repo' ,
@@ -101,46 +127,40 @@ describe('NavbarDesktop', () => {
101127
102128 openSpy . mockRestore ( ) ;
103129 } ) ;
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 } /> ) ;
109130
110- await user . click ( screen . getByText ( 'CN' ) ) ;
111- await user . click ( screen . getByText ( 'Export tasks' ) ) ;
112-
113- expect ( screen . getByText ( / W o u l d y o u l i k e t o d o w n l o a d / i) ) . toBeInTheDocument ( ) ;
131+ it ( 'exports tasks as TXT' , async ( ) => {
132+ const { exportTasksAsTXT } = require ( '@/components/utils/ExportTasks' ) ;
114133
115- await user . click ( screen . getByText ( 'Download .txt' ) ) ;
134+ render ( < NavbarDesktop { ...props } /> ) ;
135+ await userEvent . click ( screen . getByText ( 'CN' ) ) ;
136+ await userEvent . click ( screen . getByText ( 'Export tasks' ) ) ;
137+ await userEvent . click ( screen . getByText ( 'Download .txt' ) ) ;
116138
117139 expect ( exportTasksAsTXT ) . toHaveBeenCalledWith ( [ ] ) ;
118140 } ) ;
141+
119142 it ( 'exports tasks as JSON' , async ( ) => {
120143 const { exportTasksAsJSON } = require ( '@/components/utils/ExportTasks' ) ;
121144
122- render ( < NavbarDesktop { ...extendedProps } /> ) ;
123-
145+ render ( < NavbarDesktop { ...props } /> ) ;
124146 await userEvent . click ( screen . getByText ( 'CN' ) ) ;
125147 await userEvent . click ( screen . getByText ( 'Export tasks' ) ) ;
126148 await userEvent . click ( screen . getByText ( 'Download .json' ) ) ;
127149
128150 expect ( exportTasksAsJSON ) . toHaveBeenCalledWith ( [ ] ) ;
129151 } ) ;
130- it ( 'shows slider when auto sync is enabled' , async ( ) => {
131- const user = userEvent . setup ( ) ;
132- render ( < NavbarDesktop { ...extendedProps } /> ) ;
133152
134- await user . click ( screen . getByText ( 'CN' ) ) ;
135- await user . click ( screen . getByText ( 'toggle' ) ) ;
153+ it ( 'enables auto sync and shows slider' , async ( ) => {
154+ render ( < NavbarDesktop { ...props } /> ) ;
155+
156+ await userEvent . click ( screen . getByText ( 'CN' ) ) ;
157+ await userEvent . click ( screen . getByText ( 'toggle' ) ) ;
136158
137159 expect ( screen . getByTestId ( 'sync-slider' ) ) . toBeInTheDocument ( ) ;
138160 } ) ;
139- } ) ;
140161
141- describe ( 'NavbarDesktop snapshot' , ( ) => {
142- it ( 'renders correctly' , ( ) => {
143- const { asFragment } = render ( < NavbarDesktop { ...extendedProps } /> ) ;
162+ it ( 'renders consistently (snapshot)' , ( ) => {
163+ const { asFragment } = render ( < NavbarDesktop { ...props } /> ) ;
144164 expect ( asFragment ( ) ) . toMatchSnapshot ( ) ;
145165 } ) ;
146166} ) ;
0 commit comments