import React from "react";
import { fireEvent, render, waitFor } from "@testing-library/react-native";
import { Alert } from "react-native";
import type { ButtonGroupProps } from "./ButtonGroup";
import { ButtonGroup } from "./ButtonGroup";
import { Button } from "../Button";
import * as atlantisContext from "../AtlantisContext/AtlantisContext";
import { atlantisContextDefaultValues } from "../AtlantisContext";
const mockOnOpen = jest.fn();
function ButtonGroupForTest(props: ButtonGroupProps) {
return (
{props.children}
);
}
it("renders a single primary action", () => {
const createAction = jest.fn();
const { getByText, queryByLabelText } = render(
,
);
expect(getByText("Create")).not.toBeNull();
expect(queryByLabelText("More")).toBeNull();
});
it("renders 2 primary actions", () => {
const createAction = jest.fn();
const editAction = jest.fn();
const { getByText, queryByLabelText } = render(
,
);
expect(getByText("Create")).not.toBeNull();
expect(getByText("Edit")).not.toBeNull();
expect(queryByLabelText("More")).toBeNull();
});
it("does not render more than 2 primary actions but adds a More button", () => {
const createAction = jest.fn();
const editAction = jest.fn();
const mysteryAction = jest.fn();
const { getByText, queryByText, getByLabelText } = render(
,
);
expect(getByText("Create")).not.toBeNull();
expect(getByText("Edit")).not.toBeNull();
expect(queryByText("Mystery")).toBeNull();
expect(getByLabelText("More")).toBeDefined();
});
it("does not render secondary actions", () => {
const createAction = jest.fn();
const editAction = jest.fn();
const deleteAction = jest.fn();
const { getByText, queryByText, getByLabelText } = render(
,
);
expect(getByText("Create")).not.toBeNull();
expect(queryByText("Edit")).toBeNull();
expect(queryByText("Delete")).toBeNull();
expect(getByLabelText("More")).toBeDefined();
});
it("renders first secondary action as a primary action button if no primary action specified", () => {
const editAction = jest.fn();
const deleteAction = jest.fn();
const { queryByText, getByText, getByLabelText } = render(
,
);
expect(getByText("Edit")).not.toBeNull();
expect(queryByText("Delete")).toBeNull();
expect(getByLabelText("More")).toBeDefined();
});
it("fires the press handlers when the primary action buttons are pressed", () => {
const createAction = jest.fn();
const editAction = jest.fn();
const { getByText } = render(
,
);
fireEvent.press(getByText("Create"));
expect(createAction).toHaveBeenCalled();
fireEvent.press(getByText("Edit"));
expect(editAction).toHaveBeenCalled();
});
it("opens the secondary action menu when the More button is pressed", async () => {
const createAction = jest.fn();
const editAction = jest.fn();
const deleteAction = jest.fn();
const { findByText, queryByText, getByLabelText } = render(
,
);
expect(queryByText("Edit")).toBeNull();
fireEvent.press(getByLabelText("More"));
expect(await findByText("Edit")).not.toBeNull();
expect(await findByText("Delete")).not.toBeNull();
});
it("renders heading and cancel options if passed in", async () => {
const createAction = jest.fn();
const editAction = jest.fn();
const { findByText, getByLabelText } = render(
,
);
fireEvent.press(getByLabelText("More"));
expect(await findByText("Heading")).not.toBeNull();
expect(await findByText("Cancel")).not.toBeNull();
});
it("renders custom button for primary action if passed in", () => {
const createAction = jest.fn();
const customCreateButton = (
);
const { queryByText, getByText } = render(
,
);
expect(getByText("CustomCreate")).not.toBeNull();
expect(queryByText("Create")).toBeNull();
});
it("calls onOpenBottomSheet when the secondary actions are opened", async () => {
const createAction = jest.fn();
const editAction = jest.fn();
const deleteAction = jest.fn();
const { getByLabelText } = render(
,
);
fireEvent.press(getByLabelText("More"));
await waitFor(() => {
expect(mockOnOpen).toHaveBeenCalledTimes(1);
});
});
describe("ButtonGroup Offline/Online", () => {
const atlantisContextSpy = jest.spyOn(atlantisContext, "useAtlantisContext");
afterEach(() => {
jest.restoreAllMocks();
});
const handlePress = jest.fn();
const label = "Click me";
const setup = () =>
render(
,
);
it("should show an alert and not fire the onPress", () => {
const alertSpy = jest.spyOn(Alert, "alert");
atlantisContextSpy.mockReturnValue({
...atlantisContextDefaultValues,
isOnline: false,
});
const { getByText } = setup();
fireEvent.press(getByText(label));
expect(alertSpy).toHaveBeenCalled();
expect(handlePress).not.toHaveBeenCalled();
});
it("should fire the onPress and not show an alert", () => {
const alertSpy = jest.spyOn(Alert, "alert");
const { getByText } = setup();
fireEvent.press(getByText(label));
expect(handlePress).toHaveBeenCalled();
expect(alertSpy).not.toHaveBeenCalled();
});
});