From 3e3604935cb73465df4d5cbf75cf107781b0c363 Mon Sep 17 00:00:00 2001 From: Nethmi Rodrigo Date: Fri, 29 Nov 2024 16:52:57 +0530 Subject: [PATCH] (test) Add unit tests for rendering types --- .eslintrc | 8 +- .../modals/delete-form}/delete-form.modal.tsx | 0 .../modals/delete-form}/delete-form.scss | 0 .../inputs/date/date.component.tsx | 1 + .../rendering-types/inputs/date/date.test.tsx | 48 ++++++++++ .../inputs/number/number.component.tsx | 4 +- .../inputs/number/number.test.tsx | 76 ++++++++++++++++ .../inputs/text-area/textarea.component.tsx | 7 +- .../inputs/text-area/textarea.test.tsx | 50 +++++++++++ .../rendering-types/inputs/text/text.test.tsx | 62 +++++++++++++ .../inputs/toggle/toggle.test.tsx | 49 ++++++++++ .../ui-select-extended.component.tsx | 12 +-- .../ui-select-extended.test.tsx | 49 ++++++++++ .../rendering-types/rendering-type.test.tsx | 90 +++++++++++++++++++ src/index.ts | 5 +- translations/en.json | 2 +- webpack.config.js | 1 - 17 files changed, 448 insertions(+), 16 deletions(-) rename src/components/{dashboard => interactive-builder/modals/delete-form}/delete-form.modal.tsx (100%) rename src/components/{dashboard => interactive-builder/modals/delete-form}/delete-form.scss (100%) create mode 100644 src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/date/date.test.tsx create mode 100644 src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/number/number.test.tsx create mode 100644 src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/text-area/textarea.test.tsx create mode 100644 src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/text/text.test.tsx create mode 100644 src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/toggle/toggle.test.tsx create mode 100644 src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/ui-select-extended/ui-select-extended.test.tsx create mode 100644 src/components/interactive-builder/modals/question/question-form/rendering-types/rendering-type.test.tsx diff --git a/.eslintrc b/.eslintrc index eef523ff..7f954dcc 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,7 +4,6 @@ }, "extends": [ "eslint:recommended", - "plugin:playwright/recommended", "plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended-requiring-type-checking", "plugin:jest-dom/recommended", @@ -17,6 +16,13 @@ }, "plugins": ["@typescript-eslint", "import", "react-hooks", "testing-library"], "root": true, + "overrides": [ + { + "files": ["e2e/**"], + "excludedFiles":["src/**"], + "extends": ["plugin:playwright/recommended"] + } + ], "rules": { "import/no-duplicates": "error", "react-hooks/exhaustive-deps": "warn", diff --git a/src/components/dashboard/delete-form.modal.tsx b/src/components/interactive-builder/modals/delete-form/delete-form.modal.tsx similarity index 100% rename from src/components/dashboard/delete-form.modal.tsx rename to src/components/interactive-builder/modals/delete-form/delete-form.modal.tsx diff --git a/src/components/dashboard/delete-form.scss b/src/components/interactive-builder/modals/delete-form/delete-form.scss similarity index 100% rename from src/components/dashboard/delete-form.scss rename to src/components/interactive-builder/modals/delete-form/delete-form.scss diff --git a/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/date/date.component.tsx b/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/date/date.component.tsx index 9cc4beda..3daca0c9 100644 --- a/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/date/date.component.tsx +++ b/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/date/date.component.tsx @@ -24,6 +24,7 @@ const Date: React.FC = ({ formField, setFormField }) => { .flat() .map((type) => ( { + it('renders', () => { + renderDateComponent(); + + expect(screen.getByText(/the type of date picker to show/i)).toBeInTheDocument(); + }); + + it('checks the default radio button based on date picker format', () => { + renderDateComponent(); + + const calendarAndTimerRadioButton = screen.getByRole('radio', { + name: /calendar and timer/i, + }); + + expect(calendarAndTimerRadioButton).toBeChecked(); + }); + + it('updates the form field when the date picker type is changed', async () => { + renderDateComponent(); + + const user = userEvent.setup(); + const calendarRadioButton = screen.getByRole('radio', { name: /calendar only/i }); + await user.click(calendarRadioButton); + + expect(mockSetFormField).toHaveBeenCalledWith({ + ...formField, + datePickerFormat: 'calendar', + }); + }); +}); + +function renderDateComponent() { + render(); +} diff --git a/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/number/number.component.tsx b/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/number/number.component.tsx index d2fc9ec1..652cff57 100644 --- a/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/number/number.component.tsx +++ b/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/number/number.component.tsx @@ -10,7 +10,7 @@ const Number: React.FC = ({ formField, setFormField }) => { <> parseFloat(formField.questionOptions?.max ?? '')} invalidText={ @@ -28,7 +28,7 @@ const Number: React.FC = ({ formField, setFormField }) => { /> parseFloat(formField.questionOptions?.max ?? '')} invalidText={ diff --git a/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/number/number.test.tsx b/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/number/number.test.tsx new file mode 100644 index 00000000..e93c26a3 --- /dev/null +++ b/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/number/number.test.tsx @@ -0,0 +1,76 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import Number from './number.component'; +import type { FormField } from '@openmrs/esm-form-engine-lib'; + +const mockSetFormField = jest.fn(); +const formField: FormField = { + type: 'obs', + questionOptions: { rendering: 'number', min: '1', max: '10' }, + id: '1', +}; + +describe('Number Component', () => { + it('renders', () => { + renderNumberComponent(); + + expect(screen.getByText(/min value that can be entered/i)).toBeInTheDocument(); + expect(screen.getByText(/max value that can be entered/i)).toBeInTheDocument(); + }); + + it('shows the default min and max values', () => { + renderNumberComponent(); + + const minInput = screen.getByRole('textbox', { + name: /min/i, + }); + const maxInput = screen.getByRole('textbox', { + name: /max/i, + }); + + expect(minInput).toHaveValue('1'); + expect(maxInput).toHaveValue('10'); + }); + + it('updates the form field when the min or max value is changed', async () => { + formField.questionOptions.min = ''; + formField.questionOptions.max = ''; + renderNumberComponent(); + const user = userEvent.setup(); + + const minInput = screen.getByRole('textbox', { name: /min value that can be entered/i }); + await user.type(minInput, '5'); + expect(mockSetFormField).toHaveBeenCalledWith({ + ...formField, + questionOptions: { ...formField.questionOptions, min: '5' }, + }); + + const maxInput = screen.getByRole('textbox', { name: /max value that can be entered/i }); + await user.type(maxInput, '6'); + expect(mockSetFormField).toHaveBeenLastCalledWith({ + ...formField, + questionOptions: { ...formField.questionOptions, max: '6' }, + }); + }); + + it('shows the invalid min and max values', () => { + formField.questionOptions.min = '4'; + formField.questionOptions.max = '3'; + renderNumberComponent(); + + const minInput = screen.getByRole('textbox', { + name: /min value that can be entered/i, + }); + const maxInput = screen.getByRole('textbox', { + name: /max value that can be entered/i, + }); + + expect(minInput).toHaveClass('cds--text-input--invalid'); + expect(maxInput).toHaveClass('cds--text-input--invalid'); + }); +}); + +function renderNumberComponent() { + render(); +} diff --git a/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/text-area/textarea.component.tsx b/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/text-area/textarea.component.tsx index 60c57e0c..7e0c38c8 100644 --- a/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/text-area/textarea.component.tsx +++ b/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/text-area/textarea.component.tsx @@ -1,17 +1,16 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; -import { NumberInput } from '@carbon/react'; +import { TextInput } from '@carbon/react'; import type { FormField } from '@openmrs/esm-form-engine-lib'; import type { ComponentProps } from '@types'; const TextArea: React.FC = ({ formField, setFormField }) => { const { t } = useTranslation(); return ( - ) => { const updatedQuestion: FormField = { ...formField, diff --git a/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/text-area/textarea.test.tsx b/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/text-area/textarea.test.tsx new file mode 100644 index 00000000..dfb9fee0 --- /dev/null +++ b/src/components/interactive-builder/modals/question/question-form/rendering-types/inputs/text-area/textarea.test.tsx @@ -0,0 +1,50 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import TextArea from './textarea.component'; +import type { FormField } from '@openmrs/esm-form-engine-lib'; +import userEvent from '@testing-library/user-event'; + +const mockSetFormField = jest.fn(); +const formField: FormField = { + datePickerFormat: 'both', + type: 'obs', + questionOptions: { rendering: 'textarea', rows: 5 }, + id: '1', +}; + +describe('Text Component', () => { + it('renders', () => { + renderTextComponent(); + + expect(screen.getByText(/rows/i)).toBeInTheDocument(); + }); + + it('shows the default rows value', () => { + renderTextComponent(); + + const rowsInput = screen.getByRole('textbox', { + name: /rows/i, + }); + + expect(rowsInput).toHaveValue('5'); + }); + + it('updates the form field when the rows value is changed', async () => { + formField.questionOptions.rows = 0; + renderTextComponent(); + const user = userEvent.setup(); + const rowsInput = screen.getByRole('textbox', { + name: /rows/i, + }); + await user.type(rowsInput, '8'); + + expect(mockSetFormField).toHaveBeenCalledWith({ + ...formField, + questionOptions: { ...formField.questionOptions, rows: 8 }, + }); + }); +}); + +function renderTextComponent() { + render(