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