Files
PaperClipAI/tests/runner-e2e/chat-catalog-domains/runtime-task-coordination.test.ts
T

27 lines
2.1 KiB
TypeScript

import { it, expect } from "vitest";
import { gradeDependencyCycle } from "./runtime-task-coordination.js";
function valid() {
const website = { id: "website", title: "Website", companyId: "company", status: "backlog", blockedBy: [] };
const design = { id: "design", title: "Design", companyId: "company", status: "backlog", blockedBy: [{ id: "website" }] };
return { scenarioId: "task-coordination.reject-dependency-cycle", origin: "http://fixture.invalid", companyId: "company", leadId: "ceo",
state: { task: website, design }, dependencyTasks: [structuredClone(website), structuredClone(design)], agents: [], tasks: [website, design],
links: ["/ACORN/issues/website", "/ACORN/issues/design"], reply: "Design already depends on Website. That would be circular. Choose which should go first.",
activity: [], runs: [], humanQueries: [] };
}
it("accepts an independently saved acyclic rejection", () => expect(gradeDependencyCycle(valid()).passed).toBe(true));
it("accepts natural actionable cycle explanation", () => { const o = valid(); o.reply = "Design already waits for Website. Adding the reverse edge would make a dependency cycle; tell me which task should go first."; expect(gradeDependencyCycle(o).passed).toBe(true); });
it("rejects missing dependency detail", () => expect(gradeDependencyCycle(undefined).passed).toBe(false));
it("rejects a plausible explanation with the cycle actually saved", () => {
const o = valid(); o.dependencyTasks[0]!.blockedBy = [{ id: "design" }]; expect(gradeDependencyCycle(o).passed).toBe(false);
});
it("rejects silently deleting the original prerequisite", () => {
const o = valid(); o.dependencyTasks[1]!.blockedBy = []; expect(gradeDependencyCycle(o).passed).toBe(false);
});
it("rejects a conflict with no actionable order decision", () => {
const o = valid(); o.reply = "Website and Design form a cycle."; expect(gradeDependencyCycle(o).passed).toBe(false);
});
it("accepts a saved acyclic rejection naming both tasks without mandatory chat hrefs", () => {
const o = valid(); o.links = []; expect(gradeDependencyCycle(o).passed).toBe(true);
});