From 455687b848ea99f5fe1eb2dacb011b98ad0a881e Mon Sep 17 00:00:00 2001 From: Carla Martinez Date: Thu, 9 Jan 2025 11:02:21 +0100 Subject: [PATCH] Add a test for IpaTextInput component The `IpaTextInput` component must have a test to check its functionality. Signed-off-by: Carla Martinez --- .../Form/IpaTextInput/IpaTextInput.test.tsx | 122 ++++++++++++++++++ .../Form/IpaTextInput/IpaTextInput.tsx | 15 ++- 2 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 src/components/Form/IpaTextInput/IpaTextInput.test.tsx diff --git a/src/components/Form/IpaTextInput/IpaTextInput.test.tsx b/src/components/Form/IpaTextInput/IpaTextInput.test.tsx new file mode 100644 index 00000000..22cf0186 --- /dev/null +++ b/src/components/Form/IpaTextInput/IpaTextInput.test.tsx @@ -0,0 +1,122 @@ +import React from "react"; +import { render, screen, fireEvent, act } from "@testing-library/react"; +import "@testing-library/jest-dom"; +// Component +import IpaTextInput from "./IpaTextInput"; +// Utils +import { IPAParamDefinition } from "src/utils/ipaObjectUtils"; + +describe("IpaTextInput Component", () => { + const mockOnChange = jest.fn(); + + const mockMetadata = { + objects: { + user: { + name: "user", + takes_params: [ + { + alwaysask: false, + attribute: true, + autofill: false, + class: "String", + cli_metavar: "CUSTOMIPATEXTINPUT", + cli_name: "customipatextinput", + confirm: false, + deprecated_cli_aliases: [], + deprecated: false, + doc: "Custom IpaTextInput.", + flags: [], + label: "Custom IpaTextInput", + maxlength: 255, + multivalue: false, + name: "customipatextinput", + no_convert: false, + noextrawhitespace: true, + pattern_errmsg: "", + pattern: "", + primary_key: false, + query: false, + required: false, + sortorder: 1, + type: "string", + }, + ], + }, + }, + }; + + const mockIpaObject = { + attributelevelrights: {}, + default_attributes: [], + cn: "customipatextinput", + customipatextinput: "Initial value", + dn: "", + gidnumber: "1234", + ipantsecurityidentifier: [], + ipauniqueid: [], + member: [], + member_external: [], + member_group: [], + member_idoverrideuser: [], + member_service: [], + member_user: [], + memberindirect_group: [], + memberindirect_idoverrideuser: [], + memberindirect_service: [], + memberindirect_user: [], + membermanager_group: [], + membermanager_user: [], + memberof_group: [], + memberof_hbacrule: [], + memberof_netgroup: [], + memberof_role: [], + memberof_subid: [], + memberof_sudorule: [], + memberofindirect_group: [], + memberofindirect_hbacrule: [], + memberofindirect_netgroup: [], + memberofindirect_role: [], + memberofindirect_subid: [], + memberofindirect_sudorule: [], + objectclass: [], + }; + + const defaultProps: IPAParamDefinition = { + name: "customipatextinput", + ariaLabel: "Custom IpaTextInput", + ipaObject: mockIpaObject, + objectName: "user", + onChange: mockOnChange, + required: false, + readOnly: false, + metadata: mockMetadata, + }; + + afterEach(() => { + jest.clearAllMocks(); + }); + + it("renders IpaTextInput with default props", () => { + render(); + expect(screen.getByLabelText("Custom IpaTextInput")).toBeInTheDocument(); + }); + + it("calls onChange when input value changes", async () => { + render(); + const textInput = screen.getByLabelText("Custom IpaTextInput"); + + act(() => { + fireEvent.change(textInput, { target: { value: "new value" } }); + }); + + expect(mockOnChange).toHaveBeenCalledTimes(1); + expect(textInput).toHaveValue("new value"); + }); + + it("renders disabled input", () => { + render(); + expect(screen.getByLabelText("Custom IpaTextInput")).toHaveAttribute( + "readonly" + ); + }); +}); diff --git a/src/components/Form/IpaTextInput/IpaTextInput.tsx b/src/components/Form/IpaTextInput/IpaTextInput.tsx index f9188d70..c06d3f47 100644 --- a/src/components/Form/IpaTextInput/IpaTextInput.tsx +++ b/src/components/Form/IpaTextInput/IpaTextInput.tsx @@ -10,12 +10,23 @@ import { const IpaTextInput = (props: IPAParamDefinition) => { const { required, readOnly, value, onChange } = getParamProperties(props); + const [textInputValue, setTextInputValue] = React.useState( + convertToString(value) + ); + + React.useEffect(() => { + setTextInputValue(convertToString(value)); + }, [value]); + return ( onChange(value)} + value={textInputValue} + onChange={(_event, value) => { + setTextInputValue(value); + onChange(value); + }} type="text" aria-label={props.ariaLabel !== undefined ? props.ariaLabel : props.name} isRequired={required}