import "@testing-library/jest-dom";
import React, { createRef, forwardRef } from "react";
import { Image } from "./index";
import { ImageComponentProps } from "./types";
import { render, screen } from "@testing-library/react";
// Mock cx
jest.mock("@shared/utils", () => ({
cx: (...args: any[]) => args.filter(Boolean).join(" "),
}));
describe("Image", () => {
it("has displayName set to Image", () => {
expect(Image.displayName).toBe("Image");
});
describe("native img rendering", () => {
it("renders a native img element by default", () => {
render();
const img = screen.getByAltText("Test image");
expect(img.tagName).toBe("IMG");
});
it("passes src prop to img", () => {
render();
const img = screen.getByAltText("Photo");
expect(img).toHaveAttribute("src", "/photo.jpg");
});
it("passes alt prop to img", () => {
render();
const img = screen.getByAltText("My image");
expect(img).toBeInTheDocument();
});
it("passes className to img", () => {
render();
const img = screen.getByAltText("Img");
expect(img).toHaveClass("w-full");
expect(img).toHaveClass("h-auto");
});
it("uses empty string className by default", () => {
render();
const img = screen.getByAltText("Img");
expect(img).toBeInTheDocument();
});
it("passes additional HTML img attributes", () => {
render(
);
const img = screen.getByAltText("Img");
expect(img).toHaveAttribute("width", "200");
expect(img).toHaveAttribute("height", "100");
expect(img).toHaveAttribute("loading", "lazy");
});
});
describe("ref forwarding", () => {
it("forwards ref to native img element", () => {
const ref = createRef();
render();
expect(ref.current).toBeInstanceOf(HTMLImageElement);
expect(ref.current?.tagName).toBe("IMG");
});
it("forwards ref to custom component", () => {
const ref = createRef();
const CustomImage = forwardRef(
function CustomImage(props, fwdRef) {
return
;
}
);
render(
);
expect(ref.current).toBeInstanceOf(HTMLImageElement);
});
});
describe("polymorphic rendering with 'as' prop", () => {
it("renders custom component when 'as' is provided", () => {
const CustomImage = (props: any) => (
{props.alt}
);
render();
expect(screen.getByTestId("custom-image")).toBeInTheDocument();
expect(screen.getByTestId("custom-image")).toHaveAttribute(
"data-src",
"/custom.png"
);
});
it("passes className to custom component", () => {
const CustomImage = ({ className, ...props }: any) => (
);
render(
);
const img = screen.getByTestId("custom-img");
expect(img).toHaveClass("rounded");
});
it("passes all props to custom component", () => {
const CustomImage = (props: any) => (
);
render(
);
const img = screen.getByTestId("custom-img");
expect(img).toHaveAttribute("data-fill", "true");
expect(img).toHaveAttribute("data-priority", "true");
});
it("does not render native img when as prop is provided", () => {
const CustomImage = (props: any) => (
{props.alt}
);
render();
expect(screen.queryByRole("img")).not.toBeInTheDocument();
});
it("renders forwardRef component via as prop", () => {
const ForwardRefImage = forwardRef(
function ForwardRefImage(props, fwdRef) {
return
;
}
);
render(
);
expect(screen.getByTestId("fwdref-img")).toBeInTheDocument();
});
});
describe("edge cases", () => {
it("renders with empty alt for decorative images", () => {
const { container } = render();
const img = container.querySelector("img");
expect(img).toHaveAttribute("alt", "");
});
it("renders with no className (defaults to empty string)", () => {
const { container } = render();
const img = container.querySelector("img");
expect(img).toBeInTheDocument();
});
});
});