@openmrs/esm-form-engine-lib 2.1.0-pre.1502 → 2.1.0-pre.1510

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-form-engine-lib",
3
- "version": "2.1.0-pre.1502",
3
+ "version": "2.1.0-pre.1510",
4
4
  "description": "React Form Engine for O3",
5
5
  "browser": "dist/openmrs-esm-form-engine-lib.js",
6
6
  "main": "src/index.ts",
@@ -0,0 +1,107 @@
1
+ import React from 'react';
2
+ import { act, render, screen } from '@testing-library/react';
3
+ import { useFormProviderContext } from 'src/provider/form-provider';
4
+ import DateField from './date.component';
5
+ import { type FormField } from 'src/types';
6
+ import { OpenmrsDatePicker } from '@openmrs/esm-framework';
7
+ import dayjs from 'dayjs';
8
+
9
+ jest.mock('src/provider/form-provider', () => ({
10
+ useFormProviderContext: jest.fn(),
11
+ }));
12
+
13
+ const mockUseFormProviderContext = useFormProviderContext as jest.Mock;
14
+ const mockSetFieldValue = jest.fn();
15
+
16
+ const mockOpenmrsDatePicker = jest.mocked(OpenmrsDatePicker);
17
+
18
+ mockOpenmrsDatePicker.mockImplementation(({ id, labelText, value, onChange, isInvalid, invalidText }) => {
19
+ return (
20
+ <>
21
+ <label htmlFor={id}>{labelText}</label>
22
+ <input
23
+ id={id}
24
+ value={value ? dayjs(value as unknown as string).format('DD/MM/YYYY') : ''}
25
+ onChange={(evt) => {
26
+ onChange(dayjs(evt.target.value).toDate());
27
+ }}
28
+ />
29
+ {isInvalid && <span>{invalidText}</span>}
30
+ </>
31
+ );
32
+ });
33
+
34
+ const dateFieldMock: FormField = {
35
+ id: 'test-date-field',
36
+ label: 'Test Date Field',
37
+ type: 'obs',
38
+ datePickerFormat: 'both',
39
+ questionOptions: {
40
+ rendering: 'date',
41
+ concept: '6089AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
42
+ },
43
+ isHidden: false,
44
+ isDisabled: false,
45
+ readonly: false,
46
+ };
47
+
48
+ const renderDateField = async (props) => {
49
+ await act(() => render(<DateField {...props} />));
50
+ };
51
+
52
+ describe('DateField Component', () => {
53
+ beforeEach(() => {
54
+ mockUseFormProviderContext.mockReturnValue({
55
+ layoutType: 'default',
56
+ sessionMode: 'edit',
57
+ workspaceLayout: 'default',
58
+ formFieldAdapters: {},
59
+ });
60
+ });
61
+
62
+ it('should render date picker and time picker when datePickerFormat is "both"', async () => {
63
+ await renderDateField({
64
+ field: dateFieldMock,
65
+ value: new Date(),
66
+ errors: [],
67
+ warnings: [],
68
+ setFieldValue: mockSetFieldValue,
69
+ });
70
+
71
+ expect(screen.getByLabelText('Test Date Field')).toBeInTheDocument();
72
+ expect(screen.getByText('Time')).toBeInTheDocument();
73
+ });
74
+
75
+ it('should display error message when there are errors', async () => {
76
+ await renderDateField({
77
+ field: dateFieldMock,
78
+ value: new Date(),
79
+ errors: [{ resultType: 'error', message: 'Error message' }],
80
+ warnings: [],
81
+ setFieldValue: mockSetFieldValue,
82
+ });
83
+
84
+ const errorMessages = screen.getAllByText(/Error message/i);
85
+ expect(errorMessages.length).toBeGreaterThan(0);
86
+ errorMessages.forEach((message) => {
87
+ expect(message).toBeInTheDocument();
88
+ });
89
+ });
90
+
91
+ it('should display warning message when there are warnings', async () => {
92
+ const warnings = [{ resultType: 'warning', message: 'Warning message' }];
93
+ await renderDateField({
94
+ field: dateFieldMock,
95
+ value: new Date(),
96
+ errors: [],
97
+ warnings: warnings,
98
+ setFieldValue: mockSetFieldValue,
99
+ });
100
+
101
+ const warningMessages = screen.getAllByText(/Warning message/i);
102
+ expect(warningMessages.length).toBeGreaterThan(0);
103
+ warningMessages.forEach((message) => {
104
+ expect(message).toBeInTheDocument();
105
+ });
106
+ });
107
+ });
@@ -256,17 +256,11 @@ export class EncounterFormProcessor extends FormProcessor {
256
256
  const filteredFields = formFields.filter(
257
257
  (field) => field.questionOptions.rendering !== 'group' && field.type !== 'obsGroup',
258
258
  );
259
+ const fieldsWithCalculateExpressions = [];
259
260
  await Promise.all(
260
261
  filteredFields.map(async (field) => {
261
262
  const adapter = formFieldAdapters[field.type];
262
263
  initialValues[field.id] = emptyValues[field.questionOptions.rendering] ?? null;
263
- if (field.questionOptions.calculate?.calculateExpression) {
264
- try {
265
- await evaluateCalculateExpression(field, initialValues, context);
266
- } catch (error) {
267
- console.error(error);
268
- }
269
- }
270
264
  if (isEmpty(initialValues[field.id]) && contextInitializableTypes.includes(field.type)) {
271
265
  try {
272
266
  initialValues[field.id] = await adapter.getInitialValue(field, null, context);
@@ -274,8 +268,18 @@ export class EncounterFormProcessor extends FormProcessor {
274
268
  console.error(error);
275
269
  }
276
270
  }
271
+ if (field.questionOptions.calculate?.calculateExpression) {
272
+ fieldsWithCalculateExpressions.push(field);
273
+ }
277
274
  }),
278
275
  );
276
+ fieldsWithCalculateExpressions.forEach(async (field) => {
277
+ try {
278
+ await evaluateCalculateExpression(field, initialValues, context);
279
+ } catch (error) {
280
+ console.error(error);
281
+ }
282
+ });
279
283
  }
280
284
  return initialValues;
281
285
  }
@@ -215,8 +215,6 @@ export type RenderType =
215
215
  | 'toggle'
216
216
  | 'ui-select-extended'
217
217
  | 'workspace-launcher'
218
- | 'fixed-value'
219
- | 'file'
220
218
  | 'markdown'
221
219
  | 'extension-widget'
222
220
  | 'select-concept-answers';