/* @vitest-environment jsdom */ import { act } from "react"; import { createRoot, type Root } from "react-dom/client"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { PrivateAlbumSchema } from "@/data/schemas/private-zoom"; import { PrivateAlbumCard } from "../private-album-card"; describe("PrivateAlbumCard interactions", () => { let container: HTMLDivElement; let root: Root; beforeEach(() => { (globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }) .IS_REACT_ACT_ENVIRONMENT = true; container = document.createElement("div"); document.body.append(container); root = createRoot(container); }); afterEach(() => { act(() => root.unmount()); container.remove(); }); it("opens the selected thumbnail with its original source index", () => { const onOpenGallery = vi.fn(); const album = PrivateAlbumSchema.parse({ albumId: "album-1", title: "Private afternoon", imageCount: 4, images: [ { url: "", locked: false, index: 0 }, { url: "/images/private-zoom/locked.png", locked: true, index: 1 }, { url: "/images/private-zoom/photo-2.png", locked: false, index: 2 }, { url: "/images/private-zoom/photo-3.png", locked: false, index: 3 }, ], locked: false, unlocked: true, lockDetail: { locked: false }, }); act(() => { root.render( undefined} />, ); }); const thumbnail = container.querySelector( 'button[data-image-index="3"]', ); act(() => thumbnail?.click()); expect(onOpenGallery).toHaveBeenCalledOnce(); expect(onOpenGallery).toHaveBeenCalledWith(3); }); it("unlocks only from the collection CTA and disables repeat actions", () => { const onUnlock = vi.fn(); const album = PrivateAlbumSchema.parse({ albumId: "album-locked", title: "Locked afternoon", imageCount: 3, images: [ { url: "/images/private-zoom/locked.png", locked: true, index: 0 }, ], locked: true, unlocked: false, unlockCost: 40, lockDetail: { locked: true }, }); renderLockedCard(album, false, onUnlock); const avatar = container.querySelector( '[aria-label="Elio Silvestri locked collection"]', ); act(() => avatar?.parentElement?.click()); expect(onUnlock).not.toHaveBeenCalled(); const button = findCollectionButton(); act(() => button.click()); expect(onUnlock).toHaveBeenCalledOnce(); renderLockedCard(album, true, onUnlock); const disabledButton = findCollectionButton(); expect(disabledButton.disabled).toBe(true); expect(disabledButton.textContent).toBe("Opening..."); act(() => disabledButton.click()); expect(onUnlock).toHaveBeenCalledOnce(); }); function renderLockedCard( album: ReturnType, isUnlocking: boolean, onUnlock: () => void, ): void { act(() => { root.render( undefined} onUnlock={onUnlock} />, ); }); } function findCollectionButton(): HTMLButtonElement { const button = Array.from(container.querySelectorAll("button")).find( (item) => item.textContent === "View collection" || item.textContent === "Opening...", ); if (!button) throw new Error("Missing View collection button"); return button; } });