@openmrs/esm-form-engine-lib 3.1.4-pre.1779 → 3.1.4-pre.1783

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.
Files changed (56) hide show
  1. package/__mocks__/forms/afe-forms/index.ts +9 -0
  2. package/__mocks__/forms/index.ts +19 -0
  3. package/__mocks__/forms/rfe-forms/index.ts +50 -0
  4. package/__mocks__/index.ts +85 -0
  5. package/__mocks__/single-spa-react.js +4 -9
  6. package/jest.config.js +1 -1
  7. package/package.json +1 -1
  8. package/src/components/inputs/date/date.component.tsx +7 -7
  9. package/src/components/inputs/date/date.test.tsx +2 -22
  10. package/src/components/inputs/markdown/markdown.component.tsx +8 -4
  11. package/src/components/inputs/multi-select/multi-select.component.tsx +11 -15
  12. package/src/components/inputs/multi-select/multi-select.test.tsx +3 -6
  13. package/src/components/inputs/number/number.component.tsx +6 -6
  14. package/src/components/inputs/number/number.test.tsx +6 -4
  15. package/src/components/inputs/radio/radio.component.tsx +2 -2
  16. package/src/components/inputs/radio/radio.test.tsx +3 -5
  17. package/src/components/inputs/select/dropdown.component.tsx +1 -0
  18. package/src/components/inputs/select/dropdown.test.tsx +1 -1
  19. package/src/components/inputs/text/text.component.tsx +9 -9
  20. package/src/components/inputs/text/text.test.tsx +5 -5
  21. package/src/components/inputs/text-area/text-area.component.tsx +2 -2
  22. package/src/components/inputs/toggle/toggle.component.tsx +3 -3
  23. package/src/components/inputs/ui-select-extended/ui-select-extended.test.tsx +11 -21
  24. package/src/components/inputs/unspecified/unspecified.test.tsx +6 -17
  25. package/src/components/label/label.component.tsx +1 -1
  26. package/src/components/renderer/field/fieldLogic.test.ts +4 -10
  27. package/src/components/renderer/field/form-field-renderer.component.tsx +9 -9
  28. package/src/components/sidebar/useCurrentActivePage.test.ts +0 -1
  29. package/src/form-engine.test.tsx +34 -46
  30. package/src/hooks/useFormJson.test.tsx +16 -13
  31. package/src/hooks/useFormWorkspaceSize.test.ts +40 -19
  32. package/src/hooks/useInitialValues.test.ts +3 -2
  33. package/src/hooks/usePostSubmissionActions.test.tsx +0 -2
  34. package/src/setup-tests.ts +35 -0
  35. package/src/transformers/default-schema-transformer.test.ts +1 -1
  36. package/src/utils/common-utils.test.ts +4 -9
  37. package/src/utils/common-utils.ts +9 -2
  38. package/src/utils/forms-loader.test.ts +1 -1
  39. package/src/zscore-tests/bmi-age.test.tsx +2 -7
  40. package/src/zscore-tests/height-age.test.tsx +2 -7
  41. package/src/zscore-tests/weight-height.test.tsx +2 -7
  42. package/src/setupTests.ts +0 -5
  43. /package/__mocks__/forms/afe-forms/{component_art.json → component-art.json} +0 -0
  44. /package/__mocks__/forms/afe-forms/{component_preclinic-review.json → component-preclinic-review.json} +0 -0
  45. /package/__mocks__/forms/afe-forms/{demo_hts-form.json → demo-hts-form.json} +0 -0
  46. /package/__mocks__/forms/rfe-forms/{component_art.json → component-art.json} +0 -0
  47. /package/__mocks__/forms/rfe-forms/{component_preclinic-review.json → component-preclinic-review.json} +0 -0
  48. /package/__mocks__/forms/rfe-forms/{demo_hts-form.json → demo-hts-form.json} +0 -0
  49. /package/__mocks__/forms/rfe-forms/{external_data_source_form.json → external-data-source-form.json} +0 -0
  50. /package/__mocks__/forms/rfe-forms/{labour_and_delivery_test_form.json → labour-and-delivery-test-form.json} +0 -0
  51. /package/__mocks__/forms/rfe-forms/{mockHistoricalvisitsEncounter.json → mock-historical-visits-encounter.json} +0 -0
  52. /package/__mocks__/forms/rfe-forms/{mockSaveEncounter.json → mock-save-encounter.json} +0 -0
  53. /package/__mocks__/forms/rfe-forms/{obs-group-test_form.json → obs-group-test-form.json} +0 -0
  54. /package/__mocks__/forms/rfe-forms/{sample_fields.json → sample-fields.json} +0 -0
  55. /package/__mocks__/forms/rfe-forms/{sample_ui-select-ext.json → sample-ui-select-ext.json} +0 -0
  56. /package/__mocks__/forms/rfe-forms/{sample_unspecified-form.json → sample-unspecified-form.json} +0 -0
@@ -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 '../../../../__mocks__/forms/rfe-forms/sample_unspecified-form.json';
7
- import { FormEngine } from '../../..';
8
- import { mockPatient } from '../../../../__mocks__/patient.mock';
9
- import { mockSessionDataResponse } from '../../../../__mocks__/session.mock';
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 { evaluateAsyncExpression, evaluateExpression } from '../../../utils/expression-runner';
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 { Controller, useWatch } from 'react-hook-form';
11
- import { ToastNotification } from '@carbon/react';
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 { handleFieldLogic, validateFieldValue } from './fieldLogic';
22
+ import styles from './form-field-renderer.scss';
23
23
 
24
24
  export interface FormFieldRendererProps {
25
25
  fieldId: string;
@@ -22,7 +22,6 @@ describe('useCurrentActivePage', () => {
22
22
  ] as Array<FormPage>;
23
23
 
24
24
  beforeEach(() => {
25
- jest.clearAllMocks();
26
25
  jest.useFakeTimers();
27
26
  });
28
27
 
@@ -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__/patient.mock';
18
- import { mockSessionDataResponse } from '__mocks__/session.mock';
19
- import { mockVisit } from '__mocks__/visit.mock';
20
- import demoHtsForm from '__mocks__/forms/rfe-forms/demo_hts-form.json';
21
- import demoHtsOpenmrsForm from '__mocks__/forms/afe-forms/demo_hts-form.json';
22
- import filterAnswerOptionsTestForm from '__mocks__/forms/rfe-forms/filter-answer-options-test-form.json';
23
- import htsPocForm from '__mocks__/packages/hiv/forms/hts_poc/1.1.json';
24
- import labourAndDeliveryTestForm from '__mocks__/forms/rfe-forms/labour_and_delivery_test_form.json';
25
- import mockConceptsForm from '__mocks__/concepts.mock.json';
26
- import obsGroupTestForm from '__mocks__/forms/rfe-forms/obs-group-test_form.json';
27
- import postSubmissionTestForm from '__mocks__/forms/rfe-forms/post-submission-test-form.json';
28
- import referenceByMappingForm from '__mocks__/forms/rfe-forms/reference-by-mapping-form.json';
29
- import sampleFieldsForm from '__mocks__/forms/rfe-forms/sample_fields.json';
30
- import testEnrolmentForm from '__mocks__/forms/rfe-forms/test-enrolment-form.json';
31
- import historicalExpressionsForm from '__mocks__/forms/rfe-forms/historical-expressions-form.json';
32
- import mockHxpEncounter from '__mocks__/forms/rfe-forms/mockHistoricalvisitsEncounter.json';
33
- import mockSaveEncounter from '__mocks__/forms/rfe-forms/mockSaveEncounter.json';
34
- import requiredTestForm from '__mocks__/forms/rfe-forms/required-form.json';
35
- import conditionalRequiredTestForm from '__mocks__/forms/rfe-forms/conditional-required-form.json';
36
- import conditionalAnsweredForm from '__mocks__/forms/rfe-forms/conditional-answered-form.json';
37
- import ageValidationForm from '__mocks__/forms/rfe-forms/age-validation-form.json';
38
- import bmiForm from '__mocks__/forms/rfe-forms/bmi-test-form.json';
39
- import bsaForm from '__mocks__/forms/rfe-forms/bsa-test-form.json';
40
- import eddForm from '__mocks__/forms/rfe-forms/edd-test-form.json';
41
- import externalDataSourceForm from '__mocks__/forms/rfe-forms/external_data_source_form.json';
42
- import monthsOnArtForm from '__mocks__/forms/rfe-forms/months-on-art-form.json';
43
- import nextVisitForm from '__mocks__/forms/rfe-forms/next-visit-test-form.json';
44
- import viralLoadStatusForm from '__mocks__/forms/rfe-forms/viral-load-status-form.json';
45
- import readOnlyValidationForm from '__mocks__/forms/rfe-forms/read-only-validation-form.json';
46
- import jsExpressionValidationForm from '__mocks__/forms/rfe-forms/js-expression-validation-form.json';
47
- import hidePagesAndSectionsForm from '__mocks__/forms/rfe-forms/hide-pages-and-sections-form.json';
48
- import diagnosisForm from '__mocks__/forms/rfe-forms/diagnosis-test-form.json';
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: mockConceptsForm.results,
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 artComponentBody from '__mocks__/forms/rfe-forms/component_art.json';
6
- import artComponentSkeleton from '__mocks__/forms/afe-forms/component_art.json';
7
- import formComponentBody from '__mocks__/forms/rfe-forms/form-component.json';
8
- import formComponentSkeleton from '__mocks__/forms/afe-forms/form-component.json';
9
- import miniFormBody from '__mocks__/forms/rfe-forms/mini-form.json';
10
- import miniFormSkeleton from '__mocks__/forms/afe-forms/mini-form.json';
11
- import nestedForm1Body from '__mocks__/forms/rfe-forms/nested-form1.json';
12
- import nestedForm1Skeleton from '__mocks__/forms/afe-forms/nested-form1.json';
13
- import nestedForm2Body from '__mocks__/forms/rfe-forms/nested-form2.json';
14
- import nestedForm2Skeleton from '__mocks__/forms/afe-forms/nested-form2.json';
15
- import preclinicReviewComponentBody from '__mocks__/forms/rfe-forms/component_preclinic-review.json';
16
- import preclinicReviewComponentSkeleton from '__mocks__/forms/afe-forms/component_preclinic-review.json';
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
- // setup and execute
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
- jest.clearAllMocks();
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([{ target: parentElement }]);
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/afe-forms/test-schema-transformer-form.json';
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 { type FormField, type OpenmrsObs } from '../types';
11
- import { obsList } from '__mocks__/forms/rfe-forms/obs-list-data';
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 localTimeTokens = dateString.split('T')[1].split(':');
64
- dateObj.setHours(parseInt(localTimeTokens[0]), parseInt(localTimeTokens[1]), 0);
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
  }
@@ -5,7 +5,7 @@ import {
5
5
  htsRetrospectiveResultingSchemaV2,
6
6
  htsWildcardResultingSchemaV2,
7
7
  testSchemaV2,
8
- } from '__mocks__/forms/rfe-forms/forms-loader.test.schema';
8
+ } from '__mocks__/forms';
9
9
 
10
10
  const htsTestForms: FormJsonFile[] = [
11
11
  {
@@ -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 { mockSessionDataResponse } from '__mocks__/session.mock';
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 { mockSessionDataResponse } from '__mocks__/session.mock';
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
 
@@ -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 { mockVisit } from '__mocks__/visit.mock';
5
+ import { mockSessionDataResponse, mockVisit } from '__mocks__';
6
6
  import { mockPatientAge4 } from '__mocks__/patient.mock';
7
- import { mockSessionDataResponse } from '__mocks__/session.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 weightForHeightZscoreTestSchema from '__mocks__/forms/rfe-forms/zscore-weight-height-form.json';
7
+ import { demoHtsForm, demoHtsOpenmrsForm, weightForHeightZscoreTestSchema } 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 = '8673ee4f-e2ab-4077-ba55-4980f408773e';
16
11
  const visit = mockVisit;
17
12
 
package/src/setupTests.ts DELETED
@@ -1,5 +0,0 @@
1
- import '@testing-library/jest-dom';
2
- import 'jest-when';
3
-
4
- // https://github.com/jsdom/jsdom/issues/1695
5
- window.HTMLElement.prototype.scrollIntoView = function () {};