1a88ab3199
The v0.8 milestone: installable on any Debian-based server via docker (Gitea registry image, honest sandbox degrade), deb (amd64+arm64, advisory postinst), and arch-aware binary — with release consistency enforced by pre-commit hooks + Gitea Actions (3-runner fleet on CT 113, machine-made releases with the full 8-asset matrix + registry image), the CLI carrying the full suite (guide, channel-aware doctor), and the admin runbook (deploy/README.md, evidence-backed recipes). ---ci--- phase: 6 milestone: v0.8 status: complete requirements: covered: [REQ-8-001, REQ-8-002, REQ-8-003, REQ-8-004, REQ-8-005] partial: [] ---/ci---
68 lines
2.6 KiB
TypeScript
68 lines
2.6 KiB
TypeScript
// guide command tests (v0.8 P4, D-072/G-210).
|
|
|
|
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { run } from "../src/index.ts";
|
|
import { testCtx } from "./helpers.ts";
|
|
|
|
test("guide: overview (default) lists all channels + ends at doctor/verify", async () => {
|
|
const ctx = testCtx();
|
|
const code = await run(["guide"], ctx);
|
|
assert.equal(code, 0);
|
|
const out = ctx.out();
|
|
assert.ok(out.includes("DOCKER"), "names the docker channel");
|
|
assert.ok(out.includes("DEB"), "names the deb channel");
|
|
assert.ok(out.includes("BINARY"), "names the binary channel");
|
|
assert.ok(out.includes("doctor"), "ends at doctor/verify");
|
|
});
|
|
|
|
test("guide: every topic routes + carries its channel's recipe", async () => {
|
|
const topics: Array<[string, string[]]> = [
|
|
["docker", ["docker run", "8420", "SANDBOX FABRIC", "seccomp"]],
|
|
["deb", ["dpkg -i", "Recommends", "deploy --service"]],
|
|
["binary", ["install.sh", "aarch64", "deploy --service"]],
|
|
["upgrade", ["docker pull", "dpkg -i", "idempotent"]],
|
|
["troubleshooting", ["JSON 404", "8420", "hecksum"]],
|
|
];
|
|
for (const [topic, markers] of topics) {
|
|
const ctx = testCtx();
|
|
assert.equal(await run(["guide", topic], ctx), 0, `topic ${topic} exits 0`);
|
|
for (const m of markers) {
|
|
assert.ok(ctx.out().includes(m), `topic ${topic} mentions ${m}`);
|
|
}
|
|
}
|
|
});
|
|
|
|
test("guide: unknown topic exits 2 with the topic list", async () => {
|
|
const ctx = testCtx();
|
|
assert.equal(await run(["guide", "warp"], ctx), 2);
|
|
assert.ok(ctx.err().includes("unknown guide topic: warp"));
|
|
assert.ok(ctx.err().includes("docker | deb | binary"));
|
|
});
|
|
|
|
test("guide: more than one topic is a usage error (exit 2)", async () => {
|
|
const ctx = testCtx();
|
|
assert.equal(await run(["guide", "docker", "deb"], ctx), 2);
|
|
});
|
|
|
|
test("guide: docker-mode tail names the in-container commands", async () => {
|
|
const ctx = testCtx({
|
|
env: { ...process.env, NC_CONTAINER: "1" } as Record<string, string | undefined>,
|
|
});
|
|
assert.equal(await run(["guide", "docker"], ctx), 0);
|
|
assert.ok(ctx.out().includes("docker image detected"), "container-aware tail");
|
|
assert.ok(ctx.out().includes("nextcraft doctor"), "points at in-container commands");
|
|
});
|
|
|
|
test("guide: offline-first — forge URLs are pointers (https), never fetches", async () => {
|
|
const ctx = testCtx();
|
|
await run(["guide", "overview"], ctx);
|
|
await run(["guide", "binary"], ctx);
|
|
// Any URL in the text is a pointer for the HUMAN; the command itself
|
|
// performs no I/O (embedded text only).
|
|
const out = ctx.out();
|
|
if (out.includes("http")) {
|
|
assert.ok(out.includes("https://"), "URLs are https pointers");
|
|
}
|
|
});
|