@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.
Files changed (342) hide show
  1. package/dist/1339.js +1 -0
  2. package/dist/1339.js.map +1 -0
  3. package/dist/1480.js +1 -0
  4. package/dist/1480.js.map +1 -0
  5. package/dist/1646.js +1 -0
  6. package/dist/1646.js.map +1 -0
  7. package/dist/1789.js +1 -0
  8. package/dist/1789.js.map +1 -0
  9. package/dist/1869.js +1 -0
  10. package/dist/1869.js.map +1 -0
  11. package/dist/1877.js +1 -0
  12. package/dist/1877.js.map +1 -0
  13. package/dist/2317.js +1 -0
  14. package/dist/2317.js.map +1 -0
  15. package/dist/2416.js +1 -0
  16. package/dist/2416.js.map +1 -0
  17. package/dist/2747.js +1 -0
  18. package/dist/2747.js.map +1 -0
  19. package/dist/282.js +1 -0
  20. package/dist/282.js.map +1 -0
  21. package/dist/2881.js +1 -0
  22. package/dist/2881.js.map +1 -0
  23. package/dist/3378.js +1 -0
  24. package/dist/3378.js.map +1 -0
  25. package/dist/3720.js +1 -0
  26. package/dist/3720.js.map +1 -0
  27. package/dist/3906.js +1 -0
  28. package/dist/3906.js.map +1 -0
  29. package/dist/3963.js +1 -0
  30. package/dist/3963.js.map +1 -0
  31. package/dist/3989.js +1 -0
  32. package/dist/3989.js.map +1 -0
  33. package/dist/4106.js +1 -0
  34. package/dist/4106.js.map +1 -0
  35. package/dist/4111.js +1 -0
  36. package/dist/4111.js.map +1 -0
  37. package/dist/434.js +1 -0
  38. package/dist/434.js.map +1 -0
  39. package/dist/4348.js +1 -0
  40. package/dist/4348.js.map +1 -0
  41. package/dist/4383.js +1 -0
  42. package/dist/4383.js.map +1 -0
  43. package/dist/4658.js +1 -0
  44. package/dist/4658.js.map +1 -0
  45. package/dist/466.js +1 -0
  46. package/dist/466.js.map +1 -0
  47. package/dist/4928.js +1 -0
  48. package/dist/4928.js.map +1 -0
  49. package/dist/5117.js +1 -0
  50. package/dist/5117.js.map +1 -0
  51. package/dist/5132.js +1 -0
  52. package/dist/5132.js.map +1 -0
  53. package/dist/5145.js +1 -0
  54. package/dist/5145.js.map +1 -0
  55. package/dist/5208.js +43 -0
  56. package/dist/5208.js.map +1 -0
  57. package/dist/527.js +1 -0
  58. package/dist/527.js.map +1 -0
  59. package/dist/5280.js +1 -0
  60. package/dist/5280.js.map +1 -0
  61. package/dist/5338.js +6 -0
  62. package/dist/5338.js.map +1 -0
  63. package/dist/5503.js +1 -0
  64. package/dist/5503.js.map +1 -0
  65. package/dist/555.js +1 -0
  66. package/dist/555.js.map +1 -0
  67. package/dist/556.js +1 -0
  68. package/dist/556.js.map +1 -0
  69. package/dist/5644.js +1 -0
  70. package/dist/5644.js.map +1 -0
  71. package/dist/5697.js +1 -0
  72. package/dist/{4024.js.map → 5697.js.map} +1 -1
  73. package/dist/5940.js +1 -0
  74. package/dist/5940.js.map +1 -0
  75. package/dist/6047.js +1 -0
  76. package/dist/6047.js.map +1 -0
  77. package/dist/6371.js +1 -0
  78. package/dist/6371.js.map +1 -0
  79. package/dist/6377.js +1 -0
  80. package/dist/6377.js.map +1 -0
  81. package/dist/6388.js +1 -0
  82. package/dist/6388.js.map +1 -0
  83. package/dist/6444.js +1 -0
  84. package/dist/6444.js.map +1 -0
  85. package/dist/6508.js +1 -0
  86. package/dist/6508.js.map +1 -0
  87. package/dist/6724.js +1 -0
  88. package/dist/6724.js.map +1 -0
  89. package/dist/689.js +1 -0
  90. package/dist/689.js.map +1 -0
  91. package/dist/6904.js +1 -0
  92. package/dist/6904.js.map +1 -0
  93. package/dist/7045.js +1 -0
  94. package/dist/7045.js.map +1 -0
  95. package/dist/7175.js +1 -0
  96. package/dist/7175.js.map +1 -0
  97. package/dist/7182.js +1 -0
  98. package/dist/7182.js.map +1 -0
  99. package/dist/7649.js +1 -0
  100. package/dist/7649.js.map +1 -0
  101. package/dist/7742.js +1 -0
  102. package/dist/7742.js.map +1 -0
  103. package/dist/7912.js +1 -0
  104. package/dist/7912.js.map +1 -0
  105. package/dist/8358.js +1 -0
  106. package/dist/8358.js.map +1 -0
  107. package/dist/8359.js +1 -0
  108. package/dist/8359.js.map +1 -0
  109. package/dist/8695.js +1 -0
  110. package/dist/8695.js.map +1 -0
  111. package/dist/903.js +1 -0
  112. package/dist/903.js.map +1 -0
  113. package/dist/9061.js +1 -0
  114. package/dist/9061.js.map +1 -0
  115. package/dist/9072.js +1 -0
  116. package/dist/9072.js.map +1 -0
  117. package/dist/9397.js +1 -0
  118. package/dist/9397.js.map +1 -0
  119. package/dist/9712.js +1 -0
  120. package/dist/9712.js.map +1 -0
  121. package/dist/9771.js +1 -0
  122. package/dist/9771.js.map +1 -0
  123. package/dist/9806.js +1 -0
  124. package/dist/9806.js.map +1 -0
  125. package/dist/9816.js +1 -0
  126. package/dist/9816.js.map +1 -0
  127. package/dist/main.js +7 -6
  128. package/dist/main.js.map +1 -1
  129. package/dist/openmrs-esm-patient-registration-app.js +6 -0
  130. package/dist/{olaboot-esm-patient-registration-app.js.buildmanifest.json → openmrs-esm-patient-registration-app.js.buildmanifest.json} +540 -455
  131. package/dist/openmrs-esm-patient-registration-app.js.map +1 -0
  132. package/dist/routes.json +1 -1
  133. package/package.json +8 -9
  134. package/src/add-patient-link.extension.tsx +3 -2
  135. package/src/add-patient-link.test.tsx +2 -1
  136. package/src/config-schema.ts +507 -507
  137. package/src/constants.ts +1 -1
  138. package/src/index.ts +2 -24
  139. package/src/nav-link.test.tsx +1 -0
  140. package/src/offline.resources.ts +97 -31
  141. package/src/patient-registration/before-save-prompt.test.tsx +199 -0
  142. package/src/patient-registration/field/__mocks__/field.resource.ts +8 -7
  143. package/src/patient-registration/field/address/address-field.component.tsx +183 -186
  144. package/src/patient-registration/field/address/address-hierarchy-levels.component.tsx +6 -1
  145. package/src/patient-registration/field/address/address-hierarchy.test.tsx +289 -296
  146. package/src/patient-registration/field/address/address-search.component.tsx +20 -8
  147. package/src/patient-registration/field/address/address-search.scss +19 -2
  148. package/src/patient-registration/field/address/address-search.test.tsx +333 -141
  149. package/src/patient-registration/field/address/custom-address-field.component.tsx +1 -1
  150. package/src/patient-registration/field/cause-of-death/cause-of-death.component.tsx +1 -1
  151. package/src/patient-registration/field/cause-of-death/cause-of-death.test.tsx +251 -0
  152. package/src/patient-registration/field/custom-field.component.tsx +1 -1
  153. package/src/patient-registration/field/date-and-time-of-death/date-and-time-of-death.component.tsx +1 -1
  154. package/src/patient-registration/field/date-and-time-of-death/date-and-time-of-death.test.tsx +144 -0
  155. package/src/patient-registration/field/dob/dob.component.tsx +2 -2
  156. package/src/patient-registration/field/dob/dob.test.tsx +370 -54
  157. package/src/patient-registration/field/field.component.tsx +1 -1
  158. package/src/patient-registration/field/field.resource.ts +2 -2
  159. package/src/patient-registration/field/field.test.tsx +333 -330
  160. package/src/patient-registration/field/gender/gender-field.test.tsx +240 -54
  161. package/src/patient-registration/field/id/id-field.component.tsx +146 -144
  162. package/src/patient-registration/field/id/id-field.test.tsx +177 -121
  163. package/src/patient-registration/field/id/identifier-selection-overlay.component.tsx +200 -200
  164. package/src/patient-registration/field/id/identifier-selection-overlay.test.tsx +346 -0
  165. package/src/patient-registration/field/name/name-field.component.tsx +2 -2
  166. package/src/patient-registration/field/name/name-field.test.tsx +282 -0
  167. package/src/patient-registration/field/obs/obs-field.test.tsx +294 -118
  168. package/src/patient-registration/field/person-attributes/coded-person-attribute-field.test.tsx +172 -108
  169. package/src/patient-registration/field/person-attributes/location-person-attribute-field.component.tsx +3 -3
  170. package/src/patient-registration/field/person-attributes/location-person-attribute-field.resource.tsx +2 -5
  171. package/src/patient-registration/field/person-attributes/person-attribute-field.component.tsx +2 -2
  172. package/src/patient-registration/field/person-attributes/person-attribute-field.test.tsx +249 -131
  173. package/src/patient-registration/field/person-attributes/person-attributes.resource.ts +1 -1
  174. package/src/patient-registration/field/person-attributes/text-person-attribute-field.test.tsx +98 -70
  175. package/src/patient-registration/field/phone/phone-field.test.tsx +100 -0
  176. package/src/patient-registration/form-manager.test.ts +6 -5
  177. package/src/patient-registration/form-manager.ts +5 -2
  178. package/src/patient-registration/input/basic-input/input/input.component.tsx +3 -121
  179. package/src/patient-registration/input/basic-input/input/input.test.tsx +151 -51
  180. package/src/patient-registration/input/basic-input/select/select-input.test.tsx +113 -33
  181. package/src/patient-registration/input/combo-input/combo-input.component.tsx +60 -24
  182. package/src/patient-registration/input/custom-input/autosuggest/autosuggest.component.tsx +10 -101
  183. package/src/patient-registration/input/custom-input/autosuggest/autosuggest.test.tsx +144 -108
  184. package/src/patient-registration/input/custom-input/identifier/identifier-input.test.tsx +241 -177
  185. package/src/patient-registration/input/custom-input/identifier/utils.test.ts +47 -8
  186. package/src/patient-registration/input/dummy-data/dummy-data-input.component.tsx +12 -12
  187. package/src/patient-registration/input/dummy-data/dummy-data-input.test.tsx +52 -20
  188. package/src/patient-registration/input/input.scss +1 -2
  189. package/src/patient-registration/patient-registration-context.ts +5 -3
  190. package/src/patient-registration/patient-registration-hooks.ts +4 -12
  191. package/src/patient-registration/patient-registration-utils.test.ts +2 -1
  192. package/src/patient-registration/patient-registration-utils.ts +2 -98
  193. package/src/patient-registration/patient-registration.component.tsx +50 -46
  194. package/src/patient-registration/patient-registration.resource.test.tsx +4 -7
  195. package/src/patient-registration/patient-registration.resource.ts +1 -4
  196. package/src/patient-registration/patient-registration.scss +16 -3
  197. package/src/patient-registration/patient-registration.test.tsx +614 -580
  198. package/src/patient-registration/patient-registration.types.ts +17 -28
  199. package/src/patient-registration/section/death-info/death-info-section.test.tsx +130 -34
  200. package/src/patient-registration/section/demographics/demographics-section.test.tsx +122 -68
  201. package/src/patient-registration/section/patient-relationships/relationships-section.component.tsx +15 -15
  202. package/src/patient-registration/section/patient-relationships/relationships-section.test.tsx +278 -84
  203. package/src/patient-registration/section/section-wrapper.component.tsx +1 -1
  204. package/src/patient-registration/ui-components/overlay/overlay.test.tsx +104 -0
  205. package/src/patient-registration/validation/patient-registration-validation.test.ts +2 -1
  206. package/src/patient-registration/validation/patient-registration-validation.ts +9 -3
  207. package/src/root.component.tsx +2 -5
  208. package/src/widgets/cancel-patient-edit.test.tsx +48 -11
  209. package/src/widgets/delete-identifier-confirmation.test.tsx +77 -24
  210. package/src/widgets/edit-patient-details-button.component.tsx +14 -18
  211. package/src/widgets/edit-patient-details-button.scss +2 -2
  212. package/src/widgets/edit-patient-details-button.test.tsx +11 -13
  213. package/translations/am.json +9 -4
  214. package/translations/ar.json +9 -4
  215. package/translations/ar_SY.json +9 -4
  216. package/translations/bn.json +9 -4
  217. package/translations/cs.json +9 -4
  218. package/translations/de.json +120 -115
  219. package/translations/en.json +10 -4
  220. package/translations/en_US.json +9 -4
  221. package/translations/es.json +9 -4
  222. package/translations/es_MX.json +9 -4
  223. package/translations/fr.json +9 -4
  224. package/translations/he.json +9 -4
  225. package/translations/hi.json +9 -4
  226. package/translations/hi_IN.json +9 -4
  227. package/translations/id.json +9 -4
  228. package/translations/it.json +9 -4
  229. package/translations/ka.json +9 -4
  230. package/translations/km.json +9 -4
  231. package/translations/ku.json +9 -4
  232. package/translations/ky.json +9 -4
  233. package/translations/lg.json +9 -4
  234. package/translations/ne.json +9 -4
  235. package/translations/pl.json +9 -4
  236. package/translations/pt.json +9 -4
  237. package/translations/pt_BR.json +10 -5
  238. package/translations/qu.json +9 -4
  239. package/translations/ro_RO.json +9 -4
  240. package/translations/ru_RU.json +9 -4
  241. package/translations/si.json +9 -4
  242. package/translations/sq.json +9 -4
  243. package/translations/sw.json +9 -4
  244. package/translations/sw_KE.json +9 -4
  245. package/translations/tr.json +9 -4
  246. package/translations/tr_TR.json +9 -4
  247. package/translations/uk.json +9 -4
  248. package/translations/uz.json +9 -4
  249. package/translations/uz@Latn.json +9 -4
  250. package/translations/uz_UZ.json +9 -4
  251. package/translations/vi.json +9 -4
  252. package/translations/zh.json +50 -45
  253. package/translations/zh_CN.json +9 -4
  254. package/translations/zh_TW.json +9 -4
  255. package/vitest.config.ts +4 -0
  256. package/dist/126.js +0 -1
  257. package/dist/15.js +0 -1
  258. package/dist/1564.js +0 -1
  259. package/dist/1567.js +0 -1
  260. package/dist/1845.js +0 -1
  261. package/dist/1953.js +0 -1
  262. package/dist/200.js +0 -1
  263. package/dist/200.js.map +0 -1
  264. package/dist/215.js +0 -1
  265. package/dist/2178.js +0 -1
  266. package/dist/250.js +0 -1
  267. package/dist/250.js.map +0 -1
  268. package/dist/2523.js +0 -1
  269. package/dist/2523.js.map +0 -1
  270. package/dist/2566.js +0 -1
  271. package/dist/2586.js +0 -1
  272. package/dist/2586.js.map +0 -1
  273. package/dist/2716.js +0 -1
  274. package/dist/2716.js.map +0 -1
  275. package/dist/2759.js +0 -1
  276. package/dist/2821.js +0 -6
  277. package/dist/2821.js.map +0 -1
  278. package/dist/3089.js +0 -1
  279. package/dist/3089.js.map +0 -1
  280. package/dist/3230.js +0 -1
  281. package/dist/3441.js +0 -1
  282. package/dist/3565.js +0 -1
  283. package/dist/3571.js +0 -1
  284. package/dist/3571.js.map +0 -1
  285. package/dist/3746.js +0 -1
  286. package/dist/3925.js +0 -1
  287. package/dist/3946.js +0 -1
  288. package/dist/4024.js +0 -1
  289. package/dist/4744.js +0 -1
  290. package/dist/4744.js.map +0 -1
  291. package/dist/4809.js +0 -1
  292. package/dist/4894.js +0 -1
  293. package/dist/4970.js +0 -1
  294. package/dist/4970.js.map +0 -1
  295. package/dist/5130.js +0 -1
  296. package/dist/5187.js +0 -1
  297. package/dist/5491.js +0 -1
  298. package/dist/5491.js.map +0 -1
  299. package/dist/5595.js +0 -1
  300. package/dist/5961.js +0 -1
  301. package/dist/6133.js +0 -1
  302. package/dist/634.js +0 -1
  303. package/dist/634.js.map +0 -1
  304. package/dist/6456.js +0 -1
  305. package/dist/6466.js +0 -1
  306. package/dist/6613.js +0 -1
  307. package/dist/6783.js +0 -1
  308. package/dist/7073.js +0 -38
  309. package/dist/7073.js.map +0 -1
  310. package/dist/7154.js +0 -1
  311. package/dist/7154.js.map +0 -1
  312. package/dist/7348.js +0 -1
  313. package/dist/7439.js +0 -1
  314. package/dist/7439.js.map +0 -1
  315. package/dist/7543.js +0 -1
  316. package/dist/7607.js +0 -1
  317. package/dist/772.js +0 -1
  318. package/dist/7984.js +0 -1
  319. package/dist/7984.js.map +0 -1
  320. package/dist/8538.js +0 -1
  321. package/dist/8538.js.map +0 -1
  322. package/dist/8599.js +0 -1
  323. package/dist/8727.js +0 -1
  324. package/dist/8847.js +0 -1
  325. package/dist/9015.js +0 -1
  326. package/dist/906.js +0 -1
  327. package/dist/9065.js +0 -1
  328. package/dist/9182.js +0 -1
  329. package/dist/9339.js +0 -1
  330. package/dist/9453.js +0 -1
  331. package/dist/9833.js +0 -1
  332. package/dist/9833.js.map +0 -1
  333. package/dist/9856.js +0 -1
  334. package/dist/9856.js.map +0 -1
  335. package/dist/9920.js +0 -1
  336. package/dist/9938.js +0 -1
  337. package/dist/9943.js +0 -1
  338. package/dist/9943.js.map +0 -1
  339. package/dist/olaboot-esm-patient-registration-app.js +0 -5
  340. package/dist/olaboot-esm-patient-registration-app.js.map +0 -1
  341. package/jest.config.js +0 -3
  342. package/src/resource.ts +0 -12
@@ -1,330 +1,333 @@
1
- import React from 'react';
2
- import { Form, Formik } from 'formik';
3
- import { render, screen } from '@testing-library/react';
4
- import { getDefaultsFromConfigSchema, useConfig } from '@openmrs/esm-framework';
5
- import { Field } from './field.component';
6
- import { esmPatientRegistrationSchema, type RegistrationConfig } from '../../config-schema';
7
- import { type Resources } from '../../offline.resources';
8
- import type { AddressTemplate, FormValues } from '../patient-registration.types';
9
- import { PatientRegistrationContextProvider } from '../patient-registration-context';
10
- import { ResourcesContextProvider } from '../../resources-context';
11
- import { renderWithContext } from 'tools';
12
-
13
- const mockUseConfig = jest.mocked(useConfig<RegistrationConfig>);
14
-
15
- const predefinedAddressTemplate = {
16
- uuid: 'test-address-template-uuid',
17
- property: 'layout.address.format',
18
- description: 'Test Address Template',
19
- display:
20
- 'Layout - Address Format = <org.openmrs.layout.address.AddressTemplate>\n <nameMappings class="properties">\n <property name="postalCode" value="Location.postalCode"/>\n <property name="address2" value="Location.address2"/>\n <property name="address1" value="Location.address1"/>\n <property name="country" value="Location.country"/>\n <property name="stateProvince" value="Location.stateProvince"/>\n <property name="cityVillage" value="Location.cityVillage"/>\n </nameMappings>\n <sizeMappings class="properties">\n <property name="postalCode" value="10"/>\n <property name="address2" value="40"/>\n <property name="address1" value="40"/>\n <property name="country" value="10"/>\n <property name="stateProvince" value="10"/>\n <property name="cityVillage" value="10"/>\n </sizeMappings>\n <lineByLineFormat>\n <string>address1</string>\n <string>address2</string>\n <string>cityVillage stateProvince country postalCode</string>\n </lineByLineFormat>\n </org.openmrs.layout.address.AddressTemplate>',
21
- value:
22
- '<org.openmrs.layout.address.AddressTemplate>\r\n <nameMappings class="properties">\r\n <property name="postalCode" value="Location.postalCode"/>\r\n <property name="address2" value="Location.address2"/>\r\n <property name="address1" value="Location.address1"/>\r\n <property name="country" value="Location.country"/>\r\n <property name="stateProvince" value="Location.stateProvince"/>\r\n <property name="cityVillage" value="Location.cityVillage"/>\r\n </nameMappings>\r\n <sizeMappings class="properties">\r\n <property name="postalCode" value="4"/>\r\n <property name="address1" value="40"/>\r\n <property name="address2" value="40"/>\r\n <property name="country" value="10"/>\r\n <property name="stateProvince" value="10"/>\r\n <property name="cityVillage" value="10"/>\r\n <asset name="cityVillage" value="10"/>\r\n </sizeMappings>\r\n <lineByLineFormat>\r\n <string>address1 address2</string>\r\n <string>cityVillage stateProvince postalCode</string>\r\n <string>country</string>\r\n </lineByLineFormat>\r\n <elementDefaults class="properties">\r\n <property name="country" value=""/>\r\n </elementDefaults>\r\n <elementRegex class="properties">\r\n <property name="address1" value="[a-zA-Z]+$"/>\r\n </elementRegex>\r\n <elementRegexFormats class="properties">\r\n <property name="address1" value="Countries can only be letters"/>\r\n </elementRegexFormats>\r\n </org.openmrs.layout.address.AddressTemplate>',
23
- };
24
-
25
- const mockIdentifierTypes = [
26
- {
27
- fieldName: 'openMrsId',
28
- format: '',
29
- identifierSources: [
30
- {
31
- uuid: '8549f706-7e85-4c1d-9424-217d50a2988b',
32
- name: 'Generator for OpenMRS ID',
33
- description: 'Generator for OpenMRS ID',
34
- baseCharacterSet: '0123456789ACDEFGHJKLMNPRTUVWXY',
35
- prefix: '',
36
- },
37
- ],
38
- isPrimary: true,
39
- name: 'OpenMRS ID',
40
- required: true,
41
- uniquenessBehavior: 'UNIQUE' as const,
42
- uuid: '05a29f94-c0ed-11e2-94be-8c13b969e334',
43
- },
44
- {
45
- fieldName: 'idCard',
46
- format: '',
47
- identifierSources: [],
48
- isPrimary: false,
49
- name: 'ID Card',
50
- required: false,
51
- uniquenessBehavior: 'UNIQUE' as const,
52
- uuid: 'b4143563-16cd-4439-b288-f83d61670fc8',
53
- },
54
- {
55
- fieldName: 'legacyId',
56
- format: '',
57
- identifierSources: [],
58
- isPrimary: false,
59
- name: 'Legacy ID',
60
- required: false,
61
- uniquenessBehavior: null,
62
- uuid: '22348099-3873-459e-a32e-d93b17eda533',
63
- },
64
- {
65
- fieldName: 'oldIdentificationNumber',
66
- format: '',
67
- identifierSources: [],
68
- isPrimary: false,
69
- name: 'Old Identification Number',
70
- required: false,
71
- uniquenessBehavior: null,
72
- uuid: '8d79403a-c2cc-11de-8d13-0010c6dffd0f',
73
- },
74
- {
75
- fieldName: 'openMrsIdentificationNumber',
76
- format: '',
77
- identifierSources: [],
78
- isPrimary: false,
79
- name: 'OpenMRS Identification Number',
80
- required: false,
81
- uniquenessBehavior: null,
82
- uuid: '8d793bee-c2cc-11de-8d13-0010c6dffd0f',
83
- },
84
- ];
85
-
86
- const mockResourcesContextValue: Resources = {
87
- addressTemplate: predefinedAddressTemplate as unknown as AddressTemplate,
88
- currentSession: {
89
- authenticated: true,
90
- sessionId: 'JSESSION',
91
- currentProvider: { uuid: 'provider-uuid', identifier: 'PRO-123' },
92
- },
93
- relationshipTypes: [],
94
- identifierTypes: [...mockIdentifierTypes],
95
- };
96
-
97
- const initialContextValues = {
98
- currentPhoto: 'data:image/png;base64,1234567890',
99
- identifierTypes: [],
100
- inEditMode: false,
101
- initialFormValues: {} as FormValues,
102
- isOffline: false,
103
- setCapturePhotoProps: jest.fn(),
104
- setFieldValue: jest.fn(),
105
- setFieldTouched: jest.fn(),
106
- setInitialFormValues: jest.fn(),
107
- validationSchema: null,
108
- values: {} as FormValues,
109
- };
110
-
111
- describe('Field', () => {
112
- beforeEach(() => {
113
- mockUseConfig.mockReturnValue({
114
- ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
115
- });
116
- });
117
-
118
- it('should render NameField component when name prop is "name"', () => {
119
- mockUseConfig.mockReturnValue({
120
- ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
121
- fieldConfigurations: {
122
- name: {
123
- allowUnidentifiedPatients: true,
124
- displayMiddleName: true,
125
- defaultUnknownGivenName: 'UNKNOWN',
126
- defaultUnknownFamilyName: 'UNKNOWN',
127
- },
128
- } as RegistrationConfig['fieldConfigurations'],
129
- });
130
-
131
- renderWithContext(
132
- <Formik initialValues={{}} onSubmit={jest.fn()}>
133
- <Form>
134
- <PatientRegistrationContextProvider value={initialContextValues}>
135
- <Field name="name" />
136
- </PatientRegistrationContextProvider>
137
- </Form>
138
- </Formik>,
139
- ResourcesContextProvider,
140
- mockResourcesContextValue,
141
- );
142
-
143
- expect(screen.getByText('Full Name')).toBeInTheDocument();
144
- });
145
-
146
- it('should render GenderField component when name prop is "gender"', () => {
147
- mockUseConfig.mockReturnValue({
148
- ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
149
- fieldConfigurations: {
150
- gender: [
151
- {
152
- value: 'Male',
153
- label: 'Male',
154
- id: 'male',
155
- },
156
- ],
157
- } as unknown as RegistrationConfig['fieldConfigurations'],
158
- });
159
-
160
- renderWithContext(
161
- <Formik initialValues={{}} onSubmit={jest.fn()}>
162
- <Form>
163
- <PatientRegistrationContextProvider value={initialContextValues}>
164
- <Field name="gender" />
165
- </PatientRegistrationContextProvider>
166
- </Form>
167
- </Formik>,
168
- ResourcesContextProvider,
169
- mockResourcesContextValue,
170
- );
171
- expect(screen.getByLabelText('Male')).toBeInTheDocument();
172
- });
173
-
174
- it('should render DobField component when name prop is "dob"', () => {
175
- renderWithContext(
176
- <Formik initialValues={{}} onSubmit={jest.fn()}>
177
- <Form>
178
- <PatientRegistrationContextProvider value={initialContextValues}>
179
- <Field name="dob" />
180
- </PatientRegistrationContextProvider>
181
- </Form>
182
- </Formik>,
183
- ResourcesContextProvider,
184
- mockResourcesContextValue,
185
- );
186
-
187
- expect(screen.getByText('Birth')).toBeInTheDocument();
188
- });
189
-
190
- it('should render AddressComponent component when name prop is "address"', () => {
191
- jest.mock('./address/address-hierarchy.resource', () => ({
192
- ...jest.requireActual('../address-hierarchy.resource'),
193
- useOrderedAddressHierarchyLevels: jest.fn(),
194
- }));
195
-
196
- mockUseConfig.mockReturnValue({
197
- ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
198
- fieldConfigurations: {
199
- address: {
200
- useAddressHierarchy: {
201
- enabled: false,
202
- useQuickSearch: false,
203
- searchAddressByLevel: false,
204
- },
205
- requiredAddressFields: [],
206
- },
207
- } as RegistrationConfig['fieldConfigurations'],
208
- });
209
-
210
- renderWithContext(
211
- <Formik initialValues={{}} onSubmit={jest.fn()}>
212
- <Form>
213
- <PatientRegistrationContextProvider value={initialContextValues}>
214
- <Field name="address" />
215
- </PatientRegistrationContextProvider>
216
- </Form>
217
- </Formik>,
218
- ResourcesContextProvider,
219
- mockResourcesContextValue,
220
- );
221
-
222
- expect(screen.getByText('Address')).toBeInTheDocument();
223
- });
224
-
225
- it('should render Identifiers component when name prop is "id"', () => {
226
- mockUseConfig.mockReturnValue({
227
- ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
228
- defaultPatientIdentifierTypes: ['OpenMRS ID'],
229
- });
230
-
231
- const openmrsID = {
232
- name: 'OpenMRS ID',
233
- fieldName: 'openMrsId',
234
- required: true,
235
- uuid: '05a29f94-c0ed-11e2-94be-8c13b969e334',
236
- format: null,
237
- isPrimary: true,
238
- identifierSources: [
239
- {
240
- uuid: '691eed12-c0f1-11e2-94be-8c13b969e334',
241
- name: 'Generator 1 for OpenMRS ID',
242
- autoGenerationOption: {
243
- manualEntryEnabled: false,
244
- automaticGenerationEnabled: true,
245
- },
246
- },
247
- {
248
- uuid: '01af8526-cea4-4175-aa90-340acb411771',
249
- name: 'Generator 2 for OpenMRS ID',
250
- autoGenerationOption: {
251
- manualEntryEnabled: true,
252
- automaticGenerationEnabled: true,
253
- },
254
- },
255
- ],
256
- identifierUuid: 'openmrs-identifier-uuid',
257
- identifierTypeUuid: 'openmrs-id-identifier-type-uuid',
258
- initialValue: '12345',
259
- identifierValue: '12345',
260
- identifierName: 'OpenMRS ID',
261
- preferred: true,
262
- selectedSource: {
263
- uuid: 'openmrs-id-selected-source-uuid',
264
- name: 'Generator 1 for OpenMRS ID',
265
- autoGenerationOption: {
266
- manualEntryEnabled: false,
267
- automaticGenerationEnabled: true,
268
- },
269
- },
270
- autoGenerationSource: null,
271
- };
272
-
273
- const updatedContextValues = {
274
- currentPhoto: 'data:image/png;base64,1234567890',
275
- identifierTypes: [],
276
- inEditMode: false,
277
- initialFormValues: { identifiers: { openmrsID } } as unknown as FormValues,
278
- isOffline: false,
279
- setCapturePhotoProps: jest.fn(),
280
- setFieldValue: jest.fn(),
281
- setInitialFormValues: jest.fn(),
282
- validationSchema: null,
283
- values: { identifiers: { openmrsID } } as unknown as FormValues,
284
- setFieldTouched: jest.fn(),
285
- };
286
-
287
- renderWithContext(
288
- <Formik initialValues={{}} onSubmit={jest.fn()}>
289
- <Form>
290
- <PatientRegistrationContextProvider value={updatedContextValues}>
291
- <Field name="id" />
292
- </PatientRegistrationContextProvider>
293
- </Form>
294
- </Formik>,
295
- ResourcesContextProvider,
296
- mockResourcesContextValue,
297
- );
298
- expect(screen.getByText('Identifiers')).toBeInTheDocument();
299
- });
300
-
301
- it('should return null and report an error for an invalid field name', () => {
302
- const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {});
303
-
304
- mockUseConfig.mockReturnValue({
305
- ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
306
- fieldDefinitions: [{ id: 'weight' }] as RegistrationConfig['fieldDefinitions'],
307
- });
308
-
309
- let error = null;
310
-
311
- try {
312
- renderWithContext(
313
- <Formik initialValues={{}} onSubmit={jest.fn()}>
314
- <Form>
315
- <Field name="invalidField" />
316
- </Form>
317
- </Formik>,
318
- ResourcesContextProvider,
319
- mockResourcesContextValue,
320
- );
321
- } catch (err) {
322
- error = err;
323
- }
324
-
325
- expect(error).toMatch(/Invalid field name 'invalidField'. Valid options are /);
326
- expect(screen.queryByTestId('invalid-field')).not.toBeInTheDocument();
327
-
328
- consoleError.mockRestore();
329
- });
330
- });
1
+ import React from 'react';
2
+ import { vi, describe, it, expect, test, beforeEach } from 'vitest';
3
+ import { Form, Formik } from 'formik';
4
+ import { render, screen } from '@testing-library/react';
5
+ import { getDefaultsFromConfigSchema, useConfig } from '@openmrs/esm-framework';
6
+ import { Field } from './field.component';
7
+ import { esmPatientRegistrationSchema, type RegistrationConfig } from '../../config-schema';
8
+ import { type Resources } from '../../offline.resources';
9
+ import type { AddressTemplate, FormValues } from '../patient-registration.types';
10
+ import { PatientRegistrationContextProvider } from '../patient-registration-context';
11
+ import { ResourcesContextProvider } from '../../resources-context';
12
+ import { renderWithContext } from 'tools';
13
+
14
+ const mockUseConfig = vi.mocked(useConfig<RegistrationConfig>);
15
+
16
+ const predefinedAddressTemplate = {
17
+ uuid: 'test-address-template-uuid',
18
+ property: 'layout.address.format',
19
+ description: 'Test Address Template',
20
+ display:
21
+ 'Layout - Address Format = <org.openmrs.layout.address.AddressTemplate>\n <nameMappings class="properties">\n <property name="postalCode" value="Location.postalCode"/>\n <property name="address2" value="Location.address2"/>\n <property name="address1" value="Location.address1"/>\n <property name="country" value="Location.country"/>\n <property name="stateProvince" value="Location.stateProvince"/>\n <property name="cityVillage" value="Location.cityVillage"/>\n </nameMappings>\n <sizeMappings class="properties">\n <property name="postalCode" value="10"/>\n <property name="address2" value="40"/>\n <property name="address1" value="40"/>\n <property name="country" value="10"/>\n <property name="stateProvince" value="10"/>\n <property name="cityVillage" value="10"/>\n </sizeMappings>\n <lineByLineFormat>\n <string>address1</string>\n <string>address2</string>\n <string>cityVillage stateProvince country postalCode</string>\n </lineByLineFormat>\n </org.openmrs.layout.address.AddressTemplate>',
22
+ value:
23
+ '<org.openmrs.layout.address.AddressTemplate>\r\n <nameMappings class="properties">\r\n <property name="postalCode" value="Location.postalCode"/>\r\n <property name="address2" value="Location.address2"/>\r\n <property name="address1" value="Location.address1"/>\r\n <property name="country" value="Location.country"/>\r\n <property name="stateProvince" value="Location.stateProvince"/>\r\n <property name="cityVillage" value="Location.cityVillage"/>\r\n </nameMappings>\r\n <sizeMappings class="properties">\r\n <property name="postalCode" value="4"/>\r\n <property name="address1" value="40"/>\r\n <property name="address2" value="40"/>\r\n <property name="country" value="10"/>\r\n <property name="stateProvince" value="10"/>\r\n <property name="cityVillage" value="10"/>\r\n <asset name="cityVillage" value="10"/>\r\n </sizeMappings>\r\n <lineByLineFormat>\r\n <string>address1 address2</string>\r\n <string>cityVillage stateProvince postalCode</string>\r\n <string>country</string>\r\n </lineByLineFormat>\r\n <elementDefaults class="properties">\r\n <property name="country" value=""/>\r\n </elementDefaults>\r\n <elementRegex class="properties">\r\n <property name="address1" value="[a-zA-Z]+$"/>\r\n </elementRegex>\r\n <elementRegexFormats class="properties">\r\n <property name="address1" value="Countries can only be letters"/>\r\n </elementRegexFormats>\r\n </org.openmrs.layout.address.AddressTemplate>',
24
+ };
25
+
26
+ const mockIdentifierTypes = [
27
+ {
28
+ fieldName: 'openMrsId',
29
+ format: '',
30
+ identifierSources: [
31
+ {
32
+ uuid: '8549f706-7e85-4c1d-9424-217d50a2988b',
33
+ name: 'Generator for OpenMRS ID',
34
+ description: 'Generator for OpenMRS ID',
35
+ baseCharacterSet: '0123456789ACDEFGHJKLMNPRTUVWXY',
36
+ prefix: '',
37
+ },
38
+ ],
39
+ isPrimary: true,
40
+ name: 'OpenMRS ID',
41
+ required: true,
42
+ uniquenessBehavior: 'UNIQUE' as const,
43
+ uuid: '05a29f94-c0ed-11e2-94be-8c13b969e334',
44
+ },
45
+ {
46
+ fieldName: 'idCard',
47
+ format: '',
48
+ identifierSources: [],
49
+ isPrimary: false,
50
+ name: 'ID Card',
51
+ required: false,
52
+ uniquenessBehavior: 'UNIQUE' as const,
53
+ uuid: 'b4143563-16cd-4439-b288-f83d61670fc8',
54
+ },
55
+ {
56
+ fieldName: 'legacyId',
57
+ format: '',
58
+ identifierSources: [],
59
+ isPrimary: false,
60
+ name: 'Legacy ID',
61
+ required: false,
62
+ uniquenessBehavior: null,
63
+ uuid: '22348099-3873-459e-a32e-d93b17eda533',
64
+ },
65
+ {
66
+ fieldName: 'oldIdentificationNumber',
67
+ format: '',
68
+ identifierSources: [],
69
+ isPrimary: false,
70
+ name: 'Old Identification Number',
71
+ required: false,
72
+ uniquenessBehavior: null,
73
+ uuid: '8d79403a-c2cc-11de-8d13-0010c6dffd0f',
74
+ },
75
+ {
76
+ fieldName: 'openMrsIdentificationNumber',
77
+ format: '',
78
+ identifierSources: [],
79
+ isPrimary: false,
80
+ name: 'OpenMRS Identification Number',
81
+ required: false,
82
+ uniquenessBehavior: null,
83
+ uuid: '8d793bee-c2cc-11de-8d13-0010c6dffd0f',
84
+ },
85
+ ];
86
+
87
+ const mockResourcesContextValue: Resources = {
88
+ addressTemplate: predefinedAddressTemplate as unknown as AddressTemplate,
89
+ currentSession: {
90
+ authenticated: true,
91
+ sessionId: 'JSESSION',
92
+ currentProvider: { uuid: 'provider-uuid', identifier: 'PRO-123' },
93
+ },
94
+ relationshipTypes: { results: [] },
95
+ identifierTypes: [...mockIdentifierTypes],
96
+ };
97
+
98
+ const initialContextValues = {
99
+ currentPhoto: 'data:image/png;base64,1234567890',
100
+ identifierTypes: [],
101
+ inEditMode: false,
102
+ initialFormValues: {} as FormValues,
103
+ isOffline: false,
104
+ setCapturePhotoProps: vi.fn(),
105
+ setFieldValue: vi.fn(),
106
+ setFieldTouched: vi.fn(),
107
+ setInitialFormValues: vi.fn(),
108
+ validationSchema: null,
109
+ values: {} as FormValues,
110
+ };
111
+
112
+ describe('Field', () => {
113
+ beforeEach(() => {
114
+ mockUseConfig.mockReturnValue({
115
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
116
+ });
117
+ });
118
+
119
+ it('should render NameField component when name prop is "name"', () => {
120
+ mockUseConfig.mockReturnValue({
121
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
122
+ fieldConfigurations: {
123
+ name: {
124
+ allowUnidentifiedPatients: true,
125
+ displayMiddleName: true,
126
+ defaultUnknownGivenName: 'UNKNOWN',
127
+ defaultUnknownFamilyName: 'UNKNOWN',
128
+ },
129
+ } as RegistrationConfig['fieldConfigurations'],
130
+ });
131
+
132
+ renderWithContext(
133
+ <Formik initialValues={{}} onSubmit={vi.fn()}>
134
+ <Form>
135
+ <PatientRegistrationContextProvider value={initialContextValues}>
136
+ <Field name="name" />
137
+ </PatientRegistrationContextProvider>
138
+ </Form>
139
+ </Formik>,
140
+ ResourcesContextProvider,
141
+ mockResourcesContextValue,
142
+ );
143
+
144
+ expect(screen.getByText('Full Name')).toBeInTheDocument();
145
+ });
146
+
147
+ it('should render GenderField component when name prop is "gender"', () => {
148
+ mockUseConfig.mockReturnValue({
149
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
150
+ fieldConfigurations: {
151
+ gender: [
152
+ {
153
+ value: 'Male',
154
+ label: 'Male',
155
+ id: 'male',
156
+ },
157
+ ],
158
+ } as unknown as RegistrationConfig['fieldConfigurations'],
159
+ });
160
+
161
+ renderWithContext(
162
+ <Formik initialValues={{}} onSubmit={vi.fn()}>
163
+ <Form>
164
+ <PatientRegistrationContextProvider value={initialContextValues}>
165
+ <Field name="gender" />
166
+ </PatientRegistrationContextProvider>
167
+ </Form>
168
+ </Formik>,
169
+ ResourcesContextProvider,
170
+ mockResourcesContextValue,
171
+ );
172
+ expect(screen.getByLabelText('Male')).toBeInTheDocument();
173
+ });
174
+
175
+ it('should render DobField component when name prop is "dob"', () => {
176
+ renderWithContext(
177
+ <Formik initialValues={{}} onSubmit={vi.fn()}>
178
+ <Form>
179
+ <PatientRegistrationContextProvider value={initialContextValues}>
180
+ <Field name="dob" />
181
+ </PatientRegistrationContextProvider>
182
+ </Form>
183
+ </Formik>,
184
+ ResourcesContextProvider,
185
+ mockResourcesContextValue,
186
+ );
187
+
188
+ expect(screen.getByText('Birth')).toBeInTheDocument();
189
+ });
190
+
191
+ // TODO: Re-enable after migrating the in-test `vi.mock` of `address-hierarchy.resource`
192
+ // to a top-level mock with `mockReturnValue` set. The current setup leaves
193
+ // `useOrderedAddressHierarchyLevels` returning undefined and the component crashes.
194
+ it.skip('should render AddressComponent component when name prop is "address"', () => {
195
+ vi.mock('./address/address-hierarchy.resource', async () => ({
196
+ ...((await vi.importActual('./address/address-hierarchy.resource')) as object),
197
+ useOrderedAddressHierarchyLevels: vi.fn(),
198
+ }));
199
+
200
+ mockUseConfig.mockReturnValue({
201
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
202
+ fieldConfigurations: {
203
+ address: {
204
+ useAddressHierarchy: {
205
+ enabled: false,
206
+ useQuickSearch: false,
207
+ searchAddressByLevel: false,
208
+ },
209
+ },
210
+ } as RegistrationConfig['fieldConfigurations'],
211
+ });
212
+
213
+ renderWithContext(
214
+ <Formik initialValues={{}} onSubmit={vi.fn()}>
215
+ <Form>
216
+ <PatientRegistrationContextProvider value={initialContextValues}>
217
+ <Field name="address" />
218
+ </PatientRegistrationContextProvider>
219
+ </Form>
220
+ </Formik>,
221
+ ResourcesContextProvider,
222
+ mockResourcesContextValue,
223
+ );
224
+
225
+ expect(screen.getByText('Address')).toBeInTheDocument();
226
+ });
227
+
228
+ it('should render Identifiers component when name prop is "id"', () => {
229
+ mockUseConfig.mockReturnValue({
230
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
231
+ defaultPatientIdentifierTypes: ['OpenMRS ID'],
232
+ });
233
+
234
+ const openmrsID = {
235
+ name: 'OpenMRS ID',
236
+ fieldName: 'openMrsId',
237
+ required: true,
238
+ uuid: '05a29f94-c0ed-11e2-94be-8c13b969e334',
239
+ format: null,
240
+ isPrimary: true,
241
+ identifierSources: [
242
+ {
243
+ uuid: '691eed12-c0f1-11e2-94be-8c13b969e334',
244
+ name: 'Generator 1 for OpenMRS ID',
245
+ autoGenerationOption: {
246
+ manualEntryEnabled: false,
247
+ automaticGenerationEnabled: true,
248
+ },
249
+ },
250
+ {
251
+ uuid: '01af8526-cea4-4175-aa90-340acb411771',
252
+ name: 'Generator 2 for OpenMRS ID',
253
+ autoGenerationOption: {
254
+ manualEntryEnabled: true,
255
+ automaticGenerationEnabled: true,
256
+ },
257
+ },
258
+ ],
259
+ identifierUuid: 'openmrs-identifier-uuid',
260
+ identifierTypeUuid: 'openmrs-id-identifier-type-uuid',
261
+ initialValue: '12345',
262
+ identifierValue: '12345',
263
+ identifierName: 'OpenMRS ID',
264
+ preferred: true,
265
+ selectedSource: {
266
+ uuid: 'openmrs-id-selected-source-uuid',
267
+ name: 'Generator 1 for OpenMRS ID',
268
+ autoGenerationOption: {
269
+ manualEntryEnabled: false,
270
+ automaticGenerationEnabled: true,
271
+ },
272
+ },
273
+ autoGenerationSource: null,
274
+ };
275
+
276
+ const updatedContextValues = {
277
+ currentPhoto: 'data:image/png;base64,1234567890',
278
+ identifierTypes: [],
279
+ inEditMode: false,
280
+ initialFormValues: { identifiers: { openmrsID } } as unknown as FormValues,
281
+ isOffline: false,
282
+ setCapturePhotoProps: vi.fn(),
283
+ setFieldValue: vi.fn(),
284
+ setInitialFormValues: vi.fn(),
285
+ validationSchema: null,
286
+ values: { identifiers: { openmrsID } } as unknown as FormValues,
287
+ setFieldTouched: vi.fn(),
288
+ };
289
+
290
+ renderWithContext(
291
+ <Formik initialValues={{}} onSubmit={vi.fn()}>
292
+ <Form>
293
+ <PatientRegistrationContextProvider value={updatedContextValues}>
294
+ <Field name="id" />
295
+ </PatientRegistrationContextProvider>
296
+ </Form>
297
+ </Formik>,
298
+ ResourcesContextProvider,
299
+ mockResourcesContextValue,
300
+ );
301
+ expect(screen.getByText('Identifiers')).toBeInTheDocument();
302
+ });
303
+
304
+ it('should return null and report an error for an invalid field name', () => {
305
+ const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {});
306
+
307
+ mockUseConfig.mockReturnValue({
308
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
309
+ fieldDefinitions: [{ id: 'weight' }] as RegistrationConfig['fieldDefinitions'],
310
+ });
311
+
312
+ let error = null;
313
+
314
+ try {
315
+ renderWithContext(
316
+ <Formik initialValues={{}} onSubmit={vi.fn()}>
317
+ <Form>
318
+ <Field name="invalidField" />
319
+ </Form>
320
+ </Formik>,
321
+ ResourcesContextProvider,
322
+ mockResourcesContextValue,
323
+ );
324
+ } catch (err) {
325
+ error = err;
326
+ }
327
+
328
+ expect(error).toMatch(/Invalid field name 'invalidField'. Valid options are /);
329
+ expect(screen.queryByTestId('invalid-field')).not.toBeInTheDocument();
330
+
331
+ consoleError.mockRestore();
332
+ });
333
+ });