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) => (
),
}));
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"
);
});
});