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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/lib/davinci_pas_test_kit/client_suite.rb +24 -0
  3. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_approval_submit_test.rb +29 -1
  4. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_denial_submit_test.rb +27 -4
  5. 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
  6. 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
  7. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_submit_test.rb +124 -5
  8. 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
  9. 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
  10. 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
  11. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_subscription_create_test.rb +49 -0
  12. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_subscription_pas_conformance_test.rb +48 -0
  13. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_approval_group.rb +21 -9
  14. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_authentication_group.rb +2 -2
  15. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_denial_group.rb +21 -22
  16. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_pended_group.rb +97 -31
  17. data/lib/davinci_pas_test_kit/docs/client_suite_description_v201.md +213 -72
  18. data/lib/davinci_pas_test_kit/endpoints/claim_endpoint.rb +85 -134
  19. data/lib/davinci_pas_test_kit/endpoints/subscription_create_endpoint.rb +96 -0
  20. data/lib/davinci_pas_test_kit/endpoints/subscription_status_endpoint.rb +90 -0
  21. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/metadata.yml +0 -2
  22. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/server_pas_inquiry_request_bundle_validation_test.rb +3 -1
  23. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_response_bundle/server_pas_inquiry_response_bundle_validation_test.rb +2 -1
  24. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/metadata.yml +0 -2
  25. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/server_pas_request_bundle_validation_test.rb +3 -1
  26. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_response_bundle/metadata.yml +0 -4
  27. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_response_bundle/server_pas_response_bundle_validation_test.rb +2 -1
  28. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_denial_use_case_group.rb +1 -1
  29. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_pended_use_case_group.rb +6 -5
  30. data/lib/davinci_pas_test_kit/generated/v2.0.1/server_suite.rb +1 -0
  31. data/lib/davinci_pas_test_kit/generator/group_generator.rb +9 -8
  32. data/lib/davinci_pas_test_kit/generator/group_metadata_extractor.rb +7 -3
  33. data/lib/davinci_pas_test_kit/generator/templates/suite.rb.erb +1 -0
  34. data/lib/davinci_pas_test_kit/generator/validation_test_generator.rb +19 -56
  35. data/lib/davinci_pas_test_kit/generator/value_extractor.rb +4 -1
  36. data/lib/davinci_pas_test_kit/generator.rb +1 -1
  37. data/lib/davinci_pas_test_kit/jobs/send_pas_subscription_notification.rb +136 -0
  38. data/lib/davinci_pas_test_kit/jobs/send_subscription_handshake.rb +139 -0
  39. data/lib/davinci_pas_test_kit/pas_bundle_validation.rb +8 -7
  40. data/lib/davinci_pas_test_kit/response_generator.rb +397 -0
  41. data/lib/davinci_pas_test_kit/tags.rb +9 -0
  42. data/lib/davinci_pas_test_kit/urls.rb +8 -0
  43. data/lib/davinci_pas_test_kit/user_input_response.rb +11 -8
  44. data/lib/davinci_pas_test_kit/validation_test.rb +0 -1
  45. data/lib/davinci_pas_test_kit/version.rb +2 -2
  46. metadata +30 -14
  47. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_denial_submit_response_attest.rb +0 -38
  48. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_inquire_response_attest.rb +0 -39
  49. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_inquire_test.rb +0 -35
  50. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_submit_response_attest.rb +0 -39
  51. data/lib/davinci_pas_test_kit/generator/templates/validation_client.rb.erb +0 -50
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d8d0b9a954307d87237d925246cea164d132e5c224b78986f6e949ef2655e96
4
- data.tar.gz: 43e264bd0e029fbc0e183818e8b7d6b7358765566ea1776cae732d6cf810a805
3
+ metadata.gz: 62baa1ef3d1f180bb4ca13321592b2068377bc014a075338b2a2549f72b9a471
4
+ data.tar.gz: 032b4d39b5f4e5b82912f46dce3ae2d22431d14119c036c528f6620249299e16
5
5
  SHA512:
6
- metadata.gz: 230bd86fc641dacf8492c49d7e322c954c391ece2c6a6474886336709141e7862fd1d51612cb36c303e4323bc88b013bb7161acf279d7c0a0c8f8c841b99a338
7
- data.tar.gz: de2f53ac72aa59f9cd1e985b9b3685a8228e4981d202c9f9bb82ad6376ba001c079b71822f1341c374485dfb542f9e3be7d6dd81b1974e2e4a5bf7ed1702d185
6
+ metadata.gz: 9d32c1fc5e23da501b1b708a18b564f8f722c0759994c87c04c2ebbebb5806361ba0893af1178ee2de99ba0ecd17aeb36cfab9af0e42eba2f286884138e7edbd
7
+ data.tar.gz: cfbdece1e0e3d1dc963d0335608a698bb3c7e8cfb8e9a337e89a90fa0756f8c23f8732cdd986303dee3ac1b3a788cc1b3efe723aa5d973572d2d37346f876348
@@ -1,12 +1,17 @@
1
+ require 'subscriptions_test_kit'
1
2
  require_relative 'validator_suppressions'
2
3
  require_relative 'tags'
3
4
  require_relative 'urls'
4
5
  require_relative 'endpoints/claim_endpoint'
5
6
  require_relative 'endpoints/token_endpoint'
7
+ require_relative 'endpoints/subscription_create_endpoint'
8
+ require_relative 'endpoints/subscription_status_endpoint'
6
9
  require_relative 'custom_groups/v2.0.1/pas_client_authentication_group'
7
10
  require_relative 'custom_groups/v2.0.1/pas_client_approval_group'
8
11
  require_relative 'custom_groups/v2.0.1/pas_client_denial_group'
9
12
  require_relative 'custom_groups/v2.0.1/pas_client_pended_group'
13
+ require_relative 'custom_groups/v2.0.1/client_tests/pas_client_subscription_create_test'
14
+ require_relative 'custom_groups/v2.0.1/client_tests/pas_client_subscription_pas_conformance_test'
10
15
  require_relative 'generated/v2.0.1/pas_client_submit_must_support_use_case_group'
11
16
  require_relative 'generated/v2.0.1/pas_client_inquiry_must_support_use_case_group'
12
17
 
@@ -48,6 +53,11 @@ module DaVinciPASTestKit
48
53
  suite_endpoint :post, TOKEN_PATH, TokenEndpoint
49
54
  suite_endpoint :post, SUBMIT_PATH, ClaimEndpoint
50
55
  suite_endpoint :post, INQUIRE_PATH, ClaimEndpoint
56
+ suite_endpoint :post, FHIR_SUBSCRIPTION_PATH, SubscriptionCreateEndpoint
57
+ suite_endpoint :get, FHIR_SUBSCRIPTION_INSTANCE_PATH, SubscriptionsTestKit::SubscriptionReadEndpoint
58
+ suite_endpoint :post, FHIR_SUBSCRIPTION_INSTANCE_STATUS_PATH, SubscriptionStatusEndpoint
59
+ suite_endpoint :get, FHIR_SUBSCRIPTION_INSTANCE_STATUS_PATH, SubscriptionStatusEndpoint
60
+ suite_endpoint :post, FHIR_SUBSCRIPTION_RESOURCE_STATUS_PATH, SubscriptionStatusEndpoint
51
61
 
52
62
  resume_test_route :get, RESUME_PASS_PATH do |request|
53
63
  request.query_parameters['token']
@@ -67,6 +77,20 @@ module DaVinciPASTestKit
67
77
  (user provided or generated during the authorization tests)
68
78
  in the Authorization HTTP header with prefix "Bearer: ".
69
79
  )
80
+ group do
81
+ title 'PAS Subscription Setup'
82
+ description %(
83
+ These tests verify that the client can create a Subscription instance
84
+ that will tell the Payer how to notify the client when pended claims
85
+ are updated.
86
+ )
87
+ run_as_group
88
+
89
+ test from: :pas_client_v201_subscription_create_test
90
+ test from: :subscriptions_r4_client_subscription_verification
91
+ test from: :pas_client_v201_subscription_pas_conformance_test
92
+ test from: :subscriptions_r4_client_handshake_notification_verification
93
+ end
70
94
 
71
95
  group do
72
96
  title 'Demonstrate Workflow Support'
@@ -1,9 +1,11 @@
1
1
  require_relative '../../../urls'
2
+ require_relative '../../../user_input_response'
2
3
 
3
4
  module DaVinciPASTestKit
4
5
  module DaVinciPASV201
5
6
  class PASClientApprovalSubmitTest < Inferno::Test
6
7
  include URLs
8
+ include UserInputResponse
7
9
 
8
10
  id :pas_client_v201_approval_submit_test
9
11
  title 'Client submits a claim using the $submit operation'
@@ -18,8 +20,30 @@ module DaVinciPASTestKit
18
20
  Access token that the client will provide in the Authorization header of each request
19
21
  made during this test.
20
22
  )
23
+ input :approval_json_response,
24
+ title: 'Claim approved response JSON',
25
+ type: 'textarea',
26
+ optional: true,
27
+ description: %(
28
+ If provided, this JSON will be sent in response to $submit requests during this test
29
+ to indicate that the request has been approved.
30
+ It will be updated to make creation timestamps current.
31
+ If not provided, an approval response will be generated from the submitted Claim.
32
+ In either case, the response will be validated against the PAS Response Bundle profile.
33
+ )
34
+ submit_respond_with :approval_json_response
21
35
 
22
36
  run do
37
+ if user_inputted_response? :approval_json_response
38
+ assert_valid_json approval_json_response,
39
+ 'Input "Claim approved response JSON" must be valid JSON'
40
+ else
41
+ add_message('info', %(
42
+ No approved response provided in input '#{input_title(:approval_json_response)}'. Any responses to $submit
43
+ requests will be generated by Inferno from the submitted Claim.
44
+ ))
45
+ end
46
+
23
47
  wait(
24
48
  identifier: access_token,
25
49
  message: %(
@@ -29,7 +53,11 @@ module DaVinciPASTestKit
29
53
 
30
54
  `#{submit_url}`
31
55
 
32
- An approved response generated by Inferno will be returned.
56
+ The request must have an `Authorization` header with the value `Bearer #{access_token}`.
57
+
58
+ If the optional '**#{input_title(:approval_json_response)}**' input is populated, it will
59
+ be returned, updated with current timestamps. Otherwise, an approval response will
60
+ be generated by Inferno using the received Claim.
33
61
  )
34
62
  )
35
63
  end
@@ -1,13 +1,11 @@
1
1
  require_relative '../../../urls'
2
2
  require_relative '../../../user_input_response'
3
- require_relative '../../../pas_bundle_validation'
4
3
 
5
4
  module DaVinciPASTestKit
6
5
  module DaVinciPASV201
7
6
  class PASClientDenialSubmitTest < Inferno::Test
8
7
  include URLs
9
8
  include UserInputResponse
10
- include PasBundleValidation
11
9
 
12
10
  id :pas_client_v201_denial_submit_test
13
11
  title 'Client submits a claim using the $submit operation'
@@ -22,9 +20,30 @@ module DaVinciPASTestKit
22
20
  Access token that the client will provide in the Authorization header of each request
23
21
  made during this test.
24
22
  )
23
+ input :denial_json_response,
24
+ title: 'Claim denied response JSON',
25
+ type: 'textarea',
26
+ optional: true,
27
+ description: %(
28
+ If provided, this JSON will be sent in response to $submit requests during this test
29
+ to indicate that the request has been denied.
30
+ It will be updated to make creation timestamps current.
31
+ If not provided, a denial response will be generated from the submitted Claim.
32
+ In either case, the response will be validated against the PAS Response Bundle profile.
33
+ )
34
+ submit_respond_with :denial_json_response
25
35
 
26
36
  run do
27
- check_user_inputted_response :denial_json_response
37
+ if user_inputted_response? :denial_json_response
38
+ assert_valid_json denial_json_response,
39
+ 'Input "Claim denied response JSON" must be valid JSON'
40
+ else
41
+ add_message('info', %(
42
+ No denied response provided in input '#{input_title(:denial_json_response)}'. Any responses to $submit
43
+ requests will be generated by Inferno from the submitted Claim.
44
+ ))
45
+ end
46
+
28
47
  wait(
29
48
  identifier: access_token,
30
49
  message: %(
@@ -34,7 +53,11 @@ module DaVinciPASTestKit
34
53
 
35
54
  `#{submit_url}`
36
55
 
37
- The denial response provided in the '**#{input_title(:denial_json_response)}**' input will be returned.
56
+ The request must have an `Authorization` header with the value `Bearer #{access_token}`.
57
+
58
+ If the optional '**#{input_title(:denial_json_response)}**' input is populated, it will
59
+ be returned, updated with current timestamps. Otherwise, a denial response will
60
+ be generated by Inferno using the received Claim.
38
61
  )
39
62
  )
40
63
  end
@@ -3,32 +3,31 @@ require_relative '../../../urls'
3
3
 
4
4
  module DaVinciPASTestKit
5
5
  module DaVinciPASV201
6
- class ClientPendedPasInquiryRequestBundleValidationTest < Inferno::Test
6
+ class PasClientInquireRequestBundleValidationTest < Inferno::Test
7
7
  include DaVinciPASTestKit::PasBundleValidation
8
8
  include URLs
9
9
 
10
- id :pas_client_v201_pended_pas_inquiry_request_bundle_validation_test
11
- title 'Inquiry Request Bundle is valid'
10
+ id :pas_client_v201_inquire_request_bundle_validation_test
11
+ title 'Inquire Request Bundle is valid'
12
12
  description %(
13
- This test validates the conformity of the
14
- client's request to the
15
- [PAS Inquiry Request Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-inquiry-request-bundle) structure.
16
- It also checks that other conformance requirements defined in the [PAS Formal
13
+ This test verifies the conformity of the client's request body to the
14
+ [PAS Inquiry Request Bundle](http://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-pas-inquiry-request-bundle.html)
15
+ structure. It also checks that other conformance requirements defined in the [PAS Formal
17
16
  Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
18
17
  such as the presence of all referenced instances within the bundle and the
19
18
  conformance of those instances to the appropriate profiles, are met.
20
-
19
+
21
20
  It verifies the presence of mandatory elements and that elements with
22
21
  required bindings contain appropriate values. CodeableConcept element
23
22
  bindings will fail if none of their codings have a code/system belonging
24
23
  to the bound ValueSet. Quantity, Coding, and code element bindings will
25
24
  fail if their code/system are not found in the valueset.
26
-
25
+
27
26
  Note that because X12 value sets are not public, elements bound to value
28
27
  sets containing X12 codes are not validated.
29
-
28
+
30
29
  **Limitations**
31
-
30
+
32
31
  Due to recognized errors in the PAS IG around extension context definitions,
33
32
  this test may not pass due to spurious errors of the form "The extension
34
33
  [extension url] is not allowed at this point". See [this
@@ -36,27 +35,30 @@ module DaVinciPASTestKit
36
35
  for additional details.
37
36
  )
38
37
 
39
- def resource_type
40
- 'Bundle'
38
+ def request_type_tag
39
+ INQUIRE_TAG
41
40
  end
42
41
 
43
- def request_type
44
- 'inquire'
42
+ def workflow_tag
43
+ config.options[:workflow_tag]
45
44
  end
46
45
 
47
46
  run do
48
- assert request.url == inquire_url,
49
- "Request made to wrong URL: #{request.url}. Should instead be to #{inquire_url}"
47
+ if workflow_tag.present?
48
+ load_tagged_requests(request_type_tag, workflow_tag)
49
+ else
50
+ load_tagged_requests(request_type_tag)
51
+ end
52
+ skip_if !request.present?, 'No inquire requests received.'
50
53
 
51
54
  validate_pas_bundle_json(
52
55
  request.request_body,
53
56
  'http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-inquiry-request-bundle',
54
57
  '2.0.1',
55
- request_type,
58
+ 'inquire',
56
59
  'request_bundle',
57
- message: 'The inquire Bundle request provided for the Claim/$inquire operation is invalid:'
60
+ message: 'The Bundle provided for the Claim/$inquire operation is invalid:'
58
61
  )
59
-
60
62
  end
61
63
  end
62
64
  end
@@ -1,37 +1,43 @@
1
1
  require_relative '../../../pas_bundle_validation'
2
2
  require_relative '../../../user_input_response'
3
+ require_relative '../../../response_generator'
3
4
 
4
5
  module DaVinciPASTestKit
5
6
  module DaVinciPASV201
6
- class ClientDenialPasResponseBundleValidationTest < Inferno::Test
7
+ class PasClientInquireResponseBundleValidationTest < Inferno::Test
7
8
  include DaVinciPASTestKit::PasBundleValidation
8
9
  include UserInputResponse
10
+ include ResponseGenerator
9
11
 
10
- id :pas_client_v201_denial_pas_response_bundle_validation_test
11
- title '[USER INPUT VALIDATION] Response Bundle is valid'
12
+ id :pas_client_v201_inquire_response_bundle_validation_test
13
+ title '[USER INPUT VERIFICATION] Inquire Response Bundle is valid'
12
14
  description %(
13
- **USER INPUT VALIDATION**: This test validates input provided by the user instead of the system under test.
15
+ **USER INPUT VERIFICATION**: This test verifies input provided by the tester instead of the system under test.
14
16
  Errors encountered will be treated as a skip instead of a failure.
15
-
16
- This test validates the conformity of the
17
- user input to the
18
- [PAS Response Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-response-bundle) structure.
19
- It also checks that other conformance requirements defined in the [PAS Formal
17
+
18
+ This test verifies the conformity of the inquire response sent by Inferno, which will have been
19
+ either:
20
+ - the response body provided by the tester in the corresponding input, or
21
+ - created by Inferno from the $inquire Bundle.
22
+
23
+ In either case, this test verifies the conformity of the response body to the
24
+ [PAS Inquiry Response Bundle](https://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-pas-inquiry-response-bundle.html)
25
+ structure. It also checks that other conformance requirements defined in the [PAS Formal
20
26
  Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
21
27
  such as the presence of all referenced instances within the bundle and the
22
28
  conformance of those instances to the appropriate profiles, are met.
23
-
29
+
24
30
  It verifies the presence of mandatory elements and that elements with
25
31
  required bindings contain appropriate values. CodeableConcept element
26
32
  bindings will fail if none of their codings have a code/system belonging
27
33
  to the bound ValueSet. Quantity, Coding, and code element bindings will
28
34
  fail if their code/system are not found in the valueset.
29
-
35
+
30
36
  Note that because X12 value sets are not public, elements bound to value
31
37
  sets containing X12 codes are not validated.
32
-
38
+
33
39
  **Limitations**
34
-
40
+
35
41
  Due to recognized errors in the PAS IG around extension context definitions,
36
42
  this test may not pass due to spurious errors of the form "The extension
37
43
  [extension url] is not allowed at this point". See [this
@@ -39,24 +45,31 @@ module DaVinciPASTestKit
39
45
  for additional details.
40
46
  )
41
47
 
42
- def resource_type
43
- 'Bundle'
48
+ def request_type
49
+ 'inquire'
44
50
  end
45
51
 
46
- def request_type
47
- 'submit'
52
+ def workflow_tag
53
+ config.options[:workflow_tag]
48
54
  end
49
55
 
50
56
  run do
51
- check_user_inputted_response :denial_json_response
57
+ load_tagged_requests(workflow_tag, INQUIRE_TAG)
58
+ skip_if requests.empty?, 'No responses to verify because no inquire requests were made.'
59
+ message = if user_inputted_response? :inquire_json_response
60
+ "Invalid response generated from provided input '#{input_title(:inquire_json_response)}':"
61
+ else
62
+ 'Invalid response generated from the submitted claim:'
63
+ end
64
+
52
65
  validate_pas_bundle_json(
53
- denial_json_response,
54
- 'http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-response-bundle',
66
+ request.response_body,
67
+ 'http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-inquiry-response-bundle',
55
68
  '2.0.1',
56
69
  request_type,
57
70
  'response_bundle',
58
71
  skips: true,
59
- message: "Invalid input for '#{input_title(:denial_json_response)}':"
72
+ message:
60
73
  )
61
74
  end
62
75
  end
@@ -10,31 +10,150 @@ module DaVinciPASTestKit
10
10
  include PasBundleValidation
11
11
 
12
12
  id :pas_client_v201_pended_submit_test
13
- title 'Client submits a claim using the $submit operation'
13
+ title 'Client submits a claim and reacts to a pended response'
14
14
  description %(
15
15
  Inferno will wait for a prior authorization submission request
16
16
  from the client. Upon receipt, Inferno will respond with the
17
- provided pended response.
17
+ provided pended response. Subsequently, Inferno will send a
18
+ notification that the claim has been finalized and expect the
19
+ client under test to send a follow-up inquiry.
18
20
  )
21
+ config options: { accepts_multiple_requests: true }
19
22
  input :access_token,
20
23
  title: 'Access Token',
21
24
  description: %(
22
25
  Access token that the client will provide in the Authorization header of each request
23
26
  made during this test.
24
27
  )
28
+ input :notification_bundle,
29
+ title: 'Claim updated notification JSON',
30
+ type: 'textarea',
31
+ optional: true,
32
+ description: %(
33
+ If provided, this JSON will be sent as the notification for the
34
+ PAS Subscription to tell the client that a decision has been made on the pended claim.
35
+ Before sending, Inferno will update the provided notification with details that the tester cannot
36
+ know ahead of time, including timestamps corresponding to the notification trigger time, and the id of
37
+ the triggering ClaimResponse if Inferno mocks that ClaimResponse because it is not provided by the
38
+ tester through the *Claim pended response JSON* input.
39
+ If not provided, a notification will be generated from the returned ClaimResponse.
40
+ In either case the response will be validated to ensure that the notification
41
+ is conformant.
42
+ )
43
+ input :pended_json_response,
44
+ title: 'Claim pended response JSON',
45
+ type: 'textarea',
46
+ optional: true,
47
+ description: %(
48
+ If provided, this JSON will be sent in response to $submit requests during this test
49
+ to indicate that the request has been pended awaiting a final decision.
50
+ It will be updated to make creation timestamps current.
51
+ If not provided, a pended response will be generated from the submitted Claim.
52
+ In either case the response will be validated against the PAS Response Bundle profile.
53
+ )
54
+ input :inquire_json_response,
55
+ title: 'Inquire approved response JSON',
56
+ type: 'textarea',
57
+ optional: true,
58
+ description: %(
59
+ If provided, this JSON will be sent in response to $inquire requests during this test
60
+ to indicate that the request has been approved.
61
+ It will be updated to make creation timestamps current.
62
+ If not provided, an approval response will be generated from the submitted Claim.
63
+ In either case, the response will be validated against the PAS Response Bundle profile.
64
+ )
65
+ input :client_endpoint_access_token,
66
+ optional: true,
67
+ title: 'Client Notification Access Token',
68
+ description: %(
69
+ The bearer token that Inferno will send on requests to the client under test's rest-hook notification
70
+ endpoint. Not needed if the client under test will create a Subscription with an appropriate header value
71
+ in the `channel.header` element. If a value for the `authorization` header is provided in
72
+ `channel.header`, this value will override it.
73
+ )
74
+ submit_respond_with :pended_json_response
75
+ inquire_respond_with :inquire_json_response
25
76
 
26
77
  run do
27
- check_user_inputted_response :pended_json_response
78
+ load_tagged_requests(SUBSCRIPTION_CREATE_TAG)
79
+ skip_if requests.empty?, # NOTE: subscription needed ahead of time to support notification generation
80
+ %(
81
+ Pended workflow tests cannot proceed because no Subscription exists to receive notifications
82
+ for pended claims. Run the _PAS Subscription Setup_ tests to provide a Subscription for use
83
+ in delivering notifications before re-running the pended workflow tests.
84
+ )
85
+
86
+ if user_inputted_response? :pended_json_response
87
+ assert_valid_json pended_json_response,
88
+ "Input '#{input_title(:pended_json_response)}' must be valid JSON"
89
+ else
90
+ add_message('info', %(
91
+ No pended response provided in input '#{input_title(:pended_json_response)}'. Any responses to $submit
92
+ requests will be generated by Inferno from the submitted Claim.
93
+ ))
94
+ end
95
+
96
+ if user_inputted_response? :inquire_json_response
97
+ assert_valid_json inquire_json_response,
98
+ "Input '#{input_title(:inquire_json_response)}' must be valid JSON"
99
+ else
100
+ add_message('info', %(
101
+ No inquire response provided in input '#{input_title(:inquire_json_response)}'. Any responses to $inquire
102
+ requests will be generated by Inferno from the inquired Claim.
103
+ ))
104
+ end
105
+
106
+ if notification_bundle.present?
107
+ assert_valid_json notification_bundle,
108
+ "Input '#{input_title(:notification_bundle)}' must be valid JSON"
109
+ else
110
+ add_message('info', %(
111
+ No notification body provided in input '#{input_title(:notification_bundle)}'. When sending a
112
+ notification finalizing a pended $submit response, the notification body will be generated by Inferno
113
+ from the submitted Claim.
114
+ ))
115
+ end
116
+
28
117
  wait(
29
118
  identifier: access_token,
119
+ timeout: 600,
30
120
  message: %(
31
121
  **Pended Workflow Test**:
32
122
 
33
- Submit a PAS request to
123
+ 1. Submit a PAS request to
34
124
 
35
125
  `#{submit_url}`
36
126
 
37
- The pended response provided in the '**#{input_title(:pended_json_response)}**' input will be returned.
127
+ The request must have an `Authorization` header with the value `Bearer #{access_token}`.
128
+
129
+ If the optional '**#{input_title(:pended_json_response)}**' input is populated, it will
130
+ be returned, updated with current timestamps. Otherwise, a pended response will
131
+ be generated by Inferno using the received Claim.
132
+
133
+ 2. Within 5-10 seconds, Inferno will send a notification indicating that the ClaimResponse has been
134
+ finalized. If the optional '**#{input_title(:notification_bundle)}**' input is populated
135
+ Inferno will send it as a notification. Otherwise, a notification will be generated
136
+ from Inferno. In either case, the notification will be delivered to the endpoint provided on the
137
+ Subscription during the _PAS Subscription Setup_ tests.
138
+
139
+ 3. Once the notification has been received, submit a PAS inquiry request to
140
+
141
+ `#{inquire_url}`
142
+
143
+ The request must have an `Authorization` header with the value `Bearer #{access_token}`.
144
+
145
+ If the optional '**#{input_title(:inquire_json_response)}**' input is populated, it will
146
+ be returned, updated with current timestamps. Otherwise, an approval response will
147
+ be generated by Inferno using the received Claim.
148
+
149
+ Note that Inferno will ask testers to attest to correct behavior of the system between these steps,
150
+ i.e., that the system marked the pended prior auth request appropriately after step 1 (submit) but
151
+ before step 2 (notification). Thus testers should check their system state as appropriate in order
152
+ to be able to faithfully answer the attestations.
153
+
154
+ Once the client has completed these steps,
155
+ [click here to complete the test](#{resume_pass_url}?token=#{access_token})
156
+ and continue Inferno's evaluation of the interaction.
38
157
  )
39
158
  )
40
159
  end
@@ -3,32 +3,31 @@ require_relative '../../../urls'
3
3
 
4
4
  module DaVinciPASTestKit
5
5
  module DaVinciPASV201
6
- class ClientPasRequestBundleValidationTest < Inferno::Test
6
+ class PasClientRequestBundleValidationTest < Inferno::Test
7
7
  include DaVinciPASTestKit::PasBundleValidation
8
8
  include URLs
9
9
 
10
- id :pas_client_v201_pas_request_bundle_validation_test
11
- title 'Request Bundle is valid'
10
+ id :pas_client_v201_request_bundle_validation_test
11
+ title 'Submit Request Bundle is valid'
12
12
  description %(
13
- This test validates the conformity of the
14
- client's request to the
15
- [PAS Request Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-request-bundle) structure.
16
- It also checks that other conformance requirements defined in the [PAS Formal
13
+ This test verifies the conformity of the client's submit request body to the
14
+ [PAS Request Bundle](http://hl7.org/fhir/us/davinci-pas/STU2/StructureDefinition-profile-pas-request-bundle.html)
15
+ structure. It also checks that other conformance requirements defined in the [PAS Formal
17
16
  Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
18
17
  such as the presence of all referenced instances within the bundle and the
19
18
  conformance of those instances to the appropriate profiles, are met.
20
-
19
+
21
20
  It verifies the presence of mandatory elements and that elements with
22
21
  required bindings contain appropriate values. CodeableConcept element
23
22
  bindings will fail if none of their codings have a code/system belonging
24
23
  to the bound ValueSet. Quantity, Coding, and code element bindings will
25
24
  fail if their code/system are not found in the valueset.
26
-
25
+
27
26
  Note that because X12 value sets are not public, elements bound to value
28
27
  sets containing X12 codes are not validated.
29
-
28
+
30
29
  **Limitations**
31
-
30
+
32
31
  Due to recognized errors in the PAS IG around extension context definitions,
33
32
  this test may not pass due to spurious errors of the form "The extension
34
33
  [extension url] is not allowed at this point". See [this
@@ -36,27 +35,30 @@ module DaVinciPASTestKit
36
35
  for additional details.
37
36
  )
38
37
 
39
- def resource_type
40
- 'Bundle'
38
+ def workflow_tag
39
+ config.options[:workflow_tag]
41
40
  end
42
41
 
43
- def request_type
44
- 'submit'
42
+ def request_type_tag
43
+ SUBMIT_TAG
45
44
  end
46
45
 
47
46
  run do
48
- assert request.url == submit_url,
49
- "Request made to wrong URL: #{request.url}. Should instead be to #{submit_url}"
47
+ if workflow_tag.present?
48
+ load_tagged_requests(request_type_tag, workflow_tag)
49
+ else
50
+ load_tagged_requests(request_type_tag)
51
+ end
52
+ skip_if !request.present?, 'No submit requests received.'
50
53
 
51
54
  validate_pas_bundle_json(
52
55
  request.request_body,
53
56
  'http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-request-bundle',
54
57
  '2.0.1',
55
- request_type,
58
+ 'submit',
56
59
  'request_bundle',
57
- message: 'The submit Bundle request provided for the Claim/$submit operation is invalid:'
60
+ message: 'The Bundle provided for the Claim/$submit operation is invalid:'
58
61
  )
59
-
60
62
  end
61
63
  end
62
64
  end
@@ -2,15 +2,15 @@ require_relative '../../../urls'
2
2
 
3
3
  module DaVinciPASTestKit
4
4
  module DaVinciPASV201
5
- class PASClientApprovalSubmitResponseAttest < Inferno::Test
5
+ class PASClientResponseAttest < Inferno::Test
6
6
  include URLs
7
7
 
8
- id :pas_client_v201_approval_submit_response_attest
9
- title 'Check that the client registers the request as approved (Attestation)'
8
+ id :pas_client_v201_response_attest
9
+ title 'Check that the client reacts appropriately to the response (Attestation)'
10
10
  description %(
11
11
  This test provides the tester an opportunity to observe their client following
12
- the receipt of the approved response and attest that users are able to determine
13
- that the response has been approved.
12
+ the receipt of response and attest that users are able to see the appropriate
13
+ updates to the corresponding prior authorization request in their system.
14
14
  )
15
15
  input :access_token,
16
16
  title: 'Access Token',
@@ -19,15 +19,32 @@ module DaVinciPASTestKit
19
19
  made during this test.
20
20
  )
21
21
 
22
+ def workflow_tag
23
+ config.options[:workflow_tag]
24
+ end
25
+
26
+ def attest_message
27
+ config.options[:attest_message]
28
+ end
29
+
30
+ def workflow_name
31
+ case workflow_tag
32
+ when APPROVAL_WORKFLOW_TAG
33
+ 'Approval'
34
+ when DENIAL_WORKFLOW_TAG
35
+ 'Denial'
36
+ when PENDED_WORKFLOW_TAG
37
+ 'Pended'
38
+ end
39
+ end
40
+
22
41
  run do
23
- skip_if request.status.between?(400, 499), 'Bad claim submission request.'
24
42
  wait(
25
43
  identifier: access_token,
26
44
  message: %(
27
- **Approval Workflow Test**:
45
+ **#{workflow_name} Workflow Test**:
28
46
 
29
- I attest that the client system displays the submitted claim as 'approved' meaning that
30
- the user can proceed with ordering or providing the requested service.
47
+ #{attest_message}
31
48
 
32
49
  [Click here](#{resume_pass_url}?token=#{access_token}) if the above statement is **true**.
33
50