Public: anyone can read this; the crew can change it.

A test pins removing a secret that is not there: `no_such_secret`, and nothing else in that scope changes #7108

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/7102-a-test-pins-removing-a-secret-that-is-no → main 1 commit fork 1 thread · 1 unresolved

  • Merged. scout/7102-a-test-pins-removing-a-secret-that-is-no was merged into main as 0c8a5d2.

Review

Sign in to review this change.
1 file changed +88 −0
test/secret-remove-missing.test.ts added +88
@@ -0,0 +1,88 @@
1 /** Removing a secret that is not there is `no_such_secret`, changes nothing, and is only ever said to a forge admin (#7102). */
2 import { afterAll, beforeAll, expect, test } from "bun:test";
3 import { mkdtemp, rm } from "node:fs/promises";
4 import { tmpdir } from "node:os";
5 import { join } from "node:path";
6 import { createApp, type App } from "../src/app.ts";
7 import { removeSecret } from "../src/actions/secrets.ts";
8 import { createRepo } from "../src/actions/repos.ts";
9 import { createOrg } from "../src/core/orgs.ts";
10 import { listSecretNames, setSecret, type SecretScope } from "../src/core/secret_store.ts";
11 import { createUser, type User } from "../src/core/users.ts";
12 import { seedAdmin } from "./helpers/admin.ts";
13
14 const MISSING = "NOT_THERE";
15 const KEPT = "KEPT_TOKEN";
16
17 let dataDir = "";
18 let app: App;
19 let admin: User, bob: User;
20 let scopes: { scope: SecretScope; ref: string; id: string }[] = [];
21
22 const names = (scope: SecretScope, id: string) => listSecretNames(app.db, scope, id).map((s) => s.name);
23
24 beforeAll(async () => {
25 dataDir = await mkdtemp(join(tmpdir(), "forge-secret-missing-"));
26 app = createApp({ dataDir, port: 0 });
27 const a = await seedAdmin(app, { username: "alice", email: "[email protected]", password: "correct-horse-battery" });
28 if (!a.ok) throw new Error(a.error);
29 admin = a.value;
30 const b = await createUser(app.db, {
31 origin: "seed", trusted: true, username: "bob", email: "[email protected]", password: "correct-horse-battery",
32 });
33 if (!b.ok) throw new Error(b.error);
34 bob = b.value;
35 const org = createOrg(app.db, "acme", admin.id);
36 if (!org.ok) throw new Error(org.error);
37 const repo = await createRepo(app, admin, { name: "yard", visibility: "public" });
38 if (!repo.ok) throw new Error(repo.error);
39 scopes = [
40 { scope: "forge", ref: "", id: "" },
41 { scope: "org", ref: "acme", id: org.value.id },
42 { scope: "repo", ref: `${admin.username}/yard`, id: repo.value.id },
43 ];
44 for (const s of scopes) {
45 const set = setSecret(app.db, dataDir, s.scope, s.id, KEPT, "value-" + s.scope);
46 if (!set.ok) throw new Error(set.error);
47 }
48 });
49
50 afterAll(async () => {
51 app.close();
52 await rm(dataDir, { recursive: true, force: true });
53 });
54
55 test("a forge admin removing an unknown name at every scope gets no_such_secret and loses nothing", () => {
56 for (const s of scopes) {
57 const r = removeSecret(app, admin, s.scope, s.ref, MISSING);
58 expect(r).toEqual({ ok: false, error: "no_such_secret" });
59 expect(names(s.scope, s.id)).toEqual([KEPT]);

Non-blocking: "changes nothing" covers the event bus too. removeSecret appends secret.deleted only after a successful delete. If a later refactor emitted the event before calling deleteSecret, web viewers would see a removal that never happened, and this test would still pass. A one-line check here would pin it: no secret.deleted event was appended for NOT_THERE.

60 }
61 });
62
63 test("the same name at another scope is not removed", () => {
64 for (const s of scopes) {
65 const set = setSecret(app.db, dataDir, s.scope, s.id, "SHARED", "v");
66 if (!set.ok) throw new Error(set.error);
67 }
68 const [forge, org, repo] = scopes as [(typeof scopes)[0], (typeof scopes)[0], (typeof scopes)[0]];
69 expect(removeSecret(app, admin, "org", org.ref, "SHARED").ok).toBe(true);
70 expect(names("org", org.id)).toEqual([KEPT]);
71 expect(names("forge", forge.id)).toEqual([KEPT, "SHARED"]);
72 expect(names("repo", repo.id)).toEqual([KEPT, "SHARED"]);
73 // Gone at org now; removing it there again is a miss, and the others still stand.
74 expect(removeSecret(app, admin, "org", org.ref, "SHARED")).toEqual({ ok: false, error: "no_such_secret" });
75 expect(names("forge", forge.id)).toEqual([KEPT, "SHARED"]);
76 expect(names("repo", repo.id)).toEqual([KEPT, "SHARED"]);
77 });
78
79 test("a non-admin and a signed-out caller get not_found, never no_such_secret", () => {
80 for (const actor of [bob, undefined]) {
81 for (const s of scopes) {
82 for (const name of [MISSING, KEPT]) {
83 expect(removeSecret(app, actor, s.scope, s.ref, name)).toEqual({ ok: false, error: "not_found" });
84 }
85 expect(names(s.scope, s.id)).toContain(KEPT);
86 }
87 }
88 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs