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"], ); }); });