Files
stack/packages/webui/tests/helpers/w15-project-remote-real.mjs

48 lines
3.2 KiB
JavaScript

import { mkdtempSync, mkdirSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { businessDoc, rolesCopy, systemFor, writeJson } from '../../../organization/tests/helpers.mjs';
import { loadBusiness } from '../../../organization/src/organization-config.mjs';
import { resolveInstance } from '../../../organization/src/resolve.mjs';
import { busOrganization } from '../../../bus/src/organization-context.mjs';
import { startBroker } from '../../../bus/src/runtime.mjs';
import { serve } from '../../../bus/src/server.mjs';
import { Client } from '../../../bus/src/client.mjs';
import { startServer } from '../../src/serve.mjs';
import { close } from '../fixture.mjs';
// Ephemeral organization, real runtime writer, broker socket and HTTP listener. The proof
// verifier and SSO session are fixture authorities; no live service or network is involved.
export async function realRemoteFixture(t, mutate = () => {}) {
const root = mkdtempSync(join(tmpdir(), 'remote-real-'));
const rolesDir = rolesCopy(root), system = systemFor(root);
const doc = businessDoc(root, 'demo'); mutate(doc);
const file = writeJson(join(root, 'businesses/demo.json'), doc);
mkdirSync(join(root, 'data'), { mode: 0o700 });
const form = () => {
const business = loadBusiness('demo', { dir: root, rolesDir });
const resolved = Object.fromEntries(Object.keys(business.roles).map(instance => [instance, resolveInstance({ system, business, instance })]));
return busOrganization(business, resolved);
};
const start = () => startBroker({ dataRoot: join(root, 'data'), businesses: { demo: form() }, organization: { dir: root, rolesDir, system } });
let runtime = await start();
let socketServer;
const path = join(root, 'fixture.sock');
const attach = async () => {
socketServer = await serve({ broker: runtime.broker, path, peerReader: { read: async () => ({}), close: () => {} },
authenticateConsole: proof => runtime.broker.bindConsole({ business: 'demo', human: 'jason', subject: proof.subject }) });
};
await attach();
const subject = { provider: 'fixture', iss: 'https://issuer.example', sub: 'owner' };
const session = { rootOwner: true, instanceRole: 'operator', ...subject, name: 'jason' };
let active = true;
const sso = { publicOrigin: '', publicHost: '', formTargets: () => [], session: () => active ? session : null, handle: () => {}, health: () => ({}) };
const transport = (verb, args, ctx) => new Client({ path, console: { subject: ctx.subject } }).call(verb, args);
const web = await startServer({ port: 0, board: 'http://127.0.0.1:9', sso, send: async () => ({}), requestRead: transport, requestWrite: transport, log: () => {} });
const base = `http://127.0.0.1:${web.address().port}`;
sso.publicOrigin = base; sso.publicHost = new URL(base).host;
t.after(async () => { await close(web); await socketServer.close(); await runtime.close(); rmSync(root, { recursive: true, force: true }); });
const restart = async () => { await socketServer.close(); await runtime.close(); runtime = await start(); await attach(); };
return { root, file, base, path, session, subject, restart, signOut: () => { active = false; }, broker: () => runtime.broker };
}