// Contract tests for src/api/authService.js. Mirrors taskService.test.js: // mock the apiClient module and assert the HTTP call shape + return value. // Both login and refreshAccessToken rethrow the original error verbatim so // callers (the Pinia store) can read error.response.data.detail — verify // that the rethrow preserves the same Error instance. import { describe, it, expect, vi, beforeEach } from 'vitest' vi.mock('@/api/index.js', () => ({ default: { post: vi.fn() }, apiEndpoints: { AUTH: { LOGIN: '/api/token/', REFRESH: '/api/token/refresh/', }, }, })) import apiClient from '@/api/index.js' import { login, refreshAccessToken } from '@/api/authService.js' beforeEach(() => { vi.clearAllMocks() }) describe('login', () => { it('POSTs /api/token/ with credentials and returns response.data', async () => { apiClient.post.mockResolvedValueOnce({ data: { access: 'A', refresh: 'R' }, }) const out = await login({ username: 'alice', password: 'pw' }) expect(apiClient.post).toHaveBeenCalledTimes(1) expect(apiClient.post).toHaveBeenCalledWith('/api/token/', { username: 'alice', password: 'pw', }) expect(out).toEqual({ access: 'A', refresh: 'R' }) }) it('rethrows the original axios error (preserves error.response) on 401', async () => { const axiosError = Object.assign(new Error('Request failed'), { response: { status: 401, data: { detail: 'Invalid credentials' } }, }) apiClient.post.mockRejectedValueOnce(axiosError) await expect(login({ username: 'u', password: 'bad' })).rejects.toBe( axiosError, ) }) it('rethrows network errors that have no response attached', async () => { const netErr = new Error('Network Error') apiClient.post.mockRejectedValueOnce(netErr) await expect(login({ username: 'u', password: 'p' })).rejects.toBe(netErr) }) }) describe('refreshAccessToken', () => { it('POSTs /api/token/refresh/ with {refresh} and returns response.data', async () => { apiClient.post.mockResolvedValueOnce({ data: { access: 'NEW' } }) const out = await refreshAccessToken('OLD-REFRESH') expect(apiClient.post).toHaveBeenCalledTimes(1) expect(apiClient.post).toHaveBeenCalledWith('/api/token/refresh/', { refresh: 'OLD-REFRESH', }) expect(out).toEqual({ access: 'NEW' }) }) it('rethrows the original error when refresh fails', async () => { const axiosError = Object.assign(new Error('refresh failed'), { response: { status: 401, data: { detail: 'Token expired' } }, }) apiClient.post.mockRejectedValueOnce(axiosError) await expect(refreshAccessToken('OLD')).rejects.toBe(axiosError) }) })