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

A test pins stopping a mirror: only the repository's admin can, anyone else is told not found, and the target stays until then #6845

Merged opened this

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

Merged

scout/forge:scout/6826-a-test-pins-stopping-a-mirror-only-the-r → main 3 commits fork

  • Merged. scout/6826-a-test-pins-stopping-a-mirror-only-the-r was merged into main as 6c31c39.

Review

Sign in to review this change.
1 file changed +99 −0
test/mirror-target.test.ts added +99
@@ -0,0 +1,99 @@
1 /**
2 * Stopping a mirror (#3408): only the repository's admin can, anyone else is
3 * told not found, and the target stays until then.
4 */
5
6 import { afterAll, beforeAll, describe, expect, test } from "bun:test";
7 import { mkdtemp, rm } from "node:fs/promises";
8 import { tmpdir } from "node:os";
9 import { join } from "node:path";
10 import { stopMirroring } from "../src/actions/mirror_target.ts";
11 import { createApp, type App } from "../src/app.ts";
12 import { getMirrorTarget, setMirrorTarget } from "../src/core/migrate_mirror.ts";
13 import { addTeamMember, createOrg, createTeam } from "../src/core/orgs.ts";
14 import { createRepo, type Repo } from "../src/core/repos.ts";
15 import { createUser, type User } from "../src/core/users.ts";
16
17 describe("stopping a mirror", () => {
18 let dataDir: string;
19 let app: App;
20 let repo: Repo;
21 let siteAdmin: User;
22 let admin: User;
23 let writer: User;
24 let stranger: User;
25
26 const person = async (username: string, adminIfFirst = false): Promise<User> => {
27 const made = await createUser(app.db, {
28 origin: "seed",
29 trusted: true,
30 adminIfFirst,
31 username,
32 email: `${username}@forge.test`,
33 password: "mirrors-are-one-way",
34 });
35 if (!made.ok) throw new Error(String(made.error));
36 return made.value;
37 };
38
39 const target = () => getMirrorTarget(app.db, repo.id);
40 const arm = () => {
41 app.db.run("PRAGMA foreign_keys = OFF");
42 setMirrorTarget(app.db, {
43 repoId: repo.id,
44 originId: "origin-none",
45 fullName: "octo/gizmo",
46 cloneUrl: "https://example.test/octo/gizmo.git",
47 tips: {},
48 });
49 };
50
51 beforeAll(async () => {
52 dataDir = await mkdtemp(join(tmpdir(), "forge-mirror-target-"));
53 app = createApp({ dataDir, port: 0 });
54 // The first account is the site admin; none of the actors below is it.
55 siteAdmin = await person("siteowner", true);
56 admin = await person("alice");
57 writer = await person("bob");
58 stranger = await person("carol");
59 const org = createOrg(app.db, "acme", admin.id);
60 if (!org.ok) throw new Error(org.error);
61 const team = createTeam(app.db, org.value.id, "Writers", "write");
62 if (!team.ok) throw new Error(team.error);
63 addTeamMember(app.db, team.value, writer.id);
64 const made = await createRepo(app.db, app.reposRoot, {
65 ownerId: org.value.id,
66 name: "gizmo",
67 visibility: "private",
68 });
69 if (!made.ok) throw new Error(String(made.error));
70 repo = made.value;
71 arm();
72 });
73
74 afterAll(async () => {
75 app.close();
76 await rm(dataDir, { recursive: true, force: true, maxRetries: 20, retryDelay: 100 });
77 });
78
79 test("a writer who is not admin, a stranger and a guest are told not found, and the target stays", () => {
80 for (const actor of [writer, stranger, undefined]) {
81 const answer = stopMirroring(app, actor, repo);
82 expect(answer.ok).toBe(false);
83 if (!answer.ok) expect(answer.error).toBe("not_found");
84 expect(target()?.fullName).toBe("octo/gizmo");
85 }
86 });
87
88 test("the admin stops it: the target is gone, and a second stop answers false", () => {
89 expect(stopMirroring(app, admin, repo)).toEqual({ ok: true, value: true });
90 expect(target()).toBeUndefined();
91 expect(stopMirroring(app, admin, repo)).toEqual({ ok: true, value: false });
92 });
93
94 test("the site admin may stop it too", () => {
95 arm();
96 expect(stopMirroring(app, siteAdmin, repo)).toEqual({ ok: true, value: true });
97 expect(target()).toBeUndefined();
98 });
99 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs