diff --git a/tests/integration/narrative.test.ts b/tests/integration/narrative.test.ts new file mode 100644 index 0000000..6e83657 --- /dev/null +++ b/tests/integration/narrative.test.ts @@ -0,0 +1,76 @@ +import { describe, it, expect, beforeAll } from "vitest"; +import PocketBase from "pocketbase"; + +import { APP_URL, DEMO, adminPb, requireServices, signIn } from "./helpers"; + +let admin: PocketBase; +let projectId: string; + +beforeAll(async () => { + await requireServices(); + admin = await adminPb(); + projectId = ( + await admin.collection("projects").getFirstListItem(`slug = "${DEMO.projectSlug}"`) + ).id; +}); + +describe("a card with no commits gets no narrative", () => { + it("is left empty rather than invented", async () => { + const { narrateProject } = await import("@/lib/ai/narrate"); + await narrateProject(projectId); + + const cards = await admin.collection("cards").getFullList({ + filter: `project = "${projectId}" && archived = false`, + fields: "id,narrative", + }); + + for (const card of cards) { + const linked = ( + await admin + .collection("commits") + .getList(1, 1, { filter: `card = "${card.id}"`, fields: "id" }) + ).totalItems; + + if (linked === 0) { + expect(card.narrative ?? "").toBe(""); + } + } + }); +}); + +describe("the card page always shows something for a commit", () => { + it("falls back to the raw subject when there is no summary", async () => { + const card = await admin + .collection("cards") + .getFirstListItem(`project = "${projectId}"`); + + const marker = `raw-subject-probe-${Date.now()}`; + const commit = await admin.collection("commits").create({ + project: projectId, + sha: `narrative-probe-${Date.now()}`, + short_sha: "narprb", + message: `feat(probe): ${marker}`, + subject: `feat(probe): ${marker}`, + type: "feat", + scope: "probe", + authored_at: new Date().toISOString(), + is_merge: false, + card: card.id, + link_source: "manual", + summary: "", + }); + + const cookie = await signIn(DEMO.managerEmail, DEMO.managerPassword); + const response = await fetch( + `${APP_URL}/p/${DEMO.clientSlug}/${DEMO.projectSlug}/c/${card.id}`, + { headers: { cookie } } + ); + const html = await response.text(); + + expect(response.status).toBe(200); + // A gap here would look to the client like no work happened. + expect(html).toContain(marker); + + await admin.collection("commits").delete(commit.id); + }); +});