import { beforeEach, describe, expect, mock, test } from "bun:test"; import { memoryScopes } from "./scoped-db/testing"; class StubEntrypoint {} mock.module("cloudflare:workers", () => ({ env: {}, waitUntil: () => undefined, WorkflowEntrypoint: StubEntrypoint, DurableObject: StubEntrypoint, WorkerEntrypoint: StubEntrypoint, })); const ZERO = "0".repeat(40); let scopes = memoryScopes(); let forkOf: string | null = null; mock.module("./db", () => ({ all: async () => [], first: async () => ({ fork_of_id: forkOf }), run: async () => ({ meta: { changes: 0 } }), batch: async () => [], stmt: () => ({}), placeholders: () => "", chunks: (items: T[]) => [items], MAX_IN_LIST: 90, })); mock.module("./scoped-db", () => ({ repoDb: (id: string) => scopes.repoDb(id), accountDb: (id: string) => scopes.accountDb(id), stmt: (sql: string, ...params: unknown[]) => ({ sql, params }), })); const { recentBranchPushesFor } = await import("./branch-pushes"); const repo = { id: "r1", default_branch: "main" }; function push(repoId: string, ref: string, after: string, at: number, pusher = "u1") { scopes .raw("repo", repoId) .query( "INSERT INTO push_events (id, repo_id, ref, before_sha, after_sha, pusher_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)", ) .run(crypto.randomUUID(), repoId, ref, ZERO, after, pusher, at); } function openPull(baseId: string, headRepoId: string, headRef: string, number: number) { const db = scopes.raw("repo", baseId); const id = `${baseId}-${number}`; db.query( "INSERT INTO issues (id, repo_id, number, author_id, title, state, is_pull, created_at, updated_at) VALUES (?, ?, ?, 'u1', 't', 'open', 1, 0, 0)", ).run(id, baseId, number); db.query( "INSERT INTO pull_requests (issue_id, repo_id, head_repo_id, head_ref, head_sha, base_ref, base_sha) VALUES (?, ?, ?, ?, 'x', 'main', 'y')", ).run(id, baseId, headRepoId, headRef); } beforeEach(() => { scopes = memoryScopes(); forkOf = null; }); describe("recentBranchPushesFor", () => { test("skips default branch, deletions, older pushes of a ref and caps at three newest", async () => { push("r1", "refs/heads/main", "a".repeat(40), 900); push("r1", "refs/heads/gone", ZERO, 800); push("r1", "refs/heads/one", "b".repeat(40), 700); push("r1", "refs/heads/one", "c".repeat(40), 650); push("r1", "refs/heads/two", "d".repeat(40), 600); push("r1", "refs/heads/three", "e".repeat(40), 500); push("r1", "refs/heads/four", "f".repeat(40), 400); push("r1", "refs/heads/other", "f".repeat(40), 950, "u2"); expect(await recentBranchPushesFor(repo, "u1", 1000)).toEqual([ { branch: "one", pushedAt: 700 }, { branch: "two", pushedAt: 600 }, { branch: "three", pushedAt: 500 }, ]); }); test("only counts the two hour window", async () => { const now = 10 * 60 * 60 * 1000; push("r1", "refs/heads/old", "a".repeat(40), now - 3 * 60 * 60 * 1000); expect(await recentBranchPushesFor(repo, "u1", now)).toEqual([]); }); test("leaves out branches with an open pull request here or in the parent", async () => { forkOf = "parent"; push("r1", "refs/heads/local", "a".repeat(40), 900); push("r1", "refs/heads/upstream", "b".repeat(40), 800); push("r1", "refs/heads/free", "c".repeat(40), 700); openPull("r1", "r1", "local", 1); openPull("parent", "r1", "upstream", 1); expect(await recentBranchPushesFor(repo, "u1", 1000)).toEqual([{ branch: "free", pushedAt: 700 }]); }); });