/** * Smoke test · API Key 模型检测接口 * * 测试 POST /api/ps/apikey/detect-models 和 POST /api/ps/apikey/chat * 的输入验证与错误处理逻辑 */ const http = require('http'); const BASE = process.env.TEST_BASE || 'http://localhost:3002'; function post(path, body) { return new Promise((resolve, reject) => { const url = new URL(BASE + path); const data = JSON.stringify(body); const options = { hostname: url.hostname, port: url.port, path: url.pathname, method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) }, timeout: 10000 }; const req = http.request(options, (res) => { let chunks = ''; res.on('data', (c) => { chunks += c; }); res.on('end', () => { try { resolve({ status: res.statusCode, body: JSON.parse(chunks) }); } catch { resolve({ status: res.statusCode, body: chunks }); } }); }); req.on('error', reject); req.write(data); req.end(); }); } describe('POST /api/ps/apikey/detect-models', () => { test('returns MISSING_API_BASE when api_base is missing', async () => { const res = await post('/api/ps/apikey/detect-models', {}); expect(res.status).toBe(400); expect(res.body.error).toBe(true); expect(res.body.code).toBe('MISSING_API_BASE'); }); test('returns MISSING_API_KEY when api_key is missing', async () => { const res = await post('/api/ps/apikey/detect-models', { api_base: 'https://example.com' }); expect(res.status).toBe(400); expect(res.body.error).toBe(true); expect(res.body.code).toBe('MISSING_API_KEY'); }); test('returns error for unreachable API base', async () => { const res = await post('/api/ps/apikey/detect-models', { api_base: 'http://invalid.test.local', api_key: 'sk-test-invalid' }); expect(res.status).toBe(502); expect(res.body.error).toBe(true); expect(res.body.code).toBe('DETECT_FAILED'); }); }); describe('POST /api/ps/apikey/chat', () => { test('returns MISSING_PARAMS when required fields are missing', async () => { const res = await post('/api/ps/apikey/chat', {}); expect(res.status).toBe(400); expect(res.body.error).toBe(true); expect(res.body.code).toBe('MISSING_PARAMS'); }); test('returns MISSING_MESSAGES when messages array is missing', async () => { const res = await post('/api/ps/apikey/chat', { api_base: 'https://example.com', api_key: 'sk-test', model: 'gpt-4' }); expect(res.status).toBe(400); expect(res.body.error).toBe(true); expect(res.body.code).toBe('MISSING_MESSAGES'); }); }); describe('POST /api/ps/auth/login (dev_id still works)', () => { test('EXP-000 dev_id login succeeds', async () => { const res = await post('/api/ps/auth/login', { dev_id: 'EXP-000' }); expect(res.status).toBe(200); expect(res.body.error).toBe(false); expect(res.body.dev_id).toBe('EXP-000'); expect(res.body.token).toBeTruthy(); }); test('invalid dev_id is rejected', async () => { const res = await post('/api/ps/auth/login', { dev_id: 'INVALID' }); expect(res.status).toBe(400); expect(res.body.error).toBe(true); }); });