us_core_test_kit 0.8.1 → 0.9.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/us_core_test_kit/custom_groups/base_smart_granular_scopes_group.rb +87 -6
  3. data/lib/us_core_test_kit/custom_groups/smart_app_launch_group.rb +28 -6
  4. data/lib/us_core_test_kit/custom_groups/smart_ehr_launch_stu2_2.rb +40 -0
  5. data/lib/us_core_test_kit/custom_groups/smart_standalone_launch_stu2_2_group.rb +40 -0
  6. data/lib/us_core_test_kit/custom_groups/v3.1.1/capability_statement_group.rb +2 -2
  7. data/lib/us_core_test_kit/custom_groups/v3.1.1/{profile_support_test.rb → resource_support_test.rb} +1 -1
  8. data/lib/us_core_test_kit/custom_groups/v7.0.0/smart_app_launch_group.rb +3 -3
  9. data/lib/us_core_test_kit/custom_groups/v7.0.0/smart_app_launch_stu2_2_group.rb +16 -0
  10. data/lib/us_core_test_kit/custom_groups/v7.0.0/smart_discovery_stu2_2_group.rb +11 -0
  11. data/lib/us_core_test_kit/generated/v3.1.1/us_core_test_suite.rb +8 -2
  12. data/lib/us_core_test_kit/generated/v4.0.0/us_core_test_suite.rb +8 -2
  13. data/lib/us_core_test_kit/generated/v5.0.1/us_core_test_suite.rb +8 -2
  14. data/lib/us_core_test_kit/generated/v6.1.0/diagnostic_report_note/diagnostic_report_note_must_support_test.rb +0 -2
  15. data/lib/us_core_test_kit/generated/v6.1.0/diagnostic_report_note/diagnostic_report_note_reference_resolution_test.rb +0 -1
  16. data/lib/us_core_test_kit/generated/v6.1.0/diagnostic_report_note/metadata.yml +0 -4
  17. data/lib/us_core_test_kit/generated/v6.1.0/metadata.yml +3 -16
  18. data/lib/us_core_test_kit/generated/v6.1.0/practitioner/metadata.yml +2 -6
  19. data/lib/us_core_test_kit/generated/v6.1.0/practitioner/practitioner_address_test.rb +32 -0
  20. data/lib/us_core_test_kit/generated/v6.1.0/practitioner/practitioner_must_support_test.rb +0 -6
  21. data/lib/us_core_test_kit/generated/v6.1.0/practitioner_group.rb +2 -0
  22. data/lib/us_core_test_kit/generated/v6.1.0/smokingstatus/metadata.yml +1 -6
  23. data/lib/us_core_test_kit/generated/v6.1.0/smokingstatus/smokingstatus_must_support_test.rb +1 -1
  24. data/lib/us_core_test_kit/generated/v6.1.0/us_core_test_suite.rb +16 -3
  25. data/lib/us_core_test_kit/generated/v7.0.0/diagnostic_report_note/diagnostic_report_note_must_support_test.rb +0 -2
  26. data/lib/us_core_test_kit/generated/v7.0.0/diagnostic_report_note/diagnostic_report_note_reference_resolution_test.rb +0 -1
  27. data/lib/us_core_test_kit/generated/v7.0.0/diagnostic_report_note/metadata.yml +0 -4
  28. data/lib/us_core_test_kit/generated/v7.0.0/metadata.yml +2 -10
  29. data/lib/us_core_test_kit/generated/v7.0.0/practitioner/metadata.yml +2 -6
  30. data/lib/us_core_test_kit/generated/v7.0.0/practitioner/practitioner_address_test.rb +32 -0
  31. data/lib/us_core_test_kit/generated/v7.0.0/practitioner/practitioner_must_support_test.rb +0 -6
  32. data/lib/us_core_test_kit/generated/v7.0.0/practitioner_group.rb +2 -0
  33. data/lib/us_core_test_kit/generated/v7.0.0/us_core_test_suite.rb +21 -5
  34. data/lib/us_core_test_kit/generator/group_generator.rb +1 -2
  35. data/lib/us_core_test_kit/generator/must_support_metadata_extractor_us_core_6.rb +23 -0
  36. data/lib/us_core_test_kit/generator/must_support_metadata_extractor_us_core_7.rb +5 -1
  37. data/lib/us_core_test_kit/generator/practitioner_address_test_generator.rb +68 -0
  38. data/lib/us_core_test_kit/generator/suite_generator.rb +15 -2
  39. data/lib/us_core_test_kit/generator.rb +6 -0
  40. data/lib/us_core_test_kit/must_support_test.rb +25 -22
  41. data/lib/us_core_test_kit/practitioner_address_test.rb +85 -0
  42. data/lib/us_core_test_kit/reference_resolution_test.rb +31 -23
  43. data/lib/us_core_test_kit/us_core_options.rb +9 -8
  44. data/lib/us_core_test_kit/version.rb +1 -1
  45. metadata +14 -6
@@ -15,7 +15,7 @@ module USCoreTestKit
15
15
  * Observation.category
16
16
  * Observation.category:SocialHistory
17
17
  * Observation.code
18
- * Observation.effective[x]:effectiveDateTime
18
+ * Observation.effective[x]
19
19
  * Observation.status
20
20
  * Observation.subject
21
21
  * Observation.valueCodeableConcept
@@ -76,7 +76,7 @@ module USCoreTestKit
76
76
  )
77
77
  version VERSION
78
78
 
79
- VALIDATION_MESSAGE_FILTERS = [
79
+ GENERAL_MESSAGE_FILTERS = [
80
80
  %r{Sub-extension url 'introspect' is not defined by the Extension http://fhir-registry\.smarthealthit\.org/StructureDefinition/oauth-uris},
81
81
  %r{Sub-extension url 'revoke' is not defined by the Extension http://fhir-registry\.smarthealthit\.org/StructureDefinition/oauth-uris},
82
82
  /Observation\.effective\.ofType\(Period\): .*vs-1:/, # Invalid invariant in FHIR v4.0.1
@@ -88,7 +88,13 @@ module USCoreTestKit
88
88
  %r{Observation.component\[\d+\].value.ofType\(Quantity\): The code provided \(http://unitsofmeasure.org#L/min\) was not found in the value set 'Vital Signs Units'} # Known issue with the Pulse Oximetry Profile
89
89
  ].freeze
90
90
 
91
- VERSION_SPECIFIC_MESSAGE_FILTERS = [].freeze
91
+ VERSION_SPECIFIC_MESSAGE_FILTERS = [
92
+ %r{Observation\.effective\.ofType\(Period\):.*http://hl7.org/fhir/us/core/StructureDefinition/us-core-smokingstatus|6.1.0},
93
+ %r{Observation: Slice 'Observation\.effective\[x\]:effectiveDateTime':.*http://hl7.org/fhir/us/core/StructureDefinition/us-core-smokingstatus|6.1.0},
94
+ %r{Observation\.effective\.ofType\(Period\)\.end: This element is not allowed by the profile http://hl7.org/fhir/StructureDefinition/dateTime}
95
+ ].freeze
96
+
97
+ VALIDATION_MESSAGE_FILTERS = GENERAL_MESSAGE_FILTERS + VERSION_SPECIFIC_MESSAGE_FILTERS
92
98
 
93
99
  def self.metadata
94
100
  @metadata ||= YAML.load_file(File.join(__dir__, 'metadata.yml'), aliases: true)[:groups].map do |raw_metadata|
@@ -100,7 +106,7 @@ module USCoreTestKit
100
106
 
101
107
  fhir_resource_validator do
102
108
  igs 'hl7.fhir.us.core#6.1.0'
103
- message_filters = VALIDATION_MESSAGE_FILTERS + VERSION_SPECIFIC_MESSAGE_FILTERS
109
+ message_filters = VALIDATION_MESSAGE_FILTERS
104
110
 
105
111
  exclude_message do |message|
106
112
 
@@ -126,6 +132,10 @@ module USCoreTestKit
126
132
  {
127
133
  label: 'SMART App Launch 2.0.0',
128
134
  value: USCoreOptions::SMART_2
135
+ },
136
+ {
137
+ label: 'SMART App Launch 2.2.0',
138
+ value: USCoreOptions::SMART_2_2
129
139
  }
130
140
  ]
131
141
 
@@ -206,6 +216,9 @@ module USCoreTestKit
206
216
 
207
217
  group from: :us_core_v610_smart_granular_scopes,
208
218
  required_suite_options: USCoreOptions::SMART_2_REQUIREMENT
219
+ group from: :us_core_v610_smart_granular_scopes,
220
+ id: :us_core_v610_smart_granular_scopes_stu2_2,
221
+ required_suite_options: USCoreOptions::SMART_2_2_REQUIREMENT
209
222
 
210
223
  end
211
224
  end
@@ -18,8 +18,6 @@ module USCoreTestKit
18
18
  * DiagnosticReport.effectiveDateTime
19
19
  * DiagnosticReport.encounter
20
20
  * DiagnosticReport.issued
21
- * DiagnosticReport.media
22
- * DiagnosticReport.media.link
23
21
  * DiagnosticReport.performer
24
22
  * DiagnosticReport.presentedForm
25
23
  * DiagnosticReport.result
@@ -16,7 +16,6 @@ module USCoreTestKit
16
16
  Elements which may provide external references include:
17
17
 
18
18
  * DiagnosticReport.encounter
19
- * DiagnosticReport.media.link
20
19
  * DiagnosticReport.performer
21
20
  * DiagnosticReport.result
22
21
  * DiagnosticReport.subject
@@ -219,10 +219,6 @@
219
219
  :target_profiles:
220
220
  - http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-lab
221
221
  - http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-clinical-result
222
- - :path: media
223
- - :path: media.link
224
- :types:
225
- - Reference
226
222
  - :path: presentedForm
227
223
  :mandatory_elements:
228
224
  - DiagnosticReport.status
@@ -1981,10 +1981,6 @@
1981
1981
  :target_profiles:
1982
1982
  - http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-lab
1983
1983
  - http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-clinical-result
1984
- - :path: media
1985
- - :path: media.link
1986
- :types:
1987
- - Reference
1988
1984
  - :path: presentedForm
1989
1985
  :mandatory_elements:
1990
1986
  - DiagnosticReport.status
@@ -12533,12 +12529,6 @@
12533
12529
  - :path: telecom
12534
12530
  - :path: telecom.system
12535
12531
  - :path: telecom.value
12536
- - :path: address
12537
- - :path: address.line
12538
- - :path: address.city
12539
- - :path: address.state
12540
- - :path: address.postalCode
12541
- - :path: address.country
12542
12532
  :mandatory_elements:
12543
12533
  - Practitioner.identifier
12544
12534
  - Practitioner.identifier.system
@@ -12595,6 +12585,8 @@
12595
12585
  :file_name: practitioner_validation_test.rb
12596
12586
  - :id: us_core_v700_practitioner_must_support_test
12597
12587
  :file_name: practitioner_must_support_test.rb
12588
+ - :id: us_core_v700_practitioner_address_test
12589
+ :file_name: practitioner_address_test.rb
12598
12590
  :id: us_core_v700_practitioner
12599
12591
  :file_name: practitioner_group.rb
12600
12592
  :delayed_references: []
@@ -100,12 +100,6 @@
100
100
  - :path: telecom
101
101
  - :path: telecom.system
102
102
  - :path: telecom.value
103
- - :path: address
104
- - :path: address.line
105
- - :path: address.city
106
- - :path: address.state
107
- - :path: address.postalCode
108
- - :path: address.country
109
103
  :mandatory_elements:
110
104
  - Practitioner.identifier
111
105
  - Practitioner.identifier.system
@@ -162,6 +156,8 @@
162
156
  :file_name: practitioner_validation_test.rb
163
157
  - :id: us_core_v700_practitioner_must_support_test
164
158
  :file_name: practitioner_must_support_test.rb
159
+ - :id: us_core_v700_practitioner_address_test
160
+ :file_name: practitioner_address_test.rb
165
161
  :id: us_core_v700_practitioner
166
162
  :file_name: practitioner_group.rb
167
163
  :delayed_references: []
@@ -0,0 +1,32 @@
1
+ require_relative '../../../practitioner_address_test'
2
+
3
+ module USCoreTestKit
4
+ module USCoreV700
5
+ class PractitionerAddressTest < Inferno::Test
6
+ include USCoreTestKit::PractitionerAddressTest
7
+
8
+ title 'Server support either Practitioner.address or PractitionerRole'
9
+ description %(
10
+ US Core Responders SHALL support either US Core PractitionerRole Profile or
11
+ these data elements in US Core Practitioner Profile
12
+
13
+ * Practitioner.address
14
+ * Practitioner.address.city
15
+ * Practitioner.address.country
16
+ * Practitioner.address.line
17
+ * Practitioner.address.postalCode
18
+ * Practitioner.address.state
19
+ )
20
+
21
+ id :us_core_v700_practitioner_address_test
22
+
23
+ def self.metadata
24
+ @metadata ||= Generator::GroupMetadata.new(YAML.load_file(File.join(__dir__, 'metadata.yml'), aliases: true))
25
+ end
26
+
27
+ run do
28
+ verify_practitioner_address
29
+ end
30
+ end
31
+ end
32
+ end
@@ -12,12 +12,6 @@ module USCoreTestKit
12
12
  Statement. This test will look through the Practitioner resources
13
13
  found previously for the following must support elements:
14
14
 
15
- * Practitioner.address
16
- * Practitioner.address.city
17
- * Practitioner.address.country
18
- * Practitioner.address.line
19
- * Practitioner.address.postalCode
20
- * Practitioner.address.state
21
15
  * Practitioner.identifier
22
16
  * Practitioner.identifier.system
23
17
  * Practitioner.identifier.value
@@ -4,6 +4,7 @@ require_relative 'practitioner/practitioner_identifier_search_test'
4
4
  require_relative 'practitioner/practitioner_name_search_test'
5
5
  require_relative 'practitioner/practitioner_validation_test'
6
6
  require_relative 'practitioner/practitioner_must_support_test'
7
+ require_relative 'practitioner/practitioner_address_test'
7
8
 
8
9
  module USCoreTestKit
9
10
  module USCoreV700
@@ -82,6 +83,7 @@ read succeeds.
82
83
  test from: :us_core_v700_practitioner_name_search_test
83
84
  test from: :us_core_v700_practitioner_validation_test
84
85
  test from: :us_core_v700_practitioner_must_support_test
86
+ test from: :us_core_v700_practitioner_address_test
85
87
  end
86
88
  end
87
89
  end
@@ -9,6 +9,7 @@ require_relative '../../custom_groups/v7.0.0/screening_assessment_group'
9
9
  require_relative '../../provenance_validator'
10
10
  require_relative '../../us_core_options'
11
11
  require_relative '../../custom_groups/v7.0.0/smart_app_launch_group'
12
+ require_relative '../../custom_groups/v7.0.0/smart_app_launch_stu2_2_group'
12
13
 
13
14
  require_relative 'patient_group'
14
15
  require_relative 'allergy_intolerance_group'
@@ -81,7 +82,7 @@ module USCoreTestKit
81
82
  )
82
83
  version VERSION
83
84
 
84
- VALIDATION_MESSAGE_FILTERS = [
85
+ GENERAL_MESSAGE_FILTERS = [
85
86
  %r{Sub-extension url 'introspect' is not defined by the Extension http://fhir-registry\.smarthealthit\.org/StructureDefinition/oauth-uris},
86
87
  %r{Sub-extension url 'revoke' is not defined by the Extension http://fhir-registry\.smarthealthit\.org/StructureDefinition/oauth-uris},
87
88
  /Observation\.effective\.ofType\(Period\): .*vs-1:/, # Invalid invariant in FHIR v4.0.1
@@ -95,6 +96,8 @@ module USCoreTestKit
95
96
 
96
97
  VERSION_SPECIFIC_MESSAGE_FILTERS = [].freeze
97
98
 
99
+ VALIDATION_MESSAGE_FILTERS = GENERAL_MESSAGE_FILTERS + VERSION_SPECIFIC_MESSAGE_FILTERS
100
+
98
101
  def self.metadata
99
102
  @metadata ||= YAML.load_file(File.join(__dir__, 'metadata.yml'), aliases: true)[:groups].map do |raw_metadata|
100
103
  Generator::GroupMetadata.new(raw_metadata)
@@ -105,7 +108,7 @@ module USCoreTestKit
105
108
 
106
109
  fhir_resource_validator do
107
110
  igs 'hl7.fhir.us.core#7.0.0'
108
- message_filters = VALIDATION_MESSAGE_FILTERS + VERSION_SPECIFIC_MESSAGE_FILTERS
111
+ message_filters = VALIDATION_MESSAGE_FILTERS
109
112
 
110
113
  exclude_message do |message|
111
114
 
@@ -131,10 +134,20 @@ module USCoreTestKit
131
134
  {
132
135
  label: 'SMART App Launch 2.0.0',
133
136
  value: USCoreOptions::SMART_2
137
+ },
138
+ {
139
+ label: 'SMART App Launch 2.2.0',
140
+ value: USCoreOptions::SMART_2_2
134
141
  }
135
142
  ]
136
143
 
137
- group from: :us_core_v700_smart_app_launch
144
+ group from: :us_core_v700_smart_app_launch,
145
+ required_suite_options: USCoreOptions::SMART_1_REQUIREMENT
146
+ group from: :us_core_v700_smart_app_launch,
147
+ required_suite_options: USCoreOptions::SMART_2_REQUIREMENT,
148
+ id: :us_core_v700_smart_app_launch_stu2
149
+ group from: :us_core_v700_smart_app_launch_stu2_2,
150
+ required_suite_options: USCoreOptions::SMART_2_2_REQUIREMENT
138
151
 
139
152
  group do
140
153
  input :smart_credentials,
@@ -157,7 +170,7 @@ module USCoreTestKit
157
170
  )
158
171
 
159
172
  group from: :us_core_v700_capability_statement
160
-
173
+
161
174
  group from: :us_core_v700_patient
162
175
  group from: :us_core_v700_allergy_intolerance
163
176
  group from: :us_core_v700_care_plan
@@ -215,7 +228,10 @@ module USCoreTestKit
215
228
 
216
229
  group from: :us_core_v700_smart_granular_scopes,
217
230
  required_suite_options: USCoreOptions::SMART_2_REQUIREMENT
218
-
231
+ group from: :us_core_v700_smart_granular_scopes,
232
+ id: :us_core_v700_smart_granular_scopes_stu2_2,
233
+ required_suite_options: USCoreOptions::SMART_2_2_REQUIREMENT
234
+
219
235
  end
220
236
  end
221
237
  end
@@ -110,8 +110,7 @@ module USCoreTestKit
110
110
  def add_special_tests
111
111
  return if group_metadata.reformatted_version == 'v311'
112
112
 
113
- case group_metadata.resource
114
- when 'DocumentReference'
113
+ if group_metadata.resource == 'DocumentReference'
115
114
  group_metadata.add_test(
116
115
  id: 'us_core_v400_document_reference_custodian_test',
117
116
  file_name: '../../custom_groups/v4.0.0/document_reference_custodian_test.rb'
@@ -27,6 +27,9 @@ module USCoreTestKit
27
27
  def handle_special_cases
28
28
  add_must_support_choices
29
29
  add_patient_uscdi_elements
30
+ update_smoking_status_effective
31
+ remove_practitioner_address
32
+ remove_diagnosticreport_media
30
33
  end
31
34
 
32
35
  def add_must_support_choices
@@ -79,8 +82,28 @@ module USCoreTestKit
79
82
  element[:path] = 'deceasedDateTime'
80
83
  end
81
84
  end
85
+ end
86
+
87
+ # US Core v6.1.0 Patch FHIR-43355, US Core Smoking Status Observation Profile may be supported
88
+ # either Observation.effectiveDateTime or Observation.effectivePeriod data element
89
+ def update_smoking_status_effective
90
+ return unless profile.id == 'us-core-smokingstatus'
91
+
92
+ must_supports[:slices].delete_if { |slice| slice[:slice_id] == 'Observation.effective[x]:effectiveDateTime' }
93
+ must_supports[:elements] << { path: 'effective[x]' }
94
+ end
95
+
96
+ # US Core v6.1.0 Patch FI-44693, Add MustSupport choice between Practitioner.address and PractitionerRole
97
+ def remove_practitioner_address
98
+ return unless profile.type == 'Practitioner'
82
99
 
100
+ must_supports[:elements].delete_if { |element| element[:path].start_with?('address') }
101
+ end
83
102
 
103
+ # US Core v6.1.0 Patch FI-46240, Remove the Must Support on media and media.link
104
+ def remove_diagnosticreport_media
105
+ return unless profile.id == 'us-core-diagnosticreport-note'
106
+ must_supports[:elements].delete_if { |element| element[:path].start_with?('media') }
84
107
  end
85
108
  end
86
109
  end
@@ -17,11 +17,15 @@ module USCoreTestKit
17
17
  end
18
18
 
19
19
  def handle_special_cases
20
- us_core_6_extractor.handle_special_cases
20
+ us_core_6_extractor.add_patient_uscdi_elements
21
21
  add_must_support_choices
22
+ us_core_6_extractor.remove_practitioner_address
23
+ us_core_6_extractor.remove_diagnosticreport_media
22
24
  end
23
25
 
24
26
  def add_must_support_choices
27
+ us_core_6_extractor.add_must_support_choices
28
+
25
29
  more_choices = []
26
30
 
27
31
  case profile.type
@@ -0,0 +1,68 @@
1
+ module USCoreTestKit
2
+ class Generator
3
+ class PractitionerAddressTestGenerator
4
+ class << self
5
+ def generate(ig_metadata, base_output_dir)
6
+ ig_metadata.groups
7
+ .reject { |group| SpecialCases.exclude_group? group }
8
+ .each { |group| new(group, base_output_dir).generate }
9
+ end
10
+ end
11
+
12
+ attr_accessor :group_metadata, :base_output_dir
13
+
14
+ def initialize(group_metadata, base_output_dir)
15
+ self.group_metadata = group_metadata
16
+ self.base_output_dir = base_output_dir
17
+ end
18
+
19
+ def template
20
+ @template ||= File.read(File.join(__dir__, 'templates', 'practitioner_address_test.rb.erb'))
21
+ end
22
+
23
+ def output
24
+ @output ||= ERB.new(template).result(binding)
25
+ end
26
+
27
+ def base_output_file_name
28
+ "#{class_name.underscore}.rb"
29
+ end
30
+
31
+ def output_file_directory
32
+ File.join(base_output_dir, profile_identifier)
33
+ end
34
+
35
+ def output_file_name
36
+ File.join(output_file_directory, base_output_file_name)
37
+ end
38
+
39
+ def profile_identifier
40
+ Naming.snake_case_for_profile(group_metadata)
41
+ end
42
+
43
+ def test_id
44
+ "us_core_#{group_metadata.reformatted_version}_practitioner_address_test"
45
+ end
46
+
47
+ def class_name
48
+ "PractitionerAddressTest"
49
+ end
50
+
51
+ def module_name
52
+ "USCore#{group_metadata.reformatted_version.upcase}"
53
+ end
54
+
55
+ def generate
56
+ return unless group_metadata.resource == 'Practitioner' && group_metadata.version[1].to_i > 5
57
+
58
+ FileUtils.mkdir_p(output_file_directory)
59
+ File.open(output_file_name, 'w') { |f| f.write(output) }
60
+
61
+ group_metadata.add_test(
62
+ id: test_id,
63
+ file_name: base_output_file_name
64
+ )
65
+ end
66
+ end
67
+ end
68
+ end
@@ -18,7 +18,16 @@ module USCoreTestKit
18
18
  end
19
19
 
20
20
  def version_specific_message_filters
21
- []
21
+ case ig_metadata.reformatted_version
22
+ when 'v610'
23
+ [
24
+ %r{Observation\.effective\.ofType\(Period\):.*http://hl7.org/fhir/us/core/StructureDefinition/us-core-smokingstatus|6.1.0},
25
+ %r{Observation: Slice 'Observation\.effective\[x\]:effectiveDateTime':.*http://hl7.org/fhir/us/core/StructureDefinition/us-core-smokingstatus|6.1.0},
26
+ %r{Observation\.effective\.ofType\(Period\)\.end: This element is not allowed by the profile http://hl7.org/fhir/StructureDefinition/dateTime}
27
+ ]
28
+ else
29
+ []
30
+ end
22
31
  end
23
32
 
24
33
  def template
@@ -75,7 +84,7 @@ module USCoreTestKit
75
84
  end
76
85
 
77
86
  def generate
78
- File.open(output_file_name, 'w') { |f| f.write(output) }
87
+ File.write(output_file_name, output)
79
88
  end
80
89
 
81
90
  def groups
@@ -137,6 +146,10 @@ module USCoreTestKit
137
146
  "../../custom_groups/#{ig_metadata.ig_version}/smart_app_launch_group"
138
147
  end
139
148
 
149
+ def stu2_2_smart_app_launch_file_name
150
+ "../../custom_groups/#{ig_metadata.ig_version}/smart_app_launch_stu2_2_group"
151
+ end
152
+
140
153
  def smart_app_launch_id
141
154
  if us_core_7_and_above?
142
155
  "us_core_#{ig_metadata.reformatted_version}_smart_app_launch"
@@ -15,6 +15,7 @@ require_relative 'generator/reference_resolution_test_generator'
15
15
  require_relative 'generator/search_test_generator'
16
16
  require_relative 'generator/suite_generator'
17
17
  require_relative 'generator/validation_test_generator'
18
+ require_relative 'generator/practitioner_address_test_generator'
18
19
 
19
20
  module USCoreTestKit
20
21
  class Generator
@@ -44,6 +45,7 @@ module USCoreTestKit
44
45
  generate_validation_tests
45
46
  generate_must_support_tests
46
47
  generate_reference_resolution_tests
48
+ generate_practitioner_address_tests
47
49
 
48
50
  generate_granular_scope_tests
49
51
 
@@ -120,6 +122,10 @@ module USCoreTestKit
120
122
  GranularScopeGroupGenerator.generate(ig_metadata, base_output_dir)
121
123
  end
122
124
 
125
+ def generate_practitioner_address_tests
126
+ PractitionerAddressTestGenerator.generate(ig_metadata, base_output_dir)
127
+ end
128
+
123
129
  def generate_suites
124
130
  SuiteGenerator.generate(ig_metadata, base_output_dir)
125
131
  end
@@ -107,33 +107,36 @@ module USCoreTestKit
107
107
  end
108
108
 
109
109
  def missing_elements(resources = [])
110
- @missing_elements ||=
111
- must_support_elements.select do |element_definition|
112
- resources.none? do |resource|
113
- path = element_definition[:path]
114
- ms_extension_urls = must_support_extensions.select { |ex| ex[:path] == "#{path}.extension" }
115
- .map { |ex| ex[:url] }
116
-
117
- value_found = find_a_value_at(resource, path) do |value|
118
- if value.instance_of?(USCoreTestKit::PrimitiveType) && ms_extension_urls.present?
119
- urls = value.extension&.map(&:url)
120
- has_ms_extension = (urls & ms_extension_urls).present?
121
- end
110
+ @missing_elements ||= find_missing_elements(resources, must_support_elements)
111
+ @missing_elements
112
+ end
122
113
 
123
- unless has_ms_extension
124
- value = value.value if value.instance_of?(USCoreTestKit::PrimitiveType)
125
- value_without_extensions =
126
- value.respond_to?(:to_hash) ? value.to_hash.reject { |key, _| key == 'extension' } : value
127
- end
114
+ def find_missing_elements(resources, must_support_elements)
115
+ must_support_elements.select do |element_definition|
116
+ resources.none? do |resource|
117
+ path = element_definition[:path]
118
+ ms_extension_urls = must_support_extensions.select { |ex| ex[:path] == "#{path}.extension" }
119
+ .map { |ex| ex[:url] }
120
+
121
+ value_found = find_a_value_at(resource, path) do |value|
122
+ if value.instance_of?(USCoreTestKit::PrimitiveType) && ms_extension_urls.present?
123
+ urls = value.extension&.map(&:url)
124
+ has_ms_extension = (urls & ms_extension_urls).present?
125
+ end
128
126
 
129
- (has_ms_extension || value_without_extensions.present? || value_without_extensions == false) &&
130
- (element_definition[:fixed_value].blank? || value == element_definition[:fixed_value])
127
+ unless has_ms_extension
128
+ value = value.value if value.instance_of?(USCoreTestKit::PrimitiveType)
129
+ value_without_extensions =
130
+ value.respond_to?(:to_hash) ? value.to_hash.reject { |key, _| key == 'extension' } : value
131
131
  end
132
- # Note that false.present? => false, which is why we need to add this extra check
133
- value_found.present? || value_found == false
132
+
133
+ (has_ms_extension || value_without_extensions.present? || value_without_extensions == false) &&
134
+ (element_definition[:fixed_value].blank? || value == element_definition[:fixed_value])
134
135
  end
136
+ # Note that false.present? => false, which is why we need to add this extra check
137
+ value_found.present? || value_found == false
135
138
  end
136
- @missing_elements
139
+ end
137
140
  end
138
141
 
139
142
  def must_support_slices
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module USCoreTestKit
4
+ module PractitionerAddressTest
5
+ include SearchTest
6
+ include ReferenceResolutionTest
7
+ include MustSupportTest
8
+
9
+ MUST_SUPPORT_ELEMENTS = [
10
+ { path: 'address' },
11
+ { path: 'address.line' },
12
+ { path: 'address.city' },
13
+ { path: 'address.state' },
14
+ { path: 'address.postalCode' },
15
+ { path: 'address.country' }
16
+ ].freeze
17
+
18
+ def resource_type
19
+ 'Practitioner'
20
+ end
21
+
22
+ def scratch_resources
23
+ scratch[:practitioner_resource] ||= {}
24
+ end
25
+
26
+ def verify_practitioner_address
27
+ references = scratch.dig(:references, 'Practitioner')
28
+ assert references.any?, 'No Pracitioner references found.'
29
+
30
+ @missing_elements = MUST_SUPPORT_ELEMENTS
31
+ practitioners = []
32
+
33
+ references.each do |reference|
34
+ resolved_resource = resolve_reference(reference)
35
+
36
+ if resolved_resource.nil? ||
37
+ resolved_resource.resourceType != resource_type ||
38
+ resolved_resource.id != reference.reference_id
39
+ next
40
+ end
41
+
42
+ practitioners << resolved_resource
43
+
44
+ some_missing_elements = find_missing_elements([resolved_resource], MUST_SUPPORT_ELEMENTS)
45
+ @missing_elements &= some_missing_elements
46
+
47
+ break if @missing_elements.empty?
48
+ end
49
+
50
+ missing_elements_string = @missing_elements.map { |element| missing_element_string(element) }
51
+ support_practitioner_role = false
52
+
53
+ if @missing_elements.any?
54
+ resource_type = 'PractitionerRole'
55
+ support_practitioner_role = practitioners.any? do |practitioner|
56
+ search_params = { practitioner: practitioner.id }
57
+
58
+ search_and_check_response(search_params, resource_type)
59
+
60
+ practitioner_roles = fetch_all_bundled_resources(resource_type:)
61
+ .select { |resource| resource.resourceType == resource_type }
62
+
63
+ next false if practitioner_roles.empty?
64
+ next true if config.options[:skip_practitioner_role_validation]
65
+
66
+ target_profile_with_version =
67
+ "http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitionerrole|#{metadata.profile_version}"
68
+
69
+ practitioner_roles.any? { |pr| resource_is_valid_with_target_profile?(pr, target_profile_with_version) }
70
+ end
71
+ end
72
+
73
+ missing_must_support_message = "Could not find US Core PractitionerRole Profile resources and " \
74
+ "these MustSupport elements #{missing_elements_string.join(', ')} " \
75
+ "in US Core Practitioner Profile resources. " \
76
+ "Please use patients with more information."
77
+
78
+ assert (support_practitioner_role || @missing_elements.blank?), missing_must_support_message
79
+ end
80
+
81
+ def get_practitioner_ids(references)
82
+ references.map { |reference| reference.reference&.split('/')&.last }.compact.uniq
83
+ end
84
+ end
85
+ end