Files
dttmr-fe/src/stores/__tests__/auth.spec.ts
T
2026-08-21 17:09:32 +02:00

192 lines
6.9 KiB
TypeScript

import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useAuthStore } from '../auth'
import * as authApi from '@/api/auth'
describe('useAuthStore', () => {
beforeEach(() => {
setActivePinia(createPinia())
localStorage.clear()
vi.restoreAllMocks()
})
afterEach(() => {
localStorage.clear()
})
it('initializes with tokens from localStorage if available', () => {
localStorage.setItem('access_token', 'initial-access-token')
localStorage.setItem('refresh_token', 'initial-refresh-token')
const authStore = useAuthStore()
expect(authStore.accessToken).toBe('initial-access-token')
expect(authStore.refreshToken).toBe('initial-refresh-token')
expect(authStore.isAuthenticated).toBe(true)
})
it('initializes with null tokens if localStorage is empty', () => {
const authStore = useAuthStore()
expect(authStore.accessToken).toBeNull()
expect(authStore.refreshToken).toBeNull()
expect(authStore.isAuthenticated).toBe(false)
})
it('successfully logs in and stores tokens in state and localStorage', async () => {
const mockTokenPair = {
access_token: 'new-access-token',
refresh_token: 'new-refresh-token',
}
vi.spyOn(authApi, 'loginApi').mockResolvedValueOnce(mockTokenPair)
const authStore = useAuthStore()
const result = await authStore.login({
email: 'test@example.com',
password: 'password123',
})
expect(result).toEqual(mockTokenPair)
expect(authStore.accessToken).toBe('new-access-token')
expect(authStore.refreshToken).toBe('new-refresh-token')
expect(authStore.isAuthenticated).toBe(true)
expect(localStorage.getItem('access_token')).toBe('new-access-token')
expect(localStorage.getItem('refresh_token')).toBe('new-refresh-token')
expect(authStore.error).toBeNull()
})
it('handles login failure and sets error message', async () => {
vi.spyOn(authApi, 'loginApi').mockRejectedValueOnce(new Error('Invalid credentials'))
const authStore = useAuthStore()
await expect(
authStore.login({
email: 'test@example.com',
password: 'wrong-password',
}),
).rejects.toThrow('Invalid credentials')
expect(authStore.accessToken).toBeNull()
expect(authStore.refreshToken).toBeNull()
expect(authStore.isAuthenticated).toBe(false)
expect(authStore.error).toBe('Invalid credentials')
})
it('refreshes tokens successfully and updates state and localStorage', async () => {
localStorage.setItem('access_token', 'old-access-token')
localStorage.setItem('refresh_token', 'old-refresh-token')
const authStore = useAuthStore()
const refreshedTokenPair = {
access_token: 'refreshed-access-token',
refresh_token: 'refreshed-refresh-token',
}
const refreshSpy = vi.spyOn(authApi, 'refreshApi').mockResolvedValueOnce(refreshedTokenPair)
const result = await authStore.refreshTokens()
expect(refreshSpy).toHaveBeenCalledWith({ refresh_token: 'old-refresh-token' })
expect(result).toEqual(refreshedTokenPair)
expect(authStore.accessToken).toBe('refreshed-access-token')
expect(authStore.refreshToken).toBe('refreshed-refresh-token')
expect(localStorage.getItem('access_token')).toBe('refreshed-access-token')
expect(localStorage.getItem('refresh_token')).toBe('refreshed-refresh-token')
})
it('clears tokens and throws if refreshTokens is called without a refresh token', async () => {
const authStore = useAuthStore()
await expect(authStore.refreshTokens()).rejects.toThrow('No refresh token available')
expect(authStore.accessToken).toBeNull()
expect(authStore.refreshToken).toBeNull()
})
it('clears tokens and sets error when refresh API call fails', async () => {
localStorage.setItem('access_token', 'old-access-token')
localStorage.setItem('refresh_token', 'expired-refresh-token')
const authStore = useAuthStore()
vi.spyOn(authApi, 'refreshApi').mockRejectedValueOnce(new Error('Refresh token expired'))
await expect(authStore.refreshTokens()).rejects.toThrow('Refresh token expired')
expect(authStore.accessToken).toBeNull()
expect(authStore.refreshToken).toBeNull()
expect(authStore.error).toBe('Refresh token expired')
expect(localStorage.getItem('access_token')).toBeNull()
expect(localStorage.getItem('refresh_token')).toBeNull()
})
it('clears tokens and calls logout API on logout', async () => {
localStorage.setItem('access_token', 'sample-access')
localStorage.setItem('refresh_token', 'sample-refresh')
const authStore = useAuthStore()
expect(authStore.isAuthenticated).toBe(true)
const logoutSpy = vi.spyOn(authApi, 'logoutApi').mockResolvedValueOnce()
await authStore.logout()
expect(logoutSpy).toHaveBeenCalledWith({ refresh_token: 'sample-refresh' })
expect(authStore.accessToken).toBeNull()
expect(authStore.refreshToken).toBeNull()
expect(authStore.isAuthenticated).toBe(false)
expect(localStorage.getItem('access_token')).toBeNull()
expect(localStorage.getItem('refresh_token')).toBeNull()
})
it('still clears tokens if logout API fails', async () => {
localStorage.setItem('access_token', 'sample-access')
localStorage.setItem('refresh_token', 'sample-refresh')
const authStore = useAuthStore()
vi.spyOn(authApi, 'logoutApi').mockRejectedValueOnce(new Error('Network error'))
await authStore.logout()
expect(authStore.accessToken).toBeNull()
expect(authStore.refreshToken).toBeNull()
expect(authStore.isAuthenticated).toBe(false)
expect(localStorage.getItem('access_token')).toBeNull()
expect(localStorage.getItem('refresh_token')).toBeNull()
})
it('clears tokens and calls logoutAll API on logoutAll', async () => {
localStorage.setItem('access_token', 'sample-access')
localStorage.setItem('refresh_token', 'sample-refresh')
const authStore = useAuthStore()
const logoutAllSpy = vi.spyOn(authApi, 'logoutAllApi').mockResolvedValueOnce()
await authStore.logoutAll()
expect(logoutAllSpy).toHaveBeenCalledWith('sample-access')
expect(authStore.accessToken).toBeNull()
expect(authStore.refreshToken).toBeNull()
expect(authStore.isAuthenticated).toBe(false)
expect(localStorage.getItem('access_token')).toBeNull()
expect(localStorage.getItem('refresh_token')).toBeNull()
})
it('still clears tokens if logoutAll API fails', async () => {
localStorage.setItem('access_token', 'sample-access')
localStorage.setItem('refresh_token', 'sample-refresh')
const authStore = useAuthStore()
vi.spyOn(authApi, 'logoutAllApi').mockRejectedValueOnce(new Error('Network error'))
await authStore.logoutAll()
expect(authStore.accessToken).toBeNull()
expect(authStore.refreshToken).toBeNull()
expect(authStore.isAuthenticated).toBe(false)
expect(localStorage.getItem('access_token')).toBeNull()
expect(localStorage.getItem('refresh_token')).toBeNull()
})
})