@olaboot/esm-patient-registration-app 9.2.0 → 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 +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 +10 -13
- package/src/patient-registration/field/address/address-hierarchy-levels.component.tsx +6 -1
- package/src/patient-registration/field/address/address-hierarchy.test.tsx +191 -198
- 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 +249 -57
- 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 +25 -22
- package/src/patient-registration/field/gender/gender-field.test.tsx +240 -54
- package/src/patient-registration/field/id/id-field.component.tsx +15 -5
- package/src/patient-registration/field/id/id-field.test.tsx +103 -47
- 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 +99 -65
- 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 +9 -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/ADDRESS_CONFIGURATION.md +0 -152
- package/IDENTIFIER_CONFIGURATION.md +0 -142
- package/IMPLEMENTATION_SUMMARY.md +0 -111
- package/QUICK_START.md +0 -95
- package/address-required-fields-config.json +0 -26
- 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/example-config.json +0 -14
- package/jest.config.js +0 -3
- package/src/resource.ts +0 -12
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vitest-environment jsdom
|
|
3
|
+
*
|
|
4
|
+
* The form-submit flow under test does not fire its callback under happy-dom
|
|
5
|
+
* (likely a DOM-event-dispatch divergence). Run this file under jsdom.
|
|
6
|
+
*/
|
|
1
7
|
import React from 'react';
|
|
8
|
+
import { vi, describe, it, expect, test, beforeEach } from 'vitest';
|
|
2
9
|
import userEvent from '@testing-library/user-event';
|
|
3
10
|
import { useParams } from 'react-router-dom';
|
|
4
|
-
import { screen, within } from '@testing-library/react';
|
|
11
|
+
import { fireEvent, screen, within } from '@testing-library/react';
|
|
5
12
|
import {
|
|
6
13
|
type FetchResponse,
|
|
7
14
|
getDefaultsFromConfigSchema,
|
|
@@ -19,18 +26,18 @@ import { PatientRegistration } from './patient-registration.component';
|
|
|
19
26
|
import { useInitialFormValues } from './patient-registration-hooks';
|
|
20
27
|
import { ResourcesContextProvider } from '../resources-context';
|
|
21
28
|
|
|
22
|
-
const mockSaveEncounter =
|
|
23
|
-
const mockSavePatient = savePatient
|
|
24
|
-
const mockShowSnackbar =
|
|
25
|
-
const mockUseConfig =
|
|
26
|
-
const mockUsePatient =
|
|
27
|
-
const mockUseParams = useParams
|
|
28
|
-
const mockUseInitialFormValues =
|
|
29
|
+
const mockSaveEncounter = vi.mocked(saveEncounter);
|
|
30
|
+
const mockSavePatient = vi.mocked(savePatient);
|
|
31
|
+
const mockShowSnackbar = vi.mocked(showSnackbar);
|
|
32
|
+
const mockUseConfig = vi.mocked(useConfig<RegistrationConfig>);
|
|
33
|
+
const mockUsePatient = vi.mocked(usePatient);
|
|
34
|
+
const mockUseParams = vi.mocked(useParams);
|
|
35
|
+
const mockUseInitialFormValues = vi.mocked(useInitialFormValues);
|
|
29
36
|
|
|
30
|
-
|
|
31
|
-
useConcept:
|
|
37
|
+
vi.mock('./field/field.resource', () => ({
|
|
38
|
+
useConcept: vi.fn().mockImplementation((uuid: string) => {
|
|
32
39
|
let data;
|
|
33
|
-
if (uuid
|
|
40
|
+
if (uuid === 'weight-uuid') {
|
|
34
41
|
data = {
|
|
35
42
|
uuid: 'weight-uuid',
|
|
36
43
|
display: 'Weight (kg)',
|
|
@@ -38,7 +45,7 @@ jest.mock('./field/field.resource', () => ({
|
|
|
38
45
|
answers: [],
|
|
39
46
|
setMembers: [],
|
|
40
47
|
};
|
|
41
|
-
} else if (uuid
|
|
48
|
+
} else if (uuid === 'chief-complaint-uuid') {
|
|
42
49
|
data = {
|
|
43
50
|
uuid: 'chief-complaint-uuid',
|
|
44
51
|
display: 'Chief Complaint',
|
|
@@ -46,7 +53,7 @@ jest.mock('./field/field.resource', () => ({
|
|
|
46
53
|
answers: [],
|
|
47
54
|
setMembers: [],
|
|
48
55
|
};
|
|
49
|
-
} else if (uuid
|
|
56
|
+
} else if (uuid === 'nationality-uuid') {
|
|
50
57
|
data = {
|
|
51
58
|
uuid: 'nationality-uuid',
|
|
52
59
|
display: 'Nationality',
|
|
@@ -63,8 +70,8 @@ jest.mock('./field/field.resource', () => ({
|
|
|
63
70
|
isLoading: !data,
|
|
64
71
|
};
|
|
65
72
|
}),
|
|
66
|
-
useConceptAnswers:
|
|
67
|
-
if (uuid
|
|
73
|
+
useConceptAnswers: vi.fn().mockImplementation((uuid: string) => {
|
|
74
|
+
if (uuid === 'nationality-uuid') {
|
|
68
75
|
return {
|
|
69
76
|
data: [
|
|
70
77
|
{ display: 'USA', uuid: 'usa' },
|
|
@@ -72,7 +79,7 @@ jest.mock('./field/field.resource', () => ({
|
|
|
72
79
|
],
|
|
73
80
|
isLoading: false,
|
|
74
81
|
};
|
|
75
|
-
} else if (uuid
|
|
82
|
+
} else if (uuid === 'other-countries-uuid') {
|
|
76
83
|
return {
|
|
77
84
|
data: [
|
|
78
85
|
{ display: 'Kenya', uuid: 'ke' },
|
|
@@ -84,27 +91,56 @@ jest.mock('./field/field.resource', () => ({
|
|
|
84
91
|
}),
|
|
85
92
|
}));
|
|
86
93
|
|
|
87
|
-
|
|
88
|
-
...
|
|
94
|
+
vi.mock('react-router-dom', async () => ({
|
|
95
|
+
...((await vi.importActual('react-router-dom')) as object),
|
|
89
96
|
useLocation: () => ({
|
|
90
97
|
pathname: 'openmrs/spa/patient-registration',
|
|
91
98
|
}),
|
|
92
99
|
useHistory: () => [],
|
|
93
|
-
useParams:
|
|
100
|
+
useParams: vi.fn().mockReturnValue({ patientUuid: undefined }),
|
|
94
101
|
}));
|
|
95
102
|
|
|
96
|
-
|
|
97
|
-
...
|
|
98
|
-
saveEncounter:
|
|
99
|
-
savePatient:
|
|
103
|
+
vi.mock('./patient-registration.resource', async () => ({
|
|
104
|
+
...((await vi.importActual('./patient-registration.resource')) as object),
|
|
105
|
+
saveEncounter: vi.fn(),
|
|
106
|
+
savePatient: vi.fn(),
|
|
100
107
|
}));
|
|
101
108
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
109
|
+
vi.mock('./patient-registration-hooks', async () => {
|
|
110
|
+
const actual = (await vi.importActual('./patient-registration-hooks')) as object;
|
|
111
|
+
const defaultInitialFormValues = {
|
|
112
|
+
additionalFamilyName: '',
|
|
113
|
+
additionalGivenName: '',
|
|
114
|
+
additionalMiddleName: '',
|
|
115
|
+
addNameInLocalLanguage: false,
|
|
116
|
+
address: {},
|
|
117
|
+
birthdate: '',
|
|
118
|
+
birthdateEstimated: false,
|
|
119
|
+
deathCause: '',
|
|
120
|
+
deathDate: undefined,
|
|
121
|
+
deathTime: undefined,
|
|
122
|
+
deathTimeFormat: 'AM',
|
|
123
|
+
familyName: '',
|
|
124
|
+
gender: '',
|
|
125
|
+
givenName: '',
|
|
126
|
+
identifiers: {},
|
|
127
|
+
isDead: false,
|
|
128
|
+
middleName: '',
|
|
129
|
+
monthsEstimated: 0,
|
|
130
|
+
nonCodedCauseOfDeath: '',
|
|
131
|
+
patientUuid: 'new-patient-uuid',
|
|
132
|
+
relationships: [],
|
|
133
|
+
telephoneNumber: '',
|
|
134
|
+
yearsEstimated: 0,
|
|
135
|
+
} as FormValues;
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
...actual,
|
|
139
|
+
useInitialFormValues: vi.fn().mockReturnValue([defaultInitialFormValues, vi.fn()]),
|
|
140
|
+
useInitialAddressFieldValues: vi.fn().mockReturnValue([{}, vi.fn()]),
|
|
141
|
+
usePatientUuidMap: vi.fn().mockReturnValue([{}, vi.fn()]),
|
|
142
|
+
};
|
|
143
|
+
});
|
|
108
144
|
|
|
109
145
|
const mockResourcesContextValue = {
|
|
110
146
|
addressTemplate: mockedAddressTemplate as AddressTemplate,
|
|
@@ -113,7 +149,7 @@ const mockResourcesContextValue = {
|
|
|
113
149
|
sessionId: 'JSESSION',
|
|
114
150
|
currentProvider: { uuid: 'provider-uuid', identifier: 'PRO-123' },
|
|
115
151
|
},
|
|
116
|
-
relationshipTypes: [],
|
|
152
|
+
relationshipTypes: { results: [] },
|
|
117
153
|
identifierTypes: [],
|
|
118
154
|
};
|
|
119
155
|
|
|
@@ -161,7 +197,6 @@ const mockOpenmrsConfig: RegistrationConfig = {
|
|
|
161
197
|
useQuickSearch: true,
|
|
162
198
|
searchAddressByLevel: true,
|
|
163
199
|
},
|
|
164
|
-
requiredAddressFields: [],
|
|
165
200
|
},
|
|
166
201
|
causeOfDeath: {
|
|
167
202
|
conceptUuid: 'cause-of-death-concept-uuid',
|
|
@@ -226,24 +261,26 @@ const fillRequiredFields = async () => {
|
|
|
226
261
|
const demographicsSection = await screen.findByLabelText('Demographics Section');
|
|
227
262
|
const givenNameInput = within(demographicsSection).getByLabelText(/first/i) as HTMLInputElement;
|
|
228
263
|
const familyNameInput = within(demographicsSection).getByLabelText(/family/i) as HTMLInputElement;
|
|
229
|
-
|
|
230
|
-
name: /day, date of birth/i,
|
|
231
|
-
}) as HTMLInputElement;
|
|
232
|
-
const monthInput = within(demographicsSection).getByRole('spinbutton', {
|
|
233
|
-
name: /month, date of birth/i,
|
|
234
|
-
}) as HTMLInputElement;
|
|
235
|
-
const yearInput = within(demographicsSection).getByRole('spinbutton', {
|
|
236
|
-
name: /year, date of birth/i,
|
|
237
|
-
}) as HTMLInputElement;
|
|
238
|
-
const genderInput = within(demographicsSection).getByLabelText(/Male/) as HTMLSelectElement;
|
|
264
|
+
|
|
239
265
|
await user.type(givenNameInput, 'Paul');
|
|
240
266
|
await user.type(familyNameInput, 'Gaihre');
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
267
|
+
|
|
268
|
+
// Set birthdate using the date picker's public API
|
|
269
|
+
let dateOfBirthInput: HTMLInputElement;
|
|
270
|
+
const birthDateString = '1993-08-02';
|
|
271
|
+
|
|
272
|
+
try {
|
|
273
|
+
// Approach 1: Find as textbox (like appointments test)
|
|
274
|
+
dateOfBirthInput = within(demographicsSection).getByRole('textbox', { name: /date of birth/i }) as HTMLInputElement;
|
|
275
|
+
} catch (e) {
|
|
276
|
+
// Approach 2: Find by label
|
|
277
|
+
dateOfBirthInput = within(demographicsSection).getByLabelText(/date of birth/i) as HTMLInputElement;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
fireEvent.change(dateOfBirthInput, { target: { value: birthDateString } });
|
|
281
|
+
fireEvent.blur(dateOfBirthInput);
|
|
282
|
+
|
|
283
|
+
const genderInput = within(demographicsSection).getByLabelText(/Male/) as HTMLSelectElement;
|
|
247
284
|
await user.click(genderInput);
|
|
248
285
|
};
|
|
249
286
|
|
|
@@ -253,12 +290,12 @@ describe('Registering a new patient', () => {
|
|
|
253
290
|
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
254
291
|
...mockOpenmrsConfig,
|
|
255
292
|
});
|
|
256
|
-
mockSavePatient.
|
|
293
|
+
mockSavePatient.mockResolvedValue({ data: { uuid: 'new-pt-uuid' }, ok: true } as any);
|
|
257
294
|
});
|
|
258
295
|
|
|
259
296
|
it('should render all the required fields and sections', async () => {
|
|
260
297
|
renderWithContext(
|
|
261
|
-
<PatientRegistration isOffline={false} savePatientForm={
|
|
298
|
+
<PatientRegistration isOffline={false} savePatientForm={vi.fn()} />,
|
|
262
299
|
ResourcesContextProvider,
|
|
263
300
|
mockResourcesContextValue,
|
|
264
301
|
);
|
|
@@ -286,8 +323,7 @@ describe('Registering a new patient', () => {
|
|
|
286
323
|
expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument();
|
|
287
324
|
});
|
|
288
325
|
|
|
289
|
-
|
|
290
|
-
it.skip('saves the patient without extra info', async () => {
|
|
326
|
+
it('saves the patient without extra info', async () => {
|
|
291
327
|
const user = userEvent.setup();
|
|
292
328
|
|
|
293
329
|
renderWithContext(
|
|
@@ -297,10 +333,11 @@ describe('Registering a new patient', () => {
|
|
|
297
333
|
);
|
|
298
334
|
|
|
299
335
|
await fillRequiredFields();
|
|
300
|
-
|
|
336
|
+
const registerButton = await screen.findByRole('button', { name: /register patient/i });
|
|
337
|
+
await user.click(registerButton);
|
|
301
338
|
expect(mockSavePatient).toHaveBeenCalledWith(
|
|
302
339
|
expect.objectContaining({
|
|
303
|
-
identifiers: [], //
|
|
340
|
+
identifiers: [], // Note: Identifier story may need test data update when complete
|
|
304
341
|
person: {
|
|
305
342
|
addresses: expect.arrayContaining([expect.any(Object)]),
|
|
306
343
|
attributes: [],
|
|
@@ -319,7 +356,7 @@ describe('Registering a new patient', () => {
|
|
|
319
356
|
|
|
320
357
|
it('should not save the patient if validation fails', async () => {
|
|
321
358
|
const user = userEvent.setup();
|
|
322
|
-
const mockSavePatientForm =
|
|
359
|
+
const mockSavePatientForm = vi.fn();
|
|
323
360
|
|
|
324
361
|
renderWithContext(
|
|
325
362
|
<PatientRegistration isOffline={false} savePatientForm={mockSavePatientForm} />,
|
|
@@ -333,8 +370,7 @@ describe('Registering a new patient', () => {
|
|
|
333
370
|
expect(mockSavePatientForm).not.toHaveBeenCalled();
|
|
334
371
|
});
|
|
335
372
|
|
|
336
|
-
|
|
337
|
-
it.skip('renders and saves registration obs', async () => {
|
|
373
|
+
it('renders and saves registration obs', async () => {
|
|
338
374
|
const user = userEvent.setup();
|
|
339
375
|
|
|
340
376
|
mockSaveEncounter.mockResolvedValue({} as unknown as FetchResponse);
|
|
@@ -355,7 +391,8 @@ describe('Registering a new patient', () => {
|
|
|
355
391
|
const nationality = within(customSection).getByLabelText('Nationality');
|
|
356
392
|
await user.selectOptions(nationality, 'USA');
|
|
357
393
|
|
|
358
|
-
await
|
|
394
|
+
const registerButton = await screen.findByRole('button', { name: /register patient/i });
|
|
395
|
+
await user.click(registerButton);
|
|
359
396
|
|
|
360
397
|
expect(mockSavePatient).toHaveBeenCalled();
|
|
361
398
|
|
|
@@ -372,8 +409,7 @@ describe('Registering a new patient', () => {
|
|
|
372
409
|
);
|
|
373
410
|
});
|
|
374
411
|
|
|
375
|
-
|
|
376
|
-
it.skip('retries saving registration obs after a failed attempt', async () => {
|
|
412
|
+
it('retries saving registration obs after a failed attempt', async () => {
|
|
377
413
|
const user = userEvent.setup();
|
|
378
414
|
|
|
379
415
|
mockUseConfig.mockReturnValue(configWithObs);
|
|
@@ -391,7 +427,7 @@ describe('Registering a new patient', () => {
|
|
|
391
427
|
|
|
392
428
|
mockSaveEncounter.mockRejectedValue({ status: 400, responseBody: { error: { message: 'an error message' } } });
|
|
393
429
|
|
|
394
|
-
const registerPatientButton = screen.
|
|
430
|
+
const registerPatientButton = await screen.findByRole('button', { name: /register patient/i });
|
|
395
431
|
|
|
396
432
|
await user.click(registerPatientButton);
|
|
397
433
|
|
|
@@ -423,13 +459,13 @@ describe('Updating an existing patient record', () => {
|
|
|
423
459
|
patientUuid: mockPatient.id,
|
|
424
460
|
};
|
|
425
461
|
});
|
|
426
|
-
mockSavePatient.
|
|
462
|
+
mockSavePatient.mockResolvedValue({ data: { uuid: 'new-pt-uuid' }, ok: true } as any);
|
|
427
463
|
mockUseParams.mockReturnValue({ patientUuid: mockPatient.id });
|
|
428
464
|
});
|
|
429
465
|
|
|
430
466
|
it('edits patient demographics', async () => {
|
|
431
467
|
const user = userEvent.setup();
|
|
432
|
-
const mockSavePatientForm =
|
|
468
|
+
const mockSavePatientForm = vi.fn();
|
|
433
469
|
|
|
434
470
|
mockUseInitialFormValues.mockReturnValue([
|
|
435
471
|
{
|
|
@@ -480,7 +516,7 @@ describe('Updating an existing patient record', () => {
|
|
|
480
516
|
telephoneNumber: '',
|
|
481
517
|
yearsEstimated: 0,
|
|
482
518
|
} as FormValues,
|
|
483
|
-
|
|
519
|
+
vi.fn(),
|
|
484
520
|
]);
|
|
485
521
|
|
|
486
522
|
renderWithContext(
|
|
@@ -497,8 +533,6 @@ describe('Updating an existing patient record', () => {
|
|
|
497
533
|
|
|
498
534
|
expect(screen.getByLabelText(/first name/i)).toHaveValue(mockPatient.name[0].given[0]);
|
|
499
535
|
expect(screen.getByLabelText(/family name/i)).toHaveValue(mockPatient.name[0].family);
|
|
500
|
-
// FIXME: Fix the mock so that this value is visible
|
|
501
|
-
// expect(screen.getByLabelText(/date of birth/i)).toHaveValue(mockPatient.birthDate);
|
|
502
536
|
expect(
|
|
503
537
|
screen.getByRole('radio', {
|
|
504
538
|
name: /^male$/i,
|
|
@@ -85,7 +85,7 @@ export interface PatientRegistration {
|
|
|
85
85
|
isNewPatient: boolean;
|
|
86
86
|
formValues: FormValues;
|
|
87
87
|
patientUuidMap: PatientUuidMapType;
|
|
88
|
-
initialAddressFieldValues: Record<
|
|
88
|
+
initialAddressFieldValues: Partial<Record<AddressProperties, string>>;
|
|
89
89
|
capturePhotoProps: CapturePhotoProps;
|
|
90
90
|
currentLocation: string;
|
|
91
91
|
initialIdentifierValues: FormValues['identifiers'];
|
|
@@ -201,22 +201,6 @@ export interface CapturePhotoProps {
|
|
|
201
201
|
dateTime: string;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
-
export interface AddressValidationSchemaType {
|
|
205
|
-
name: string;
|
|
206
|
-
label: string;
|
|
207
|
-
regex: RegExp;
|
|
208
|
-
regexFormat: string;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
export interface CodedPersonAttributeConfig {
|
|
212
|
-
personAttributeUuid: string;
|
|
213
|
-
conceptUuid: string;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
export interface TextBasedPersonAttributeConfig {
|
|
217
|
-
personAttributeUuid: string;
|
|
218
|
-
validationRegex: string;
|
|
219
|
-
}
|
|
220
204
|
export interface PatientIdentifierResponse {
|
|
221
205
|
uuid: string;
|
|
222
206
|
identifier: string;
|
|
@@ -251,6 +235,11 @@ export interface PersonAttributeResponse {
|
|
|
251
235
|
};
|
|
252
236
|
}
|
|
253
237
|
|
|
238
|
+
export interface ConceptAnswers {
|
|
239
|
+
display: string;
|
|
240
|
+
uuid: string;
|
|
241
|
+
}
|
|
242
|
+
|
|
254
243
|
export interface ConceptResponse {
|
|
255
244
|
uuid: string;
|
|
256
245
|
display: string;
|
|
@@ -262,9 +251,18 @@ export interface ConceptResponse {
|
|
|
262
251
|
setMembers: Array<ConceptAnswers>;
|
|
263
252
|
}
|
|
264
253
|
|
|
265
|
-
export interface
|
|
266
|
-
display: string;
|
|
254
|
+
export interface RelationshipType {
|
|
267
255
|
uuid: string;
|
|
256
|
+
display: string;
|
|
257
|
+
aIsToB: string;
|
|
258
|
+
bIsToA: string;
|
|
259
|
+
displayAIsToB?: string;
|
|
260
|
+
displayBIsToA?: string;
|
|
261
|
+
description?: string;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export interface RelationshipTypesResponse {
|
|
265
|
+
results: Array<RelationshipType>;
|
|
268
266
|
}
|
|
269
267
|
|
|
270
268
|
export type AddressProperties =
|
|
@@ -311,12 +309,3 @@ export interface AddressTemplate {
|
|
|
311
309
|
elementRegexFormats: ExtensibleAddressProperties;
|
|
312
310
|
requiredElements: Array<AddressProperties> | null;
|
|
313
311
|
}
|
|
314
|
-
|
|
315
|
-
// https://rest.openmrs.org/#address-template
|
|
316
|
-
export interface RestAddressTemplate {
|
|
317
|
-
uuid: string;
|
|
318
|
-
description: string;
|
|
319
|
-
property: string;
|
|
320
|
-
display: string;
|
|
321
|
-
value: string;
|
|
322
|
-
}
|
|
@@ -1,47 +1,143 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
3
5
|
import { Form, Formik } from 'formik';
|
|
6
|
+
import { getDefaultsFromConfigSchema, useConfig } from '@openmrs/esm-framework';
|
|
4
7
|
import { type FormValues } from '../../patient-registration.types';
|
|
5
|
-
import { renderWithContext } from 'tools';
|
|
6
8
|
import { initialFormValues } from '../../patient-registration.component';
|
|
7
9
|
import { PatientRegistrationContextProvider } from '../../patient-registration-context';
|
|
10
|
+
import { type RegistrationConfig, esmPatientRegistrationSchema } from '../../../config-schema';
|
|
8
11
|
import { DeathInfoSection } from './death-info-section.component';
|
|
9
12
|
|
|
10
|
-
const
|
|
11
|
-
currentPhoto: 'data:image/png;base64,1234567890',
|
|
12
|
-
identifierTypes: [],
|
|
13
|
-
inEditMode: false,
|
|
14
|
-
initialFormValues: {} as FormValues,
|
|
15
|
-
isOffline: false,
|
|
16
|
-
setCapturePhotoProps: jest.fn(),
|
|
17
|
-
setFieldValue: jest.fn(),
|
|
18
|
-
setFieldTouched: jest.fn(),
|
|
19
|
-
setInitialFormValues: jest.fn(),
|
|
20
|
-
validationSchema: null,
|
|
21
|
-
values: {
|
|
22
|
-
isDead: true,
|
|
23
|
-
} as FormValues,
|
|
24
|
-
};
|
|
13
|
+
const mockUseConfig = vi.mocked(useConfig<RegistrationConfig>);
|
|
25
14
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<DeathInfoSection fields={[]} />
|
|
34
|
-
</Form>
|
|
35
|
-
</Formik>,
|
|
36
|
-
PatientRegistrationContextProvider,
|
|
37
|
-
initialContextValues,
|
|
38
|
-
);
|
|
15
|
+
/**
|
|
16
|
+
* Helper to render DeathInfoSection with Formik for state-dependent tests.
|
|
17
|
+
*/
|
|
18
|
+
function renderDeathInfoSectionWithFormik(fields: string[] = [], initialValues: Partial<FormValues> = {}) {
|
|
19
|
+
const defaultValues = {
|
|
20
|
+
isDead: false,
|
|
21
|
+
...initialValues,
|
|
39
22
|
};
|
|
40
23
|
|
|
41
|
-
|
|
42
|
-
|
|
24
|
+
let formValuesRef: FormValues = { ...initialFormValues, ...defaultValues } as FormValues;
|
|
25
|
+
|
|
26
|
+
const utils = render(
|
|
27
|
+
<Formik initialValues={defaultValues} onSubmit={() => {}}>
|
|
28
|
+
{({ setFieldValue, values }) => {
|
|
29
|
+
formValuesRef = { ...initialFormValues, ...values } as FormValues;
|
|
30
|
+
return (
|
|
31
|
+
<Form>
|
|
32
|
+
<PatientRegistrationContextProvider
|
|
33
|
+
value={{
|
|
34
|
+
identifierTypes: [],
|
|
35
|
+
values: formValuesRef,
|
|
36
|
+
validationSchema: null,
|
|
37
|
+
inEditMode: false,
|
|
38
|
+
setFieldValue: setFieldValue as any,
|
|
39
|
+
setCapturePhotoProps: vi.fn(),
|
|
40
|
+
setFieldTouched: vi.fn().mockResolvedValue(undefined),
|
|
41
|
+
currentPhoto: '',
|
|
42
|
+
isOffline: false,
|
|
43
|
+
initialFormValues: formValuesRef,
|
|
44
|
+
}}>
|
|
45
|
+
<DeathInfoSection fields={fields} />
|
|
46
|
+
</PatientRegistrationContextProvider>
|
|
47
|
+
</Form>
|
|
48
|
+
);
|
|
49
|
+
}}
|
|
50
|
+
</Formik>,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
...utils,
|
|
55
|
+
getFormValues: () => formValuesRef,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
describe('Death info section', () => {
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
mockUseConfig.mockReturnValue({
|
|
62
|
+
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
63
|
+
fieldDefinitions: [],
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('Rendering', () => {
|
|
68
|
+
it('renders the section with checkbox', () => {
|
|
69
|
+
renderDeathInfoSectionWithFormik();
|
|
70
|
+
|
|
71
|
+
expect(screen.getByRole('region', { name: /death info section/i })).toBeInTheDocument();
|
|
72
|
+
expect(screen.getByRole('checkbox', { name: /is dead/i })).toBeInTheDocument();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('shows checkbox as checked when isDead is true', () => {
|
|
76
|
+
renderDeathInfoSectionWithFormik([], { isDead: true });
|
|
77
|
+
|
|
78
|
+
const checkbox = screen.getByRole('checkbox', { name: /is dead/i });
|
|
79
|
+
expect(checkbox).toBeChecked();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('shows checkbox as unchecked when isDead is false', () => {
|
|
83
|
+
renderDeathInfoSectionWithFormik([], { isDead: false });
|
|
84
|
+
|
|
85
|
+
const checkbox = screen.getByRole('checkbox', { name: /is dead/i });
|
|
86
|
+
expect(checkbox).not.toBeChecked();
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe('User interaction', () => {
|
|
91
|
+
it('toggles death info fields when user clicks the checkbox', async () => {
|
|
92
|
+
const user = userEvent.setup();
|
|
93
|
+
const { getFormValues } = renderDeathInfoSectionWithFormik([]);
|
|
94
|
+
|
|
95
|
+
const checkbox = screen.getByRole('checkbox', { name: /is dead/i });
|
|
96
|
+
expect(checkbox).not.toBeChecked();
|
|
97
|
+
|
|
98
|
+
// Click to check
|
|
99
|
+
await user.click(checkbox);
|
|
100
|
+
|
|
101
|
+
await waitFor(() => {
|
|
102
|
+
expect(getFormValues().isDead).toBe(true);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
await waitFor(() => {
|
|
106
|
+
expect(checkbox).toBeChecked();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Click to uncheck
|
|
110
|
+
await user.click(checkbox);
|
|
111
|
+
|
|
112
|
+
await waitFor(() => {
|
|
113
|
+
expect(getFormValues().isDead).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
await waitFor(() => {
|
|
117
|
+
expect(checkbox).not.toBeChecked();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('updates form values when user toggles the checkbox', async () => {
|
|
122
|
+
const user = userEvent.setup();
|
|
123
|
+
const { getFormValues } = renderDeathInfoSectionWithFormik([]);
|
|
124
|
+
|
|
125
|
+
const checkbox = screen.getByRole('checkbox', { name: /is dead/i });
|
|
126
|
+
expect(checkbox).not.toBeChecked();
|
|
127
|
+
expect(getFormValues().isDead).toBe(false);
|
|
128
|
+
|
|
129
|
+
// Check the checkbox
|
|
130
|
+
await user.click(checkbox);
|
|
131
|
+
|
|
132
|
+
expect(checkbox).toBeChecked();
|
|
133
|
+
expect(getFormValues().isDead).toBe(true);
|
|
43
134
|
|
|
44
|
-
|
|
45
|
-
|
|
135
|
+
// Uncheck the checkbox
|
|
136
|
+
await user.click(checkbox);
|
|
137
|
+
await waitFor(() => {
|
|
138
|
+
expect(checkbox).not.toBeChecked();
|
|
139
|
+
});
|
|
140
|
+
expect(getFormValues().isDead).toBe(false);
|
|
141
|
+
});
|
|
46
142
|
});
|
|
47
143
|
});
|