Class: USCoreTestKit::Generator::SearchTestGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/us_core_test_kit/generator/search_test_generator.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(group_metadata, search_metadata, base_output_dir) ⇒ SearchTestGenerator

Returns a new instance of SearchTestGenerator.



20
21
22
23
24
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 20

def initialize(, , base_output_dir)
  self. = 
  self. = 
  self.base_output_dir = base_output_dir
end

Instance Attribute Details

#base_output_dirObject

Returns the value of attribute base_output_dir.



18
19
20
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 18

def base_output_dir
  @base_output_dir
end

#group_metadataObject

Returns the value of attribute group_metadata.



18
19
20
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 18

def 
  @group_metadata
end

#search_metadataObject

Returns the value of attribute search_metadata.



18
19
20
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 18

def 
  @search_metadata
end

Class Method Details

.generate(ig_metadata, base_output_dir) ⇒ Object



8
9
10
11
12
13
14
15
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 8

def generate(, base_output_dir)
  .groups
    .reject { |group| SpecialCases.exclude_group? group }
    .select { |group| group.searches.present? }
    .each do |group|
      group.searches.each { |search| new(group, search, base_output_dir).generate }
    end
end

Instance Method Details

#array_of_strings(array) ⇒ Object



177
178
179
180
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 177

def array_of_strings(array)
  quoted_strings = array.map { |element| "'#{element}'" }
  "[#{quoted_strings.join(', ')}]"
end

#base_output_file_nameObject



34
35
36
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 34

def base_output_file_name
  "#{class_name.underscore}.rb"
end

#class_nameObject



62
63
64
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 62

def class_name
  "#{Naming.upper_camel_case_for_profile()}#{search_title}SearchTest"
end

#conformance_expectationObject



74
75
76
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 74

def conformance_expectation
  [:expectation]
end

#descriptionObject



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 272

def description
  <<~DESCRIPTION.gsub(/\n{3,}/, "\n\n")
  A server #{conformance_expectation} support searching by
  #{search_param_name_string} on the #{resource_type} resource. This test
  will pass if resources are returned and match the search criteria. If
  none are returned, the test is skipped.

  #{medication_inclusion_description}
  #{reference_search_description}
  #{first_search_description}
  #{post_search_description}

  [US Core Server CapabilityStatement](#{ig_link}/CapabilityStatement-us-core-server.html)
  DESCRIPTION
end

#first_search?Boolean

Returns:

  • (Boolean)


88
89
90
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 88

def first_search?
  .searches.first == 
end

#first_search_descriptionObject



242
243
244
245
246
247
248
249
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 242

def first_search_description
  return '' unless first_search?

  <<~FIRST_SEARCH_DESCRIPTION
  Because this is the first search of the sequence, resources in the
  response will be used for subsequent tests.
  FIRST_SEARCH_DESCRIPTION
end

#fixed_value_search?Boolean

Returns:

  • (Boolean)


92
93
94
95
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 92

def fixed_value_search?
  first_search? && [:names] != ['patient'] &&
    !.delayed? && resource_type != 'Patient'
end

#fixed_value_search_param_nameObject



97
98
99
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 97

def fixed_value_search_param_name
  ([:names] - [:patient]).first
end

#generateObject



221
222
223
224
225
226
227
228
229
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 221

def generate
  FileUtils.mkdir_p(output_file_directory)
  File.open(output_file_name, 'w') { |f| f.write(output) }

  .add_test(
    id: test_id,
    file_name: base_output_file_name
  )
end


211
212
213
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 211

def ig_link
  Naming.ig_link(.version)
end

#medication_inclusion_descriptionObject



251
252
253
254
255
256
257
258
259
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 251

def medication_inclusion_description
  return '' unless test_medication_inclusion?

  <<~MEDICATION_INCLUSION_DESCRIPTION
  If any #{resource_type} resources use external references to
  Medications, the search will be repeated with
  `_include=#{resource_type}:medication`.
  MEDICATION_INCLUSION_DESCRIPTION
end

#module_nameObject



66
67
68
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 66

def module_name
  "USCore#{.reformatted_version.upcase}"
end

#needs_patient_id?Boolean

Returns:

  • (Boolean)


105
106
107
108
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 105

def needs_patient_id?
  [:names].include?('patient') ||
    (resource_type == 'Patient' && [:names].include?('_id'))
end

#optional?Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 134

def optional?
  conformance_expectation != 'SHALL' || ![:must_support_or_mandatory]
end

#outputObject



30
31
32
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 30

def output
  @output ||= ERB.new(template).result(binding)
end

#output_file_directoryObject



38
39
40
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 38

def output_file_directory
  File.join(base_output_dir, profile_identifier)
end

#output_file_nameObject



42
43
44
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 42

def output_file_name
  File.join(output_file_directory, base_output_file_name)
end

#path_for_value(path) ⇒ Object



118
119
120
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 118

def path_for_value(path)
  path == 'class' ? 'local_class' : path
end

#possible_status_search?Boolean

Returns:

  • (Boolean)


146
147
148
149
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 146

def possible_status_search?
  ![:names].any? { |name| name.include? 'status' } &&
    .search_definitions.keys.any? { |key| key.to_s.include? 'status' }
end

#post_search_descriptionObject



261
262
263
264
265
266
267
268
269
270
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 261

def post_search_description
  return '' unless test_post_search?

  <<~POST_SEARCH_DESCRIPTION
  Additionally, this test will check that GET and POST search methods
  return the same number of results. Search by POST is required by the
  FHIR R4 specification, and these tests interpret search by GET as a
  requirement of US Core #{.version}.
  POST_SEARCH_DESCRIPTION
end

#profile_identifierObject



46
47
48
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 46

def profile_identifier
  Naming.snake_case_for_profile()
end

#reference_search_descriptionObject



231
232
233
234
235
236
237
238
239
240
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 231

def reference_search_description
  return '' unless test_reference_variants?

  <<~REFERENCE_SEARCH_DESCRIPTION
  This test verifies that the server supports searching by reference using
  the form `patient=[id]` as well as `patient=Patient/[id]`. The two
  different forms are expected to return the same number of results. US
  Core requires that both forms are supported by US Core responders.
  REFERENCE_SEARCH_DESCRIPTION
end

#required_comparatorsObject



126
127
128
129
130
131
132
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 126

def required_comparators
  @required_comparators ||=
    search_param_names.each_with_object({}) do |name, comparators|
      required_comparators = required_comparators_for_param(name)
      comparators[name] = required_comparators if required_comparators.present?
    end
end

#required_comparators_for_param(name) ⇒ Object



122
123
124
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 122

def required_comparators_for_param(name)
  search_definition(name)[:comparators].select { |_comparator, expectation| expectation == 'SHALL' }
end

#required_comparators_stringObject



173
174
175
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 173

def required_comparators_string
  array_of_strings(required_comparators.keys)
end

#required_multiple_or_search_paramsObject



162
163
164
165
166
167
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 162

def required_multiple_or_search_params
  @multiple_or_search_params ||=
    search_param_names.select do |name|
      search_definition(name)[:multiple_or] == 'SHALL'
    end
end

#required_multiple_or_search_params_stringObject



169
170
171
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 169

def required_multiple_or_search_params_string
  array_of_strings(required_multiple_or_search_params)
end

#resource_typeObject



70
71
72
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 70

def resource_type
  .resource
end

#saves_delayed_references?Boolean

Returns:

  • (Boolean)


142
143
144
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 142

def saves_delayed_references?
  first_search? && .delayed_references.present?
end

#search_definition(name) ⇒ Object



138
139
140
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 138

def search_definition(name)
  .search_definitions[name.to_sym]
end

#search_identifierObject



54
55
56
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 54

def search_identifier
  [:names].join('_').tr('-', '_')
end

#search_param_name_stringObject



101
102
103
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 101

def search_param_name_string
  [:names].join(' + ')
end

#search_param_namesObject



110
111
112
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 110

def search_param_names
  search_params.map { |param| param[:name] }
end

#search_param_names_arrayObject



114
115
116
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 114

def search_param_names_array
  array_of_strings(search_param_names)
end

#search_paramsObject



78
79
80
81
82
83
84
85
86
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 78

def search_params
  @search_params ||=
    [:names].map do |name|
      {
        name: name,
        path: search_definition(name)[:path]
      }
    end
end

#search_propertiesObject



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 194

def search_properties
  {}.tap do |properties|
    properties[:first_search] = 'true' if first_search?
    properties[:fixed_value_search] = 'true' if fixed_value_search?
    properties[:resource_type] = "'#{resource_type}'"
    properties[:search_param_names] = search_param_names_array
    properties[:saves_delayed_references] = 'true' if saves_delayed_references?
    properties[:possible_status_search] = 'true' if possible_status_search?
    properties[:test_medication_inclusion] = 'true' if test_medication_inclusion?
    properties[:token_search_params] = token_search_params_string if token_search_params.present?
    properties[:test_reference_variants] = 'true' if test_reference_variants?
    properties[:params_with_comparators] = required_comparators_string if required_comparators.present?
    properties[:multiple_or_search_params] = required_multiple_or_search_params_string if required_multiple_or_search_params.present?
    properties[:test_post_search] = 'true' if first_search?
  end
end

#search_test_properties_stringObject



215
216
217
218
219
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 215

def search_test_properties_string
  search_properties
    .map { |key, value| "#{' ' * 8}#{key}: #{value}" }
    .join(",\n")
end

#search_titleObject



58
59
60
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 58

def search_title
  search_identifier.camelize
end

#templateObject



26
27
28
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 26

def template
  @template ||= File.read(File.join(__dir__, 'templates', 'search.rb.erb'))
end

#test_idObject



50
51
52
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 50

def test_id
  "us_core_#{.reformatted_version}_#{profile_identifier}_#{search_identifier}_search_test"
end

#test_medication_inclusion?Boolean

Returns:

  • (Boolean)


186
187
188
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 186

def test_medication_inclusion?
  ['MedicationRequest', 'MedicationDispense'].include?(resource_type)
end

#test_post_search?Boolean

Returns:

  • (Boolean)


190
191
192
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 190

def test_post_search?
  first_search?
end

#test_reference_variants?Boolean

Returns:

  • (Boolean)


182
183
184
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 182

def test_reference_variants?
  first_search? && search_param_names.include?('patient')
end

#token_search_paramsObject



151
152
153
154
155
156
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 151

def token_search_params
  @token_search_params ||=
    search_param_names.select do |name|
      ['Identifier', 'CodeableConcept', 'Coding'].include? .search_definitions[name.to_sym][:type]
    end
end

#token_search_params_stringObject



158
159
160
# File 'lib/us_core_test_kit/generator/search_test_generator.rb', line 158

def token_search_params_string
  array_of_strings(token_search_params)
end