1import { describe, expect, it, vi } from "vite-plus/test";
2import { EnvironmentId, ThreadId } from "@t3tools/contracts";
3import type { FilePreviewItem } from "../components/ui/FilePreviewModal.types";
4import type { DraftComposerAttachment } from "./composerImages";
5import { composerImageGallery } from "./composerImageGallery";
6import { messageImageGallery } from "../features/threads/messageImageGallery";
7import { filePreviewGallery, filePreviewKey } from "./filePreviewGallery";
8
9vi.mock("./uuid", () => ({}));
10
11describe("image preview groups", () => {
12 it.each([false, true])(
13 "keeps one entry per image through upload and delivery (file: %s)",
14 (fileBacked) => {
15 const environmentId = EnvironmentId.make("test");
16 const context = { environmentId, threadId: ThreadId.make("thread"), workspaceRoot: null };
17 const attachments: DraftComposerAttachment[] = ["a", "b"].map((id) => ({
18 id,
19 type: "image",
20 name: `${id}.png`,
21 mimeType: "image/png",
22 sizeBytes: 3,
23 previewUri: `data:image/png;base64,${id}`,
24 ...(fileBacked ? { fileUri: `file:///documents/${id}.png` } : {}),
25 }));
26 const delivered = (id: string) =>
27 messageImageGallery(
28 {
29 text: "",
30 attachments: [
31 {
32 type: "image",
33 id: `uploaded-${id}`,
34 name: `${id}.png`,
35 mimeType: "image/png",
36 sizeBytes: 3,
37 },
38 ],
39 },
40 context,
41 )[0]!;
42 const local = composerImageGallery(attachments, environmentId);
43 const uploading = composerImageGallery(
44 [{ ...attachments[0]!, uploadedAttachmentId: "uploaded-a" }, attachments[1]!],
45 environmentId,
46 );
47 const uploaded = composerImageGallery(
48 attachments.map((attachment) => ({
49 ...attachment,
50 uploadedAttachmentId: `uploaded-${attachment.id}`,
51 })),
52 environmentId,
53 );
54 for (const [selected, gallery] of [
55 [local[0]!, local],
56 [delivered("a"), uploading],
57 [uploading[1]!, uploading],
58 [delivered("a"), uploaded],
59 [delivered("a"), [...uploaded, delivered("a"), delivered("b")]],
60 [delivered("a"), [delivered("a"), delivered("b")]],
61 ] as const) {
62 const result = filePreviewGallery(selected, gallery);
63 expect(result).toHaveLength(2);
64 expect(result.map(filePreviewKey)).toEqual([...new Set(gallery.map(filePreviewKey))]);
65 }
66 expect(composerImageGallery(attachments)).toEqual(local);
67 },
68 );
69
70 it("matches remote originals despite metadata and property order differences", () => {
71 const environmentId = EnvironmentId.make("test");
72 const a: FilePreviewItem = {
73 kind: "image",
74 environmentId,
75 resource: { _tag: "attachment", attachmentId: "a", fileName: "old.png" },
76 };
77 const b: FilePreviewItem = {
78 kind: "image",
79 environmentId,
80 resource: {
81 attachmentId: "a",
82 _tag: "attachment",
83 fileName: "new.png",
84 mimeType: "image/png",
85 },
86 };
87 expect(filePreviewKey(a)).toBe(filePreviewKey(b));
88 expect(filePreviewGallery(b, [a])).toEqual([b]);
89 });
90});