davinci_pas_test_kit 0.12.0 → 0.12.1
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/lib/davinci_pas_test_kit/client_suite.rb +24 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_approval_submit_test.rb +29 -1
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_denial_submit_test.rb +27 -4
- data/lib/davinci_pas_test_kit/{generated/v2.0.1/client_tests/client_pended_pas_inquiry_request_bundle_validation_test.rb → custom_groups/v2.0.1/client_tests/pas_client_inquire_request_bundle_validation_test.rb} +22 -20
- data/lib/davinci_pas_test_kit/{generated/v2.0.1/client_tests/client_denial_pas_response_bundle_validation_test.rb → custom_groups/v2.0.1/client_tests/pas_client_inquire_response_bundle_validation_test.rb} +34 -21
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_submit_test.rb +124 -5
- data/lib/davinci_pas_test_kit/{generated/v2.0.1/client_tests/client_pas_request_bundle_validation_test.rb → custom_groups/v2.0.1/client_tests/pas_client_request_bundle_validation_test.rb} +22 -20
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/{pas_client_approval_submit_response_attest.rb → pas_client_response_attest.rb} +26 -9
- data/lib/davinci_pas_test_kit/{generated/v2.0.1/client_tests/client_pended_pas_response_bundle_validation_test.rb → custom_groups/v2.0.1/client_tests/pas_client_response_bundle_validation_test.rb} +44 -20
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_subscription_create_test.rb +49 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_subscription_pas_conformance_test.rb +48 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_approval_group.rb +21 -9
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_authentication_group.rb +2 -2
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_denial_group.rb +21 -22
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_pended_group.rb +97 -31
- data/lib/davinci_pas_test_kit/docs/client_suite_description_v201.md +213 -72
- data/lib/davinci_pas_test_kit/endpoints/claim_endpoint.rb +85 -134
- data/lib/davinci_pas_test_kit/endpoints/subscription_create_endpoint.rb +96 -0
- data/lib/davinci_pas_test_kit/endpoints/subscription_status_endpoint.rb +90 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/metadata.yml +0 -2
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/server_pas_inquiry_request_bundle_validation_test.rb +3 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_response_bundle/server_pas_inquiry_response_bundle_validation_test.rb +2 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/metadata.yml +0 -2
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/server_pas_request_bundle_validation_test.rb +3 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_response_bundle/metadata.yml +0 -4
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_response_bundle/server_pas_response_bundle_validation_test.rb +2 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_denial_use_case_group.rb +1 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_pended_use_case_group.rb +6 -5
- data/lib/davinci_pas_test_kit/generated/v2.0.1/server_suite.rb +1 -0
- data/lib/davinci_pas_test_kit/generator/group_generator.rb +9 -8
- data/lib/davinci_pas_test_kit/generator/group_metadata_extractor.rb +7 -3
- data/lib/davinci_pas_test_kit/generator/templates/suite.rb.erb +1 -0
- data/lib/davinci_pas_test_kit/generator/validation_test_generator.rb +19 -56
- data/lib/davinci_pas_test_kit/generator/value_extractor.rb +4 -1
- data/lib/davinci_pas_test_kit/generator.rb +1 -1
- data/lib/davinci_pas_test_kit/jobs/send_pas_subscription_notification.rb +136 -0
- data/lib/davinci_pas_test_kit/jobs/send_subscription_handshake.rb +139 -0
- data/lib/davinci_pas_test_kit/pas_bundle_validation.rb +8 -7
- data/lib/davinci_pas_test_kit/response_generator.rb +397 -0
- data/lib/davinci_pas_test_kit/tags.rb +9 -0
- data/lib/davinci_pas_test_kit/urls.rb +8 -0
- data/lib/davinci_pas_test_kit/user_input_response.rb +11 -8
- data/lib/davinci_pas_test_kit/validation_test.rb +0 -1
- data/lib/davinci_pas_test_kit/version.rb +2 -2
- metadata +30 -14
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_denial_submit_response_attest.rb +0 -38
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_inquire_response_attest.rb +0 -39
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_inquire_test.rb +0 -35
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_submit_response_attest.rb +0 -39
- data/lib/davinci_pas_test_kit/generator/templates/validation_client.rb.erb +0 -50
@@ -0,0 +1,96 @@
|
|
1
|
+
require_relative '../tags'
|
2
|
+
require_relative '../jobs/send_subscription_handshake'
|
3
|
+
require 'subscriptions_test_kit'
|
4
|
+
|
5
|
+
module DaVinciPASTestKit
|
6
|
+
class SubscriptionCreateEndpoint < Inferno::DSL::SuiteEndpoint
|
7
|
+
include SubscriptionsTestKit::SubscriptionsR5BackportR4Client::SubscriptionSimulationUtils
|
8
|
+
|
9
|
+
def test_run_identifier
|
10
|
+
request.headers['authorization']&.delete_prefix('Bearer ')
|
11
|
+
end
|
12
|
+
|
13
|
+
def make_response
|
14
|
+
response.format = :json
|
15
|
+
response.status = 400
|
16
|
+
|
17
|
+
begin
|
18
|
+
subscription = FHIR.from_contents(request.body.string)
|
19
|
+
rescue StandardError
|
20
|
+
response.body = operation_outcome('error', 'invalid', 'No recognized R4 Subscription in request body').to_json
|
21
|
+
return
|
22
|
+
end
|
23
|
+
|
24
|
+
verification_outcome = verify_subscription(subscription)
|
25
|
+
if verification_outcome.present?
|
26
|
+
response.body = verification_outcome.to_json
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
# Deny subscription if one already created
|
31
|
+
requests = requests_repo.tagged_requests(test_run.test_session_id, tags)
|
32
|
+
existing_subscription_request = requests.find { |r| r.status == 201 }
|
33
|
+
if existing_subscription_request.present?
|
34
|
+
subscription_hash = JSON.parse(existing_subscription_request.response_body)
|
35
|
+
error_text = 'Inferno only supports one subscription per test run. Subscription already created with ' \
|
36
|
+
"ID #{subscription_hash['id']}"
|
37
|
+
response.body = operation_outcome('error', 'business-rule', error_text).to_json
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
# Form response
|
42
|
+
notification_json = nil # no notification
|
43
|
+
subscription_id = SecureRandom.uuid
|
44
|
+
# We have to manipulate the raw hash so that we don't lose the _payload primitive extension
|
45
|
+
subscription_hash = JSON.parse(request.body.string).merge('id' => subscription_id, 'status' => 'requested')
|
46
|
+
subscription_hash['channel']['payload'] = actual_mime_type(subscription)
|
47
|
+
response.status = 201
|
48
|
+
response.body = subscription_hash.to_json
|
49
|
+
|
50
|
+
# Kick off handshake job
|
51
|
+
subscription_url = "#{request.url}/#{subscription_id}"
|
52
|
+
client_endpoint = subscription.channel.endpoint
|
53
|
+
bearer_token = client_access_token_input(result)
|
54
|
+
test_suite_base_url = request.url.chomp('/').chomp(FHIR_SUBSCRIPTION_PATH)
|
55
|
+
Inferno::Jobs.perform(Jobs::SendSubscriptionHandshake, test_run.id, test_run.test_session_id, result.id,
|
56
|
+
subscription_id, subscription_url, client_endpoint, bearer_token, notification_json,
|
57
|
+
test_run_identifier, test_suite_base_url)
|
58
|
+
end
|
59
|
+
|
60
|
+
def tags
|
61
|
+
[SUBSCRIPTION_CREATE_TAG]
|
62
|
+
end
|
63
|
+
|
64
|
+
def verify_subscription(subscription)
|
65
|
+
unless subscription.is_a? FHIR::Subscription
|
66
|
+
return operation_outcome('error', 'invalid', 'No recognized R4 Subscription in request body')
|
67
|
+
end
|
68
|
+
|
69
|
+
unless subscription.channel&.type == 'rest-hook'
|
70
|
+
return operation_outcome('error', 'business-rule', 'channel.type must be rest-hook')
|
71
|
+
end
|
72
|
+
|
73
|
+
unless valid_url?(subscription.channel&.endpoint)
|
74
|
+
return operation_outcome('error', 'value', 'channel.endpoint is not recognized as a conformant URL')
|
75
|
+
end
|
76
|
+
|
77
|
+
heartbeat_period = find_heartbeat_period(subscription)
|
78
|
+
operation_outcome('error', 'not-supported', 'heartbeatPeriod is not supported') unless heartbeat_period.nil?
|
79
|
+
end
|
80
|
+
|
81
|
+
def find_heartbeat_period(subscription)
|
82
|
+
return unless subscription.present?
|
83
|
+
|
84
|
+
subscription.channel&.extension&.find do |e|
|
85
|
+
e.url == 'http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-heartbeat-period'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def valid_url?(url)
|
90
|
+
uri = URI.parse(url)
|
91
|
+
%w[http https].include?(uri.scheme)
|
92
|
+
rescue URI::InvalidURIError
|
93
|
+
false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require_relative '../tags'
|
2
|
+
require 'subscriptions_test_kit'
|
3
|
+
|
4
|
+
module DaVinciPASTestKit
|
5
|
+
class SubscriptionStatusEndpoint < Inferno::DSL::SuiteEndpoint
|
6
|
+
include SubscriptionsTestKit::SubscriptionsR5BackportR4Client::SubscriptionSimulationUtils
|
7
|
+
include ResponseGenerator
|
8
|
+
|
9
|
+
def test_run_identifier
|
10
|
+
request.headers['authorization']&.delete_prefix('Bearer ')
|
11
|
+
end
|
12
|
+
|
13
|
+
def make_response
|
14
|
+
response.format = :json
|
15
|
+
subscription = find_subscription(test_run.test_session_id)
|
16
|
+
|
17
|
+
unless subscription.present?
|
18
|
+
not_found
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
subscription_id = request.params[:id]
|
23
|
+
|
24
|
+
# Handle resource-level status params
|
25
|
+
unless subscription_id.present?
|
26
|
+
begin
|
27
|
+
params = FHIR.from_contents(request.body.string)
|
28
|
+
rescue StandardError
|
29
|
+
response.status = 400
|
30
|
+
response.body = operation_outcome('error', 'invalid', 'Invalid Parameters in request body').to_json
|
31
|
+
return
|
32
|
+
end
|
33
|
+
|
34
|
+
unless subscription_params_match?(params, subscription)
|
35
|
+
not_found
|
36
|
+
return
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
subscription_url = "#{base_subscription_url}/#{subscription.id}"
|
41
|
+
subscription_topic = subscription.criteria
|
42
|
+
status_code = determine_subscription_status_code(subscription_id)
|
43
|
+
event_count = determine_event_count(test_run.test_session_id)
|
44
|
+
|
45
|
+
notification_json = notification_bundle_input(result)
|
46
|
+
if notification_json.blank?
|
47
|
+
notification_timestamp = Time.now.utc
|
48
|
+
mock_status_bundle = FHIR::Bundle.new(
|
49
|
+
id: SecureRandom.uuid,
|
50
|
+
timestamp: notification_timestamp.iso8601,
|
51
|
+
type: 'history'
|
52
|
+
)
|
53
|
+
mock_notification_status = build_mock_notification_status(notification_timestamp, subscription_url,
|
54
|
+
subscription_topic, nil, nil)
|
55
|
+
mock_status_bundle.entry << build_mock_notification_status_entry(mock_notification_status, subscription_url)
|
56
|
+
notification_json = mock_status_bundle.to_json
|
57
|
+
end
|
58
|
+
response.body = derive_status_bundle(notification_json, subscription_url, subscription_topic, status_code,
|
59
|
+
event_count, request.url).to_json
|
60
|
+
response.status = 200
|
61
|
+
end
|
62
|
+
|
63
|
+
def subscription_params_match?(params, subscription)
|
64
|
+
id_params = find_params(params, 'id')
|
65
|
+
|
66
|
+
return false if id_params&.any? && id_params&.none? { |p| p.valueString == subscription.id }
|
67
|
+
|
68
|
+
status_params = find_params(params, 'status')
|
69
|
+
subscription_status = determine_subscription_status_code(subscription.id)
|
70
|
+
status_params.blank? || status_params.any? { |p| p.valueString == subscription_status }
|
71
|
+
end
|
72
|
+
|
73
|
+
def tags
|
74
|
+
[SUBSCRIPTION_STATUS_TAG]
|
75
|
+
end
|
76
|
+
|
77
|
+
def not_found
|
78
|
+
response.status = 404
|
79
|
+
response.body = operation_outcome('error', 'not-found').to_json
|
80
|
+
end
|
81
|
+
|
82
|
+
def find_params(params, name)
|
83
|
+
params&.parameter&.filter { |p| p.name == name }
|
84
|
+
end
|
85
|
+
|
86
|
+
def base_subscription_url
|
87
|
+
request.url.sub(/(#{Regexp.escape(FHIR_SUBSCRIPTION_PATH)}).*/, '\1')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -68,8 +68,6 @@
|
|
68
68
|
:tests:
|
69
69
|
- :id: pas_server_v201_pas_inquiry_request_bundle_validation_test
|
70
70
|
:file_name: server_pas_inquiry_request_bundle_validation_test.rb
|
71
|
-
- :id: pas_client_v201_pended_pas_inquiry_request_bundle_validation_test
|
72
|
-
:file_name: client_pended_pas_inquiry_request_bundle_validation_test.rb
|
73
71
|
- :id: pas_server_inquire_request_v201_pas_inquiry_request_bundle_must_support_test
|
74
72
|
:file_name: server_inquire_request_pas_inquiry_request_bundle_must_support_test.rb
|
75
73
|
- :id: pas_client_inquire_request_v201_pas_inquiry_request_bundle_must_support_test
|
@@ -11,9 +11,11 @@ module DaVinciPASTestKit
|
|
11
11
|
**USER INPUT VALIDATION**: This test validates input provided by the user instead of the system under test.
|
12
12
|
Errors encountered will be treated as a skip instead of a failure.
|
13
13
|
|
14
|
+
|
14
15
|
This test validates the conformity of the
|
15
16
|
user input to the
|
16
|
-
[PAS Inquiry Request Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-inquiry-request-bundle)
|
17
|
+
[PAS Inquiry Request Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-inquiry-request-bundle)
|
18
|
+
structure, ensuring subsequent tests can accurately simulate content.
|
17
19
|
|
18
20
|
It also checks that other conformance requirements defined in the [PAS Formal
|
19
21
|
Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
|
@@ -10,7 +10,8 @@ module DaVinciPASTestKit
|
|
10
10
|
description %(
|
11
11
|
This test validates the conformity of the
|
12
12
|
server's response to the
|
13
|
-
[PAS Inquiry Response Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-inquiry-response-bundle)
|
13
|
+
[PAS Inquiry Response Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-inquiry-response-bundle)
|
14
|
+
structure.
|
14
15
|
|
15
16
|
It also checks that other conformance requirements defined in the [PAS Formal
|
16
17
|
Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
|
@@ -68,8 +68,6 @@
|
|
68
68
|
:tests:
|
69
69
|
- :id: pas_server_v201_pas_request_bundle_validation_test
|
70
70
|
:file_name: server_pas_request_bundle_validation_test.rb
|
71
|
-
- :id: pas_client_v201_pas_request_bundle_validation_test
|
72
|
-
:file_name: client_pas_request_bundle_validation_test.rb
|
73
71
|
- :id: pas_server_submit_request_v201_pas_request_bundle_must_support_test
|
74
72
|
:file_name: server_submit_request_pas_request_bundle_must_support_test.rb
|
75
73
|
- :id: pas_client_submit_request_v201_pas_request_bundle_must_support_test
|
@@ -11,9 +11,11 @@ module DaVinciPASTestKit
|
|
11
11
|
**USER INPUT VALIDATION**: This test validates input provided by the user instead of the system under test.
|
12
12
|
Errors encountered will be treated as a skip instead of a failure.
|
13
13
|
|
14
|
+
|
14
15
|
This test validates the conformity of the
|
15
16
|
user input to the
|
16
|
-
[PAS Request Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-request-bundle)
|
17
|
+
[PAS Request Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-request-bundle)
|
18
|
+
structure, ensuring subsequent tests can accurately simulate content.
|
17
19
|
|
18
20
|
It also checks that other conformance requirements defined in the [PAS Formal
|
19
21
|
Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
|
@@ -62,10 +62,6 @@
|
|
62
62
|
:tests:
|
63
63
|
- :id: pas_server_v201_pas_response_bundle_validation_test
|
64
64
|
:file_name: server_pas_response_bundle_validation_test.rb
|
65
|
-
- :id: pas_client_v201_denial_pas_response_bundle_validation_test
|
66
|
-
:file_name: client_denial_pas_response_bundle_validation_test.rb
|
67
|
-
- :id: pas_client_v201_pended_pas_response_bundle_validation_test
|
68
|
-
:file_name: client_pended_pas_response_bundle_validation_test.rb
|
69
65
|
- :id: pas_server_submit_response_v201_pas_response_bundle_must_support_test
|
70
66
|
:file_name: server_submit_response_pas_response_bundle_must_support_test.rb
|
71
67
|
:delayed_references: []
|
@@ -10,7 +10,8 @@ module DaVinciPASTestKit
|
|
10
10
|
description %(
|
11
11
|
This test validates the conformity of the
|
12
12
|
server's response to the
|
13
|
-
[PAS Response Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-response-bundle)
|
13
|
+
[PAS Response Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-response-bundle)
|
14
|
+
structure.
|
14
15
|
|
15
16
|
It also checks that other conformance requirements defined in the [PAS Formal
|
16
17
|
Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
|
@@ -13,12 +13,13 @@ module DaVinciPASTestKit
|
|
13
13
|
title 'Successful Pended Workflow'
|
14
14
|
description %(
|
15
15
|
Demonstrate a complete prior authorization workflow including a period
|
16
|
-
during which the final decision is pending. This includes
|
16
|
+
during which the final decision is pending. This includes demonstrating
|
17
|
+
the ability of the server to
|
17
18
|
|
18
|
-
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
- Respond to a prior authorization request with a `pended` status.
|
20
|
+
- Accept a Subscription creation request and send a notification when
|
21
|
+
the pended claim has been finalized.
|
22
|
+
- Respond to a subsequent inquiry request with a final decision for the request.
|
22
23
|
|
23
24
|
)
|
24
25
|
|
@@ -276,7 +276,7 @@ module DaVinciPASTestKit
|
|
276
276
|
else
|
277
277
|
client_inquiry_request_must_support_test_ids
|
278
278
|
end
|
279
|
-
elsif
|
279
|
+
elsif ['approval', 'denial'].include?(use_case)
|
280
280
|
grouped_approval_denial_test_ids
|
281
281
|
elsif use_case == 'pended'
|
282
282
|
grouped_pended_test_ids
|
@@ -292,7 +292,7 @@ module DaVinciPASTestKit
|
|
292
292
|
else
|
293
293
|
client_inquiry_request_must_support_test_file_list
|
294
294
|
end
|
295
|
-
elsif
|
295
|
+
elsif ['approval', 'denial'].include?(use_case)
|
296
296
|
approval_denial_test_file_list
|
297
297
|
elsif use_case == 'pended'
|
298
298
|
pended_test_file_list
|
@@ -375,17 +375,18 @@ module DaVinciPASTestKit
|
|
375
375
|
when 'denial'
|
376
376
|
<<~DESCRIPTION
|
377
377
|
Demonstrate the ability of the server to respond to a prior
|
378
|
-
authorization request with
|
378
|
+
authorization request with a `denied` decision.
|
379
379
|
DESCRIPTION
|
380
380
|
when 'pended'
|
381
381
|
<<~DESCRIPTION
|
382
382
|
Demonstrate a complete prior authorization workflow including a period
|
383
|
-
during which the final decision is pending. This includes
|
383
|
+
during which the final decision is pending. This includes demonstrating
|
384
|
+
the ability of the server to
|
384
385
|
|
385
|
-
-
|
386
|
-
|
387
|
-
|
388
|
-
|
386
|
+
- Respond to a prior authorization request with a `pended` status.
|
387
|
+
- Accept a Subscription creation request and send a notification when
|
388
|
+
the pended claim has been finalized.
|
389
|
+
- Respond to a subsequent inquiry request with a final decision for the request.
|
389
390
|
DESCRIPTION
|
390
391
|
else # must_support
|
391
392
|
<<~DESCRIPTION
|
@@ -130,7 +130,9 @@ module DaVinciPASTestKit
|
|
130
130
|
end
|
131
131
|
|
132
132
|
def conformance_expectation
|
133
|
-
resource_capabilities
|
133
|
+
return unless resource_capabilities.present?
|
134
|
+
|
135
|
+
resource_capabilities.extension&.first&.valueCode
|
134
136
|
end
|
135
137
|
|
136
138
|
def profile_name
|
@@ -155,7 +157,8 @@ module DaVinciPASTestKit
|
|
155
157
|
resource_capabilities.interaction.map do |interaction|
|
156
158
|
{
|
157
159
|
code: interaction.code,
|
158
|
-
|
160
|
+
# TODO: fix expectation extension finding
|
161
|
+
expectation: interaction.present? ? interaction.extension&.first&.valueCode : nil
|
159
162
|
}
|
160
163
|
end
|
161
164
|
end
|
@@ -165,7 +168,8 @@ module DaVinciPASTestKit
|
|
165
168
|
resource_capabilities.operation.map do |operation|
|
166
169
|
{
|
167
170
|
code: operation.name,
|
168
|
-
|
171
|
+
# TODO: fix expectation extension finding
|
172
|
+
expectation: operation.present? ? operation.extension&.first&.valueCode : nil
|
169
173
|
}
|
170
174
|
end
|
171
175
|
end
|
@@ -6,42 +6,23 @@ module DaVinciPASTestKit
|
|
6
6
|
class ValidationTestGenerator
|
7
7
|
class << self
|
8
8
|
def generate(ig_metadata, base_output_dir)
|
9
|
-
|
10
|
-
|
11
|
-
ig_metadata.bundle_groups.each do |group|
|
12
|
-
new(group, system, base_output_dir:).generate
|
13
|
-
end
|
14
|
-
else
|
15
|
-
ig_metadata.bundle_groups.each do |group|
|
16
|
-
case group.profile_name
|
17
|
-
when 'PAS Request Bundle'
|
18
|
-
new(group, system, base_output_dir:).generate
|
19
|
-
when 'PAS Inquiry Request Bundle'
|
20
|
-
new(group, system, 'pended_inquiry', base_output_dir:).generate
|
21
|
-
when 'PAS Response Bundle'
|
22
|
-
['denial', 'pended'].each do |workflow|
|
23
|
-
new(group, system, workflow, base_output_dir:).generate
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
9
|
+
ig_metadata.bundle_groups.each do |group|
|
10
|
+
new(group, base_output_dir:).generate
|
28
11
|
end
|
29
12
|
end
|
30
13
|
end
|
31
14
|
|
32
|
-
attr_accessor :group_metadata, :medication_request_metadata, :base_output_dir, :
|
15
|
+
attr_accessor :group_metadata, :medication_request_metadata, :base_output_dir, :workflow
|
33
16
|
|
34
|
-
def initialize(group_metadata,
|
17
|
+
def initialize(group_metadata, workflow = nil, medication_request_metadata = nil, base_output_dir:)
|
35
18
|
self.group_metadata = group_metadata
|
36
|
-
self.system = system
|
37
19
|
self.workflow = workflow
|
38
20
|
self.medication_request_metadata = medication_request_metadata
|
39
21
|
self.base_output_dir = base_output_dir
|
40
22
|
end
|
41
23
|
|
42
24
|
def template
|
43
|
-
|
44
|
-
@template ||= File.read(File.join(__dir__, 'templates', temp))
|
25
|
+
@template ||= File.read(File.join(__dir__, 'templates', 'validation.rb.erb'))
|
45
26
|
end
|
46
27
|
|
47
28
|
def output
|
@@ -61,8 +42,6 @@ module DaVinciPASTestKit
|
|
61
42
|
end
|
62
43
|
|
63
44
|
def directory_name
|
64
|
-
return 'client_tests' if system == 'client'
|
65
|
-
|
66
45
|
Naming.snake_case_for_profile(medication_request_metadata || group_metadata)
|
67
46
|
end
|
68
47
|
|
@@ -87,12 +66,12 @@ module DaVinciPASTestKit
|
|
87
66
|
end
|
88
67
|
|
89
68
|
def test_id
|
90
|
-
pref = "
|
69
|
+
pref = "pas_server_#{group_metadata.reformatted_version}_#{formatted_workflow}".delete_suffix('_')
|
91
70
|
"#{pref}_#{profile_identifier}_validation_test"
|
92
71
|
end
|
93
72
|
|
94
73
|
def class_name
|
95
|
-
pref = "#{
|
74
|
+
pref = "Server#{formatted_workflow.camelize}"
|
96
75
|
"#{pref}#{Naming.upper_camel_case_for_profile(group_metadata)}ValidationTest"
|
97
76
|
end
|
98
77
|
|
@@ -135,14 +114,23 @@ module DaVinciPASTestKit
|
|
135
114
|
end
|
136
115
|
|
137
116
|
def user_input?
|
138
|
-
|
139
|
-
(system == 'client' && request_type.include?('response'))
|
117
|
+
request_type.include?('request')
|
140
118
|
end
|
141
119
|
|
142
120
|
def description
|
143
121
|
<<~DESCRIPTION
|
144
122
|
#{description_user_input_validation if user_input?}
|
145
|
-
|
123
|
+
|
124
|
+
This test validates the conformity of the
|
125
|
+
#{request_type.include?('request') ? 'user input' : "server's response"} to the
|
126
|
+
[#{profile_name}](#{profile_url})#{' '}
|
127
|
+
structure#{request_type.include?('request') ? ', ensuring subsequent tests can accurately simulate content.' : '.'}
|
128
|
+
|
129
|
+
It also checks that other conformance requirements defined in the [PAS Formal
|
130
|
+
Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
|
131
|
+
such as the presence of all referenced instances within the bundle and the
|
132
|
+
conformance of those instances to the appropriate profiles, are met.
|
133
|
+
|
146
134
|
It verifies the presence of mandatory elements and that elements with
|
147
135
|
required bindings contain appropriate values. CodeableConcept element
|
148
136
|
bindings will fail if none of their codings have a code/system belonging
|
@@ -162,31 +150,6 @@ module DaVinciPASTestKit
|
|
162
150
|
DESCRIPTION
|
163
151
|
end
|
164
152
|
|
165
|
-
def description_intro_server
|
166
|
-
<<~GENERIC_INTRO
|
167
|
-
This test validates the conformity of the
|
168
|
-
#{request_type.include?('request') ? 'user input' : "server's response"} to the
|
169
|
-
[#{profile_name}](#{profile_url}) structure#{request_type.include?('request') ? ', ensuring subsequent tests can accurately simulate content.' : '.'}
|
170
|
-
|
171
|
-
It also checks that other conformance requirements defined in the [PAS Formal
|
172
|
-
Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
|
173
|
-
such as the presence of all referenced instances within the bundle and the
|
174
|
-
conformance of those instances to the appropriate profiles, are met.
|
175
|
-
GENERIC_INTRO
|
176
|
-
end
|
177
|
-
|
178
|
-
def description_intro_client
|
179
|
-
<<~GENERIC_INTRO
|
180
|
-
This test validates the conformity of the
|
181
|
-
#{request_type.include?('response') ? 'user input' : "client's request"} to the
|
182
|
-
[#{profile_name}](#{profile_url}) structure.
|
183
|
-
It also checks that other conformance requirements defined in the [PAS Formal
|
184
|
-
Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
|
185
|
-
such as the presence of all referenced instances within the bundle and the
|
186
|
-
conformance of those instances to the appropriate profiles, are met.
|
187
|
-
GENERIC_INTRO
|
188
|
-
end
|
189
|
-
|
190
153
|
def description_user_input_validation
|
191
154
|
<<~USER_INPUT_INTRO
|
192
155
|
**USER INPUT VALIDATION**: This test validates input provided by the user instead of the system under test.
|
@@ -17,7 +17,10 @@ module DaVinciPASTestKit
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def bound_systems(the_element)
|
20
|
-
value_set(the_element)
|
20
|
+
vs = value_set(the_element)
|
21
|
+
return unless vs.present?
|
22
|
+
|
23
|
+
vs.compose&.include&.reject { |code| code.concept.nil? }
|
21
24
|
end
|
22
25
|
|
23
26
|
def values_from_value_set_binding(the_element)
|