import React from "react"; import { VideoLink } from "./index"; import { fireEvent, render, screen } from "@testing-library/react"; jest.mock("./contentful-video-embed", () => ({ ContentfulVideoEmbed: ({ videoAssetUrl, autoplay }: any) => (
), })); jest.mock("./vimeo-embed", () => ({ VimeoEmbed: ({ link, autoplay }: any) => (
), })); jest.mock("./youtube-embed", () => ({ YoutubeEmbed: ({ link, autoplay }: any) => (
), })); jest.mock("./helper", () => ({ PlayButton: ({ isHovered }: any) => (
), })); jest.mock("@shared/components/next-image", () => ({ NextImage: ({ src, alt }: any) => ( {alt} ), })); jest.mock("@shared/utils", () => ({ cx: (...args: any[]) => args.filter(Boolean).join(" "), })); const clickVideoSection = (container: HTMLElement) => { fireEvent.click(container.querySelector(".video-section")!); }; describe("VideoLink", () => { it("renders nothing when videoLink is undefined", () => { const { container } = render(); expect(container.innerHTML).toBe(""); }); it("renders nothing when there is no video and no image to fall back to", () => { const { container } = render(); expect(container.innerHTML).toBe(""); }); it("renders the video link's own poster as a static image when there is no video", () => { render(); const img = screen.getByAltText("section-image"); expect(img).toHaveAttribute("src", "thumb.jpg"); expect(screen.queryByTestId("play-button")).not.toBeInTheDocument(); }); it("ignores an unrelated fallbackImage-like prop - only videoLink.image is used as the poster", () => { const { container } = render( // @ts-expect-error - fallbackImage is intentionally not a supported prop ); expect(container.innerHTML).toBe(""); }); it("renders nothing when videoSourceType is 'contentful' but videoAssetUrl is missing and there is no image", () => { const { container } = render( ); expect(container.innerHTML).toBe(""); }); it("falls back to videoLink.link when videoSourceType is 'contentful' but videoAssetUrl is missing", () => { const { container } = render( ); clickVideoSection(container); expect(screen.getByTestId("youtube-embed")).toHaveAttribute( "data-link", "https://youtube.com/watch?v=123" ); }); it("falls back to the poster when videoSourceType is 'contentful' but videoAssetUrl is missing", () => { render( ); expect(screen.getByAltText("section-image")).toHaveAttribute( "src", "thumb.jpg" ); }); it("renders preview image and play button when videoLink has link and image", () => { render( ); expect(screen.getByTestId("play-button")).toBeInTheDocument(); expect(screen.getByAltText("Video preview")).toBeInTheDocument(); }); it("does not render preview image when videoLink.image is missing", () => { render( ); expect(screen.queryByAltText("Video preview")).not.toBeInTheDocument(); }); it("shows youtube embed inline on click for a youtube link", () => { const { container } = render( ); clickVideoSection(container); expect(screen.getByTestId("youtube-embed")).toBeInTheDocument(); }); it("shows vimeo embed inline on click for a vimeo link", () => { const { container } = render( ); clickVideoSection(container); expect(screen.getByTestId("vimeo-embed")).toBeInTheDocument(); }); it("shows the contentful embed when videoSourceType is 'contentful'", () => { const { container } = render( ); clickVideoSection(container); expect(screen.getByTestId("contentful-video-embed")).toHaveAttribute( "data-video-asset-url", "https://videos.ctfassets.net/space/asset/sample.mp4" ); }); it("shows popup overlay when videoPopup is true and playing", () => { const { container } = render( ); clickVideoSection(container); expect(container.querySelector(".fixed")).toBeInTheDocument(); }); it("does not render inline embed when videoPopup is true", () => { const { container } = render( ); clickVideoSection(container); expect(container.querySelector(".fixed")).toBeInTheDocument(); }); it("renders inline (not popup) when videoPopup is not provided", () => { const { container } = render( ); clickVideoSection(container); expect(container.querySelector(".fixed")).not.toBeInTheDocument(); expect(screen.getByTestId("youtube-embed")).toBeInTheDocument(); }); it("closes popup on overlay click", () => { const { container } = render( ); clickVideoSection(container); fireEvent.click(container.querySelector(".fixed")!); expect(container.querySelector(".fixed")).not.toBeInTheDocument(); }); it("does not close popup when clicking inside the popup content", () => { const { container } = render( ); clickVideoSection(container); fireEvent.click(container.querySelector(".max-w-6xl")!); expect(container.querySelector(".fixed")).toBeInTheDocument(); }); it("handles hover state on the video section", () => { const { container } = render( ); const videoSection = container.querySelector(".video-section")!; fireEvent.mouseEnter(videoSection); expect(screen.getByTestId("play-button")).toHaveAttribute( "data-hovered", "true" ); fireEvent.mouseLeave(videoSection); expect(screen.getByTestId("play-button")).toHaveAttribute( "data-hovered", "false" ); }); });