import { describe, expect, mock, test } from "bun:test"; const kv = new Map(); mock.module("cloudflare:workers", () => ({ env: { KV: { get: async (key: string) => kv.get(key) ?? null, put: async () => undefined } }, })); mock.module("./db", () => ({ all: async () => [{ id: "every-repo" }], first: async () => null, run: async () => ({ meta: { changes: 0 } }), chunks: (items: T[]) => [items], })); const { memoryScopes } = await import("./scoped-db/testing"); const scopes = memoryScopes(); mock.module("./scoped-db", () => scopes.module); const { activityRepoIds, activityTouches, indexActivity } = await import("./activity-index"); const { repoActivityStatement } = await import("./issue-scope"); describe("activity index", () => { test("picks counted activity inserts out of a batch", () => { const statements = [ repoActivityStatement("alice", "repo-1", "issue_opened", {}), repoActivityStatement("alice", "repo-1", "view", {}), repoActivityStatement(null, "repo-1", "issue_opened", {}), { sql: "UPDATE issues SET title = ?", params: ["x"] }, ]; expect(activityTouches(statements).map((touch) => [touch.actorId, touch.repoId])).toEqual([["alice", "repo-1"]]); }); test("before the backfill is done every repository is a candidate; afterwards only indexed ones in range", async () => { expect(await activityRepoIds("alice", null)).toEqual(["every-repo"]); await indexActivity([ { actorId: "alice", repoId: "old", at: 100 }, { actorId: "alice", repoId: "recent", at: 5_000 }, { actorId: "alice", repoId: "recent", at: 9_000 }, ]); kv.set("backfill:activity-repos", "done"); expect((await activityRepoIds("alice", null)).sort()).toEqual(["old", "recent"]); expect(await activityRepoIds("alice", { start: 1_000, end: 10_000 })).toEqual(["recent"]); expect(await activityRepoIds("bob", { start: 0, end: 10_000 })).toEqual([]); }); });