Skip to content
File

Blob: tests/worker/queues/page-projection.workers.test.ts

typescript66 lines
1import { env } from "cloudflare:workers";
2import { ulid } from "ulid";
3import { beforeEach, describe, expect, it } from "vitest";
4 
5import { handlePageProjection } from "@/worker/queues/page-projection";
6import { buildSiteR2ObjectKey, readSiteR2 } from "@/worker/sites/cache";
7import { resetD1Tables } from "@tests/worker/helpers/db";
8import { buildYjsDocBytes, seedDocSyncSnapshot } from "@tests/worker/helpers/do";
9import { seedPage, seedUser, seedWorkspace } from "@tests/worker/helpers/seeds";
10 
11async function clearSitesBucket(): Promise<void> {
12 const listing = await env.SITES.list();
13 await Promise.all(listing.objects.map((object) => env.SITES.delete(object.key)));
14}
15 
16describe("handlePageProjection", () => {
17 beforeEach(async () => {
18 await resetD1Tables();
19 await clearSitesBucket();
20 });
21 
22 it("returns retry when the page is not yet visible in D1", async () => {
23 await expect(handlePageProjection(ulid(), env)).resolves.toEqual({ kind: "retry", delaySeconds: 2 });
24 });
25 
26 it("projects a doc snapshot into the Sites R2 envelope", async () => {
27 const owner = await seedUser();
28 const ws = await seedWorkspace({ owner_id: owner.id });
29 const page = await seedPage({ workspace_id: ws.id, created_by: owner.id, title: "Projected" });
30 await seedDocSyncSnapshot(page.id, buildYjsDocBytes("Projected", "Projected body text"));
31 
32 await expect(handlePageProjection(page.id, env)).resolves.toEqual({ kind: "ok" });
33 
34 const r2 = await readSiteR2(env, ws.id, page.id, page.updated_at);
35 expect(r2?.fresh).toBe(true);
36 expect(r2?.envelope?.updatedAt).toBe(page.updated_at);
37 expect(JSON.stringify(r2?.envelope?.content)).toContain("Projected body text");
38 expect(r2?.envelope?.metrics).toEqual({ words: 3, characters: 19 });
39 });
40 
41 it("writes an empty envelope when a doc snapshot is missing", async () => {
42 const owner = await seedUser();
43 const ws = await seedWorkspace({ owner_id: owner.id });
44 const page = await seedPage({ workspace_id: ws.id, created_by: owner.id, title: "Empty" });
45 
46 await expect(handlePageProjection(page.id, env)).resolves.toEqual({ kind: "ok" });
47 
48 const r2 = await readSiteR2(env, ws.id, page.id, page.updated_at);
49 expect(r2?.fresh).toBe(true);
50 expect(r2?.envelope).toEqual({
51 content: { type: "doc", content: [] },
52 metrics: { words: 0, characters: 0 },
53 updatedAt: page.updated_at,
54 });
55 });
56 
57 it("skips canvas pages", async () => {
58 const owner = await seedUser();
59 const ws = await seedWorkspace({ owner_id: owner.id });
60 const canvas = await seedPage({ workspace_id: ws.id, created_by: owner.id, kind: "canvas", title: "Canvas" });
61 
62 await expect(handlePageProjection(canvas.id, env)).resolves.toEqual({ kind: "ok" });
63 await expect(env.SITES.get(buildSiteR2ObjectKey(ws.id, canvas.id))).resolves.toBeNull();
64 });
65});