// @vitest-environment jsdom import type { ReactNode } from "react" import { cleanup, fireEvent, render, screen, waitFor, } from "@testing-library/react" import { afterEach, describe, expect, it, vi } from "vitest" import { I18nProvider } from "@workspace/i18n" import { MediaProvider } from "./context" import { MediaLibrary } from "./media-library" import { MediaPickerDialog } from "./media-picker-dialog" import type { MediaAdapter, MediaAsset } from "./types" import { defaultMediaReference, getMediaFolderPath, splitMediaName, } from "./utils" const imageAsset: MediaAsset = { createdAt: "2026-08-01T00:00:00Z", favorite: false, folderId: null, height: 600, id: "image-1", kind: "image", mimeType: "image/png", name: "product.png", sizeBytes: 1024, url: "/media/product.png", width: 800, } function createAdapter(): MediaAdapter { return { createFolder: vi.fn(async ({ name, parentId }) => ({ id: name, name, parentId, })), deleteAsset: vi.fn(async () => undefined), deleteFolder: vi.fn(async () => undefined), listAssets: vi.fn(async () => ({ assets: [imageAsset], hasNextPage: false, })), listFolders: vi.fn(async () => []), listStorageTargets: vi.fn(async () => [ { id: "local", kind: "local" as const, label: "Local" }, ]), moveAsset: vi.fn(async () => imageAsset), renameAsset: vi.fn(async () => imageAsset), updateFavorite: vi.fn(async () => imageAsset), updateFolder: vi.fn(async ({ id, name, parentId }) => ({ id, name, parentId, })), upload: vi.fn(async () => [imageAsset]), } } function MediaTestProvider({ adapter, children, }: { adapter: MediaAdapter children: ReactNode }) { return ( {children} ) } describe("media blocks", () => { afterEach(cleanup) it("loads and uploads media only through the provider adapter", async () => { const adapter = createAdapter() const { container } = render( ) expect(await screen.findByRole("img", { name: "product.png" })).toBeTruthy() const fileInput = container.querySelector('input[type="file"]') expect(fileInput).not.toBeNull() fireEvent.change(fileInput!, { target: { files: [new File(["image"], "new-image.png", { type: "image/png" })], }, }) await waitFor(() => expect(adapter.upload).toHaveBeenCalledOnce()) expect(adapter.upload).toHaveBeenCalledWith( expect.objectContaining({ files: expect.arrayContaining([expect.any(File)]), target: expect.objectContaining({ id: "local" }), }) ) }) it("returns image picker selections with an intrinsic-size reference URL", async () => { const adapter = createAdapter() const onConfirm = vi.fn() render( undefined} onConfirm={onConfirm} /> ) const image = await screen.findByRole("img", { name: "product.png" }) fireEvent.click(image.closest("button")!) await waitFor(() => expect( ( screen.getByRole("button", { name: "Use selected media", }) as HTMLButtonElement ).disabled ).toBe(false) ) fireEvent.click(screen.getByRole("button", { name: "Use selected media" })) expect(onConfirm).toHaveBeenCalledWith([ expect.objectContaining({ url: "/media/product.png?w=800&h=600" }), ]) }) it("builds stable media references and folder paths", () => { expect(defaultMediaReference(imageAsset)).toBe( "/media/product.png?w=800&h=600" ) expect(splitMediaName("archive.tar.gz")).toEqual({ baseName: "archive.tar", extension: ".gz", }) expect( getMediaFolderPath({ id: "child", name: "Shoes", parentId: "root" }, [ { id: "root", name: "Products", parentId: null }, { id: "child", name: "Shoes", parentId: "root" }, ]) ).toBe("Products / Shoes") }) })