import assert from 'node:assert/strict'; import { once } from 'node:events'; import test from 'node:test'; import { createAdminApp } from './app.mjs'; function createServices({ role = 'admin' } = {}) { const calls = { update: [], shadow: [], plans: [], detail: [], }; const configState = { config: { mode: 'shadow', primaryEngine: 'langgraph', fallbackEngine: 'native', serviceUrl: 'http://127.0.0.1:8093', requestTimeoutMs: 5000, rolloutPercent: 0, userAllowlist: [], workflowAllowlist: ['code-run-v1'], fallbackToNative: true, requireHealthy: true, executionEnabled: false, }, configVersion: 4, updatedBy: 'admin-user', updatedAt: 1, source: 'admin-db', runtime: { effective: true, shadowsLangGraph: true, executesLangGraph: false, executionHandoff: { enabled: false }, }, engines: [], executors: [], }; return { calls, services: { ready: Promise.resolve(), parseCookies: () => ({ test_session: 'token' }), USER_COOKIE: 'test_session', userLoginCookies: () => [], clearUserSessionCookie: () => {}, resolveCookieDomainForRequest: () => undefined, userAuth: { getMe: async () => ({ id: 'john-id', username: 'john', role }), }, orchestratorConfigService: { getAdminConfig: async () => configState, updateAdminConfig: async (config, context) => { calls.update.push({ config, context }); return { ...configState, config, updatedBy: context.updatedBy }; }, getRuntimeState: async ({ probe }) => ({ ...configState, serviceHealth: { ok: true, status: 'healthy', probe }, }), }, orchestratorObservabilityService: { listShadowRuns: async (query) => { calls.shadow.push(query); return { metrics: { observations: 0 }, runs: [] }; }, listExecutionPlans: async (query) => { calls.plans.push(query); return { metrics: { decisions: 0 }, plans: [] }; }, getCanaryReadiness: async () => ({ ready: false, recommendation: 'keep_shadow', }), getShadowRun: async (runId) => { calls.detail.push(runId); return runId === 'missing' ? null : { native: { runId }, remote: { available: true } }; }, }, }, }; } async function startApp(options) { const harness = createServices(options); const server = createAdminApp(harness.services).listen(0, '127.0.0.1'); await once(server, 'listening'); const address = server.address(); assert.ok(address && typeof address === 'object'); return { ...harness, request: (path, init = {}) => fetch(`http://127.0.0.1:${address.port}${path}`, { ...init, headers: { Cookie: 'test_session=token', 'Content-Type': 'application/json', ...init.headers, }, }), close: () => new Promise((resolve, reject) => { server.close((error) => error ? reject(error) : resolve()); }), }; } test('admin can read orchestrator config, runtime and observability endpoints', async (t) => { const app = await startApp(); t.after(app.close); const config = await app.request('/admin-api/orchestrator/config'); assert.equal(config.status, 200); assert.equal((await config.json()).config.mode, 'shadow'); const runtime = await app.request('/admin-api/orchestrator/runtime'); assert.equal(runtime.status, 200); assert.deepEqual((await runtime.json()).serviceHealth, { ok: true, status: 'healthy', probe: true, }); const shadow = await app.request( '/admin-api/orchestrator/shadow-runs?hours=24&limit=50&status=failed', ); assert.equal(shadow.status, 200); assert.deepEqual(app.calls.shadow, [{ hours: '24', limit: '50', status: 'failed' }]); const plans = await app.request( '/admin-api/orchestrator/execution-plans?hours=168&limit=20&selection=native', ); assert.equal(plans.status, 200); assert.deepEqual(app.calls.plans, [{ hours: '168', limit: '20', selection: 'native' }]); const readiness = await app.request('/admin-api/orchestrator/canary-readiness'); assert.equal(readiness.status, 200); assert.equal((await readiness.json()).recommendation, 'keep_shadow'); const detail = await app.request('/admin-api/orchestrator/shadow-runs/run-1'); assert.equal(detail.status, 200); assert.deepEqual(app.calls.detail, ['run-1']); const missing = await app.request('/admin-api/orchestrator/shadow-runs/missing'); assert.equal(missing.status, 404); }); test('admin config update records the authenticated administrator', async (t) => { const app = await startApp(); t.after(app.close); const response = await app.request('/admin-api/orchestrator/config', { method: 'PUT', body: JSON.stringify({ config: { mode: 'off', executionEnabled: false } }), }); assert.equal(response.status, 200); assert.deepEqual(app.calls.update, [{ config: { mode: 'off', executionEnabled: false }, context: { updatedBy: 'john-id' }, }]); }); test('ordinary users cannot access or mutate orchestrator controls', async (t) => { const app = await startApp({ role: 'user' }); t.after(app.close); const read = await app.request('/admin-api/orchestrator/config'); assert.equal(read.status, 403); const update = await app.request('/admin-api/orchestrator/config', { method: 'PUT', body: JSON.stringify({ config: { mode: 'active', executionEnabled: true } }), }); assert.equal(update.status, 403); assert.equal(app.calls.update.length, 0); });