import { Effect } from "effect"; import { describe, expect, it } from "vitest"; import { decodeProjectIssueRequest, ProjectIssueTransitionError, ProjectIssueValidationError, projectIssueDraftFromSignal, queueProjectIssue, validateProjectIssueDraft, } from "./project-issue"; describe("project issue primitives", () => { it("normalizes an explicit project request", () => { const request = Effect.runSync( decodeProjectIssueRequest({ body: " Investigate the staging failure. ", kind: "explicit", projectId: "project-1", title: " Staging failure ", }) ); expect(request).toEqual({ body: "Investigate the staging failure.", kind: "explicit", projectId: "project-1", title: "Staging failure", }); }); it("rejects invalid issue drafts before persistence", () => { const error = Effect.runSync( Effect.flip( validateProjectIssueDraft({ body: "too short", title: "No", }) ) ); expect(error).toBeInstanceOf(ProjectIssueValidationError); expect(error.reason).toBe("TitleTooShort"); }); it("projects a project Signal into the existing issue shape", () => { const draft = Effect.runSync( projectIssueDraftFromSignal({ problemStatement: { constraints: ["Do not change production"], desiredOutcome: "Staging deploys successfully", summary: "The deploy fails during DNS resolution", title: "Fix staging deploy DNS failure", }, signalId: "signal-1", }) ); expect(draft.title).toBe("Fix staging deploy DNS failure"); expect(draft.body).toContain("The deploy fails during DNS resolution"); expect(draft.body).toContain("Source Signal: signal-1"); }); it("queues retryable issue states and preserves active states", () => { expect(Effect.runSync(queueProjectIssue("open"))).toBe("queued"); expect(Effect.runSync(queueProjectIssue("failed"))).toBe("queued"); expect(Effect.runSync(queueProjectIssue("needs-input"))).toBe("queued"); expect(Effect.runSync(queueProjectIssue("working"))).toBe("working"); }); it("does not reopen completed issues", () => { const error = Effect.runSync(Effect.flip(queueProjectIssue("completed"))); expect(error).toBeInstanceOf(ProjectIssueTransitionError); expect(error.reason).toBe("CompletedIssue"); }); });