Files
IdeA/frontend/src/adapters/ticket.test.ts
Blomios 712b19ed10 fix(tickets): normalise createdBy manquant sur les payloads legacy
Les tickets legacy sans champ createdBy faisaient noircir la fenêtre
tickets côté frontend. Les adapters (ticket.ts, streamGateways.ts)
normalisent désormais ce champ absent, avec couverture de test dédiée.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 14:19:50 +02:00

166 lines
4.3 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from "vitest";
const invoke = vi.fn();
vi.mock("@tauri-apps/api/core", () => ({
invoke: (...args: unknown[]) => invoke(...args),
Channel: class {
onmessage: ((chunk: unknown) => void) | null = null;
},
}));
import { TauriTicketGateway } from "./ticket";
describe("TauriTicketGateway invoke payloads", () => {
beforeEach(() => invoke.mockReset().mockResolvedValue({ items: [] }));
it("bulk status wraps refs and status in the request DTO", async () => {
await new TauriTicketGateway().bulkUpdateStatus(
"proj-1",
["#1", "#2"],
"inProgress",
);
expect(invoke).toHaveBeenCalledWith("ticket_bulk_update_status", {
request: {
projectId: "proj-1",
refs: ["#1", "#2"],
status: "inProgress",
},
});
});
it("bulk delete wraps refs in the request DTO", async () => {
await new TauriTicketGateway().bulkDelete("proj-1", ["#3", "#4"]);
expect(invoke).toHaveBeenCalledWith("ticket_bulk_delete", {
request: {
projectId: "proj-1",
refs: ["#3", "#4"],
},
});
});
it("passes createdBy through the ticket list request DTO", async () => {
await new TauriTicketGateway().list("proj-1", {
createdBy: { kind: "agent", agentId: "agent-1" },
});
expect(invoke).toHaveBeenCalledWith("ticket_list", {
request: {
projectId: "proj-1",
statuses: [],
priorities: [],
createdBy: { kind: "agent", agentId: "agent-1" },
},
});
});
it("normalizes legacy ticket list rows that omit assignedAgentIds and createdBy", async () => {
invoke.mockResolvedValueOnce({
items: [
{
ref: "#12",
path: ".ideai/tickets/12/issue.md",
title: "Legacy row",
status: "open",
priority: "medium",
updatedAt: 1,
},
],
});
const list = await new TauriTicketGateway().list("proj-1");
expect(list.items[0]?.assignedAgentIds).toEqual([]);
expect(list.items[0]?.createdBy).toEqual({ kind: "user" });
});
it("wraps ticket attachment commands in the request DTO", async () => {
const gateway = new TauriTicketGateway();
await gateway.addAttachment(
"proj-1",
"#12",
"/tmp/note.txt",
3,
"text/plain",
);
await gateway.readAttachment("proj-1", "#12", "att-1");
await gateway.markAttachmentSummarized("proj-1", "#12", "att-1", 4);
expect(invoke).toHaveBeenNthCalledWith(1, "ticket_attachment_add", {
request: {
projectId: "proj-1",
ref: "#12",
path: "/tmp/note.txt",
expectedVersion: 3,
mime: "text/plain",
},
});
expect(invoke).toHaveBeenNthCalledWith(2, "ticket_attachment_read", {
request: {
projectId: "proj-1",
ref: "#12",
attachmentId: "att-1",
},
});
expect(invoke).toHaveBeenNthCalledWith(
3,
"ticket_attachment_mark_summarized",
{
request: {
projectId: "proj-1",
ref: "#12",
attachmentId: "att-1",
expectedVersion: 4,
},
},
);
});
it("normalizes legacy ticket payloads that omit array fields and actors", async () => {
invoke.mockResolvedValueOnce({
id: "issue-1",
ref: "#12",
number: 12,
title: "Legacy",
description: "",
status: "open",
priority: "medium",
createdAt: 1,
updatedAt: 1,
version: 1,
});
const ticket = await new TauriTicketGateway().read("proj-1", "#12", true);
expect(ticket.links).toEqual([]);
expect(ticket.assignedAgentIds).toEqual([]);
expect(ticket.attachments).toEqual([]);
expect(ticket.createdBy).toEqual({ kind: "user" });
expect(ticket.updatedBy).toEqual({ kind: "user" });
});
it("normalizes malformed ticket actors", async () => {
invoke.mockResolvedValueOnce({
id: "issue-1",
ref: "#12",
number: 12,
title: "Legacy",
description: "",
status: "open",
priority: "medium",
createdBy: { kind: "agent" },
updatedBy: { kind: "unknown" },
createdAt: 1,
updatedAt: 1,
version: 1,
});
const ticket = await new TauriTicketGateway().read("proj-1", "#12", true);
expect(ticket.createdBy).toEqual({ kind: "user" });
expect(ticket.updatedBy).toEqual({ kind: "user" });
});
});