Fix tester project tests for organization refusal
This commit is contained in:
1 parent
544918a715
commit
221c1e9d35
1 file changed
+40
-13
@@ -5,7 +5,7 @@
|
||||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { spawn, spawnSync } from "node:child_process";
|
||||
import { existsSync, readdirSync } from "node:fs";
|
||||
import { existsSync, readdirSync, writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { main } from "../src/cli.mjs";
|
||||
@@ -124,10 +124,10 @@ test("row 175: --tester on limits set, reset and migrate and every write form ou
|
||||
// W7 through the real tester transport: the CLI runs as its own process, so the tester-cli.mjs it
|
||||
// spawns can reach the runtime in this one.
|
||||
const MOSAIC = fileURLToPath(new URL("../../../scripts/mosaic", import.meta.url));
|
||||
function mosaic(args, env) {
|
||||
function command(executable, args, env) {
|
||||
const clean = Object.fromEntries(Object.entries(env).filter(([k]) => !/^MOSAIC_BUS_(TESTER|CLI)_NONCE$/.test(k)));
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = spawn(MOSAIC, args, { env: clean, timeout: 60000 });
|
||||
const child = spawn(executable, args, { env: clean, timeout: 60000 });
|
||||
let out = "";
|
||||
let err = "";
|
||||
child.stdout.on("data", (d) => (out += d));
|
||||
@@ -136,6 +136,8 @@ function mosaic(args, env) {
|
||||
child.on("close", (status) => resolve({ status, out, err }));
|
||||
});
|
||||
}
|
||||
const mosaic = (args, env) => command(MOSAIC, args, env);
|
||||
|
||||
// sage-1081: these six fell through to the seat CLI, which refused with its own usage, so W1
|
||||
// (`plugins set`) and W4 (`name`) failed through the wrapper. Each now reaches packages/cli.
|
||||
test("row 175: scripts/mosaic sends plugins, name, names, follow, threads and thread to packages/cli, not the seat CLI", (t) => {
|
||||
@@ -158,35 +160,49 @@ test("row 175: scripts/mosaic sends plugins, name, names, follow, threads and th
|
||||
|
||||
const listing = (dir) => readdirSync(dir, { recursive: true }).map(String).sort();
|
||||
async function w7(t, vars, edit) {
|
||||
const { root, f, org } = await orgFixture(t, "acme", edit);
|
||||
const rt = await startBroker({ dataRoot: org.root, businesses: bus(vars) });
|
||||
const root = tmp(t, "w7-");
|
||||
const f = fixture(root, "acme", edit);
|
||||
const rt = await startBroker({ dataRoot: f.dataRoot, businesses: bus(vars) });
|
||||
t.after(() => rt.close());
|
||||
return { root, f, agent: { ...f.env, CLAUDECODE: "1", CLAUDE_CODE_ENTRYPOINT: "sdk-ts" } };
|
||||
// Production CLI routes its transport through an organization. Inject the real tester transport
|
||||
// in a child so the legacy non-org project path can still exercise the broker and its proof.
|
||||
const driver = join(root, "driver.mjs");
|
||||
writeFileSync(driver, `
|
||||
import { run } from ${JSON.stringify(new URL("../src/cli.mjs", import.meta.url).href)};
|
||||
import { testerTransport } from ${JSON.stringify(new URL("../src/transport.mjs", import.meta.url).href)};
|
||||
const [socket, ...args] = process.argv.slice(2);
|
||||
process.exitCode = await run(args, undefined, {
|
||||
testerTransport: business => testerTransport({ socket, business }),
|
||||
});
|
||||
`);
|
||||
const agent = { ...f.env, CLAUDECODE: "1", CLAUDE_CODE_ENTRYPOINT: "sdk-ts" };
|
||||
const project = (args, env = agent) => command(process.execPath, [driver, join(f.dataRoot, "bus", "broker.sock"), ...args], env);
|
||||
return { root, f, agent, project };
|
||||
}
|
||||
|
||||
test("row 175 W7: project init --tester makes the repository under the project area, committed by tester", async (t) => {
|
||||
const { f, agent } = await w7(t);
|
||||
const r = await mosaic(["project", "init", "acme", "stack", "--tester"], agent);
|
||||
const { f, agent, project } = await w7(t);
|
||||
const r = await project(["project", "init", "acme", "stack", "--tester"], agent);
|
||||
assert.equal(r.status, 0, r.err);
|
||||
const repo = join(f.dataRoot, "projects", "acme", "stack");
|
||||
assert.match(r.out, new RegExp(`^initialized ${repo}\ncommit [0-9a-f]{40}\n$`));
|
||||
const log = spawnSync("git", ["-C", repo, "log", "--format=%an|%cn"], { encoding: "utf8" });
|
||||
assert.equal(log.stdout, "tester|tester\n");
|
||||
// Without --tester the same init inside an agent refuses, as before.
|
||||
const again = await mosaic(["project", "init", "acme", "stack"], agent);
|
||||
const again = await project(["project", "init", "acme", "stack"], agent);
|
||||
assert.equal(again.status, 3);
|
||||
assert.match(again.err, /outside any agent run/);
|
||||
});
|
||||
|
||||
test("row 175 W7: a repo outside the project area refuses tester-project-area before any bus call, and nothing changes", async (t) => {
|
||||
// The switch is off: a bind would refuse tester-off (exit 3), so exit 2 shows the area check ran first.
|
||||
const { f, agent } = await w7(t, null, (doc) => {
|
||||
const { f, agent, project } = await w7(t, null, (doc) => {
|
||||
doc.projects.stack.repo = join(doc.projects.stack.root, "..", "records");
|
||||
return doc;
|
||||
});
|
||||
const records = f.doc.projects.stack.repo;
|
||||
const data = listing(f.dataRoot);
|
||||
const r = await mosaic(["project", "init", "acme", "stack", "--tester"], agent);
|
||||
const r = await project(["project", "init", "acme", "stack", "--tester"], agent);
|
||||
assert.equal(r.status, 2, r.err);
|
||||
assert.match(r.err, /tester-project-area/);
|
||||
assert.equal(existsSync(records), false);
|
||||
@@ -196,7 +212,7 @@ test("row 175 W7: a repo outside the project area refuses tester-project-area be
|
||||
test("row 175 W7: the tester bind refuses tester-off and tester-required before any directory", async (t) => {
|
||||
const off = await w7(t, null);
|
||||
const data = listing(off.f.dataRoot);
|
||||
const r = await mosaic(["project", "init", "acme", "stack", "--tester"], off.agent);
|
||||
const r = await off.project(["project", "init", "acme", "stack", "--tester"], off.agent);
|
||||
assert.equal(r.status, 3, r.err);
|
||||
assert.match(r.err, /tester-off/);
|
||||
assert.deepEqual(listing(off.f.dataRoot), data);
|
||||
@@ -204,10 +220,21 @@ test("row 175 W7: the tester bind refuses tester-off and tester-required before
|
||||
const on = await w7(t);
|
||||
const before = listing(on.f.dataRoot);
|
||||
for (const marker of ["MOSAIC_RUN_ID", "MOSAIC_BUS_CAP", "MOSAIC_AGENT_RUN"]) {
|
||||
const under = await mosaic(["project", "init", "acme", "stack", "--tester"], { ...on.agent, [marker]: "x" });
|
||||
const under = await on.project(["project", "init", "acme", "stack", "--tester"], { ...on.agent, [marker]: "x" });
|
||||
assert.equal(under.status, 3, `${marker}: ${under.err}`);
|
||||
assert.match(under.err, /tester-required/, marker);
|
||||
}
|
||||
assert.deepEqual(listing(on.f.dataRoot), before);
|
||||
assert.equal(existsSync(join(on.f.dataRoot, "projects")), false);
|
||||
});
|
||||
|
||||
// Organization setup deliberately refuses tester init before creating a project record.
|
||||
test("organization project init --tester refuses without writing", async (t) => {
|
||||
const { f, org } = await orgFixture(t);
|
||||
const before = listing(org.root);
|
||||
const agent = { ...f.env, CLAUDECODE: "1", CLAUDE_CODE_ENTRYPOINT: "sdk-ts" };
|
||||
const r = await mosaic(["project", "init", "acme", "stack", "--tester"], agent);
|
||||
assert.equal(r.status, 3, r.err);
|
||||
assert.match(r.err, /organization project init --tester is unavailable/);
|
||||
assert.deepEqual(listing(org.root), before);
|
||||
});
|
||||
Reference in new issue
Block a user