/** * Authentication integration tests * Tests the full authentication flow through the API */ import { assertEquals, assertExists } from 'jsr:@std/assert'; import { describe, it, beforeAll, afterAll, beforeEach } from 'jsr:@std/testing/bdd'; import { setupTestDb, teardownTestDb, cleanupTestDb, createTestUser, post, get, assertStatus, createAuthHeader, } from '../helpers/index.ts'; describe('Auth API Integration', () => { beforeAll(async () => { await setupTestDb(); }); afterAll(async () => { await teardownTestDb(); }); beforeEach(async () => { await cleanupTestDb(); }); describe('POST /api/v1/auth/login', () => { it('should login with valid credentials', async () => { const { user, password } = await createTestUser({ email: 'api-login@example.com', status: 'active', }); const response = await post('/api/v1/auth/login', { email: user.email, password: password, }); assertStatus(response, 200); const body = response.body as Record; assertExists(body.accessToken); assertExists(body.refreshToken); assertExists(body.user); }); it('should return 401 for invalid credentials', async () => { const response = await post('/api/v1/auth/login', { email: 'nonexistent@example.com', password: 'wrongpassword', }); assertStatus(response, 401); const body = response.body as Record; assertEquals(body.error, 'INVALID_CREDENTIALS'); }); it('should return 401 for inactive user', async () => { const { user, password } = await createTestUser({ email: 'suspended@example.com', status: 'suspended', }); const response = await post('/api/v1/auth/login', { email: user.email, password: password, }); assertStatus(response, 401); const body = response.body as Record; assertEquals(body.error, 'ACCOUNT_INACTIVE'); }); }); describe('POST /api/v1/auth/refresh', () => { it('should refresh access token', async () => { const { user, password } = await createTestUser({ email: 'refresh@example.com', status: 'active', }); // Login first const loginResponse = await post('/api/v1/auth/login', { email: user.email, password: password, }); const loginBody = loginResponse.body as Record; // Refresh const refreshResponse = await post('/api/v1/auth/refresh', { refreshToken: loginBody.refreshToken, }); assertStatus(refreshResponse, 200); const refreshBody = refreshResponse.body as Record; assertExists(refreshBody.accessToken); }); it('should return 401 for invalid refresh token', async () => { const response = await post('/api/v1/auth/refresh', { refreshToken: 'invalid-token', }); assertStatus(response, 401); }); }); describe('GET /api/v1/auth/me', () => { it('should return current user info', async () => { const { user, password } = await createTestUser({ email: 'me@example.com', status: 'active', }); // Login const loginResponse = await post('/api/v1/auth/login', { email: user.email, password: password, }); const loginBody = loginResponse.body as Record; // Get current user const meResponse = await get( '/api/v1/auth/me', createAuthHeader(loginBody.accessToken as string) ); assertStatus(meResponse, 200); const meBody = meResponse.body as Record; assertEquals(meBody.email, user.email); }); it('should return 401 without token', async () => { const response = await get('/api/v1/auth/me'); assertStatus(response, 401); }); }); describe('POST /api/v1/auth/logout', () => { it('should invalidate session', async () => { const { user, password } = await createTestUser({ email: 'logout@example.com', status: 'active', }); // Login const loginResponse = await post('/api/v1/auth/login', { email: user.email, password: password, }); const loginBody = loginResponse.body as Record; const token = loginBody.accessToken as string; // Logout const logoutResponse = await post('/api/v1/auth/logout', {}, createAuthHeader(token)); assertStatus(logoutResponse, 200); // Token should no longer work const meResponse = await get('/api/v1/auth/me', createAuthHeader(token)); assertStatus(meResponse, 401); }); }); });