/** * Integration Test: Database Constraints and Error Mapping * * Tests that the API properly handles and maps database constraint violations. */ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { ApiClient } from '../harness/api-client'; import { DockerManager } from '../harness/docker-manager'; describe('Database Constraints - API Integration', () => { let api: ApiClient; let docker: DockerManager; beforeAll(async () => { docker = DockerManager.getInstance(); await docker.start(); api = new ApiClient({ baseUrl: 'http://localhost:3101', timeout: 60000 }); await api.waitForReady(); }, 120000); afterAll(async () => { docker.stop(); }, 30000); it('should handle unique constraint violations gracefully', async () => { // This test verifies that duplicate operations are rejected // The exact behavior depends on the API implementation // Try to perform an operation that might violate uniqueness // For example, creating the same resource twice const createData = { name: 'Test League', description: 'Test', ownerId: 'test-owner', }; // First attempt should succeed or fail gracefully try { await api.post('/leagues', createData); } catch (error) { // Expected: endpoint might not exist or validation fails expect(error).toBeDefined(); } }); it('should handle foreign key constraint violations', async () => { // Try to create a resource with invalid foreign key const invalidData = { leagueId: 'non-existent-league', // Other required fields... }; await expect( api.post('/leagues/non-existent/seasons', invalidData) ).rejects.toThrow(); }); it('should provide meaningful error messages', async () => { // Test various invalid operations const operations = [ () => api.post('/races/invalid-id/results/import', { resultsFileContent: 'invalid' }), () => api.post('/leagues/invalid/seasons/invalid/publish', {}), ]; for (const operation of operations) { try { await operation(); throw new Error('Expected operation to fail'); } catch (error) { // Should throw an error expect(error).toBeDefined(); } } }); it('should maintain data integrity after failed operations', async () => { // Verify that failed operations don't corrupt data const initialHealth = await api.health(); expect(initialHealth).toBe(true); // Try some invalid operations try { await api.post('/races/invalid/results/import', { resultsFileContent: 'invalid' }); } catch {} // Verify API is still healthy const finalHealth = await api.health(); expect(finalHealth).toBe(true); }); it('should handle concurrent operations safely', async () => { // Test that concurrent requests don't cause issues const concurrentRequests = Array(5).fill(null).map(() => api.post('/races/invalid-id/results/import', { resultsFileContent: JSON.stringify([{ invalid: 'data' }]) }) ); const results = await Promise.allSettled(concurrentRequests); // At least some should fail (since they're invalid) const failures = results.filter(r => r.status === 'rejected'); expect(failures.length).toBeGreaterThan(0); }); });