75 lines
3.2 KiB
JavaScript
75 lines
3.2 KiB
JavaScript
// Row 298/Q228: the real CLI parser and human-shell refusal. Transport is a
|
|
// recorder; no socket, config, credential or live grant is accessed.
|
|
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { main } from "../src/cli.mjs";
|
|
import { humanEnv, io } from "./helpers.mjs";
|
|
|
|
const AGENT_MARKERS = ["MOSAIC_BUS_CAP", "MOSAIC_RUN_ID", "MOSAIC_AGENT_RUN", "CLAUDECODE", "CLAUDE_CODE_ENTRYPOINT", "CODEX_THREAD_ID", "PI_AGENT_DIR"];
|
|
const REVISION = "a".repeat(64);
|
|
const SCOPE = { gitea: { agents: ["coder"], projects: ["app"] } };
|
|
const READ = ["grants", "scope", "--business", "acme"];
|
|
const SET = ["grants", "scope", "set", "--business", "acme", "--revision", REVISION];
|
|
function setup(env = humanEnv(), stdin = JSON.stringify(SCOPE)) {
|
|
const x = io(env);
|
|
x.stdin.end(stdin);
|
|
const calls = [];
|
|
const deps = {
|
|
system: { dataRoot: "/nonexistent" },
|
|
transport: (business) => async (verb, args) => {
|
|
calls.push({ business, verb, args });
|
|
return { revision: REVISION, scope: SCOPE, fallback: false };
|
|
},
|
|
testerTransport: () => async () => { throw new Error("tester transport must never run"); },
|
|
};
|
|
return { x, calls, deps };
|
|
}
|
|
|
|
// Break caught: dropping scope dispatch or misrouting the writer's revision.
|
|
test("row 298 CLI: scope reads and scope set sends JSON and the observed revision", async () => {
|
|
const f = setup();
|
|
await main(READ, f.x, f.deps);
|
|
assert.deepEqual(f.calls, [{ business: "acme", verb: "grants.scope", args: {} }]);
|
|
assert.deepEqual(JSON.parse(f.x.out.text), { revision: REVISION, scope: SCOPE, fallback: false });
|
|
const w = setup();
|
|
await main(SET, w.x, w.deps);
|
|
assert.deepEqual(w.calls, [{ business: "acme", verb: "grants.scope.set", args: { revision: REVISION, scope: SCOPE } }]);
|
|
const empty = setup(humanEnv(), "{}");
|
|
await main(SET, empty.x, empty.deps);
|
|
assert.deepEqual(empty.calls[0].args.scope, {});
|
|
});
|
|
|
|
// Break caught: a new grants path bypassing access's refuseInsideAgent guard.
|
|
test("row 298 CLI: every access agent marker refuses scope set before transport", async () => {
|
|
for (const marker of AGENT_MARKERS) {
|
|
const f = setup({ ...humanEnv(), [marker]: "agent" });
|
|
await assert.rejects(main(SET, f.x, f.deps), (e) => e.exitCode === 3 && /human shell/.test(e.message), marker);
|
|
assert.deepEqual(f.calls, []);
|
|
assert.equal(f.x.out.text, "");
|
|
}
|
|
});
|
|
|
|
// Break caught: --tester selecting a nonhuman transport for this approval.
|
|
test("row 298 CLI: --tester cannot read or change the scope", async () => {
|
|
for (const args of [READ, SET]) {
|
|
const f = setup();
|
|
await assert.rejects(main([...args, "--tester"], f.x, f.deps), (e) => e.exitCode === 4);
|
|
assert.deepEqual(f.calls, []);
|
|
}
|
|
});
|
|
|
|
// Break caught: a missing revision or invalid stdin being sent as an approval.
|
|
test("row 298 CLI: missing revision and empty, invalid or oversized JSON refuse without a call", async () => {
|
|
for (const [args, input, code] of [
|
|
[SET.slice(0, -2), "{}", 4],
|
|
[SET, "", 4],
|
|
[SET, " \n", 4],
|
|
[SET, "{bad", 4],
|
|
[SET, " ".repeat(65537), 2],
|
|
]) {
|
|
const f = setup(humanEnv(), input);
|
|
await assert.rejects(main(args, f.x, f.deps), (e) => e.exitCode === code);
|
|
assert.deepEqual(f.calls, []);
|
|
}
|
|
});
|