Skip to content

Commit

Permalink
(test) Add unit tests for rendering types
Browse files Browse the repository at this point in the history
  • Loading branch information
NethmiRodrigo committed Nov 29, 2024
1 parent 2f935f0 commit 3e36049
Show file tree
Hide file tree
Showing 17 changed files with 448 additions and 16 deletions.
8 changes: 7 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const Date: React.FC<ComponentProps> = ({ formField, setFormField }) => {
.flat()
.map((type) => (
<RadioButton
key={`date-picker-type-${type.value}`}
id={type.value}
checked={formField.datePickerFormat && formField.datePickerFormat === type.value}
labelText={type.label}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import Date from './date.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: 'date' },
id: '1',
};

describe('Date Component', () => {
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(<Date formField={formField} setFormField={mockSetFormField} />);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const Number: React.FC<ComponentProps> = ({ formField, setFormField }) => {
<>
<TextInput
id="min"
labelText="Min"
labelText="Min value that can be entered"
value={formField.questionOptions?.min ?? ''}
invalid={parseFloat(formField.questionOptions?.min ?? '') > parseFloat(formField.questionOptions?.max ?? '')}
invalidText={
Expand All @@ -28,7 +28,7 @@ const Number: React.FC<ComponentProps> = ({ formField, setFormField }) => {
/>
<TextInput
id="max"
labelText="Max"
labelText="Max value that can be entered"
value={formField.questionOptions?.max ?? ''}
invalid={parseFloat(formField.questionOptions?.min ?? '') > parseFloat(formField.questionOptions?.max ?? '')}
invalidText={
Expand Down
Original file line number Diff line number Diff line change
@@ -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(<Number formField={formField} setFormField={mockSetFormField} />);
}
Original file line number Diff line number Diff line change
@@ -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<ComponentProps> = ({ formField, setFormField }) => {
const { t } = useTranslation();
return (
<NumberInput
<TextInput
id="textAreaRows"
labelText={t('rows', 'Rows')}
value={formField.questionOptions?.rows ?? ''}
hideSteppers={true}
value={formField.questionOptions?.rows ? formField.questionOptions.rows.toString() : ''}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
const updatedQuestion: FormField = {
...formField,
Expand Down
Original file line number Diff line number Diff line change
@@ -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(<TextArea formField={formField} setFormField={mockSetFormField} />);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import Text from './text.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: 'text', minLength: '1', maxLength: '10' },
id: '1',
};

describe('Text Component', () => {
it('renders', () => {
renderTextComponent();

expect(screen.getByText(/min length of characters/i)).toBeInTheDocument();
expect(screen.getByText(/max length of characters/i)).toBeInTheDocument();
});

it('shows the default min and max values', () => {
renderTextComponent();

const minInput = screen.getByRole('textbox', {
name: /min length of characters/i,
});
const maxInput = screen.getByRole('textbox', {
name: /max length of characters/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.minLength = '';
formField.questionOptions.maxLength = '';
const user = userEvent.setup();

renderTextComponent();

const minInput = screen.getByRole('textbox', { name: /min length of characters/i });
await user.type(minInput, '5');
expect(mockSetFormField).toHaveBeenCalledWith({
...formField,
questionOptions: { ...formField.questionOptions, minLength: '5' },
});

const maxInput = screen.getByRole('textbox', { name: /max length of characters/i });
await user.type(maxInput, '6');
expect(mockSetFormField).toHaveBeenLastCalledWith({
...formField,
questionOptions: { ...formField.questionOptions, maxLength: '6' },
});
});
});

function renderTextComponent() {
render(<Text formField={formField} setFormField={mockSetFormField} />);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import Toggle from './toggle.component';
import type { FormField } from '@openmrs/esm-form-engine-lib';

const mockSetFormField = jest.fn();
const formField: FormField = {
datePickerFormat: 'both',
type: 'obs',
questionOptions: { rendering: 'toggle', toggleOptions: { labelTrue: 'True', labelFalse: 'False' } },
id: '1',
};

describe('Toggle Component', () => {
it('renders', () => {
renderToggleComponent();

expect(screen.getByText(/label true/i)).toBeInTheDocument();
expect(screen.getByText(/label false/i)).toBeInTheDocument();
});

it('shows the default labelTrue and labelFalse values', () => {
renderToggleComponent();

const labelTrue = screen.getByRole('textbox', { name: /label true/i });
const labelFalse = screen.getByRole('textbox', { name: /label false/i });

expect(labelTrue).toHaveValue('True');
expect(labelFalse).toHaveValue('False');
});

it('updates the form field when the labelTrue value is changed', () => {
formField.questionOptions.toggleOptions.labelTrue = '';
renderToggleComponent();

const labelTrueInput = screen.getByRole('textbox', { name: /label true/i });

fireEvent.input(labelTrueInput, { target: { value: 'Yes' } });

expect(mockSetFormField).toHaveBeenLastCalledWith({
...formField,
questionOptions: { ...formField.questionOptions, toggleOptions: { labelTrue: 'Yes', labelFalse: 'False' } },
});
});
});

function renderToggleComponent() {
render(<Toggle formField={formField} setFormField={mockSetFormField} />);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ const UiSelectExtended: React.FC<ComponentProps> = ({ formField, setFormField })
return (
<>
<RadioButtonGroup
defaultSelected="optional"
defaultSelected="notSearchable"
name="isUiSelectSearchable"
legendText={t('is', 'Is the ui-select-extended rendering searchable')}
legendText={t('isUiSelectSearchable', 'Is the ui-select-extended rendering searchable')}
>
<RadioButton
id="uiSelectNotSearchable"
defaultChecked={!formField.questionOptions?.isSearchable}
checked={!formField.questionOptions?.isSearchable}
labelText={t('notSearchable', 'Not Searchable')}
onClick={() => {
const updatedQuestion: FormField = {
Expand All @@ -24,11 +24,11 @@ const UiSelectExtended: React.FC<ComponentProps> = ({ formField, setFormField })
};
setFormField(updatedQuestion);
}}
value="optional"
value="notSearchable"
/>
<RadioButton
id="uiSelectSearchable"
defaultChecked={formField.questionOptions?.isSearchable}
checked={formField.questionOptions?.isSearchable}
labelText={t('searchable', 'Searchable')}
onClick={() => {
const updatedQuestion: FormField = {
Expand All @@ -37,7 +37,7 @@ const UiSelectExtended: React.FC<ComponentProps> = ({ formField, setFormField })
};
setFormField(updatedQuestion);
}}
value="required"
value="searchable"
/>
</RadioButtonGroup>
</>
Expand Down
Loading

0 comments on commit 3e36049

Please sign in to comment.