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);
});
});