unified-runtime.test.mjs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import test from 'node:test';
  2. import assert from 'node:assert/strict';
  3. import { readFile } from 'node:fs/promises';
  4. import { createServer } from 'node:http';
  5. import { once } from 'node:events';
  6. import { createLibraryApi } from '../server/library-api.mjs';
  7. import { createIndustryApi } from '../server/industry-api.mjs';
  8. const config = process.env.KSF_TEST_UNIFIED_CONFIG;
  9. test('unified HTTP runtime: auth, real PG reads, restart, no SQLite fallback', { skip: !config, timeout: 120000 }, async t => {
  10. const target = JSON.parse(await readFile(config, 'utf8'));
  11. assert.equal(target.connection.host, '127.0.0.1');
  12. assert.equal(target.connection.port, 55439);
  13. const python = process.env.KSF_LIBRARY_PYTHON || 'python3';
  14. const token = 'local-test-only-token';
  15. async function serve(factory, options = {}) {
  16. const handler = factory({ unifiedConfig: config, python, token, monitoringStore: process.env.KSF_TEST_MONITORING_STORE || 'unused-asset-root', ...options });
  17. const server = createServer(handler);
  18. server.on('close', handler.close);
  19. server.listen(0, '127.0.0.1'); await once(server, 'listening');
  20. const close = () => new Promise(resolve => { handler.close(); server.close(resolve); });
  21. t.after(close);
  22. return { url: `http://127.0.0.1:${server.address().port}`, close };
  23. }
  24. const library = await serve(createLibraryApi);
  25. const call = async (url, request, authorized = true) => {
  26. const r = await fetch(url, { method: 'POST', headers: { 'content-type': 'application/json', ...(authorized ? {authorization: `Bearer ${token}`} : {}) }, body: JSON.stringify(request) });
  27. return { status: r.status, body: await r.json() };
  28. };
  29. assert.equal((await call(library.url, { op: 'summary' }, false)).status, 401);
  30. const summary = await call(library.url, { op: 'summary' });
  31. assert.equal(summary.status, 200); assert.equal(summary.body.ok, true);
  32. const detail = await call(library.url, { op: 'browse', entity: 'products', keyword: '拌面' });
  33. assert.equal(detail.body.ok, true); assert.ok(detail.body.records.length > 0);
  34. assert.equal(detail.body.generation, summary.body.generation);
  35. assert.equal(JSON.stringify(detail.body).includes(token), false);
  36. const industry = await serve(createIndustryApi);
  37. assert.equal((await call(industry.url, {op: 'contract'})).body.ok, true);
  38. await library.close();
  39. const restarted = await serve(createLibraryApi);
  40. assert.deepEqual((await call(restarted.url, {op: 'summary'})).body, summary.body);
  41. const broken = await serve(createLibraryApi, {unifiedConfig: config + '.missing', db: 'old-library.sqlite'});
  42. const failure = await call(broken.url, {op: 'summary'});
  43. assert.equal(failure.body.ok, false); assert.notEqual(failure.status, 200);
  44. assert.equal(JSON.stringify(failure.body).includes('old-library.sqlite'), false);
  45. });