@openmrs/esm-patient-tests-app 11.3.1-patch.9064 → 11.3.1-patch.9508

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 (180) hide show
  1. package/.turbo/turbo-build.log +22 -22
  2. package/dist/1119.js +1 -1
  3. package/dist/1197.js +1 -1
  4. package/dist/{6231.js → 1477.js} +1 -1
  5. package/dist/1477.js.map +1 -0
  6. package/dist/1638.js +1 -1
  7. package/dist/1638.js.map +1 -1
  8. package/dist/1935.js +1 -1
  9. package/dist/1935.js.map +1 -1
  10. package/dist/2146.js +1 -1
  11. package/dist/2690.js +1 -1
  12. package/dist/3099.js +1 -1
  13. package/dist/34.js +1 -1
  14. package/dist/34.js.map +1 -1
  15. package/dist/3509.js +1 -1
  16. package/dist/3509.js.map +1 -1
  17. package/dist/3584.js +1 -1
  18. package/dist/4055.js +1 -1
  19. package/dist/4132.js +1 -1
  20. package/dist/4300.js +1 -1
  21. package/dist/4335.js +1 -1
  22. package/dist/439.js +1 -0
  23. package/dist/4618.js +1 -1
  24. package/dist/4652.js +1 -1
  25. package/dist/4944.js +1 -1
  26. package/dist/5173.js +1 -1
  27. package/dist/5241.js +1 -1
  28. package/dist/5442.js +1 -1
  29. package/dist/5661.js +1 -1
  30. package/dist/5670.js +1 -1
  31. package/dist/5670.js.map +1 -1
  32. package/dist/6022.js +1 -1
  33. package/dist/6113.js +1 -0
  34. package/dist/6113.js.map +1 -0
  35. package/dist/6301.js +1 -1
  36. package/dist/6301.js.map +1 -1
  37. package/dist/6336.js +1 -0
  38. package/dist/6336.js.map +1 -0
  39. package/dist/6468.js +1 -1
  40. package/dist/6589.js +1 -0
  41. package/dist/6679.js +1 -1
  42. package/dist/6840.js +1 -1
  43. package/dist/6859.js +1 -1
  44. package/dist/7097.js +1 -1
  45. package/dist/7159.js +1 -1
  46. package/dist/7202.js +1 -0
  47. package/dist/7202.js.map +1 -0
  48. package/dist/723.js +1 -1
  49. package/dist/7617.js +1 -1
  50. package/dist/790.js +1 -1
  51. package/dist/790.js.map +1 -1
  52. package/dist/795.js +1 -1
  53. package/dist/8163.js +1 -1
  54. package/dist/8307.js +2 -0
  55. package/dist/8307.js.map +1 -0
  56. package/dist/8349.js +1 -1
  57. package/dist/8371.js +1 -0
  58. package/dist/8555.js +2 -0
  59. package/dist/8555.js.map +1 -0
  60. package/dist/8618.js +1 -1
  61. package/dist/890.js +1 -1
  62. package/dist/9214.js +1 -1
  63. package/dist/9538.js +1 -1
  64. package/dist/9569.js +1 -1
  65. package/dist/986.js +1 -1
  66. package/dist/9879.js +1 -1
  67. package/dist/9895.js +1 -1
  68. package/dist/9900.js +1 -1
  69. package/dist/9913.js +1 -1
  70. package/dist/main.js +1 -1
  71. package/dist/main.js.map +1 -1
  72. package/dist/openmrs-esm-patient-tests-app.js +1 -1
  73. package/dist/openmrs-esm-patient-tests-app.js.buildmanifest.json +319 -249
  74. package/dist/openmrs-esm-patient-tests-app.js.map +1 -1
  75. package/dist/routes.json +1 -1
  76. package/package.json +3 -3
  77. package/src/edit-test-results/modal/edit-lab-results.modal.tsx +6 -2
  78. package/src/index.ts +1 -1
  79. package/src/routes.json +2 -2
  80. package/src/test-orders/add-test-order/add-test-order.test.tsx +13 -10
  81. package/src/test-orders/add-test-order/add-test-order.workspace.tsx +43 -7
  82. package/src/test-orders/add-test-order/test-order-form.component.tsx +41 -7
  83. package/src/test-orders/add-test-order/test-type-search.component.tsx +56 -8
  84. package/src/test-orders/lab-order-basket-panel/lab-icon.component.tsx +27 -0
  85. package/src/test-orders/lab-order-basket-panel/lab-order-basket-panel.extension.tsx +62 -15
  86. package/src/test-orders/lab-order-basket-panel/lab-order-basket-panel.scss +26 -11
  87. package/src/test-orders/lab-order-basket-panel/lab-order-basket-panel.test.tsx +18 -5
  88. package/src/test-results/filter/filter-context.test.tsx +556 -0
  89. package/src/test-results/filter/filter-context.tsx +1 -1
  90. package/src/test-results/filter/filter-reducer.test.ts +540 -0
  91. package/src/test-results/filter/filter-reducer.ts +1 -1
  92. package/src/test-results/filter/filter-set.component.tsx +75 -48
  93. package/src/test-results/filter/filter-set.test.tsx +694 -0
  94. package/src/test-results/filter/filter-types.ts +24 -1
  95. package/src/test-results/grouped-timeline/grid.component.tsx +4 -2
  96. package/src/test-results/grouped-timeline/grouped-timeline.component.tsx +20 -22
  97. package/src/test-results/grouped-timeline/grouped-timeline.test.tsx +52 -2
  98. package/src/test-results/grouped-timeline/reference-range-helpers.test.ts +308 -0
  99. package/src/test-results/grouped-timeline/reference-range-helpers.ts +161 -0
  100. package/src/test-results/grouped-timeline/timeline-data-group.component.tsx +13 -6
  101. package/src/test-results/grouped-timeline/useObstreeData.test.ts +471 -0
  102. package/src/test-results/grouped-timeline/useObstreeData.ts +108 -13
  103. package/src/test-results/individual-results-table/individual-results-table.component.tsx +18 -6
  104. package/src/test-results/individual-results-table/individual-results-table.test.tsx +65 -3
  105. package/src/test-results/individual-results-table-tablet/helper.tsx +8 -2
  106. package/src/test-results/individual-results-table-tablet/individual-results-table-tablet.component.tsx +5 -5
  107. package/src/test-results/individual-results-table-tablet/lab-set-panel.component.tsx +2 -1
  108. package/src/test-results/individual-results-table-tablet/usePanelData.tsx +40 -26
  109. package/src/test-results/loadPatientTestData/helpers.test.ts +834 -0
  110. package/src/test-results/loadPatientTestData/helpers.ts +143 -12
  111. package/src/test-results/loadPatientTestData/loadPatientData.ts +66 -11
  112. package/src/test-results/loadPatientTestData/usePatientResultsData.ts +20 -9
  113. package/src/test-results/overview/common-datatable.component.tsx +1 -1
  114. package/src/test-results/overview/external-overview.extension.tsx +1 -2
  115. package/src/test-results/overview/useOverviewData.ts +22 -10
  116. package/src/test-results/print-modal/print-modal.extension.tsx +1 -1
  117. package/src/test-results/results-viewer/results-viewer.extension.tsx +12 -7
  118. package/src/test-results/tree-view/tree-view.component.tsx +31 -8
  119. package/src/test-results/tree-view/tree-view.test.tsx +119 -2
  120. package/src/test-results/trendline/trendline-resource.tsx +48 -5
  121. package/src/test-results/trendline/trendline.component.tsx +88 -52
  122. package/src/test-results/ui-elements/{resetFiltersEmptyState → reset-filters-empty-state}/filter-empty-data-illustration.tsx +2 -2
  123. package/src/test-results/ui-elements/{resetFiltersEmptyState → reset-filters-empty-state}/filter-empty-state.component.tsx +5 -6
  124. package/src/types.ts +20 -1
  125. package/translations/am.json +3 -4
  126. package/translations/ar.json +3 -4
  127. package/translations/ar_SY.json +3 -4
  128. package/translations/bn.json +3 -4
  129. package/translations/cs.json +119 -0
  130. package/translations/de.json +3 -4
  131. package/translations/en.json +3 -2
  132. package/translations/en_US.json +3 -4
  133. package/translations/es.json +3 -4
  134. package/translations/es_MX.json +3 -4
  135. package/translations/fr.json +5 -6
  136. package/translations/he.json +3 -4
  137. package/translations/hi.json +3 -4
  138. package/translations/hi_IN.json +3 -4
  139. package/translations/id.json +3 -4
  140. package/translations/it.json +3 -4
  141. package/translations/ka.json +3 -4
  142. package/translations/km.json +3 -4
  143. package/translations/ku.json +3 -4
  144. package/translations/ky.json +3 -4
  145. package/translations/lg.json +3 -4
  146. package/translations/ne.json +3 -4
  147. package/translations/pl.json +3 -4
  148. package/translations/pt.json +3 -4
  149. package/translations/pt_BR.json +3 -4
  150. package/translations/qu.json +3 -4
  151. package/translations/ro_RO.json +3 -4
  152. package/translations/ru_RU.json +3 -4
  153. package/translations/si.json +3 -4
  154. package/translations/sq.json +119 -0
  155. package/translations/sw.json +3 -4
  156. package/translations/sw_KE.json +3 -4
  157. package/translations/tr.json +3 -4
  158. package/translations/tr_TR.json +3 -4
  159. package/translations/uk.json +3 -4
  160. package/translations/uz.json +3 -4
  161. package/translations/uz@Latn.json +3 -4
  162. package/translations/uz_UZ.json +3 -4
  163. package/translations/vi.json +3 -4
  164. package/translations/zh.json +3 -4
  165. package/translations/zh_CN.json +3 -4
  166. package/translations/zh_TW.json +119 -0
  167. package/dist/1479.js +0 -1
  168. package/dist/1479.js.map +0 -1
  169. package/dist/2537.js +0 -1
  170. package/dist/2537.js.map +0 -1
  171. package/dist/4918.js +0 -1
  172. package/dist/4918.js.map +0 -1
  173. package/dist/5836.js +0 -2
  174. package/dist/5836.js.map +0 -1
  175. package/dist/6231.js.map +0 -1
  176. package/dist/7053.js +0 -2
  177. package/dist/7053.js.map +0 -1
  178. /package/dist/{7053.js.LICENSE.txt → 8307.js.LICENSE.txt} +0 -0
  179. /package/dist/{5836.js.LICENSE.txt → 8555.js.LICENSE.txt} +0 -0
  180. /package/src/test-results/ui-elements/{resetFiltersEmptyState/index.scss → reset-filters-empty-state/filter-empty-state.scss} +0 -0
@@ -0,0 +1,834 @@
1
+ import type { ObsRecord } from '@openmrs/esm-patient-common-lib';
2
+ import { extractObservationReferenceRanges, extractObservationInterpretation } from './helpers';
3
+ import type { FHIRObservationResource } from '../../types';
4
+
5
+ describe('Observation Extraction Helpers', () => {
6
+ describe('extractObservationReferenceRanges', () => {
7
+ it('returns undefined when referenceRange is missing', () => {
8
+ const resource: FHIRObservationResource = {
9
+ resourceType: 'Observation',
10
+ id: 'test-id',
11
+ category: [],
12
+ code: { coding: [], text: '' },
13
+ effectiveDateTime: '2024-01-01',
14
+ issued: '2024-01-01',
15
+ referenceRange: [],
16
+ };
17
+
18
+ expect(extractObservationReferenceRanges(resource)).toBeUndefined();
19
+ });
20
+
21
+ it('returns undefined when referenceRange is empty array', () => {
22
+ const resource: FHIRObservationResource = {
23
+ resourceType: 'Observation',
24
+ id: 'test-id',
25
+ category: [],
26
+ code: { coding: [], text: '' },
27
+ effectiveDateTime: '2024-01-01',
28
+ issued: '2024-01-01',
29
+ referenceRange: [],
30
+ };
31
+
32
+ expect(extractObservationReferenceRanges(resource)).toBeUndefined();
33
+ });
34
+
35
+ it('extracts normal ranges from HL7 referencerange-meaning system', () => {
36
+ const resource: FHIRObservationResource = {
37
+ resourceType: 'Observation',
38
+ id: 'test-id',
39
+ category: [],
40
+ code: { coding: [], text: '' },
41
+ effectiveDateTime: '2024-01-01',
42
+ issued: '2024-01-01',
43
+ referenceRange: [
44
+ {
45
+ type: {
46
+ coding: [
47
+ {
48
+ system: 'http://terminology.hl7.org/CodeSystem/referencerange-meaning',
49
+ code: 'normal',
50
+ },
51
+ ],
52
+ },
53
+ low: { value: 0 },
54
+ high: { value: 50 },
55
+ },
56
+ ],
57
+ valueQuantity: {
58
+ value: 25,
59
+ unit: 'mg/dL',
60
+ system: 'http://unitsofmeasure.org',
61
+ code: 'mg/dL',
62
+ },
63
+ };
64
+
65
+ const result = extractObservationReferenceRanges(resource);
66
+
67
+ expect(result).toEqual({
68
+ lowNormal: 0,
69
+ hiNormal: 50,
70
+ units: 'mg/dL',
71
+ });
72
+ });
73
+
74
+ it('extracts treatment ranges from HL7 referencerange-meaning system', () => {
75
+ const resource: FHIRObservationResource = {
76
+ resourceType: 'Observation',
77
+ id: 'test-id',
78
+ category: [],
79
+ code: { coding: [], text: '' },
80
+ effectiveDateTime: '2024-01-01',
81
+ issued: '2024-01-01',
82
+ referenceRange: [
83
+ {
84
+ type: {
85
+ coding: [
86
+ {
87
+ system: 'http://terminology.hl7.org/CodeSystem/referencerange-meaning',
88
+ code: 'treatment',
89
+ },
90
+ ],
91
+ },
92
+ low: { value: 25 },
93
+ high: { value: 541 },
94
+ },
95
+ ],
96
+ valueQuantity: {
97
+ value: 30,
98
+ unit: 'U/L',
99
+ system: 'http://unitsofmeasure.org',
100
+ code: 'U/L',
101
+ },
102
+ };
103
+
104
+ const result = extractObservationReferenceRanges(resource);
105
+
106
+ expect(result).toEqual({
107
+ lowCritical: 25,
108
+ hiCritical: 541,
109
+ units: 'U/L',
110
+ });
111
+ });
112
+
113
+ it('extracts absolute ranges from OpenMRS extension system', () => {
114
+ const resource: FHIRObservationResource = {
115
+ resourceType: 'Observation',
116
+ id: 'test-id',
117
+ category: [],
118
+ code: { coding: [], text: '' },
119
+ effectiveDateTime: '2024-01-01',
120
+ issued: '2024-01-01',
121
+ referenceRange: [
122
+ {
123
+ type: {
124
+ coding: [
125
+ {
126
+ system: 'http://fhir.openmrs.org/ext/obs/reference-range',
127
+ code: 'absolute',
128
+ },
129
+ ],
130
+ },
131
+ low: { value: -10 },
132
+ high: { value: 100 },
133
+ },
134
+ ],
135
+ valueQuantity: {
136
+ value: 50,
137
+ unit: 'mg/dL',
138
+ system: 'http://unitsofmeasure.org',
139
+ code: 'mg/dL',
140
+ },
141
+ };
142
+
143
+ const result = extractObservationReferenceRanges(resource);
144
+
145
+ expect(result).toEqual({
146
+ lowAbsolute: -10,
147
+ hiAbsolute: 100,
148
+ units: 'mg/dL',
149
+ });
150
+ });
151
+
152
+ it('handles multiple range types in single observation', () => {
153
+ const resource: FHIRObservationResource = {
154
+ resourceType: 'Observation',
155
+ id: 'test-id',
156
+ category: [],
157
+ code: { coding: [], text: '' },
158
+ effectiveDateTime: '2024-01-01',
159
+ issued: '2024-01-01',
160
+ referenceRange: [
161
+ {
162
+ type: {
163
+ coding: [
164
+ {
165
+ system: 'http://terminology.hl7.org/CodeSystem/referencerange-meaning',
166
+ code: 'normal',
167
+ },
168
+ ],
169
+ },
170
+ low: { value: 0 },
171
+ high: { value: 50 },
172
+ },
173
+ {
174
+ type: {
175
+ coding: [
176
+ {
177
+ system: 'http://terminology.hl7.org/CodeSystem/referencerange-meaning',
178
+ code: 'treatment',
179
+ },
180
+ ],
181
+ },
182
+ low: { value: 25 },
183
+ high: { value: 541 },
184
+ },
185
+ ],
186
+ valueQuantity: {
187
+ value: 30,
188
+ unit: 'U/L',
189
+ system: 'http://unitsofmeasure.org',
190
+ code: 'U/L',
191
+ },
192
+ };
193
+
194
+ const result = extractObservationReferenceRanges(resource);
195
+
196
+ expect(result).toEqual({
197
+ lowNormal: 0,
198
+ hiNormal: 50,
199
+ lowCritical: 25,
200
+ hiCritical: 541,
201
+ units: 'U/L',
202
+ });
203
+ });
204
+
205
+ it('handles partial ranges (only high or only low)', () => {
206
+ const resource: FHIRObservationResource = {
207
+ resourceType: 'Observation',
208
+ id: 'test-id',
209
+ category: [],
210
+ code: { coding: [], text: '' },
211
+ effectiveDateTime: '2024-01-01',
212
+ issued: '2024-01-01',
213
+ referenceRange: [
214
+ {
215
+ type: {
216
+ coding: [
217
+ {
218
+ system: 'http://terminology.hl7.org/CodeSystem/referencerange-meaning',
219
+ code: 'normal',
220
+ },
221
+ ],
222
+ },
223
+ high: { value: 50 },
224
+ },
225
+ ],
226
+ valueQuantity: {
227
+ value: 25,
228
+ unit: 'mg/dL',
229
+ system: 'http://unitsofmeasure.org',
230
+ code: 'mg/dL',
231
+ },
232
+ };
233
+
234
+ const result = extractObservationReferenceRanges(resource);
235
+
236
+ expect(result).toEqual({
237
+ hiNormal: 50,
238
+ units: 'mg/dL',
239
+ });
240
+ });
241
+
242
+ it('returns undefined when no valid range values are found', () => {
243
+ const resource: FHIRObservationResource = {
244
+ resourceType: 'Observation',
245
+ id: 'test-id',
246
+ category: [],
247
+ code: { coding: [], text: '' },
248
+ effectiveDateTime: '2024-01-01',
249
+ issued: '2024-01-01',
250
+ referenceRange: [
251
+ {
252
+ type: {
253
+ coding: [
254
+ {
255
+ system: 'http://unknown.system',
256
+ code: 'unknown',
257
+ },
258
+ ],
259
+ },
260
+ },
261
+ ],
262
+ };
263
+
264
+ expect(extractObservationReferenceRanges(resource)).toBeUndefined();
265
+ });
266
+
267
+ it('handles ObsRecord type input', () => {
268
+ const obsRecord: ObsRecord = {
269
+ resourceType: 'Observation',
270
+ id: 'test-id',
271
+ category: [],
272
+ code: { coding: [], text: '' },
273
+ effectiveDateTime: '2024-01-01',
274
+ issued: '2024-01-01',
275
+ encounter: {
276
+ reference: 'Encounter/test-encounter',
277
+ type: 'Encounter',
278
+ },
279
+ referenceRange: [
280
+ {
281
+ type: {
282
+ coding: [
283
+ {
284
+ system: 'http://terminology.hl7.org/CodeSystem/referencerange-meaning',
285
+ code: 'normal',
286
+ },
287
+ ],
288
+ },
289
+ low: { value: 0 },
290
+ high: { value: 50 },
291
+ },
292
+ ],
293
+ valueQuantity: {
294
+ value: 25,
295
+ unit: 'mg/dL',
296
+ system: 'http://unitsofmeasure.org',
297
+ code: 'mg/dL',
298
+ },
299
+ conceptClass: 'test-uuid',
300
+ value: '25',
301
+ name: 'Test',
302
+ interpretation: 'NORMAL' as const,
303
+ };
304
+
305
+ const result = extractObservationReferenceRanges(obsRecord);
306
+
307
+ expect(result).toEqual({
308
+ lowNormal: 0,
309
+ hiNormal: 50,
310
+ units: 'mg/dL',
311
+ });
312
+ });
313
+
314
+ it('handles missing valueQuantity units', () => {
315
+ const resource: FHIRObservationResource = {
316
+ resourceType: 'Observation',
317
+ id: 'test-id',
318
+ category: [],
319
+ code: { coding: [], text: '' },
320
+ effectiveDateTime: '2024-01-01',
321
+ issued: '2024-01-01',
322
+ referenceRange: [
323
+ {
324
+ type: {
325
+ coding: [
326
+ {
327
+ system: 'http://terminology.hl7.org/CodeSystem/referencerange-meaning',
328
+ code: 'normal',
329
+ },
330
+ ],
331
+ },
332
+ low: { value: 0 },
333
+ high: { value: 50 },
334
+ },
335
+ ],
336
+ };
337
+
338
+ const result = extractObservationReferenceRanges(resource);
339
+
340
+ expect(result).toEqual({
341
+ lowNormal: 0,
342
+ hiNormal: 50,
343
+ units: undefined,
344
+ });
345
+ });
346
+ });
347
+
348
+ describe('extractObservationInterpretation', () => {
349
+ it('returns undefined when interpretation is missing', () => {
350
+ const resource: FHIRObservationResource = {
351
+ resourceType: 'Observation',
352
+ id: 'test-id',
353
+ category: [],
354
+ code: { coding: [], text: '' },
355
+ effectiveDateTime: '2024-01-01',
356
+ issued: '2024-01-01',
357
+ referenceRange: [],
358
+ };
359
+
360
+ expect(extractObservationInterpretation(resource)).toBeUndefined();
361
+ });
362
+
363
+ it('returns undefined when interpretation is empty array', () => {
364
+ const resource: FHIRObservationResource = {
365
+ resourceType: 'Observation',
366
+ id: 'test-id',
367
+ category: [],
368
+ code: { coding: [], text: '' },
369
+ effectiveDateTime: '2024-01-01',
370
+ issued: '2024-01-01',
371
+ referenceRange: [],
372
+ interpretation: [],
373
+ };
374
+
375
+ expect(extractObservationInterpretation(resource)).toBeUndefined();
376
+ });
377
+
378
+ describe('HL7 v3 ObservationInterpretation codes', () => {
379
+ it('maps LL to CRITICALLY_LOW', () => {
380
+ const resource: FHIRObservationResource = {
381
+ resourceType: 'Observation',
382
+ id: 'test-id',
383
+ category: [],
384
+ code: { coding: [], text: '' },
385
+ effectiveDateTime: '2024-01-01',
386
+ issued: '2024-01-01',
387
+ referenceRange: [],
388
+ interpretation: [
389
+ {
390
+ coding: [{ code: 'LL', display: 'Critically Low' }],
391
+ },
392
+ ],
393
+ };
394
+
395
+ expect(extractObservationInterpretation(resource)).toBe('CRITICALLY_LOW');
396
+ });
397
+
398
+ it('maps HH to CRITICALLY_HIGH', () => {
399
+ const resource: FHIRObservationResource = {
400
+ resourceType: 'Observation',
401
+ id: 'test-id',
402
+ category: [],
403
+ code: { coding: [], text: '' },
404
+ effectiveDateTime: '2024-01-01',
405
+ issued: '2024-01-01',
406
+ referenceRange: [],
407
+ interpretation: [
408
+ {
409
+ coding: [{ code: 'HH', display: 'Critically High' }],
410
+ },
411
+ ],
412
+ };
413
+
414
+ expect(extractObservationInterpretation(resource)).toBe('CRITICALLY_HIGH');
415
+ });
416
+
417
+ it('maps L to LOW', () => {
418
+ const resource: FHIRObservationResource = {
419
+ resourceType: 'Observation',
420
+ id: 'test-id',
421
+ category: [],
422
+ code: { coding: [], text: '' },
423
+ effectiveDateTime: '2024-01-01',
424
+ issued: '2024-01-01',
425
+ referenceRange: [],
426
+ interpretation: [
427
+ {
428
+ coding: [{ code: 'L', display: 'Low' }],
429
+ },
430
+ ],
431
+ };
432
+
433
+ expect(extractObservationInterpretation(resource)).toBe('LOW');
434
+ });
435
+
436
+ it('maps H to HIGH', () => {
437
+ const resource: FHIRObservationResource = {
438
+ resourceType: 'Observation',
439
+ id: 'test-id',
440
+ category: [],
441
+ code: { coding: [], text: '' },
442
+ effectiveDateTime: '2024-01-01',
443
+ issued: '2024-01-01',
444
+ referenceRange: [],
445
+ interpretation: [
446
+ {
447
+ coding: [{ code: 'H', display: 'High' }],
448
+ },
449
+ ],
450
+ };
451
+
452
+ expect(extractObservationInterpretation(resource)).toBe('HIGH');
453
+ });
454
+
455
+ it('maps N to NORMAL', () => {
456
+ const resource: FHIRObservationResource = {
457
+ resourceType: 'Observation',
458
+ id: 'test-id',
459
+ category: [],
460
+ code: { coding: [], text: '' },
461
+ effectiveDateTime: '2024-01-01',
462
+ issued: '2024-01-01',
463
+ referenceRange: [],
464
+ interpretation: [
465
+ {
466
+ coding: [{ code: 'N', display: 'Normal' }],
467
+ },
468
+ ],
469
+ };
470
+
471
+ expect(extractObservationInterpretation(resource)).toBe('NORMAL');
472
+ });
473
+
474
+ it('maps LU to OFF_SCALE_LOW', () => {
475
+ const resource: FHIRObservationResource = {
476
+ resourceType: 'Observation',
477
+ id: 'test-id',
478
+ category: [],
479
+ code: { coding: [], text: '' },
480
+ effectiveDateTime: '2024-01-01',
481
+ issued: '2024-01-01',
482
+ referenceRange: [],
483
+ interpretation: [
484
+ {
485
+ coding: [{ code: 'LU', display: 'Off Scale Low' }],
486
+ },
487
+ ],
488
+ };
489
+
490
+ expect(extractObservationInterpretation(resource)).toBe('OFF_SCALE_LOW');
491
+ });
492
+
493
+ it('maps HU to OFF_SCALE_HIGH', () => {
494
+ const resource: FHIRObservationResource = {
495
+ resourceType: 'Observation',
496
+ id: 'test-id',
497
+ category: [],
498
+ code: { coding: [], text: '' },
499
+ effectiveDateTime: '2024-01-01',
500
+ issued: '2024-01-01',
501
+ referenceRange: [],
502
+ interpretation: [
503
+ {
504
+ coding: [{ code: 'HU', display: 'Off Scale High' }],
505
+ },
506
+ ],
507
+ };
508
+
509
+ expect(extractObservationInterpretation(resource)).toBe('OFF_SCALE_HIGH');
510
+ });
511
+
512
+ it('handles case-insensitive codes', () => {
513
+ const resource: FHIRObservationResource = {
514
+ resourceType: 'Observation',
515
+ id: 'test-id',
516
+ category: [],
517
+ code: { coding: [], text: '' },
518
+ effectiveDateTime: '2024-01-01',
519
+ issued: '2024-01-01',
520
+ referenceRange: [],
521
+ interpretation: [
522
+ {
523
+ coding: [{ code: 'll', display: 'Critically Low' }],
524
+ },
525
+ ],
526
+ };
527
+
528
+ expect(extractObservationInterpretation(resource)).toBe('CRITICALLY_LOW');
529
+ });
530
+ });
531
+
532
+ describe('Display value mapping', () => {
533
+ it('maps "Critically Low" to CRITICALLY_LOW', () => {
534
+ const resource: FHIRObservationResource = {
535
+ resourceType: 'Observation',
536
+ id: 'test-id',
537
+ category: [],
538
+ code: { coding: [], text: '' },
539
+ effectiveDateTime: '2024-01-01',
540
+ issued: '2024-01-01',
541
+ referenceRange: [],
542
+ interpretation: [
543
+ {
544
+ coding: [{ code: 'UNKNOWN', display: 'Critically Low' }],
545
+ },
546
+ ],
547
+ };
548
+
549
+ expect(extractObservationInterpretation(resource)).toBe('CRITICALLY_LOW');
550
+ });
551
+
552
+ it('maps "Critically High" to CRITICALLY_HIGH', () => {
553
+ const resource: FHIRObservationResource = {
554
+ resourceType: 'Observation',
555
+ id: 'test-id',
556
+ category: [],
557
+ code: { coding: [], text: '' },
558
+ effectiveDateTime: '2024-01-01',
559
+ issued: '2024-01-01',
560
+ referenceRange: [],
561
+ interpretation: [
562
+ {
563
+ coding: [{ code: 'UNKNOWN', display: 'Critically High' }],
564
+ },
565
+ ],
566
+ };
567
+
568
+ expect(extractObservationInterpretation(resource)).toBe('CRITICALLY_HIGH');
569
+ });
570
+
571
+ it('maps "Low" to LOW', () => {
572
+ const resource: FHIRObservationResource = {
573
+ resourceType: 'Observation',
574
+ id: 'test-id',
575
+ category: [],
576
+ code: { coding: [], text: '' },
577
+ effectiveDateTime: '2024-01-01',
578
+ issued: '2024-01-01',
579
+ referenceRange: [],
580
+ interpretation: [
581
+ {
582
+ coding: [{ code: 'UNKNOWN', display: 'Low' }],
583
+ },
584
+ ],
585
+ };
586
+
587
+ expect(extractObservationInterpretation(resource)).toBe('LOW');
588
+ });
589
+
590
+ it('maps "High" to HIGH', () => {
591
+ const resource: FHIRObservationResource = {
592
+ resourceType: 'Observation',
593
+ id: 'test-id',
594
+ category: [],
595
+ code: { coding: [], text: '' },
596
+ effectiveDateTime: '2024-01-01',
597
+ issued: '2024-01-01',
598
+ referenceRange: [],
599
+ interpretation: [
600
+ {
601
+ coding: [{ code: 'UNKNOWN', display: 'High' }],
602
+ },
603
+ ],
604
+ };
605
+
606
+ expect(extractObservationInterpretation(resource)).toBe('HIGH');
607
+ });
608
+
609
+ it('maps "Normal" to NORMAL', () => {
610
+ const resource: FHIRObservationResource = {
611
+ resourceType: 'Observation',
612
+ id: 'test-id',
613
+ category: [],
614
+ code: { coding: [], text: '' },
615
+ effectiveDateTime: '2024-01-01',
616
+ issued: '2024-01-01',
617
+ referenceRange: [],
618
+ interpretation: [
619
+ {
620
+ coding: [{ code: 'UNKNOWN', display: 'Normal' }],
621
+ },
622
+ ],
623
+ };
624
+
625
+ expect(extractObservationInterpretation(resource)).toBe('NORMAL');
626
+ });
627
+
628
+ it('maps "Off Scale Low" to OFF_SCALE_LOW', () => {
629
+ const resource: FHIRObservationResource = {
630
+ resourceType: 'Observation',
631
+ id: 'test-id',
632
+ category: [],
633
+ code: { coding: [], text: '' },
634
+ effectiveDateTime: '2024-01-01',
635
+ issued: '2024-01-01',
636
+ referenceRange: [],
637
+ interpretation: [
638
+ {
639
+ coding: [{ code: 'UNKNOWN', display: 'Off Scale Low' }],
640
+ },
641
+ ],
642
+ };
643
+
644
+ expect(extractObservationInterpretation(resource)).toBe('OFF_SCALE_LOW');
645
+ });
646
+
647
+ it('maps "Off Scale High" to OFF_SCALE_HIGH', () => {
648
+ const resource: FHIRObservationResource = {
649
+ resourceType: 'Observation',
650
+ id: 'test-id',
651
+ category: [],
652
+ code: { coding: [], text: '' },
653
+ effectiveDateTime: '2024-01-01',
654
+ issued: '2024-01-01',
655
+ referenceRange: [],
656
+ interpretation: [
657
+ {
658
+ coding: [{ code: 'UNKNOWN', display: 'Off Scale High' }],
659
+ },
660
+ ],
661
+ };
662
+
663
+ expect(extractObservationInterpretation(resource)).toBe('OFF_SCALE_HIGH');
664
+ });
665
+
666
+ it('handles case-insensitive display values', () => {
667
+ const resource: FHIRObservationResource = {
668
+ resourceType: 'Observation',
669
+ id: 'test-id',
670
+ category: [],
671
+ code: { coding: [], text: '' },
672
+ effectiveDateTime: '2024-01-01',
673
+ issued: '2024-01-01',
674
+ referenceRange: [],
675
+ interpretation: [
676
+ {
677
+ coding: [{ code: 'UNKNOWN', display: 'CRITICALLY LOW' }],
678
+ },
679
+ ],
680
+ };
681
+
682
+ expect(extractObservationInterpretation(resource)).toBe('CRITICALLY_LOW');
683
+ });
684
+
685
+ it('handles display values with extra whitespace', () => {
686
+ const resource: FHIRObservationResource = {
687
+ resourceType: 'Observation',
688
+ id: 'test-id',
689
+ category: [],
690
+ code: { coding: [], text: '' },
691
+ effectiveDateTime: '2024-01-01',
692
+ issued: '2024-01-01',
693
+ referenceRange: [],
694
+ interpretation: [
695
+ {
696
+ coding: [{ code: 'UNKNOWN', display: ' Critically Low ' }],
697
+ },
698
+ ],
699
+ };
700
+
701
+ expect(extractObservationInterpretation(resource)).toBe('CRITICALLY_LOW');
702
+ });
703
+ });
704
+
705
+ describe('Fallback behavior', () => {
706
+ it('falls back to display when code is unknown', () => {
707
+ const resource: FHIRObservationResource = {
708
+ resourceType: 'Observation',
709
+ id: 'test-id',
710
+ category: [],
711
+ code: { coding: [], text: '' },
712
+ effectiveDateTime: '2024-01-01',
713
+ issued: '2024-01-01',
714
+ referenceRange: [],
715
+ interpretation: [
716
+ {
717
+ coding: [{ code: 'UNKNOWN_CODE', display: 'High' }],
718
+ },
719
+ ],
720
+ };
721
+
722
+ expect(extractObservationInterpretation(resource)).toBe('HIGH');
723
+ });
724
+
725
+ it('falls back to text when coding is missing', () => {
726
+ const resource: FHIRObservationResource = {
727
+ resourceType: 'Observation',
728
+ id: 'test-id',
729
+ category: [],
730
+ code: { coding: [], text: '' },
731
+ effectiveDateTime: '2024-01-01',
732
+ issued: '2024-01-01',
733
+ referenceRange: [],
734
+ interpretation: [
735
+ {
736
+ coding: [],
737
+ text: 'Normal',
738
+ },
739
+ ],
740
+ };
741
+
742
+ expect(extractObservationInterpretation(resource)).toBe('NORMAL');
743
+ });
744
+
745
+ it('returns undefined for unknown codes and displays', () => {
746
+ const resource: FHIRObservationResource = {
747
+ resourceType: 'Observation',
748
+ id: 'test-id',
749
+ category: [],
750
+ code: { coding: [], text: '' },
751
+ effectiveDateTime: '2024-01-01',
752
+ issued: '2024-01-01',
753
+ referenceRange: [],
754
+ interpretation: [
755
+ {
756
+ coding: [{ code: 'UNKNOWN', display: 'Unknown Value' }],
757
+ },
758
+ ],
759
+ };
760
+
761
+ expect(extractObservationInterpretation(resource)).toBeUndefined();
762
+ });
763
+ });
764
+
765
+ it('uses first interpretation when multiple are present', () => {
766
+ const resource: FHIRObservationResource = {
767
+ resourceType: 'Observation',
768
+ id: 'test-id',
769
+ category: [],
770
+ code: { coding: [], text: '' },
771
+ effectiveDateTime: '2024-01-01',
772
+ issued: '2024-01-01',
773
+ referenceRange: [],
774
+ interpretation: [
775
+ {
776
+ coding: [{ code: 'L', display: 'Low' }],
777
+ },
778
+ {
779
+ coding: [{ code: 'H', display: 'High' }],
780
+ },
781
+ ],
782
+ };
783
+
784
+ expect(extractObservationInterpretation(resource)).toBe('LOW');
785
+ });
786
+
787
+ it('handles ObsRecord type input', () => {
788
+ const obsRecord: ObsRecord = {
789
+ resourceType: 'Observation',
790
+ id: 'test-id',
791
+ category: [],
792
+ code: { coding: [], text: '' },
793
+ effectiveDateTime: '2024-01-01',
794
+ issued: '2024-01-01',
795
+ encounter: {
796
+ reference: 'Encounter/test-encounter',
797
+ type: 'Encounter',
798
+ },
799
+ referenceRange: [],
800
+ // Add interpretation array for extraction function (ObsRecord has [_: string]: any)
801
+ interpretation: [
802
+ {
803
+ coding: [{ code: 'H', display: 'High' }],
804
+ },
805
+ ] as any,
806
+ conceptClass: 'test-uuid',
807
+ value: '25',
808
+ name: 'Test',
809
+ };
810
+
811
+ expect(extractObservationInterpretation(obsRecord)).toBe('HIGH');
812
+ });
813
+
814
+ it('handles missing coding array', () => {
815
+ const resource: FHIRObservationResource = {
816
+ resourceType: 'Observation',
817
+ id: 'test-id',
818
+ category: [],
819
+ code: { coding: [], text: '' },
820
+ effectiveDateTime: '2024-01-01',
821
+ issued: '2024-01-01',
822
+ referenceRange: [],
823
+ interpretation: [
824
+ {
825
+ coding: [],
826
+ text: 'Normal',
827
+ },
828
+ ],
829
+ };
830
+
831
+ expect(extractObservationInterpretation(resource)).toBe('NORMAL');
832
+ });
833
+ });
834
+ });