UDT-002: Logout + Refresh Token con rotación y chain revocation #3

Merged
dmolinari merged 36 commits from feature/UDT-002 into main 2026-04-14 17:37:47 +00:00
Showing only changes of commit dd4f4dbd5e - Show all commits

View File

@@ -37,7 +37,8 @@ const server = setupServer(
beforeAll(() => server.listen({ onUnhandledRequest: 'error' })) beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
afterEach(() => { afterEach(() => {
server.resetHandlers() server.resetHandlers()
useAuthStore.getState().logout() // Use clearAuth (sync) to avoid triggering API logout call in tests
useAuthStore.getState().clearAuth()
localStorage.clear() localStorage.clear()
mockNavigate.mockClear() mockNavigate.mockClear()
}) })
@@ -114,4 +115,28 @@ describe('LoginPage', () => {
expect(state.user?.username).toBe('admin') expect(state.user?.username).toBe('admin')
}) })
}) })
it('setAuth receives expiresIn and store calculates expiresAt correctly', async () => {
const before = Date.now()
const user = userEvent.setup()
renderLoginPage()
await user.type(screen.getByLabelText(/usuario/i), 'admin')
await user.type(screen.getByLabelText(/contraseña/i), '@Diego550@')
await user.click(screen.getByRole('button', { name: /ingresar/i }))
await waitFor(() => {
const state = useAuthStore.getState()
const after = Date.now()
// refreshToken should be persisted
expect(state.refreshToken).toBe(mockLoginResponse.refreshToken)
// expiresAt should be computed as Date.now() + expiresIn * 1000
// Allow a 2s window for test execution
expect(state.expiresAt).not.toBeNull()
expect(state.expiresAt!).toBeGreaterThanOrEqual(before + mockLoginResponse.expiresIn * 1000)
expect(state.expiresAt!).toBeLessThanOrEqual(after + mockLoginResponse.expiresIn * 1000)
})
})
}) })