import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import os from 'os'; import path from 'path'; import type { Server } from 'http'; process.env.DB_PATH = path.join(os.tmpdir(), `ai-review-bs-${Date.now()}-${Math.random().toString(36).slice(2)}.db`); let server: Server; let token = ''; let projectId = ''; const BASE = 'http://localhost:18906'; async function api(method: string, p: string, body?: any): Promise<{ status: number; data: any }> { const res = await fetch(`${BASE}${p}`, { method, headers: { 'Content-Type': 'application/json', ...(token ? { Authorization: `Bearer ${token}` } : {}) }, body: body ? JSON.stringify(body) : undefined, }); const text = await res.text(); let data: any; try { data = JSON.parse(text); } catch { data = text; } return { status: res.status, data }; } beforeAll(async () => { const mod = await import('../index'); const { config } = await import('../config'); server = mod.app.listen(18906); await fetch(`${BASE}/api/health`); const login = await api('POST', '/api/auth/login', { password: config.authPassword }); token = login.data.token; const proj = await api('POST', '/api/projects', { name: 'build-status-proj', track: '赛道二' }); projectId = proj.data.id; }); afterAll(async () => { try { await api('DELETE', `/api/projects/${projectId}?force=true`); } catch { } server?.close(); }); describe('build_status(赛道二/人才测评 单阶段人工构建确认,§2.2 扩展)', () => { it('创建条目可带 build_status=done/failed,并持久化', async () => { const r = await api('POST', `/api/projects/${projectId}/entries`, { title: 'bs-done', repo_url: `file://D:\\bs-${Date.now()}`, build_status: 'done', }); expect(r.status).toBe(200); expect(r.data.build_status).toBe('done'); }); it('创建条目带非法 build_status → 400', async () => { const r = await api('POST', `/api/projects/${projectId}/entries`, { title: 'bs-bad', repo_url: `file://D:\\bs-${Date.now()}`, build_status: 'maybe', }); expect(r.status).toBe(400); expect(String(r.data.error)).toContain('构建结果'); }); it('PUT 更新 build_status', async () => { const c = await api('POST', `/api/projects/${projectId}/entries`, { title: 'bs-edit', repo_url: `file://D:\\bs-${Date.now()}`, }); const r = await api('PUT', `/api/projects/${projectId}/entries/${c.data.id}`, { build_status: 'failed' }); expect(r.status).toBe(200); expect(r.data.build_status).toBe('failed'); }); it('缺省 build_status 为空字符串', async () => { const c = await api('POST', `/api/projects/${projectId}/entries`, { title: 'bs-default', repo_url: `file://D:\\bs-${Date.now()}`, }); expect(c.data.build_status).toBe(''); }); });