import React from "react"; import { render, within } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { FieldList, FieldListColumn, FieldListColumnSeparator, FieldListAddButton } from ".."; import { TextInput } from "../../textInput"; const mockItems = [ { name: "Brian Vaughn", role: "Software Engineer", city: "San Jose", id: 0 }, { name: "Jon Doe", role: "Product engineer", city: "Mountain View", id: 1 }, { name: "Jane Doe", role: "UX Designer", city: "San Francisco", id: 2 } ]; describe("FieldList", () => { it("renders", () => { const testRemoveHandler = jest.fn(_rowIndex => () => { jest.fn(); }); const testFieldUpdateHandler = jest.fn((_rowIndex, _pathToValue) => _e => { jest.fn(); }); const { asFragment } = render( {({ defaultProps, onChange, value }) => ( )} : {({ defaultProps, onChange, value }) => ( )} Add row ); expect(asFragment()).toMatchSnapshot(); }); it("calls onAddItem when clicking the add button", () => { const newItem = { id: 42 }; const testAddHandlerInner = jest.fn(); const testAddHandler = jest.fn(itemToAdd => () => { testAddHandlerInner(itemToAdd); }); const testFieldUpdateHandler = jest.fn((_rowIndex, _pathToValue) => _e => { jest.fn(); }); const { getByText } = render( {({ defaultProps, onChange, value }) => ( )} {({ defaultProps, onChange, value }) => ( )} Add Item ); const addButton = getByText("Add Item"); expect(testAddHandlerInner).not.toHaveBeenCalled(); addButton.click(); expect(testAddHandlerInner).toHaveBeenCalledWith(newItem); }); it("calls onRemoveItem when clicking the remove button", () => { const testRemoveHandlerInner = jest.fn(); const testRemoveHandler = jest.fn(rowIndex => () => { testRemoveHandlerInner(rowIndex); }); const testFieldUpdateHandler = jest.fn((_rowIndex, _pathToValue) => _e => { jest.fn(); }); const { getAllByTestId } = render( {({ defaultProps, onChange, value }) => ( )} {({ defaultProps, onChange, value }) => ( )} ); const firstRow = getAllByTestId("fieldList-row")[0] as HTMLDivElement; const firsRowRemoveButton = within(firstRow).getByTestId( "fieldList-removeButton" ); expect(testRemoveHandlerInner).not.toHaveBeenCalled(); firsRowRemoveButton.click(); expect(testRemoveHandlerInner).toHaveBeenCalledWith(0); }); it("disables the inputs and buttons in the rows specified by the disabledRows prop", () => { const testRemoveHandlerInner = jest.fn(); const testRemoveHandler = jest.fn(rowIndex => () => { testRemoveHandlerInner(rowIndex); }); const testFieldUpdateHandler = jest.fn((_rowIndex, _pathToValue) => _e => { jest.fn(); }); const { getAllByTestId } = render( {({ disabled, defaultProps, onChange, value }) => ( )} {({ disabled, defaultProps, onChange, value }) => ( )} ); const testDisabledRow = (disabledRow: HTMLDivElement) => { const textInputsWithinDisabledRow = within(disabledRow).getAllByRole( "textbox" ) as HTMLInputElement[]; const removeButtons = within(disabledRow).getAllByTestId( "fieldList-removeButton" ) as HTMLButtonElement[]; textInputsWithinDisabledRow.forEach(textInputEl => { expect(textInputEl.disabled).toBeTruthy(); }); removeButtons.forEach(buttonEl => { expect(buttonEl.disabled).toBeTruthy(); }); }; const testEnabledRow = (row: HTMLDivElement) => { const textInputsWithinDisabledRow = within(row).getAllByRole( "textbox" ) as HTMLInputElement[]; const removeButtons = within(row).getAllByTestId( "fieldList-removeButton" ) as HTMLButtonElement[]; textInputsWithinDisabledRow.forEach(textInputEl => { expect(textInputEl.disabled).toBeFalsy(); }); removeButtons.forEach(buttonEl => { expect(buttonEl.disabled).toBeFalsy(); }); }; const rows = getAllByTestId("fieldList-row") as HTMLDivElement[]; rows.forEach((row, index) => { if (index === 0) { testDisabledRow(row); } else { testEnabledRow(row); } }); }); it("calls FieldListColumn's `onChange` render prop", async () => { const pathToValue = "name"; const testFieldUpdateHandlerInner = jest.fn(); const testRemoveHandler = jest.fn(_rowIndex => () => { jest.fn(); }); const testFieldUpdateHandler = jest.fn((rowIndex, pathToValue) => _e => { testFieldUpdateHandlerInner(rowIndex, pathToValue); }); const { getAllByTestId } = render( {({ defaultProps, onChange, value }) => ( )} ); const firstRow = getAllByTestId("fieldList-row")[0] as HTMLDivElement; const firstRowFirstColumnTextInput = within(firstRow).getAllByTestId( "textInput-input" )[0] as HTMLInputElement; expect(testFieldUpdateHandlerInner).not.toHaveBeenCalled(); await userEvent.type(firstRowFirstColumnTextInput, "D2iQ"); expect(testFieldUpdateHandlerInner).toHaveBeenCalledWith(0, pathToValue); }); });