import React from "react"; import type { RenderAPI } from "@testing-library/react-native"; import { fireEvent, render } from "@testing-library/react-native"; import { tokens } from "@jobber/design"; import { AccessibilityInfo } from "react-native"; import { Option, Select } from "."; import { SelectInternalPicker } from "./components/SelectInternalPicker"; const A11yInfoSpy = jest.spyOn(AccessibilityInfo, "isScreenReaderEnabled"); const onChange = jest.fn(); beforeEach(() => { A11yInfoSpy.mockImplementation(() => Promise.resolve(false)); }); afterEach(() => { jest.resetAllMocks(); }); const defaultPlaceholder = "Select an option"; describe("Select", () => { it("renders a Select", () => { const component = render( , ); expect(component.getByTestId("arrowDown")).toBeDefined(); expect( component.getByText(defaultPlaceholder, { includeHiddenElements: true, }), ).toBeDefined(); }); it("renders a Select with a label", () => { const label = "Press me"; const { getByText } = render( , ); expect(getByText(label, { includeHiddenElements: true })).toBeDefined(); }); it("renders a Select with a placeholder", () => { const placeholder = "I am a placeholder"; const { getByText } = render( , ); expect( getByText(placeholder, { includeHiddenElements: true }), ).toBeDefined(); }); it("renders a Select with assistive text", () => { const assistiveText = "You need to pick something"; const { getByText } = render( , ); expect( getByText(assistiveText, { includeHiddenElements: true }), ).toBeDefined(); }); it("renders a disabled Select", () => { const labelText = "labelText"; const { getByText } = render( , ); expect( getByText(labelText, { includeHiddenElements: true }).props.style, ).toContainEqual({ color: tokens["color-disabled"], }); }); it("renders a Select with a value provided", () => { const expectedValue = "That should be me"; const { getByText } = render( , ); expect( getByText(expectedValue, { includeHiddenElements: true }), ).toBeDefined(); }); it("renders a Select with a defaultValue provided", () => { const expectedValue = "It's the 3rd value"; const { getByText } = render( , ); expect( getByText(expectedValue, { includeHiddenElements: true }), ).toBeDefined(); }); it("renders a Select with custom testID", () => { const testID = "testID"; const { getByTestId } = render( , ); expect(getByTestId(`ATL-${testID}-Select`)).toBeDefined(); }); it("renders an accessibilityLabel if provided", () => { const { getByLabelText } = render( , ); expect(getByLabelText("accessibilityLabel")).toBeTruthy(); }); it("fires the onChange callback", () => { const { getByTestId } = render( , ); const select = getByTestId("ATL-Select").findByType(SelectInternalPicker); expect(select).toBeTruthy(); fireEvent(select, "onChange", "1"); expect(onChange).toHaveBeenCalledWith("1"); }); }); describe("when Select is invalid", () => { const labelText = "labelText"; it("renders an invalid Select", () => { const { getByText } = render( , ); expect( getByText(labelText, { includeHiddenElements: true }).props.style, ).toContainEqual({ color: tokens["color-critical"], }); }); it("renders an invalid Select with placeholder", () => { const placeholder = "Place me in the holder"; const { getByText } = render( , ); expect( getByText(placeholder, { includeHiddenElements: true }), ).toBeDefined(); expect( getByText(labelText, { includeHiddenElements: true }).props.style, ).toContainEqual({ color: tokens["color-critical"], }); }); }); describe("when validations are passed to the component", () => { describe("validations fail", () => { let tree: RenderAPI; const labelText = "labelText"; const errorMsg = "Too short"; beforeEach(() => { tree = render( , ); }); it("renders the error message when there is an error", async () => { const select = tree .getByTestId("ATL-Select") .findByType(SelectInternalPicker); fireEvent(select, "onChange", "Apple"); expect( await tree.findByText(errorMsg, { includeHiddenElements: true }), ).toBeTruthy(); }); it("shows the invalid colours", async () => { const select = tree .getByTestId("ATL-Select") .findByType(SelectInternalPicker); fireEvent(select, "onChange", "Apple"); expect( (await tree.findByText(labelText, { includeHiddenElements: true })) .props.style, ).toContainEqual({ color: tokens["color-critical"], }); }); }); describe("validations passes", () => { let tree: RenderAPI; const labelText = "labelText"; const errorMsg = "Not too short"; beforeEach(() => { tree = render( , ); }); it("does not render any error messages", () => { const select = tree .getByTestId("ATL-Select") .findByType(SelectInternalPicker); expect(select).toBeTruthy(); fireEvent(select, "onChange", "Apple"); expect(tree.queryByText(errorMsg)).toBeNull(); }); it("has non-critical colours", () => { const select = tree .getByTestId("ATL-Select") .findByType(SelectInternalPicker); fireEvent(select, "onChange", "Apple"); expect( tree.getByText(labelText, { includeHiddenElements: true }).props.style, ).toContainEqual({ color: tokens["color-text--secondary"], }); }); }); });