import { describe, expect, mock, test } from "bun:test"; import type { RepoRow, Viewer } from "~/lib/types"; import type { WorkflowRunRow } from "./jobs"; mock.module("cloudflare:workers", () => ({ env: {}, waitUntil: () => undefined })); const repos = new Map(); const actualRepos = await import("../repos"); mock.module("../repos", () => ({ ...actualRepos, loadRepoById: async (id: string) => repos.get(id) ?? null })); const actualPulls = await import("../pulls"); mock.module("../pulls", () => ({ ...actualPulls, loadPull: async () => null })); mock.module("../scoped-db", () => ({ repoDb: () => ({ first: async () => null }) })); mock.module("./event-triggers", () => ({ toExprValue: (value: unknown) => value })); const { rerunTrigger } = await import("./rerun"); const { HttpError } = await import("../errors"); const base = { id: "base-repo", owner_id: "org", name: "app" } as RepoRow; const fork = { id: "fork-repo", owner_id: "mallory", name: "app" } as RepoRow; const viewer = { id: "maintainer", name: "maintainer" } as Viewer; function run(overrides: Partial): WorkflowRunRow { return { id: "run", repo_id: base.id, source_repo_id: base.id, run_number: 1, workflow_path: ".gitfor/workflows/ci.yml", workflow_name: "ci", event: "pull_request", ref: "refs/pull/1/merge", sha: "a".repeat(40), title: "PR", actor_id: "mallory", pr_number: null, approval_required: 0, workflow_source: null, context: null, trigger_depth: 0, rerun_of: null, untrusted: 0, status: "completed", conclusion: "failure", created_at: 0, started_at: null, completed_at: null, ...overrides, }; } describe("re-running a fork pull request run", () => { test("stays untrusted while the fork exists", async () => { repos.set(fork.id, fork); const trigger = await rerunTrigger(base, run({ source_repo_id: fork.id }), viewer); expect(trigger.sourceRepo.id).toBe(fork.id); expect(trigger.untrusted).toBe(true); repos.delete(fork.id); }); test("is refused once the fork is deleted instead of running its commit as trusted base code", async () => { const error = await rerunTrigger(base, run({ source_repo_id: fork.id }), viewer).catch((caught: unknown) => caught); expect(error).toBeInstanceOf(HttpError); }); test("a run of the repository's own code keeps its trust", async () => { const trigger = await rerunTrigger(base, run({ event: "push", ref: "refs/heads/main" }), viewer); expect(trigger.sourceRepo.id).toBe(base.id); expect(trigger.untrusted).toBe(false); }); });