davinci_pas_test_kit 0.11.1 → 0.12.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.
@@ -9,13 +9,11 @@ require_relative 'custom_groups/v2.0.1/pas_client_denial_group'
9
9
  require_relative 'custom_groups/v2.0.1/pas_client_pended_group'
10
10
  require_relative 'generated/v2.0.1/pas_client_submit_must_support_use_case_group'
11
11
  require_relative 'generated/v2.0.1/pas_client_inquiry_must_support_use_case_group'
12
- require_relative 'version'
13
12
 
14
13
  module DaVinciPASTestKit
15
14
  class ClientSuite < Inferno::TestSuite
16
15
  id :davinci_pas_client_suite_v201
17
16
  title 'Da Vinci PAS Client Suite v2.0.1'
18
- version VERSION
19
17
  description File.read(File.join(__dir__, 'docs', 'client_suite_description_v201.md'))
20
18
 
21
19
  links [
@@ -27,6 +25,10 @@ module DaVinciPASTestKit
27
25
  label: 'Open Source',
28
26
  url: 'https://github.com/inferno-framework/davinci-pas-test-kit/'
29
27
  },
28
+ {
29
+ label: 'Download',
30
+ url: 'https://github.com/inferno-framework/davinci-pas-test-kit/releases'
31
+ },
30
32
  {
31
33
  label: 'Implementation Guide',
32
34
  url: 'https://hl7.org/fhir/us/davinci-pas/STU2/'
@@ -20,7 +20,7 @@ module DaVinciPASTestKit
20
20
  end.compact
21
21
  end
22
22
 
23
- def find_a_value_at(element, path, include_dar: false, &block)
23
+ def find_a_value_at(element, path, include_dar: false, &)
24
24
  return nil if element.nil?
25
25
 
26
26
  elements = Array.wrap(element)
@@ -32,7 +32,7 @@ module DaVinciPASTestKit
32
32
  end
33
33
  end
34
34
 
35
- return elements.find(&block) if block_given?
35
+ return elements.find(&) if block_given?
36
36
 
37
37
  return elements.first
38
38
  end
@@ -52,7 +52,7 @@ module DaVinciPASTestKit
52
52
  elements.each do |elmt|
53
53
  child = get_next_value(elmt, segment)
54
54
  element_found = if block_given?
55
- find_a_value_at(child, remaining_path, include_dar:, &block)
55
+ find_a_value_at(child, remaining_path, include_dar:, &)
56
56
  else
57
57
  find_a_value_at(child, remaining_path, include_dar:)
58
58
  end
@@ -1,6 +1,5 @@
1
1
  require_relative '../../validator_suppressions'
2
2
  require_relative '../../custom_groups/v2.0.1/pas_error_group'
3
- require_relative '../../version'
4
3
  require_relative 'pas_server_approval_use_case_group'
5
4
  require_relative 'pas_server_denial_use_case_group'
6
5
  require_relative 'pas_server_pended_use_case_group'
@@ -11,7 +10,6 @@ module DaVinciPASTestKit
11
10
  class ServerSuite < Inferno::TestSuite
12
11
  id :davinci_pas_server_suite_v201
13
12
  title 'Da Vinci PAS Server Suite v2.0.1'
14
- version DaVinciPASTestKit::VERSION
15
13
  description File.read(File.join(__dir__, '..', '..', 'docs', 'server_suite_description_v201.md'))
16
14
 
17
15
  links [
@@ -23,6 +21,10 @@ module DaVinciPASTestKit
23
21
  label: 'Open Source',
24
22
  url: 'https://github.com/inferno-framework/davinci-pas-test-kit/'
25
23
  },
24
+ {
25
+ label: 'Download',
26
+ url: 'https://github.com/inferno-framework/davinci-pas-test-kit/releases'
27
+ },
26
28
  {
27
29
  label: 'Implementation Guide',
28
30
  url: 'https://hl7.org/fhir/us/davinci-pas/STU2/'
@@ -0,0 +1,129 @@
1
+ <% test_file_list.each do |file_name| %>require_relative '<%= file_name %>'
2
+ <% end %>
3
+ module DaVinciPASTestKit
4
+ module <%= module_name %>
5
+ class <%= class_name %> < Inferno::TestGroup
6
+ title '<%= title %>'
7
+ description %(
8
+ <%=description.gsub("\n", "\n" + " "*8) %>
9
+ )
10
+
11
+ id :<%= group_id %>
12
+ <% if run_as_group %>run_as_group<% end %>
13
+ <% if system == 'client'%>
14
+ <% test_id_list.each do |id| %>
15
+ test from: :<%= id %><% end %>
16
+ <% else %>
17
+ def use_case
18
+ '<%= use_case %>'
19
+ end
20
+ <% if use_case != 'must_support'%>
21
+ <% test_id_list.each do |category, id_list| %>
22
+ group do
23
+ title '<%= category %>'
24
+ <% id_list.each do |id| %>
25
+ test from: :<%= id %><% if rename_input?(id) %> do
26
+ id :<%= alt_test_id(id, use_case) %>
27
+ config(
28
+ inputs: {
29
+ pa_submit_request_payload: {
30
+ name: :<%= alt_request_input_name(use_case, 'submit')%> ,
31
+ title: '<%= alt_request_input_title(use_case, 'submit')%>'
32
+ }
33
+ }
34
+ )
35
+ end<% end %><% end %>
36
+ end<% end %>
37
+ <% else %>
38
+ <% test_id_list.each do |group, subgroup|%>
39
+ group do
40
+ title '<%= group%>'
41
+ <% if group == '$submit Element Support' %>description %(
42
+ Check that the provided `$submit` requests both themselves contain
43
+ and elicit server responses that contain all PAS-defined profiles
44
+ and their must support elements.
45
+
46
+ For `$submit` requests, this includes the following profiles:
47
+
48
+ - [PAS Request Bundle](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-pas-request-bundle.html)
49
+ - [PAS Claim Update](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-claim-update.html)
50
+ - [PAS Coverage](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-coverage.html)
51
+ - [PAS Beneficiary Patient](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-beneficiary.html)
52
+ - [PAS Subscriber Patient](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-subscriber.html)
53
+ - [PAS Insurer Organization](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-insurer.html)
54
+ - [PAS Requestor Organization](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-requestor.html)
55
+ - [PAS Practitioner](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-practitioner.html)
56
+ - [PAS PractitionerRole](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-practitionerrole.html)
57
+ - [PAS Encounter](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-encounter.html)
58
+ - At least one of the following request profiles
59
+ - [PAS Device Request](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-devicerequest.html)
60
+ - [PAS Medication Request](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-medicationrequest.html)
61
+ - [PAS Nutrition Order](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-nutritionorder.html)
62
+ - [PAS Service Request](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-servicerequest.html)
63
+
64
+ For `$submit` responses, this includes the following profiles (NOTE: request-specific
65
+ profiles that may be echoed from `$submit` requests, such as the Claim instance or request instances,
66
+ are not currently checked):
67
+
68
+ - [PAS Response Bundle](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-pas-response-bundle.html)
69
+ - [PAS Claim Response](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-claimresponse.html)
70
+ - [PAS CommunicationRequest](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-communicationrequest.html)
71
+ - [PAS Task](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-task.html)
72
+ - [PAS Beneficiary Patient](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-beneficiary.html)
73
+ - [PAS Insurer Organization](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-insurer.html)
74
+ - [PAS Requestor Organization](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-requestor.html)
75
+ - [PAS Practitioner](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-practitioner.html)
76
+ - [PAS PractitionerRole](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-practitionerrole.html)
77
+ )<% elsif group == '$inquire Element Support' %>description %(
78
+ Check that the provided `$inquire` requests both themselves contain
79
+ and elicit server responses that contain all PAS-defined profiles
80
+ and their must support elements.
81
+
82
+ For `$inquire` requests, this includes the following profiles:
83
+
84
+ - [PAS Inquiry Request Bundle](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-pas-inquiry-request-bundle.html)
85
+ - [PAS Claim Inquiry](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-claim-inquiry.html)
86
+ - [PAS Coverage](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-coverage.html)
87
+ - [PAS Beneficiary Patient](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-beneficiary.html)
88
+ - [PAS Subscriber Patient](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-subscriber.html)
89
+ - [PAS Insurer Organization](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-insurer.html)
90
+ - [PAS Requestor Organization](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-requestor.html)
91
+ - [PAS Practitioner](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-practitioner.html)
92
+ - [PAS PractitionerRole](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-practitionerrole.html)
93
+
94
+ For `$inquire` responses, this includes the following profiles (NOTE: request-specific
95
+ profiles that may be echoed from `$submit` requests, such as the Claim instance or request instances,
96
+ are not currently checked):
97
+
98
+ - [PAS Inquiry Response Bundle](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-pas-inquiry-request-bundle.html)
99
+ - [PAS Claim Inquiry Response](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-claiminquiryresponse.html)
100
+ - [PAS Task](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-task.html)
101
+ - [PAS Beneficiary Patient](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-beneficiary.html)
102
+ - [PAS Insurer Organization](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-insurer.html)
103
+ - [PAS Requestor Organization](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-requestor.html)
104
+ - [PAS Practitioner](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-practitioner.html)
105
+ - [PAS PractitionerRole](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-practitionerrole.html)
106
+ )<% end %>
107
+ run_as_group
108
+ <% subgroup.each do |category, id_list| %>
109
+ group do
110
+ title '<%= category%>'
111
+ <% id_list.each do |id|%>
112
+ test from: :<%= id%><% if must_support_rename_input?(id) %> do
113
+ id :<%= alt_test_id(id, use_case) %>
114
+ config(
115
+ inputs: {<% request_type = id.include?('inquiry') ? 'inquire' : 'submit' %>
116
+ pa_<%= request_type%>_request_payload: {
117
+ name: :<%= alt_request_input_name(use_case, request_type)%>,
118
+ title: '<%= alt_request_input_title(use_case, request_type)%>',
119
+ description: 'Insert an additional request bundle or a list of bundles (e.g. [bundle_1, bundle_2])'
120
+ }
121
+ }
122
+ )
123
+ end<%end%><% end %>
124
+ end<% end %>
125
+ end<%end%>
126
+ <% end %><% end %>
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,73 @@
1
+ require_relative '../../../must_support_test'
2
+ require_relative '../../../generator/group_metadata'
3
+ require_relative '../../../tags'
4
+
5
+ module DaVinciPASTestKit
6
+ module <%= module_name %>
7
+ class <%= class_name %> < Inferno::Test
8
+ include DaVinciPASTestKit::MustSupportTest
9
+
10
+ title 'All must support elements for Profile <%= profile_name %> are observed across all instances <%= request_type.include?('request') ? 'submitted' : 'returned' %>'
11
+ description %(
12
+ <% if system == 'client' && request_type.include?('request') %>
13
+ PAS client systems are required to be able to populate all
14
+ must support elements on instances of all profiles included in <% request_type.include?('submit') ? 'Submit' : 'Inquiry' %>
15
+ requests, including instances of the <%= profile_name %> Profile.
16
+ This test checks all identified instances of the <%= profile_name %>
17
+ Profile on requests sent by the client to ensure that the following
18
+ must support elements are observed: <% end %><% if system == 'client' && request_type.include?('response') %>
19
+ PAS client systems are required to be able to receive all
20
+ must support elements on instances of all profiles included in <% request_type.include?('submit') ? 'Submit' : 'Inquiry' %>
21
+ responses, including instances of the <%= profile_name %> Profile.
22
+ This test checks all identified instances of the <%= profile_name %>
23
+ Profile on responses sent to the client to ensure that the following
24
+ must support elements are observed:<% end %><% if system == 'server' && request_type.include?('request') %>
25
+ **USER INPUT VALIDATION**: This test validates input provided by the user instead of the system under test. Errors encountered will be treated as a skip instead of a failure.
26
+
27
+ PAS server systems are required to be able to receive all
28
+ must support elements on instances of all profiles included in <% request_type.include?('submit') ? 'Submit' : 'Inquiry' %>
29
+ requests, including instances of the <%= profile_name %> Profile.
30
+ This test checks all identified instances of the <%= profile_name %>
31
+ Profile on requests sent to the server to ensure that the following
32
+ must support elements are observed:<% end %><% if system == 'server' && request_type.include?('response') %>
33
+ PAS server systems are required to be able to populate all
34
+ must support elements on instances of all profiles included in <% request_type.include?('submit') ? 'Submit' : 'Inquiry' %>
35
+ responses, including instances of the <%= profile_name %> Profile.
36
+ This test checks all identified instances of the <%= profile_name %>
37
+ Profile on responses returned by the server to ensure that the following
38
+ must support elements are observed:<% end %>
39
+
40
+ <%= must_support_list_string %>
41
+ )
42
+
43
+ id :<%= test_id %>
44
+
45
+ def resource_type
46
+ '<%= resource_type %>'
47
+ end
48
+
49
+ def user_input_validation
50
+ <% if system == 'server' && request_type.include?('request') %>true<% else %>false<% end %>
51
+ end
52
+
53
+ def self.metadata
54
+ @metadata ||= Generator::GroupMetadata.new(YAML.load_file(File.join(__dir__, 'metadata.yml'), aliases: true))
55
+ end
56
+
57
+ def scratch_resources
58
+ # The scratch key in MS test should be the same as the scratch key in the validation test for a given profile.
59
+ scratch[:<%= request_type %>_resources] ||= {}
60
+ end
61
+
62
+ def resources_of_interest
63
+ collection = tagged_resources(<%= request_type.include?('submit') ? 'SUBMIT_TAG' : 'INQUIRE_TAG' %>).presence || <%= resource_collection_string %>
64
+ collection.select { |res| res.resourceType == resource_type }
65
+ end
66
+
67
+ run do
68
+ perform_must_support_test(resources_of_interest)
69
+ validate_must_support(user_input_validation)
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,62 @@
1
+ module DaVinciPASTestKit
2
+ module <%= module_name %>
3
+ class <%= class_name %> < Inferno::Test
4
+
5
+ id :<%= test_id %>
6
+ title '<%= title %>'
7
+ description %(
8
+ <%=description.gsub("\n", "\n" + " "*8) %>
9
+ )
10
+
11
+ input :pa_<%= request_type %>_payload,
12
+ title: 'PAS <%= request_type.humanize.titleize%> Payload',
13
+ description: 'Insert Bundle to be sent for PAS <%= request_type.humanize.titleize%>',
14
+ type: 'textarea',
15
+ optional: true
16
+ input_order :server_endpoint, :smart_credentials
17
+ <% if operation == 'submit'%>output :response_time<% end %>
18
+ makes_request :pa_<%= operation %>
19
+
20
+ def scratch_resources
21
+ scratch[:<%= operation %>_request_response_pair] ||= {}
22
+ end
23
+
24
+ def request_bundles
25
+ parsed_payload = JSON.parse(pa_<%= request_type %>_payload)
26
+ [parsed_payload].flatten.compact.uniq
27
+ end
28
+
29
+ def perform_operation(request_payload)
30
+ <% if operation == 'submit'%>start_time = Time.now<% end %>
31
+ fhir_operation('/Claim/$<%= operation %>', body: request_payload, name: :pa_<%= operation %>)
32
+ <% if operation == 'submit'%>response_time = Time.now - start_time
33
+
34
+ if response_time > 15
35
+ warning %(
36
+ The server took more that 15 seconds to respond to the Prior Authorization
37
+ request.
38
+
39
+ Response Time: #{response_time}
40
+ )
41
+ end
42
+ <% end %>
43
+ assert_response_status([200, 201])
44
+ assert_valid_json(request.response_body)
45
+
46
+ # Save request/response pair
47
+ scratch_resources[:all] ||= []
48
+ scratch_resources[:all] << {request_bundle: request.request_body, response_bundle: resource}
49
+ <% if operation == 'submit'%>output response_time:<% end %>
50
+ end
51
+
52
+ run do
53
+ skip_if pa_<%= request_type %>_payload.blank?, 'No bundle request provided to perform the <%= operation %> operation'
54
+ assert_valid_json(pa_<%= request_type %>_payload)
55
+
56
+ request_bundles.each do |bundle|
57
+ perform_operation(bundle)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,13 @@
1
+ module DaVinciPASTestKit
2
+ module <%= module_name %>
3
+ module ResourceList
4
+ RESOURCE_LIST = [
5
+ <%= resource_list_string.gsub("\n", "\n" + " "*4) %>
6
+ ].freeze
7
+
8
+ RESOURCE_SUPPORTED_PROFILES = {<% resource_supported_profiles.each do |resource, profile_list| %>
9
+ <%= resource %>: <%= profile_list %>,<% end %>
10
+ }.freeze
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,91 @@
1
+ require_relative '../../validator_suppressions'
2
+ require_relative '<%= error_group_file_name %>'
3
+ <% group_file_list.each do |file_name| %>require_relative '<%= file_name %>'
4
+ <% end %>
5
+ module DaVinciPASTestKit
6
+ module <%= module_name %>
7
+ class <%= class_name %> < Inferno::TestSuite
8
+ id :<%= suite_id %>
9
+ title '<%= title %>'
10
+ description File.read(File.join(__dir__, '..', '..', 'docs', 'server_suite_description_<%= ig_metadata.reformatted_version %>.md'))
11
+
12
+ links [
13
+ {
14
+ label: 'Report Issue',
15
+ url: 'https://github.com/inferno-framework/davinci-pas-test-kit/issues/'
16
+ },
17
+ {
18
+ label: 'Open Source',
19
+ url: 'https://github.com/inferno-framework/davinci-pas-test-kit/'
20
+ },
21
+ {
22
+ label: 'Download',
23
+ url: 'https://github.com/inferno-framework/davinci-pas-test-kit/releases'
24
+ },
25
+ {
26
+ label: 'Implementation Guide',
27
+ url: '<%= ig_link %>'
28
+ }
29
+ ]
30
+
31
+ resume_test_route :get, '/resume_after_notification' do |request|
32
+ request.query_parameters['token']
33
+ end
34
+
35
+ fhir_resource_validator do
36
+ igs '<%= ig_identifier %>'
37
+
38
+ exclude_message do |message|
39
+ # Messages expected of the form `<ResourceType>: <FHIRPath>: <message>`
40
+ # We strip `<ResourceType>: <FHIRPath>: ` for the sake of matching
41
+ SUPPRESSED_MESSAGES.match?(message.message.sub(/\A\S+: \S+: /, '')) ||
42
+ message.message.downcase.include?('x12')
43
+ end
44
+ end
45
+
46
+ input :server_endpoint,
47
+ title: 'FHIR Server Endpoint URL',
48
+ description: 'Insert the FHIR server endpoint URL for PAS'
49
+
50
+ input :smart_credentials,
51
+ title: 'OAuth Credentials',
52
+ type: :auth_info,
53
+ options: {
54
+ mode: 'access',
55
+ components: [
56
+ {
57
+ name: :auth_type,
58
+ default: 'backend_services'
59
+ }
60
+ ]
61
+ },
62
+ optional: true
63
+
64
+ fhir_client do
65
+ url :server_endpoint
66
+ auth_info :smart_credentials
67
+ end
68
+
69
+ # Used for attestation experiment - see pas_claim_response_decision_test.rb
70
+ # resume_test_route :get, RESUME_PASS_PATH do |request|
71
+ # request.query_parameters['token']
72
+ # end
73
+ #
74
+ # resume_test_route :get, RESUME_FAIL_PATH, result: 'fail' do |request|
75
+ # request.query_parameters['token']
76
+ # end
77
+
78
+ group 'Demonstrate Workflow Support' do
79
+ description %(
80
+ The workflow tests validate that the server can participate in complete
81
+ end-to-end prior authorization interactions, returning responses that are
82
+ conformant and also contain the correct codes.
83
+ )
84
+ <% group_id_list.each do |id| %>
85
+ group from: :<%= id %><% end %>
86
+ end
87
+ group from: :<%= must_support_group_id %>
88
+ group from: :<%= error_group_id %>
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,98 @@
1
+ require_relative '../../../pas_bundle_validation'
2
+
3
+ module DaVinciPASTestKit
4
+ module <%= module_name %>
5
+ class <%= class_name %> < Inferno::Test
6
+ include DaVinciPASTestKit::PasBundleValidation
7
+
8
+ id :<%= test_id %>
9
+ title '<%= title %>'
10
+ description %(
11
+ <%=description.strip.gsub("\n", "\n" + " "*8) %>
12
+ )
13
+ <% if request_type.include?('request') %>
14
+ input :pa_<%= request_type %>_payload,
15
+ title: 'PAS <%= request_type.humanize.titleize%> Payload',
16
+ description: 'Insert Bundle to be sent for PAS <%= request_type.humanize.titleize%>',
17
+ type: 'textarea',
18
+ optional: true
19
+
20
+ input_order :server_endpoint, :smart_credentials<% end %>
21
+ output :dar_code_found, :dar_extension_found
22
+
23
+ def resource_type
24
+ '<%= resource_type %>'
25
+ end
26
+
27
+ def scratch_resources
28
+ scratch[:<%= request_type %>_resources] ||= {}
29
+ end
30
+
31
+ def request_type
32
+ '<%= request_type.split('_').first %>'
33
+ end
34
+ <%if request_type.include?('response')%>
35
+ def target_request_response_pairs<% operation = request_type.split('_').first %>
36
+ scratch[:<%= operation %>_request_response_pair] ||= {}
37
+ scratch[:<%= operation %>_request_response_pair][:all] ||= []
38
+ end<% end %>
39
+
40
+ <%if request_type.include?('request')%>
41
+ def request_bundles
42
+ parsed_payload = JSON.parse(pa_<%= request_type %>_payload)
43
+ fhir_resources = [parsed_payload].flatten.compact.uniq.map { |payload| FHIR.from_contents(payload.to_json)}.compact
44
+ fhir_resources.select { |res| res.resourceType == 'Bundle'}
45
+ end<% end %>
46
+
47
+ run do<% if request_type.include?('request') %>
48
+ skip_if pa_<%= request_type %>_payload.blank?, 'No bundle request input provided.'
49
+ assert_valid_json(pa_<%= request_type %>_payload)
50
+ assert request_bundles.present?, 'Provided input is not a bundle or list of bundles'
51
+
52
+ save_bundles_and_entries_to_scratch(request_bundles)
53
+
54
+ request_bundles.each do |bundle|
55
+ perform_request_validation(
56
+ bundle,
57
+ '<%= profile_url %>',
58
+ '<%= profile_version %>',
59
+ request_type
60
+ )
61
+ end
62
+
63
+ validation_error_messages.each do |msg|
64
+ messages << { type: 'error', message: msg }
65
+ end
66
+ msg = 'Bundle(s) provided and/or entry resources are not conformant. Check messages for issues found.'
67
+ skip_if validation_error_messages.present?, msg
68
+ <% else %>
69
+ skip_if target_request_response_pairs.blank?, 'No <%= request_type.split('_').first%> response to validate. Either no <%= request_type.split('_').first%> request was made in a previous test or it resulted in a server error.'
70
+ target_pairs = target_request_response_pairs
71
+ # Clean request/response pair after validatation
72
+ scratch[:<%= operation %>_request_response_pair][:all] = []
73
+
74
+ response_bundles = target_pairs.map { |pair| pair[:response_bundle] }
75
+ save_bundles_and_entries_to_scratch(response_bundles)
76
+
77
+ target_pairs.each do |pair|
78
+ pair => {request_bundle:, response_bundle:}
79
+ assert_resource_type(:bundle, resource: response_bundle)
80
+
81
+ perform_response_validation(
82
+ response_bundle,
83
+ '<%= profile_url %>',
84
+ '<%= profile_version %>',
85
+ request_type,
86
+ request_bundle
87
+ )
88
+ end
89
+
90
+ validation_error_messages.each do |msg|
91
+ messages << { type: 'error', message: msg }
92
+ end
93
+ msg = 'Bundle response returned and/or entry resources are not conformant. Check messages for issues found.'
94
+ assert validation_error_messages.blank?, msg<% end %>
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,50 @@
1
+ require_relative '../../../pas_bundle_validation'
2
+ require_relative '../../../<% if request_type.include?('response') %>user_input_response'<% else %>urls'<% end %>
3
+
4
+ module DaVinciPASTestKit
5
+ module <%= module_name %>
6
+ class <%= class_name %> < Inferno::Test
7
+ include DaVinciPASTestKit::PasBundleValidation
8
+ include <% if request_type.include?('response') %>UserInputResponse<% else %>URLs<% end %>
9
+
10
+ id :<%= test_id %>
11
+ title '<%= title %>'
12
+ description %(
13
+ <%=description.strip.gsub("\n", "\n" + " "*8) %>
14
+ )
15
+
16
+ def resource_type
17
+ '<%= resource_type %>'
18
+ end
19
+
20
+ def request_type
21
+ '<%= request_type.split('_').first %>'
22
+ end
23
+
24
+ run do<% if request_type.include?('request') %><% type = request_type.split('_').first == 'submit' ? 'submit' : 'inquire' %>
25
+ assert request.url == <%= type %>_url,
26
+ "Request made to wrong URL: #{request.url}. Should instead be to #{<%= type %>_url}"
27
+
28
+ validate_pas_bundle_json(
29
+ request.request_body,
30
+ '<%= profile_url %>',
31
+ '<%= profile_version %>',
32
+ request_type,
33
+ 'request_bundle',
34
+ message: 'The <%= type%> Bundle request provided for the Claim/$<%= type%> operation is invalid:'
35
+ )
36
+ <% else %>
37
+ check_user_inputted_response :<%= workflow %>_json_response
38
+ validate_pas_bundle_json(
39
+ <%= workflow %>_json_response,
40
+ '<%= profile_url %>',
41
+ '<%= profile_version %>',
42
+ request_type,
43
+ 'response_bundle',
44
+ skips: true,
45
+ message: "Invalid input for '#{input_title(:<%= workflow %>_json_response)}':"
46
+ )<% end %>
47
+ end
48
+ end
49
+ end
50
+ end