Skip to content

Commit c528265

Browse files
GraysonCAdamsclaude
andcommitted
Add unit and integration tests for core modules and API routes
Unit tests for utils, crypto, rate-limit, env validation, and notification prefs. Integration tests for health, tracks, and reactions API routes using in-memory PGlite. Disable max-lines and no-explicit-any lint rules for test files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e952c8c commit c528265

9 files changed

Lines changed: 1651 additions & 0 deletions

File tree

eslint.config.mjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ const eslintConfig = defineConfig([
2626
'max-lines': ['warn', { max: 300, skipBlankLines: true, skipComments: true }],
2727
},
2828
},
29+
{
30+
files: ['**/*.test.ts', 'src/test/**/*.ts'],
31+
rules: {
32+
'max-lines': 'off',
33+
'@typescript-eslint/no-explicit-any': 'off',
34+
},
35+
},
2936
]);
3037

3138
export default eslintConfig;

src/app/api/health/route.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest';
2+
import { setupTestDb, teardownTestDb } from '@/test/db-setup';
3+
4+
// Mock logger to suppress output
5+
vi.mock('@/lib/logger', () => ({
6+
logger: { error: vi.fn(), warn: vi.fn(), info: vi.fn(), debug: vi.fn() },
7+
}));
8+
9+
describe('GET /api/health', () => {
10+
beforeAll(async () => {
11+
const testDb = await setupTestDb();
12+
vi.doMock('@/db', () => ({ db: testDb }));
13+
});
14+
15+
afterAll(async () => {
16+
await teardownTestDb();
17+
});
18+
19+
it('returns 200 when DB is reachable', async () => {
20+
const { GET } = await import('./route');
21+
const response = await GET();
22+
expect(response.status).toBe(200);
23+
const data = await response.json();
24+
expect(data.status).toBe('ok');
25+
});
26+
27+
it('returns 503 when DB throws', async () => {
28+
vi.doMock('@/db', () => ({
29+
db: {
30+
select: () => ({
31+
from: () => ({
32+
limit: () => {
33+
throw new Error('connection refused');
34+
},
35+
}),
36+
}),
37+
},
38+
}));
39+
40+
// Dynamic import picks up the new mock
41+
const { GET } = await import('./route');
42+
const response = await GET();
43+
expect(response.status).toBe(503);
44+
const data = await response.json();
45+
expect(data.status).toBe('error');
46+
expect(data.message).toBe('Database unreachable');
47+
});
48+
});

0 commit comments

Comments
 (0)