diff --git a/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/TypeEditor.test.tsx b/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/TypeEditor.test.tsx index 80e684449..b409f629e 100644 --- a/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/TypeEditor.test.tsx +++ b/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/TypeEditor.test.tsx @@ -11,10 +11,6 @@ jest.mock("@madie/madie-util", () => ({ }), })); -const adverseEventStructureDefinition = { - id: "AdverseEvent.actuality", - path: "AdverseEvent.actuality", -}; const codingDef = { path: "Coding", definition: { resourceType: "StructureDefinition", id: "Coding" }, @@ -63,6 +59,75 @@ useFhirDefinitionsServiceApiMock.mockImplementation( ); describe("TypeEditor Component", () => { + test("Should render String component", () => { + const handleChange = jest.fn(); + render( + + ); + const inputField = screen.getByTestId("string-field-input-VALUE"); + expect(inputField).toBeInTheDocument(); + expect(inputField.value).toBe("test string"); + }); + + test("Should render String component", () => { + const handleChange = jest.fn(); + render( + + ); + const inputField = screen.getByTestId("string-field-input-VALUE"); + expect(inputField).toBeInTheDocument(); + expect(inputField.value).toBe("test string"); + }); + + test("Should render Period component", () => { + const handleChange = jest.fn(); + render( + + ); + + expect(screen.getByText("start")).toBeInTheDocument(); + expect(screen.getByText("End")).toBeInTheDocument(); + }); + + test("Should render DateTime component", () => { + const handleChange = jest.fn(); + render( + + ); + const inputDate = screen.getByTestId("date-field-input"); + expect(inputDate).toBeInTheDocument(); + + const inputTime = screen.getByPlaceholderText("hh:mm:ss aa"); + expect(inputTime).toBeInTheDocument(); + + const inputZone = screen.getByTestId("timezone-input-field-"); + expect(inputZone).toBeInTheDocument(); + }); + test("Should render Boolean component", () => { const handleChange = jest.fn(); render( @@ -92,6 +157,7 @@ describe("TypeEditor Component", () => { ); expect(screen.getByTestId("uri-input-field-URI")).toBeInTheDocument(); }); + test("Should render Instant component by instant", () => { const handleChange = jest.fn(); render( @@ -118,4 +184,67 @@ describe("TypeEditor Component", () => { ); expect(screen.getByTestId("instant-input")).toBeInTheDocument(); }); + + test("Should render Date component", () => { + const handleChange = jest.fn(); + render( + + ); + + const inputField = screen.getByTestId("date-field--input"); + expect(inputField).toBeInTheDocument(); + expect(inputField.value).toBe("09/26/2024"); + }); + + test("Should render PositiveInt component", () => { + const handleChange = jest.fn(); + render( + + ); + const inputField = screen.getByTestId("integer-field-input-"); + expect(inputField).toBeInTheDocument(); + expect(inputField.value).toBe("1234"); + }); + + test("Should render unsignedInt component", () => { + const handleChange = jest.fn(); + render( + + ); + const inputField = screen.getByTestId("integer-field-input-Integer Field"); + expect(inputField).toBeInTheDocument(); + expect(inputField.value).toBe("1234"); + }); + + test("Should display unsupported", () => { + const handleChange = jest.fn(); + render( + + ); + expect(screen.getByText(`Unsupported Type [test]`)).toBeInTheDocument(); + }); }); diff --git a/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/TypeEditor.tsx b/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/TypeEditor.tsx index e246c4b86..ddbb9cc21 100644 --- a/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/TypeEditor.tsx +++ b/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/TypeEditor.tsx @@ -8,6 +8,7 @@ import DateTimeComponent from "./types/DateTimeComponent"; import BooleanComponent from "./types/BooleanComponent"; import UriComponent from "./types/UriComponent"; import DateComponent from "./types/DateComponent"; +import IntegerComponent, { IntegerType } from "./types/IntegerComponent"; import CodesComponent from "./types/CodesComponent"; import { Instant } from "@madie/madie-design-system/dist/react"; @@ -113,6 +114,30 @@ const TypeEditor = ({ value={value} /> ); + case "positiveInt": + return ( + + ); + case "unsignedInt": + return ( + + ); case "code": return ( { @@ -9,13 +9,13 @@ describe("IntegerComponent", () => { const handleChange = jest.fn(); render( ); @@ -23,7 +23,10 @@ describe("IntegerComponent", () => { expect(integerField).toBeInTheDocument(); const integerFieldInput = screen.getByTestId("integer-field-input-"); expect(integerFieldInput).toBeInTheDocument(); - expect(integerFieldInput.value).toBe("4294967295"); + expect(integerFieldInput.value).toBe("-1"); + expect( + screen.getByText("Unsigned integer range is [0 to 2147483647]") + ).toBeInTheDocument(); }); test("Should validate Unsigned IntegerComponent", () => { @@ -36,7 +39,7 @@ describe("IntegerComponent", () => { fieldRequired={false} onChange={handleChange} structureDefinition={null} - signed={false} + integerType={IntegerType.UNSIGNED} /> ); @@ -46,14 +49,14 @@ describe("IntegerComponent", () => { expect(integerFieldInput).toBeInTheDocument(); expect(integerFieldInput.value).toBe("1"); - fireEvent.change(integerFieldInput, { target: { value: "10" } }); + fireEvent.change(integerFieldInput, { target: { value: "2147483647" } }); expect( - screen.queryByText("Unsigned integer range is [0 to 4294967295]") + screen.queryByText("Unsigned integer range is [0 to 2147483647]") ).not.toBeInTheDocument(); fireEvent.change(integerFieldInput, { target: { value: "-10" } }); expect( - screen.getByText("Unsigned integer range is [0 to 4294967295]") + screen.getByText("Unsigned integer range is [0 to 2147483647]") ).toBeInTheDocument(); }); @@ -67,7 +70,7 @@ describe("IntegerComponent", () => { fieldRequired={false} onChange={handleChange} structureDefinition={null} - signed={false} + integerType={IntegerType.UNSIGNED} /> ); const integerField = screen.getByTestId("integer-field-"); @@ -79,7 +82,7 @@ describe("IntegerComponent", () => { expect(screen.getByText("Invalid format")).toBeInTheDocument(); userEvent.type(integerFieldInput, "1"); expect( - screen.getByText("Unsigned integer range is [0 to 4294967295]") + screen.getByText("Unsigned integer range is [0 to 2147483647]") ).toBeInTheDocument(); }); @@ -93,7 +96,7 @@ describe("IntegerComponent", () => { fieldRequired={false} onChange={handleChange} structureDefinition={null} - signed={false} + integerType={IntegerType.UNSIGNED} /> ); const integerField = screen.getByTestId("integer-field-"); @@ -105,7 +108,61 @@ describe("IntegerComponent", () => { expect(integerFieldInput.value).toBe(""); }); - test("Test on key press of reaching maximum causes prevent default for Unsigned IntegerComponent", () => { + test("Test on key press of valid Unsigned IntegerComponent", () => { + const handleChange = jest.fn(); + render( + + ); + const integerField = screen.getByTestId("integer-field-Integer"); + expect(integerField).toBeInTheDocument(); + const integerFieldInput = screen.getByTestId( + "integer-field-input-Integer" + ); + expect(integerFieldInput).toBeInTheDocument(); + expect(integerFieldInput.value).toBe(""); + + fireEvent.keyPress(integerFieldInput, { key: "8", charCode: 56 }); + expect( + screen.queryByText("Unsigned integer range is [0 to 2147483647]") + ).not.toBeInTheDocument(); + }); + + test("Test on key press of number reaching maximum causes prevent default for Unsigned IntegerComponent", () => { + const handleChange = jest.fn(); + render( + + ); + const integerField = screen.getByTestId("integer-field-Unsigned"); + expect(integerField).toBeInTheDocument(); + const integerFieldInput = screen.getByTestId( + "integer-field-input-Unsigned" + ); + expect(integerFieldInput).toBeInTheDocument(); + expect(integerFieldInput.value).toBe(""); + + fireEvent.change(integerFieldInput, { target: { value: "214748364" } }); + expect(integerFieldInput.value).toBe("214748364"); + + fireEvent.keyPress(integerFieldInput, { key: "8", charCode: 56 }); + expect(integerFieldInput.value).toBe("214748364"); + }); + + test("Test on key press of number reaching minimum causes prevent default for Unsigned IntegerComponent", () => { const handleChange = jest.fn(); render( { fieldRequired={false} onChange={handleChange} structureDefinition={null} - signed={false} + integerType={IntegerType.UNSIGNED} /> ); const integerField = screen.getByTestId("integer-field-"); @@ -124,15 +181,16 @@ describe("IntegerComponent", () => { expect(integerFieldInput).toBeInTheDocument(); expect(integerFieldInput.value).toBe(""); - fireEvent.change(integerFieldInput, { target: { value: "429496729" } }); - expect(integerFieldInput.value).toBe("429496729"); - fireEvent.keyPress(integerFieldInput, { key: "6", charCode: 54 }); - expect(integerFieldInput.value).toBe("429496729"); + fireEvent.change(integerFieldInput, { target: { value: "0" } }); + expect(integerFieldInput.value).toBe("0"); + + fireEvent.keyPress(integerFieldInput, { key: "-", charCode: 173 }); + expect(integerFieldInput.value).toBe("0"); }); }); - describe("Signed IntegerComponent", () => { - test("Should render Signed IntegerComponent", () => { + describe("PositiveInt IntegerComponent", () => { + test("Should render PositiveInt IntegerComponent", () => { const handleChange = jest.fn(); render( { fieldRequired={false} onChange={handleChange} structureDefinition={null} - signed={true} + integerType={IntegerType.POSITIVE_INT} /> ); @@ -153,44 +211,42 @@ describe("IntegerComponent", () => { expect(integerFieldInput.value).toBe("2147483647"); }); - test("Should validate Signed IntegerComponent", () => { + test("Should validate PositiveInt IntegerComponent", () => { const handleChange = jest.fn(); render( ); const integerField = screen.getByTestId("integer-field-"); expect(integerField).toBeInTheDocument(); const integerFieldInput = screen.getByTestId("integer-field-input-"); expect(integerFieldInput).toBeInTheDocument(); - expect(integerFieldInput.value).toBe(""); + expect(integerFieldInput.value).toBe("1"); fireEvent.change(integerFieldInput, { target: { value: "10" } }); expect( - screen.queryByText( - "Signed integer range is [-2147483648 to 2147483647]" - ) + screen.queryByText("Positive integer range is [1 to 2147483647]") ).not.toBeInTheDocument(); fireEvent.change(integerFieldInput, { target: { value: "2147483648" } }); expect( - screen.getByText("Signed integer range is [-2147483648 to 2147483647]") + screen.getByText("Positive integer range is [1 to 2147483647]") ).toBeInTheDocument(); - fireEvent.change(integerFieldInput, { target: { value: "-2147483649" } }); + fireEvent.change(integerFieldInput, { target: { value: "0" } }); expect( - screen.getByText("Signed integer range is [-2147483648 to 2147483647]") + screen.getByText("Positive integer range is [1 to 2147483647]") ).toBeInTheDocument(); }); - test("Test on key press of non-numeric causes prevent default for Signed IntegerComponent", () => { + test("Test 1 on key press of non-numeric causes prevent default for PositiveInt IntegerComponent", () => { const handleChange = jest.fn(); render( { fieldRequired={false} onChange={handleChange} structureDefinition={null} - signed={true} + integerType={IntegerType.POSITIVE_INT} /> ); const integerField = screen.getByTestId("integer-field-"); @@ -213,7 +269,7 @@ describe("IntegerComponent", () => { expect(integerFieldInput.value).toBe(""); }); - test("Test on key press of duplicate minus signs causes prevent default for Signed IntegerComponent", () => { + test("Test 4 on key press of reaching maximum number causes prevent default for PositiveInt IntegerComponent", () => { const handleChange = jest.fn(); render( { fieldRequired={false} onChange={handleChange} structureDefinition={null} - signed={true} + integerType={IntegerType.POSITIVE_INT} + /> + ); + const integerField = screen.getByTestId("integer-field-"); + expect(integerField).toBeInTheDocument(); + const integerFieldInput = screen.getByTestId("integer-field-input-"); + expect(integerFieldInput).toBeInTheDocument(); + expect(integerFieldInput.value).toBe(""); + + fireEvent.change(integerFieldInput, { target: { value: "214748364" } }); + expect(integerFieldInput.value).toBe("214748364"); + fireEvent.keyPress(integerFieldInput, { key: "8", charCode: 56 }); + expect(integerFieldInput.value).toBe("214748364"); + }); + + test("Test on key press of valid PositiveInt IntegerComponent", () => { + const handleChange = jest.fn(); + render( + + ); + const integerField = screen.getByTestId("integer-field-Integer"); + expect(integerField).toBeInTheDocument(); + const integerFieldInput = screen.getByTestId( + "integer-field-input-Integer" + ); + expect(integerFieldInput).toBeInTheDocument(); + expect(integerFieldInput.value).toBe(""); + + fireEvent.change(integerFieldInput, { target: { value: "214748364" } }); + expect(integerFieldInput.value).toBe("214748364"); + fireEvent.keyPress(integerFieldInput, { key: "7", charCode: 55 }); + expect( + screen.queryByText("Positive integer range is [1 to 2147483647]") + ).not.toBeInTheDocument(); + }); + }); + + describe("Signed IntegerComponent", () => { + test("Should render Signed IntegerComponent", () => { + const handleChange = jest.fn(); + render( + + ); + + const integerField = screen.getByTestId("integer-field-"); + expect(integerField).toBeInTheDocument(); + const integerFieldInput = screen.getByTestId("integer-field-input-"); + expect(integerFieldInput).toBeInTheDocument(); + expect(integerFieldInput.value).toBe("-2147483649"); + expect( + screen.getByText("Signed integer range is [-2147483648 to 2147483647]") + ).toBeInTheDocument(); + }); + + test("Should validate Signed IntegerComponent", () => { + const handleChange = jest.fn(); + render( + + ); + + const integerField = screen.getByTestId("integer-field-"); + expect(integerField).toBeInTheDocument(); + const integerFieldInput = screen.getByTestId("integer-field-input-"); + expect(integerFieldInput).toBeInTheDocument(); + expect(integerFieldInput.value).toBe("1"); + + fireEvent.change(integerFieldInput, { target: { value: "2147483647" } }); + expect( + screen.queryByText("Unsigned integer range is [0 to 2147483647]") + ).not.toBeInTheDocument(); + + fireEvent.change(integerFieldInput, { target: { value: "2147483648" } }); + expect( + screen.getByText("Signed integer range is [-2147483648 to 2147483647]") + ).toBeInTheDocument(); + }); + + test("Test 2 on key press of duplicate minus signs causes prevent default for Signed IntegerComponent", () => { + const handleChange = jest.fn(); + render( + ); const integerField = screen.getByTestId("integer-field-"); @@ -241,7 +407,7 @@ describe("IntegerComponent", () => { expect(integerFieldInput.value).toBe("-1"); }); - test("Test on key press of minus sign with a positive number causes prevent default for Signed IntegerComponent", () => { + test("Test 3 on key press of minus sign with a positive number causes prevent default for Signed IntegerComponent", () => { const handleChange = jest.fn(); render( { fieldRequired={false} onChange={handleChange} structureDefinition={null} - signed={true} + integerType={IntegerType.SIGNED} /> ); const integerField = screen.getByTestId("integer-field-"); @@ -266,7 +432,7 @@ describe("IntegerComponent", () => { expect(integerFieldInput.value).toBe("1"); }); - test("Test on key press of number reaching minimum causes prevent default for Signed IntegerComponent", () => { + test("Test 4 on key press of reaching maximum number causes prevent default for Signed IntegerComponent", () => { const handleChange = jest.fn(); render( { fieldRequired={false} onChange={handleChange} structureDefinition={null} + integerType={IntegerType.SIGNED} /> ); const integerField = screen.getByTestId("integer-field-"); @@ -284,38 +451,38 @@ describe("IntegerComponent", () => { expect(integerFieldInput).toBeInTheDocument(); expect(integerFieldInput.value).toBe(""); - fireEvent.change(integerFieldInput, { target: { value: "-214748364" } }); - expect(integerFieldInput.value).toBe("-214748364"); - - fireEvent.keyPress(integerFieldInput, { key: "9", charCode: 57 }); - expect(integerFieldInput.value).toBe("-214748364"); + fireEvent.change(integerFieldInput, { target: { value: "214748364" } }); + expect(integerFieldInput.value).toBe("214748364"); + fireEvent.keyPress(integerFieldInput, { key: "8", charCode: 56 }); + expect(integerFieldInput.value).toBe("214748364"); }); - test("Test on key press of number reaching maximum causes prevent default for Signed IntegerComponent", () => { + test("Test on key press of valid Signed IntegerComponent", () => { const handleChange = jest.fn(); render( ); - const integerField = screen.getByTestId("integer-field-Signed"); + const integerField = screen.getByTestId("integer-field-Integer"); expect(integerField).toBeInTheDocument(); const integerFieldInput = screen.getByTestId( - "integer-field-input-Signed" + "integer-field-input-Integer" ); expect(integerFieldInput).toBeInTheDocument(); expect(integerFieldInput.value).toBe(""); - fireEvent.change(integerFieldInput, { target: { value: "214748364" } }); - expect(integerFieldInput.value).toBe("214748364"); - fireEvent.keyPress(integerFieldInput, { key: "8", charCode: 56 }); - expect(integerFieldInput.value).toBe("214748364"); + expect( + screen.queryByText( + "Signed integer range is [-2147483648 to 2147483647]" + ) + ).not.toBeInTheDocument(); }); }); }); diff --git a/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/types/IntegerComponent.tsx b/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/types/IntegerComponent.tsx index c10a76d13..ceefc41c7 100644 --- a/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/types/IntegerComponent.tsx +++ b/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/types/IntegerComponent.tsx @@ -1,9 +1,19 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { TextField } from "@madie/madie-design-system/dist/react/"; import "twin.macro"; import "styled-components/macro"; import { TypeComponentProps } from "./TypeComponentProps"; +export enum IntegerType { + UNSIGNED = "Unsigned", + SIGNED = "Signed", + POSITIVE_INT = "PositiveInt", +} + +interface IntegerComponentProps extends TypeComponentProps { + integerType: IntegerType; +} + const IntegerComponent = ({ canEdit, fieldRequired, @@ -11,14 +21,43 @@ const IntegerComponent = ({ onChange, label = "Integer", structureDefinition, - signed = true, -}: TypeComponentProps) => { - const SIGNED_MINIMUM = -2147483648; - const SIGNED_MAXIMUM = 2147483647; + integerType, +}: IntegerComponentProps) => { + const POSITIVEINT_MINIMUM = 1; + const POSITIVEINT_MAXIMUM = 2147483647; const UNSIGNED_MINIMUM = 0; - const UNSIGNED_MAXIMUN = 4294967295; + const UNSIGNED_MAXIMUN = 2147483647; + const SIGNED_MINIMUM = -2147483648; + const SIGNED_MAXIMUN = 2147483647; const [inputValue, setInputValue] = useState(value ? value : ""); const [error, setError] = useState(""); + useEffect(() => { + if (integerType === IntegerType.UNSIGNED) { + if ( + Number(value) < UNSIGNED_MINIMUM || + Number(value) > UNSIGNED_MAXIMUN + ) { + setError( + `Unsigned integer range is [${UNSIGNED_MINIMUM} to ${UNSIGNED_MAXIMUN}]` + ); + } + } else if (integerType === IntegerType.POSITIVE_INT) { + if ( + Number(value) < POSITIVEINT_MINIMUM || + Number(value) > POSITIVEINT_MAXIMUM + ) { + setError( + `Positive integer range is [${POSITIVEINT_MINIMUM} to ${POSITIVEINT_MAXIMUM}]` + ); + } + } else { + if (Number(value) < SIGNED_MINIMUM || Number(value) > SIGNED_MAXIMUN) { + setError( + `Signed integer range is [${SIGNED_MINIMUM} to ${SIGNED_MAXIMUN}]` + ); + } + } + }); return ( { - if (!signed && !Number(e.key) && e.key != "0") { + if ( + integerType !== IntegerType.SIGNED && + !Number(e.key) && + e.key != "0" + ) { //when input . after 12, or - for unsigned integer e.preventDefault(); - } else if (signed) { + } else if (integerType === IntegerType.SIGNED) { if (!inputValue && !Number(e.key) && e.key != "0" && e.key != "-") { e.preventDefault(); } else if ( @@ -55,13 +98,19 @@ const IntegerComponent = ({ e.preventDefault(); } else if ( Number(inputValue + e.key) < SIGNED_MINIMUM || - Number(inputValue + e.key) > SIGNED_MAXIMUM + Number(inputValue + e.key) > SIGNED_MAXIMUN ) { e.preventDefault(); } } else { - if (Number(inputValue + e.key) > UNSIGNED_MAXIMUN) { - e.preventDefault(); + if (integerType === IntegerType.UNSIGNED) { + if (Number(inputValue + e.key) > UNSIGNED_MAXIMUN) { + e.preventDefault(); + } + } else { + if (Number(inputValue + e.key) > POSITIVEINT_MAXIMUM) { + e.preventDefault(); + } } } }} @@ -74,7 +123,7 @@ const IntegerComponent = ({ } else { setError(""); } - if (!signed) { + if (integerType === IntegerType.UNSIGNED) { if ( Number(value) >= UNSIGNED_MINIMUM && Number(value) <= UNSIGNED_MAXIMUN @@ -85,15 +134,26 @@ const IntegerComponent = ({ `Unsigned integer range is [${UNSIGNED_MINIMUM} to ${UNSIGNED_MAXIMUN}]` ); } + } else if (integerType === IntegerType.POSITIVE_INT) { + if ( + Number(value) >= POSITIVEINT_MINIMUM && + Number(value) <= POSITIVEINT_MAXIMUM + ) { + onChange(Number(value)); + } else { + setError( + `Positive integer range is [${POSITIVEINT_MINIMUM} to ${POSITIVEINT_MAXIMUM}]` + ); + } } else { if ( Number(value) >= SIGNED_MINIMUM && - Number(value) <= SIGNED_MAXIMUM + Number(value) <= SIGNED_MAXIMUN ) { onChange(Number(value)); } else { setError( - `Signed integer range is [${SIGNED_MINIMUM} to ${SIGNED_MAXIMUM}]` + `Signed integer range is [${SIGNED_MINIMUM} to ${SIGNED_MAXIMUN}]` ); } } diff --git a/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/types/TypeComponentProps.ts b/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/types/TypeComponentProps.ts index 9f8cddae4..d64a99124 100644 --- a/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/types/TypeComponentProps.ts +++ b/src/components/editTestCase/qiCore/LeftPanel/ElementsTab/builder/element/types/TypeComponentProps.ts @@ -5,5 +5,4 @@ export interface TypeComponentProps { onChange?: (nextValue: any) => void; structureDefinition: any; fieldRequired: boolean; - signed?: boolean; }