@olaboot/esm-patient-registration-app 9.2.1 → 10.0.2
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/dist/1339.js +1 -0
- package/dist/1339.js.map +1 -0
- package/dist/1480.js +1 -0
- package/dist/1480.js.map +1 -0
- package/dist/1646.js +1 -0
- package/dist/1646.js.map +1 -0
- package/dist/1789.js +1 -0
- package/dist/1789.js.map +1 -0
- package/dist/1869.js +1 -0
- package/dist/1869.js.map +1 -0
- package/dist/1877.js +1 -0
- package/dist/1877.js.map +1 -0
- package/dist/2317.js +1 -0
- package/dist/2317.js.map +1 -0
- package/dist/2416.js +1 -0
- package/dist/2416.js.map +1 -0
- package/dist/2747.js +1 -0
- package/dist/2747.js.map +1 -0
- package/dist/282.js +1 -0
- package/dist/282.js.map +1 -0
- package/dist/2881.js +1 -0
- package/dist/2881.js.map +1 -0
- package/dist/3378.js +1 -0
- package/dist/3378.js.map +1 -0
- package/dist/3720.js +1 -0
- package/dist/3720.js.map +1 -0
- package/dist/3906.js +1 -0
- package/dist/3906.js.map +1 -0
- package/dist/3963.js +1 -0
- package/dist/3963.js.map +1 -0
- package/dist/3989.js +1 -0
- package/dist/3989.js.map +1 -0
- package/dist/4106.js +1 -0
- package/dist/4106.js.map +1 -0
- package/dist/4111.js +1 -0
- package/dist/4111.js.map +1 -0
- package/dist/434.js +1 -0
- package/dist/434.js.map +1 -0
- package/dist/4348.js +1 -0
- package/dist/4348.js.map +1 -0
- package/dist/4383.js +1 -0
- package/dist/4383.js.map +1 -0
- package/dist/4658.js +1 -0
- package/dist/4658.js.map +1 -0
- package/dist/466.js +1 -0
- package/dist/466.js.map +1 -0
- package/dist/4928.js +1 -0
- package/dist/4928.js.map +1 -0
- package/dist/5117.js +1 -0
- package/dist/5117.js.map +1 -0
- package/dist/5132.js +1 -0
- package/dist/5132.js.map +1 -0
- package/dist/5145.js +1 -0
- package/dist/5145.js.map +1 -0
- package/dist/5208.js +43 -0
- package/dist/5208.js.map +1 -0
- package/dist/527.js +1 -0
- package/dist/527.js.map +1 -0
- package/dist/5280.js +1 -0
- package/dist/5280.js.map +1 -0
- package/dist/5338.js +6 -0
- package/dist/5338.js.map +1 -0
- package/dist/5503.js +1 -0
- package/dist/5503.js.map +1 -0
- package/dist/555.js +1 -0
- package/dist/555.js.map +1 -0
- package/dist/556.js +1 -0
- package/dist/556.js.map +1 -0
- package/dist/5644.js +1 -0
- package/dist/5644.js.map +1 -0
- package/dist/5697.js +1 -0
- package/dist/{4024.js.map → 5697.js.map} +1 -1
- package/dist/5940.js +1 -0
- package/dist/5940.js.map +1 -0
- package/dist/6047.js +1 -0
- package/dist/6047.js.map +1 -0
- package/dist/6371.js +1 -0
- package/dist/6371.js.map +1 -0
- package/dist/6377.js +1 -0
- package/dist/6377.js.map +1 -0
- package/dist/6388.js +1 -0
- package/dist/6388.js.map +1 -0
- package/dist/6444.js +1 -0
- package/dist/6444.js.map +1 -0
- package/dist/6508.js +1 -0
- package/dist/6508.js.map +1 -0
- package/dist/6724.js +1 -0
- package/dist/6724.js.map +1 -0
- package/dist/689.js +1 -0
- package/dist/689.js.map +1 -0
- package/dist/6904.js +1 -0
- package/dist/6904.js.map +1 -0
- package/dist/7045.js +1 -0
- package/dist/7045.js.map +1 -0
- package/dist/7175.js +1 -0
- package/dist/7175.js.map +1 -0
- package/dist/7182.js +1 -0
- package/dist/7182.js.map +1 -0
- package/dist/7649.js +1 -0
- package/dist/7649.js.map +1 -0
- package/dist/7742.js +1 -0
- package/dist/7742.js.map +1 -0
- package/dist/7912.js +1 -0
- package/dist/7912.js.map +1 -0
- package/dist/8358.js +1 -0
- package/dist/8358.js.map +1 -0
- package/dist/8359.js +1 -0
- package/dist/8359.js.map +1 -0
- package/dist/8695.js +1 -0
- package/dist/8695.js.map +1 -0
- package/dist/903.js +1 -0
- package/dist/903.js.map +1 -0
- package/dist/9061.js +1 -0
- package/dist/9061.js.map +1 -0
- package/dist/9072.js +1 -0
- package/dist/9072.js.map +1 -0
- package/dist/9397.js +1 -0
- package/dist/9397.js.map +1 -0
- package/dist/9712.js +1 -0
- package/dist/9712.js.map +1 -0
- package/dist/9771.js +1 -0
- package/dist/9771.js.map +1 -0
- package/dist/9806.js +1 -0
- package/dist/9806.js.map +1 -0
- package/dist/9816.js +1 -0
- package/dist/9816.js.map +1 -0
- package/dist/main.js +7 -6
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-patient-registration-app.js +6 -0
- package/dist/{olaboot-esm-patient-registration-app.js.buildmanifest.json → openmrs-esm-patient-registration-app.js.buildmanifest.json} +540 -455
- package/dist/openmrs-esm-patient-registration-app.js.map +1 -0
- package/dist/routes.json +1 -1
- package/package.json +8 -9
- package/src/add-patient-link.extension.tsx +3 -2
- package/src/add-patient-link.test.tsx +2 -1
- package/src/config-schema.ts +507 -507
- package/src/constants.ts +1 -1
- package/src/index.ts +2 -24
- package/src/nav-link.test.tsx +1 -0
- package/src/offline.resources.ts +97 -31
- package/src/patient-registration/before-save-prompt.test.tsx +199 -0
- package/src/patient-registration/field/__mocks__/field.resource.ts +8 -7
- package/src/patient-registration/field/address/address-field.component.tsx +183 -186
- package/src/patient-registration/field/address/address-hierarchy-levels.component.tsx +6 -1
- package/src/patient-registration/field/address/address-hierarchy.test.tsx +289 -296
- package/src/patient-registration/field/address/address-search.component.tsx +20 -8
- package/src/patient-registration/field/address/address-search.scss +19 -2
- package/src/patient-registration/field/address/address-search.test.tsx +333 -141
- package/src/patient-registration/field/address/custom-address-field.component.tsx +1 -1
- package/src/patient-registration/field/cause-of-death/cause-of-death.component.tsx +1 -1
- package/src/patient-registration/field/cause-of-death/cause-of-death.test.tsx +251 -0
- package/src/patient-registration/field/custom-field.component.tsx +1 -1
- package/src/patient-registration/field/date-and-time-of-death/date-and-time-of-death.component.tsx +1 -1
- package/src/patient-registration/field/date-and-time-of-death/date-and-time-of-death.test.tsx +144 -0
- package/src/patient-registration/field/dob/dob.component.tsx +2 -2
- package/src/patient-registration/field/dob/dob.test.tsx +370 -54
- package/src/patient-registration/field/field.component.tsx +1 -1
- package/src/patient-registration/field/field.resource.ts +2 -2
- package/src/patient-registration/field/field.test.tsx +333 -330
- package/src/patient-registration/field/gender/gender-field.test.tsx +240 -54
- package/src/patient-registration/field/id/id-field.component.tsx +146 -144
- package/src/patient-registration/field/id/id-field.test.tsx +177 -121
- package/src/patient-registration/field/id/identifier-selection-overlay.component.tsx +200 -200
- package/src/patient-registration/field/id/identifier-selection-overlay.test.tsx +346 -0
- package/src/patient-registration/field/name/name-field.component.tsx +2 -2
- package/src/patient-registration/field/name/name-field.test.tsx +282 -0
- package/src/patient-registration/field/obs/obs-field.test.tsx +294 -118
- package/src/patient-registration/field/person-attributes/coded-person-attribute-field.test.tsx +172 -108
- package/src/patient-registration/field/person-attributes/location-person-attribute-field.component.tsx +3 -3
- package/src/patient-registration/field/person-attributes/location-person-attribute-field.resource.tsx +2 -5
- package/src/patient-registration/field/person-attributes/person-attribute-field.component.tsx +2 -2
- package/src/patient-registration/field/person-attributes/person-attribute-field.test.tsx +249 -131
- package/src/patient-registration/field/person-attributes/person-attributes.resource.ts +1 -1
- package/src/patient-registration/field/person-attributes/text-person-attribute-field.test.tsx +98 -70
- package/src/patient-registration/field/phone/phone-field.test.tsx +100 -0
- package/src/patient-registration/form-manager.test.ts +6 -5
- package/src/patient-registration/form-manager.ts +5 -2
- package/src/patient-registration/input/basic-input/input/input.component.tsx +3 -121
- package/src/patient-registration/input/basic-input/input/input.test.tsx +151 -51
- package/src/patient-registration/input/basic-input/select/select-input.test.tsx +113 -33
- package/src/patient-registration/input/combo-input/combo-input.component.tsx +60 -24
- package/src/patient-registration/input/custom-input/autosuggest/autosuggest.component.tsx +10 -101
- package/src/patient-registration/input/custom-input/autosuggest/autosuggest.test.tsx +144 -108
- package/src/patient-registration/input/custom-input/identifier/identifier-input.test.tsx +241 -177
- package/src/patient-registration/input/custom-input/identifier/utils.test.ts +47 -8
- package/src/patient-registration/input/dummy-data/dummy-data-input.component.tsx +12 -12
- package/src/patient-registration/input/dummy-data/dummy-data-input.test.tsx +52 -20
- package/src/patient-registration/input/input.scss +1 -2
- package/src/patient-registration/patient-registration-context.ts +5 -3
- package/src/patient-registration/patient-registration-hooks.ts +4 -12
- package/src/patient-registration/patient-registration-utils.test.ts +2 -1
- package/src/patient-registration/patient-registration-utils.ts +2 -98
- package/src/patient-registration/patient-registration.component.tsx +50 -46
- package/src/patient-registration/patient-registration.resource.test.tsx +4 -7
- package/src/patient-registration/patient-registration.resource.ts +1 -4
- package/src/patient-registration/patient-registration.scss +16 -3
- package/src/patient-registration/patient-registration.test.tsx +614 -580
- package/src/patient-registration/patient-registration.types.ts +17 -28
- package/src/patient-registration/section/death-info/death-info-section.test.tsx +130 -34
- package/src/patient-registration/section/demographics/demographics-section.test.tsx +122 -68
- package/src/patient-registration/section/patient-relationships/relationships-section.component.tsx +15 -15
- package/src/patient-registration/section/patient-relationships/relationships-section.test.tsx +278 -84
- package/src/patient-registration/section/section-wrapper.component.tsx +1 -1
- package/src/patient-registration/ui-components/overlay/overlay.test.tsx +104 -0
- package/src/patient-registration/validation/patient-registration-validation.test.ts +2 -1
- package/src/patient-registration/validation/patient-registration-validation.ts +9 -3
- package/src/root.component.tsx +2 -5
- package/src/widgets/cancel-patient-edit.test.tsx +48 -11
- package/src/widgets/delete-identifier-confirmation.test.tsx +77 -24
- package/src/widgets/edit-patient-details-button.component.tsx +14 -18
- package/src/widgets/edit-patient-details-button.scss +2 -2
- package/src/widgets/edit-patient-details-button.test.tsx +11 -13
- package/translations/am.json +9 -4
- package/translations/ar.json +9 -4
- package/translations/ar_SY.json +9 -4
- package/translations/bn.json +9 -4
- package/translations/cs.json +9 -4
- package/translations/de.json +120 -115
- package/translations/en.json +10 -4
- package/translations/en_US.json +9 -4
- package/translations/es.json +9 -4
- package/translations/es_MX.json +9 -4
- package/translations/fr.json +9 -4
- package/translations/he.json +9 -4
- package/translations/hi.json +9 -4
- package/translations/hi_IN.json +9 -4
- package/translations/id.json +9 -4
- package/translations/it.json +9 -4
- package/translations/ka.json +9 -4
- package/translations/km.json +9 -4
- package/translations/ku.json +9 -4
- package/translations/ky.json +9 -4
- package/translations/lg.json +9 -4
- package/translations/ne.json +9 -4
- package/translations/pl.json +9 -4
- package/translations/pt.json +9 -4
- package/translations/pt_BR.json +10 -5
- package/translations/qu.json +9 -4
- package/translations/ro_RO.json +9 -4
- package/translations/ru_RU.json +9 -4
- package/translations/si.json +9 -4
- package/translations/sq.json +9 -4
- package/translations/sw.json +9 -4
- package/translations/sw_KE.json +9 -4
- package/translations/tr.json +9 -4
- package/translations/tr_TR.json +9 -4
- package/translations/uk.json +9 -4
- package/translations/uz.json +9 -4
- package/translations/uz@Latn.json +9 -4
- package/translations/uz_UZ.json +9 -4
- package/translations/vi.json +9 -4
- package/translations/zh.json +50 -45
- package/translations/zh_CN.json +9 -4
- package/translations/zh_TW.json +9 -4
- package/vitest.config.ts +4 -0
- package/dist/126.js +0 -1
- package/dist/15.js +0 -1
- package/dist/1564.js +0 -1
- package/dist/1567.js +0 -1
- package/dist/1845.js +0 -1
- package/dist/1953.js +0 -1
- package/dist/200.js +0 -1
- package/dist/200.js.map +0 -1
- package/dist/215.js +0 -1
- package/dist/2178.js +0 -1
- package/dist/250.js +0 -1
- package/dist/250.js.map +0 -1
- package/dist/2523.js +0 -1
- package/dist/2523.js.map +0 -1
- package/dist/2566.js +0 -1
- package/dist/2586.js +0 -1
- package/dist/2586.js.map +0 -1
- package/dist/2716.js +0 -1
- package/dist/2716.js.map +0 -1
- package/dist/2759.js +0 -1
- package/dist/2821.js +0 -6
- package/dist/2821.js.map +0 -1
- package/dist/3089.js +0 -1
- package/dist/3089.js.map +0 -1
- package/dist/3230.js +0 -1
- package/dist/3441.js +0 -1
- package/dist/3565.js +0 -1
- package/dist/3571.js +0 -1
- package/dist/3571.js.map +0 -1
- package/dist/3746.js +0 -1
- package/dist/3925.js +0 -1
- package/dist/3946.js +0 -1
- package/dist/4024.js +0 -1
- package/dist/4744.js +0 -1
- package/dist/4744.js.map +0 -1
- package/dist/4809.js +0 -1
- package/dist/4894.js +0 -1
- package/dist/4970.js +0 -1
- package/dist/4970.js.map +0 -1
- package/dist/5130.js +0 -1
- package/dist/5187.js +0 -1
- package/dist/5491.js +0 -1
- package/dist/5491.js.map +0 -1
- package/dist/5595.js +0 -1
- package/dist/5961.js +0 -1
- package/dist/6133.js +0 -1
- package/dist/634.js +0 -1
- package/dist/634.js.map +0 -1
- package/dist/6456.js +0 -1
- package/dist/6466.js +0 -1
- package/dist/6613.js +0 -1
- package/dist/6783.js +0 -1
- package/dist/7073.js +0 -38
- package/dist/7073.js.map +0 -1
- package/dist/7154.js +0 -1
- package/dist/7154.js.map +0 -1
- package/dist/7348.js +0 -1
- package/dist/7439.js +0 -1
- package/dist/7439.js.map +0 -1
- package/dist/7543.js +0 -1
- package/dist/7607.js +0 -1
- package/dist/772.js +0 -1
- package/dist/7984.js +0 -1
- package/dist/7984.js.map +0 -1
- package/dist/8538.js +0 -1
- package/dist/8538.js.map +0 -1
- package/dist/8599.js +0 -1
- package/dist/8727.js +0 -1
- package/dist/8847.js +0 -1
- package/dist/9015.js +0 -1
- package/dist/906.js +0 -1
- package/dist/9065.js +0 -1
- package/dist/9182.js +0 -1
- package/dist/9339.js +0 -1
- package/dist/9453.js +0 -1
- package/dist/9833.js +0 -1
- package/dist/9833.js.map +0 -1
- package/dist/9856.js +0 -1
- package/dist/9856.js.map +0 -1
- package/dist/9920.js +0 -1
- package/dist/9938.js +0 -1
- package/dist/9943.js +0 -1
- package/dist/9943.js.map +0 -1
- package/dist/olaboot-esm-patient-registration-app.js +0 -5
- package/dist/olaboot-esm-patient-registration-app.js.map +0 -1
- package/jest.config.js +0 -3
- package/src/resource.ts +0 -12
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/* eslint-disable testing-library/no-node-access */
|
|
2
1
|
import React from 'react';
|
|
2
|
+
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
|
3
3
|
import userEvent from '@testing-library/user-event';
|
|
4
|
-
import { screen } from '@testing-library/react';
|
|
4
|
+
import { screen, waitFor } from '@testing-library/react';
|
|
5
5
|
import { Form, Formik } from 'formik';
|
|
6
6
|
import { getDefaultsFromConfigSchema, useConfig } from '@openmrs/esm-framework';
|
|
7
7
|
import { esmPatientRegistrationSchema, type RegistrationConfig } from '../../../../config-schema';
|
|
@@ -69,7 +69,7 @@ const mockResourcesContextValue: Resources = {
|
|
|
69
69
|
sessionId: 'JSESSION',
|
|
70
70
|
currentProvider: { uuid: 'provider-uuid', identifier: 'PRO-123' },
|
|
71
71
|
},
|
|
72
|
-
relationshipTypes: [],
|
|
72
|
+
relationshipTypes: { results: [] },
|
|
73
73
|
identifierTypes: [...mockIdentifierTypes],
|
|
74
74
|
};
|
|
75
75
|
|
|
@@ -96,19 +96,42 @@ const mockContextValues: PatientRegistrationContextProps = {
|
|
|
96
96
|
identifierTypes: [],
|
|
97
97
|
initialFormValues: mockInitialFormValues,
|
|
98
98
|
isOffline: false,
|
|
99
|
-
setCapturePhotoProps:
|
|
100
|
-
setFieldValue:
|
|
101
|
-
setInitialFormValues:
|
|
102
|
-
setFieldTouched:
|
|
99
|
+
setCapturePhotoProps: vi.fn(),
|
|
100
|
+
setFieldValue: vi.fn(),
|
|
101
|
+
setInitialFormValues: vi.fn(),
|
|
102
|
+
setFieldTouched: vi.fn(),
|
|
103
103
|
validationSchema: null,
|
|
104
104
|
values: mockInitialFormValues,
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
-
const mockUseConfig =
|
|
107
|
+
const mockUseConfig = vi.mocked(useConfig<RegistrationConfig>);
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Helper to render IdentifierInput component with Formik.
|
|
111
|
+
*/
|
|
112
|
+
function renderIdentifierInput(
|
|
113
|
+
patientIdentifier: PatientIdentifierValue,
|
|
114
|
+
fieldName: string = 'openMrsId',
|
|
115
|
+
initialValues: Record<string, any> = {},
|
|
116
|
+
) {
|
|
117
|
+
return renderWithContext(
|
|
118
|
+
<Formik initialValues={initialValues} onSubmit={vi.fn()}>
|
|
119
|
+
<Form>
|
|
120
|
+
<PatientRegistrationContextProvider value={mockContextValues}>
|
|
121
|
+
<IdentifierInput patientIdentifier={patientIdentifier} fieldName={fieldName} />
|
|
122
|
+
</PatientRegistrationContextProvider>
|
|
123
|
+
</Form>
|
|
124
|
+
</Formik>,
|
|
125
|
+
ResourcesContextProvider,
|
|
126
|
+
mockResourcesContextValue,
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
describe('IdentifierInput component', () => {
|
|
131
|
+
beforeEach(() => {
|
|
132
|
+
mockUseConfig.mockReturnValue({
|
|
133
|
+
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
134
|
+
});
|
|
112
135
|
});
|
|
113
136
|
|
|
114
137
|
const fieldName = 'openMrsId';
|
|
@@ -129,207 +152,248 @@ describe('identifier input', () => {
|
|
|
129
152
|
required: true,
|
|
130
153
|
} as PatientIdentifierValue;
|
|
131
154
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
<IdentifierInput patientIdentifier={patientIdentifier} fieldName={fieldName} />
|
|
138
|
-
</PatientRegistrationContextProvider>
|
|
139
|
-
</Form>
|
|
140
|
-
</Formik>,
|
|
141
|
-
ResourcesContextProvider,
|
|
142
|
-
mockResourcesContextValue,
|
|
143
|
-
);
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
it('shows the identifier input', () => {
|
|
147
|
-
openmrsID.autoGeneration = false;
|
|
148
|
-
setupIdentifierInput(openmrsID as PatientIdentifierValue);
|
|
149
|
-
expect(screen.getByLabelText(openmrsID.identifierName)).toBeInTheDocument();
|
|
150
|
-
});
|
|
155
|
+
describe('Rendering', () => {
|
|
156
|
+
it('shows the identifier input', () => {
|
|
157
|
+
renderIdentifierInput({ ...openmrsID, autoGeneration: false });
|
|
158
|
+
expect(screen.getByLabelText(openmrsID.identifierName)).toBeInTheDocument();
|
|
159
|
+
});
|
|
151
160
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
161
|
+
it('displays an edit button when there is an initial value and field is not required', () => {
|
|
162
|
+
renderIdentifierInput({
|
|
163
|
+
...openmrsID,
|
|
164
|
+
autoGeneration: false,
|
|
165
|
+
required: false,
|
|
166
|
+
initialValue: '1002UU9',
|
|
167
|
+
identifierValue: '1002UU9',
|
|
168
|
+
});
|
|
169
|
+
expect(screen.getByText('Edit')).toBeInTheDocument();
|
|
170
|
+
});
|
|
162
171
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
172
|
+
it('hides the edit button when the identifier is required', () => {
|
|
173
|
+
renderIdentifierInput({
|
|
174
|
+
...openmrsID,
|
|
175
|
+
autoGeneration: false,
|
|
176
|
+
required: true,
|
|
177
|
+
initialValue: '1002UU9',
|
|
178
|
+
identifierValue: '1002UU9',
|
|
179
|
+
});
|
|
180
|
+
expect(screen.queryByText('Edit')).not.toBeInTheDocument();
|
|
181
|
+
});
|
|
173
182
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
183
|
+
it('displays a delete button when the identifier is not a default type', () => {
|
|
184
|
+
renderIdentifierInput({
|
|
185
|
+
...openmrsID,
|
|
186
|
+
required: false,
|
|
187
|
+
});
|
|
188
|
+
expect(screen.getByText('Delete')).toBeInTheDocument();
|
|
189
|
+
});
|
|
180
190
|
});
|
|
181
191
|
|
|
182
|
-
describe('
|
|
192
|
+
describe('Auto-generated identifier', () => {
|
|
183
193
|
it('hides the input when the identifier is auto-generated', () => {
|
|
184
|
-
|
|
185
|
-
|
|
194
|
+
renderIdentifierInput({
|
|
195
|
+
...openmrsID,
|
|
196
|
+
autoGeneration: true,
|
|
197
|
+
});
|
|
186
198
|
expect(screen.getByTestId('identifier-input')).toHaveAttribute('type', 'hidden');
|
|
187
199
|
});
|
|
188
200
|
|
|
189
|
-
it("displays 'Auto-Generated' when the
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
201
|
+
it("displays 'Auto-Generated' when the identifier has auto generation", () => {
|
|
202
|
+
renderIdentifierInput({
|
|
203
|
+
...openmrsID,
|
|
204
|
+
autoGeneration: true,
|
|
205
|
+
});
|
|
206
|
+
const placeholder = screen.getByTestId('identifier-placeholder');
|
|
207
|
+
expect(placeholder).toHaveTextContent('Auto-generated');
|
|
193
208
|
expect(screen.getByTestId('identifier-input')).toBeDisabled();
|
|
194
209
|
});
|
|
195
210
|
|
|
196
|
-
describe('
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
211
|
+
describe('Manual entry allowed', () => {
|
|
212
|
+
it('shows the edit button when manual entry is enabled', () => {
|
|
213
|
+
renderIdentifierInput({
|
|
214
|
+
...openmrsID,
|
|
215
|
+
autoGeneration: true,
|
|
216
|
+
required: false,
|
|
217
|
+
selectedSource: {
|
|
218
|
+
uuid: '01af8526-cea4-4175-aa90-340acb411771',
|
|
219
|
+
name: 'Generator 2 for OpenMRS ID',
|
|
220
|
+
autoGenerationOption: {
|
|
221
|
+
manualEntryEnabled: true,
|
|
222
|
+
automaticGenerationEnabled: true,
|
|
223
|
+
},
|
|
224
|
+
} as IdentifierSource,
|
|
225
|
+
});
|
|
206
226
|
expect(screen.getByText('Edit')).toBeInTheDocument();
|
|
207
227
|
});
|
|
208
228
|
|
|
209
|
-
describe('
|
|
210
|
-
it('displays an empty input field', async () => {
|
|
229
|
+
describe('Edit button interaction', () => {
|
|
230
|
+
it('displays an empty input field when edit button is clicked', async () => {
|
|
211
231
|
const user = userEvent.setup();
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
232
|
+
renderIdentifierInput(
|
|
233
|
+
{
|
|
234
|
+
...openmrsID,
|
|
235
|
+
autoGeneration: true,
|
|
236
|
+
required: false,
|
|
237
|
+
selectedSource: {
|
|
238
|
+
...openmrsID.selectedSource,
|
|
239
|
+
autoGenerationOption: {
|
|
240
|
+
manualEntryEnabled: true,
|
|
241
|
+
automaticGenerationEnabled: true,
|
|
242
|
+
},
|
|
243
|
+
} as IdentifierSource,
|
|
217
244
|
},
|
|
218
|
-
|
|
219
|
-
|
|
245
|
+
fieldName,
|
|
246
|
+
);
|
|
247
|
+
|
|
220
248
|
const editButton = screen.getByTestId('edit-button');
|
|
221
249
|
await user.click(editButton);
|
|
222
|
-
|
|
250
|
+
|
|
251
|
+
await waitFor(() => {
|
|
252
|
+
expect(screen.getByLabelText(new RegExp(`${openmrsID.identifierName}`))).toHaveValue('');
|
|
253
|
+
});
|
|
223
254
|
});
|
|
224
255
|
|
|
225
256
|
it('displays an input field with the identifier value if it exists', async () => {
|
|
226
257
|
const user = userEvent.setup();
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
258
|
+
renderIdentifierInput(
|
|
259
|
+
{
|
|
260
|
+
...openmrsID,
|
|
261
|
+
autoGeneration: true,
|
|
262
|
+
required: false,
|
|
263
|
+
selectedSource: {
|
|
264
|
+
...openmrsID.selectedSource,
|
|
265
|
+
autoGenerationOption: {
|
|
266
|
+
manualEntryEnabled: true,
|
|
267
|
+
automaticGenerationEnabled: true,
|
|
268
|
+
},
|
|
269
|
+
} as IdentifierSource,
|
|
232
270
|
},
|
|
233
|
-
|
|
234
|
-
|
|
271
|
+
fieldName,
|
|
272
|
+
{ identifiers: { [fieldName]: { identifierValue: '10001V' } } },
|
|
273
|
+
);
|
|
274
|
+
|
|
235
275
|
const editButton = screen.getByTestId('edit-button');
|
|
236
276
|
await user.click(editButton);
|
|
237
|
-
|
|
277
|
+
|
|
278
|
+
await waitFor(() => {
|
|
279
|
+
expect(screen.getByLabelText(new RegExp(`${openmrsID.identifierName}`))).toHaveValue('10001V');
|
|
280
|
+
});
|
|
238
281
|
});
|
|
239
282
|
});
|
|
240
283
|
});
|
|
241
284
|
});
|
|
242
285
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
286
|
+
describe('Format validation', () => {
|
|
287
|
+
it('validates identifier format correctly for identifier types with regex formats', async () => {
|
|
288
|
+
const user = userEvent.setup();
|
|
289
|
+
|
|
290
|
+
const ssnIdentifier = {
|
|
291
|
+
...openmrsID,
|
|
292
|
+
autoGeneration: false,
|
|
293
|
+
format: '^[A-Z]{1}-[0-9]{7}$',
|
|
294
|
+
identifierName: 'SSN',
|
|
295
|
+
identifierTypeUuid: 'a71403f3-8584-4289-ab41-2b4e5570bd45',
|
|
296
|
+
identifierValue: undefined,
|
|
297
|
+
initialValue: '',
|
|
298
|
+
required: true,
|
|
299
|
+
selectedSource: {
|
|
300
|
+
uuid: '01af8526-cea4-4175-aa90-340acb411771',
|
|
301
|
+
name: 'Generator 2 for SSN',
|
|
302
|
+
autoGenerationOption: {
|
|
303
|
+
manualEntryEnabled: true,
|
|
304
|
+
automaticGenerationEnabled: false,
|
|
305
|
+
},
|
|
306
|
+
} as IdentifierSource,
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
const mockSetFieldTouched = vi.fn();
|
|
310
|
+
const mockSetFieldValue = vi.fn();
|
|
311
|
+
const testContextValues = {
|
|
312
|
+
...mockContextValues,
|
|
313
|
+
setFieldTouched: mockSetFieldTouched,
|
|
314
|
+
setFieldValue: mockSetFieldValue,
|
|
315
|
+
values: {
|
|
316
|
+
...mockInitialFormValues,
|
|
317
|
+
identifiers: {
|
|
318
|
+
[fieldName]: ssnIdentifier,
|
|
319
|
+
},
|
|
261
320
|
},
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
const mockSetFieldTouched = jest.fn();
|
|
266
|
-
const mockSetFieldValue = jest.fn();
|
|
267
|
-
const testContextValues = {
|
|
268
|
-
...mockContextValues,
|
|
269
|
-
setFieldTouched: mockSetFieldTouched,
|
|
270
|
-
setFieldValue: mockSetFieldValue,
|
|
271
|
-
values: {
|
|
272
|
-
...mockInitialFormValues,
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
const initialValues = {
|
|
273
324
|
identifiers: {
|
|
274
|
-
[fieldName]:
|
|
325
|
+
[fieldName]: {
|
|
326
|
+
identifierValue: '',
|
|
327
|
+
},
|
|
275
328
|
},
|
|
276
|
-
}
|
|
277
|
-
};
|
|
329
|
+
};
|
|
278
330
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
331
|
+
renderWithContext(
|
|
332
|
+
<Formik initialValues={initialValues} onSubmit={vi.fn()}>
|
|
333
|
+
<Form>
|
|
334
|
+
<PatientRegistrationContextProvider value={testContextValues}>
|
|
335
|
+
<IdentifierInput patientIdentifier={ssnIdentifier} fieldName={fieldName} />
|
|
336
|
+
</PatientRegistrationContextProvider>
|
|
337
|
+
</Form>
|
|
338
|
+
</Formik>,
|
|
339
|
+
ResourcesContextProvider,
|
|
340
|
+
mockResourcesContextValue,
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
const input = screen.getByRole('textbox', {
|
|
344
|
+
name: /ssn/i,
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
// Valid case
|
|
348
|
+
await user.type(input, 'A-1234567');
|
|
349
|
+
await user.tab();
|
|
350
|
+
|
|
351
|
+
await waitFor(() => {
|
|
352
|
+
expect(input).toHaveValue('A-1234567');
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
await waitFor(() => {
|
|
356
|
+
expect(input).not.toHaveClass('cds--text-input--invalid');
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
expect(screen.queryByText(/identifier should be/i)).not.toBeInTheDocument();
|
|
360
|
+
|
|
361
|
+
// Invalid cases
|
|
362
|
+
await user.clear(input);
|
|
363
|
+
await user.type(input, 'A-0010902aaa'); // Extra characters
|
|
364
|
+
await user.tab();
|
|
365
|
+
|
|
366
|
+
await waitFor(() => {
|
|
367
|
+
expect(input).toHaveClass('cds--text-input--invalid');
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
await waitFor(() => {
|
|
371
|
+
expect(screen.getByText(/identifier should be/i)).toBeInTheDocument();
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
await user.clear(input);
|
|
375
|
+
await user.type(input, 'a-1234567'); // Lowercase letter
|
|
376
|
+
await user.tab();
|
|
302
377
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
await user.clear(input);
|
|
324
|
-
await user.type(input, 'AB-1234567'); // Two letters
|
|
325
|
-
await user.tab();
|
|
326
|
-
expect(input).toHaveClass('cds--text-input--invalid');
|
|
327
|
-
expect(screen.getByText(/identifier should be/i)).toBeInTheDocument();
|
|
328
|
-
|
|
329
|
-
await user.clear(input);
|
|
330
|
-
await user.type(input, 'A-123456'); // Only 6 digits
|
|
331
|
-
await user.tab();
|
|
332
|
-
expect(input).toHaveClass('cds--text-input--invalid');
|
|
333
|
-
expect(screen.getByText(/identifier should be/i)).toBeInTheDocument();
|
|
378
|
+
await waitFor(() => {
|
|
379
|
+
expect(input).toHaveClass('cds--text-input--invalid');
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
await user.clear(input);
|
|
383
|
+
await user.type(input, 'AB-1234567'); // Two letters
|
|
384
|
+
await user.tab();
|
|
385
|
+
|
|
386
|
+
await waitFor(() => {
|
|
387
|
+
expect(input).toHaveClass('cds--text-input--invalid');
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
await user.clear(input);
|
|
391
|
+
await user.type(input, 'A-123456'); // Only 6 digits
|
|
392
|
+
await user.tab();
|
|
393
|
+
|
|
394
|
+
await waitFor(() => {
|
|
395
|
+
expect(input).toHaveClass('cds--text-input--invalid');
|
|
396
|
+
});
|
|
397
|
+
});
|
|
334
398
|
});
|
|
335
399
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isUniqueIdentifierTypeForOffline, shouldBlockPatientIdentifierInOfflineMode } from './utils';
|
|
2
|
+
import { vi, describe, it, expect } from 'vitest';
|
|
2
3
|
|
|
3
4
|
interface IdentifierTypeOptions {
|
|
4
5
|
uniquenessBehavior?: 'UNIQUE' | 'LOCATION' | 'NON_UNIQUE';
|
|
@@ -31,23 +32,57 @@ function createIdentifierType(options: IdentifierTypeOptions) {
|
|
|
31
32
|
describe('shouldBlockPatientIdentifierInOfflineMode function', () => {
|
|
32
33
|
it('should return false if identifierType is not unique', () => {
|
|
33
34
|
const identifierType = createIdentifierType({ uniquenessBehavior: null });
|
|
34
|
-
|
|
35
35
|
const result = shouldBlockPatientIdentifierInOfflineMode(identifierType);
|
|
36
36
|
|
|
37
37
|
expect(result).toBe(false);
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
it('should return false if identifierType is
|
|
41
|
-
const identifierType = createIdentifierType({ uniquenessBehavior:
|
|
40
|
+
it('should return false if identifierType is NON_UNIQUE', () => {
|
|
41
|
+
const identifierType = createIdentifierType({ uniquenessBehavior: 'NON_UNIQUE' });
|
|
42
|
+
const result = shouldBlockPatientIdentifierInOfflineMode(identifierType);
|
|
43
|
+
|
|
44
|
+
expect(result).toBe(false);
|
|
45
|
+
});
|
|
42
46
|
|
|
47
|
+
it('should return false if identifierType is unique but has automatic generation only (no manual entry)', () => {
|
|
48
|
+
const identifierType = createIdentifierType({
|
|
49
|
+
uniquenessBehavior: 'UNIQUE',
|
|
50
|
+
manualEntryEnabled: false,
|
|
51
|
+
automaticGenerationEnabled: true,
|
|
52
|
+
});
|
|
43
53
|
const result = shouldBlockPatientIdentifierInOfflineMode(identifierType);
|
|
44
54
|
|
|
45
55
|
expect(result).toBe(false);
|
|
46
56
|
});
|
|
47
57
|
|
|
48
58
|
it('should return true if identifierType is unique and manual entry is enabled', () => {
|
|
49
|
-
const identifierType = createIdentifierType({
|
|
59
|
+
const identifierType = createIdentifierType({
|
|
60
|
+
uniquenessBehavior: 'UNIQUE',
|
|
61
|
+
manualEntryEnabled: true,
|
|
62
|
+
automaticGenerationEnabled: false,
|
|
63
|
+
});
|
|
64
|
+
const result = shouldBlockPatientIdentifierInOfflineMode(identifierType);
|
|
65
|
+
|
|
66
|
+
expect(result).toBe(true);
|
|
67
|
+
});
|
|
50
68
|
|
|
69
|
+
it('should return true if identifierType is unique and both manual entry and auto generation are enabled', () => {
|
|
70
|
+
const identifierType = createIdentifierType({
|
|
71
|
+
uniquenessBehavior: 'UNIQUE',
|
|
72
|
+
manualEntryEnabled: true,
|
|
73
|
+
automaticGenerationEnabled: true,
|
|
74
|
+
});
|
|
75
|
+
const result = shouldBlockPatientIdentifierInOfflineMode(identifierType);
|
|
76
|
+
|
|
77
|
+
expect(result).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should return true if identifierType is unique with LOCATION behavior and manual entry enabled', () => {
|
|
81
|
+
const identifierType = createIdentifierType({
|
|
82
|
+
uniquenessBehavior: 'LOCATION',
|
|
83
|
+
manualEntryEnabled: true,
|
|
84
|
+
automaticGenerationEnabled: false,
|
|
85
|
+
});
|
|
51
86
|
const result = shouldBlockPatientIdentifierInOfflineMode(identifierType);
|
|
52
87
|
|
|
53
88
|
expect(result).toBe(true);
|
|
@@ -57,7 +92,6 @@ describe('shouldBlockPatientIdentifierInOfflineMode function', () => {
|
|
|
57
92
|
describe('isUniqueIdentifierTypeForOffline function', () => {
|
|
58
93
|
it('should return true if uniquenessBehavior is UNIQUE', () => {
|
|
59
94
|
const identifierType = createIdentifierType({ uniquenessBehavior: 'UNIQUE' });
|
|
60
|
-
|
|
61
95
|
const result = isUniqueIdentifierTypeForOffline(identifierType);
|
|
62
96
|
|
|
63
97
|
expect(result).toBe(true);
|
|
@@ -65,15 +99,20 @@ describe('isUniqueIdentifierTypeForOffline function', () => {
|
|
|
65
99
|
|
|
66
100
|
it('should return true if uniquenessBehavior is LOCATION', () => {
|
|
67
101
|
const identifierType = createIdentifierType({ uniquenessBehavior: 'LOCATION' });
|
|
68
|
-
|
|
69
102
|
const result = isUniqueIdentifierTypeForOffline(identifierType);
|
|
70
103
|
|
|
71
104
|
expect(result).toBe(true);
|
|
72
105
|
});
|
|
73
106
|
|
|
74
|
-
it('should return false
|
|
75
|
-
const identifierType = createIdentifierType({ uniquenessBehavior:
|
|
107
|
+
it('should return false if uniquenessBehavior is NON_UNIQUE', () => {
|
|
108
|
+
const identifierType = createIdentifierType({ uniquenessBehavior: 'NON_UNIQUE' });
|
|
109
|
+
const result = isUniqueIdentifierTypeForOffline(identifierType);
|
|
76
110
|
|
|
111
|
+
expect(result).toBe(false);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should return false if uniquenessBehavior is null or undefined', () => {
|
|
115
|
+
const identifierType = createIdentifierType({ uniquenessBehavior: null });
|
|
77
116
|
const result = isUniqueIdentifierTypeForOffline(identifierType);
|
|
78
117
|
|
|
79
118
|
expect(result).toBe(false);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { Button } from '@carbon/react';
|
|
3
4
|
import { v4 } from 'uuid';
|
|
4
5
|
import { type FormValues } from '../../patient-registration.types';
|
|
5
6
|
import styles from './../input.scss';
|
|
@@ -17,8 +18,8 @@ export const dummyFormValues: FormValues = {
|
|
|
17
18
|
additionalMiddleName: '',
|
|
18
19
|
additionalFamilyName: 'Smitty',
|
|
19
20
|
addNameInLocalLanguage: true,
|
|
20
|
-
gender: '
|
|
21
|
-
birthdate: new Date(2020, 1, 1)
|
|
21
|
+
gender: 'male',
|
|
22
|
+
birthdate: new Date(2020, 1, 1),
|
|
22
23
|
yearsEstimated: 1,
|
|
23
24
|
monthsEstimated: 2,
|
|
24
25
|
birthdateEstimated: true,
|
|
@@ -42,15 +43,14 @@ export const dummyFormValues: FormValues = {
|
|
|
42
43
|
};
|
|
43
44
|
|
|
44
45
|
export const DummyDataInput: React.FC<DummyDataInputProps> = ({ setValues }) => {
|
|
46
|
+
const { t } = useTranslation();
|
|
45
47
|
return (
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
</button>
|
|
54
|
-
</main>
|
|
48
|
+
<Button
|
|
49
|
+
kind="tertiary"
|
|
50
|
+
onClick={() => setValues(dummyFormValues)}
|
|
51
|
+
className={styles.dummyData}
|
|
52
|
+
aria-label={t('inputDummyData', 'Input Dummy Data')}>
|
|
53
|
+
{t('inputDummyData', 'Input Dummy Data')}
|
|
54
|
+
</Button>
|
|
55
55
|
);
|
|
56
56
|
};
|