import {
render,
fireEvent,
screen,
within,
} from "@testing-library/react-native";
import React from "react";
import { PageHeader } from "./"; // Assuming index.tsx is in the same folder
import { ButtonProps } from "../../Button"; // Adjust path as necessary
// import { AppIcons } from "../../../index"; // Adjust path as necessary - Not directly used in mock after change
// Define a simple type for the mocked icon
type MockIconType = { name: string };
// Mock the Button component
jest.mock("../../Button", () => ({
Button: jest.fn(
({
label,
onPress,
icon,
showBadge,
...rest
}: ButtonProps & { icon?: MockIconType }) => {
const MockButton = require("react-native").TouchableOpacity;
const MockText = require("react-native").Text;
return (
{label}
{icon && Icon:{icon.name}}
{showBadge && Badge}
);
},
),
}));
// Mock AppIcons - specifically the Bell icon used by PageHeader's NotificationAction
jest.mock("../../../index", () => ({
AppIcons: {
Bell: { name: "Bell" } as MockIconType, // Ensure the mock matches MockIconType
},
}));
describe("PageHeader", () => {
const mockOnPressNotification = jest.fn();
const defaultProps = {
title: "Test Page Title",
};
const propsWithActions = {
...defaultProps,
actions: [
{
type: "notifications" as const,
label: "Notifications",
onPress: mockOnPressNotification,
showBadge: false,
},
],
};
const propsWithMultipleActions = {
...defaultProps,
actions: [
{
type: "notifications" as const,
label: "Notifications",
onPress: mockOnPressNotification,
showBadge: true,
},
{
type: "notifications" as const, // Assuming another action of the same type for simplicity
label: "Alerts",
onPress: jest.fn(),
},
],
};
beforeEach(() => {
jest.clearAllMocks();
});
// Snapshot tests
it("Snapshot - renders correctly with only a title", () => {
const { toJSON } = render();
expect(toJSON()).toMatchSnapshot();
});
it("Snapshot - renders correctly with one action", () => {
const { toJSON } = render();
expect(toJSON()).toMatchSnapshot();
});
it("Snapshot - renders correctly with multiple actions", () => {
const { toJSON } = render();
expect(toJSON()).toMatchSnapshot();
});
it("Snapshot - renders correctly with one action with a badge", () => {
const propsWithBadge = {
...defaultProps,
actions: [
{
type: "notifications" as const,
label: "Notifications",
onPress: mockOnPressNotification,
showBadge: true,
},
],
};
const { toJSON } = render();
expect(toJSON()).toMatchSnapshot();
});
// Functional tests
it("renders the title correctly", () => {
render();
const title = screen.getByText("Test Page Title");
expect(title).toBeDefined();
});
it("does not render actions if actions prop is not provided", () => {
render();
const notificationButton = screen.queryByText("Notifications");
expect(notificationButton).toBeNull();
});
it("renders action buttons when actions prop is provided", () => {
render();
const notificationButton = screen.getByText("Notifications");
expect(notificationButton).toBeDefined();
});
it("calls the onPress handler of an action button when pressed", () => {
render();
const notificationButton = screen.getByText("Notifications");
fireEvent.press(notificationButton);
expect(mockOnPressNotification).toHaveBeenCalledTimes(1);
});
it("displays a badge on an action button if showBadge is true", () => {
render(
,
);
const badge = screen.getByText("Badge");
expect(badge).toBeDefined();
});
it("does not display a badge if showBadge is false or undefined", () => {
render(
,
);
const badge = screen.queryByText("Badge");
expect(badge).toBeNull();
});
it("renders multiple action buttons correctly", () => {
render();
const notificationsButton = screen.getByText("Notifications");
const alertsButton = screen.getByText("Alerts");
expect(notificationsButton).toBeDefined();
expect(alertsButton).toBeDefined();
const notificationButtonContainer = screen.getByLabelText("Notifications");
const badge = within(notificationButtonContainer).getByText("Badge");
expect(badge).toBeDefined();
});
});