Skip to content

Commit ba9999e

Browse files
committed
test(auth): update AuthContext tests for toast-based session expiry
1 parent cd3b625 commit ba9999e

1 file changed

Lines changed: 40 additions & 3 deletions

File tree

frontend/src/context/__tests__/AuthContext.test.tsx

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { act, render, screen, waitFor } from '@testing-library/react'
2+
import { toast } from 'react-hot-toast'
23
import { describe, it, expect, beforeEach, vi } from 'vitest'
34

45
import client, { setAuthToken, setAuthErrorHandler } from '../../api/client'
@@ -7,6 +8,13 @@ import { useAuth } from '../../hooks/useAuth'
78

89
const TOKEN_KEY = 'charon_auth_token'
910

11+
vi.mock('react-hot-toast', () => ({
12+
toast: {
13+
error: vi.fn(),
14+
dismiss: vi.fn(),
15+
},
16+
}))
17+
1018
vi.mock('../../api/client', () => ({
1119
default: {
1220
post: vi.fn().mockResolvedValue({}),
@@ -19,6 +27,7 @@ vi.mock('../../api/client', () => ({
1927
const mockClient = vi.mocked(client)
2028
const mockSetAuthToken = vi.mocked(setAuthToken)
2129
const mockSetAuthErrorHandler = vi.mocked(setAuthErrorHandler)
30+
const mockToast = vi.mocked(toast)
2231

2332
const AuthStateProbe = () => {
2433
const { user, isAuthenticated, isLoading } = useAuth()
@@ -83,10 +92,9 @@ describe('<AuthProvider /> session validation on mount (page reload)', () => {
8392
expect(mockSetAuthToken).toHaveBeenCalledWith('valid-token')
8493
})
8594

86-
it('registers an auth-error handler that clears the session, and unregisters it on unmount', async () => {
95+
it('registers an auth-error handler that clears the session, shows a toast, and unregisters on unmount', async () => {
8796
localStorage.setItem(TOKEN_KEY, 'valid-token')
8897
mockClient.get.mockResolvedValue({ data: sessionUser, status: 200 })
89-
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
9098

9199
const { unmount } = renderProvider()
92100
await waitFor(() => expect(screen.getByTestId('authenticated').textContent).toBe('true'))
@@ -99,10 +107,39 @@ describe('<AuthProvider /> session validation on mount (page reload)', () => {
99107
await waitFor(() => expect(screen.getByTestId('authenticated').textContent).toBe('false'))
100108
expect(localStorage.getItem(TOKEN_KEY)).toBeNull()
101109
expect(mockSetAuthToken).toHaveBeenLastCalledWith(null)
110+
expect(mockToast.error).toHaveBeenCalledWith(
111+
'Session expired. Please log in again.',
112+
expect.objectContaining({ id: 'auth-session-expired' })
113+
)
102114

103115
unmount()
104116
expect(mockSetAuthErrorHandler).toHaveBeenLastCalledWith(null)
117+
})
118+
119+
it('dismisses the session-expired toast when login succeeds', async () => {
120+
mockClient.get.mockResolvedValue({ data: sessionUser, status: 200 })
105121

106-
warnSpy.mockRestore()
122+
let loginFn: ((token?: string) => Promise<void>) | undefined
123+
const LoginProbe = () => {
124+
const { login } = useAuth()
125+
loginFn = login
126+
return null
127+
}
128+
129+
render(
130+
<AuthProvider>
131+
<LoginProbe />
132+
<AuthStateProbe />
133+
</AuthProvider>
134+
)
135+
136+
await waitFor(() => expect(screen.getByTestId('loading').textContent).toBe('false'))
137+
138+
await act(async () => {
139+
await loginFn?.('new-token')
140+
})
141+
142+
expect(mockToast.dismiss).toHaveBeenCalledWith('auth-session-expired')
143+
expect(screen.getByTestId('authenticated').textContent).toBe('true')
107144
})
108145
})

0 commit comments

Comments
 (0)