@fireproof/core 0.20.0-dev-preview-51 → 0.20.0-dev-preview-53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,199 @@
1
+ import { render, waitFor } from "@testing-library/react";
2
+ import { describe, expect, it, vi } from "vitest";
3
+ import { ImgFile, bs } from "use-fireproof";
4
+ import { createElement } from "react";
5
+ import type { DocFileMeta } from "use-fireproof";
6
+
7
+ // Extend HTMLElement to include querySelector for TypeScript
8
+ declare global {
9
+ interface HTMLElement {
10
+ querySelector(selectors: string): HTMLElement | null;
11
+ getAttribute(name: string): string | null;
12
+ classList: {
13
+ contains(token: string): boolean;
14
+ };
15
+ }
16
+ }
17
+
18
+ // Simple SVG content for testing
19
+ const SVG_CONTENT = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
20
+ <circle cx="12" cy="12" r="10" fill="blue" />
21
+ </svg>`;
22
+
23
+ describe("COMPONENT: ImgFile", () => {
24
+ // Mock URL methods
25
+ const mockObjectURL = "mock-object-url";
26
+ const originalCreateObjectURL = window.URL.createObjectURL;
27
+ const originalRevokeObjectURL = window.URL.revokeObjectURL;
28
+
29
+ beforeEach(() => {
30
+ window.URL.createObjectURL = vi.fn(() => mockObjectURL);
31
+ window.URL.revokeObjectURL = vi.fn();
32
+ });
33
+
34
+ afterEach(() => {
35
+ window.URL.createObjectURL = originalCreateObjectURL;
36
+ window.URL.revokeObjectURL = originalRevokeObjectURL;
37
+ });
38
+
39
+ // Test timeout value for CI
40
+ const TEST_TIMEOUT = 60000; // 1 minute per test
41
+
42
+ it(
43
+ "renders the image from a File object",
44
+ async () => {
45
+ const file = new File([new Blob([SVG_CONTENT], { type: "image/svg+xml" })], "test.svg", { type: "image/svg+xml" });
46
+
47
+ const { container } = render(
48
+ createElement(ImgFile, {
49
+ file: file,
50
+ alt: "Test SVG",
51
+ className: "test-class",
52
+ }),
53
+ );
54
+
55
+ await waitFor(() => {
56
+ const img = container.querySelector("img");
57
+ expect(img).not.toBeNull();
58
+ });
59
+
60
+ const img = container.querySelector("img");
61
+ expect(img?.getAttribute("src")).toBe(mockObjectURL);
62
+ expect(img?.getAttribute("alt")).toBe("Test SVG");
63
+ expect(img?.classList.contains("test-class")).toBe(true);
64
+ expect(window.URL.createObjectURL).toHaveBeenCalledWith(file);
65
+ },
66
+ TEST_TIMEOUT,
67
+ );
68
+
69
+ it(
70
+ "does not render when file is not present",
71
+ () => {
72
+ const { container } = render(
73
+ createElement(ImgFile, {
74
+ file: undefined,
75
+ alt: "No File",
76
+ }),
77
+ );
78
+
79
+ const img = container.querySelector("img");
80
+ expect(img).toBeNull();
81
+ expect(window.URL.createObjectURL).not.toHaveBeenCalled();
82
+ },
83
+ TEST_TIMEOUT,
84
+ );
85
+
86
+ it(
87
+ "supports legacy 'meta' parameter",
88
+ async () => {
89
+ const file = new File([new Blob([SVG_CONTENT], { type: "image/svg+xml" })], "legacy.svg", { type: "image/svg+xml" });
90
+
91
+ const { container } = render(
92
+ createElement(ImgFile, {
93
+ meta: file,
94
+ alt: "Legacy File",
95
+ }),
96
+ );
97
+
98
+ await waitFor(() => {
99
+ const img = container.querySelector("img");
100
+ expect(img).not.toBeNull();
101
+ });
102
+
103
+ const img = container.querySelector("img");
104
+ expect(img?.getAttribute("src")).toBe(mockObjectURL);
105
+ expect(img?.getAttribute("alt")).toBe("Legacy File");
106
+ expect(window.URL.createObjectURL).toHaveBeenCalledWith(file);
107
+ },
108
+ TEST_TIMEOUT,
109
+ );
110
+
111
+ it(
112
+ "renders from DocFileMeta object",
113
+ async () => {
114
+ const file = new File([new Blob([SVG_CONTENT], { type: "image/svg+xml" })], "meta.svg", { type: "image/svg+xml" });
115
+
116
+ // Create a mock DocFileMeta with required cid property
117
+ const mockCid = { toString: () => "test-cid" } as bs.AnyLink;
118
+ const docFileMeta: DocFileMeta = {
119
+ type: "image/svg+xml",
120
+ size: file.size,
121
+ cid: mockCid,
122
+ file: async () => file,
123
+ };
124
+
125
+ const { container } = render(
126
+ createElement(ImgFile, {
127
+ file: docFileMeta,
128
+ alt: "DocFileMeta Image",
129
+ }),
130
+ );
131
+
132
+ await waitFor(() => {
133
+ const img = container.querySelector("img");
134
+ expect(img).not.toBeNull();
135
+ });
136
+
137
+ const img = container.querySelector("img");
138
+ expect(img?.getAttribute("src")).toBe(mockObjectURL);
139
+ expect(img?.getAttribute("alt")).toBe("DocFileMeta Image");
140
+ expect(window.URL.createObjectURL).toHaveBeenCalledWith(file);
141
+ },
142
+ TEST_TIMEOUT,
143
+ );
144
+
145
+ it(
146
+ "does not render for non-image file types",
147
+ async () => {
148
+ const textFile = new File(["test content"], "test.txt", { type: "text/plain" });
149
+
150
+ const { container } = render(
151
+ createElement(ImgFile, {
152
+ file: textFile,
153
+ alt: "Text File",
154
+ }),
155
+ );
156
+
157
+ // Wait a bit to ensure any async operations complete
158
+ await waitFor(
159
+ () => {
160
+ // Verify that createObjectURL was called (or not called)
161
+ expect(window.URL.createObjectURL).toHaveBeenCalledTimes(0);
162
+ },
163
+ { timeout: 1000 },
164
+ );
165
+
166
+ const img = container.querySelector("img");
167
+ expect(img).toBeNull();
168
+ },
169
+ TEST_TIMEOUT,
170
+ );
171
+
172
+ it(
173
+ "cleans up object URLs when unmounted",
174
+ async () => {
175
+ const file = new File([new Blob([SVG_CONTENT], { type: "image/svg+xml" })], "cleanup.svg", { type: "image/svg+xml" });
176
+
177
+ const { container, unmount } = render(
178
+ createElement(ImgFile, {
179
+ file: file,
180
+ alt: "Cleanup Test",
181
+ }),
182
+ );
183
+
184
+ await waitFor(() => {
185
+ const img = container.querySelector("img");
186
+ expect(img).not.toBeNull();
187
+ });
188
+
189
+ expect(window.URL.createObjectURL).toHaveBeenCalledWith(file);
190
+ expect(window.URL.revokeObjectURL).not.toHaveBeenCalled();
191
+
192
+ // Unmount to trigger cleanup
193
+ unmount();
194
+
195
+ expect(window.URL.revokeObjectURL).toHaveBeenCalledWith(mockObjectURL);
196
+ },
197
+ TEST_TIMEOUT,
198
+ );
199
+ });