import React from "react"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { fireEvent, render, screen, waitFor, } from "../../../../../test/src/react-render.js"; import { TEST_CLIENT } from "../../../../../test/src/test-clients.js"; import { IframePlayer, LinkPlayer, MediaRenderer, mergeRefs, } from "./MediaRenderer.js"; const three3dModelLink = "https://i2.seadn.io/matic/0x2953399124f0cbb46d2cbacd8a89cf0599974963/bd1801876c5cf1302484e225c72959/49bd1801876c5cf1302484e225c72959.glb"; const imageLink = "https://i2.seadn.io/ethereum/0xbd3531da5cf5857e7cfaa92426877b022e612cf8/750c4805cd12ea19c8c3909677e61988.png?w=350"; describe("MediaRenderer", () => { it("should render nothing if no src provided", () => { render(); expect(screen.queryByText("File")).not.toBeInTheDocument(); // would display file if it shows the "not found" div }); it.skip("should render unknown if nothing found", () => { render(); setTimeout(() => { expect(screen.queryByText("File")).toBeInTheDocument(); // would display file if it shows the "not found" div }, 1000); }); it.skip("should render a plain image", async () => { render(); await waitFor(() => { expect(screen.getByRole("img")).toBeInTheDocument(); }); }); describe("mergeRefs", () => { it("should call all callback refs with the given value", () => { const callbackRef1 = vi.fn(); const callbackRef2 = vi.fn(); const mergedRef = mergeRefs([callbackRef1, callbackRef2]); const testValue = { test: "value" }; mergedRef(testValue); expect(callbackRef1).toHaveBeenCalledWith(testValue); expect(callbackRef2).toHaveBeenCalledWith(testValue); }); it("should assign the value to all mutable object refs", () => { const mutableRef1 = React.createRef(); const mutableRef2 = React.createRef(); const mergedRef = mergeRefs([mutableRef1, mutableRef2]); const testValue = { test: "value" }; mergedRef(testValue); expect(mutableRef1.current).toBe(testValue); expect(mutableRef2.current).toBe(testValue); }); it("should handle a mix of callback and mutable object refs", () => { const callbackRef = vi.fn(); const mutableRef = React.createRef(); const mergedRef = mergeRefs([callbackRef, mutableRef]); const testValue = { test: "value" }; mergedRef(testValue); expect(callbackRef).toHaveBeenCalledWith(testValue); expect(mutableRef.current).toBe(testValue); }); it("should do nothing if refs array is empty", () => { const mergedRef = mergeRefs([]); expect(() => mergedRef(null)).not.toThrow(); }); }); describe("LinkPlayer", () => { it("renders with default props", () => { render(); const linkElement = screen.getByText("File"); expect(linkElement).toBeInTheDocument(); expect(linkElement.tagName).toBe("A"); expect(linkElement).toHaveAttribute("target", "_blank"); expect(linkElement).toHaveAttribute("rel", "noopener noreferrer"); }); it("renders with custom src and alt", () => { const src = "https://example.com/file"; const alt = "Custom File Name"; render(); const linkElement = screen.getByText(alt); expect(linkElement).toBeInTheDocument(); expect(linkElement).toHaveAttribute("href", src); }); it("applies custom style and className", () => { const customStyle = { backgroundColor: "red" }; const customClassName = "custom-class"; const { container } = render( , ); const outerDiv = container.querySelector(".custom-class"); if (!outerDiv) { throw new Error("Failed to render LinkPlayer"); } const styles = window.getComputedStyle(outerDiv); expect(styles.backgroundColor).toBe("red"); }); it("forwards ref to anchor element", () => { const ref = React.createRef(); render(); expect(ref.current).toBeInstanceOf(HTMLAnchorElement); }); }); describe("IframePlayer", () => { beforeEach(() => { // Reset the body before each test document.body.innerHTML = ""; }); it("renders with default props", () => { render(); const iframe = screen.getByTitle("thirdweb iframe player"); expect(iframe).toBeInTheDocument(); expect(iframe.tagName).toBe("IFRAME"); expect(iframe).toHaveAttribute("sandbox", "allow-scripts"); expect(iframe).toHaveAttribute( "allow", "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture", ); }); it("applies custom src and alt", () => { const src = "https://example.com/video"; const alt = "Custom Video"; render(); const iframe = screen.getByTitle(alt); expect(iframe).toBeInTheDocument(); expect(iframe).toHaveAttribute("src", src); }); it("renders poster image when provided", () => { const poster = "https://example.com/poster.jpg"; render(); const posterImg = screen.getByRole("img"); expect(posterImg).toBeInTheDocument(); expect(posterImg).toHaveAttribute("src", poster); }); it("toggles play state when PlayButton is clicked", async () => { render(); const playButton = screen.getByRole("button"); expect(playButton).toBeInTheDocument(); const iframe = screen.getByTitle("thirdweb iframe player"); expect(iframe).toHaveAttribute("src", "https://example.com/video"); fireEvent.click(playButton); // After clicking, the iframe src should be undefined expect(iframe).not.toHaveAttribute("src"); fireEvent.click(playButton); // After clicking again, the iframe src should be restored expect(iframe).toHaveAttribute("src", "https://example.com/video"); }); it("applies custom style", () => { const customStyle = { backgroundColor: "red" }; const { container } = render( , ); const element = container.querySelector(".iframe-test"); if (!element) { throw new Error("no iframe detected"); } expect(element).toHaveStyle("background-color: red"); }); it("forwards ref to iframe element", () => { const ref = React.createRef(); render(); expect(ref.current).toBeInstanceOf(HTMLIFrameElement); }); it("respects requireInteraction prop", () => { render( , ); const iframe = screen.getByTitle("thirdweb iframe player"); expect(iframe).not.toHaveAttribute("src"); const playButton = screen.getByRole("button"); fireEvent.click(playButton); expect(iframe).toHaveAttribute("src", "https://example.com/video"); }); }); it("should render poster image for 3d models", async () => { render( , ); await waitFor(() => { expect(screen.getByRole("img")).toBeInTheDocument(); }); }); });