71 lines
3.8 KiB
JavaScript
71 lines
3.8 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { createServer } from 'node:net';
|
|
import { mkdtempSync, rmSync, readFileSync } from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import { businessDoc, REPO, REPO_ROLES, writeJson } from '../../business/tests/helpers.mjs';
|
|
import { consoleReads } from '../src/reads.mjs';
|
|
import { startServer } from '../src/serve.mjs';
|
|
import { humanCall, consoleCall } from '../src/bus.mjs';
|
|
|
|
const fixed = Date.parse('2026-10-10T12:00:00.000Z');
|
|
const golden = new URL('./fixtures/rename-a/business-response.json', import.meta.url);
|
|
|
|
test('v1 /api/business response preserves its complete JSON shape and redaction', async t => {
|
|
const root = mkdtempSync(join(tmpdir(), 'wire-'));
|
|
t.after(() => rmSync(root, { recursive: true, force: true }));
|
|
const configDir = join(root, 'config'), dataRoot = join(root, 'data');
|
|
const doc = businessDoc(root);
|
|
writeJson(join(configDir, 'businesses/acme.json'), doc);
|
|
const system = { configVersion: 1, environment: 'development', dataRoot, execution: { backend: 'docker', provider: 'zai', model: 'glm-5.3-flash', adapter: 'mock' } };
|
|
const reads = consoleReads({ root: REPO, configDir, rolesDir: REPO_ROLES, system, business: 'acme', now: () => fixed });
|
|
const server = await startServer({ port: 0, reads });
|
|
t.after(() => server.close());
|
|
const response = await fetch(`http://127.0.0.1:${server.address().port}/api/business`);
|
|
assert.equal(response.status, 200);
|
|
const body = await response.text();
|
|
assert.doesNotMatch(body, /placeholder-not-a-token|secret|"file"|"botId"/);
|
|
assert.deepEqual(JSON.parse(body), JSON.parse(readFileSync(golden, 'utf8')));
|
|
});
|
|
|
|
test('v1 Console human and owner reads send their exact business-bound IPC envelopes', async t => {
|
|
const root = mkdtempSync(join(tmpdir(), 'ipc-'));
|
|
t.after(() => rmSync(root, { recursive: true, force: true }));
|
|
const socket = join(root, 's');
|
|
const received = [];
|
|
const server = createServer(conn => {
|
|
let input = '';
|
|
conn.on('data', chunk => {
|
|
input += chunk;
|
|
if (!input.includes('\n')) return;
|
|
received.push(JSON.parse(input));
|
|
conn.end('{"ok":true,"result":{"answer":"fixture"}}\n');
|
|
});
|
|
});
|
|
await new Promise((resolve, reject) => server.listen(socket, resolve).once('error', reject));
|
|
t.after(() => server.close());
|
|
const env = { PATH: process.env.PATH, HOME: process.env.HOME, TMPDIR: process.env.TMPDIR };
|
|
const human = humanCall({ socket, business: 'acme', env });
|
|
assert.deepEqual(await human('instances', {}), { answer: 'fixture' });
|
|
assert.deepEqual(await human('limits', {}), { answer: 'fixture' });
|
|
const owner = consoleCall({ socket, dataRoot: root, business: 'acme', env });
|
|
assert.deepEqual(await owner('request.draft.console', { request: 'r1' }, { subject: { provider: 'local', iss: 'fixture', sub: 'owner' } }), { answer: 'fixture' });
|
|
for (const [i, verb] of ['instances', 'limits'].entries()) {
|
|
const { human: proof, ...rest } = received[i];
|
|
assert.deepEqual(rest, { verb, args: {} });
|
|
assert.deepEqual(Object.keys(proof), ['business', 'pid', 'startTime', 'nonce']);
|
|
assert.equal(proof.business, 'acme');
|
|
assert.ok(Number.isInteger(proof.pid));
|
|
assert.match(String(proof.startTime), /^\d+$/);
|
|
assert.match(proof.nonce, /^[a-f0-9]{64}$/);
|
|
}
|
|
const { console: proof, ...rest } = received[2];
|
|
assert.deepEqual(rest, { verb: 'request.draft.console', args: { request: 'r1' } });
|
|
assert.deepEqual(Object.keys(proof), ['business', 'provider', 'iss', 'sub', 'pid', 'startTime', 'nonce']);
|
|
assert.deepEqual([proof.business, proof.provider, proof.iss, proof.sub], ['acme', 'local', 'fixture', 'owner']);
|
|
assert.ok(Number.isInteger(proof.pid));
|
|
assert.match(String(proof.startTime), /^\d+$/);
|
|
assert.match(proof.nonce, /^[a-f0-9]{64}$/);
|
|
});
|