import test from 'node:test'; import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import { createServer } from 'node:http'; import { once } from 'node:events'; import { createLibraryApi } from '../server/library-api.mjs'; import { createIndustryApi } from '../server/industry-api.mjs'; const config = process.env.KSF_TEST_UNIFIED_CONFIG; test('unified HTTP runtime: auth, real PG reads, restart, no SQLite fallback', { skip: !config, timeout: 120000 }, async t => { const target = JSON.parse(await readFile(config, 'utf8')); assert.equal(target.connection.host, '127.0.0.1'); assert.equal(target.connection.port, 55439); const python = process.env.KSF_LIBRARY_PYTHON || 'python3'; const token = 'local-test-only-token'; async function serve(factory, options = {}) { const handler = factory({ unifiedConfig: config, python, token, monitoringStore: process.env.KSF_TEST_MONITORING_STORE || 'unused-asset-root', ...options }); const server = createServer(handler); server.on('close', handler.close); server.listen(0, '127.0.0.1'); await once(server, 'listening'); const close = () => new Promise(resolve => { handler.close(); server.close(resolve); }); t.after(close); return { url: `http://127.0.0.1:${server.address().port}`, close }; } const library = await serve(createLibraryApi); const call = async (url, request, authorized = true) => { const r = await fetch(url, { method: 'POST', headers: { 'content-type': 'application/json', ...(authorized ? {authorization: `Bearer ${token}`} : {}) }, body: JSON.stringify(request) }); return { status: r.status, body: await r.json() }; }; assert.equal((await call(library.url, { op: 'summary' }, false)).status, 401); const summary = await call(library.url, { op: 'summary' }); assert.equal(summary.status, 200); assert.equal(summary.body.ok, true); const detail = await call(library.url, { op: 'browse', entity: 'products', keyword: '拌面' }); assert.equal(detail.body.ok, true); assert.ok(detail.body.records.length > 0); assert.equal(detail.body.generation, summary.body.generation); assert.equal(JSON.stringify(detail.body).includes(token), false); const industry = await serve(createIndustryApi); assert.equal((await call(industry.url, {op: 'contract'})).body.ok, true); await library.close(); const restarted = await serve(createLibraryApi); assert.deepEqual((await call(restarted.url, {op: 'summary'})).body, summary.body); const broken = await serve(createLibraryApi, {unifiedConfig: config + '.missing', db: 'old-library.sqlite'}); const failure = await call(broken.url, {op: 'summary'}); assert.equal(failure.body.ok, false); assert.notEqual(failure.status, 200); assert.equal(JSON.stringify(failure.body).includes('old-library.sqlite'), false); });