@kenyaemr/esm-patient-registration-app 7.0.3-pre.89 → 8.0.0

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 (89) hide show
  1. package/.turbo/turbo-build.log +16 -15
  2. package/dist/130.js +1 -1
  3. package/dist/130.js.map +1 -1
  4. package/dist/271.js +1 -1
  5. package/dist/319.js +1 -1
  6. package/dist/460.js +1 -1
  7. package/dist/564.js +1 -0
  8. package/dist/564.js.map +1 -0
  9. package/dist/623.js +1 -0
  10. package/dist/623.js.map +1 -0
  11. package/dist/644.js +1 -1
  12. package/dist/757.js +1 -1
  13. package/dist/788.js +1 -1
  14. package/dist/807.js +1 -1
  15. package/dist/831.js +2 -0
  16. package/dist/831.js.map +1 -0
  17. package/dist/833.js +1 -1
  18. package/dist/kenyaemr-esm-patient-registration-app.js +1 -1
  19. package/dist/kenyaemr-esm-patient-registration-app.js.buildmanifest.json +99 -99
  20. package/dist/main.js +1 -1
  21. package/dist/main.js.map +1 -1
  22. package/dist/routes.json +1 -1
  23. package/package.json +2 -3
  24. package/src/add-patient-link.test.tsx +5 -9
  25. package/src/config-schema.ts +2 -0
  26. package/src/nav-link.test.tsx +3 -3
  27. package/src/patient-registration/field/address/address-field.component.tsx +2 -2
  28. package/src/patient-registration/field/address/address-hierarchy-levels.component.tsx +16 -18
  29. package/src/patient-registration/field/address/address-search.scss +5 -5
  30. package/src/patient-registration/field/address/tests/address-hierarchy.test.tsx +165 -95
  31. package/src/patient-registration/field/address/tests/address-search-component.test.tsx +18 -17
  32. package/src/patient-registration/field/dob/dob.component.tsx +3 -6
  33. package/src/patient-registration/field/dob/dob.test.tsx +69 -53
  34. package/src/patient-registration/field/field.scss +30 -25
  35. package/src/patient-registration/field/field.test.tsx +50 -52
  36. package/src/patient-registration/field/gender/gender-field.component.tsx +2 -2
  37. package/src/patient-registration/field/gender/gender-field.test.tsx +45 -27
  38. package/src/patient-registration/field/id/id-field.component.tsx +11 -12
  39. package/src/patient-registration/field/id/id-field.test.tsx +64 -49
  40. package/src/patient-registration/field/id/identifier-selection.scss +12 -8
  41. package/src/patient-registration/field/name/name-field.component.tsx +1 -1
  42. package/src/patient-registration/field/obs/obs-field.component.tsx +7 -12
  43. package/src/patient-registration/field/obs/obs-field.test.tsx +98 -62
  44. package/src/patient-registration/field/person-attributes/coded-person-attribute-field.test.tsx +9 -6
  45. package/src/patient-registration/field/person-attributes/person-attribute-field.test.tsx +49 -51
  46. package/src/patient-registration/field/person-attributes/text-person-attribute-field.test.tsx +2 -0
  47. package/src/patient-registration/input/basic-input/select/select-input.test.tsx +1 -1
  48. package/src/patient-registration/input/custom-input/autosuggest/autosuggest.scss +5 -5
  49. package/src/patient-registration/input/custom-input/autosuggest/autosuggest.test.tsx +75 -33
  50. package/src/patient-registration/input/custom-input/identifier/identifier-input.component.tsx +3 -1
  51. package/src/patient-registration/input/custom-input/identifier/identifier-input.test.tsx +9 -12
  52. package/src/patient-registration/input/dummy-data/dummy-data-input.test.tsx +2 -11
  53. package/src/patient-registration/input/input.scss +12 -12
  54. package/src/patient-registration/patient-registration-context.ts +6 -6
  55. package/src/patient-registration/patient-registration-utils.ts +4 -5
  56. package/src/patient-registration/patient-registration.component.tsx +4 -14
  57. package/src/patient-registration/patient-registration.resource.test.tsx +0 -4
  58. package/src/patient-registration/patient-registration.scss +11 -25
  59. package/src/patient-registration/patient-registration.test.tsx +75 -85
  60. package/src/patient-registration/patient-registration.types.ts +18 -18
  61. package/src/patient-registration/section/death-info/death-info-section.test.tsx +1 -10
  62. package/src/patient-registration/section/demographics/demographics-section.test.tsx +32 -29
  63. package/src/patient-registration/section/patient-relationships/relationships-section.test.tsx +16 -6
  64. package/src/patient-registration/section/patient-relationships/relationships.scss +4 -4
  65. package/src/patient-registration/section/section-wrapper.component.tsx +1 -1
  66. package/src/patient-registration/section/section.scss +16 -1
  67. package/src/patient-registration/ui-components/overlay/overlay.scss +8 -8
  68. package/src/patient-registration/validation/patient-registration-validation.test.tsx +35 -10
  69. package/src/patient-verification/patient-verification-utils.ts +0 -1
  70. package/src/widgets/cancel-patient-edit.test.tsx +0 -4
  71. package/src/widgets/delete-identifier-confirmation.scss +8 -8
  72. package/src/widgets/delete-identifier-confirmation.test.tsx +0 -4
  73. package/src/widgets/edit-patient-details-button.test.tsx +2 -8
  74. package/translations/am.json +4 -0
  75. package/translations/ar.json +4 -0
  76. package/translations/es.json +4 -0
  77. package/translations/fr.json +4 -0
  78. package/translations/he.json +4 -0
  79. package/translations/km.json +4 -0
  80. package/translations/zh.json +4 -0
  81. package/translations/zh_CN.json +4 -0
  82. package/dist/220.js +0 -2
  83. package/dist/220.js.map +0 -1
  84. package/dist/453.js +0 -1
  85. package/dist/453.js.map +0 -1
  86. package/dist/975.js +0 -1
  87. package/dist/975.js.map +0 -1
  88. package/src/root.test.tsx +0 -32
  89. /package/dist/{220.js.LICENSE.txt → 831.js.LICENSE.txt} +0 -0
package/dist/routes.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":"^2.24.0"},"pages":[{"component":"root","route":"patient-registration","online":true,"offline":true},{"component":"editPatient","routeRegex":"patient\\/([a-zA-Z0-9\\-]+)\\/edit","online":true,"offline":true}],"extensions":[{"component":"addPatientLink","name":"add-patient-action","slot":"top-nav-actions-slot","online":true,"offline":true},{"component":"cancelPatientEditModal","name":"cancel-patient-edit-modal","online":true,"offline":true},{"component":"patientPhotoExtension","name":"patient-photo-widget","slot":"patient-photo-slot","online":true,"offline":true},{"component":"editPatientDetailsButton","name":"edit-patient-details-button","slot":"patient-actions-slot","online":true,"offline":true},{"component":"editPatientDetailsButton","name":"edit-patient-details-button","slot":"patient-search-actions-slot","online":true,"offline":true},{"component":"deleteIdentifierConfirmationModal","name":"delete-identifier-confirmation-modal","online":true,"offline":true},{"component":"emptyClientRegistryModal","name":"empty-client-registry-modal","online":true,"offline":true},{"component":"confirmClientRegistryModal","name":"confirm-client-registry-modal","online":true,"offline":true}],"version":"7.0.3-pre.89"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":"^2.24.0"},"pages":[{"component":"root","route":"patient-registration","online":true,"offline":true},{"component":"editPatient","routeRegex":"patient\\/([a-zA-Z0-9\\-]+)\\/edit","online":true,"offline":true}],"extensions":[{"component":"addPatientLink","name":"add-patient-action","slot":"top-nav-actions-slot","online":true,"offline":true},{"component":"cancelPatientEditModal","name":"cancel-patient-edit-modal","online":true,"offline":true},{"component":"patientPhotoExtension","name":"patient-photo-widget","slot":"patient-photo-slot","online":true,"offline":true},{"component":"editPatientDetailsButton","name":"edit-patient-details-button","slot":"patient-actions-slot","online":true,"offline":true},{"component":"editPatientDetailsButton","name":"edit-patient-details-button","slot":"patient-search-actions-slot","online":true,"offline":true},{"component":"deleteIdentifierConfirmationModal","name":"delete-identifier-confirmation-modal","online":true,"offline":true},{"component":"emptyClientRegistryModal","name":"empty-client-registry-modal","online":true,"offline":true},{"component":"confirmClientRegistryModal","name":"confirm-client-registry-modal","online":true,"offline":true}],"version":"8.0.0"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenyaemr/esm-patient-registration-app",
3
- "version": "7.0.3-pre.89",
3
+ "version": "8.0.0",
4
4
  "description": "Patient registration microfrontend for the OpenMRS SPA",
5
5
  "browser": "dist/kenyaemr-esm-patient-registration-app.js",
6
6
  "main": "src/index.ts",
@@ -53,6 +53,5 @@
53
53
  },
54
54
  "devDependencies": {
55
55
  "webpack": "^5.74.0"
56
- },
57
- "stableVersion": "7.0.2"
56
+ }
58
57
  }
@@ -1,20 +1,16 @@
1
1
  import React from 'react';
2
2
  import userEvent from '@testing-library/user-event';
3
- import { render } from '@testing-library/react';
3
+ import { render, screen } from '@testing-library/react';
4
4
  import { navigate } from '@openmrs/esm-framework';
5
5
  import Root from './add-patient-link';
6
6
 
7
- const mockedNavigate = navigate as jest.Mock;
7
+ const mockNavigate = jest.mocked(navigate);
8
8
 
9
9
  describe('Add patient link component', () => {
10
10
  it('renders an "Add Patient" button and triggers navigation on click', async () => {
11
11
  const user = userEvent.setup();
12
-
13
- const { getByRole } = render(<Root />);
14
- const addButton = getByRole('button', { name: /add patient/i });
15
-
16
- await user.click(addButton);
17
-
18
- expect(mockedNavigate).toHaveBeenCalledWith({ to: '${openmrsSpaBase}/patient-registration' });
12
+ render(<Root />);
13
+ await user.click(screen.getByRole('button', { name: /add patient/i }));
14
+ expect(mockNavigate).toHaveBeenCalledWith({ to: '${openmrsSpaBase}/patient-registration' });
19
15
  });
20
16
  });
@@ -26,10 +26,12 @@ export interface FieldDefinition {
26
26
  };
27
27
  renderType?: string;
28
28
  }
29
+
29
30
  export interface CustomConceptAnswer {
30
31
  uuid: string;
31
32
  label?: string;
32
33
  }
34
+
33
35
  export interface Gender {
34
36
  label?: string;
35
37
  value: string;
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
- import { render } from '@testing-library/react';
2
+ import { render, screen } from '@testing-library/react';
3
3
  import Root from './nav-link';
4
4
 
5
5
  describe('Nav link component', () => {
6
6
  it('renders a link to the patient registration page', () => {
7
- const { getByText } = render(<Root />);
8
- const linkElement = getByText('Patient Registration');
7
+ render(<Root />);
8
+ const linkElement = screen.getByText('Patient Registration');
9
9
 
10
10
  expect(linkElement).toBeInTheDocument();
11
11
  expect(linkElement).toHaveAttribute('href', '/openmrs/spa/patient-registration');
@@ -70,10 +70,10 @@ export const AddressComponent: React.FC = () => {
70
70
  );
71
71
  }, [isLoadingFieldOrder, errorFetchingFieldOrder, orderedFields, addressLayout]);
72
72
 
73
- if (!addressTemplate) {
73
+ if (addressTemplate && !Object.keys(addressTemplate)?.length) {
74
74
  return (
75
75
  <AddressComponentContainer>
76
- <SkeletonText />
76
+ <SkeletonText role="progressbar" />
77
77
  </AddressComponentContainer>
78
78
  );
79
79
  }
@@ -4,24 +4,6 @@ import { useAddressEntries, useAddressEntryFetchConfig } from './address-hierarc
4
4
  import { useField } from 'formik';
5
5
  import ComboInput from '../../input/combo-input/combo-input.component';
6
6
 
7
- interface AddressHierarchyLevelsProps {
8
- orderedAddressFields: Array<any>;
9
- }
10
-
11
- const AddressHierarchyLevels: React.FC<AddressHierarchyLevelsProps> = ({ orderedAddressFields }) => {
12
- const { t } = useTranslation();
13
-
14
- return (
15
- <>
16
- {orderedAddressFields.map((attribute) => (
17
- <AddressComboBox key={attribute.id} attribute={attribute} />
18
- ))}
19
- </>
20
- );
21
- };
22
-
23
- export default AddressHierarchyLevels;
24
-
25
7
  interface AddressComboBoxProps {
26
8
  attribute: {
27
9
  id: string;
@@ -32,6 +14,10 @@ interface AddressComboBoxProps {
32
14
  };
33
15
  }
34
16
 
17
+ interface AddressHierarchyLevelsProps {
18
+ orderedAddressFields: Array<any>;
19
+ }
20
+
35
21
  const AddressComboBox: React.FC<AddressComboBoxProps> = ({ attribute }) => {
36
22
  const { t } = useTranslation();
37
23
  const [field, meta, { setValue }] = useField(`address.${attribute.name}`);
@@ -71,3 +57,15 @@ const AddressComboBox: React.FC<AddressComboBoxProps> = ({ attribute }) => {
71
57
  />
72
58
  );
73
59
  };
60
+
61
+ const AddressHierarchyLevels: React.FC<AddressHierarchyLevelsProps> = ({ orderedAddressFields }) => {
62
+ return (
63
+ <>
64
+ {orderedAddressFields.map((attribute) => (
65
+ <AddressComboBox key={attribute.id} attribute={attribute} />
66
+ ))}
67
+ </>
68
+ );
69
+ };
70
+
71
+ export default AddressHierarchyLevels;
@@ -1,6 +1,6 @@
1
- @use '@carbon/styles/scss/spacing';
2
- @use '@carbon/styles/scss/type';
3
- @import '~@openmrs/esm-styleguide/src/vars';
1
+ @use '@carbon/layout';
2
+ @use '@carbon/type';
3
+ @use '@openmrs/esm-styleguide/src/vars' as *;
4
4
 
5
5
  .label01 {
6
6
  @include type.type-style('label-01');
@@ -17,13 +17,13 @@
17
17
  position: absolute;
18
18
  left: 0;
19
19
  background-color: #fff;
20
- margin-bottom: 20px;
20
+ margin-bottom: 1.25rem;
21
21
  z-index: 99;
22
22
  border: 1px solid $ui-03;
23
23
  }
24
24
 
25
25
  .suggestions li {
26
- padding: spacing.$spacing-05;
26
+ padding: layout.$spacing-05;
27
27
  line-height: 1.29;
28
28
  color: #525252;
29
29
  border-bottom: 1px solid #8d8d8d;
@@ -1,40 +1,75 @@
1
1
  import React from 'react';
2
- import { cleanup, render, screen } from '@testing-library/react';
3
- import { AddressComponent } from '../address-field.component';
2
+ import { render, screen } from '@testing-library/react';
4
3
  import { Formik, Form } from 'formik';
4
+ import { getDefaultsFromConfigSchema, useConfig } from '@openmrs/esm-framework';
5
+ import { mockedAddressTemplate, mockedOrderedFields, mockOpenmrsId, mockPatient, mockSession } from '__mocks__';
6
+ import { type AddressTemplate } from '../../../patient-registration.types';
7
+ import { type RegistrationConfig, esmPatientRegistrationSchema } from '../../../../config-schema';
5
8
  import { type Resources, ResourcesContext } from '../../../../offline.resources';
6
- import { PatientRegistrationContext } from '../../../patient-registration-context';
7
- import { useConfig } from '@openmrs/esm-framework';
9
+ import {
10
+ PatientRegistrationContext,
11
+ type PatientRegistrationContextProps,
12
+ } from '../../../patient-registration-context';
8
13
  import { useOrderedAddressHierarchyLevels } from '../address-hierarchy.resource';
9
- import { mockedAddressTemplate, mockedOrderedFields } from '__mocks__';
10
-
11
- // Mocking the AddressSearchComponent
12
- jest.mock('../address-search.component', () => jest.fn(() => <div data-testid="address-search-bar" />));
13
- // Mocking the AddressHierarchyLevels
14
- jest.mock('../address-hierarchy-levels.component', () => jest.fn(() => <div data-testid="address-hierarchy-levels" />));
15
- // Mocking the SkeletonText
16
- jest.mock('@carbon/react', () => ({
17
- ...jest.requireActual('@carbon/react'),
18
- SkeletonText: jest.fn(() => <div data-testid="skeleton-text" />),
19
- InlineNotification: jest.fn(() => <div data-testid="inline-notification" />),
20
- }));
14
+ import { AddressComponent } from '../address-field.component';
21
15
 
22
- jest.mock('@openmrs/esm-framework', () => ({
23
- ...jest.requireActual('@openmrs/esm-framework'),
24
- useConfig: jest.fn(),
25
- }));
16
+ const mockUseConfig = jest.mocked(useConfig<RegistrationConfig>);
17
+ const mockUseOrderedAddressHierarchyLevels = jest.mocked(useOrderedAddressHierarchyLevels);
18
+
19
+ const mockResourcesContextValue = {
20
+ addressTemplate: {} as AddressTemplate,
21
+ currentSession: mockSession.data,
22
+ identifierTypes: [],
23
+ relationshipTypes: [],
24
+ } as Resources;
25
+
26
+ const mockInitialFormValues = {
27
+ additionalFamilyName: '',
28
+ additionalGivenName: '',
29
+ additionalMiddleName: '',
30
+ addNameInLocalLanguage: false,
31
+ address: {},
32
+ birthdate: '',
33
+ birthdateEstimated: false,
34
+ deathCause: '',
35
+ deathDate: '',
36
+ familyName: 'Doe',
37
+ gender: 'male',
38
+ givenName: 'John',
39
+ identifiers: mockOpenmrsId,
40
+ isDead: false,
41
+ middleName: 'Test',
42
+ monthsEstimated: 0,
43
+ patientUuid: mockPatient.uuid,
44
+ relationships: [],
45
+ telephoneNumber: '',
46
+ yearsEstimated: 0,
47
+ };
48
+
49
+ const initialContextValues: PatientRegistrationContextProps = {
50
+ currentPhoto: '',
51
+ inEditMode: false,
52
+ identifierTypes: [],
53
+ initialFormValues: mockInitialFormValues,
54
+ isOffline: false,
55
+ setCapturePhotoProps: jest.fn(),
56
+ setFieldValue: jest.fn(),
57
+ setInitialFormValues: jest.fn(),
58
+ validationSchema: null,
59
+ values: mockInitialFormValues,
60
+ };
26
61
 
27
62
  jest.mock('../address-hierarchy.resource', () => ({
28
- ...(jest.requireActual('../address-hierarchy.resource') as jest.Mock),
63
+ ...jest.requireActual('../address-hierarchy.resource'),
29
64
  useOrderedAddressHierarchyLevels: jest.fn(),
30
65
  }));
31
66
 
32
- async function renderAddressHierarchy(addressTemplate = mockedAddressTemplate) {
67
+ async function renderAddressHierarchy(contextValues: PatientRegistrationContextProps) {
33
68
  await render(
34
- <ResourcesContext.Provider value={{ addressTemplate } as unknown as Resources}>
35
- <Formik initialValues={{}} onSubmit={null}>
69
+ <ResourcesContext.Provider value={mockResourcesContextValue}>
70
+ <Formik initialValues={mockInitialFormValues} onSubmit={null}>
36
71
  <Form>
37
- <PatientRegistrationContext.Provider value={{ setFieldValue: jest.fn() } as any}>
72
+ <PatientRegistrationContext.Provider value={contextValues}>
38
73
  <AddressComponent />
39
74
  </PatientRegistrationContext.Provider>
40
75
  </Form>
@@ -43,11 +78,10 @@ async function renderAddressHierarchy(addressTemplate = mockedAddressTemplate) {
43
78
  );
44
79
  }
45
80
 
46
- describe('Testing address hierarchy', () => {
47
- beforeEach(cleanup);
48
-
49
- it('should render skeleton when address template is loading', () => {
50
- (useConfig as jest.Mock).mockImplementation(() => ({
81
+ describe('Address hierarchy', () => {
82
+ it('renders a loading skeleton when the address template is loading', () => {
83
+ mockUseConfig.mockReturnValue({
84
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
51
85
  fieldConfigurations: {
52
86
  address: {
53
87
  useAddressHierarchy: {
@@ -56,21 +90,22 @@ describe('Testing address hierarchy', () => {
56
90
  searchAddressByLevel: false,
57
91
  },
58
92
  },
59
- },
60
- }));
61
- (useOrderedAddressHierarchyLevels as jest.Mock).mockImplementation(() => ({
93
+ } as RegistrationConfig['fieldConfigurations'],
94
+ });
95
+
96
+ mockUseOrderedAddressHierarchyLevels.mockReturnValue({
62
97
  orderedFields: [],
63
98
  isLoadingFieldOrder: false,
64
- errorFetchingFieldOrder: null,
65
- }));
66
- // @ts-ignore
67
- renderAddressHierarchy(null);
68
- const skeletonText = screen.getByTestId('skeleton-text');
69
- expect(skeletonText).toBeInTheDocument();
99
+ errorFetchingFieldOrder: undefined,
100
+ });
101
+
102
+ renderAddressHierarchy(initialContextValues);
103
+ expect(screen.getByRole('progressbar')).toBeInTheDocument();
70
104
  });
71
105
 
72
- it('should render skeleton when address hierarchy is enabled and addresshierarchy order is loading', () => {
73
- (useConfig as jest.Mock).mockImplementation(() => ({
106
+ it('renders a loading skeleton when the address hierarchy feature is enabled and address hierarchy order levels are loading', () => {
107
+ mockUseConfig.mockReturnValue({
108
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
74
109
  fieldConfigurations: {
75
110
  address: {
76
111
  useAddressHierarchy: {
@@ -79,20 +114,22 @@ describe('Testing address hierarchy', () => {
79
114
  searchAddressByLevel: false,
80
115
  },
81
116
  },
82
- },
83
- }));
84
- (useOrderedAddressHierarchyLevels as jest.Mock).mockImplementation(() => ({
117
+ } as RegistrationConfig['fieldConfigurations'],
118
+ });
119
+
120
+ mockUseOrderedAddressHierarchyLevels.mockReturnValue({
85
121
  orderedFields: [],
86
122
  isLoadingFieldOrder: true,
87
- errorFetchingFieldOrder: null,
88
- }));
89
- renderAddressHierarchy();
90
- const skeletonText = screen.getByTestId('skeleton-text');
91
- expect(skeletonText).toBeInTheDocument();
123
+ errorFetchingFieldOrder: undefined,
124
+ });
125
+
126
+ renderAddressHierarchy(initialContextValues);
127
+ expect(screen.getByRole('progressbar')).toBeInTheDocument();
92
128
  });
93
129
 
94
- it('should render skeleton when address hierarchy is enabled and addresshierarchy order is loading', () => {
95
- (useConfig as jest.Mock).mockImplementation(() => ({
130
+ it('renders a loading skeleton when the address hierarchy feature is enabled and address hierarchy order levels are loading', () => {
131
+ mockUseConfig.mockReturnValue({
132
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
96
133
  fieldConfigurations: {
97
134
  address: {
98
135
  useAddressHierarchy: {
@@ -101,20 +138,22 @@ describe('Testing address hierarchy', () => {
101
138
  searchAddressByLevel: false,
102
139
  },
103
140
  },
104
- },
105
- }));
106
- (useOrderedAddressHierarchyLevels as jest.Mock).mockImplementation(() => ({
141
+ } as RegistrationConfig['fieldConfigurations'],
142
+ });
143
+
144
+ mockUseOrderedAddressHierarchyLevels.mockReturnValue({
107
145
  orderedFields: [],
108
146
  isLoadingFieldOrder: false,
109
- errorFetchingFieldOrder: true,
110
- }));
111
- renderAddressHierarchy();
112
- const inlineNotification = screen.getByTestId('inline-notification');
113
- expect(inlineNotification).toBeInTheDocument();
147
+ errorFetchingFieldOrder: undefined,
148
+ });
149
+
150
+ renderAddressHierarchy(initialContextValues);
151
+ expect(screen.getByRole('progressbar')).toBeInTheDocument();
114
152
  });
115
153
 
116
- it('should render the address component with address hierarchy disabled', () => {
117
- (useConfig as jest.Mock).mockImplementation(() => ({
154
+ it('renders the address component with address hierarchy disabled', () => {
155
+ mockUseConfig.mockReturnValue({
156
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
118
157
  fieldConfigurations: {
119
158
  address: {
120
159
  useAddressHierarchy: {
@@ -123,14 +162,19 @@ describe('Testing address hierarchy', () => {
123
162
  searchAddressByLevel: false,
124
163
  },
125
164
  },
126
- },
127
- }));
128
- (useOrderedAddressHierarchyLevels as jest.Mock).mockImplementation(() => ({
165
+ } as RegistrationConfig['fieldConfigurations'],
166
+ });
167
+
168
+ mockUseOrderedAddressHierarchyLevels.mockReturnValue({
129
169
  orderedFields: [],
130
170
  isLoadingFieldOrder: false,
131
- errorFetchingFieldOrder: null,
132
- }));
133
- renderAddressHierarchy();
171
+ errorFetchingFieldOrder: undefined,
172
+ });
173
+
174
+ mockResourcesContextValue.addressTemplate = mockedAddressTemplate;
175
+
176
+ renderAddressHierarchy(initialContextValues);
177
+
134
178
  const allFields = mockedAddressTemplate.lines.flat().filter(({ isToken }) => isToken === 'IS_ADDR_TOKEN');
135
179
  allFields.forEach((field) => {
136
180
  const textFieldInput = screen.getByLabelText(`${field.displayText} (optional)`);
@@ -138,8 +182,9 @@ describe('Testing address hierarchy', () => {
138
182
  });
139
183
  });
140
184
 
141
- it('should render the fields in order if the address hierarcy is enabled', () => {
142
- (useConfig as jest.Mock).mockImplementation(() => ({
185
+ it('renders the address hierarchy fields in order if the address hierarchy feature is enabled', () => {
186
+ mockUseConfig.mockReturnValue({
187
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
143
188
  fieldConfigurations: {
144
189
  address: {
145
190
  useAddressHierarchy: {
@@ -148,14 +193,19 @@ describe('Testing address hierarchy', () => {
148
193
  searchAddressByLevel: false,
149
194
  },
150
195
  },
151
- },
152
- }));
153
- (useOrderedAddressHierarchyLevels as jest.Mock).mockImplementation(() => ({
196
+ } as RegistrationConfig['fieldConfigurations'],
197
+ });
198
+
199
+ mockUseOrderedAddressHierarchyLevels.mockReturnValue({
154
200
  orderedFields: [],
155
201
  isLoadingFieldOrder: false,
156
- errorFetchingFieldOrder: null,
157
- }));
158
- renderAddressHierarchy();
202
+ errorFetchingFieldOrder: undefined,
203
+ });
204
+
205
+ mockResourcesContextValue.addressTemplate = mockedAddressTemplate;
206
+
207
+ renderAddressHierarchy(initialContextValues);
208
+
159
209
  const allFields = mockedAddressTemplate.lines.flat().filter(({ isToken }) => isToken === 'IS_ADDR_TOKEN');
160
210
  const orderMap = Object.fromEntries(mockedOrderedFields.map((field, indx) => [field, indx]));
161
211
  allFields.sort(
@@ -168,8 +218,9 @@ describe('Testing address hierarchy', () => {
168
218
  });
169
219
  });
170
220
 
171
- it('should render quick search bar on above the fields when address hierarchy is enabled and quicksearch is set to true', () => {
172
- (useConfig as jest.Mock).mockImplementation(() => ({
221
+ it('renders the quick search bar above the address hierarchy fields when the address hierarchy feature is enabled and useQuickSearch is set to true', () => {
222
+ mockUseConfig.mockReturnValue({
223
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
173
224
  fieldConfigurations: {
174
225
  address: {
175
226
  useAddressHierarchy: {
@@ -178,20 +229,26 @@ describe('Testing address hierarchy', () => {
178
229
  searchAddressByLevel: false,
179
230
  },
180
231
  },
181
- },
182
- }));
183
- (useOrderedAddressHierarchyLevels as jest.Mock).mockImplementation(() => ({
232
+ } as RegistrationConfig['fieldConfigurations'],
233
+ });
234
+
235
+ mockUseOrderedAddressHierarchyLevels.mockReturnValue({
184
236
  orderedFields: [],
185
237
  isLoadingFieldOrder: false,
186
- errorFetchingFieldOrder: null,
187
- }));
188
- renderAddressHierarchy();
189
- const addressSearchBar = screen.getByTestId('address-search-bar');
190
- expect(addressSearchBar).toBeInTheDocument();
238
+ errorFetchingFieldOrder: undefined,
239
+ });
240
+
241
+ mockResourcesContextValue.addressTemplate = mockedAddressTemplate;
242
+
243
+ renderAddressHierarchy(initialContextValues);
244
+
245
+ const searchbox = screen.getByRole('searchbox', { name: /search address/i });
246
+ expect(searchbox).toBeInTheDocument();
191
247
  });
192
248
 
193
- it('should render combo boxes fields when address hierarchy is enabled and searchAddressByLevel is set to true', () => {
194
- (useConfig as jest.Mock).mockImplementation(() => ({
249
+ it('renders combobox fields when address hierarchy is enabled and searchAddressByLevel is set to true', () => {
250
+ mockUseConfig.mockReturnValue({
251
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
195
252
  fieldConfigurations: {
196
253
  address: {
197
254
  useAddressHierarchy: {
@@ -200,15 +257,28 @@ describe('Testing address hierarchy', () => {
200
257
  searchAddressByLevel: true,
201
258
  },
202
259
  },
203
- },
204
- }));
205
- (useOrderedAddressHierarchyLevels as jest.Mock).mockImplementation(() => ({
260
+ } as RegistrationConfig['fieldConfigurations'],
261
+ });
262
+
263
+ mockUseOrderedAddressHierarchyLevels.mockReturnValue({
206
264
  orderedFields: [],
207
265
  isLoadingFieldOrder: false,
208
- errorFetchingFieldOrder: null,
209
- }));
210
- renderAddressHierarchy();
211
- const addressHierarchyLevels = screen.getByTestId('address-hierarchy-levels');
212
- expect(addressHierarchyLevels).toBeInTheDocument();
266
+ errorFetchingFieldOrder: undefined,
267
+ });
268
+
269
+ mockResourcesContextValue.addressTemplate = mockedAddressTemplate;
270
+
271
+ renderAddressHierarchy(initialContextValues);
272
+
273
+ const allFields = mockedAddressTemplate.lines.flat().filter(({ isToken }) => isToken === 'IS_ADDR_TOKEN');
274
+ const orderMap = Object.fromEntries(mockedOrderedFields.map((field, indx) => [field, indx]));
275
+ allFields.sort(
276
+ (existingField1, existingField2) =>
277
+ orderMap[existingField1.codeName ?? 0] - orderMap[existingField2.codeName ?? 0],
278
+ );
279
+ allFields.forEach((field) => {
280
+ const textFieldInput = screen.getByLabelText(`${field.displayText} (optional)`);
281
+ expect(textFieldInput).toBeInTheDocument();
282
+ });
213
283
  });
214
284
  });
@@ -4,16 +4,16 @@ import { render, screen } from '@testing-library/react';
4
4
  import { Formik, Form, useFormikContext } from 'formik';
5
5
  import { type Resources, ResourcesContext } from '../../../../offline.resources';
6
6
  import { PatientRegistrationContext } from '../../../patient-registration-context';
7
- import { useConfig } from '@openmrs/esm-framework';
7
+ import { getDefaultsFromConfigSchema, useConfig } from '@openmrs/esm-framework';
8
8
  import { useAddressHierarchy, useOrderedAddressHierarchyLevels } from '../address-hierarchy.resource';
9
+ import { type RegistrationConfig, esmPatientRegistrationSchema } from '../../../../config-schema';
9
10
  import { mockedAddressTemplate, mockedAddressOptions, mockedOrderedFields } from '__mocks__';
10
11
  import AddressSearchComponent from '../address-search.component';
11
12
 
12
- useAddressHierarchy;
13
- jest.mock('@openmrs/esm-framework', () => ({
14
- ...jest.requireActual('@openmrs/esm-framework'),
15
- useConfig: jest.fn(),
16
- }));
13
+ const mockUseConfig = jest.mocked(useConfig<RegistrationConfig>);
14
+ const mockUseAddressHierarchy = jest.mocked(useAddressHierarchy);
15
+ const mockUseOrderedAddressHierarchyLevels = jest.mocked(useOrderedAddressHierarchyLevels);
16
+ const mockUseFormikContext = useFormikContext as jest.Mock;
17
17
 
18
18
  jest.mock('../address-hierarchy.resource', () => ({
19
19
  ...(jest.requireActual('../address-hierarchy.resource') as jest.Mock),
@@ -60,7 +60,8 @@ const setFieldValue = jest.fn();
60
60
 
61
61
  describe('Testing address search bar', () => {
62
62
  beforeEach(() => {
63
- (useConfig as jest.Mock).mockImplementation(() => ({
63
+ mockUseConfig.mockReturnValue({
64
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
64
65
  fieldConfigurations: {
65
66
  address: {
66
67
  useAddressHierarchy: {
@@ -69,24 +70,24 @@ describe('Testing address search bar', () => {
69
70
  searchAddressByLevel: false,
70
71
  },
71
72
  },
72
- },
73
- }));
74
- (useOrderedAddressHierarchyLevels as jest.Mock).mockImplementation(() => ({
73
+ } as RegistrationConfig['fieldConfigurations'],
74
+ });
75
+ mockUseOrderedAddressHierarchyLevels.mockReturnValue({
75
76
  orderedFields: mockedOrderedFields,
76
77
  isLoadingFieldOrder: false,
77
78
  errorFetchingFieldOrder: null,
78
- }));
79
- (useFormikContext as jest.Mock).mockImplementation(() => ({
79
+ });
80
+ mockUseFormikContext.mockReturnValue({
80
81
  setFieldValue,
81
- }));
82
+ });
82
83
  });
83
84
 
84
85
  it('should render the search bar', () => {
85
- (useAddressHierarchy as jest.Mock).mockImplementation(() => ({
86
+ mockUseAddressHierarchy.mockReturnValue({
86
87
  addresses: [],
87
88
  error: null,
88
89
  isLoading: false,
89
- }));
90
+ });
90
91
 
91
92
  renderAddressHierarchy();
92
93
 
@@ -100,11 +101,11 @@ describe('Testing address search bar', () => {
100
101
  it("should render only the results for the search term matched address' parents", async () => {
101
102
  const user = userEvent.setup();
102
103
 
103
- (useAddressHierarchy as jest.Mock).mockImplementation(() => ({
104
+ mockUseAddressHierarchy.mockReturnValue({
104
105
  addresses: mockedAddressOptions,
105
106
  error: null,
106
107
  isLoading: false,
107
- }));
108
+ });
108
109
 
109
110
  renderAddressHierarchy();
110
111
 
@@ -2,7 +2,6 @@ import React, { type ChangeEvent, useCallback, useContext } from 'react';
2
2
  import { ContentSwitcher, Layer, Switch, TextInput } from '@carbon/react';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import { useField } from 'formik';
5
- import { type CalendarDate, getLocalTimeZone } from '@internationalized/date';
6
5
  import { PatientRegistrationContext } from '../../patient-registration-context';
7
6
  import { OpenmrsDatePicker, useConfig } from '@openmrs/esm-framework';
8
7
  import { type RegistrationConfig } from '../../../config-schema';
@@ -45,8 +44,8 @@ export const DobField: React.FC = () => {
45
44
  );
46
45
 
47
46
  const onDateChange = useCallback(
48
- (birthdate: CalendarDate) => {
49
- setFieldValue('birthdate', birthdate?.toDate(getLocalTimeZone()));
47
+ (birthdate: Date) => {
48
+ setFieldValue('birthdate', birthdate);
50
49
  },
51
50
  [setFieldValue],
52
51
  );
@@ -107,11 +106,9 @@ export const DobField: React.FC = () => {
107
106
  maxDate={today}
108
107
  labelText={t('dateOfBirthLabelText', 'Date of Birth')}
109
108
  isInvalid={!!(birthdateMeta.touched && birthdateMeta.error)}
109
+ invalidText={t(birthdateMeta.error)}
110
110
  value={birthdate.value}
111
111
  />
112
- {!!(birthdateMeta.touched && birthdateMeta.error) && (
113
- <div className={styles.radioFieldError}>{birthdateMeta.error && t(birthdateMeta.error)}</div>
114
- )}
115
112
  </div>
116
113
  ) : (
117
114
  <div className={styles.grid}>