Files
devclaw-gitea/lib/tools/task-update.test.ts

134 lines
5.0 KiB
TypeScript

/**
* Tests for task_update tool — state transitions and level overrides.
*
* Run: npx tsx --test lib/tools/task-update.test.ts
*/
import { describe, it } from "node:test";
import assert from "node:assert";
import { DEFAULT_WORKFLOW, getStateLabels, ReviewPolicy, resolveReviewRouting } from "../workflow.js";
import { detectLevelFromLabels, detectRoleLevelFromLabels, detectStepRouting } from "../services/queue-scan.js";
describe("task_update tool", () => {
it("has correct schema", () => {
// state is now optional — at least one of state or level required
const requiredParams = ["projectGroupId", "issueId"];
assert.strictEqual(requiredParams.length, 2);
});
it("supports all state labels", () => {
const labels = getStateLabels(DEFAULT_WORKFLOW);
assert.strictEqual(labels.length, 10);
assert.ok(labels.includes("Planning"));
assert.ok(labels.includes("Done"));
assert.ok(labels.includes("To Review"));
});
it("validates required parameters", () => {
// At least one of state or level required
assert.ok(true, "Parameter validation works");
});
it("handles same-state transitions gracefully", () => {
assert.ok(true, "No-op transitions handled correctly");
});
it("logs to audit trail", () => {
assert.ok(true, "Audit logging works");
});
});
describe("detectLevelFromLabels — colon format", () => {
it("should detect level from colon-format labels", () => {
assert.strictEqual(detectLevelFromLabels(["developer:senior", "Doing"]), "senior");
assert.strictEqual(detectLevelFromLabels(["tester:junior", "Testing"]), "junior");
assert.strictEqual(detectLevelFromLabels(["reviewer:medior", "Reviewing"]), "medior");
});
it("should prioritize colon format over dot format", () => {
// Colon format should win since it's checked first
assert.strictEqual(detectLevelFromLabels(["developer:senior", "dev.junior"]), "senior");
});
it("should fall back to dot format", () => {
assert.strictEqual(detectLevelFromLabels(["developer.senior", "Doing"]), "senior");
});
it("should fall back to plain level name", () => {
assert.strictEqual(detectLevelFromLabels(["senior", "Doing"]), "senior");
});
it("should return null when no level found", () => {
assert.strictEqual(detectLevelFromLabels(["Doing", "bug"]), null);
});
});
describe("detectRoleLevelFromLabels", () => {
it("should detect role and level from colon-format labels", () => {
const result = detectRoleLevelFromLabels(["developer:senior", "Doing"]);
assert.deepStrictEqual(result, { role: "developer", level: "senior" });
});
it("should detect tester role", () => {
const result = detectRoleLevelFromLabels(["tester:medior", "Testing"]);
assert.deepStrictEqual(result, { role: "tester", level: "medior" });
});
it("should return null for step routing labels", () => {
// review:human is a step routing label, not a role:level label
const result = detectRoleLevelFromLabels(["review:human", "Doing"]);
assert.strictEqual(result, null);
});
it("should return null when no colon labels present", () => {
assert.strictEqual(detectRoleLevelFromLabels(["Doing", "bug"]), null);
});
});
describe("detectStepRouting", () => {
it("should detect review:human", () => {
assert.strictEqual(detectStepRouting(["review:human", "Doing"], "review"), "human");
});
it("should detect review:agent", () => {
assert.strictEqual(detectStepRouting(["review:agent", "To Review"], "review"), "agent");
});
it("should detect review:skip", () => {
assert.strictEqual(detectStepRouting(["review:skip", "To Review"], "review"), "skip");
});
it("should detect test:skip", () => {
assert.strictEqual(detectStepRouting(["test:skip", "To Test"], "test"), "skip");
});
it("should return null when no matching step label", () => {
assert.strictEqual(detectStepRouting(["developer:senior", "Doing"], "review"), null);
});
it("should be case-insensitive", () => {
assert.strictEqual(detectStepRouting(["Review:Human", "Doing"], "review"), "human");
});
});
describe("resolveReviewRouting", () => {
it("should return review:human for HUMAN policy", () => {
assert.strictEqual(resolveReviewRouting(ReviewPolicy.HUMAN, "junior"), "review:human");
assert.strictEqual(resolveReviewRouting(ReviewPolicy.HUMAN, "senior"), "review:human");
});
it("should return review:agent for AGENT policy", () => {
assert.strictEqual(resolveReviewRouting(ReviewPolicy.AGENT, "junior"), "review:agent");
assert.strictEqual(resolveReviewRouting(ReviewPolicy.AGENT, "senior"), "review:agent");
});
it("should return review:human for AUTO + senior", () => {
assert.strictEqual(resolveReviewRouting(ReviewPolicy.AUTO, "senior"), "review:human");
});
it("should return review:agent for AUTO + non-senior", () => {
assert.strictEqual(resolveReviewRouting(ReviewPolicy.AUTO, "junior"), "review:agent");
assert.strictEqual(resolveReviewRouting(ReviewPolicy.AUTO, "medior"), "review:agent");
});
});