import React from "react"; import { ImagePromoBar } from "./index"; import { ImagePromoBarProps } from "./types"; import { render, screen } from "@testing-library/react"; jest.mock("../button", () => ({ __esModule: true, // eslint-disable-next-line @typescript-eslint/no-unused-vars Button: ({ buttonLabel, disableAnimation, ...rest }: any) => ( ), default: ({ buttonLabel, disableAnimation }: any) => ( ), })); jest.mock("@shared/components/video-link", () => ({ VideoLink: ({ videoLink }: any) => (
), })); jest.mock("@shared/components/checklist", () => ({ Checklist: ({ items }: any) => ( ), })); jest.mock("@shared/components/image", () => ({ Image: ({ src, alt }: any) => {alt}, })); jest.mock("@shared/components/link", () => ({ Link: ({ children, href }: any) => ( {children} ), })); jest.mock("@shared/components/next-image", () => ({ NextImage: ({ src, alt }: any) => ( {alt} ), })); jest.mock("@shared/components/text", () => ({ Text: ({ as: Tag = "span", children, className }: any) => ( {children} ), })); jest.mock("@shared/utils", () => ({ cx: (...args: any[]) => args.filter(Boolean).join(" "), })); const defaultProps: ImagePromoBarProps = { brow: "", enableHeading: false, title: "", subTitle: "", image: "", imageWidth: 660, imageHeight: 660, mediaPosition: true, description: null, openDescriptionLinksOnANewTab: false, checklist: [], disclaimer: null, imageLinks: [], cta: null, secondaryCta: null, ctaDisclaimer: null, maxWidth: true, color: "light", }; describe("ImagePromoBar", () => { describe("Text content", () => { it("renders brow text when provided", () => { render(); expect(screen.getByText("New")).toBeInTheDocument(); }); it("renders title as h2 when enableHeading is false", () => { render(); expect(screen.getByRole("heading", { level: 2 })).toHaveTextContent( "Title" ); }); it("renders title as h1 when enableHeading is true", () => { render( ); expect(screen.getByRole("heading", { level: 1 })).toHaveTextContent( "Title" ); }); it("renders subTitle as h3 when enableHeading is false", () => { render(); expect(screen.getByRole("heading", { level: 3 })).toHaveTextContent( "Sub" ); }); it("renders subTitle as h2 when enableHeading is true", () => { render( ); expect(screen.getByText("Sub").tagName).toBe("H2"); }); it("renders description", () => { render(); expect(screen.getByText("Desc text")).toBeInTheDocument(); }); it("renders ctaDisclaimer and disclaimer", () => { render( ); expect(screen.getByText("Discl1")).toBeInTheDocument(); expect(screen.getByText("Discl2")).toBeInTheDocument(); }); }); describe("Color and layout", () => { it("applies text-white for light color", () => { const { container } = render( ); expect(container.querySelector(".text-white")).toBeInTheDocument(); }); it("applies text-text for dark color", () => { const { container } = render( ); expect(container.querySelector(".text-text")).toBeInTheDocument(); }); it("applies max-w-120 when maxWidth is true", () => { const { container } = render( ); expect(container.querySelector(".max-w-120")).toBeInTheDocument(); }); it("does not apply max-w-120 when maxWidth is false", () => { const { container } = render( ); expect(container.querySelector(".max-w-120")).not.toBeInTheDocument(); }); it("applies lg:flex-row-reverse when mediaPosition is true", () => { const { container } = render( ); expect(container.innerHTML).toContain("xl:flex-row-reverse"); }); it("applies lg:flex-row when mediaPosition is false", () => { const { container } = render( ); expect(container.innerHTML).toContain("xl:flex-row"); expect(container.innerHTML).not.toContain("xl:flex-row-reverse"); }); }); describe("Checklist", () => { it("renders checklist when items exist", () => { render( ); expect(screen.getByTestId("checklist")).toBeInTheDocument(); }); it("does not render checklist when empty", () => { render(); expect(screen.queryByTestId("checklist")).not.toBeInTheDocument(); }); }); describe("Image links", () => { it("renders image links when provided", () => { const imageLinks = [ { url: "https://a.com", image: "https://img.test/a.png" }, { url: "https://b.com", image: "https://img.test/b.png" }, ]; render(); const links = screen.getAllByTestId("image-link"); expect(links).toHaveLength(2); expect(links[0]).toHaveAttribute("href", "https://a.com"); }); }); describe("CTAs", () => { it("renders primary CTA", () => { render(); expect(screen.getByTestId("cta-button")).toBeInTheDocument(); }); it("renders both CTAs", () => { render( ); expect(screen.getAllByTestId("cta-button")).toHaveLength(2); }); it("does not render CTA section when neither provided", () => { const { container } = render(); expect(container.querySelector(".primary-cta")).not.toBeInTheDocument(); }); it("keeps disableAnimation true on both CTAs by default", () => { render( ); const buttons = screen.getAllByTestId("cta-button"); expect(buttons).toHaveLength(2); buttons.forEach(button => { expect(button).toHaveAttribute("data-disable-animation", "true"); }); }); it("passes disableAnimation false to both CTAs when enableAnimation is true", () => { render( ); const buttons = screen.getAllByTestId("cta-button"); expect(buttons).toHaveLength(2); buttons.forEach(button => { expect(button).toHaveAttribute("data-disable-animation", "false"); }); }); }); describe("Image", () => { it("renders the plain image when there is no videoLink content", () => { render( ); expect(screen.getByTestId("next-image")).toHaveAttribute( "src", "https://img.test/hero.jpg" ); }); it("does not render the image section when image is empty", () => { render(); expect(screen.queryByTestId("next-image")).not.toBeInTheDocument(); }); it("does not render the plain image when videoLink has a valid href", () => { render( ); expect(screen.queryByTestId("next-image")).not.toBeInTheDocument(); }); it("does not render the plain image when videoLink has its own poster image, even without a valid href", () => { render( ); expect(screen.queryByTestId("next-image")).not.toBeInTheDocument(); }); it("renders the plain image when no videoLink is attached at all", () => { render( ); expect(screen.getByTestId("next-image")).toBeInTheDocument(); }); it("suppresses the plain image when an empty videoLink object is attached (VideoLink owns its own fallback from there)", () => { render( ); expect(screen.queryByTestId("next-image")).not.toBeInTheDocument(); }); }); describe("Video", () => { it("always renders VideoLink, passing videoLink through", () => { render( ); expect(screen.getByTestId("video-link")).toBeInTheDocument(); }); it("passes the videoLink prop through to VideoLink", () => { render( ); expect(screen.getByTestId("video-link")).toHaveAttribute( "data-link", "https://vimeo.com/123" ); }); it("still renders VideoLink when videoLink has no valid href (VideoLink owns its own poster fallback)", () => { render(); expect(screen.getByTestId("video-link")).toBeInTheDocument(); }); }); });