import React from "react";
import { allColors, darkTokens } from "@jobber/design";
import { fireEvent, render } from "@testing-library/react-native";
import { Path } from "react-native-svg";
import { Chip } from "./Chip";
import type { ChipProps } from "./Chip";
import { AtlantisThemeContextProvider } from "../AtlantisThemeContext";
import type { EffectiveTheme } from "../AtlantisThemeContext";
import { tokens } from "../utils/design";
it("renders an active Chip", () => {
const { getByText, getByLabelText } = render(
,
);
expect(getByText("Foo")).toBeDefined();
expect(getByLabelText("Foo chip").props.style).toContainEqual({
backgroundColor: tokens["color-surface--reverse"],
});
});
it("renders an active Chip without onPress as disabled", () => {
const { getByTestId } = render(
,
);
expect(
getByTestId("chipTest").props.accessibilityState.disabled,
).toBeTruthy();
});
it("renders an inactive Chip with a default backgroundColor", () => {
const { getByTestId } = render(
,
);
expect(getByTestId("chipTest").props.style).not.toContainEqual({
backgroundColor: tokens["color-surface--reverse"],
});
expect(getByTestId("chipTest").props.style).toContainEqual({
backgroundColor: tokens["color-interactive--background"],
});
});
it("renders an inactive Chip with a surface backgroundColor", () => {
const { getByTestId } = render(
,
);
expect(getByTestId("chipTest").props.style).toContainEqual({
backgroundColor: tokens["color-surface"],
});
});
it("renders an active Chip with icon", () => {
const { getByTestId } = render(
,
);
expect(getByTestId("invoice")).toBeDefined();
});
it("renders an inactive Chip with icon", () => {
const { getByTestId } = render(
,
);
expect(getByTestId("invoice")).toBeDefined();
});
it("renders a Chip with the dismiss icon", () => {
const { getByTestId } = render(
,
);
expect(getByTestId("cross")).toBeDefined();
});
it("should call the handler with the new value", () => {
const pressHandler = jest.fn();
const accessibilityLabel = "test chip";
const { getByLabelText } = render(
,
);
fireEvent.press(getByLabelText(accessibilityLabel));
expect(pressHandler).toHaveBeenCalled();
});
describe("accessibilityLabel", () => {
it("uses accessibilityLabel if specified", () => {
const pressHandler = jest.fn();
const { getByLabelText } = render(
,
);
expect(getByLabelText("accessibilityLabel")).toBeTruthy();
});
it("uses label if unspecified", () => {
const pressHandler = jest.fn();
const { getByLabelText } = render(
,
);
expect(getByLabelText("label")).toBeTruthy();
});
});
describe("accent", () => {
it("uses accent color when present and chip is Active", () => {
const { getByTestId } = render(
,
);
expect(getByTestId("chipTest").props.style).toContainEqual({
backgroundColor: tokens["color-client"],
});
});
});
describe("selection color transitions", () => {
function example(theme: EffectiveTheme, props: Partial = {}) {
return (
);
}
function expectColors(
view: ReturnType,
background: string,
text: string,
icon = text,
) {
expect(view.getByTestId("chipTest")).toHaveStyle({
backgroundColor: background,
});
expect(view.getByText("Object")).toHaveStyle({ color: text });
const paths = view.UNSAFE_root.findAllByType(Path);
expect(paths.length).toBeGreaterThan(0);
for (const path of paths) {
expect(path.props.fill).toBe(icon);
}
}
it.each(["request", "quote", "job", "invoice"] as const)(
"keeps the selected %s fill and white content when the theme changes",
accent => {
expect.hasAssertions();
const props = { accent, icon: accent };
const view = render(example("light", props));
for (const theme of ["light", "dark", "light"] as const) {
view.rerender(example(theme, props));
expectColors(
view,
allColors[`color-${accent}`],
allColors["color-text--reverse"],
);
}
},
);
it("changes the selected client fill and foreground together with the theme", () => {
expect.hasAssertions();
const props = { accent: "client", icon: "clients" } as const;
const view = render(example("light", props));
expectColors(
view,
allColors["color-client"],
allColors["color-text--reverse"],
);
view.rerender(example("dark", props));
expectColors(view, darkTokens["color-client"], allColors["color-text"]);
view.rerender(example("light", props));
expectColors(
view,
allColors["color-client"],
allColors["color-text--reverse"],
);
});
it.each(["request", "client"] as const)(
"restores the theme's normal colors when %s is deselected",
accent => {
const view = render(example("dark", { accent }));
view.rerender(example("dark", { accent, isActive: false }));
expectColors(
view,
darkTokens["color-interactive--background"],
darkTokens["color-text"],
darkTokens[`color-${accent}`],
);
expect(
view.getByTestId("chipTest").props.accessibilityState.checked,
).toBe(false);
},
);
it("preserves default selected colors when an accent is removed and the theme changes", () => {
expect.hasAssertions();
const view = render(example("dark", { accent: "request" }));
view.rerender(example("dark"));
expectColors(
view,
darkTokens["color-surface--reverse"],
darkTokens["color-text--reverse"],
darkTokens["color-surface"],
);
view.rerender(example("light"));
expectColors(
view,
allColors["color-surface--reverse"],
allColors["color-text--reverse"],
allColors["color-surface"],
);
});
});