onc_certification_g10_test_kit 3.1.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|