import assert from 'node:assert/strict'; import type { AddressInfo } from 'node:net'; import test from 'node:test'; import type { Pool } from 'pg'; import { createApp } from '../src/app.js'; import { loadConfig } from '../src/config/env.js'; const config = loadConfig({ NODE_ENV: 'test', HOST: '127.0.0.1', PORT: '4400', DATABASE_URL: 'postgres://runtime:password@127.0.0.1:5432/saas_voc', PARSE_APP_ID: 'test-app-id', PARSE_MASTER_KEY: 'a'.repeat(32), PARSE_MAINTENANCE_KEY: 'b'.repeat(32), PARSE_SERVER_URL: 'http://127.0.0.1:4400/parse', FMODE_BASE_URL: 'http://127.0.0.1:3000/api/voc-e-commerce', FMODE_API_KEY: 'test-key', CORS_ORIGINS: 'http://127.0.0.1:4300', }); function createMockPool(): Pool { return { async query(text: string) { if (text.includes('to_regclass')) { return { rows: [{ schema_ready: 'voc.workspace' }], rowCount: 1 }; } if (text.includes('WITH target_workspace')) { return { rows: [{ public_id: '11111111-1111-4111-8111-111111111111', workspace_public_id: 'demashi', platform: 'jd', status: 'pending', scopes: ['product', 'reviews'], product_ids: ['11266507445'], progress: 0, attempts: 0, max_attempts: 3, error_summary: null, requested_at: '2026-07-23T00:00:00.000Z', started_at: null, completed_at: null, }], rowCount: 1, }; } if (text.includes('FROM voc.workspace')) { return { rows: [{ id: '1', public_id: 'demashi', case_name: 'Demashi' }], rowCount: 1 }; } return { rows: [], rowCount: 0 }; }, } as unknown as Pool; } test('HTTP surface exposes health, empty snapshot, and sync queue contract', async () => { const app = createApp({ config, pool: createMockPool() }); const server = await new Promise>((resolve) => { const listening = app.listen(0, '127.0.0.1', () => resolve(listening)); }); try { const address = server.address() as AddressInfo; const baseUrl = `http://127.0.0.1:${address.port}`; const health = await fetch(`${baseUrl}/health`); assert.equal(health.status, 200); assert.equal((await health.json() as { database: string }).database, 'ready'); const snapshot = await fetch(`${baseUrl}/api/domestic-voc/snapshot?workspaceId=demashi&platform=jd`); assert.equal(snapshot.status, 200); assert.deepEqual((await snapshot.json() as { products: unknown[] }).products, []); const sync = await fetch(`${baseUrl}/api/domestic-voc/sync`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ productIds: ['11266507445'] }), }); assert.equal(sync.status, 202); assert.equal((await sync.json() as { job: { status: string } }).job.status, 'pending'); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } });