import { describe, expect, it } from "bun:test";
import { Effect, Schema } from "effect";
import {
WorklogSchema,
WorklogsResponseSchema,
IntakeIssueSchema,
IntakeIssuesResponseSchema,
PageSchema,
PagesResponseSchema,
CommentSchema,
CommentsResponseSchema,
CycleIssueSchema,
CycleIssuesResponseSchema,
} from "@/config";
async function decode(
schema: Schema.Schema,
data: unknown,
): Promise {
return Effect.runPromise(
Schema.decodeUnknown(schema)(data).pipe(
Effect.mapError((e) => new Error(String(e))),
),
);
}
describe("WorklogSchema", () => {
it("decodes a full worklog", async () => {
const w = await decode(WorklogSchema, {
id: "w1",
description: "Code review",
duration: 90,
logged_by_detail: { display_name: "Aaron" },
created_at: "2025-01-15T10:00:00Z",
});
expect(w.duration).toBe(90);
expect(w.logged_by_detail?.display_name).toBe("Aaron");
});
it("decodes with null description", async () => {
const w = await decode(WorklogSchema, {
id: "w2",
description: null,
duration: 30,
created_at: "2025-01-15T10:00:00Z",
});
expect(w.description).toBeNull();
});
it("rejects missing duration", async () => {
await expect(
decode(WorklogSchema, { id: "w3", created_at: "2025-01-15T10:00:00Z" }),
).rejects.toThrow();
});
});
describe("WorklogsResponseSchema", () => {
it("decodes results", async () => {
const resp = await decode(WorklogsResponseSchema, {
results: [{ id: "w1", duration: 60, created_at: "2025-01-15T10:00:00Z" }],
});
expect(resp.results).toHaveLength(1);
});
it("decodes empty", async () => {
const resp = await decode(WorklogsResponseSchema, { results: [] });
expect(resp.results).toHaveLength(0);
});
});
describe("IntakeIssueSchema", () => {
it("decodes a full intake issue", async () => {
const i = await decode(IntakeIssueSchema, {
id: "int1",
issue: "issue-uuid",
issue_detail: {
id: "issue-uuid",
sequence_id: 42,
name: "Bug report",
priority: "high",
},
status: 0,
created_at: "2025-01-15T10:00:00Z",
});
expect(i.status).toBe(0);
expect(i.issue_detail?.sequence_id).toBe(42);
});
it("decodes minimal intake issue", async () => {
const i = await decode(IntakeIssueSchema, {
id: "int2",
created_at: "2025-01-15T10:00:00Z",
});
expect(i.id).toBe("int2");
expect(i.status).toBeUndefined();
});
it("rejects missing id", async () => {
await expect(
decode(IntakeIssueSchema, { created_at: "2025-01-15T10:00:00Z" }),
).rejects.toThrow();
});
});
describe("IntakeIssuesResponseSchema", () => {
it("decodes results", async () => {
const resp = await decode(IntakeIssuesResponseSchema, {
results: [{ id: "int1", created_at: "2025-01-15T10:00:00Z" }],
});
expect(resp.results).toHaveLength(1);
});
});
describe("PageSchema", () => {
it("decodes a page", async () => {
const p = await decode(PageSchema, {
id: "pg1",
name: "Architecture Overview",
created_at: "2025-01-15T10:00:00Z",
updated_at: "2025-01-16T10:00:00Z",
});
expect(p.name).toBe("Architecture Overview");
expect(p.updated_at).toBe("2025-01-16T10:00:00Z");
});
it("accepts null description_html", async () => {
const p = await decode(PageSchema, {
id: "pg2",
name: "Empty page",
description_html: null,
created_at: "2025-01-15T10:00:00Z",
});
expect(p.description_html).toBeNull();
});
it("rejects missing name", async () => {
await expect(
decode(PageSchema, { id: "pg3", created_at: "2025-01-15T10:00:00Z" }),
).rejects.toThrow();
});
});
describe("PagesResponseSchema", () => {
it("decodes results", async () => {
const resp = await decode(PagesResponseSchema, {
results: [
{ id: "pg1", name: "Arch", created_at: "2025-01-15T10:00:00Z" },
],
});
expect(resp.results[0].name).toBe("Arch");
});
});
describe("CommentSchema", () => {
it("decodes a comment", async () => {
const c = await decode(CommentSchema, {
id: "c1",
comment_html: "Hello
",
actor_detail: { display_name: "Aaron" },
created_at: "2025-01-15T10:00:00Z",
});
expect(c.comment_html).toBe("Hello
");
expect(c.actor_detail?.display_name).toBe("Aaron");
});
it("decodes without optional fields", async () => {
const c = await decode(CommentSchema, {
id: "c2",
created_at: "2025-01-15T10:00:00Z",
});
expect(c.id).toBe("c2");
});
it("rejects missing id", async () => {
await expect(
decode(CommentSchema, { created_at: "2025-01-15T10:00:00Z" }),
).rejects.toThrow();
});
});
describe("CommentsResponseSchema", () => {
it("decodes results", async () => {
const resp = await decode(CommentsResponseSchema, {
results: [{ id: "c1", created_at: "2025-01-15T10:00:00Z" }],
});
expect(resp.results).toHaveLength(1);
});
});
describe("CycleIssueSchema", () => {
it("decodes with detail", async () => {
const ci = await decode(CycleIssueSchema, {
id: "ci1",
issue: "i1",
issue_detail: { id: "i1", sequence_id: 5, name: "Fix bug" },
});
expect(ci.issue_detail?.sequence_id).toBe(5);
});
it("decodes without detail", async () => {
const ci = await decode(CycleIssueSchema, { id: "ci2", issue: "i2" });
expect(ci.issue).toBe("i2");
});
it("rejects missing issue", async () => {
await expect(decode(CycleIssueSchema, { id: "ci3" })).rejects.toThrow();
});
});
describe("CycleIssuesResponseSchema", () => {
it("decodes results", async () => {
const resp = await decode(CycleIssuesResponseSchema, {
results: [{ id: "ci1", issue: "i1" }],
});
expect(resp.results).toHaveLength(1);
});
});