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.
- checksums.yaml +4 -4
- data/config/presets/pas_client_example.json +30 -0
- data/config/presets/pas_ri.json +69 -0
- data/lib/davinci_pas_test_kit/client_suite.rb +4 -2
- data/lib/davinci_pas_test_kit/docs/PAS Requirements Interpretation.xlsx +0 -0
- data/lib/davinci_pas_test_kit/fhir_resource_navigation.rb +3 -3
- data/lib/davinci_pas_test_kit/generated/v2.0.1/server_suite.rb +4 -2
- data/lib/davinci_pas_test_kit/generator/templates/group.rb.erb +129 -0
- data/lib/davinci_pas_test_kit/generator/templates/must_support.rb.erb +73 -0
- data/lib/davinci_pas_test_kit/generator/templates/operation.rb.erb +62 -0
- data/lib/davinci_pas_test_kit/generator/templates/resource_list.rb.erb +13 -0
- data/lib/davinci_pas_test_kit/generator/templates/suite.rb.erb +91 -0
- data/lib/davinci_pas_test_kit/generator/templates/validation.rb.erb +98 -0
- data/lib/davinci_pas_test_kit/generator/templates/validation_client.rb.erb +50 -0
- data/lib/davinci_pas_test_kit/igs/davinci_pas_2.0.1.tgz +0 -0
- data/lib/davinci_pas_test_kit/metadata.rb +87 -0
- data/lib/davinci_pas_test_kit/version.rb +2 -1
- data/lib/davinci_pas_test_kit.rb +1 -0
- metadata +19 -6
@@ -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/'
|
Binary file
|
@@ -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, &
|
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(&
|
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:, &
|
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
|
Binary file
|