| ... | ... | @@ -1,51 +1,43 @@ |
| 1 | | import { EnvironmentId, ThreadId } from "@t3tools/contracts"; |
| 2 | | import { renderToStaticMarkup } from "react-dom/server"; |
| 3 | | import { describe, expect, it, vi } from "vite-plus/test"; |
| 4 | | |
| 5 | | const mocks = vi.hoisted(() => ({ favicon: null as string | null })); |
| 6 | | |
| 7 | | vi.mock("~/browserFaviconStore", () => ({ |
| 8 | | useFaviconForThreadUrl: () => mocks.favicon, |
| 9 | | })); |
| 10 | | |
| 11 | | import { FaviconImage, PreviewFaviconIcon, selectFaviconSource } from "./PreviewFaviconIcon"; |
| 12 | | |
| 13 | | const threadRef = { |
| 14 | | environmentId: EnvironmentId.make("env-1"), |
| 15 | | threadId: ThreadId.make("thread-1"), |
| 16 | | }; |
| 17 | | |
| 18 | | describe("preview favicon image", () => { |
| 19 | | it("renders a captured source before later fallback sources", () => { |
| 20 | | expect( |
| 21 | | renderToStaticMarkup( |
| 22 | | <FaviconImage |
| 23 | | sources={["data:image/png;base64,AAAA", "https://public.example/icon"]} |
| 24 | | fallback={<span>fallback</span>} |
| 25 | | />, |
| 26 | | ), |
| 27 | | ).toContain('src="data:image/png;base64,AAAA"'); |
| 28 | | const captured = "data:image/png;base64,AAAA"; |
| 29 | | const google = "https://public.example/icon"; |
| 30 | | expect(selectFaviconSource([captured, google], new Set())).toBe(captured); |
| 31 | | expect(selectFaviconSource([captured, google], new Set([captured]))).toBe(google); |
| 32 | | expect(selectFaviconSource([captured, google], new Set([captured, google]))).toBeNull(); |
| 33 | | expect(selectFaviconSource(["data:image/png;base64,BBBB", google], new Set([captured]))).toBe( |
| 34 | | "data:image/png;base64,BBBB", |
| 1 | import { act } from "react"; |
| 2 | import { create, type ReactTestRenderer } from "react-test-renderer"; |
| 3 | import { afterEach, expect, it, vi } from "vite-plus/test"; |
| 4 | |
| 5 | vi.mock("~/browserFaviconStore", () => ({ useFaviconForThreadUrl: () => null })); |
| 6 | |
| 7 | import { FaviconImage } from "./PreviewFaviconIcon"; |
| 8 | |
| 9 | let renderer: ReactTestRenderer | undefined; |
| 10 | |
| 11 | afterEach(async () => { |
| 12 | await act(async () => renderer?.unmount()); |
| 13 | vi.unstubAllGlobals(); |
| 14 | }); |
| 15 | |
| 16 | it("falls through failed favicon sources and retries when the source list changes", async () => { |
| 17 | vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true); |
| 18 | const captured = "data:image/png;base64,AAAA"; |
| 19 | const remote = "https://public.example/icon"; |
| 20 | await act(async () => { |
| 21 | renderer = create( |
| 22 | <FaviconImage sources={[captured, remote]} fallback={<span>fallback</span>} />, |
| 35 | 23 | ); |
| 36 | 24 | }); |
| 25 | expect(renderer!.root.findByType("img").props.src).toBe(captured); |
| 37 | 26 | |
| 38 | | it("uses a stored project icon or falls back to the browser mockup", () => { |
| 39 | | mocks.favicon = null; |
| 40 | | const html = renderToStaticMarkup( |
| 41 | | <PreviewFaviconIcon threadRef={threadRef} url="http://localhost:3000/" />, |
| 42 | | ); |
| 43 | | expect(html).not.toContain("<img"); |
| 44 | | expect(html).toContain("rounded-[5px]"); |
| 45 | | mocks.favicon = "data:image/png;base64,AAAA"; |
| 46 | | const faviconHtml = renderToStaticMarkup( |
| 47 | | <PreviewFaviconIcon threadRef={threadRef} url="http://localhost:3000/" />, |
| 27 | await act(async () => renderer!.root.findByType("img").props.onError()); |
| 28 | expect(renderer!.root.findByType("img").props.src).toBe(remote); |
| 29 | |
| 30 | await act(async () => renderer!.root.findByType("img").props.onError()); |
| 31 | expect(renderer!.root.findAllByType("img")).toHaveLength(0); |
| 32 | expect(renderer!.root.findByType("span").children).toEqual(["fallback"]); |
| 33 | |
| 34 | await act(async () => { |
| 35 | renderer!.update( |
| 36 | <FaviconImage |
| 37 | sources={[captured, "https://public.example/new-icon"]} |
| 38 | fallback={<span>fallback</span>} |
| 39 | />, |
| 48 | 40 | ); |
| 49 | | expect(faviconHtml).toContain('src="data:image/png;base64,AAAA"'); |
| 50 | 41 | }); |
| 42 | expect(renderer!.root.findByType("img").props.src).toBe(captured); |
| 51 | 43 | }); |