kanban-dev-webapp/tests/integration/summarise.test.ts

97 lines
2.9 KiB
TypeScript

import { describe, it, expect, beforeAll, afterAll } from "vitest";
import PocketBase from "pocketbase";
import { DEMO, adminPb, requireServices } from "./helpers";
let admin: PocketBase;
let projectId: string;
const created: string[] = [];
beforeAll(async () => {
await requireServices();
admin = await adminPb();
projectId = (
await admin.collection("projects").getFirstListItem(`slug = "${DEMO.projectSlug}"`)
).id;
});
afterAll(async () => {
for (const id of created) {
await admin.collection("commits").delete(id).catch(() => {});
}
});
describe("merge commits are never summarised", () => {
it("excludes them from the pending set", async () => {
const { summaryStatus } = await import("@/lib/ai/summarise");
const status = await summaryStatus(projectId);
const merges = (
await admin
.collection("commits")
.getList(1, 1, { filter: `project = "${projectId}" && is_merge = true`, fields: "id" })
).totalItems;
const all = (
await admin
.collection("commits")
.getList(1, 1, { filter: `project = "${projectId}"`, fields: "id" })
).totalItems;
// status.total counts non-merge commits only.
expect(status.total).toBe(all - merges);
expect(merges).toBeGreaterThan(0);
});
});
describe("summarisation degrades rather than failing", () => {
it("returns a skipped result when no provider is configured", async () => {
const settings = await admin
.collection("settings")
.getFirstListItem("id != ''")
.catch(() => null);
const previousKey = settings?.ai_api_key ?? "";
if (settings) {
await admin.collection("settings").update(settings.id, { ai_api_key: "" });
}
const { summariseProject } = await import("@/lib/ai/summarise");
const result = await summariseProject(projectId);
// Must not throw. The dashboard and board depend on this.
expect(result.skipped).toBe(true);
expect(result.summarised).toBe(0);
if (settings && previousKey) {
await admin.collection("settings").update(settings.id, { ai_api_key: previousKey });
}
});
});
describe("a stored summary survives re-ingestion", () => {
it("is not cleared when the same commit arrives again", async () => {
const commit = await admin.collection("commits").create({
project: projectId,
sha: `summary-probe-${Date.now()}`,
short_sha: "sumprb",
message: "feat(probe): a thing",
subject: "a thing",
type: "feat",
scope: "probe",
authored_at: new Date().toISOString(),
is_merge: false,
link_source: "none",
summary: "Did a thing for the client.",
summary_version: 1,
summary_attempts: 0,
});
created.push(commit.id);
const { relinkProject } = await import("@/lib/linking/engine");
await relinkProject(projectId);
const after = await admin.collection("commits").getOne(commit.id);
expect(after.summary).toBe("Did a thing for the client.");
});
});