paperclip/ui/src/lib/optimistic-issue-comments.test.ts

141 lines
4 KiB
TypeScript
Raw Normal View History

import { describe, expect, it } from "vitest";
import {
applyOptimisticIssueCommentUpdate,
createOptimisticIssueComment,
mergeIssueComments,
upsertIssueComment,
} from "./optimistic-issue-comments";
describe("optimistic issue comments", () => {
it("creates a pending optimistic comment for the current user", () => {
const comment = createOptimisticIssueComment({
companyId: "company-1",
issueId: "issue-1",
body: "Working on it",
authorUserId: "board-1",
});
expect(comment.id).toMatch(/^optimistic-/);
expect(comment.clientId).toBe(comment.id);
expect(comment.clientStatus).toBe("pending");
expect(comment.authorUserId).toBe("board-1");
expect(comment.authorAgentId).toBeNull();
});
it("merges optimistic comments into the server thread in chronological order", () => {
const merged = mergeIssueComments(
[
{
id: "comment-2",
companyId: "company-1",
issueId: "issue-1",
authorAgentId: null,
authorUserId: "board-1",
body: "Second",
createdAt: new Date("2026-03-28T14:00:02.000Z"),
updatedAt: new Date("2026-03-28T14:00:02.000Z"),
},
],
[
{
id: "optimistic-1",
clientId: "optimistic-1",
clientStatus: "pending",
companyId: "company-1",
issueId: "issue-1",
authorAgentId: null,
authorUserId: "board-1",
body: "First",
createdAt: new Date("2026-03-28T14:00:01.000Z"),
updatedAt: new Date("2026-03-28T14:00:01.000Z"),
},
],
);
expect(merged.map((comment) => comment.id)).toEqual(["optimistic-1", "comment-2"]);
});
it("upserts confirmed comments without creating duplicates", () => {
const next = upsertIssueComment(
[
{
id: "comment-1",
companyId: "company-1",
issueId: "issue-1",
authorAgentId: null,
authorUserId: "board-1",
body: "Original",
createdAt: new Date("2026-03-28T14:00:00.000Z"),
updatedAt: new Date("2026-03-28T14:00:00.000Z"),
},
],
{
id: "comment-1",
companyId: "company-1",
issueId: "issue-1",
authorAgentId: null,
authorUserId: "board-1",
body: "Updated",
createdAt: new Date("2026-03-28T14:00:00.000Z"),
updatedAt: new Date("2026-03-28T14:00:05.000Z"),
},
);
expect(next).toHaveLength(1);
expect(next[0]?.body).toBe("Updated");
});
it("applies optimistic reopen and reassignment updates to the issue cache", () => {
const next = applyOptimisticIssueCommentUpdate(
{
id: "issue-1",
companyId: "company-1",
projectId: null,
projectWorkspaceId: null,
goalId: null,
parentId: null,
title: "Fix comment flow",
description: null,
status: "done",
priority: "medium",
assigneeAgentId: "agent-1",
assigneeUserId: null,
checkoutRunId: null,
executionRunId: null,
executionAgentNameKey: null,
executionLockedAt: null,
createdByAgentId: null,
createdByUserId: "board-1",
issueNumber: 1,
identifier: "PAP-1",
originKind: "manual",
originId: null,
originRunId: null,
requestDepth: 0,
billingCode: null,
assigneeAdapterOverrides: null,
executionWorkspaceId: null,
executionWorkspacePreference: null,
executionWorkspaceSettings: null,
startedAt: null,
completedAt: null,
cancelledAt: null,
hiddenAt: null,
createdAt: new Date("2026-03-28T14:00:00.000Z"),
updatedAt: new Date("2026-03-28T14:00:00.000Z"),
},
{
reopen: true,
reassignment: {
assigneeAgentId: null,
assigneeUserId: "board-2",
},
},
);
expect(next?.status).toBe("todo");
expect(next?.assigneeAgentId).toBeNull();
expect(next?.assigneeUserId).toBe("board-2");
});
});