35 lines
2.8 KiB
JavaScript
35 lines
2.8 KiB
JavaScript
// C2-04 only wires callbacks. HTTP routes and pages are later rows.
|
|
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { spawnSync } from 'node:child_process';
|
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
import { join } from 'node:path';
|
|
import { tmp, fixture } from '../../cli/tests/helpers.mjs';
|
|
import { HUMAN_CLI, TESTER_CLI } from '../../cli/src/transport.mjs';
|
|
|
|
test('C2-04 CLI: both listener callback pairs dispatch library verbs with their own transport', t => {
|
|
const root = tmp(t, 'library-cli-'), f = fixture(root), log = join(root, 'calls.jsonl');
|
|
writeFileSync(log, '');
|
|
const hook = join(root, 'hooks.mjs');
|
|
// The loader supplies a fixture bus and captures callbacks instead of
|
|
// opening an HTTP listener. Production imports and routes are unchanged.
|
|
const serveSource = "export const DEFAULT_BOARD='http://127.0.0.1:9';export const previewOptions=()=>null;export const proofOptions=()=>null;export async function startServer(o){if(typeof o.libraryFile!=='function'||typeof o.libraryStatus!=='function')throw Error('missing library callbacks');await o.libraryFile({project:'books',path:'Book One/A.md'});await o.libraryStatus({project:'books'});return {address:()=>({port:0}),close:()=>{}};}";
|
|
const busSource = `import {appendFileSync} from 'node:fs';export class BusReadError extends Error{};export const busCaller=o=>async(verb,args)=>{appendFileSync(${JSON.stringify(log)},JSON.stringify({verb,args,cli:o.cli??${JSON.stringify(HUMAN_CLI)}})+'\\n');return {};};export const organizationConsole=()=>{throw Error('organizationConsole outside dev-owner')};export const busBusiness=()=>{throw Error('busBusiness outside --sso')};export const userCaller=()=>{throw Error('userCaller outside --sso')};export const consoleCall=()=>{throw Error('consoleCall outside --sso')};`;
|
|
writeFileSync(hook, `import {registerHooks} from 'node:module';
|
|
registerHooks({load(url,context,next){
|
|
if(url.endsWith('/webui/src/serve.mjs'))return {format:'module',shortCircuit:true,source:${JSON.stringify(serveSource)}};
|
|
if(url.endsWith('/webui/src/bus.mjs'))return {format:'module',shortCircuit:true,source:${JSON.stringify(busSource)}};
|
|
return next(url,context);
|
|
}});`);
|
|
const result = spawnSync(process.execPath, [new URL('../src/cli.mjs', import.meta.url).pathname,
|
|
'serve', '--business', 'acme', '--port', '0', '--tester-socket'],
|
|
{ env: { ...f.env, NODE_OPTIONS: `--import=${hook}` }, encoding: 'utf8', timeout: 10000 });
|
|
assert.equal(result.status, 0, result.stdout + result.stderr);
|
|
const calls = readFileSync(log, 'utf8').trim().split('\n').filter(Boolean).map(JSON.parse);
|
|
assert.deepEqual(calls.map(c => [c.verb, c.cli]), [
|
|
['library.file', HUMAN_CLI], ['library.status', HUMAN_CLI],
|
|
['library.file', TESTER_CLI], ['library.status', TESTER_CLI],
|
|
]);
|
|
assert.equal(calls[0].args.path, 'Book One/A.md');
|
|
});
|