135 lines
3.6 KiB
TypeScript
135 lines
3.6 KiB
TypeScript
import { Effect } from "effect";
|
|
import { describe, expect, test } from "vitest";
|
|
|
|
import {
|
|
projectWorkNotices,
|
|
signalAttachedEvent,
|
|
workDraftFromSignal,
|
|
workProposedEventFromSignal,
|
|
} from "./work";
|
|
|
|
describe("workDraftFromSignal", () => {
|
|
test("creates a proposed Work draft from Signal meaning", async () => {
|
|
const draft = await Effect.runPromise(
|
|
workDraftFromSignal({
|
|
desiredOutcome: "The phone flow is usable.",
|
|
summary: "The current mobile workspace is hard to test.",
|
|
title: "Make Slice 1 phone-testable",
|
|
})
|
|
);
|
|
|
|
expect(draft).toEqual({
|
|
objective: "The phone flow is usable.",
|
|
title: "Make Slice 1 phone-testable",
|
|
});
|
|
});
|
|
|
|
test("rejects empty Signal meaning", async () => {
|
|
await expect(
|
|
Effect.runPromise(
|
|
workDraftFromSignal({ desiredOutcome: "", summary: "", title: "" })
|
|
)
|
|
).rejects.toMatchObject({ reason: "InvalidInput" });
|
|
});
|
|
|
|
test("constructs stable proposed and attached event drafts", async () => {
|
|
const proposed = await Effect.runPromise(
|
|
workProposedEventFromSignal({
|
|
organizationId: "org-1",
|
|
projectId: "project-1",
|
|
signalId: "signal-1",
|
|
title: " Improve the phone flow ",
|
|
})
|
|
);
|
|
const attached = await Effect.runPromise(
|
|
signalAttachedEvent({
|
|
signal: {
|
|
organizationId: "org-1",
|
|
projectId: "project-1",
|
|
signalId: "signal-2",
|
|
title: "Reuse the existing outcome",
|
|
},
|
|
work: {
|
|
organizationId: "org-1",
|
|
projectId: "project-1",
|
|
workId: "work-1",
|
|
},
|
|
})
|
|
);
|
|
|
|
expect(proposed).toEqual({
|
|
data: { signalId: "signal-1", title: "Improve the phone flow" },
|
|
idempotencyKey: "proposed:signal-1",
|
|
kind: "work.proposed",
|
|
});
|
|
expect(attached).toEqual({
|
|
data: { signalId: "signal-2", title: "Reuse the existing outcome" },
|
|
idempotencyKey: "signal:signal-2",
|
|
kind: "signal.attached",
|
|
});
|
|
});
|
|
|
|
test("rejects a cross-project attachment", async () => {
|
|
await expect(
|
|
Effect.runPromise(
|
|
signalAttachedEvent({
|
|
signal: {
|
|
organizationId: "org-1",
|
|
projectId: "project-2",
|
|
signalId: "signal-1",
|
|
title: "Cross project",
|
|
},
|
|
work: {
|
|
organizationId: "org-1",
|
|
projectId: "project-1",
|
|
workId: "work-1",
|
|
},
|
|
})
|
|
)
|
|
).rejects.toMatchObject({ reason: "ProjectMismatch" });
|
|
});
|
|
|
|
test("projects proposed Work events into chronological notices", () => {
|
|
expect(
|
|
projectWorkNotices([
|
|
{
|
|
_id: "work-2",
|
|
events: [{ _id: "event-2", createdAt: 20, kind: "work.proposed" }],
|
|
signals: [
|
|
{
|
|
sources: [{ messageId: "message-2", rawText: "Second" }],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
_id: "work-1",
|
|
events: [
|
|
{ _id: "event-1", createdAt: 10, kind: "work.proposed" },
|
|
{ _id: "event-3", createdAt: 30, kind: "signal.attached" },
|
|
],
|
|
signals: [
|
|
{
|
|
sources: [{ messageId: "message-1", rawText: "First" }],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
).toEqual([
|
|
{
|
|
createdAt: 10,
|
|
eventId: "event-1",
|
|
sourceMessageIds: ["message-1"],
|
|
sourceTexts: ["First"],
|
|
workId: "work-1",
|
|
},
|
|
{
|
|
createdAt: 20,
|
|
eventId: "event-2",
|
|
sourceMessageIds: ["message-2"],
|
|
sourceTexts: ["Second"],
|
|
workId: "work-2",
|
|
},
|
|
]);
|
|
});
|
|
});
|