@@ -2,10 +2,47 @@ const fhirpath = require('../src/fhirpath');
2
2
const model = require ( '../fhir-context/r4' ) ;
3
3
const resource = require ( './resources/observation-example.json' ) ;
4
4
5
+ let fetchSpy ;
6
+
7
+ /**
8
+ * Mocks fetch requests.
9
+ * @param {Array } results - an array of fetch response descriptions, each item
10
+ * of which is an array with the RegExp URL as the first item and the response
11
+ * JSON object as the second.
12
+ */
13
+ function mockFetchResults ( results ) {
14
+ fetchSpy = jest . spyOn ( global , 'fetch' ) . mockImplementation (
15
+ ( url ) => new Promise ( ( resolve , _ ) => {
16
+ const mockedResult = results ?. find ( r => r [ 0 ] . test ( url ) ) ?. [ 1 ]
17
+ if ( mockedResult ) {
18
+ resolve ( { json : ( ) => mockedResult } ) ;
19
+ } else {
20
+ console . error ( `"${ url } " is not mocked.` )
21
+ }
22
+ } )
23
+ ) ;
24
+ }
25
+
5
26
describe ( 'Async functions' , ( ) => {
6
27
7
- describe ( '%terminologies' , ( ) => {
8
- it ( 'should support validateVS' , ( done ) => {
28
+ describe ( '%terminologies.validateVS' , ( ) => {
29
+ afterEach ( ( ) => {
30
+ fetchSpy ?. mockRestore ( ) ;
31
+ } )
32
+
33
+ it ( 'should work ' , ( done ) => {
34
+ mockFetchResults ( [
35
+ [ / c o d e = 2 9 4 6 3 - 7 / , {
36
+ "resourceType" : "Parameters" ,
37
+ "parameter" : [
38
+ {
39
+ "name" : "result" ,
40
+ "valueBoolean" : true
41
+ }
42
+ ]
43
+ } ]
44
+ ] ) ;
45
+
9
46
let result = fhirpath . evaluate (
10
47
resource ,
11
48
"%terminologies.validateVS('http://hl7.org/fhir/ValueSet/observation-vitalsignresult', Observation.code.coding[0]).parameter.value" ,
@@ -19,10 +56,45 @@ describe('Async functions', () => {
19
56
done ( ) ;
20
57
} )
21
58
} ) ;
59
+
60
+ it ( 'should throw an error if the params parameter is not a valid URL encoded string' , ( ) => {
61
+ let result = ( ) => fhirpath . evaluate (
62
+ resource ,
63
+ "%terminologies.validateVS('http://hl7.org/fhir/ValueSet/observation-vitalsignresult', Observation.code.coding[0], 'something=???').parameter.value" ,
64
+ { } ,
65
+ model ,
66
+ { async : true , terminologyUrl : "https://lforms-fhir.nlm.nih.gov/baseR4" }
67
+ ) ;
68
+ expect ( result ) . toThrowError ( 'should be a valid URL encoded string' ) ;
69
+ } ) ;
22
70
} ) ;
23
71
24
72
describe ( 'memberOf' , ( ) => {
25
73
it ( 'should work with Codings when async functions are enabled' , ( done ) => {
74
+ mockFetchResults ( [
75
+ [ / c o d e = 2 9 4 6 3 - 7 / , {
76
+ "resourceType" : "Parameters" ,
77
+ "parameter" : [
78
+ {
79
+ "name" : "result" ,
80
+ "valueBoolean" : true
81
+ }
82
+ ]
83
+ } ] ,
84
+ [ / .* / , {
85
+ "resourceType" : "Parameters" ,
86
+ "parameter" : [
87
+ {
88
+ "name" : "result" ,
89
+ "valueBoolean" : false
90
+ } ,
91
+ {
92
+ "name" : "message" ,
93
+ "valueString" : "Unknown code"
94
+ }
95
+ ]
96
+ } ]
97
+ ] ) ;
26
98
27
99
let result = fhirpath . evaluate (
28
100
resource ,
@@ -40,6 +112,17 @@ describe('Async functions', () => {
40
112
41
113
it ( 'should work with CodeableConcept when async functions are enabled' , ( done ) => {
42
114
115
+ mockFetchResults ( [
116
+ [ / V a l u e S e t \/ \$ v a l i d a t e - c o d e / , {
117
+ "resourceType" : "Parameters" ,
118
+ "parameter" : [
119
+ {
120
+ "name" : "result" ,
121
+ "valueBoolean" : true
122
+ }
123
+ ]
124
+ } ]
125
+ ] ) ;
43
126
let result = fhirpath . evaluate (
44
127
resource ,
45
128
"Observation.code.memberOf('http://hl7.org/fhir/ValueSet/observation-vitalsignresult')" ,
@@ -54,7 +137,35 @@ describe('Async functions', () => {
54
137
} )
55
138
} ) ;
56
139
57
- it ( 'should work with Code when async functions are enabled' , ( done ) => {
140
+ it ( 'should work with "code" when async functions are enabled' , ( done ) => {
141
+ mockFetchResults ( [
142
+ [ / V a l u e S e t \? u r l = h t t p % 3 A % 2 F % 2 F h l 7 \. o r g % 2 F f h i r % 2 F V a l u e S e t % 2 F o b s e r v a t i o n - v i t a l s i g n r e s u l t / , {
143
+ "resourceType" : "Bundle" ,
144
+ "entry" : [
145
+ {
146
+ "resource" : {
147
+ "resourceType" : "ValueSet" ,
148
+ "compose" : {
149
+ "include" : [
150
+ {
151
+ "system" : "http://loinc.org" ,
152
+ }
153
+ ]
154
+ }
155
+ }
156
+ }
157
+ ]
158
+ } ] ,
159
+ [ / c o d e = 2 9 4 6 3 - 7 & s y s t e m = h t t p % 3 A % 2 F % 2 F l o i n c \. o r g / , {
160
+ "resourceType" : "Parameters" ,
161
+ "parameter" : [
162
+ {
163
+ "name" : "result" ,
164
+ "valueBoolean" : true
165
+ }
166
+ ]
167
+ } ]
168
+ ] ) ;
58
169
let result = fhirpath . evaluate (
59
170
resource ,
60
171
"Observation.code.coding.code[0].memberOf('http://hl7.org/fhir/ValueSet/observation-vitalsignresult')" ,
@@ -70,6 +181,12 @@ describe('Async functions', () => {
70
181
} ) ;
71
182
72
183
it ( 'should return an empty result when the ValueSet cannot be resolved' , ( done ) => {
184
+ mockFetchResults ( [
185
+ [ / V a l u e S e t \? u r l = h t t p % 3 A % 2 F % 2 F u n k n o w n - v a l u e s e t / , {
186
+ "resourceType" : "Bundle" ,
187
+ "total" : 0 ,
188
+ } ]
189
+ ] ) ;
73
190
let result = fhirpath . evaluate (
74
191
resource ,
75
192
"Observation.code.coding.code[0].memberOf('http://unknown-valueset')" ,
@@ -84,6 +201,109 @@ describe('Async functions', () => {
84
201
} )
85
202
} ) ;
86
203
204
+ it ( 'should work with "code" when there is more than one identical coding system in the ValueSet' , ( done ) => {
205
+ mockFetchResults ( [
206
+ [ / V a l u e S e t \? u r l = h t t p % 3 A % 2 F % 2 F h l 7 \. o r g % 2 F f h i r % 2 F V a l u e S e t % 2 F o b s e r v a t i o n - v i t a l s i g n r e s u l t / , {
207
+ "resourceType" : "Bundle" ,
208
+ "entry" : [
209
+ {
210
+ "resource" : {
211
+ "resourceType" : "ValueSet" ,
212
+ "compose" : {
213
+ "include" : [
214
+ {
215
+ "system" : "http://loinc.org" ,
216
+ } ,
217
+ {
218
+ "system" : "http://loinc.org" ,
219
+ }
220
+ ]
221
+ } ,
222
+ "expansion" : {
223
+ "contains" : [
224
+ {
225
+ "system" : "http://loinc.org" ,
226
+ } ,
227
+ {
228
+ "system" : "http://loinc.org" ,
229
+ }
230
+ ]
231
+ }
232
+ }
233
+ }
234
+ ]
235
+ } ] ,
236
+ [ / c o d e = 2 9 4 6 3 - 7 & s y s t e m = h t t p % 3 A % 2 F % 2 F l o i n c \. o r g / , {
237
+ "resourceType" : "Parameters" ,
238
+ "parameter" : [
239
+ {
240
+ "name" : "result" ,
241
+ "valueBoolean" : true
242
+ }
243
+ ]
244
+ } ]
245
+ ] ) ;
246
+ let result = fhirpath . evaluate (
247
+ resource ,
248
+ "Observation.code.coding.code[0].memberOf('http://hl7.org/fhir/ValueSet/observation-vitalsignresult')" ,
249
+ { } ,
250
+ model ,
251
+ { async : true , terminologyUrl : "https://lforms-fhir.nlm.nih.gov/baseR4" }
252
+ ) ;
253
+ expect ( result instanceof Promise ) . toBe ( true ) ;
254
+ result . then ( ( r ) => {
255
+ expect ( r ) . toEqual ( [ true ] ) ;
256
+ done ( ) ;
257
+ } )
258
+ } ) ;
259
+
260
+ it ( 'should return an empty result when there is more than one different coding system in the ValueSet' , ( done ) => {
261
+ mockFetchResults ( [
262
+ [ / V a l u e S e t \? u r l = h t t p % 3 A % 2 F % 2 F h l 7 \. o r g % 2 F f h i r % 2 F V a l u e S e t % 2 F o b s e r v a t i o n - v i t a l s i g n r e s u l t / , {
263
+ "resourceType" : "Bundle" ,
264
+ "entry" : [
265
+ {
266
+ "resource" : {
267
+ "resourceType" : "ValueSet" ,
268
+ "compose" : {
269
+ "include" : [
270
+ {
271
+ "system" : "http://loinc.org" ,
272
+ } ,
273
+ {
274
+ "system" : "http://loinc.org" ,
275
+ }
276
+ ]
277
+ } ,
278
+ "expansion" : {
279
+ "contains" : [
280
+ {
281
+ "system" : "http://loinc.org" ,
282
+ } ,
283
+ {
284
+ "system" : "http://something-else" ,
285
+ }
286
+ ]
287
+ }
288
+ }
289
+ }
290
+ ]
291
+ } ]
292
+ ] ) ;
293
+ let result = fhirpath . evaluate (
294
+ resource ,
295
+ "Observation.code.coding.code[0].memberOf('http://hl7.org/fhir/ValueSet/observation-vitalsignresult')" ,
296
+ { } ,
297
+ model ,
298
+ { async : true , terminologyUrl : "https://lforms-fhir.nlm.nih.gov/baseR4" }
299
+ ) ;
300
+ expect ( result instanceof Promise ) . toBe ( true ) ;
301
+ result . then ( ( r ) => {
302
+ expect ( r ) . toEqual ( [ ] ) ;
303
+ done ( ) ;
304
+ } )
305
+ } ) ;
306
+
87
307
it ( 'should throw an exception when async functions are disabled' , ( ) => {
88
308
89
309
let result = ( ) => fhirpath . evaluate (
0 commit comments