import React from "react"; import { FloatingBanner } from "./index"; import { FloatingBannerProps } from "./types"; import { render, screen } from "@testing-library/react"; // Mock dependencies jest.mock("@shared/components/next-image", () => ({ NextImage: ({ src, alt, width, height, }: { src: string; alt: string; width: number; height: number; }) => {alt}, })); jest.mock("@shared/components/text", () => ({ Text: ({ as: Tag = "span", children, className }: any) => ( {children} ), })); jest.mock("@shared/contentful/blocks/button", () => ({ // eslint-disable-next-line @typescript-eslint/no-unused-vars Button: ({ buttonLabel, buttonVariant, size, ...rest }: any) => ( ), })); const defaultProps: FloatingBannerProps = { title: "Special Offer", subtitle: "Limited Time", description: "Get the best deals now", disclaimer: "Terms and conditions apply", icon: "https://example.com/icon.png", cta: { buttonLabel: "Shop Now", href: "/shop" }, }; describe("FloatingBanner", () => { describe("Rendering", () => { it("renders with all props", () => { render(); expect(screen.getByText("Special Offer")).toBeInTheDocument(); expect(screen.getByText("Limited Time")).toBeInTheDocument(); expect(screen.getByText("Get the best deals now")).toBeInTheDocument(); expect( screen.getByText("Terms and conditions apply") ).toBeInTheDocument(); }); it("renders with no optional props", () => { const { container } = render(); expect(container.firstChild).toBeInTheDocument(); }); it("renders title when provided", () => { render(); expect(screen.getByText("Banner Title")).toBeInTheDocument(); }); it("does not render title when not provided", () => { render(); expect(screen.queryByText("Banner Title")).not.toBeInTheDocument(); }); it("renders subtitle when provided", () => { render(); expect(screen.getByText("Sub Text")).toBeInTheDocument(); }); it("does not render subtitle when not provided", () => { render(); expect(screen.queryByText("Sub Text")).not.toBeInTheDocument(); }); it("renders description when provided", () => { render(); expect(screen.getByText("Desc here")).toBeInTheDocument(); }); it("does not render description when not provided", () => { render(); expect(screen.queryByText("Desc here")).not.toBeInTheDocument(); }); it("renders disclaimer when provided", () => { render(); expect(screen.getByText("Disclaimer text")).toBeInTheDocument(); }); it("does not render disclaimer when not provided", () => { render(); expect(screen.queryByText("Disclaimer text")).not.toBeInTheDocument(); }); }); describe("Heading levels", () => { it("renders title as h2 when enableHeading is false/undefined", () => { render(); const el = screen.getByText("H2 Title"); expect(el.tagName).toBe("H2"); }); it("renders title as h1 when enableHeading is true", () => { render(); const el = screen.getByText("H1 Title"); expect(el.tagName).toBe("H1"); }); it("renders subtitle always as h3", () => { render(); const el = screen.getByText("Always H3"); expect(el.tagName).toBe("H3"); }); }); describe("Background themes", () => { it("applies navy background by default", () => { const { container } = render(); const bannerInner = container.querySelector(".bg-\\[\\#00002D\\]"); expect(bannerInner).toBeInTheDocument(); }); it.each([ ["blue", "bg-[#07B2E2]"], ["green", "bg-[#26B170]"], ["yellow", "bg-[#F5FF1E]"], ["purple", "bg-[#931D69]"], ["white", "bg-white"], ["navy", "bg-[#00002D]"], ] as const)("applies %s background class", (bg, expectedClass) => { const { container } = render( ); const bannerInner = container.querySelector( `.${CSS.escape(expectedClass)}` ); expect(bannerInner).toBeInTheDocument(); }); }); describe("Color theme", () => { it("applies light (white) text by default", () => { const { container } = render(); const bannerInner = container.querySelector(".text-white"); expect(bannerInner).toBeInTheDocument(); }); it("applies dark text when color is dark", () => { const { container } = render( ); const bannerInner = container.querySelector(".text-text"); expect(bannerInner).toBeInTheDocument(); }); it("applies white text when color is light", () => { const { container } = render( ); const bannerInner = container.querySelector(".text-white"); expect(bannerInner).toBeInTheDocument(); }); }); describe("Max width", () => { it("applies max-w-120 when maxWidth is true (default)", () => { const { container } = render(); const wrapper = container.querySelector(".max-w-120"); expect(wrapper).toBeInTheDocument(); }); it("does not apply max-w-120 when maxWidth is false", () => { const { container } = render( ); const wrapper = container.querySelector(".max-w-120"); expect(wrapper).not.toBeInTheDocument(); }); }); describe("Icon", () => { it("renders icon image when provided", () => { render(); const img = screen.getByAltText("icon"); expect(img).toHaveAttribute("src", "https://example.com/icon.png"); expect(img).toHaveAttribute("width", "80"); expect(img).toHaveAttribute("height", "80"); }); it("does not render icon when not provided", () => { render(); expect(screen.queryByAltText("icon")).not.toBeInTheDocument(); }); }); describe("CTA Button", () => { it("renders CTA button when cta is provided", () => { render( ); expect(screen.getByTestId("cta-button")).toBeInTheDocument(); }); it("does not render CTA button when cta is not provided", () => { render(); expect(screen.queryByTestId("cta-button")).not.toBeInTheDocument(); }); it("does not render CTA button when cta is null", () => { render(); expect(screen.queryByTestId("cta-button")).not.toBeInTheDocument(); }); }); describe("Description as ReactNode", () => { it("renders JSX description", () => { render( Rich description } /> ); expect(screen.getByTestId("jsx-desc")).toBeInTheDocument(); }); }); describe("Disclaimer as ReactNode", () => { it("renders JSX disclaimer", () => { render( Legal info} /> ); expect(screen.getByTestId("jsx-disc")).toBeInTheDocument(); }); }); });