import React from "react"; import { FloatingImageCard } from "./index"; import { describe, expect, it, jest } from "@jest/globals"; import "@testing-library/jest-dom/jest-globals"; import { render, screen } from "@testing-library/react"; jest.mock("@shared/components/next-image", () => ({ NextImage: ({ src, alt, width, height, className, onClick, ...rest }: any) => ( {alt} ), })); jest.mock("@shared/components/text", () => ({ Text: ({ as: Tag = "span", children, className }: any) => ( {children} ), })); jest.mock("../../button", () => ({ Button: ({ children, linkClassName, ...rest }: any) => ( ), })); jest.mock("@shared/utils", () => ({ cx: (...args: any[]) => args.filter(Boolean).join(" "), })); describe("FloatingImageCard", () => { const defaultCard = { title: "Card Title", header: "Card Header", body: "Card body content", image: { href: "/image.jpg", title: "Test Image", width: 400, height: 285 }, }; describe("Rendering", () => { it("renders the section element", () => { const { container } = render(); expect(container.querySelector("section")).toBeInTheDocument(); }); it("renders header text", () => { render(); expect(screen.getByText("Card Header")).toBeInTheDocument(); }); it("renders body text", () => { render(); expect(screen.getByText("Card body content")).toBeInTheDocument(); }); it("renders image when provided", () => { render(); const img = screen.getByTestId("next-image"); expect(img).toHaveAttribute("src", "/image.jpg"); expect(img).toHaveAttribute("alt", "Test Image"); }); it("does not render image when not provided", () => { render(); expect(screen.queryByTestId("next-image")).not.toBeInTheDocument(); }); it("does not render header when not provided", () => { render( ); expect(screen.queryByText("Card Header")).not.toBeInTheDocument(); }); it("does not render body when not provided", () => { render(); expect(screen.queryByText("Card body content")).not.toBeInTheDocument(); }); }); describe("CTA", () => { it("renders CTA button when cta is provided", () => { const card = { ...defaultCard, cta: { buttonLabel: "Learn More", href: "/learn" }, }; render(); expect(screen.getByTestId("cta-button")).toBeInTheDocument(); }); it("does not render CTA when not provided", () => { render(); expect(screen.queryByTestId("cta-button")).not.toBeInTheDocument(); }); it("renders Button when buttonIconName is provided", () => { const card = { ...defaultCard, cta: { buttonLabel: "See Jobs", href: "/jobs", showButtonAs: "text" as const, buttonIconName: "expand_circle_right", buttonIconPosition: "left" as const, }, }; render(); expect(screen.getByTestId("cta-button")).toBeInTheDocument(); }); it("renders Button for primary_inverse text CTA variant", () => { const card = { ...defaultCard, cta: { buttonLabel: "See Jobs", href: "/jobs", showButtonAs: "text" as const, buttonVariant: "primary_inverse" as const, buttonIconName: "expand_circle_right", }, }; render(); expect(screen.getByTestId("cta-button")).toBeInTheDocument(); }); it("renders Button for primary_navy alias", () => { const card = { ...defaultCard, cta: { buttonLabel: "See Jobs", href: "/jobs", showButtonAs: "text" as const, buttonVariant: "primary_navy" as any, buttonIconName: "expand_circle_right", }, }; render(); expect(screen.getByTestId("cta-button")).toBeInTheDocument(); }); it("renders authored icon CTA when buttonIconName is set even if href is missing", () => { const card = { ...defaultCard, cta: { buttonLabel: "See Jobs", showButtonAs: "text" as const, buttonIconName: "expand_circle_right", }, }; render(); expect(screen.getByTestId("cta-button")).toBeInTheDocument(); }); }); describe("CTA alignment", () => { it("applies left alignment by default", () => { const card = { ...defaultCard, cta: { buttonLabel: "Click", href: "/click" }, }; render(); const ctaWrapper = screen.getByTestId("cta-button").parentElement; expect(ctaWrapper?.className).toContain("justify-start"); }); it("applies center alignment", () => { const card = { ...defaultCard, cta: { buttonLabel: "Click", href: "/click" }, ctaAlignment: "center" as const, }; render(); const ctaWrapper = screen.getByTestId("cta-button").parentElement; expect(ctaWrapper?.className).toContain("justify-center"); }); it("applies right alignment", () => { const card = { ...defaultCard, cta: { buttonLabel: "Click", href: "/click" }, ctaAlignment: "right" as const, }; render(); const ctaWrapper = screen.getByTestId("cta-button").parentElement; expect(ctaWrapper?.className).toContain("justify-end"); }); }); describe("PromoBar mode", () => { it("renders only image when isPromoBarImg is true", () => { const card = { ...defaultCard, isPromoBarImg: true, }; const { container } = render(); expect(container.querySelector("section")).not.toBeInTheDocument(); expect(screen.getByTestId("next-image")).toBeInTheDocument(); }); it("returns null when isPromoBarImg is true and no image", () => { const card = { ...defaultCard, image: undefined, isPromoBarImg: true, }; const { container } = render(); expect(container.firstChild).toBeNull(); }); }); describe("Image link", () => { it("makes image clickable when imageLink is provided", () => { const windowOpen = jest .spyOn(window, "open") .mockImplementation(() => null); const card = { ...defaultCard, imageLink: "https://example.com", }; render(); const img = screen.getByTestId("next-image"); img.click(); expect(windowOpen).toHaveBeenCalledWith("https://example.com", "_blank"); windowOpen.mockRestore(); }); }); describe("Layout props", () => { it("applies lgWidth class", () => { const { container } = render( ); expect(container.querySelector("section")?.className).toContain( "lg:w-1/3" ); }); it("applies mdWidth class", () => { const { container } = render( ); expect(container.querySelector("section")?.className).toContain( "md:w-1/2" ); }); it("applies shadow class when shadow is true", () => { const card = { ...defaultCard, shadow: true }; const { container } = render(); expect(container.querySelector("section")?.className).toContain( "shadow-card" ); }); }); });