Some checks are pending
offline / test (push) Waiting to run
Match CS/sales/accounting/access-staff to the portal indigo system with dollar amounts, skip links, and empty states. Fleet replica actions move into overflow menus, roles become chips, Docs become cards, and the header copy reflects the 0.0.0.0 bind. Simulator uses the same shell (orange only for faults). Portal API keys are masked; admin customers edit in a drawer. Catalog uses system-ui. New UI-Docs repo holds screenshots, usage notes, and UI-REVIEW.pdf.
61 lines
2.3 KiB
JavaScript
61 lines
2.3 KiB
JavaScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { spawn } from 'node:child_process';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
const authzRoot = path.join(root, '..', 'verae-access-authz');
|
|
const booksRoot = path.join(root, '..', 'zappier-account-balance');
|
|
|
|
test('staff plane can credit after authz; zapier cannot', async () => {
|
|
const authzPort = 18031;
|
|
const booksPort = 18032;
|
|
const staffPort = 18033;
|
|
const authz = spawn(process.execPath, ['src/server.js'], {
|
|
cwd: authzRoot,
|
|
env: { ...process.env, PORT: String(authzPort) },
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
});
|
|
const books = spawn(process.execPath, ['src/server.js'], {
|
|
cwd: booksRoot,
|
|
env: { ...process.env, PORT: String(booksPort), BOOKS_PATH: `/tmp/staff-books-${Date.now()}.json` },
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
});
|
|
const staff = spawn(process.execPath, ['src/server.js'], {
|
|
cwd: root,
|
|
env: {
|
|
...process.env,
|
|
PORT: String(staffPort),
|
|
AUTHZ_URL: `http://127.0.0.1:${authzPort}`,
|
|
ACCOUNT_BALANCE_URL: `http://127.0.0.1:${booksPort}`,
|
|
},
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
});
|
|
await new Promise((r) => setTimeout(r, 600));
|
|
try {
|
|
const h = await (await fetch(`http://127.0.0.1:${staffPort}/health`)).json();
|
|
assert.equal(h.plane, 'staff');
|
|
const page = await fetch(`http://127.0.0.1:${staffPort}/`);
|
|
assert.match(page.headers.get('content-type') || '', /text\/html/);
|
|
const html = await page.text();
|
|
assert.match(html, /Staff access/);
|
|
assert.match(html, /Amount \(USD\)/);
|
|
const add = await fetch(`http://127.0.0.1:${staffPort}/credits`, {
|
|
method: 'POST',
|
|
headers: { 'content-type': 'application/json' },
|
|
body: JSON.stringify({ customerId: 'c-staff', cents: 50, reason: 'test', agent: 'cs' }),
|
|
});
|
|
assert.equal(add.status, 200);
|
|
const deny = await fetch(`http://127.0.0.1:${authzPort}/check`, {
|
|
method: 'POST',
|
|
headers: { 'content-type': 'application/json' },
|
|
body: JSON.stringify({ plane: 'zapier', subject: 'verae.billing.balance.adjust' }),
|
|
});
|
|
assert.equal(deny.status, 403);
|
|
} finally {
|
|
staff.kill('SIGTERM');
|
|
books.kill('SIGTERM');
|
|
authz.kill('SIGTERM');
|
|
}
|
|
});
|