import { beforeEach, describe, expect, mock, test } from "bun:test"; import { scopedTestState } from "./scoped.test-helper"; const kv = new Map(); mock.module("cloudflare:workers", () => ({ env: { KV: { get: async (key: string) => kv.get(key) ?? null, put: async (key: string, value: string) => void kv.set(key, value), }, }, waitUntil: () => undefined, })); mock.module("./directory", () => ({ forgetSiteDirectory: async () => undefined })); const repos: Record = { u1: ["r1", "r2"] }; mock.module("../db", () => ({ all: async (_sql: string, ownerId: string) => (repos[ownerId] ?? []).map((id) => ({ id })), })); const scoped = scopedTestState(); scoped.install(); const { backfillDomainSites, backfillOwnedSites, domainSites, forgetSite, ownerSiteScopes, registerOwnedSite } = await import("./store"); beforeEach(() => { kv.clear(); scoped.reset(); scoped.site({ id: "s1", repo_id: "r1", owner_id: "u1" }); scoped.site({ id: "s2", owner_id: "u1" }); scoped.site({ id: "s3", owner_id: "u2" }); scoped.site({ id: "s4" }); }); describe("owner site scopes", () => { test("before the backfill every repo-less site scope is a candidate", async () => { expect((await ownerSiteScopes("u1")).sort()).toEqual(["r1", "site:s2", "site:s3", "site:s4"]); }); test("after the backfill only the owner's claimed sites and repositories holding a site", async () => { await backfillOwnedSites(); expect(kv.get("backfill:owner-site-locators")).toBe("done"); expect((await ownerSiteScopes("u1")).sort()).toEqual(["r1", "site:s2"]); expect(await ownerSiteScopes("u2")).toEqual(["site:s3"]); expect(await ownerSiteScopes("u")).toEqual([]); }); test("a claim indexes the site and deleting it drops the entry", async () => { kv.set("backfill:owner-site-locators", "done"); await registerOwnedSite("u2", "s3"); scoped.site({ id: "s5", owner_id: "u2" }); await registerOwnedSite("u2", "s5"); expect((await ownerSiteScopes("u2")).sort()).toEqual(["site:s3", "site:s5"]); await forgetSite({ id: "s5", label: "s5", custom_domain: null, owner_id: "u2", repo_id: null }); expect(await ownerSiteScopes("u2")).toEqual(["site:s3"]); }); }); describe("domain sites", () => { test("only indexed scopes are visited once the backfill is done, and deletion drops the entry", async () => { scoped.site({ id: "d1", repo_id: "r2", owner_id: "u1", custom_domain: "a.example" }); scoped.site({ id: "d2", owner_id: "u2", custom_domain: "b.example" }); expect((await domainSites()).map((site) => site.id).sort()).toEqual(["d1", "d2"]); await backfillDomainSites(); expect(scoped.locate("site_domain", "d1")).toBe("r2"); scoped.repo("r1").run("UPDATE sites SET custom_domain = 'stray.example' WHERE id = 's1'"); expect((await domainSites("owner_id = ?", "u1")).map((site) => site.id)).toEqual(["d1"]); await forgetSite({ id: "d2", label: "d2", custom_domain: "b.example", owner_id: "u2", repo_id: null }); expect(scoped.locate("site_domain", "d2")).toBeNull(); }); });