import { describe, expect, mock, test } from "bun:test"; import type { RepoRow } from "~/lib/types"; const writers = new Set(["maintainer", "base-owner"]); mock.module("cloudflare:workers", () => ({ DurableObject: class {}, env: {}, waitUntil: () => undefined })); mock.module("../pull-events", () => { const forkRunNeedsApproval = async (baseRepo: RepoRow, headRepo: RepoRow, actorId: string | null) => baseRepo.id !== headRepo.id && !(actorId !== null && writers.has(actorId)); return { forkRunNeedsApproval, forkPullNeedsApproval: async (baseRepo: RepoRow, headRepo: RepoRow, authorId: string) => (await forkRunNeedsApproval(baseRepo, headRepo, authorId)) || forkRunNeedsApproval(baseRepo, headRepo, headRepo.owner_id), }; }); const { forkPushNeedsApproval } = await import("./fork-approval"); function repo(id: string, ownerId: string): RepoRow { return Object.assign(Object.create(null), { id, owner_id: ownerId }); } const base = repo("base", "base-owner"); describe("fork push approval", () => { test("a trusted pusher can't approve an untrusted author's fork", async () => { expect(await forkPushNeedsApproval(base, repo("fork", "stranger"), "stranger", "maintainer")).toBe(true); }); test("an untrusted pusher can't ride a trusted author's fork", async () => { expect(await forkPushNeedsApproval(base, repo("fork", "maintainer"), "maintainer", "stranger")).toBe(true); }); test("everyone trusted, or same-repo pulls, run without approval", async () => { expect(await forkPushNeedsApproval(base, repo("fork", "maintainer"), "maintainer", "maintainer")).toBe(false); expect(await forkPushNeedsApproval(base, base, "stranger", "stranger")).toBe(false); }); });