onc_certification_g10_test_kit 3.2.0 → 3.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/lib/inferno/terminology/loader.rb +1 -1
  3. data/lib/inferno/terminology/tasks/create_value_set_validators.rb +3 -3
  4. data/lib/inferno/terminology/tasks/download_umls.rb +1 -1
  5. data/lib/inferno/terminology/tasks/validate_code.rb +1 -1
  6. data/lib/inferno/terminology/terminology_validation.rb +1 -1
  7. data/lib/inferno/terminology/validator.rb +9 -9
  8. data/lib/inferno/terminology/value_set.rb +7 -7
  9. data/lib/onc_certification_g10_test_kit/authorization_request_builder.rb +2 -2
  10. data/lib/onc_certification_g10_test_kit/bulk_data_authorization.rb +4 -4
  11. data/lib/onc_certification_g10_test_kit/bulk_data_group_export_stu1.rb +1 -1
  12. data/lib/onc_certification_g10_test_kit/bulk_export_validation_tester.rb +3 -3
  13. data/lib/onc_certification_g10_test_kit/configuration_checker.rb +1 -1
  14. data/lib/onc_certification_g10_test_kit/export_kick_off_performer.rb +2 -2
  15. data/lib/onc_certification_g10_test_kit/incorrectly_permitted_tls_versions_messages_setup_test.rb +1 -1
  16. data/lib/onc_certification_g10_test_kit/patient_scope_test.rb +25 -0
  17. data/lib/onc_certification_g10_test_kit/profile_selector.rb +1 -1
  18. data/lib/onc_certification_g10_test_kit/short_id_map.yml +2 -0
  19. data/lib/onc_certification_g10_test_kit/smart_ehr_patient_launch_group.rb +27 -4
  20. data/lib/onc_certification_g10_test_kit/smart_ehr_patient_launch_group_stu2.rb +27 -4
  21. data/lib/onc_certification_g10_test_kit/smart_ehr_practitioner_app_group.rb +0 -1
  22. data/lib/onc_certification_g10_test_kit/smart_invalid_pkce_group.rb +1 -1
  23. data/lib/onc_certification_g10_test_kit/smart_invalid_token_group.rb +1 -1
  24. data/lib/onc_certification_g10_test_kit/smart_invalid_token_group_stu2.rb +1 -1
  25. data/lib/onc_certification_g10_test_kit/smart_standalone_patient_app_group.rb +0 -2
  26. data/lib/onc_certification_g10_test_kit/tasks/test_procedure.rb +1 -1
  27. data/lib/onc_certification_g10_test_kit/terminology_binding_validator.rb +32 -2
  28. data/lib/onc_certification_g10_test_kit/version.rb +1 -1
  29. data/lib/onc_certification_g10_test_kit.rb +16 -3
  30. metadata +18 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 587e4588500ed400853d80eadaff6dee35d30b7957160d8a289944c54542e645
4
- data.tar.gz: e2dd885bc7a30fb1c8f2b0c91b552e3967b762f6c2e4cda9ecaeb13db13b7309
3
+ metadata.gz: 29d1384f7d5a0ae29a25db2bef10d89572ef5112298a21ddc9ec8a7316947a62
4
+ data.tar.gz: 5c4b63d1d7a45c65fc3af1e8d56b466fd99a811a06baedbdf6cd558b1085e3b2
5
5
  SHA512:
6
- metadata.gz: 476ac874567f91de725cb2f88a1d86c5dee9a7163e1fc3b3eec020ad0c9d03419cd02e68562c9edc7574f654db8ad221fb2eb50939b7b683975ce511950b7574
7
- data.tar.gz: b478b9d93e5bedeb2e2eda74a391b8674a4c233a9f76cf91f448df14875d4602c61ac756412119f5f0387ccbf9eea5295513639edd3776c05f4b13d3adab9a17
6
+ metadata.gz: 6a9bc19aa48b0b24bb045368b08e5de4dd1256258a4f17b0ef810a0c02653049ba4b5c300ccb24f1d47f300cca274f816a5d7c8a9e274e8ab7a8d69371885a74
7
+ data.tar.gz: 3bfcbb63b923db092d12cd148911ee7993161799ea6bf25a60b187676ecf923e53935ea7546c7052e4489ff337f0b17c0dcd3078fde3a68dc2033039f7b9a214
@@ -107,7 +107,7 @@ module Inferno
107
107
  file: name_by_type(File.basename(filename), type),
108
108
  count: new_count,
109
109
  type: type.to_s,
110
- code_systems: code_systems
110
+ code_systems:
111
111
  }
112
112
  rescue UnknownCodeSystemException,
113
113
  FilterOperationException,
@@ -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: type,
23
- minimum_binding_strength: minimum_binding_strength,
24
- delete_existing: delete_existing
22
+ type:,
23
+ minimum_binding_strength:,
24
+ delete_existing:
25
25
  )
26
26
  end
27
27
 
@@ -99,7 +99,7 @@ module Inferno
99
99
  RestClient::Request.execute(
100
100
  method: :get,
101
101
  url: "#{location}?ticket=#{ticket}",
102
- headers: { cookie: cookie },
102
+ headers: { cookie: },
103
103
  block_response: block
104
104
  )
105
105
  end
@@ -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: code, system: self.system, value_set_url: value_set_url)
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
@@ -35,7 +35,7 @@ module Inferno
35
35
  validators_repo.find(system) || raise(UnknownCodeSystemException, system)
36
36
  end
37
37
 
38
- validator.validate(code: code, system: system)
38
+ validator.validate(code:, system:)
39
39
  end
40
40
  end
41
41
  end
@@ -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(**params)
9
- @url = params[:url]
10
- @concept_count = params[:count]
11
- @type = params[:type]
12
- @code_systems = params[:code_systems]
13
- @file_name = params[:file]
14
- @bloom_filter = params[: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: code, system: system)
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: code, system: possible_system)
55
+ coding_in_filter?(code:, system: possible_system)
56
56
  end
57
57
  end
58
58
 
@@ -116,7 +116,7 @@ module Inferno
116
116
  'WA', 'WV', 'WI', 'WY', 'AE', 'AP', 'AA'
117
117
  ]
118
118
  codes.each_with_object(Set.new) do |code, set|
119
- set.add(system: 'https://www.usps.com/', code: code)
119
+ set.add(system: 'https://www.usps.com/', code:)
120
120
  end
121
121
  end
122
122
  }.freeze
@@ -423,11 +423,11 @@ module Inferno
423
423
  @db.execute(
424
424
  "SELECT code FROM mrconso WHERE SAB = '#{umls_abbreviation(system)}' AND TTY IN('PT', 'OP')"
425
425
  ) do |row|
426
- filtered_set.add(system: system, code: row[0])
426
+ filtered_set.add(system:, code: row[0])
427
427
  end
428
428
  elsif filter.nil?
429
429
  @db.execute("SELECT code FROM mrconso WHERE SAB = '#{umls_abbreviation(system)}'") do |row|
430
- filtered_set.add(system: system, code: row[0])
430
+ filtered_set.add(system:, code: row[0])
431
431
  end
432
432
  elsif ['=', 'in', nil].include? filter&.op
433
433
  if FILTER_PROP[filter.property]
@@ -435,13 +435,13 @@ module Inferno
435
435
  "SELECT code FROM mrsat WHERE SAB = '#{umls_abbreviation(system)}' " \
436
436
  "AND ATN = '#{fp_self(filter.property)}' AND ATV = '#{fp_self(filter.value)}'"
437
437
  ) do |row|
438
- filtered_set.add(system: system, code: row[0])
438
+ filtered_set.add(system:, code: row[0])
439
439
  end
440
440
  else
441
441
  @db.execute(
442
442
  "SELECT code FROM mrconso WHERE SAB = '#{umls_abbreviation(system)}' AND #{filter_clause.call(filter)}"
443
443
  ) do |row|
444
- filtered_set.add(system: system, code: row[0])
444
+ filtered_set.add(system:, code: row[0])
445
445
  end
446
446
  end
447
447
  elsif filter&.op == 'is-a'
@@ -486,9 +486,9 @@ module Inferno
486
486
  desired_children = Set.new
487
487
  subsume = lambda do |parent|
488
488
  # Only execute if we haven't processed this parent yet
489
- par = { system: system, code: parent }
489
+ par = { system:, code: parent }
490
490
  unless desired_children.include? par
491
- desired_children.add(system: system, code: parent)
491
+ desired_children.add(system:, code: parent)
492
492
  children[parent]&.each do |child|
493
493
  subsume.call(child)
494
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: iss, sub: sub, aud: aud, exp: exp, jti: jti).compact
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: 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: polling_url
168
+ output polling_url:
169
169
  end
170
170
  end
171
171
 
@@ -51,7 +51,7 @@ module ONCCertificationG10TestKit
51
51
  end
52
52
  }
53
53
 
54
- stream(process_body, endpoint, headers: headers)
54
+ stream(process_body, endpoint, headers:)
55
55
 
56
56
  max_redirect = 5
57
57
 
@@ -66,7 +66,7 @@ module ONCCertificationG10TestKit
66
66
  # handle relative redirects
67
67
  redirect_url = URI.parse(endpoint).merge(redirect_url).to_s unless redirect_url.start_with?('http')
68
68
 
69
- redirect_headers = headers.reject { |key, _value| key == :authorization }
69
+ redirect_headers = headers.except(:authorization)
70
70
 
71
71
  stream(process_body, redirect_url, headers: redirect_headers)
72
72
  end
@@ -144,7 +144,7 @@ module ONCCertificationG10TestKit
144
144
  scratch[:patient_ids_seen] = patient_ids_seen | [resource.id] if resource_type == 'Patient'
145
145
 
146
146
  profile_with_version = versioned_profile_url(profile_url)
147
- unless resource_is_valid?(resource: resource, profile_url: profile_with_version)
147
+ unless resource_is_valid?(resource:, profile_url: profile_with_version)
148
148
  if first_error.key?(:line_number)
149
149
  @invalid_resource_count += 1
150
150
  else
@@ -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.1.0'.freeze
5
+ EXPECTED_VALIDATOR_VERSION = '2.2.0'.freeze
6
6
 
7
7
  def configuration_messages
8
8
  validator_version_message + terminology_messages + version_message
@@ -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: 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: headers)
21
+ delete(polling_url, headers:)
22
22
  assert_response_status(202)
23
23
  end
24
24
  end
@@ -17,7 +17,7 @@ module ONCCertificationG10TestKit
17
17
 
18
18
  raw_previous_warning_messages =
19
19
  Inferno::Repositories::SessionData.new.load(
20
- test_session_id: test_session_id,
20
+ test_session_id:,
21
21
  name: 'unique_incorrectly_permitted_tls_versions_messages'
22
22
  )
23
23
 
@@ -0,0 +1,25 @@
1
+ module ONCCertificationG10TestKit
2
+ class PatientScopeTest < Inferno::Test
3
+ title 'Patient-level scopes were granted'
4
+ description %(
5
+ Systems are required to support the `permission-patient` capability as
6
+ part of the [Clinician Access for EHR Launch Capability
7
+ Set.](http://hl7.org/fhir/smart-app-launch/1.0.0/conformance/index.html#clinician-access-for-ehr-launch)
8
+
9
+ This test verifies that systems are capable of granting patient-level
10
+ scopes during an EHR Launch.
11
+ )
12
+ id :g10_patient_scope
13
+ input :received_scopes
14
+
15
+ run do
16
+ expected_scope = if config.options[:scope_version] == :v2
17
+ 'patient/Patient.rs'
18
+ else
19
+ 'patient/Patient.read'
20
+ end
21
+ assert received_scopes&.include?(expected_scope),
22
+ "#{expected_scope} scope was requested, but not received. Received: `#{received_scopes}`"
23
+ end
24
+ end
25
+ end
@@ -135,7 +135,7 @@ module ONCCertificationG10TestKit
135
135
 
136
136
  if using_us_core_5? &&
137
137
  resource_contains_category(
138
- resource, 'clinical-test', 'http://terminology.hl7.org/CodeSystem/observation-category'
138
+ resource, 'clinical-test', 'http://hl7.org/fhir/us/core/CodeSystem/us-core-observation-category'
139
139
  )
140
140
  return extract_profile('ObservationClinicalTest')
141
141
  end
@@ -1507,6 +1507,7 @@ g10_certification-Group06-g10_ehr_patient_launch-smart_token_exchange: 9.8.07
1507
1507
  g10_certification-Group06-g10_ehr_patient_launch-smart_token_response_body: 9.8.08
1508
1508
  g10_certification-Group06-g10_ehr_patient_launch-smart_token_response_headers: 9.8.09
1509
1509
  g10_certification-Group06-g10_ehr_patient_launch-g10_patient_context: 9.8.10
1510
+ g10_certification-Group06-g10_ehr_patient_launch-g10_patient_scope: 9.8.11
1510
1511
  g10_certification-Group06-g10_ehr_patient_launch_stu2: '9.9'
1511
1512
  g10_certification-Group06-g10_ehr_patient_launch_stu2-smart_app_launch: 9.9.01
1512
1513
  g10_certification-Group06-g10_ehr_patient_launch_stu2-smart_launch_received: 9.9.02
@@ -1518,6 +1519,7 @@ g10_certification-Group06-g10_ehr_patient_launch_stu2-smart_token_exchange: 9.9.
1518
1519
  g10_certification-Group06-g10_ehr_patient_launch_stu2-smart_token_response_body: 9.9.08
1519
1520
  g10_certification-Group06-g10_ehr_patient_launch_stu2-smart_token_response_headers: 9.9.09
1520
1521
  g10_certification-Group06-g10_ehr_patient_launch_stu2-g10_patient_context: 9.9.10
1522
+ g10_certification-Group06-g10_ehr_patient_launch_stu2-g10_patient_scope: 9.9.11
1521
1523
  g10_certification-Group06-g10_visual_inspection_and_attestations: '9.10'
1522
1524
  g10_certification-Group06-g10_visual_inspection_and_attestations-Test01: 9.10.01
1523
1525
  g10_certification-Group06-g10_visual_inspection_and_attestations-Test02: 9.10.02
@@ -1,17 +1,29 @@
1
+ require_relative 'patient_scope_test'
2
+
1
3
  module ONCCertificationG10TestKit
2
4
  class SMARTEHRPatientLaunchGroup < SMARTAppLaunch::EHRLaunchGroup
3
5
  title 'EHR Launch with Patient Scopes'
4
6
  description %(
5
7
  # Background
8
+ Systems are required to support the `permission-patient` capability as
9
+ part of the [Clinician Access for EHR Launch Capability
10
+ Set.](http://hl7.org/fhir/smart-app-launch/1.0.0/conformance/index.html#clinician-access-for-ehr-launch)
11
+
12
+ Additionally, if an application launched from an EHR requests and is
13
+ granted a clinical scope restricted to a single patient, the EHR SHALL
14
+ establish a patient in context.
6
15
 
7
- If an application launched from an EHR requests and is granted a clinical
8
- scope restricted to a single patient, the EHR SHALL establish a patient in
9
- context.
16
+ Register Inferno as an EHR-launched application using patient-level scopes
17
+ and the following URIs:
18
+
19
+ * Launch URI: `#{SMARTAppLaunch::AppLaunchTest.config.options[:launch_uri]}`
20
+ * Redirect URI: `#{SMARTAppLaunch::AppRedirectTest.config.options[:redirect_uri]}`
10
21
 
11
22
  # Test Methodology
12
23
 
13
24
  Inferno will attempt an EHR Launch with a clinical scope restricted to a
14
- single patient and verify that a patient id is received.
25
+ single patient and verify that a patient-level scope is granted and a
26
+ patient id is received.
15
27
 
16
28
  For more information on the #{title}
17
29
 
@@ -43,6 +55,9 @@ module ONCCertificationG10TestKit
43
55
  launch: {
44
56
  name: :ehr_patient_launch
45
57
  },
58
+ received_scopes: {
59
+ name: :ehr_patient_received_scopes
60
+ },
46
61
  smart_credentials: {
47
62
  name: :ehr_patient_smart_credentials
48
63
  },
@@ -67,6 +82,7 @@ module ONCCertificationG10TestKit
67
82
  patient_id: { name: :ehr_patient_patient_id },
68
83
  encounter_id: { name: :ehr_patient_encounter_id },
69
84
  received_scopes: { name: :ehr_patient_received_scopes },
85
+ requested_scopes: { name: :ehr_patient_requested_scopes },
70
86
  intent: { name: :ehr_patient_intent },
71
87
  smart_credentials: { name: :ehr_patient_smart_credentials }
72
88
  },
@@ -89,5 +105,12 @@ module ONCCertificationG10TestKit
89
105
  smart_credentials: { name: :ehr_patient_smart_credentials }
90
106
  }
91
107
  }
108
+
109
+ test from: :g10_patient_scope,
110
+ config: {
111
+ options: {
112
+ scope_version: :v1
113
+ }
114
+ }
92
115
  end
93
116
  end
@@ -1,17 +1,29 @@
1
+ require_relative 'patient_scope_test'
2
+
1
3
  module ONCCertificationG10TestKit
2
4
  class SMARTEHRPatientLaunchGroupSTU2 < SMARTAppLaunch::EHRLaunchGroupSTU2
3
5
  title 'EHR Launch with Patient Scopes'
4
6
  description %(
5
7
  # Background
8
+ Systems are required to support the `permission-patient` capability as
9
+ part of the [Clinician Access for EHR Launch Capability
10
+ Set.](http://hl7.org/fhir/smart-app-launch/STU2/conformance.html#clinician-access-for-ehr-launch)
11
+
12
+ Additionally, if an application launched from an EHR requests and is
13
+ granted a clinical scope restricted to a single patient, the EHR SHALL
14
+ establish a patient in context.
6
15
 
7
- If an application launched from an EHR requests and is granted a clinical
8
- scope restricted to a single patient, the EHR SHALL establish a patient in
9
- context.
16
+ Register Inferno as an EHR-launched application using patient-level scopes
17
+ and the following URIs:
18
+
19
+ * Launch URI: `#{SMARTAppLaunch::AppLaunchTest.config.options[:launch_uri]}`
20
+ * Redirect URI: `#{SMARTAppLaunch::AppRedirectTest.config.options[:redirect_uri]}`
10
21
 
11
22
  # Test Methodology
12
23
 
13
24
  Inferno will attempt an EHR Launch with a clinical scope restricted to a
14
- single patient and verify that a patient id is received.
25
+ single patient and verify that a patient-level scope is granted and a
26
+ patient id is received.
15
27
 
16
28
  For more information on the #{title}
17
29
 
@@ -43,6 +55,9 @@ module ONCCertificationG10TestKit
43
55
  launch: {
44
56
  name: :ehr_patient_launch
45
57
  },
58
+ received_scopes: {
59
+ name: :ehr_patient_received_scopes
60
+ },
46
61
  smart_credentials: {
47
62
  name: :ehr_patient_smart_credentials
48
63
  },
@@ -67,6 +82,7 @@ module ONCCertificationG10TestKit
67
82
  patient_id: { name: :ehr_patient_patient_id },
68
83
  encounter_id: { name: :ehr_patient_encounter_id },
69
84
  received_scopes: { name: :ehr_patient_received_scopes },
85
+ requested_scopes: { name: :ehr_patient_requested_scopes },
70
86
  intent: { name: :ehr_patient_intent },
71
87
  smart_credentials: { name: :ehr_patient_smart_credentials }
72
88
  },
@@ -90,5 +106,12 @@ module ONCCertificationG10TestKit
90
106
  smart_credentials: { name: :ehr_patient_smart_credentials }
91
107
  }
92
108
  }
109
+
110
+ test from: :g10_patient_scope,
111
+ config: {
112
+ options: {
113
+ scope_version: :v2
114
+ }
115
+ }
93
116
  end
94
117
  end
@@ -95,7 +95,6 @@ module ONCCertificationG10TestKit
95
95
  'permission-offline',
96
96
  'permission-user',
97
97
  'authorize-post',
98
- 'permission-v1',
99
98
  'permission-v2'
100
99
  ]
101
100
  }
@@ -19,7 +19,7 @@ module ONCCertificationG10TestKit
19
19
 
20
20
  oauth2_params = {
21
21
  grant_type: 'authorization_code',
22
- code: code,
22
+ code:,
23
23
  redirect_uri: config.options[:redirect_uri]
24
24
  }
25
25
 
@@ -186,7 +186,7 @@ module ONCCertificationG10TestKit
186
186
 
187
187
  oauth2_params = {
188
188
  grant_type: 'authorization_code',
189
- code: code,
189
+ code:,
190
190
  redirect_uri: config.options[:redirect_uri]
191
191
  }
192
192
  oauth2_headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
@@ -188,7 +188,7 @@ module ONCCertificationG10TestKit
188
188
 
189
189
  oauth2_params = {
190
190
  grant_type: 'authorization_code',
191
- code: code,
191
+ code:,
192
192
  redirect_uri: config.options[:redirect_uri]
193
193
  }
194
194
  oauth2_headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
@@ -90,9 +90,7 @@ module ONCCertificationG10TestKit
90
90
  'permission-offline',
91
91
  'permission-patient',
92
92
  'authorize-post',
93
- 'permission-v1',
94
93
  'permission-v2'
95
-
96
94
  ]
97
95
  }
98
96
  }
@@ -53,7 +53,7 @@ module ONCCertificationG10TestKit
53
53
  second_prefix, _, ending = second.rpartition('.')
54
54
  raise "'#{prefix}' != '#{second_prefix}' in #{@group} #{@id}" unless prefix == second_prefix
55
55
 
56
- (beginning.to_i..ending.to_i).map { |index| "#{prefix}.#{format('%02<index>d', { index: index })}" }
56
+ (beginning.to_i..ending.to_i).map { |index| "#{prefix}.#{format('%02<index>d', { index: })}" }
57
57
  else
58
58
  [test]
59
59
  end
@@ -18,12 +18,42 @@ module ONCCertificationG10TestKit
18
18
  @validation_messages = []
19
19
  end
20
20
 
21
+ def us_core_5_condition_category?
22
+ binding_definition[:path] == 'category' &&
23
+ binding_definition[:system] == 'http://hl7.org/fhir/us/core/ValueSet/us-core-problem-or-health-concern'
24
+ end
25
+
21
26
  def validate
22
- add_error(element_with_invalid_binding) if element_with_invalid_binding.present?
27
+ # Handle special case due to required binding on a slice
28
+ if us_core_5_condition_category?
29
+ validate_us_core_5_condition_category
30
+ else
31
+ add_error(element_with_invalid_binding) if element_with_invalid_binding.present? # rubocop:disable Style/IfInsideElse
32
+ end
23
33
 
24
34
  validation_messages
25
35
  end
26
36
 
37
+ def validate_us_core_5_condition_category
38
+ valid_category =
39
+ find_a_value_at(path_source, binding_definition[:path]) do |element|
40
+ !invalid_binding?(element)
41
+ end
42
+
43
+ return if valid_category.present?
44
+
45
+ error_message = %(
46
+ #{resource_type}/#{resource.id} does not contain a `category` from the
47
+ `http://hl7.org/fhir/us/core/ValueSet/us-core-problem-or-health-concern`
48
+ ValueSet.
49
+ )
50
+
51
+ validation_messages << {
52
+ type: 'error',
53
+ message: error_message
54
+ }
55
+ end
56
+
27
57
  def path_source
28
58
  return resource if binding_definition[:extensions].blank?
29
59
 
@@ -51,7 +81,7 @@ module ONCCertificationG10TestKit
51
81
  def add_warning(message)
52
82
  validation_messages << {
53
83
  type: 'warning',
54
- message: message
84
+ message:
55
85
  }
56
86
  end
57
87
 
@@ -1,3 +1,3 @@
1
1
  module ONCCertificationG10TestKit
2
- VERSION = '3.2.0'.freeze
2
+ VERSION = '3.3.1'.freeze
3
3
  end
@@ -83,10 +83,23 @@ module ONCCertificationG10TestKit
83
83
  end
84
84
 
85
85
  perform_additional_validation do |resource, profile_url|
86
- metadata = USCoreTestKit::USCoreV311::USCoreTestSuite.metadata.find do |metadata_candidate|
87
- metadata_candidate.profile_url == profile_url
86
+ versionless_profile_url, profile_version = profile_url.split('|')
87
+ profile_version = case profile_version
88
+ when '4.0.0'
89
+ '400'
90
+ when '5.0.1'
91
+ '501'
92
+ else
93
+ # This open-ended else is primarily for Vital Signs profiles in v3.1.1, which are tagged
94
+ # with the base FHIR version (4.0.1). The profiles were migrated to US Core in later
95
+ # versions.
96
+ '311'
97
+ end
98
+
99
+ us_core_suite = USCoreTestKit.const_get("USCoreV#{profile_version}")::USCoreTestSuite
100
+ metadata = us_core_suite.metadata.find do |metadata_candidate|
101
+ metadata_candidate.profile_url == versionless_profile_url
88
102
  end
89
-
90
103
  next if metadata.nil?
91
104
 
92
105
  metadata.bindings
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: onc_certification_g10_test_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 3.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen MacVicar
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-12 00:00:00.000000000 Z
11
+ date: 2022-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bloomer
@@ -44,28 +44,28 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 0.3.11
47
+ version: 0.4.2
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 0.3.11
54
+ version: 0.4.2
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: json-jwt
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 1.13.0
61
+ version: 1.15.3
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 1.13.0
68
+ version: 1.15.3
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: mime-types
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -114,42 +114,42 @@ dependencies:
114
114
  requirements:
115
115
  - - '='
116
116
  - !ruby/object:Gem::Version
117
- version: 0.1.8
117
+ version: 0.2.0
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - '='
123
123
  - !ruby/object:Gem::Version
124
- version: 0.1.8
124
+ version: 0.2.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: tls_test_kit
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - '='
130
130
  - !ruby/object:Gem::Version
131
- version: 0.1.3
131
+ version: 0.2.0
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - '='
137
137
  - !ruby/object:Gem::Version
138
- version: 0.1.3
138
+ version: 0.2.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: us_core_test_kit
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - '='
144
144
  - !ruby/object:Gem::Version
145
- version: 0.3.2
145
+ version: 0.4.1
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - '='
151
151
  - !ruby/object:Gem::Version
152
- version: 0.3.2
152
+ version: 0.4.1
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: database_cleaner-sequel
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -272,6 +272,7 @@ files:
272
272
  - lib/onc_certification_g10_test_kit/multi_patient_api_stu2.rb
273
273
  - lib/onc_certification_g10_test_kit/onc_program_procedure.yml
274
274
  - lib/onc_certification_g10_test_kit/patient_context_test.rb
275
+ - lib/onc_certification_g10_test_kit/patient_scope_test.rb
275
276
  - lib/onc_certification_g10_test_kit/profile_selector.rb
276
277
  - lib/onc_certification_g10_test_kit/resource_access_test.rb
277
278
  - lib/onc_certification_g10_test_kit/restricted_access_test.rb
@@ -309,7 +310,7 @@ licenses:
309
310
  metadata:
310
311
  homepage_uri: https://github.com/onc-healthit/onc-certification-g10-test-kit
311
312
  source_code_uri: https://github.com/onc-healthit/onc-certification-g10-test-kit
312
- post_install_message:
313
+ post_install_message:
313
314
  rdoc_options: []
314
315
  require_paths:
315
316
  - lib
@@ -317,15 +318,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
317
318
  requirements:
318
319
  - - ">="
319
320
  - !ruby/object:Gem::Version
320
- version: 2.7.0
321
+ version: 3.1.2
321
322
  required_rubygems_version: !ruby/object:Gem::Requirement
322
323
  requirements:
323
324
  - - ">="
324
325
  - !ruby/object:Gem::Version
325
326
  version: '0'
326
327
  requirements: []
327
- rubygems_version: 3.1.6
328
- signing_key:
328
+ rubygems_version: 3.3.7
329
+ signing_key:
329
330
  specification_version: 4
330
331
  summary: ONC Certification (g)(10) Test Kit
331
332
  test_files: []