1- import { render , screen } from '@testing-library/react'
1+ import { fireEvent , render , screen } from '@testing-library/react'
22import * as React from 'react'
33import { describe , expect , it , vi } from 'vitest'
44import { Header } from '../header'
55
6+ const mockUseAuthStatus = vi . fn <
7+ ( ) => {
8+ me : { handle ?: string ; displayName ?: string ; email ?: string } | null
9+ isLoading : boolean
10+ isAuthenticated : boolean
11+ signIn : ReturnType < typeof vi . fn >
12+ signOut : ReturnType < typeof vi . fn >
13+ }
14+ > ( ( ) => ( {
15+ me : null ,
16+ isLoading : false ,
17+ isAuthenticated : false ,
18+ signIn : vi . fn ( ) ,
19+ signOut : vi . fn ( ) ,
20+ } ) )
21+
622// Mock next/link
723vi . mock ( 'next/link' , ( ) => ( {
824 default : ( { children, href, ...props } : { children : React . ReactNode ; href : string } ) =>
@@ -17,13 +33,7 @@ vi.mock('next/navigation', () => ({
1733
1834// Mock useAuthStatus hook to simulate logged-out state
1935vi . mock ( '@/hooks/use-auth-status' , ( ) => ( {
20- useAuthStatus : ( ) => ( {
21- me : null ,
22- isLoading : false ,
23- isAuthenticated : false ,
24- signIn : vi . fn ( ) ,
25- signOut : vi . fn ( ) ,
26- } ) ,
36+ useAuthStatus : ( ) => mockUseAuthStatus ( ) ,
2737} ) )
2838
2939// Mock GithubStars component
@@ -37,13 +47,48 @@ vi.mock('@/components/search/search-autocomplete', () => ({
3747} ) )
3848
3949describe ( 'Header' , ( ) => {
50+ it ( 'shows generate and submit inside the authenticated user menu' , ( ) => {
51+ mockUseAuthStatus . mockReturnValue ( {
52+ me : {
53+ handle : 'david' ,
54+ displayName : 'David' ,
55+ email : 'david@example.com' ,
56+ } ,
57+ isLoading : false ,
58+ isAuthenticated : true ,
59+ signIn : vi . fn ( ) ,
60+ signOut : vi . fn ( ) ,
61+ } )
62+
63+ render ( < Header /> )
64+
65+ fireEvent . pointerDown ( screen . getByRole ( 'button' , { name : 'User menu' } ) )
66+
67+ expect ( screen . getByRole ( 'menuitem' , { name : 'Generate' } ) ) . toHaveAttribute ( 'href' , '/create' )
68+ expect ( screen . getByRole ( 'menuitem' , { name : 'Submit' } ) ) . toHaveAttribute ( 'href' , '/upload' )
69+ } )
70+
4071 it ( 'should render the logo' , ( ) => {
72+ mockUseAuthStatus . mockReturnValue ( {
73+ me : null ,
74+ isLoading : false ,
75+ isAuthenticated : false ,
76+ signIn : vi . fn ( ) ,
77+ signOut : vi . fn ( ) ,
78+ } )
4179 render ( < Header /> )
4280
4381 expect ( screen . getByText ( 'souls.directory' ) ) . toBeInTheDocument ( )
4482 } )
4583
4684 it ( 'should render navigation links' , ( ) => {
85+ mockUseAuthStatus . mockReturnValue ( {
86+ me : null ,
87+ isLoading : false ,
88+ isAuthenticated : false ,
89+ signIn : vi . fn ( ) ,
90+ signOut : vi . fn ( ) ,
91+ } )
4792 render ( < Header /> )
4893
4994 // Use exact name "Souls" to avoid matching the logo link "souls.directory"
@@ -53,6 +98,13 @@ describe('Header', () => {
5398 } )
5499
55100 it ( 'should render Sign Up button when logged out' , ( ) => {
101+ mockUseAuthStatus . mockReturnValue ( {
102+ me : null ,
103+ isLoading : false ,
104+ isAuthenticated : false ,
105+ signIn : vi . fn ( ) ,
106+ signOut : vi . fn ( ) ,
107+ } )
56108 render ( < Header /> )
57109
58110 // Sign Up button should be visible when user is not authenticated
@@ -61,13 +113,27 @@ describe('Header', () => {
61113 } )
62114
63115 it ( 'should have correct href for logo' , ( ) => {
116+ mockUseAuthStatus . mockReturnValue ( {
117+ me : null ,
118+ isLoading : false ,
119+ isAuthenticated : false ,
120+ signIn : vi . fn ( ) ,
121+ signOut : vi . fn ( ) ,
122+ } )
64123 render ( < Header /> )
65124
66125 const logo = screen . getByRole ( 'link' , { name : / s o u l s \. d i r e c t o r y / i } )
67126 expect ( logo ) . toHaveAttribute ( 'href' , '/' )
68127 } )
69128
70129 it ( 'should have correct hrefs for navigation links' , ( ) => {
130+ mockUseAuthStatus . mockReturnValue ( {
131+ me : null ,
132+ isLoading : false ,
133+ isAuthenticated : false ,
134+ signIn : vi . fn ( ) ,
135+ signOut : vi . fn ( ) ,
136+ } )
71137 render ( < Header /> )
72138
73139 expect ( screen . getByRole ( 'link' , { name : 'Souls' } ) ) . toHaveAttribute ( 'href' , '/souls' )
@@ -76,6 +142,13 @@ describe('Header', () => {
76142 } )
77143
78144 it ( 'should apply sticky positioning' , ( ) => {
145+ mockUseAuthStatus . mockReturnValue ( {
146+ me : null ,
147+ isLoading : false ,
148+ isAuthenticated : false ,
149+ signIn : vi . fn ( ) ,
150+ signOut : vi . fn ( ) ,
151+ } )
79152 render ( < Header /> )
80153
81154 const header = screen . getByRole ( 'banner' )
0 commit comments