import React from "react"; import { PrimaryHero } from "./index"; import { render, screen } from "@testing-library/react"; jest.mock("@shared/components/checklist", () => ({ Checklist: ({ items }: any) => ( ), })); jest.mock("@shared/components/next-image", () => ({ NextImage: ({ src, alt, className }: any) => ( {alt} ), })); jest.mock("@shared/components/text", () => ({ Text: ({ as: Tag = "span", children, className }: any) => ( {children} ), })); jest.mock("@shared/contentful/blocks/button", () => ({ Button: ({ children, buttonLabel, linkClassName, buttonClassName, ...rest }: any) => ( ), })); jest.mock("@shared/utils", () => ({ cx: (...args: any[]) => args.filter(Boolean).join(" "), })); const baseProps = { title: "Fast Internet" }; describe("PrimaryHero", () => { beforeEach(() => jest.clearAllMocks()); it("renders title as h2 by default", () => { render(); expect(screen.getByText("Fast Internet").tagName).toBe("H2"); }); it("renders title as h1 when showAsHeading is true", () => { render(); expect(screen.getByText("Fast Internet").tagName).toBe("H1"); }); it("does not render title section when title is empty", () => { render(); expect(screen.queryByRole("heading")).not.toBeInTheDocument(); }); it("renders subtitle when provided", () => { render(); expect(screen.getByText("Super fast speeds")).toBeInTheDocument(); }); it("does not render subtitle when not provided", () => { const { container } = render(); expect(container.querySelectorAll("p.subheading3")).toHaveLength(0); }); describe("Price section", () => { it("renders price with dollar sign", () => { render(); expect(screen.getByText("$")).toBeInTheDocument(); expect(screen.getByText("49.99")).toBeInTheDocument(); }); it("renders priceSuffix when provided", () => { render(); expect(screen.getByText("/mo")).toBeInTheDocument(); }); it("does not render priceSuffix when not provided", () => { render(); expect(screen.queryByText("/mo")).not.toBeInTheDocument(); }); it("renders priceCallout split by pipe", () => { render( ); expect(screen.getByText("Starting at")).toBeInTheDocument(); expect(screen.getByText("per month")).toBeInTheDocument(); }); it("does not render priceCallout when not provided", () => { render(); expect(screen.queryByText("Starting at")).not.toBeInTheDocument(); }); it("does not render price section when price is not provided", () => { render(); expect(screen.queryByText("$")).not.toBeInTheDocument(); }); }); describe("Checklist", () => { it("renders checklist when provided", () => { const checklist = [{ title: "No data caps" }, { title: "Free install" }]; render(); expect(screen.getByTestId("checklist")).toBeInTheDocument(); expect(screen.getByText("No data caps")).toBeInTheDocument(); expect(screen.getByText("Free install")).toBeInTheDocument(); }); it("does not render checklist when not provided", () => { render(); expect(screen.queryByTestId("checklist")).not.toBeInTheDocument(); }); }); describe("Primary CTA", () => { it("renders primaryCta1 button", () => { render( ); expect(screen.getByText("Get Started")).toBeInTheDocument(); }); it("hides primaryCta1 on mobile when hideOnMobileCta1 is true", () => { const { container } = render( ); const ctaWrapper = container.querySelector(".hidden.md\\:block"); expect(ctaWrapper).toBeInTheDocument(); }); it("does not render primaryCta1 when not provided", () => { render(); expect(screen.queryByText("Get Started")).not.toBeInTheDocument(); }); it("renders both CTAs side by side when both are button type", () => { const { container } = render( ); expect(screen.getByText("Check plans")).toBeInTheDocument(); expect(screen.getByText("Shop AT&T deals")).toBeInTheDocument(); const row = container.querySelector(".sm\\:flex-row"); expect(row).toBeInTheDocument(); }); it("renders CTAs stacked when only primaryCta1 is present", () => { const { container } = render( ); expect(screen.getByText("Check plans")).toBeInTheDocument(); expect(container.querySelector(".sm\\:flex-row")).not.toBeInTheDocument(); }); it("renders CTAs stacked when one CTA is not a button type", () => { const { container } = render( ); expect(screen.getByText("Check plans")).toBeInTheDocument(); expect(screen.getByText("Learn more")).toBeInTheDocument(); expect(container.querySelector(".sm\\:flex-row")).not.toBeInTheDocument(); }); it("hides primaryCta2 on mobile when hideOnMobileCta2 is true", () => { const { container } = render( ); const ctaWrapper = container.querySelector(".hidden.md\\:block"); expect(ctaWrapper).toBeInTheDocument(); }); it("renders only primaryCta2 when primaryCta1 is not provided", () => { render( ); expect(screen.getByText("Shop deals")).toBeInTheDocument(); }); }); describe("Secondary CTA", () => { it("renders secondaryCtaPrefix and secondaryCta", () => { render( ); expect(screen.getAllByText("Or").length).toBeGreaterThan(0); expect(screen.getAllByText("Call us").length).toBeGreaterThan(0); }); it("renders only secondaryCtaPrefix without secondaryCta", () => { render(); expect(screen.getAllByText("Or").length).toBeGreaterThan(0); }); it("renders only secondaryCta without prefix", () => { render( ); expect(screen.getAllByText("Call us").length).toBeGreaterThan(0); }); it("does not render secondary section when neither provided", () => { const { container } = render(); expect(container.querySelectorAll(".md\\:flex")).toHaveLength(0); }); }); describe("Bottom link", () => { it("renders bottom link when buttonLabel and href exist", () => { render( ); expect(screen.getAllByText("Learn more").length).toBeGreaterThan(0); }); it("renders bottom link when only href exists (label is from label prop)", () => { render( ); expect(screen.getAllByText("Details").length).toBeGreaterThan(0); }); it("does not render bottom link when no label and no href", () => { render(); // No button rendered for bottom link expect(screen.queryAllByTestId("button")).toHaveLength(0); }); it("does not render bottom link when bottomLink is undefined", () => { render(); expect(screen.queryByText("Learn more")).not.toBeInTheDocument(); }); }); describe("Pricing description disclaimer", () => { it("renders pricingDescription with subheading and responsive alignment classes", () => { render( ); const pricingText = screen.getByText( "Building a new home? Contact us to see if you're eligible for Kinetic Internet." ); expect(pricingText).toBeInTheDocument(); expect(pricingText).toHaveClass("subheading1"); expect(pricingText).toHaveClass( "text-left", "sm:text-center", "xl:text-left" ); }); it("renders pricingDescriptionDisclaimer (desktop and mobile)", () => { render( ); expect(screen.getAllByText("Taxes apply")).toHaveLength(1); }); it("does not render disclaimer when not provided", () => { render(); expect(screen.queryByText("Taxes apply")).not.toBeInTheDocument(); }); }); describe("Images", () => { it("renders carousel image (mobile and desktop)", () => { render( ); const imgs = screen.getAllByAltText("Hero"); expect(imgs).toHaveLength(2); expect(imgs[0]).toHaveAttribute("src", "https://img.test/hero.jpg"); }); it("does not render carousel image when empty array", () => { render(); expect(screen.queryByAltText("Hero")).not.toBeInTheDocument(); }); it("renders badge image (mobile and desktop)", () => { render( ); const badges = screen.getAllByAltText("Badge"); expect(badges).toHaveLength(2); }); it("does not render badge image when not provided", () => { render(); expect(screen.queryByAltText("Badge")).not.toBeInTheDocument(); }); it("renders desktop background video when heroVideo URL exists", () => { render( ); expect( screen.getByTestId("hero-background-video-desktop") ).toHaveAttribute("aria-label", "Desktop hero video"); expect(screen.getAllByAltText("Hero")).toHaveLength(1); }); it("falls back to images when heroVideo URL is missing", () => { render( ); expect( screen.queryByTestId("hero-background-video-desktop") ).not.toBeInTheDocument(); expect(screen.getAllByAltText("Hero")).toHaveLength(2); }); it("renders mobile video when heroVideoMobile URL exists", () => { render( ); expect(screen.getByTestId("hero-video-mobile")).toHaveAttribute( "aria-label", "Mobile hero video" ); expect(screen.getAllByAltText("Hero")).toHaveLength(1); }); it("uses the default desktop video label when no titles are provided", () => { render( ); expect( screen.getByTestId("hero-background-video-desktop") ).toHaveAttribute("aria-label", "Hero background video"); }); }); describe("renderCheckPlans", () => { it("passes renderCheckPlans to Button", () => { const renderFn = jest.fn(); render( ); expect(screen.getByText("Go")).toBeInTheDocument(); }); }); });