@openmrs/esm-form-engine-lib 3.1.4-pre.1779 → 3.1.4-pre.1789
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__mocks__/forms/afe-forms/index.ts +9 -0
- package/__mocks__/forms/index.ts +19 -0
- package/__mocks__/forms/rfe-forms/index.ts +50 -0
- package/__mocks__/index.ts +85 -0
- package/__mocks__/single-spa-react.js +4 -9
- package/dist/openmrs-esm-form-engine-lib.js +1 -1
- package/jest.config.js +1 -1
- package/package.json +1 -1
- package/src/components/inputs/date/date.component.tsx +7 -7
- package/src/components/inputs/date/date.test.tsx +2 -22
- package/src/components/inputs/markdown/markdown.component.tsx +8 -4
- package/src/components/inputs/multi-select/multi-select.component.tsx +11 -15
- package/src/components/inputs/multi-select/multi-select.test.tsx +3 -6
- package/src/components/inputs/number/number.component.tsx +6 -6
- package/src/components/inputs/number/number.test.tsx +6 -4
- package/src/components/inputs/radio/radio.component.tsx +2 -2
- package/src/components/inputs/radio/radio.test.tsx +3 -5
- package/src/components/inputs/select/dropdown.component.tsx +1 -0
- package/src/components/inputs/select/dropdown.test.tsx +1 -1
- package/src/components/inputs/text/text.component.tsx +9 -9
- package/src/components/inputs/text/text.test.tsx +5 -5
- package/src/components/inputs/text-area/text-area.component.tsx +2 -2
- package/src/components/inputs/toggle/toggle.component.tsx +3 -3
- package/src/components/inputs/ui-select-extended/ui-select-extended.test.tsx +11 -21
- package/src/components/inputs/unspecified/unspecified.test.tsx +6 -17
- package/src/components/label/label.component.tsx +1 -1
- package/src/components/renderer/field/fieldLogic.test.ts +4 -10
- package/src/components/renderer/field/form-field-renderer.component.tsx +9 -9
- package/src/components/sidebar/useCurrentActivePage.test.ts +0 -1
- package/src/form-engine.test.tsx +34 -46
- package/src/hooks/useFormJson.test.tsx +16 -13
- package/src/hooks/useFormWorkspaceSize.test.ts +40 -19
- package/src/hooks/useInitialValues.test.ts +3 -2
- package/src/hooks/usePostSubmissionActions.test.tsx +0 -2
- package/src/setup-tests.ts +35 -0
- package/src/transformers/default-schema-transformer.test.ts +1 -1
- package/src/utils/common-utils.test.ts +4 -9
- package/src/utils/common-utils.ts +9 -2
- package/src/utils/forms-loader.test.ts +1 -1
- package/src/zscore-tests/bmi-age.test.tsx +2 -7
- package/src/zscore-tests/height-age.test.tsx +2 -7
- package/src/zscore-tests/weight-height.test.tsx +2 -7
- package/tools/update-openmrs-deps.mjs +42 -0
- package/src/setupTests.ts +0 -5
- /package/__mocks__/forms/afe-forms/{component_art.json → component-art.json} +0 -0
- /package/__mocks__/forms/afe-forms/{component_preclinic-review.json → component-preclinic-review.json} +0 -0
- /package/__mocks__/forms/afe-forms/{demo_hts-form.json → demo-hts-form.json} +0 -0
- /package/__mocks__/forms/rfe-forms/{component_art.json → component-art.json} +0 -0
- /package/__mocks__/forms/rfe-forms/{component_preclinic-review.json → component-preclinic-review.json} +0 -0
- /package/__mocks__/forms/rfe-forms/{demo_hts-form.json → demo-hts-form.json} +0 -0
- /package/__mocks__/forms/rfe-forms/{external_data_source_form.json → external-data-source-form.json} +0 -0
- /package/__mocks__/forms/rfe-forms/{labour_and_delivery_test_form.json → labour-and-delivery-test-form.json} +0 -0
- /package/__mocks__/forms/rfe-forms/{mockHistoricalvisitsEncounter.json → mock-historical-visits-encounter.json} +0 -0
- /package/__mocks__/forms/rfe-forms/{mockSaveEncounter.json → mock-save-encounter.json} +0 -0
- /package/__mocks__/forms/rfe-forms/{obs-group-test_form.json → obs-group-test-form.json} +0 -0
- /package/__mocks__/forms/rfe-forms/{sample_fields.json → sample-fields.json} +0 -0
- /package/__mocks__/forms/rfe-forms/{sample_ui-select-ext.json → sample-ui-select-ext.json} +0 -0
- /package/__mocks__/forms/rfe-forms/{sample_unspecified-form.json → sample-unspecified-form.json} +0 -0
@@ -1,13 +1,13 @@
|
|
1
1
|
import React, { useEffect, useMemo } from 'react';
|
2
|
+
import { useTranslation } from 'react-i18next';
|
2
3
|
import { Toggle as ToggleInput } from '@carbon/react';
|
3
4
|
import { type FormFieldInputProps } from '../../../types';
|
4
5
|
import { isTrue } from '../../../utils/boolean-utils';
|
5
6
|
import { shouldUseInlineLayout } from '../../../utils/form-helper';
|
6
|
-
import FieldValueView from '../../value/view/field-value-view.component';
|
7
7
|
import { isEmpty } from '../../../validators/form-validator';
|
8
|
-
import styles from './toggle.scss';
|
9
|
-
import { useTranslation } from 'react-i18next';
|
10
8
|
import { useFormProviderContext } from '../../../provider/form-provider';
|
9
|
+
import FieldValueView from '../../value/view/field-value-view.component';
|
10
|
+
import styles from './toggle.scss';
|
11
11
|
|
12
12
|
const Toggle: React.FC<FormFieldInputProps> = ({ field, value, errors, warnings, setFieldValue }) => {
|
13
13
|
const { t } = useTranslation();
|
@@ -1,18 +1,17 @@
|
|
1
1
|
import React from 'react';
|
2
|
+
import userEvent from '@testing-library/user-event';
|
2
3
|
import { act, render, screen } from '@testing-library/react';
|
3
|
-
import { type FormSchema, type SessionMode, type OpenmrsEncounter } from '../../../types';
|
4
4
|
import { usePatient, useSession } from '@openmrs/esm-framework';
|
5
|
-
import { mockPatient } from '../../../../__mocks__/patient.mock';
|
6
|
-
import { mockSessionDataResponse } from '../../../../__mocks__/session.mock';
|
7
|
-
import { FormEngine } from '../../..';
|
8
|
-
import uiSelectExtForm from '../../../../__mocks__/forms/rfe-forms/sample_ui-select-ext.json';
|
9
|
-
import { assertFormHasAllFields, findSelectInput } from '../../../utils/test-utils';
|
10
|
-
import userEvent from '@testing-library/user-event';
|
11
5
|
import * as api from '../../../api';
|
6
|
+
import { type FormSchema, type SessionMode, type OpenmrsEncounter } from '../../../types';
|
7
|
+
import { assertFormHasAllFields, findSelectInput } from '../../../utils/test-utils';
|
8
|
+
import { mockPatient } from '__mocks__/patient.mock';
|
9
|
+
import { mockSessionDataResponse } from '__mocks__/session.mock';
|
10
|
+
import { uiSelectExtForm } from '__mocks__/forms';
|
11
|
+
import FormEngine from '../../../form-engine.component';
|
12
12
|
|
13
13
|
const mockUsePatient = jest.mocked(usePatient);
|
14
14
|
const mockUseSession = jest.mocked(useSession);
|
15
|
-
global.ResizeObserver = require('resize-observer-polyfill');
|
16
15
|
|
17
16
|
jest.mock('lodash-es/debounce', () => jest.fn((fn) => fn));
|
18
17
|
|
@@ -145,15 +144,6 @@ describe('UiSelectExtended', () => {
|
|
145
144
|
const user = userEvent.setup();
|
146
145
|
|
147
146
|
beforeEach(() => {
|
148
|
-
Object.defineProperty(window, 'i18next', {
|
149
|
-
writable: true,
|
150
|
-
configurable: true,
|
151
|
-
value: {
|
152
|
-
language: 'en',
|
153
|
-
t: jest.fn(),
|
154
|
-
},
|
155
|
-
});
|
156
|
-
|
157
147
|
mockUsePatient.mockImplementation(() => ({
|
158
148
|
patient: mockPatient,
|
159
149
|
isLoading: false,
|
@@ -257,18 +247,18 @@ describe('UiSelectExtended', () => {
|
|
257
247
|
renderForm();
|
258
248
|
});
|
259
249
|
|
260
|
-
const transferLocationSelect = await findSelectInput(screen, 'Transfer Location');
|
250
|
+
const transferLocationSelect = await findSelectInput(screen, 'Transfer Location');
|
261
251
|
// Open the dropdown
|
262
252
|
await user.click(transferLocationSelect);
|
263
|
-
|
253
|
+
|
264
254
|
// Verify all items are displayed initially
|
265
255
|
expect(screen.getByText('Kololo')).toBeInTheDocument();
|
266
256
|
expect(screen.getByText('Naguru')).toBeInTheDocument();
|
267
257
|
expect(screen.getByText('Muyenga')).toBeInTheDocument();
|
268
|
-
|
258
|
+
|
269
259
|
// Type input
|
270
260
|
await user.type(transferLocationSelect, 'Nag');
|
271
|
-
|
261
|
+
|
272
262
|
// Verify all items are still displayed
|
273
263
|
expect(screen.getByText('Kololo')).toBeInTheDocument();
|
274
264
|
expect(screen.getByText('Naguru')).toBeInTheDocument();
|
@@ -1,20 +1,18 @@
|
|
1
1
|
import React from 'react';
|
2
|
+
import userEvent from '@testing-library/user-event';
|
2
3
|
import { act, render, screen } from '@testing-library/react';
|
3
4
|
import { usePatient, useSession } from '@openmrs/esm-framework';
|
5
|
+
import * as api from '../../../api';
|
4
6
|
import { type FormSchema, type SessionMode } from '../../../types';
|
5
7
|
import { findNumberInput } from '../../../utils/test-utils';
|
6
|
-
import unspecifiedForm from '
|
7
|
-
import {
|
8
|
-
import {
|
9
|
-
import
|
10
|
-
import userEvent from '@testing-library/user-event';
|
11
|
-
import * as api from '../../../api';
|
8
|
+
import { unspecifiedForm } from '__mocks__/forms';
|
9
|
+
import { mockPatient } from '__mocks__/patient.mock';
|
10
|
+
import { mockSessionDataResponse } from '__mocks__/session.mock';
|
11
|
+
import FormEngine from '../../../form-engine.component';
|
12
12
|
|
13
13
|
const mockUsePatient = jest.mocked(usePatient);
|
14
14
|
const mockUseSession = jest.mocked(useSession);
|
15
15
|
|
16
|
-
global.ResizeObserver = require('resize-observer-polyfill');
|
17
|
-
|
18
16
|
jest.mock('../../../api', () => {
|
19
17
|
const originalModule = jest.requireActual('../../../api');
|
20
18
|
return {
|
@@ -75,15 +73,6 @@ describe('Unspecified', () => {
|
|
75
73
|
const user = userEvent.setup();
|
76
74
|
|
77
75
|
beforeEach(() => {
|
78
|
-
Object.defineProperty(window, 'i18next', {
|
79
|
-
writable: true,
|
80
|
-
configurable: true,
|
81
|
-
value: {
|
82
|
-
language: 'en',
|
83
|
-
t: jest.fn(),
|
84
|
-
},
|
85
|
-
});
|
86
|
-
|
87
76
|
mockUsePatient.mockImplementation(() => ({
|
88
77
|
patient: mockPatient,
|
89
78
|
isLoading: false,
|
@@ -10,7 +10,7 @@ type LabelProps = {
|
|
10
10
|
const LabelField: React.FC<LabelProps> = ({ value, tooltipText }) => {
|
11
11
|
return (
|
12
12
|
<div className={styles.label}>
|
13
|
-
<DefinitionTooltip direction="bottom" tabIndex={0} definition={tooltipText}>
|
13
|
+
<DefinitionTooltip direction="bottom" tabIndex={0} definition={tooltipText ?? ''}>
|
14
14
|
<span className="cds--label">{`${value}:`}</span>
|
15
15
|
</DefinitionTooltip>
|
16
16
|
</div>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { handleFieldLogic, validateFieldValue } from './fieldLogic';
|
2
|
-
import {
|
2
|
+
import { evaluateExpression } from '../../../utils/expression-runner';
|
3
3
|
import { type FormField } from '../../../types';
|
4
4
|
import { type FormContextProps } from '../../../provider/form-provider';
|
5
5
|
|
@@ -25,7 +25,7 @@ describe('handleFieldLogic', () => {
|
|
25
25
|
formFieldAdapters: {
|
26
26
|
obs: {
|
27
27
|
transformFieldValue: jest.fn(),
|
28
|
-
}
|
28
|
+
},
|
29
29
|
},
|
30
30
|
formJson: { pages: [] },
|
31
31
|
updateFormField: jest.fn(),
|
@@ -112,9 +112,7 @@ describe('validateFieldValue', () => {
|
|
112
112
|
|
113
113
|
mockValidators = {
|
114
114
|
required: {
|
115
|
-
validate: jest.fn().mockReturnValue([
|
116
|
-
{ resultType: 'error', message: 'Field is required' },
|
117
|
-
]),
|
115
|
+
validate: jest.fn().mockReturnValue([{ resultType: 'error', message: 'Field is required' }]),
|
118
116
|
},
|
119
117
|
};
|
120
118
|
|
@@ -131,11 +129,7 @@ describe('validateFieldValue', () => {
|
|
131
129
|
it('should validate field value and return errors and warnings', () => {
|
132
130
|
const result = validateFieldValue(mockField, '', mockValidators, mockContext);
|
133
131
|
|
134
|
-
expect(mockValidators.required.validate).toHaveBeenCalledWith(
|
135
|
-
mockField,
|
136
|
-
'',
|
137
|
-
expect.objectContaining(mockContext),
|
138
|
-
);
|
132
|
+
expect(mockValidators.required.validate).toHaveBeenCalledWith(mockField, '', expect.objectContaining(mockContext));
|
139
133
|
expect(result.errors).toEqual([{ resultType: 'error', message: 'Field is required' }]);
|
140
134
|
expect(result.warnings).toEqual([]);
|
141
135
|
});
|
@@ -1,4 +1,8 @@
|
|
1
1
|
import React, { useEffect, useMemo, useState } from 'react';
|
2
|
+
import { ToastNotification } from '@carbon/react';
|
3
|
+
import { Controller, useWatch } from 'react-hook-form';
|
4
|
+
import { useTranslation } from 'react-i18next';
|
5
|
+
import { ErrorBoundary } from 'react-error-boundary';
|
2
6
|
import {
|
3
7
|
type FormField,
|
4
8
|
type FormFieldInputProps,
|
@@ -7,19 +11,15 @@ import {
|
|
7
11
|
type ValidationResult,
|
8
12
|
type ValueAndDisplay,
|
9
13
|
} from '../../../types';
|
10
|
-
import {
|
11
|
-
import {
|
12
|
-
import { useTranslation } from 'react-i18next';
|
13
|
-
import { ErrorBoundary } from 'react-error-boundary';
|
14
|
+
import { getFieldControlWithFallback, getRegisteredControl } from '../../../registry/registry';
|
15
|
+
import { handleFieldLogic, validateFieldValue } from './fieldLogic';
|
14
16
|
import { hasRendering } from '../../../utils/common-utils';
|
15
|
-
import { useFormProviderContext } from '../../../provider/form-provider';
|
16
17
|
import { isEmpty } from '../../../validators/form-validator';
|
17
|
-
import PreviousValueReview from '../../previous-value-review/previous-value-review.component';
|
18
|
-
import { getFieldControlWithFallback, getRegisteredControl } from '../../../registry/registry';
|
19
|
-
import styles from './form-field-renderer.scss';
|
20
18
|
import { isTrue } from '../../../utils/boolean-utils';
|
19
|
+
import { useFormProviderContext } from '../../../provider/form-provider';
|
20
|
+
import PreviousValueReview from '../../previous-value-review/previous-value-review.component';
|
21
21
|
import UnspecifiedField from '../../inputs/unspecified/unspecified.component';
|
22
|
-
import
|
22
|
+
import styles from './form-field-renderer.scss';
|
23
23
|
|
24
24
|
export interface FormFieldRendererProps {
|
25
25
|
fieldId: string;
|
package/src/form-engine.test.tsx
CHANGED
@@ -14,49 +14,46 @@ import { when } from 'jest-when';
|
|
14
14
|
import * as api from './api';
|
15
15
|
import { assertFormHasAllFields, findCheckboxGroup, findSelectInput, findTextOrDateInput } from './utils/test-utils';
|
16
16
|
import { evaluatePostSubmissionExpression } from './utils/post-submission-action-helper';
|
17
|
-
import { mockPatient } from '__mocks__
|
18
|
-
import {
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
import defaultValuesForm from '__mocks__/forms/rfe-forms/default-values-form.json';
|
50
|
-
|
51
|
-
import FormEngine from './form-engine.component';
|
17
|
+
import { mockConcepts, mockPatient, mockSessionDataResponse, mockVisit } from '__mocks__';
|
18
|
+
import {
|
19
|
+
ageValidationForm,
|
20
|
+
bmiForm,
|
21
|
+
bsaForm,
|
22
|
+
conditionalAnsweredForm,
|
23
|
+
conditionalRequiredTestForm,
|
24
|
+
defaultValuesForm,
|
25
|
+
demoHtsForm,
|
26
|
+
demoHtsOpenmrsForm,
|
27
|
+
diagnosisForm,
|
28
|
+
eddForm,
|
29
|
+
externalDataSourceForm,
|
30
|
+
filterAnswerOptionsTestForm,
|
31
|
+
hidePagesAndSectionsForm,
|
32
|
+
historicalExpressionsForm,
|
33
|
+
htsPocForm,
|
34
|
+
jsExpressionValidationForm,
|
35
|
+
labourAndDeliveryTestForm,
|
36
|
+
mockHxpEncounter,
|
37
|
+
mockSaveEncounter,
|
38
|
+
monthsOnArtForm,
|
39
|
+
nextVisitForm,
|
40
|
+
obsGroupTestForm,
|
41
|
+
postSubmissionTestForm,
|
42
|
+
readOnlyValidationForm,
|
43
|
+
referenceByMappingForm,
|
44
|
+
requiredTestForm,
|
45
|
+
sampleFieldsForm,
|
46
|
+
testEnrolmentForm,
|
47
|
+
viralLoadStatusForm,
|
48
|
+
} from '__mocks__/forms';
|
52
49
|
import { type FormSchema, type OpenmrsEncounter, type SessionMode } from './types';
|
53
50
|
import { useEncounter } from './hooks/useEncounter';
|
51
|
+
import FormEngine from './form-engine.component';
|
54
52
|
|
55
53
|
const patientUUID = '8673ee4f-e2ab-4077-ba55-4980f408773e';
|
56
54
|
const visit = mockVisit;
|
57
55
|
const formsResourcePath = when((url: string) => url.includes(`${restBaseUrl}/form/`));
|
58
56
|
const clobDataResourcePath = when((url: string) => url.includes(`${restBaseUrl}/clobdata/`));
|
59
|
-
global.ResizeObserver = require('resize-observer-polyfill');
|
60
57
|
|
61
58
|
const mockOpenmrsFetch = jest.mocked(openmrsFetch);
|
62
59
|
const mockExtensionSlot = jest.mocked(ExtensionSlot);
|
@@ -152,7 +149,7 @@ jest.mock('./hooks/useConcepts', () => ({
|
|
152
149
|
if ([...references].join(',').includes('PIH:Occurrence of trauma,PIH:Yes,PIH:No,PIH:COUGH')) {
|
153
150
|
return {
|
154
151
|
isLoading: false,
|
155
|
-
concepts:
|
152
|
+
concepts: mockConcepts.results,
|
156
153
|
error: undefined,
|
157
154
|
};
|
158
155
|
}
|
@@ -178,15 +175,6 @@ describe('Form engine component', () => {
|
|
178
175
|
const user = userEvent.setup();
|
179
176
|
|
180
177
|
beforeEach(() => {
|
181
|
-
Object.defineProperty(window, 'i18next', {
|
182
|
-
writable: true,
|
183
|
-
configurable: true,
|
184
|
-
value: {
|
185
|
-
language: 'en',
|
186
|
-
t: jest.fn(),
|
187
|
-
},
|
188
|
-
});
|
189
|
-
|
190
178
|
mockExtensionSlot.mockImplementation((ext) => <>{ext.name}</>);
|
191
179
|
mockUsePatient.mockImplementation(() => ({
|
192
180
|
patient: mockPatient,
|
@@ -2,18 +2,20 @@ import { act, renderHook } from '@testing-library/react';
|
|
2
2
|
import { openmrsFetch } from '@openmrs/esm-framework';
|
3
3
|
import { when } from 'jest-when';
|
4
4
|
import { useFormJson } from './useFormJson';
|
5
|
-
import
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
5
|
+
import {
|
6
|
+
artComponentBody,
|
7
|
+
artComponentSkeleton,
|
8
|
+
formComponentBody,
|
9
|
+
formComponentSkeleton,
|
10
|
+
miniFormBody,
|
11
|
+
miniFormSkeleton,
|
12
|
+
nestedForm1Body,
|
13
|
+
nestedForm1Skeleton,
|
14
|
+
nestedForm2Body,
|
15
|
+
nestedForm2Skeleton,
|
16
|
+
preclinicReviewComponentBody,
|
17
|
+
preclinicReviewComponentSkeleton,
|
18
|
+
} from '__mocks__/forms';
|
17
19
|
|
18
20
|
const MINI_FORM_NAME = 'Mini Form';
|
19
21
|
const MINI_FORM_UUID = '112d73b4-79e5-4be8-b9ae-d0840f00d4cf';
|
@@ -161,7 +163,7 @@ describe('useFormJson', () => {
|
|
161
163
|
});
|
162
164
|
|
163
165
|
it('should return an error when the form is not found', async () => {
|
164
|
-
|
166
|
+
const mockConsoleError = jest.spyOn(console, 'error').mockImplementation(() => {});
|
165
167
|
let hook = null;
|
166
168
|
await act(async () => {
|
167
169
|
hook = renderHook(() => useFormJson(NON_EXISTENT_FORM_NAME, null, null, null));
|
@@ -172,6 +174,7 @@ describe('useFormJson', () => {
|
|
172
174
|
'Error loading form JSON: Form with ID "non-existent-form" was not found',
|
173
175
|
);
|
174
176
|
expect(hook.result.current.formJson).toBe(null);
|
177
|
+
mockConsoleError.mockRestore();
|
175
178
|
});
|
176
179
|
});
|
177
180
|
|
@@ -1,28 +1,17 @@
|
|
1
|
+
import { act } from 'react';
|
1
2
|
import { renderHook } from '@testing-library/react';
|
2
3
|
import { useFormWorkspaceSize } from './useFormWorkspaceSize';
|
3
|
-
import { act } from 'react';
|
4
4
|
|
5
5
|
// Mock the pxToRem utility
|
6
6
|
jest.mock('../utils/common-utils', () => ({
|
7
7
|
pxToRem: (px: number) => px / 16, // Simulate px to rem conversion (1rem = 16px)
|
8
8
|
}));
|
9
9
|
|
10
|
-
// Mock ResizeObserver with callback ref
|
11
|
-
let resizeCallback: (entries: any[]) => void;
|
12
|
-
class ResizeObserverMock {
|
13
|
-
constructor(callback: (entries: any[]) => void) {
|
14
|
-
resizeCallback = callback;
|
15
|
-
}
|
16
|
-
observe = jest.fn();
|
17
|
-
unobserve = jest.fn();
|
18
|
-
disconnect = jest.fn();
|
19
|
-
}
|
20
|
-
|
21
|
-
global.ResizeObserver = ResizeObserverMock as any;
|
22
|
-
|
23
10
|
describe('useFormWorkspaceSize', () => {
|
24
11
|
let ref: { current: HTMLDivElement | null };
|
25
12
|
let parentElement: HTMLDivElement;
|
13
|
+
let resizeCallback: ResizeObserverCallback | null;
|
14
|
+
let originalResizeObserver: typeof global.ResizeObserver;
|
26
15
|
|
27
16
|
beforeEach(() => {
|
28
17
|
// Create DOM elements
|
@@ -37,10 +26,26 @@ describe('useFormWorkspaceSize', () => {
|
|
37
26
|
configurable: true,
|
38
27
|
value: 400,
|
39
28
|
});
|
29
|
+
|
30
|
+
// Store original ResizeObserver
|
31
|
+
originalResizeObserver = global.ResizeObserver;
|
32
|
+
resizeCallback = null;
|
33
|
+
|
34
|
+
// Store the ResizeObserver callback
|
35
|
+
global.ResizeObserver = class MockResizeObserver implements ResizeObserver {
|
36
|
+
constructor(callback: ResizeObserverCallback) {
|
37
|
+
resizeCallback = callback;
|
38
|
+
}
|
39
|
+
observe() {}
|
40
|
+
unobserve() {}
|
41
|
+
disconnect() {}
|
42
|
+
};
|
40
43
|
});
|
41
44
|
|
42
45
|
afterEach(() => {
|
43
|
-
|
46
|
+
// Restore original ResizeObserver
|
47
|
+
global.ResizeObserver = originalResizeObserver;
|
48
|
+
resizeCallback = null;
|
44
49
|
});
|
45
50
|
|
46
51
|
const setParentWidth = (width: number) => {
|
@@ -48,12 +53,28 @@ describe('useFormWorkspaceSize', () => {
|
|
48
53
|
configurable: true,
|
49
54
|
value: width,
|
50
55
|
});
|
51
|
-
if (typeof resizeCallback !== 'function') {
|
52
|
-
return;
|
53
|
-
}
|
54
56
|
// Trigger resize callback
|
55
57
|
act(() => {
|
56
|
-
resizeCallback
|
58
|
+
if (resizeCallback) {
|
59
|
+
const entry: ResizeObserverEntry = {
|
60
|
+
target: parentElement,
|
61
|
+
borderBoxSize: [{ blockSize: 0, inlineSize: width }],
|
62
|
+
contentBoxSize: [{ blockSize: 0, inlineSize: width }],
|
63
|
+
contentRect: {
|
64
|
+
width,
|
65
|
+
height: 0,
|
66
|
+
x: 0,
|
67
|
+
y: 0,
|
68
|
+
top: 0,
|
69
|
+
right: width,
|
70
|
+
bottom: 0,
|
71
|
+
left: 0,
|
72
|
+
toJSON: () => ({}),
|
73
|
+
},
|
74
|
+
devicePixelContentBoxSize: [{ blockSize: 0, inlineSize: width }],
|
75
|
+
};
|
76
|
+
resizeCallback([entry], {} as ResizeObserver);
|
77
|
+
}
|
57
78
|
});
|
58
79
|
};
|
59
80
|
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import { act, renderHook, waitFor } from '@testing-library/react';
|
2
|
-
|
3
|
-
import useInitialValues from './useInitialValues';
|
4
2
|
import { type FormField } from '../types';
|
3
|
+
import useInitialValues from './useInitialValues';
|
5
4
|
|
6
5
|
export const mockFormFields: FormField[] = [
|
7
6
|
{
|
@@ -51,6 +50,7 @@ describe('useInitialValues', () => {
|
|
51
50
|
});
|
52
51
|
|
53
52
|
it('should set error if getInitialValues rejects', async () => {
|
53
|
+
const mockConsole = jest.spyOn(console, 'error').mockImplementation(() => {});
|
54
54
|
const mockError = new Error('Failed to fetch initial values');
|
55
55
|
formProcessor.getInitialValues.mockRejectedValue(mockError);
|
56
56
|
|
@@ -58,6 +58,7 @@ describe('useInitialValues', () => {
|
|
58
58
|
|
59
59
|
expect(result.current.error).toEqual(mockError);
|
60
60
|
expect(result.current.isLoadingInitialValues).toBe(false);
|
61
|
+
mockConsole.mockRestore();
|
61
62
|
});
|
62
63
|
|
63
64
|
it('should set initial values when dependencies are loaded', async () => {
|
@@ -18,8 +18,6 @@ describe('usePostSubmissionActions', () => {
|
|
18
18
|
|
19
19
|
// Set up the mock implementation for getRegisteredPostSubmissionAction
|
20
20
|
beforeEach(() => {
|
21
|
-
jest.clearAllMocks();
|
22
|
-
jest.spyOn(global.console, 'error').mockImplementation(() => {});
|
23
21
|
jest.requireMock('../registry/registry').getRegisteredPostSubmissionAction.mockImplementation((actionId) => {
|
24
22
|
if (actionId === 'action1') {
|
25
23
|
return Promise.resolve(mockPostAction);
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import '@testing-library/jest-dom';
|
2
|
+
import 'jest-when';
|
3
|
+
|
4
|
+
global.ResizeObserver = require('resize-observer-polyfill');
|
5
|
+
|
6
|
+
// https://github.com/jsdom/jsdom/issues/1695
|
7
|
+
window.HTMLElement.prototype.scrollIntoView = function () {};
|
8
|
+
|
9
|
+
Object.defineProperty(window, 'i18next', {
|
10
|
+
writable: true,
|
11
|
+
configurable: true,
|
12
|
+
value: {
|
13
|
+
language: 'en',
|
14
|
+
t: jest.fn(),
|
15
|
+
},
|
16
|
+
});
|
17
|
+
|
18
|
+
// Mock getComputedStyle for consistent font size
|
19
|
+
Object.defineProperty(window, 'getComputedStyle', {
|
20
|
+
value: () => ({
|
21
|
+
fontSize: '16px',
|
22
|
+
getPropertyValue: () => '',
|
23
|
+
}),
|
24
|
+
});
|
25
|
+
|
26
|
+
// Mock window.getComputedStyle for elements
|
27
|
+
Object.defineProperty(HTMLElement.prototype, 'style', {
|
28
|
+
configurable: true,
|
29
|
+
get() {
|
30
|
+
return {
|
31
|
+
getPropertyValue: () => '',
|
32
|
+
setProperty: () => {},
|
33
|
+
};
|
34
|
+
},
|
35
|
+
});
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { type FormSchema } from '../types';
|
2
2
|
import { DefaultFormSchemaTransformer } from './default-schema-transformer';
|
3
|
-
import testForm from '__mocks__/forms
|
3
|
+
import { testForm } from '__mocks__/forms';
|
4
4
|
|
5
5
|
const expectedTransformedSchema = {
|
6
6
|
name: 'AFE form with aliased questions',
|
@@ -1,19 +1,14 @@
|
|
1
1
|
import {
|
2
|
-
flattenObsList,
|
3
|
-
hasRendering,
|
4
2
|
clearSubmission,
|
3
|
+
flattenObsList,
|
5
4
|
gracefullySetSubmission,
|
5
|
+
hasRendering,
|
6
6
|
hasSubmission,
|
7
7
|
parseToLocalDateTime,
|
8
8
|
} from './common-utils';
|
9
9
|
import { isEmpty } from '../validators/form-validator';
|
10
|
-
import {
|
11
|
-
import {
|
12
|
-
|
13
|
-
jest.mock('@openmrs/esm-framework', () => ({
|
14
|
-
formatDate: jest.fn(),
|
15
|
-
restBaseUrl: 'http://openmrs.com/rest',
|
16
|
-
}));
|
10
|
+
import { obsList } from '__mocks__/forms';
|
11
|
+
import { type FormField } from '../types';
|
17
12
|
|
18
13
|
jest.mock('../validators/form-validator', () => ({
|
19
14
|
isEmpty: jest.fn(),
|
@@ -59,9 +59,16 @@ export function isViewMode(sessionMode: string) {
|
|
59
59
|
|
60
60
|
export function parseToLocalDateTime(dateString: string): Date {
|
61
61
|
const dateObj = dayjs(dateString).toDate();
|
62
|
+
if (isNaN(dateObj.getTime())) {
|
63
|
+
return new Date(NaN);
|
64
|
+
}
|
65
|
+
|
62
66
|
try {
|
63
|
-
const
|
64
|
-
|
67
|
+
const timePart = dateString.split('T')[1];
|
68
|
+
if (timePart) {
|
69
|
+
const localTimeTokens = timePart.split(':');
|
70
|
+
dateObj.setHours(parseInt(localTimeTokens[0]), parseInt(localTimeTokens[1]), 0);
|
71
|
+
}
|
65
72
|
} catch (e) {
|
66
73
|
console.error(e);
|
67
74
|
}
|
@@ -2,16 +2,11 @@ import React from 'react';
|
|
2
2
|
import userEvent from '@testing-library/user-event';
|
3
3
|
import { act, render, screen } from '@testing-library/react';
|
4
4
|
import { type FetchResponse, openmrsFetch, usePatient, useSession } from '@openmrs/esm-framework';
|
5
|
+
import { mockSessionDataResponse, mockVisit } from '__mocks__';
|
5
6
|
import { mockPatientAge8 } from '__mocks__/patient.mock';
|
6
|
-
import {
|
7
|
-
import { mockVisit } from '__mocks__/visit.mock';
|
8
|
-
import bmiForAgeScoreTestSchema from '__mocks__/forms/rfe-forms/zscore-bmi-for-age-form.json';
|
9
|
-
import demoHtsForm from '__mocks__/forms/rfe-forms/demo_hts-form.json';
|
10
|
-
import demoHtsOpenmrsForm from '__mocks__/forms/afe-forms/demo_hts-form.json';
|
7
|
+
import { demoHtsForm, bmiForAgeScoreTestSchema, demoHtsOpenmrsForm } from '__mocks__/forms';
|
11
8
|
import FormEngine from '../form-engine.component';
|
12
9
|
|
13
|
-
global.ResizeObserver = require('resize-observer-polyfill');
|
14
|
-
|
15
10
|
const patientUUID = 'e13a8696-dc58-4b8c-ae40-2a1e7dd843e7';
|
16
11
|
const visit = mockVisit;
|
17
12
|
|
@@ -2,16 +2,11 @@ import React from 'react';
|
|
2
2
|
import userEvent from '@testing-library/user-event';
|
3
3
|
import { render, screen, act } from '@testing-library/react';
|
4
4
|
import { type FetchResponse, openmrsFetch, usePatient, useSession } from '@openmrs/esm-framework';
|
5
|
+
import { mockSessionDataResponse, mockVisit } from '__mocks__';
|
5
6
|
import { mockPatientAge8 } from '__mocks__/patient.mock';
|
6
|
-
import {
|
7
|
-
import { mockVisit } from '__mocks__/visit.mock';
|
8
|
-
import demoHtsOpenmrsForm from '__mocks__/forms/afe-forms/demo_hts-form.json';
|
9
|
-
import demoHtsForm from '__mocks__/forms/rfe-forms/demo_hts-form.json';
|
10
|
-
import heightForAgeZscoreTestSchema from '__mocks__/forms/rfe-forms/zscore-height-for-age-form.json';
|
7
|
+
import { demoHtsForm, demoHtsOpenmrsForm, heightForAgeZscoreTestSchema } from '__mocks__/forms';
|
11
8
|
import FormEngine from '../form-engine.component';
|
12
9
|
|
13
|
-
global.ResizeObserver = require('resize-observer-polyfill');
|
14
|
-
|
15
10
|
const patientUUID = 'e13a8696-dc58-4b8c-ae40-2a1e7dd843e7';
|
16
11
|
const visit = mockVisit;
|
17
12
|
|