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

A test pins setting how a fork follows its parent: an admin and writer only, a known mode only #7195

Merged opened this

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

Merged

scout/forge:scout/7093-a-test-pins-setting-how-a-fork-follows-i → main 1 commit fork 1 thread · 1 unresolved

  • Merged. scout/7093-a-test-pins-setting-how-a-fork-follows-i was merged into main as 2a5ee61.

Review

Sign in to review this change.
1 file changed +101 −0
test/follow-mode-refusals.test.ts added +101
@@ -0,0 +1,101 @@
1 /**
2 * Setting how a fork follows its parent (#7093): the fork's admin may choose
3 * each known mode and reads it back; an unknown mode, a repository that
4 * follows no parent, and a reader are refused, and the mode is unchanged.
5 */
6
7 import { afterAll, beforeAll, describe, expect, test } from "bun:test";
8 import { mkdtemp, rm } from "node:fs/promises";
9 import { tmpdir } from "node:os";
10 import { join } from "node:path";
11 import { setFollowMode } from "../src/actions/follow.ts";
12 import { createRepo } from "../src/actions/repos.ts";
13 import { createApp, type App } from "../src/app.ts";
14 import type { Repo } from "../src/core/repos.ts";
15 import { createUser, type User } from "../src/core/users.ts";
16 import { FOLLOW_MODES, forgeLinkOf } from "../src/spawn/chain.ts";
17 import { quietLogs } from "./helpers/globals.ts";
18
19 quietLogs();
20
21 describe("setting how a fork follows its parent", () => {
22 let dir = "";
23 let app: App;
24 let admin: User;
25 let reader: User;
26 let repo: Repo;
27 let other: Repo;
28
29 const mode = async () => (await forgeLinkOf(app))?.mode;
30
31 beforeAll(async () => {
32 dir = await mkdtemp(join(tmpdir(), "forge-followmode-"));
33 app = createApp({ dataDir: join(dir, "kid"), port: 0, host: "kid.test" });
34 const user = async (username: string, adminIfFirst: boolean): Promise<User> => {
35 const made = await createUser(app.db, {
36 origin: "seed",
37 trusted: true,
38 username,
39 email: `${username}@forge.local`,
40 password: "a-long-refusal-passphrase",
41 adminIfFirst,
42 });
43 if (!made.ok) throw new Error(made.error);
44 return made.value;
45 };
46 admin = await user("alice", true);
47 reader = await user("rita", false);
48 const made = await createRepo(app, admin, { name: "app", visibility: "public" });
49 const made2 = await createRepo(app, admin, { name: "other", visibility: "public" });
50 if (!made.ok || !made2.ok) throw new Error("repo");
51 repo = made.value;
52 other = made2.value;
53 await Bun.write(
54 join(app.config.dataDir, "parent.json"),
55 JSON.stringify({
56 upstream: "http://127.0.0.1:1",
57 name: "kid",
58 forgeCode: { repo: "alice/app", upstream: "bob/app", mode: "tell-me", tip: "", chain: [] },
59 }),
60 );
61 });
62
63 afterAll(async () => {
64 await rm(dir, { recursive: true, force: true });
65 });
66
67 test("the admin sets each known mode and reads it back", async () => {
68 for (const m of [...FOLLOW_MODES, FOLLOW_MODES[0]]) {
69 const r = await setFollowMode(app, admin, repo, m);
70 expect(r).toEqual({ ok: true, value: m });
71 expect(await mode()).toBe(m);
72 }
73 });

Nit: the loop [...FOLLOW_MODES, FOLLOW_MODES[0]] is cute but the intent (setting the same mode twice is fine) deserves a one-line comment.

74
75 test("an unknown mode is invalid_mode and the mode stays", async () => {
76 await setFollowMode(app, admin, repo, "take-updates");
77 for (const bad of ["yolo", "", "TAKE-UPDATES", 1, null, undefined, { mode: "tell-me" }]) {
78 const r = await setFollowMode(app, admin, repo, bad);
79 expect(r.ok ? "ok" : r.error).toBe("invalid_mode");
80 expect(await mode()).toBe("take-updates");
81 }
82 });
83
84 test("a repository that follows no parent is not_following and the mode stays", async () => {
85 const r = await setFollowMode(app, admin, other, "tell-me");
86 expect(r.ok ? "ok" : r.error).toBe("not_following");
87 expect(await mode()).toBe("take-updates");
88 });
89
90 test("a reader is forbidden and the mode stays", async () => {
91 const r = await setFollowMode(app, reader, repo, "tell-me");
92 expect(r.ok ? "ok" : r.error).toBe("forbidden");
93 expect(await mode()).toBe("take-updates");
94 });
95
96 test("nobody signed in is unauthorized and the mode stays", async () => {
97 const r = await setFollowMode(app, undefined, repo, "tell-me");
98 expect(r.ok ? "ok" : r.error).toBe("unauthorized");
99 expect(await mode()).toBe("take-updates");
100 });
101 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs