ipa_test_kit 0.5.1 → 0.6.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.
- checksums.yaml +4 -4
- data/config/presets/ipa_preset.json +10 -68
- data/lib/ipa_test_kit/custom_groups/v1.0.0/capability_statement_group.rb +5 -3
- data/lib/ipa_test_kit/custom_groups/v1.0.0/ipa_smart_launch_group.rb +28 -4
- data/lib/ipa_test_kit/generated/v1.0.0/allergy_intolerance/metadata.yml +2 -0
- data/lib/ipa_test_kit/generated/v1.0.0/allergy_intolerance_group.rb +5 -3
- data/lib/ipa_test_kit/generated/v1.0.0/condition/metadata.yml +2 -0
- data/lib/ipa_test_kit/generated/v1.0.0/condition_group.rb +5 -3
- data/lib/ipa_test_kit/generated/v1.0.0/document_reference/metadata.yml +2 -0
- data/lib/ipa_test_kit/generated/v1.0.0/document_reference_group.rb +5 -3
- data/lib/ipa_test_kit/generated/v1.0.0/immunization/metadata.yml +2 -0
- data/lib/ipa_test_kit/generated/v1.0.0/immunization_group.rb +5 -3
- data/lib/ipa_test_kit/generated/v1.0.0/ipa_test_suite.rb +16 -3
- data/lib/ipa_test_kit/generated/v1.0.0/medication_group.rb +5 -3
- data/lib/ipa_test_kit/generated/v1.0.0/medication_request/metadata.yml +2 -0
- data/lib/ipa_test_kit/generated/v1.0.0/medication_request_group.rb +5 -3
- data/lib/ipa_test_kit/generated/v1.0.0/medication_statement/metadata.yml +2 -0
- data/lib/ipa_test_kit/generated/v1.0.0/medication_statement_group.rb +5 -3
- data/lib/ipa_test_kit/generated/v1.0.0/metadata.yml +25 -5
- data/lib/ipa_test_kit/generated/v1.0.0/observation/metadata.yml +2 -0
- data/lib/ipa_test_kit/generated/v1.0.0/observation_group.rb +5 -3
- data/lib/ipa_test_kit/generated/v1.0.0/patient_group.rb +5 -3
- data/lib/ipa_test_kit/generated/v1.0.0/practitioner_group.rb +5 -3
- data/lib/ipa_test_kit/generated/v1.0.0/practitioner_role/metadata.yml +2 -0
- data/lib/ipa_test_kit/generated/v1.0.0/practitioner_role_group.rb +5 -3
- data/lib/ipa_test_kit/generated/v1.0.0/problem_list_item/metadata.yml +4 -1
- data/lib/ipa_test_kit/generated/v1.0.0/problem_list_item_group.rb +5 -3
- data/lib/ipa_test_kit/generated/v1.0.0/vitalsigns/metadata.yml +5 -4
- data/lib/ipa_test_kit/generated/v1.0.0/vitalsigns/vitalsigns_must_support_test.rb +3 -3
- data/lib/ipa_test_kit/generated/v1.0.0/vitalsigns_group.rb +5 -3
- data/lib/ipa_test_kit/generator/must_support_metadata_extractor.rb +4 -273
- data/lib/ipa_test_kit/generator/must_support_test_generator.rb +1 -1
- data/lib/ipa_test_kit/generator/templates/group.rb.erb +5 -3
- data/lib/ipa_test_kit/generator/templates/suite.rb.erb +16 -3
- data/lib/ipa_test_kit/must_support_test.rb +1 -176
- data/lib/ipa_test_kit/version.rb +2 -2
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cec7ab44fc8a476fb8d279146d697e5df79ce050b114dfdcb53e1b27ad007c49
|
4
|
+
data.tar.gz: e52ef2d1823ee1e3d11d46c604bf185ed40264e48333ae85a77602110a540d06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0bcfc06e932dedf245cb36a16d986b160581b4d41dc2fa107c8882662d45dfa1519a19710b8b46f29d1d7d5e3825c060650115c28c2ae8bc92af13830b84c86
|
7
|
+
data.tar.gz: fc95b2fd9c208b9c2e6f4d24aaadf52e0b49ebd744e56dbcf1303d9f97c439b9c04c150f60ea5606f5107d25ecc27a6715f50daff89359c9d7290b6a46c8a74c
|
@@ -11,74 +11,16 @@
|
|
11
11
|
"_type": "text"
|
12
12
|
},
|
13
13
|
{
|
14
|
-
"name": "
|
15
|
-
"
|
16
|
-
"
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
"_description": "OAuth 2.0 scope provided by system to enable all required functionality",
|
25
|
-
"_type": "textarea"
|
26
|
-
},
|
27
|
-
{
|
28
|
-
"name": "use_pkce",
|
29
|
-
"value": "true",
|
30
|
-
"_title": "Proof Key for Code Exchange (PKCE)",
|
31
|
-
"_type": "radio",
|
32
|
-
"_options": {
|
33
|
-
"list_options": [
|
34
|
-
{
|
35
|
-
"label": "Enabled",
|
36
|
-
"value": "true"
|
37
|
-
},
|
38
|
-
{
|
39
|
-
"label": "Disabled",
|
40
|
-
"value": "false"
|
41
|
-
}
|
42
|
-
]
|
43
|
-
},
|
44
|
-
"_locked": true
|
45
|
-
},
|
46
|
-
{
|
47
|
-
"name": "pkce_code_challenge_method",
|
48
|
-
"value": "S256",
|
49
|
-
"_title": "PKCE Code Challenge Method",
|
50
|
-
"_type": "radio",
|
51
|
-
"_optional": true,
|
52
|
-
"_options": {
|
53
|
-
"list_options": [
|
54
|
-
{
|
55
|
-
"label": "S256",
|
56
|
-
"value": "S256"
|
57
|
-
},
|
58
|
-
{
|
59
|
-
"label": "plain",
|
60
|
-
"value": "plain"
|
61
|
-
}
|
62
|
-
]
|
63
|
-
},
|
64
|
-
"_locked": true
|
65
|
-
},
|
66
|
-
{
|
67
|
-
"name": "authorization_method",
|
68
|
-
"value": "get",
|
69
|
-
"_title": "Authorization Method",
|
70
|
-
"_type": "radio",
|
71
|
-
"_options": {
|
72
|
-
"list_options": [
|
73
|
-
{
|
74
|
-
"label": "GET",
|
75
|
-
"value": "get"
|
76
|
-
},
|
77
|
-
{
|
78
|
-
"label": "POST",
|
79
|
-
"value": "post"
|
80
|
-
}
|
81
|
-
]
|
14
|
+
"name": "smart_auth_info",
|
15
|
+
"type": "auth_info",
|
16
|
+
"value": {
|
17
|
+
"auth_type": "public",
|
18
|
+
"use_discovery": "true",
|
19
|
+
"requested_scopes": "launch/patient openid fhirUser offline_access patient/*.rs",
|
20
|
+
"client_id": "SAMPLE_PUBLIC_CLIENT_ID",
|
21
|
+
"auth_request_method": "GET",
|
22
|
+
"pkce_support": "enabled",
|
23
|
+
"pkce_code_challenge_method": "S256"
|
82
24
|
}
|
83
25
|
},
|
84
26
|
{
|
@@ -48,10 +48,12 @@ module IpaTestKit
|
|
48
48
|
)
|
49
49
|
run_as_group
|
50
50
|
|
51
|
-
input :
|
52
|
-
|
51
|
+
input :smart_auth_info,
|
52
|
+
type: :auth_info,
|
53
53
|
optional: true,
|
54
|
-
|
54
|
+
options: {
|
55
|
+
mode: 'access'
|
56
|
+
}
|
55
57
|
|
56
58
|
test from: :tls_version_test,
|
57
59
|
id: :standalone_auth_tls,
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'smart_app_launch/discovery_stu2_group'
|
2
|
+
require 'smart_app_launch/standalone_launch_group_stu2'
|
3
|
+
|
1
4
|
module IpaTestKit
|
2
5
|
module IpaV100
|
3
6
|
class IPASMARTLaunchGroup < Inferno::TestGroup
|
@@ -24,6 +27,20 @@ module IpaTestKit
|
|
24
27
|
group from: :smart_discovery_stu2 do
|
25
28
|
run_as_group
|
26
29
|
|
30
|
+
config(
|
31
|
+
inputs: {
|
32
|
+
smart_auth_info: {
|
33
|
+
name: :smart_auth_info,
|
34
|
+
options: {
|
35
|
+
mode: 'auth',
|
36
|
+
components: [
|
37
|
+
{ name: :auth_type, default: 'public', locked: true }
|
38
|
+
]
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
)
|
43
|
+
|
27
44
|
test do
|
28
45
|
id :ipa_smart_capabilities
|
29
46
|
title 'Server supports required SMART capabilities'
|
@@ -81,10 +98,17 @@ module IpaTestKit
|
|
81
98
|
title: 'SMART Public Standalone Launch',
|
82
99
|
config: {
|
83
100
|
inputs: {
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
101
|
+
smart_auth_info: {
|
102
|
+
options: {
|
103
|
+
mode: 'auth',
|
104
|
+
components: [
|
105
|
+
{ name: :auth_type, default: 'public', locked: true },
|
106
|
+
{ name: :pkce_support, default: 'enabled', locked: true },
|
107
|
+
{ name: :pkce_code_challenge_method, default: 'S256', locked: true },
|
108
|
+
{ name: :requested_scopes, default: 'launch/patient openid fhirUser offline_access patient/*.rs' },
|
109
|
+
{ name: :auth_request_method, default: "GET", locked: false }
|
110
|
+
]
|
111
|
+
}
|
88
112
|
}
|
89
113
|
}
|
90
114
|
}
|
@@ -71,9 +71,11 @@ read succeeds.
|
|
71
71
|
|
72
72
|
id :ipa_v100_allergy_intolerance
|
73
73
|
run_as_group
|
74
|
-
input :
|
75
|
-
|
76
|
-
|
74
|
+
input :smart_auth_info,
|
75
|
+
type: :auth_info,
|
76
|
+
options: {
|
77
|
+
mode: 'access'
|
78
|
+
},
|
77
79
|
optional: true
|
78
80
|
|
79
81
|
def self.metadata
|
@@ -75,9 +75,11 @@ read succeeds.
|
|
75
75
|
|
76
76
|
id :ipa_v100_condition
|
77
77
|
run_as_group
|
78
|
-
input :
|
79
|
-
|
80
|
-
|
78
|
+
input :smart_auth_info,
|
79
|
+
type: :auth_info,
|
80
|
+
options: {
|
81
|
+
mode: 'access'
|
82
|
+
},
|
81
83
|
optional: true
|
82
84
|
|
83
85
|
def self.metadata
|
@@ -82,9 +82,11 @@ read succeeds.
|
|
82
82
|
|
83
83
|
id :ipa_v100_document_reference
|
84
84
|
run_as_group
|
85
|
-
input :
|
86
|
-
|
87
|
-
|
85
|
+
input :smart_auth_info,
|
86
|
+
type: :auth_info,
|
87
|
+
options: {
|
88
|
+
mode: 'access'
|
89
|
+
},
|
88
90
|
optional: true
|
89
91
|
|
90
92
|
def self.metadata
|
@@ -72,9 +72,11 @@ read succeeds.
|
|
72
72
|
|
73
73
|
id :ipa_v100_immunization
|
74
74
|
run_as_group
|
75
|
-
input :
|
76
|
-
|
77
|
-
|
75
|
+
input :smart_auth_info,
|
76
|
+
type: :auth_info,
|
77
|
+
options: {
|
78
|
+
mode: 'access'
|
79
|
+
},
|
78
80
|
optional: true
|
79
81
|
|
80
82
|
def self.metadata
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'inferno/dsl/oauth_credentials'
|
2
1
|
require 'smart_app_launch_test_kit'
|
3
2
|
|
4
3
|
require_relative '../../custom_groups/v1.0.0/capability_statement_group'
|
@@ -75,12 +74,26 @@ module IpaTestKit
|
|
75
74
|
title: 'FHIR Endpoint',
|
76
75
|
description: 'URL of the FHIR endpoint'
|
77
76
|
|
77
|
+
input :smart_auth_info,
|
78
|
+
type: :auth_info,
|
79
|
+
title: 'SMART Authorization Information',
|
80
|
+
optional: true
|
81
|
+
|
78
82
|
fhir_client do
|
79
83
|
url :url
|
80
|
-
|
84
|
+
auth_info :smart_auth_info
|
81
85
|
end
|
82
86
|
|
83
|
-
group from: :ipa_v100_smart_launch
|
87
|
+
group from: :ipa_v100_smart_launch,
|
88
|
+
config: {
|
89
|
+
inputs: {
|
90
|
+
smart_auth_info: { name: :smart_auth_info }
|
91
|
+
# TODO asymmetric smart auth info
|
92
|
+
},
|
93
|
+
outputs: {
|
94
|
+
smart_auth_info: { name: :smart_auth_info }
|
95
|
+
}
|
96
|
+
}
|
84
97
|
|
85
98
|
group do
|
86
99
|
title 'IPA Responder Tests'
|
@@ -44,9 +44,11 @@ read succeeds.
|
|
44
44
|
|
45
45
|
id :ipa_v100_medication
|
46
46
|
run_as_group
|
47
|
-
input :
|
48
|
-
|
49
|
-
|
47
|
+
input :smart_auth_info,
|
48
|
+
type: :auth_info,
|
49
|
+
options: {
|
50
|
+
mode: 'access'
|
51
|
+
},
|
50
52
|
optional: true
|
51
53
|
|
52
54
|
def self.metadata
|
@@ -75,9 +75,11 @@ read succeeds.
|
|
75
75
|
|
76
76
|
id :ipa_v100_medication_request
|
77
77
|
run_as_group
|
78
|
-
input :
|
79
|
-
|
80
|
-
|
78
|
+
input :smart_auth_info,
|
79
|
+
type: :auth_info,
|
80
|
+
options: {
|
81
|
+
mode: 'access'
|
82
|
+
},
|
81
83
|
optional: true
|
82
84
|
|
83
85
|
def self.metadata
|
@@ -71,9 +71,11 @@ read succeeds.
|
|
71
71
|
|
72
72
|
id :ipa_v100_medication_statement
|
73
73
|
run_as_group
|
74
|
-
input :
|
75
|
-
|
76
|
-
|
74
|
+
input :smart_auth_info,
|
75
|
+
type: :auth_info,
|
76
|
+
options: {
|
77
|
+
mode: 'access'
|
78
|
+
},
|
77
79
|
optional: true
|
78
80
|
|
79
81
|
def self.metadata
|
@@ -129,6 +129,8 @@
|
|
129
129
|
- :path: patient
|
130
130
|
:types:
|
131
131
|
- Reference
|
132
|
+
:target_profiles:
|
133
|
+
- http://hl7.org/fhir/uv/ipa/StructureDefinition/ipa-patient
|
132
134
|
:mandatory_elements:
|
133
135
|
- AllergyIntolerance.code
|
134
136
|
- AllergyIntolerance.patient
|
@@ -402,6 +404,8 @@
|
|
402
404
|
- :path: subject
|
403
405
|
:types:
|
404
406
|
- Reference
|
407
|
+
:target_profiles:
|
408
|
+
- http://hl7.org/fhir/uv/ipa/StructureDefinition/ipa-patient
|
405
409
|
:mandatory_elements:
|
406
410
|
- Condition.code
|
407
411
|
- Condition.subject
|
@@ -658,7 +662,8 @@
|
|
658
662
|
:must_supports:
|
659
663
|
:extensions: []
|
660
664
|
:slices:
|
661
|
-
- :
|
665
|
+
- :slice_id: Condition.category:problem-list-item
|
666
|
+
:slice_name: problem-list-item
|
662
667
|
:path: category
|
663
668
|
:discriminator:
|
664
669
|
:type: patternCodeableConcept
|
@@ -673,6 +678,8 @@
|
|
673
678
|
- :path: subject
|
674
679
|
:types:
|
675
680
|
- Reference
|
681
|
+
:target_profiles:
|
682
|
+
- http://hl7.org/fhir/uv/ipa/StructureDefinition/ipa-patient
|
676
683
|
:mandatory_elements:
|
677
684
|
- Condition.category
|
678
685
|
- Condition.code
|
@@ -968,6 +975,8 @@
|
|
968
975
|
- :path: subject
|
969
976
|
:types:
|
970
977
|
- Reference
|
978
|
+
:target_profiles:
|
979
|
+
- http://hl7.org/fhir/uv/ipa/StructureDefinition/ipa-patient
|
971
980
|
- :path: date
|
972
981
|
- :path: author
|
973
982
|
:types:
|
@@ -1229,6 +1238,8 @@
|
|
1229
1238
|
- :path: patient
|
1230
1239
|
:types:
|
1231
1240
|
- Reference
|
1241
|
+
:target_profiles:
|
1242
|
+
- http://hl7.org/fhir/uv/ipa/StructureDefinition/ipa-patient
|
1232
1243
|
- :path: occurrence[x]
|
1233
1244
|
:mandatory_elements:
|
1234
1245
|
- Immunization.status
|
@@ -1556,6 +1567,8 @@
|
|
1556
1567
|
- :path: subject
|
1557
1568
|
:types:
|
1558
1569
|
- Reference
|
1570
|
+
:target_profiles:
|
1571
|
+
- http://hl7.org/fhir/uv/ipa/StructureDefinition/ipa-patient
|
1559
1572
|
- :path: encounter
|
1560
1573
|
:types:
|
1561
1574
|
- Reference
|
@@ -1798,6 +1811,8 @@
|
|
1798
1811
|
- :path: subject
|
1799
1812
|
:types:
|
1800
1813
|
- Reference
|
1814
|
+
:target_profiles:
|
1815
|
+
- http://hl7.org/fhir/uv/ipa/StructureDefinition/ipa-patient
|
1801
1816
|
- :path: context
|
1802
1817
|
:types:
|
1803
1818
|
- Reference
|
@@ -2111,6 +2126,8 @@
|
|
2111
2126
|
- :path: subject
|
2112
2127
|
:types:
|
2113
2128
|
- Reference
|
2129
|
+
:target_profiles:
|
2130
|
+
- http://hl7.org/fhir/uv/ipa/StructureDefinition/ipa-patient
|
2114
2131
|
- :path: effective[x]
|
2115
2132
|
- :path: value[x]
|
2116
2133
|
- :path: dataAbsentReason
|
@@ -2422,7 +2439,8 @@
|
|
2422
2439
|
:must_supports:
|
2423
2440
|
:extensions: []
|
2424
2441
|
:slices:
|
2425
|
-
- :
|
2442
|
+
- :slice_id: Observation.category:VSCat
|
2443
|
+
:slice_name: VSCat
|
2426
2444
|
:path: category
|
2427
2445
|
:discriminator:
|
2428
2446
|
:type: value
|
@@ -2434,10 +2452,10 @@
|
|
2434
2452
|
:elements:
|
2435
2453
|
- :path: status
|
2436
2454
|
- :path: category
|
2437
|
-
- :path: category.coding
|
2438
|
-
- :path: category.coding.system
|
2455
|
+
- :path: category:VSCat.coding
|
2456
|
+
- :path: category:VSCat.coding.system
|
2439
2457
|
:fixed_value: http://terminology.hl7.org/CodeSystem/observation-category
|
2440
|
-
- :path: category.coding.code
|
2458
|
+
- :path: category:VSCat.coding.code
|
2441
2459
|
:fixed_value: vital-signs
|
2442
2460
|
- :path: code
|
2443
2461
|
- :path: subject
|
@@ -2816,6 +2834,8 @@
|
|
2816
2834
|
- :path: practitioner
|
2817
2835
|
:types:
|
2818
2836
|
- Reference
|
2837
|
+
:target_profiles:
|
2838
|
+
- http://hl7.org/fhir/uv/ipa/StructureDefinition/ipa-practitioner
|
2819
2839
|
:mandatory_elements:
|
2820
2840
|
- PractitionerRole.notAvailable.description
|
2821
2841
|
:bindings:
|
@@ -76,9 +76,11 @@ read succeeds.
|
|
76
76
|
|
77
77
|
id :ipa_v100_observation
|
78
78
|
run_as_group
|
79
|
-
input :
|
80
|
-
|
81
|
-
|
79
|
+
input :smart_auth_info,
|
80
|
+
type: :auth_info,
|
81
|
+
options: {
|
82
|
+
mode: 'access'
|
83
|
+
},
|
82
84
|
optional: true
|
83
85
|
input :observation_categories,
|
84
86
|
title: 'Observation categories',
|
@@ -80,9 +80,11 @@ read succeeds.
|
|
80
80
|
|
81
81
|
id :ipa_v100_patient
|
82
82
|
run_as_group
|
83
|
-
input :
|
84
|
-
|
85
|
-
|
83
|
+
input :smart_auth_info,
|
84
|
+
type: :auth_info,
|
85
|
+
options: {
|
86
|
+
mode: 'access'
|
87
|
+
},
|
86
88
|
optional: true
|
87
89
|
|
88
90
|
def self.metadata
|
@@ -44,9 +44,11 @@ read succeeds.
|
|
44
44
|
|
45
45
|
id :ipa_v100_practitioner
|
46
46
|
run_as_group
|
47
|
-
input :
|
48
|
-
|
49
|
-
|
47
|
+
input :smart_auth_info,
|
48
|
+
type: :auth_info,
|
49
|
+
options: {
|
50
|
+
mode: 'access'
|
51
|
+
},
|
50
52
|
optional: true
|
51
53
|
|
52
54
|
def self.metadata
|
@@ -45,9 +45,11 @@ read succeeds.
|
|
45
45
|
|
46
46
|
id :ipa_v100_practitioner_role
|
47
47
|
run_as_group
|
48
|
-
input :
|
49
|
-
|
50
|
-
|
48
|
+
input :smart_auth_info,
|
49
|
+
type: :auth_info,
|
50
|
+
options: {
|
51
|
+
mode: 'access'
|
52
|
+
},
|
51
53
|
optional: true
|
52
54
|
|
53
55
|
def self.metadata
|
@@ -216,7 +216,8 @@
|
|
216
216
|
:must_supports:
|
217
217
|
:extensions: []
|
218
218
|
:slices:
|
219
|
-
- :
|
219
|
+
- :slice_id: Condition.category:problem-list-item
|
220
|
+
:slice_name: problem-list-item
|
220
221
|
:path: category
|
221
222
|
:discriminator:
|
222
223
|
:type: patternCodeableConcept
|
@@ -231,6 +232,8 @@
|
|
231
232
|
- :path: subject
|
232
233
|
:types:
|
233
234
|
- Reference
|
235
|
+
:target_profiles:
|
236
|
+
- http://hl7.org/fhir/uv/ipa/StructureDefinition/ipa-patient
|
234
237
|
:mandatory_elements:
|
235
238
|
- Condition.category
|
236
239
|
- Condition.code
|
@@ -75,9 +75,11 @@ read succeeds.
|
|
75
75
|
|
76
76
|
id :ipa_v100_problem_list_item
|
77
77
|
run_as_group
|
78
|
-
input :
|
79
|
-
|
80
|
-
|
78
|
+
input :smart_auth_info,
|
79
|
+
type: :auth_info,
|
80
|
+
options: {
|
81
|
+
mode: 'access'
|
82
|
+
},
|
81
83
|
optional: true
|
82
84
|
|
83
85
|
def self.metadata
|
@@ -243,7 +243,8 @@
|
|
243
243
|
:must_supports:
|
244
244
|
:extensions: []
|
245
245
|
:slices:
|
246
|
-
- :
|
246
|
+
- :slice_id: Observation.category:VSCat
|
247
|
+
:slice_name: VSCat
|
247
248
|
:path: category
|
248
249
|
:discriminator:
|
249
250
|
:type: value
|
@@ -255,10 +256,10 @@
|
|
255
256
|
:elements:
|
256
257
|
- :path: status
|
257
258
|
- :path: category
|
258
|
-
- :path: category.coding
|
259
|
-
- :path: category.coding.system
|
259
|
+
- :path: category:VSCat.coding
|
260
|
+
- :path: category:VSCat.coding.system
|
260
261
|
:fixed_value: http://terminology.hl7.org/CodeSystem/observation-category
|
261
|
-
- :path: category.coding.code
|
262
|
+
- :path: category:VSCat.coding.code
|
262
263
|
:fixed_value: vital-signs
|
263
264
|
- :path: code
|
264
265
|
- :path: subject
|
@@ -13,10 +13,10 @@ module IpaTestKit
|
|
13
13
|
support elements:
|
14
14
|
|
15
15
|
* Observation.category
|
16
|
-
* Observation.category.coding
|
17
|
-
* Observation.category.coding.code
|
18
|
-
* Observation.category.coding.system
|
19
16
|
* Observation.category:VSCat
|
17
|
+
* Observation.category:VSCat.coding
|
18
|
+
* Observation.category:VSCat.coding.code
|
19
|
+
* Observation.category:VSCat.coding.system
|
20
20
|
* Observation.code
|
21
21
|
* Observation.component
|
22
22
|
* Observation.component.code
|
@@ -76,9 +76,11 @@ read succeeds.
|
|
76
76
|
|
77
77
|
id :ipa_v100_vitalsigns
|
78
78
|
run_as_group
|
79
|
-
input :
|
80
|
-
|
81
|
-
|
79
|
+
input :smart_auth_info,
|
80
|
+
type: :auth_info,
|
81
|
+
options: {
|
82
|
+
mode: 'access'
|
83
|
+
},
|
82
84
|
optional: true
|
83
85
|
|
84
86
|
def self.metadata
|
@@ -1,287 +1,18 @@
|
|
1
1
|
require_relative 'value_extractor'
|
2
2
|
|
3
|
+
require 'inferno'
|
4
|
+
|
3
5
|
module IpaTestKit
|
4
6
|
class Generator
|
5
|
-
class MustSupportMetadataExtractor
|
6
|
-
attr_accessor :profile_elements, :profile, :resource, :ig_resources
|
7
|
-
|
8
|
-
def initialize(profile_elements, profile, resource, ig_resources)
|
9
|
-
self.profile_elements = profile_elements
|
10
|
-
self.profile = profile
|
11
|
-
self.resource = resource
|
12
|
-
self.ig_resources = ig_resources
|
13
|
-
end
|
14
|
-
|
7
|
+
class MustSupportMetadataExtractor < Inferno::DSL::MustSupportMetadataExtractor
|
15
8
|
def must_supports
|
16
|
-
@must_supports =
|
17
|
-
extensions: must_support_extensions,
|
18
|
-
slices: must_support_slices,
|
19
|
-
elements: must_support_elements
|
20
|
-
}
|
9
|
+
@must_supports = super
|
21
10
|
|
22
11
|
handle_special_cases
|
23
12
|
|
24
13
|
@must_supports
|
25
14
|
end
|
26
15
|
|
27
|
-
def all_must_support_elements
|
28
|
-
profile_elements.select { |element| element.mustSupport }
|
29
|
-
end
|
30
|
-
|
31
|
-
def must_support_extension_elements
|
32
|
-
all_must_support_elements.select { |element| element.path.end_with? 'extension' }
|
33
|
-
end
|
34
|
-
|
35
|
-
def must_support_extensions
|
36
|
-
must_support_extension_elements.map do |element|
|
37
|
-
{
|
38
|
-
id: element.id,
|
39
|
-
url: element.type.first.profile.first
|
40
|
-
}
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def must_support_slice_elements
|
45
|
-
all_must_support_elements.select { |element| !element.path.end_with?('extension') && element.sliceName.present? }
|
46
|
-
end
|
47
|
-
|
48
|
-
def sliced_element(slice)
|
49
|
-
profile_elements.find { |element| element.id == slice.path }
|
50
|
-
end
|
51
|
-
|
52
|
-
def discriminators(slice)
|
53
|
-
slice.slicing.discriminator
|
54
|
-
end
|
55
|
-
|
56
|
-
def must_support_pattern_slice_elements
|
57
|
-
must_support_slice_elements.select do |element|
|
58
|
-
discriminators(sliced_element(element)).first.type == 'pattern'
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def pattern_slices
|
63
|
-
must_support_pattern_slice_elements.map do |current_element|
|
64
|
-
{
|
65
|
-
name: current_element.id,
|
66
|
-
path: current_element.path.gsub("#{resource}.", '')
|
67
|
-
}.tap do |metadata|
|
68
|
-
discriminator = discriminators(sliced_element(current_element)).first
|
69
|
-
discriminator_path = discriminator.path
|
70
|
-
discriminator_path = '' if discriminator_path == '$this'
|
71
|
-
pattern_element =
|
72
|
-
if discriminator_path.present?
|
73
|
-
profile_elements.find { |element| element.id == "#{current_element.id}.#{discriminator_path}" }
|
74
|
-
else
|
75
|
-
current_element
|
76
|
-
end
|
77
|
-
|
78
|
-
metadata[:discriminator] =
|
79
|
-
if pattern_element.patternCodeableConcept.present?
|
80
|
-
{
|
81
|
-
type: 'patternCodeableConcept',
|
82
|
-
path: discriminator_path,
|
83
|
-
code: pattern_element.patternCodeableConcept.coding.first.code,
|
84
|
-
system: pattern_element.patternCodeableConcept.coding.first.system
|
85
|
-
}
|
86
|
-
elsif pattern_element.patternCoding.present?
|
87
|
-
{
|
88
|
-
type: 'patternCoding',
|
89
|
-
path: discriminator_path,
|
90
|
-
code: pattern_element.patternCoding.code,
|
91
|
-
system: pattern_element.patternCoding.system
|
92
|
-
}
|
93
|
-
elsif pattern_element.patternIdentifier.present?
|
94
|
-
{
|
95
|
-
type: 'patternIdentifier',
|
96
|
-
path: discriminator_path,
|
97
|
-
system: pattern_element.patternIdentifier.system
|
98
|
-
}
|
99
|
-
elsif pattern_element.binding&.strength == 'required' &&
|
100
|
-
pattern_element.binding&.valueSet.present?
|
101
|
-
|
102
|
-
value_extractor = ValueExactor.new(ig_resources, resource, profile_elements)
|
103
|
-
|
104
|
-
values = value_extractor.values_from_value_set_binding(pattern_element).presence ||
|
105
|
-
value_extractor.values_from_resource_metadata([metadata[:path]]).presence || []
|
106
|
-
|
107
|
-
{
|
108
|
-
type: 'requiredBinding',
|
109
|
-
path: discriminator_path,
|
110
|
-
values: values
|
111
|
-
}
|
112
|
-
else
|
113
|
-
raise StandardError, 'Unsupported discriminator pattern type'
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def must_support_type_slice_elements
|
120
|
-
must_support_slice_elements.select do |element|
|
121
|
-
discriminators(sliced_element(element)).first.type == 'type'
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
def type_slices
|
126
|
-
must_support_type_slice_elements.map do |current_element|
|
127
|
-
discriminator = discriminators(sliced_element(current_element)).first
|
128
|
-
type_path = discriminator.path
|
129
|
-
type_path = '' if type_path == '$this'
|
130
|
-
type_element =
|
131
|
-
if type_path.present?
|
132
|
-
elements.find { |element| element.id == "#{current_element.id}.#{type_path}" }
|
133
|
-
else
|
134
|
-
current_element
|
135
|
-
end
|
136
|
-
|
137
|
-
type_code = type_element.type.first.code
|
138
|
-
|
139
|
-
{
|
140
|
-
name: current_element.id,
|
141
|
-
path: current_element.path.gsub("#{resource}.", ''),
|
142
|
-
discriminator: {
|
143
|
-
type: 'type',
|
144
|
-
code: type_code.upcase_first
|
145
|
-
}
|
146
|
-
}
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
def must_support_value_slice_elements
|
151
|
-
must_support_slice_elements.select do |element|
|
152
|
-
discriminators(sliced_element(element)).first.type == 'value'
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
def value_slices
|
157
|
-
must_support_value_slice_elements.map do |current_element|
|
158
|
-
{
|
159
|
-
name: current_element.id,
|
160
|
-
path: current_element.path.gsub("#{resource}.", ''),
|
161
|
-
discriminator: {
|
162
|
-
type: 'value'
|
163
|
-
}
|
164
|
-
}.tap do |metadata|
|
165
|
-
metadata[:discriminator][:values] = discriminators(sliced_element(current_element)).map do |discriminator|
|
166
|
-
fixed_element = profile_elements.find do |element|
|
167
|
-
element.id.starts_with?(current_element.id) &&
|
168
|
-
element.path == "#{current_element.path}.#{discriminator.path}"
|
169
|
-
end
|
170
|
-
|
171
|
-
{
|
172
|
-
path: discriminator.path,
|
173
|
-
value: fixed_element.fixedUri || fixed_element.fixedCode
|
174
|
-
}
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def must_support_slices
|
181
|
-
pattern_slices + type_slices + value_slices
|
182
|
-
end
|
183
|
-
|
184
|
-
def plain_must_support_elements
|
185
|
-
all_must_support_elements - must_support_extension_elements - must_support_slice_elements
|
186
|
-
end
|
187
|
-
|
188
|
-
def handle_fixed_values(metadata, element)
|
189
|
-
if element.fixedUri.present?
|
190
|
-
metadata[:fixed_value] = element.fixedUri
|
191
|
-
elsif element.patternCodeableConcept.present?
|
192
|
-
metadata[:fixed_value] = element.patternCodeableConcept.coding.first.code
|
193
|
-
metadata[:path] += '.coding.code'
|
194
|
-
elsif element.fixedCode.present?
|
195
|
-
metadata[:fixed_value] = element.fixedCode
|
196
|
-
elsif element.patternIdentifier.present?
|
197
|
-
metadata[:fixed_value] = element.patternIdentifier.system
|
198
|
-
metadata[:path] += '.system'
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
def type_must_support_extension?(extensions)
|
203
|
-
extensions&.any? do |extension|
|
204
|
-
extension.url == 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support' &&
|
205
|
-
extension.valueBoolean
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
def save_type_code?(type)
|
210
|
-
'Reference' == type.code
|
211
|
-
end
|
212
|
-
|
213
|
-
def get_type_must_support_metadata(current_metadata, current_element)
|
214
|
-
current_element.type.map do |type|
|
215
|
-
if type_must_support_extension?(type.extension)
|
216
|
-
metadata =
|
217
|
-
{
|
218
|
-
path: "#{current_metadata[:path].delete_suffix('[x]')}#{type.code.upcase_first}",
|
219
|
-
original_path: current_metadata[:path]
|
220
|
-
}
|
221
|
-
metadata[:type] = [type.code] if save_type_code?(type)
|
222
|
-
handle_type_must_support_target_profiles(type, metadata) if type.code == 'Reference'
|
223
|
-
|
224
|
-
metadata
|
225
|
-
end
|
226
|
-
end.compact
|
227
|
-
end
|
228
|
-
|
229
|
-
def handle_type_must_support_target_profiles(type, metadata)
|
230
|
-
index = 0
|
231
|
-
target_profiles = []
|
232
|
-
|
233
|
-
type.source_hash['_targetProfile']&.each do |hash|
|
234
|
-
if hash.present?
|
235
|
-
element = FHIR::Element.new(hash)
|
236
|
-
target_profiles << type.targetProfile[index] if type_must_support_extension?(element.extension)
|
237
|
-
end
|
238
|
-
index += 1
|
239
|
-
end
|
240
|
-
|
241
|
-
metadata[:target_profiles] = target_profiles if target_profiles.present?
|
242
|
-
end
|
243
|
-
|
244
|
-
def handle_choice_type_in_sliced_element(current_metadata, must_support_elements_metadata)
|
245
|
-
choice_element_metadata = must_support_elements_metadata.find do |metadata|
|
246
|
-
metadata[:original_path].present? &&
|
247
|
-
current_metadata[:path].include?( metadata[:original_path] )
|
248
|
-
end
|
249
|
-
|
250
|
-
if choice_element_metadata.present?
|
251
|
-
current_metadata[:original_path] = current_metadata[:path]
|
252
|
-
current_metadata[:path] = current_metadata[:path].sub(choice_element_metadata[:original_path], choice_element_metadata[:path])
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
def must_support_elements
|
257
|
-
plain_must_support_elements.each_with_object([]) do |current_element, must_support_elements_metadata|
|
258
|
-
{
|
259
|
-
path: current_element.path.gsub("#{resource}.", '')
|
260
|
-
}.tap do |current_metadata|
|
261
|
-
type_must_support_metadata = get_type_must_support_metadata(current_metadata, current_element)
|
262
|
-
|
263
|
-
if type_must_support_metadata.any?
|
264
|
-
must_support_elements_metadata.concat(type_must_support_metadata)
|
265
|
-
else
|
266
|
-
handle_choice_type_in_sliced_element(current_metadata, must_support_elements_metadata)
|
267
|
-
|
268
|
-
supported_types = current_element.type.select { |type| save_type_code?(type) }.map { |type| type.code }
|
269
|
-
current_metadata[:types] = supported_types if supported_types.present?
|
270
|
-
|
271
|
-
handle_type_must_support_target_profiles(current_element.type.first, current_metadata) if current_element.type.first&.code == 'Reference'
|
272
|
-
|
273
|
-
handle_fixed_values(current_metadata, current_element)
|
274
|
-
|
275
|
-
must_support_elements_metadata.delete_if do |metadata|
|
276
|
-
metadata[:path] == current_metadata[:path] && metadata[:fixed_value].blank?
|
277
|
-
end
|
278
|
-
|
279
|
-
must_support_elements_metadata << current_metadata
|
280
|
-
end
|
281
|
-
end
|
282
|
-
end.uniq
|
283
|
-
end
|
284
|
-
|
285
16
|
#### SPECIAL CASE ####
|
286
17
|
|
287
18
|
def handle_special_cases
|
@@ -73,7 +73,7 @@ module IpaTestKit
|
|
73
73
|
|
74
74
|
def build_must_support_list_string
|
75
75
|
slice_names = group_metadata.must_supports[:slices]
|
76
|
-
.map { |slice| slice[:
|
76
|
+
.map { |slice| slice[:slice_id] }
|
77
77
|
|
78
78
|
element_names = group_metadata.must_supports[:elements]
|
79
79
|
.map { |element| "#{resource_type}.#{element[:path]}" }
|
@@ -13,9 +13,11 @@ module IpaTestKit
|
|
13
13
|
run_as_group<% if optional? %>
|
14
14
|
optional
|
15
15
|
<% end %>
|
16
|
-
input :
|
17
|
-
|
18
|
-
|
16
|
+
input :smart_auth_info,
|
17
|
+
type: :auth_info,
|
18
|
+
options: {
|
19
|
+
mode: 'access'
|
20
|
+
},
|
19
21
|
optional: true<% if base_observation_group? %>
|
20
22
|
input :observation_categories,
|
21
23
|
title: 'Observation categories',
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'inferno/dsl/oauth_credentials'
|
2
1
|
require 'smart_app_launch_test_kit'
|
3
2
|
|
4
3
|
require_relative '<%= capability_statement_file_name %>'
|
@@ -63,12 +62,26 @@ module IpaTestKit
|
|
63
62
|
title: 'FHIR Endpoint',
|
64
63
|
description: 'URL of the FHIR endpoint'
|
65
64
|
|
65
|
+
input :smart_auth_info,
|
66
|
+
type: :auth_info,
|
67
|
+
title: 'SMART Authorization Information',
|
68
|
+
optional: true
|
69
|
+
|
66
70
|
fhir_client do
|
67
71
|
url :url
|
68
|
-
|
72
|
+
auth_info :smart_auth_info
|
69
73
|
end
|
70
74
|
|
71
|
-
group from: :<%= smart_launch_group_id
|
75
|
+
group from: :<%= smart_launch_group_id %>,
|
76
|
+
config: {
|
77
|
+
inputs: {
|
78
|
+
smart_auth_info: { name: :smart_auth_info }
|
79
|
+
# TODO asymmetric smart auth info
|
80
|
+
},
|
81
|
+
outputs: {
|
82
|
+
smart_auth_info: { name: :smart_auth_info }
|
83
|
+
}
|
84
|
+
}
|
72
85
|
|
73
86
|
group do
|
74
87
|
title 'IPA Responder Tests'
|
@@ -14,182 +14,7 @@ module IpaTestKit
|
|
14
14
|
def perform_must_support_test(resources)
|
15
15
|
skip_if resources.blank?, "No #{resource_type} resources were found"
|
16
16
|
|
17
|
-
|
18
|
-
missing_slices(resources)
|
19
|
-
missing_extensions(resources)
|
20
|
-
|
21
|
-
handle_must_support_choices if metadata.must_supports[:choices].present?
|
22
|
-
|
23
|
-
if (missing_elements + missing_slices + missing_extensions).length.zero?
|
24
|
-
pass
|
25
|
-
end
|
26
|
-
|
27
|
-
skip "Could not find #{missing_must_support_strings.join(', ')} in the #{resources.length} " \
|
28
|
-
"provided #{resource_type} resource(s)"
|
29
|
-
end
|
30
|
-
|
31
|
-
def handle_must_support_choices
|
32
|
-
missing_elements.delete_if do |element|
|
33
|
-
choices = metadata.must_supports[:choices].find { |choice| choice[:paths]&.include?(element[:path]) }
|
34
|
-
is_any_choice_supported?(choices)
|
35
|
-
end
|
36
|
-
|
37
|
-
missing_extensions.delete_if do |extension|
|
38
|
-
choices = metadata.must_supports[:choices].find { |choice| choice[:extension_ids]&.include?(extension[:id]) }
|
39
|
-
is_any_choice_supported?(choices)
|
40
|
-
end
|
41
|
-
|
42
|
-
missing_slices.delete_if do |slice|
|
43
|
-
choices = metadata.must_supports[:choices].find { |choice| choice[:slice_names]&.include?(slice[:name]) }
|
44
|
-
is_any_choice_supported?(choices)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def is_any_choice_supported? (choices)
|
49
|
-
choices.present? &&
|
50
|
-
(
|
51
|
-
choices[:paths]&.any? { |path| missing_elements.none? { |element| element[:path] == path } } ||
|
52
|
-
choices[:extension_ids]&.any? { |extension_id| missing_extensions.none? { |extension| extension[:id] == extension_id} } ||
|
53
|
-
choices[:slice_names]&.any? { |slice_name| missing_slices.none? { |slice| slice[:name] == slice_name} }
|
54
|
-
)
|
55
|
-
end
|
56
|
-
|
57
|
-
def missing_must_support_strings
|
58
|
-
missing_elements.map { |element_definition| missing_element_string(element_definition) } +
|
59
|
-
missing_slices.map { |slice_definition| slice_definition[:name] } +
|
60
|
-
missing_extensions.map { |extension_definition| extension_definition[:id] }
|
61
|
-
end
|
62
|
-
|
63
|
-
def missing_element_string(element_definition)
|
64
|
-
if element_definition[:fixed_value].present?
|
65
|
-
"#{element_definition[:path]}:#{element_definition[:fixed_value]}"
|
66
|
-
else
|
67
|
-
element_definition[:path]
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def must_support_extensions
|
72
|
-
metadata.must_supports[:extensions]
|
73
|
-
end
|
74
|
-
|
75
|
-
def missing_extensions(resources = [])
|
76
|
-
@missing_extensions ||=
|
77
|
-
must_support_extensions.select do |extension_definition|
|
78
|
-
resources.none? do |resource|
|
79
|
-
resource.extension.any? { |extension| extension.url == extension_definition[:url] }
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def must_support_elements
|
85
|
-
metadata.must_supports[:elements]
|
86
|
-
end
|
87
|
-
|
88
|
-
def missing_elements(resources = [])
|
89
|
-
@missing_elements ||=
|
90
|
-
must_support_elements.select do |element_definition|
|
91
|
-
resources.none? do |resource|
|
92
|
-
path = element_definition[:path] #.delete_suffix('[x]')
|
93
|
-
value_found = find_a_value_at(resource, path) do |value|
|
94
|
-
value_without_extensions =
|
95
|
-
value.respond_to?(:to_hash) ? value.to_hash.reject { |key, _| key == 'extension' } : value
|
96
|
-
|
97
|
-
(value_without_extensions.present? || value_without_extensions == false) &&
|
98
|
-
(element_definition[:fixed_value].blank? || value == element_definition[:fixed_value])
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
# Note that false.present? => false, which is why we need to add this extra check
|
103
|
-
value_found.present? || value_found == false
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
@missing_elements
|
108
|
-
end
|
109
|
-
|
110
|
-
def must_support_slices
|
111
|
-
metadata.must_supports[:slices]
|
112
|
-
end
|
113
|
-
|
114
|
-
def missing_slices(resources = [])
|
115
|
-
@missing_slices ||=
|
116
|
-
must_support_slices.select do |slice|
|
117
|
-
resources.none? do |resource|
|
118
|
-
path = slice[:path] # .delete_suffix('[x]')
|
119
|
-
find_slice(resource, path, slice[:discriminator]).present?
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
def find_slice(resource, path, discriminator)
|
125
|
-
find_a_value_at(resource, path) do |element|
|
126
|
-
case discriminator[:type]
|
127
|
-
when 'patternCodeableConcept'
|
128
|
-
coding_path = discriminator[:path].present? ? "#{discriminator[:path]}.coding" : 'coding'
|
129
|
-
find_a_value_at(element, coding_path) do |coding|
|
130
|
-
coding.code == discriminator[:code] && coding.system == discriminator[:system]
|
131
|
-
end
|
132
|
-
when 'patternCoding'
|
133
|
-
coding_path = discriminator[:path].present? ? discriminator[:path] : ''
|
134
|
-
find_a_value_at(element, coding_path) do |coding|
|
135
|
-
coding.code == discriminator[:code] && coding.system == discriminator[:system]
|
136
|
-
end
|
137
|
-
when 'patternIdentifier'
|
138
|
-
find_a_value_at(element, discriminator[:path]) { |identifier| identifier.system == discriminator[:system] }
|
139
|
-
when 'value'
|
140
|
-
values = discriminator[:values].map { |value| value.merge(path: value[:path].split('.')) }
|
141
|
-
find_slice_by_values(element, values)
|
142
|
-
when 'type'
|
143
|
-
case discriminator[:code]
|
144
|
-
when 'Date'
|
145
|
-
begin
|
146
|
-
Date.parse(element)
|
147
|
-
rescue ArgumentError
|
148
|
-
false
|
149
|
-
end
|
150
|
-
when 'DateTime'
|
151
|
-
begin
|
152
|
-
DateTime.parse(element)
|
153
|
-
rescue ArgumentError
|
154
|
-
false
|
155
|
-
end
|
156
|
-
when 'String'
|
157
|
-
element.is_a? String
|
158
|
-
else
|
159
|
-
element.is_a? FHIR.const_get(discriminator[:code])
|
160
|
-
end
|
161
|
-
when 'requiredBinding'
|
162
|
-
coding_path = discriminator[:path].present? ? "#{discriminator[:path]}.coding" : 'coding'
|
163
|
-
find_a_value_at(element, coding_path) {|coding| discriminator[:values].include?(coding.code) }
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
def find_slice_by_values(element, value_definitions)
|
169
|
-
path_prefixes = value_definitions.map { |value_definition| value_definition[:path].first }.uniq
|
170
|
-
Array.wrap(element).find do |el|
|
171
|
-
path_prefixes.all? do |path_prefix|
|
172
|
-
value_definitions_for_path =
|
173
|
-
value_definitions
|
174
|
-
.select { |value_definition| value_definition[:path].first == path_prefix }
|
175
|
-
.each { |value_definition| value_definition[:path].shift }
|
176
|
-
|
177
|
-
find_a_value_at(el, path_prefix) do |el_found|
|
178
|
-
child_element_value_definitions, current_element_value_definitions =
|
179
|
-
value_definitions_for_path.partition { |value_definition| value_definition[:path].present? }
|
180
|
-
|
181
|
-
current_element_values_match =
|
182
|
-
current_element_value_definitions
|
183
|
-
.all? { |value_definition| value_definition[:value] == el_found }
|
184
|
-
|
185
|
-
child_element_values_match =
|
186
|
-
child_element_value_definitions.present? ?
|
187
|
-
find_slice_by_values(el_found, child_element_value_definitions) : true
|
188
|
-
|
189
|
-
current_element_values_match && child_element_values_match
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
17
|
+
skip { assert_must_support_elements_present(resources, nil, metadata:) }
|
193
18
|
end
|
194
19
|
end
|
195
20
|
end
|
data/lib/ipa_test_kit/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ipa_test_kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Inferno Core Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-03-
|
11
|
+
date: 2025-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: inferno_core
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.6.
|
19
|
+
version: 0.6.7
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.6.
|
26
|
+
version: 0.6.7
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: smart_app_launch_test_kit
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.6.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.6.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: tls_test_kit
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|