/** * Regression test: tests must not pollute the production default DB path. * * Bug: `auth-security.test.ts` and `security-fixes.test.ts` called `getDb()` * without first calling `initDatabase(uniquePath)`. Since `getDb()` falls back * to `resolveDefaultPath()` → `tmpdir()/rcs-dev.db` when the singleton is null, * tests wrote real admin users into `/tmp/rcs-dev.db`. When the user later * started the RCS server, `getDb()` resolved to the same file, so: * - /web/auth/setup-status returned needsSetup=false (users table not empty) * - login failed (password hash from test data didn't match user's password) * * Fix: every test file's freshDb()/setupTestDb() must call * `initDatabase(uniquePath)` before any `getDb()` call, so the singleton * points to a unique temp file, not the production default. */ import { describe, test, expect } from 'bun:test' import { readFileSync, existsSync } from 'node:fs' import { resolve } from 'node:path' const TESTS_DIR = import.meta.dir function readTest(filename: string): string { return readFileSync(resolve(TESTS_DIR, filename), 'utf8') } describe('测试不应污染生产默认 DB 路径', () => { const POLLUTING_FILES = [ 'auth-security.test.ts', 'security-fixes.test.ts', 'auth-login.test.ts', 'team-filter-api.test.ts', 'route-mounting.test.ts', ] for (const file of POLLUTING_FILES) { test(`${file} 的 freshDb/setupTestDb 必须先 initDatabase(uniquePath) 再 getDb()`, () => { const src = readTest(file) // 禁止:调 getDb() 但没先 initDatabase(path) — 会污染 /tmp/rcs-dev.db // 检查文件里是否有 initDatabase 调用且带 path 参数 expect(src).toMatch(/initDatabase\(/) // 不能只调 getDb() 不带前置 initDatabase(uniquePath) // 简单启发式:setupTestDb/freshDb 函数体里必须出现 initDatabase const setupMatch = src.match( /function\s+(?:freshDb|setupTestDb)\s*\([^)]*\)\s*(?::\s*[^{]+)?\{[^}]*\}/, ) if (setupMatch) { const body = setupMatch[0] if (body.includes('getDb')) { // 如果 setup 函数调用了 getDb,必须也调用 initDatabase(path) expect(body).toMatch(/initDatabase\(/) } } }) } test('helpers/db.ts 的 freshDb 用唯一 path 调 initDatabase', () => { const src = readTest('helpers/db.ts') expect(src).toMatch(/initDatabase\(/) expect(src).toMatch(/randomUUID|crypto\.randomUUID/) }) })