import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, it, expect, vi } from "vitest";
import { MessageBanner } from "./MessageBanner";
describe("MessageBanner - visibility", () => {
it("returns null when showWhen is false", () => {
const { container } = render(
);
expect(container.innerHTML).toBe("");
});
it("renders when showWhen is true (default)", () => {
render();
expect(screen.getByText("Visible")).toBeInTheDocument();
});
});
describe("MessageBanner - content rendering", () => {
it("renders primary text", () => {
render();
expect(screen.getByText("Alert")).toBeInTheDocument();
});
it("renders secondary text", () => {
render();
expect(screen.getByText("Details here")).toBeInTheDocument();
});
it("renders both primary and secondary text", () => {
render();
expect(screen.getByText("Title")).toBeInTheDocument();
expect(screen.getByText("Description")).toBeInTheDocument();
});
});
describe("MessageBanner - close button", () => {
it("does not render close button by default", () => {
render();
expect(screen.queryByRole("button", { name: "Close banner" })).not.toBeInTheDocument();
});
it("renders close button when showCloseButton is true", () => {
render();
expect(screen.getByRole("button", { name: "Close banner" })).toBeInTheDocument();
});
it("calls onClose when close button is clicked", async () => {
const user = userEvent.setup();
const onClose = vi.fn();
render();
await user.click(screen.getByRole("button", { name: "Close banner" }));
expect(onClose).toHaveBeenCalledTimes(1);
});
it("renders close button without onClose handler without error", () => {
render();
expect(screen.getByRole("button", { name: "Close banner" })).toBeInTheDocument();
});
});
describe("MessageBanner - action buttons", () => {
it("does not render buttons when buttons prop is omitted", () => {
render();
expect(screen.queryByRole("group")).not.toBeInTheDocument();
});
it("does not render buttons when buttons array is empty", () => {
render();
expect(screen.queryByRole("group")).not.toBeInTheDocument();
});
it("renders buttons when buttons prop is provided", () => {
render(
);
expect(screen.getByRole("button", { name: "Retry" })).toBeInTheDocument();
});
it("renders multiple buttons", () => {
render(
);
expect(screen.getByRole("button", { name: "Accept" })).toBeInTheDocument();
expect(screen.getByRole("button", { name: "Reject" })).toBeInTheDocument();
});
it("button click handlers fire correctly", async () => {
const user = userEvent.setup();
const onClick = vi.fn();
render(
);
await user.click(screen.getByRole("button", { name: "Do it" }));
expect(onClick).toHaveBeenCalledTimes(1);
});
});
describe("MessageBanner - buttons and close together", () => {
it("renders both action buttons and close button", () => {
render(
{}}
/>
);
expect(screen.getByRole("button", { name: "Update" })).toBeInTheDocument();
expect(screen.getByRole("button", { name: "Close banner" })).toBeInTheDocument();
});
it("close and action buttons fire independently", async () => {
const user = userEvent.setup();
const onClose = vi.fn();
const onAction = vi.fn();
render(
);
await user.click(screen.getByRole("button", { name: "Action" }));
expect(onAction).toHaveBeenCalledTimes(1);
expect(onClose).not.toHaveBeenCalled();
await user.click(screen.getByRole("button", { name: "Close banner" }));
expect(onClose).toHaveBeenCalledTimes(1);
expect(onAction).toHaveBeenCalledTimes(1);
});
});