onc_certification_g10_test_kit 3.1.0 → 3.3.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/lib/inferno/terminology/expected_manifest.yml +36 -693
- data/lib/inferno/terminology/fhir_package_manager.rb +16 -14
- data/lib/inferno/terminology/loader.rb +25 -3
- data/lib/inferno/terminology/tasks/create_value_set_validators.rb +3 -3
- data/lib/inferno/terminology/tasks/download_umls.rb +3 -2
- data/lib/inferno/terminology/tasks/expand_value_set_to_file.rb +1 -1
- data/lib/inferno/terminology/tasks/run_umls_jar.rb +2 -1
- data/lib/inferno/terminology/tasks/validate_code.rb +1 -1
- data/lib/inferno/terminology/terminology_validation.rb +1 -1
- data/lib/inferno/terminology/validator.rb +9 -9
- data/lib/inferno/terminology/value_set.rb +65 -63
- data/lib/onc_certification_g10_test_kit/authorization_request_builder.rb +2 -2
- data/lib/onc_certification_g10_test_kit/bulk_data_authorization.rb +4 -4
- data/lib/onc_certification_g10_test_kit/bulk_data_group_export_stu1.rb +3 -1
- data/lib/onc_certification_g10_test_kit/bulk_data_group_export_validation.rb +7 -4
- data/lib/onc_certification_g10_test_kit/bulk_export_validation_tester.rb +5 -14
- data/lib/onc_certification_g10_test_kit/configuration_checker.rb +23 -1
- data/lib/onc_certification_g10_test_kit/export_kick_off_performer.rb +2 -2
- data/lib/onc_certification_g10_test_kit/g10_options.rb +46 -0
- data/lib/onc_certification_g10_test_kit/incorrectly_permitted_tls_versions_messages_setup_test.rb +34 -0
- data/lib/onc_certification_g10_test_kit/limited_scope_grant_test.rb +3 -1
- data/lib/onc_certification_g10_test_kit/multi_patient_api_stu1.rb +11 -0
- data/lib/onc_certification_g10_test_kit/multi_patient_api_stu2.rb +10 -0
- data/lib/onc_certification_g10_test_kit/onc_program_procedure.yml +1 -0
- data/lib/onc_certification_g10_test_kit/patient_scope_test.rb +25 -0
- data/lib/onc_certification_g10_test_kit/profile_selector.rb +33 -25
- data/lib/onc_certification_g10_test_kit/resource_access_test.rb +1 -2
- data/lib/onc_certification_g10_test_kit/restricted_resource_type_access_group.rb +2 -2
- data/lib/onc_certification_g10_test_kit/short_id_manager.rb +46 -0
- data/lib/onc_certification_g10_test_kit/short_id_map.yml +1538 -0
- data/lib/onc_certification_g10_test_kit/single_patient_api_group.rb +4 -0
- data/lib/onc_certification_g10_test_kit/single_patient_us_core_4_api_group.rb +4 -0
- data/lib/onc_certification_g10_test_kit/single_patient_us_core_5_api_group.rb +4 -0
- data/lib/onc_certification_g10_test_kit/smart_app_launch_invalid_aud_group.rb +2 -2
- data/lib/onc_certification_g10_test_kit/smart_ehr_patient_launch_group.rb +27 -4
- data/lib/onc_certification_g10_test_kit/smart_ehr_patient_launch_group_stu2.rb +27 -4
- data/lib/onc_certification_g10_test_kit/smart_ehr_practitioner_app_group.rb +58 -7
- data/lib/onc_certification_g10_test_kit/smart_invalid_pkce_group.rb +1 -1
- data/lib/onc_certification_g10_test_kit/smart_invalid_token_group.rb +1 -1
- data/lib/onc_certification_g10_test_kit/smart_invalid_token_group_stu2.rb +1 -1
- data/lib/onc_certification_g10_test_kit/smart_limited_app_group.rb +3 -2
- data/lib/onc_certification_g10_test_kit/smart_scopes_test.rb +4 -2
- data/lib/onc_certification_g10_test_kit/smart_standalone_patient_app_group.rb +57 -6
- data/lib/onc_certification_g10_test_kit/tasks/test_procedure.rb +1 -1
- data/lib/onc_certification_g10_test_kit/terminology_binding_validator.rb +1 -1
- data/lib/onc_certification_g10_test_kit/unrestricted_resource_type_access_group.rb +7 -4
- data/lib/onc_certification_g10_test_kit/version.rb +1 -1
- data/lib/onc_certification_g10_test_kit/visual_inspection_and_attestations_group.rb +52 -2
- data/lib/onc_certification_g10_test_kit/well_known_capabilities_test.rb +3 -1
- data/lib/onc_certification_g10_test_kit.rb +41 -23
- metadata +22 -17
@@ -11,28 +11,30 @@ module Inferno
|
|
11
11
|
class << self
|
12
12
|
REGISTRY_SERVER_URL = 'https://packages.fhir.org'.freeze
|
13
13
|
REQUIRED_VSAC_VALUE_SET_URLS = [
|
14
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1186.8',
|
15
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1099.30',
|
16
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1010.6',
|
17
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1010.4',
|
18
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.11.20.9.38',
|
19
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.1066',
|
20
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.1.11.10267',
|
21
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1099.27',
|
22
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.88.12.80.17',
|
23
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1010.5',
|
24
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1021.32',
|
25
14
|
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.836',
|
26
15
|
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.1.11.14914',
|
27
16
|
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.837',
|
28
17
|
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.877',
|
29
18
|
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1',
|
30
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1186.1',
|
31
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.88.12.80.17',
|
32
19
|
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1021.102',
|
33
20
|
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1021.103',
|
34
|
-
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1186.2',
|
35
21
|
'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.2074.1.1.3'
|
22
|
+
# The ValueSets below are needed when building all of the terminology
|
23
|
+
# rather than only the terminology for required bindings.
|
24
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1186.8',
|
25
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1099.30',
|
26
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1010.6',
|
27
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1010.4',
|
28
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.11.20.9.38',
|
29
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.1066',
|
30
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.1.11.10267',
|
31
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1099.27',
|
32
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.88.12.80.17',
|
33
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1010.5',
|
34
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1021.32',
|
35
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1186.1',
|
36
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.88.12.80.17',
|
37
|
+
# 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1186.2'
|
36
38
|
].freeze
|
37
39
|
|
38
40
|
# Get the FHIR Package from the registry.
|
@@ -57,7 +57,6 @@ module Inferno
|
|
57
57
|
code_systems << 'urn:oid:2.16.840.1.113883.6.13'
|
58
58
|
end
|
59
59
|
code_systems << 'urn:oid:2.16.840.1.113883.6.101' if code_systems.include? 'http://nucc.org/provider-taxonomy'
|
60
|
-
code_systems << 'urn:oid:2.16.840.1.113883.6.101' if code_systems.include? 'http://hl7.org/fhir/questionnaire-answers-status'
|
61
60
|
code_systems.uniq!
|
62
61
|
end
|
63
62
|
|
@@ -108,7 +107,7 @@ module Inferno
|
|
108
107
|
file: name_by_type(File.basename(filename), type),
|
109
108
|
count: new_count,
|
110
109
|
type: type.to_s,
|
111
|
-
code_systems:
|
110
|
+
code_systems:
|
112
111
|
}
|
113
112
|
rescue UnknownCodeSystemException,
|
114
113
|
FilterOperationException,
|
@@ -184,11 +183,34 @@ module Inferno
|
|
184
183
|
File.write(metadata_path, metadata.to_yaml)
|
185
184
|
end
|
186
185
|
|
186
|
+
def value_sets_to_load
|
187
|
+
@value_sets_to_load ||=
|
188
|
+
YAML.load_file(File.join('resources', 'value_sets.yml'))
|
189
|
+
end
|
190
|
+
|
191
|
+
# Run this method in an inferno console to update the list of value set
|
192
|
+
# bindings. This is not done automatically during the build because
|
193
|
+
# Inferno isn't loaded during the build process.
|
194
|
+
def save_new_value_set_list
|
195
|
+
all_metadata =
|
196
|
+
USCoreTestKit::USCoreV311::USCoreTestSuite.metadata +
|
197
|
+
USCoreTestKit::USCoreV400::USCoreTestSuite.metadata +
|
198
|
+
USCoreTestKit::USCoreV501::USCoreTestSuite.metadata
|
199
|
+
|
200
|
+
all_metadata =
|
201
|
+
all_metadata
|
202
|
+
.flat_map { |metadata| metadata.bindings.map { |bind| bind.merge(profile_url: metadata.profile_url) } }
|
203
|
+
.select { |metadata| metadata[:strength] == 'required' }
|
204
|
+
.uniq
|
205
|
+
|
206
|
+
File.write(File.join('resources', 'value_sets.yml'), all_metadata.to_yaml)
|
207
|
+
end
|
208
|
+
|
187
209
|
# NOTE: resources/value_sets.yml controls which value sets get loaded.
|
188
210
|
# It is currently manually generated from the US Core metadata.
|
189
211
|
def get_value_sets(strengths)
|
190
212
|
expected_vs_urls =
|
191
|
-
|
213
|
+
value_sets_to_load
|
192
214
|
.select { |vs| strengths.include? vs[:strength] }
|
193
215
|
.map! { |vs| vs[:system] }
|
194
216
|
.compact
|
@@ -19,9 +19,9 @@ module Inferno
|
|
19
19
|
Loader.register_umls_db db_for_version
|
20
20
|
Loader.load_value_sets_from_directory(PACKAGE_DIR, true)
|
21
21
|
Loader.create_validators(
|
22
|
-
type
|
23
|
-
minimum_binding_strength
|
24
|
-
delete_existing:
|
22
|
+
type:,
|
23
|
+
minimum_binding_strength:,
|
24
|
+
delete_existing:
|
25
25
|
)
|
26
26
|
end
|
27
27
|
|
@@ -11,7 +11,8 @@ module Inferno
|
|
11
11
|
UMLS_FILE_URLS = {
|
12
12
|
'2019' => 'https://download.nlm.nih.gov/umls/kss/2019AB/umls-2019AB-full.zip',
|
13
13
|
'2020' => 'https://download.nlm.nih.gov/umls/kss/2020AB/umls-2020AB-full.zip',
|
14
|
-
'2021' => 'https://download.nlm.nih.gov/umls/kss/2021AA/umls-2021AA-full.zip'
|
14
|
+
'2021' => 'https://download.nlm.nih.gov/umls/kss/2021AA/umls-2021AA-full.zip',
|
15
|
+
'2022' => 'https://download.nlm.nih.gov/umls/kss/2022AA/umls-2022AA-full.zip'
|
15
16
|
}.freeze
|
16
17
|
TICKET_GRANTING_TICKET_URL = 'https://utslogin.nlm.nih.gov/cas/v1/api-key'.freeze
|
17
18
|
|
@@ -98,7 +99,7 @@ module Inferno
|
|
98
99
|
RestClient::Request.execute(
|
99
100
|
method: :get,
|
100
101
|
url: "#{location}?ticket=#{ticket}",
|
101
|
-
headers: { cookie:
|
102
|
+
headers: { cookie: },
|
102
103
|
block_response: block
|
103
104
|
)
|
104
105
|
end
|
@@ -16,7 +16,7 @@ module Inferno
|
|
16
16
|
# Before writing the JSON to a file at the end
|
17
17
|
end_vs = nil if type == 'json'
|
18
18
|
|
19
|
-
%w[
|
19
|
+
%w[2022].each do |version|
|
20
20
|
Loader.register_umls_db File.join(TEMP_DIR, version, 'umls.db')
|
21
21
|
Loader.load_value_sets_from_directory(PACKAGE_DIR, true)
|
22
22
|
vs = Repositories::ValueSets.new.find(value_set_url)
|
@@ -19,7 +19,7 @@ module Inferno
|
|
19
19
|
def run
|
20
20
|
Inferno::Terminology::Loader.load_validators
|
21
21
|
code_display = self.system ? "#{self.system}|#{code}" : code.to_s
|
22
|
-
if validate_code(code
|
22
|
+
if validate_code(code:, system: self.system, value_set_url:)
|
23
23
|
in_system = 'is in'
|
24
24
|
symbol = "\u2713".encode('utf-8').to_s.green
|
25
25
|
else
|
@@ -5,20 +5,20 @@ module Inferno
|
|
5
5
|
class Validator
|
6
6
|
attr_reader :url, :concept_count, :type, :code_systems, :file_name, :bloom_filter
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
@url =
|
10
|
-
@concept_count =
|
11
|
-
@type =
|
12
|
-
@code_systems =
|
13
|
-
@file_name =
|
14
|
-
@bloom_filter =
|
8
|
+
def initialize(metadata)
|
9
|
+
@url = metadata[:url]
|
10
|
+
@concept_count = metadata[:count]
|
11
|
+
@type = metadata[:type]
|
12
|
+
@code_systems = metadata[:code_systems]
|
13
|
+
@file_name = metadata[:file]
|
14
|
+
@bloom_filter = metadata[:bloom_filter]
|
15
15
|
end
|
16
16
|
|
17
17
|
def validate(code:, system: nil)
|
18
18
|
if system
|
19
19
|
raise ProhibitedSystemException, system if TerminologyConfiguration.system_prohibited?(system)
|
20
20
|
|
21
|
-
coding_in_filter?(code
|
21
|
+
coding_in_filter?(code:, system:)
|
22
22
|
elsif contains_prohibited_systems?
|
23
23
|
raise ProhibitedSystemException, prohibited_systems.join(', ') unless code_in_allowed_system?(code)
|
24
24
|
|
@@ -52,7 +52,7 @@ module Inferno
|
|
52
52
|
|
53
53
|
def code_in_systems?(code, possible_systems)
|
54
54
|
possible_systems.any? do |possible_system|
|
55
|
-
coding_in_filter?(code
|
55
|
+
coding_in_filter?(code:, system: possible_system)
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -32,9 +32,9 @@ module Inferno
|
|
32
32
|
|
33
33
|
# UMLS Vocabulary: https://www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html
|
34
34
|
SAB = {
|
35
|
-
'http://
|
36
|
-
abbreviation: '
|
37
|
-
name: '
|
35
|
+
'http://unitsofmeasure.org' => {
|
36
|
+
abbreviation: 'NCI_UCUM',
|
37
|
+
name: 'Unified Code for Units of Measure (UCUM)'
|
38
38
|
}.freeze,
|
39
39
|
'http://loinc.org' => {
|
40
40
|
abbreviation: 'LNC',
|
@@ -43,59 +43,61 @@ module Inferno
|
|
43
43
|
'http://snomed.info/sct' => {
|
44
44
|
abbreviation: 'SNOMEDCT_US',
|
45
45
|
name: 'Systematized Nomenclature of Medicine-Clinical Terms (SNOMED CT), US Edition'
|
46
|
-
}.freeze
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
'
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
'
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
'
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
'
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
'
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
'
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
'
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
'
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
'
|
96
|
-
|
97
|
-
|
98
|
-
|
46
|
+
}.freeze
|
47
|
+
# The systems below are needed if building all terminology rather than
|
48
|
+
# only the required bindings.
|
49
|
+
# 'http://www.nlm.nih.gov/research/umls/rxnorm' => {
|
50
|
+
# abbreviation: 'RXNORM',
|
51
|
+
# name: 'RxNorm Vocabulary'
|
52
|
+
# }.freeze,
|
53
|
+
# 'http://www.cms.gov/Medicare/Coding/ICD10' => {
|
54
|
+
# abbreviation: 'ICD10PCS',
|
55
|
+
# name: 'ICD-10 Procedure Coding System (ICD-10-PCS)'
|
56
|
+
# }.freeze,
|
57
|
+
# 'http://hl7.org/fhir/sid/cvx' => {
|
58
|
+
# abbreviation: 'CVX',
|
59
|
+
# name: 'Vaccines Administered (CVX)'
|
60
|
+
# }.freeze,
|
61
|
+
# 'http://hl7.org/fhir/sid/icd-10-cm' => {
|
62
|
+
# abbreviation: 'ICD10CM',
|
63
|
+
# name: 'International Classification of Diseases, Tenth Revision, Clinical Modification (ICD-10-CM)'
|
64
|
+
# }.freeze,
|
65
|
+
# 'http://hl7.org/fhir/sid/icd-9-cm' => {
|
66
|
+
# abbreviation: 'ICD9CM',
|
67
|
+
# name: 'International Classification of Diseases, Ninth Revision, Clinical Modification (ICD-9-CM)'
|
68
|
+
# }.freeze,
|
69
|
+
# 'urn:oid:2.16.840.1.113883.6.101' => {
|
70
|
+
# abbreviation: 'NUCCHCPT',
|
71
|
+
# name: 'National Uniform Claim Committee - Health Care Provider Taxonomy (NUCCHCPT)'
|
72
|
+
# },
|
73
|
+
# 'http://nucc.org/provider-taxonomy' => {
|
74
|
+
# abbreviation: 'NUCCHCPT',
|
75
|
+
# name: 'National Uniform Claim Committee - Health Care Provider Taxonomy (NUCCHCPT)'
|
76
|
+
# }.freeze,
|
77
|
+
# 'http://www.ama-assn.org/go/cpt' => {
|
78
|
+
# abbreviation: 'CPT',
|
79
|
+
# name: 'Current Procedural Terminology (CPT)'
|
80
|
+
# }.freeze,
|
81
|
+
# 'http://www.cms.gov/Medicare/Coding/HCPCSReleaseCodeSets' => {
|
82
|
+
# abbreviation: 'HCPCS',
|
83
|
+
# name: 'Healthcare Common Procedure Coding System (HCPCS)'
|
84
|
+
# }.freeze,
|
85
|
+
# 'urn:oid:2.16.840.1.113883.6.285' => {
|
86
|
+
# abbreviation: 'HCPCS',
|
87
|
+
# name: 'Healthcare Common Procedure Coding System (HCPCS)'
|
88
|
+
# }.freeze,
|
89
|
+
# 'urn:oid:2.16.840.1.113883.6.13' => {
|
90
|
+
# abbreviation: 'CDT',
|
91
|
+
# name: 'Code on Dental Procedures and Nomenclature (CDT)'
|
92
|
+
# }.freeze,
|
93
|
+
# 'http://ada.org/cdt' => {
|
94
|
+
# abbreviation: 'CDT',
|
95
|
+
# name: 'Code on Dental Procedures and Nomenclature (CDT)'
|
96
|
+
# },
|
97
|
+
# 'http://www.ada.org/cdt' => {
|
98
|
+
# abbreviation: 'CDT',
|
99
|
+
# name: 'Code on Dental Procedures and Nomenclature (CDT)'
|
100
|
+
# }
|
99
101
|
}.freeze
|
100
102
|
|
101
103
|
CODE_SYS = {
|
@@ -114,7 +116,7 @@ module Inferno
|
|
114
116
|
'WA', 'WV', 'WI', 'WY', 'AE', 'AP', 'AA'
|
115
117
|
]
|
116
118
|
codes.each_with_object(Set.new) do |code, set|
|
117
|
-
set.add(system: 'https://www.usps.com/', code:
|
119
|
+
set.add(system: 'https://www.usps.com/', code:)
|
118
120
|
end
|
119
121
|
end
|
120
122
|
}.freeze
|
@@ -421,11 +423,11 @@ module Inferno
|
|
421
423
|
@db.execute(
|
422
424
|
"SELECT code FROM mrconso WHERE SAB = '#{umls_abbreviation(system)}' AND TTY IN('PT', 'OP')"
|
423
425
|
) do |row|
|
424
|
-
filtered_set.add(system
|
426
|
+
filtered_set.add(system:, code: row[0])
|
425
427
|
end
|
426
428
|
elsif filter.nil?
|
427
429
|
@db.execute("SELECT code FROM mrconso WHERE SAB = '#{umls_abbreviation(system)}'") do |row|
|
428
|
-
filtered_set.add(system
|
430
|
+
filtered_set.add(system:, code: row[0])
|
429
431
|
end
|
430
432
|
elsif ['=', 'in', nil].include? filter&.op
|
431
433
|
if FILTER_PROP[filter.property]
|
@@ -433,13 +435,13 @@ module Inferno
|
|
433
435
|
"SELECT code FROM mrsat WHERE SAB = '#{umls_abbreviation(system)}' " \
|
434
436
|
"AND ATN = '#{fp_self(filter.property)}' AND ATV = '#{fp_self(filter.value)}'"
|
435
437
|
) do |row|
|
436
|
-
filtered_set.add(system
|
438
|
+
filtered_set.add(system:, code: row[0])
|
437
439
|
end
|
438
440
|
else
|
439
441
|
@db.execute(
|
440
442
|
"SELECT code FROM mrconso WHERE SAB = '#{umls_abbreviation(system)}' AND #{filter_clause.call(filter)}"
|
441
443
|
) do |row|
|
442
|
-
filtered_set.add(system
|
444
|
+
filtered_set.add(system:, code: row[0])
|
443
445
|
end
|
444
446
|
end
|
445
447
|
elsif filter&.op == 'is-a'
|
@@ -484,9 +486,9 @@ module Inferno
|
|
484
486
|
desired_children = Set.new
|
485
487
|
subsume = lambda do |parent|
|
486
488
|
# Only execute if we haven't processed this parent yet
|
487
|
-
par = { system
|
489
|
+
par = { system:, code: parent }
|
488
490
|
unless desired_children.include? par
|
489
|
-
desired_children.add(system
|
491
|
+
desired_children.add(system:, code: parent)
|
490
492
|
children[parent]&.each do |child|
|
491
493
|
subsume.call(child)
|
492
494
|
end
|
@@ -46,7 +46,7 @@ module ONCCertificationG10TestKit
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def jwt_token
|
49
|
-
@jwt_token ||= JSON::JWT.new(iss
|
49
|
+
@jwt_token ||= JSON::JWT.new(iss:, sub:, aud:, exp:, jti:).compact
|
50
50
|
end
|
51
51
|
|
52
52
|
def jwk
|
@@ -55,7 +55,7 @@ module ONCCertificationG10TestKit
|
|
55
55
|
|
56
56
|
def authorization_request_headers
|
57
57
|
{
|
58
|
-
content_type
|
58
|
+
content_type:,
|
59
59
|
accept: 'application/json'
|
60
60
|
}.compact
|
61
61
|
end
|
@@ -87,7 +87,7 @@ module ONCCertificationG10TestKit
|
|
87
87
|
aud: bulk_token_endpoint,
|
88
88
|
grant_type: 'not_a_grant_type')
|
89
89
|
|
90
|
-
post({ client: :token_endpoint }.merge(post_request_content))
|
90
|
+
post(**{ client: :token_endpoint }.merge(post_request_content))
|
91
91
|
|
92
92
|
assert_response_status(400)
|
93
93
|
end
|
@@ -118,7 +118,7 @@ module ONCCertificationG10TestKit
|
|
118
118
|
aud: bulk_token_endpoint,
|
119
119
|
client_assertion_type: 'not_an_assertion_type')
|
120
120
|
|
121
|
-
post({ client: :token_endpoint }.merge(post_request_content))
|
121
|
+
post(**{ client: :token_endpoint }.merge(post_request_content))
|
122
122
|
|
123
123
|
assert_response_status(400)
|
124
124
|
end
|
@@ -157,7 +157,7 @@ module ONCCertificationG10TestKit
|
|
157
157
|
sub: bulk_client_id,
|
158
158
|
aud: bulk_token_endpoint)
|
159
159
|
|
160
|
-
post({ client: :token_endpoint }.merge(post_request_content))
|
160
|
+
post(**{ client: :token_endpoint }.merge(post_request_content))
|
161
161
|
|
162
162
|
assert_response_status([400, 401])
|
163
163
|
end
|
@@ -179,7 +179,7 @@ module ONCCertificationG10TestKit
|
|
179
179
|
sub: bulk_client_id,
|
180
180
|
aud: bulk_token_endpoint)
|
181
181
|
|
182
|
-
authentication_response = post({ client: :token_endpoint }.merge(post_request_content))
|
182
|
+
authentication_response = post(**{ client: :token_endpoint }.merge(post_request_content))
|
183
183
|
|
184
184
|
assert_response_status([200, 201])
|
185
185
|
|
@@ -165,7 +165,7 @@ module ONCCertificationG10TestKit
|
|
165
165
|
polling_url = request.response_header('content-location')&.value
|
166
166
|
assert polling_url.present?, 'Export response headers did not include "Content-Location"'
|
167
167
|
|
168
|
-
output polling_url:
|
168
|
+
output polling_url:
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
@@ -221,6 +221,7 @@ module ONCCertificationG10TestKit
|
|
221
221
|
assert request.response_header('content-type')&.value&.include?('application/json'),
|
222
222
|
'Content-Type not application/json'
|
223
223
|
|
224
|
+
assert_valid_json(response[:body])
|
224
225
|
response_body = JSON.parse(response[:body])
|
225
226
|
|
226
227
|
['transactionTime', 'request', 'requiresAccessToken', 'output', 'error'].each do |key|
|
@@ -255,6 +256,7 @@ module ONCCertificationG10TestKit
|
|
255
256
|
run do
|
256
257
|
assert status_response.present?, 'Bulk Data Server status response not found'
|
257
258
|
|
259
|
+
assert_valid_json(status_response)
|
258
260
|
status_output = JSON.parse(status_response)['output']
|
259
261
|
assert status_output, 'Bulk Data Server status response does not contain output'
|
260
262
|
|
@@ -578,7 +578,7 @@ module ONCCertificationG10TestKit
|
|
578
578
|
for missing data elements and value set verification.
|
579
579
|
DESCRIPTION
|
580
580
|
|
581
|
-
required_suite_options
|
581
|
+
required_suite_options G10Options::US_CORE_5_REQUIREMENT
|
582
582
|
|
583
583
|
include BulkExportValidationTester
|
584
584
|
|
@@ -598,7 +598,8 @@ module ONCCertificationG10TestKit
|
|
598
598
|
conform to the US Core RelatedPerson profile. This includes checking
|
599
599
|
for missing data elements and value set verification.
|
600
600
|
DESCRIPTION
|
601
|
-
|
601
|
+
|
602
|
+
required_suite_options G10Options::US_CORE_5_REQUIREMENT
|
602
603
|
|
603
604
|
include BulkExportValidationTester
|
604
605
|
|
@@ -620,7 +621,8 @@ module ONCCertificationG10TestKit
|
|
620
621
|
data elements and value set verification. This test is omitted if bulk
|
621
622
|
data export does not return any QuestionnaireResponse resources.
|
622
623
|
DESCRIPTION
|
623
|
-
|
624
|
+
|
625
|
+
required_suite_options G10Options::US_CORE_5_REQUIREMENT
|
624
626
|
|
625
627
|
include BulkExportValidationTester
|
626
628
|
|
@@ -642,7 +644,8 @@ module ONCCertificationG10TestKit
|
|
642
644
|
data elements and value set verification. This test is omitted if bulk
|
643
645
|
data export does not return any resources.
|
644
646
|
DESCRIPTION
|
645
|
-
|
647
|
+
|
648
|
+
required_suite_options G10Options::US_CORE_5_REQUIREMENT
|
646
649
|
|
647
650
|
include BulkExportValidationTester
|
648
651
|
|
@@ -4,6 +4,7 @@ module ONCCertificationG10TestKit
|
|
4
4
|
module BulkExportValidationTester
|
5
5
|
include USCoreTestKit::MustSupportTest
|
6
6
|
include ProfileSelector
|
7
|
+
include G10Options
|
7
8
|
|
8
9
|
attr_reader :metadata
|
9
10
|
|
@@ -11,17 +12,6 @@ module ONCCertificationG10TestKit
|
|
11
12
|
MIN_RESOURCE_COUNT = 2
|
12
13
|
OMIT_KLASS = ['Medication', 'Location', 'QuestionnaireResponse', 'PractitionerRole'].freeze
|
13
14
|
|
14
|
-
def versioned_us_core_module
|
15
|
-
case suite_options[:us_core_version]
|
16
|
-
when 'us_core_5'
|
17
|
-
USCoreTestKit::USCoreV501
|
18
|
-
when 'us_core_4'
|
19
|
-
USCoreTestKit::USCoreV400
|
20
|
-
else
|
21
|
-
USCoreTestKit::USCoreV311
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
15
|
def metadata_list
|
26
16
|
@metadata_list ||=
|
27
17
|
versioned_us_core_module::USCoreTestSuite
|
@@ -61,7 +51,7 @@ module ONCCertificationG10TestKit
|
|
61
51
|
end
|
62
52
|
}
|
63
53
|
|
64
|
-
stream(process_body, endpoint, headers:
|
54
|
+
stream(process_body, endpoint, headers:)
|
65
55
|
|
66
56
|
max_redirect = 5
|
67
57
|
|
@@ -76,7 +66,7 @@ module ONCCertificationG10TestKit
|
|
76
66
|
# handle relative redirects
|
77
67
|
redirect_url = URI.parse(endpoint).merge(redirect_url).to_s unless redirect_url.start_with?('http')
|
78
68
|
|
79
|
-
redirect_headers = headers.
|
69
|
+
redirect_headers = headers.except(:authorization)
|
80
70
|
|
81
71
|
stream(process_body, redirect_url, headers: redirect_headers)
|
82
72
|
end
|
@@ -154,7 +144,7 @@ module ONCCertificationG10TestKit
|
|
154
144
|
scratch[:patient_ids_seen] = patient_ids_seen | [resource.id] if resource_type == 'Patient'
|
155
145
|
|
156
146
|
profile_with_version = versioned_profile_url(profile_url)
|
157
|
-
unless resource_is_valid?(resource
|
147
|
+
unless resource_is_valid?(resource:, profile_url: profile_with_version)
|
158
148
|
if first_error.key?(:line_number)
|
159
149
|
@invalid_resource_count += 1
|
160
150
|
else
|
@@ -197,6 +187,7 @@ module ONCCertificationG10TestKit
|
|
197
187
|
skip_if (requires_access_token == 'true' && bearer_token.blank?),
|
198
188
|
'Could not verify this functionality when Bearer Token is required and not provided'
|
199
189
|
|
190
|
+
assert_valid_json(status_output)
|
200
191
|
file_list = JSON.parse(status_output).select { |file| file['type'] == resource_type }
|
201
192
|
if file_list.empty?
|
202
193
|
message = "No #{resource_type} resource file item returned by server."
|
@@ -2,7 +2,7 @@ require_relative '../inferno/terminology/tasks/check_built_terminology'
|
|
2
2
|
|
3
3
|
module ONCCertificationG10TestKit
|
4
4
|
class ConfigurationChecker
|
5
|
-
EXPECTED_VALIDATOR_VERSION = '2.
|
5
|
+
EXPECTED_VALIDATOR_VERSION = '2.2.0'.freeze
|
6
6
|
|
7
7
|
def configuration_messages
|
8
8
|
validator_version_message + terminology_messages + version_message
|
@@ -42,6 +42,19 @@ module ONCCertificationG10TestKit
|
|
42
42
|
}]
|
43
43
|
end
|
44
44
|
|
45
|
+
def code_system_version_messages
|
46
|
+
path = File.join('resources', 'terminology', 'validators', 'bloom', 'metadata.yml')
|
47
|
+
return '' unless File.exist? path
|
48
|
+
|
49
|
+
cs_metadata = YAML.load_file(path)
|
50
|
+
message = "Terminology was generated based on the following code system versions:\n"
|
51
|
+
cs_metadata.each do |_url, metadata|
|
52
|
+
message += "* #{metadata[:name]}: version #{metadata[:versions].join(', ')}\n"
|
53
|
+
end
|
54
|
+
|
55
|
+
message
|
56
|
+
end
|
57
|
+
|
45
58
|
def terminology_messages # rubocop:disable Metrics/CyclomaticComplexity
|
46
59
|
success_messages = []
|
47
60
|
warning_messages = []
|
@@ -64,6 +77,15 @@ module ONCCertificationG10TestKit
|
|
64
77
|
end
|
65
78
|
end
|
66
79
|
|
80
|
+
code_system_messages = code_system_version_messages
|
81
|
+
|
82
|
+
if code_system_version_messages.present?
|
83
|
+
messages << {
|
84
|
+
type: 'info',
|
85
|
+
message: code_system_messages
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
67
89
|
if success_messages.present?
|
68
90
|
messages << {
|
69
91
|
type: 'info',
|
@@ -9,7 +9,7 @@ module ONCCertificationG10TestKit
|
|
9
9
|
url = "Group/#{group_id}/$export"
|
10
10
|
param_str = params.map { |k, v| URI.encode_www_form(k => v) }.join('&')
|
11
11
|
url.concat("?#{param_str}") unless param_str.empty?
|
12
|
-
get(url, client: :bulk_server, name: :export, headers:
|
12
|
+
get(url, client: :bulk_server, name: :export, headers:)
|
13
13
|
end
|
14
14
|
|
15
15
|
def delete_export_kick_off_request
|
@@ -18,7 +18,7 @@ module ONCCertificationG10TestKit
|
|
18
18
|
|
19
19
|
headers = { accept: 'application/json', authorization: "Bearer #{bearer_token}" }
|
20
20
|
|
21
|
-
delete(polling_url, headers:
|
21
|
+
delete(polling_url, headers:)
|
22
22
|
assert_response_status(202)
|
23
23
|
end
|
24
24
|
end
|