davinci_dtr_test_kit 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/lib/davinci_dtr_test_kit/auth_groups/oauth2_authentication_group.rb +51 -0
  4. data/lib/davinci_dtr_test_kit/auth_groups/token_request_test.rb +25 -0
  5. data/lib/davinci_dtr_test_kit/auth_groups/token_validation_test.rb +13 -0
  6. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_smart_app_questionnaire_workflow_group.rb +20 -0
  7. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_questionnaire_response_save_test.rb +31 -0
  8. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_smart_app_questionnaire_workflow_group.rb +89 -0
  9. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/prepopulation_attestation_test.rb +29 -0
  10. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/prepopulation_override_attestation_test.rb +30 -0
  11. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/rendering_enabled_questions_attestation_test.rb +30 -0
  12. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_full_ehr_questionnaire_workflow_group.rb +19 -0
  13. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_package_group.rb +16 -0
  14. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_rendering_attestation_test.rb +32 -0
  15. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_rendering_group.rb +14 -0
  16. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_response_group.rb +23 -0
  17. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_response_save_test.rb +31 -0
  18. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_smart_app_questionnaire_workflow_group.rb +22 -0
  19. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_package_request_test.rb +36 -0
  20. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_package_request_validation_test.rb +35 -0
  21. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_basic_conformance_test.rb +28 -0
  22. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_pre_population_test.rb +30 -0
  23. data/lib/davinci_dtr_test_kit/cql_test.rb +387 -0
  24. data/lib/davinci_dtr_test_kit/docs/dtr_payer_server_suite_description_v201.md +127 -0
  25. data/lib/davinci_dtr_test_kit/docs/dtr_smart_app_suite_description_v201.md +118 -0
  26. data/lib/davinci_dtr_test_kit/dtr_full_ehr_suite.rb +55 -0
  27. data/lib/davinci_dtr_test_kit/dtr_light_ehr_suite.rb +39 -0
  28. data/lib/davinci_dtr_test_kit/dtr_payer_server_suite.rb +104 -0
  29. data/lib/davinci_dtr_test_kit/dtr_questionnaire_response_validation.rb +180 -0
  30. data/lib/davinci_dtr_test_kit/dtr_smart_app_suite.rb +85 -0
  31. data/lib/davinci_dtr_test_kit/ext/inferno_core/record_response_route.rb +98 -0
  32. data/lib/davinci_dtr_test_kit/ext/inferno_core/request.rb +19 -0
  33. data/lib/davinci_dtr_test_kit/ext/inferno_core/runnable.rb +35 -0
  34. data/lib/davinci_dtr_test_kit/fixture_loader.rb +99 -0
  35. data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_burrito.json +170 -0
  36. data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_hamburger.json +175 -0
  37. data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_initial.json +140 -0
  38. data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/questionnaire_dinner_order_adaptive.json +95 -0
  39. data/lib/davinci_dtr_test_kit/fixtures/dinner_static/questionnaire_dinner_order_static.json +283 -0
  40. data/lib/davinci_dtr_test_kit/fixtures/dinner_static/questionnaire_response_dinner_order_static.json +170 -0
  41. data/lib/davinci_dtr_test_kit/fixtures/pre_populated_questionnaire_response.json +581 -0
  42. data/lib/davinci_dtr_test_kit/fixtures/questionnaire_package.json +2121 -0
  43. data/lib/davinci_dtr_test_kit/fixtures.rb +65 -0
  44. data/lib/davinci_dtr_test_kit/mock_ehr.rb +72 -0
  45. data/lib/davinci_dtr_test_kit/mock_payer.rb +142 -0
  46. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_libraries_test.rb +19 -0
  47. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_questionnaire_expressions_test.rb +20 -0
  48. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_questionnaire_extensions_test.rb +19 -0
  49. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_next_questionnaire_expressions_test.rb +20 -0
  50. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_next_questionnaire_extensions_test.rb +19 -0
  51. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_group.rb +88 -0
  52. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_request_test.rb +41 -0
  53. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_request_validation_test.rb +44 -0
  54. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_bundles_validation_test.rb +40 -0
  55. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_search_validation_test.rb +42 -0
  56. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_validation_test.rb +49 -0
  57. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_next_request_validation_test.rb +61 -0
  58. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_next_response_complete_test.rb +17 -0
  59. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_next_response_validation_test.rb +43 -0
  60. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_static_group.rb +51 -0
  61. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_libraries_test.rb +19 -0
  62. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_questionnaire_expressions_test.rb +20 -0
  63. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_questionnaire_extensions_test.rb +19 -0
  64. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_request_test.rb +33 -0
  65. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_request_validation_test.rb +46 -0
  66. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_response_validation_test.rb +50 -0
  67. data/lib/davinci_dtr_test_kit/tags.rb +8 -0
  68. data/lib/davinci_dtr_test_kit/urls.rb +50 -0
  69. data/lib/davinci_dtr_test_kit/validation_test.rb +72 -0
  70. data/lib/davinci_dtr_test_kit/version.rb +5 -0
  71. data/lib/davinci_dtr_test_kit.rb +4 -0
  72. metadata +132 -0
@@ -0,0 +1,49 @@
1
+ require_relative '../validation_test'
2
+ module DaVinciDTRTestKit
3
+ class PayerAdaptiveFormQuestionnaireResponseTest < Inferno::Test
4
+ include DaVinciDTRTestKit::ValidationTest
5
+ id :payer_server_adaptive_response_validation_test
6
+ title 'Validate that the adaptive response conforms to the Output Parameters profile'
7
+ # output :questionnaire_response
8
+ description %(
9
+ This test validates the conformance of the payer's response to the
10
+ [DTR Output Parameters](http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-output-parameters)
11
+ structure.
12
+
13
+ It verifies the presence of mandatory elements and that elements with required bindings contain appropriate
14
+ values. CodeableConcept element bindings will fail if none of their codings have a code/system belonging
15
+ to the bound ValueSet. Quantity, Coding, and code element bindings will fail if their code/system are not found in
16
+ the valueset.
17
+
18
+ This test may process multiple resources, labeling messages with the corresponding tested resources
19
+ This test may process multiple resources, labeling messages with the corresponding tested resources
20
+ in the order that they were received.
21
+ )
22
+
23
+ run do
24
+ skip_if retrieval_method == 'Static', 'Performing only static flow tests - only one flow is required.'
25
+ endpoint = custom_endpoint.blank? ? '/Questionnaire/$questionnaire-package' : custom_endpoint
26
+ if initial_adaptive_questionnaire_request.nil?
27
+ resources = load_tagged_requests(QUESTIONNAIRE_TAG)
28
+ else
29
+ resources = []
30
+ if initial_adaptive_questionnaire_request.is_a?(Array)
31
+ initial_adaptive_questionnaire_request.each do |_resource|
32
+ resources.push(fhir_operation("#{url}#{endpoint}", body: JSON.parse(initial_adaptive_questionnaire_request),
33
+ headers: { 'Content-Type': 'application/json' }))
34
+ end
35
+ else
36
+ resources.push(fhir_operation("#{url}#{endpoint}", body: JSON.parse(initial_adaptive_questionnaire_request),
37
+ headers: { 'Content-Type': 'application/json' }))
38
+ end
39
+ end
40
+ scratch[:adaptive_responses] = resources
41
+ assert !scratch[:adaptive_responses].nil?, 'No resources to validate.'
42
+ perform_response_validation_test(
43
+ resources,
44
+ :parameters,
45
+ 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-output-parameters'
46
+ )
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,61 @@
1
+ require_relative '../validation_test'
2
+ module DaVinciDTRTestKit
3
+ class PayerAdaptiveFormNextRequestTest < Inferno::Test
4
+ include URLs
5
+ include DaVinciDTRTestKit::ValidationTest
6
+ title '[USER INPUT VALIDATION] Next Question request is valid'
7
+ description %(
8
+ This test validates the conformance of the client's request to the
9
+ [SDC Parameters Next Question In](http://hl7.org/fhir/uv/sdc/StructureDefinition/parameters-questionnaire-next-question-in)
10
+ structure.
11
+
12
+ It verifies the presence of mandatory elements and that elements with required bindings contain appropriate
13
+ values. CodeableConcept element bindings will fail if none of their codings have a code/system belonging
14
+ to the bound ValueSet. Quantity, Coding, and code element bindings will fail if their code/system are not found in
15
+ the valueset.
16
+
17
+ This test may process multiple resources, labeling messages with the corresponding tested resources
18
+ in the order that they were received.
19
+ )
20
+ id :payer_server_next_request_validation
21
+
22
+ run do
23
+ skip_if retrieval_method == 'Static', 'Performing only static flow tests - only one flow is required.'
24
+ if next_question_requests.nil?
25
+ resources = load_tagged_requests(NEXT_TAG)
26
+ using_manual_entry = false
27
+ skip_if resources.nil?, 'No plain resources to validate.'
28
+ json_resources = resources.map { |r| JSON.parse(r.request_body) }
29
+ else
30
+ resources = next_question_requests
31
+ json_resources = JSON.parse(resources)
32
+ using_manual_entry = true
33
+ end
34
+ skip_if json_resources.nil?, 'No json resources to validate.'
35
+ if json_resources.any? { |r| r['resourceType'] == 'QuestionnaireResponse' }
36
+ perform_request_validation_test(
37
+ resources,
38
+ :questionnaireResponse,
39
+ 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse-adapt',
40
+ next_url,
41
+ using_manual_entry
42
+ )
43
+ elsif json_resources.any? { |r| r['resourceType'] == 'Parameters' }
44
+ perform_request_validation_test(
45
+ resources,
46
+ :parameters,
47
+ 'http://hl7.org/fhir/uv/sdc/StructureDefinition/parameters-questionnaire-next-question-in',
48
+ next_url,
49
+ using_manual_entry
50
+ )
51
+ else
52
+ raise new Inferno::Exceptions::AssertionException.new "Resource does not conform to the either
53
+ accepted profiles: http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse-adapt
54
+ or http://hl7.org/fhir/uv/sdc/StructureDefinition/parameters-questionnaire-next-question-in"
55
+ end
56
+ rescue Inferno::Exceptions::AssertionException => e
57
+ msg = e.message.to_s.strip
58
+ skip msg
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,17 @@
1
+ module DaVinciDTRTestKit
2
+ class PayerAdaptiveFormCompleteTest < Inferno::Test
3
+ id :payer_server_adaptive_completion_test
4
+ title 'Adaptive questionnaire was completed.'
5
+ description %(
6
+ This test validates that in the sequence of adaptive responses, one includes a "completed" status.
7
+ )
8
+
9
+ run do
10
+ skip_if retrieval_method == 'Static', 'Performing only static flow tests - only one flow is required.'
11
+ assert !scratch[:next_responses].nil?, 'No resources to validate.'
12
+ assert scratch[:next_responses].any? { |r|
13
+ JSON.parse(r.response_body)['status'] == 'completed'
14
+ }, 'Next request sequence did not result in a completed questionnaire.'
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,43 @@
1
+ require_relative '../validation_test'
2
+ module DaVinciDTRTestKit
3
+ class PayerAdaptiveFormNextResponseTest < Inferno::Test
4
+ include DaVinciDTRTestKit::ValidationTest
5
+ id :payer_server_next_response_validation_test
6
+ title 'Inferno sends payer server a request for subsequent adaptive forms - validate the responses'
7
+ description %(
8
+ This test validates the conformance of the payer's response to the
9
+ [SDC Questionnaire Response](http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse)
10
+ structure.
11
+
12
+ It verifies the presence of mandatory elements and that elements with required bindings contain appropriate
13
+ values. CodeableConcept element bindings will fail if none of their codings have a code/system belonging
14
+ to the bound ValueSet. Quantity, Coding, and code element bindings will fail if their code/system are not found in
15
+ the valueset.
16
+
17
+ This test may process multiple resources, labeling messages with the corresponding tested resources
18
+ This test may process multiple resources, labeling messages with the corresponding tested resources
19
+ in the order that they were received.
20
+ )
21
+
22
+ run do
23
+ skip_if retrieval_method == 'Static', 'Performing only static flow tests - only one flow is required.'
24
+ if next_question_requests.nil?
25
+ resources = load_tagged_requests(NEXT_TAG)
26
+ else
27
+ json_requests = JSON.parse(next_question_requests)
28
+ resources = json_requests.map do |resource|
29
+ fhir_operation("#{url}/Questionnaire/$next-question",
30
+ body: resource,
31
+ headers: { 'Content-Type': 'application/json' })
32
+ end
33
+ end
34
+ assert !resources.nil?, 'No resources to validate.'
35
+ scratch[:next_responses] = resources
36
+ perform_response_validation_test(
37
+ resources,
38
+ :questionnaireResponse,
39
+ 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse'
40
+ )
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,51 @@
1
+ require_relative 'static_form_request_test'
2
+ require_relative 'static_form_request_validation_test'
3
+ require_relative 'static_form_response_validation_test'
4
+ require_relative 'static_form_libraries_test'
5
+ require_relative 'static_form_questionnaire_extensions_test'
6
+ require_relative 'static_form_questionnaire_expressions_test'
7
+
8
+ module DaVinciDTRTestKit
9
+ class DTRPayerServerQuestionnairePackageGroup < Inferno::TestGroup
10
+ title 'Static Questionnaire Package Retrieval'
11
+ short_description 'Verify support for the payer server capabilities required to provide
12
+ appropriate questionnaire packages upon request.'
13
+ description %(
14
+ ## Background
15
+
16
+ The DTR Payer Server sequence verifies that the system under test is
17
+ able to provide correct responses for questionnaire package queries. These queries
18
+ must contain resources conforming to the questionnaire-package as
19
+ specified in the DTR v2.0.1 Implementation Guide.
20
+
21
+ ## Testing Work Flow Options
22
+
23
+ - Enter the `FHIR Server Base Url` and `Access Token` if you are connecting a client that will
24
+ provide inferno with requests to be tested and sent to the server under test.
25
+ These inputs must align with the configuration of the DTR client being used to provide requests.
26
+
27
+ - Enter the `Initial Static Questionnaire Request`, in addition to the
28
+ `FHIR Server Base Url` pointing to the payer server,
29
+ to provide the json requests manually, rather than relying on a DTR client.
30
+ )
31
+ id :payer_server_static_package
32
+ run_as_group
33
+
34
+ input :initial_static_questionnaire_request,
35
+ optional: true,
36
+ title: 'Initial Static Questionnaire Request',
37
+ description: 'Manual Flow',
38
+ type: 'textarea'
39
+
40
+ input_order :retrieval_method,
41
+ :url,
42
+ :initial_static_questionnaire_request
43
+
44
+ test from: :dtr_v201_payer_static_questionnaire_request_test, receives_request: :statice_questionnaire_request
45
+ test from: :dtr_v201_payer_static_form_request_validation_test
46
+ test from: :dtr_v201_payer_static_form_response_test
47
+ test from: :dtr_v201_payer_static_form_libraries_test
48
+ test from: :dtr_v201_payer_static_form_extensions_test
49
+ test from: :dtr_v201_payer_static_form_expressions_test
50
+ end
51
+ end
@@ -0,0 +1,19 @@
1
+ require_relative '../cql_test'
2
+ module DaVinciDTRTestKit
3
+ class PayerStaticFormLibrariesTest < Inferno::Test
4
+ include DaVinciDTRTestKit::CQLTest
5
+
6
+ id :dtr_v201_payer_static_form_libraries_test
7
+ title 'Parameters contain libraries necessary for pre-population'
8
+ description %(
9
+ Inferno check that the payer response contains no duplicate library names
10
+ and that libraries contain cql and elm data.
11
+ )
12
+
13
+ run do
14
+ skip_if retrieval_method == 'Adaptive', 'Performing only adaptive flow tests - only one flow is required.'
15
+ skip_if scratch[:questionnaire_bundle].nil?, 'No questionnaire bundle returned.'
16
+ check_libraries(scratch[:questionnaire_bundle])
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ require_relative '../cql_test'
2
+ module DaVinciDTRTestKit
3
+ class PayerStaticFormExpressionsTest < Inferno::Test
4
+ include DaVinciDTRTestKit::CQLTest
5
+
6
+ id :dtr_v201_payer_static_form_expressions_test
7
+ title 'Questionnaire(s) contains items with expressions necessary for pre-population'
8
+ description %(
9
+ Inferno checks that the payer server response has appropriate expressions and that expressions are
10
+ written in cql.
11
+ )
12
+
13
+ run do
14
+ skip_if retrieval_method == 'Adaptive', 'Performing only adaptive flow tests - only one flow is required.'
15
+ skip_if scratch[:questionnaire_bundle].nil?, 'No questionnaire bundle returned.'
16
+ questionnaire_items_test(scratch[:questionnaire_bundle], final_cql_test: true)
17
+ scratch[:questionnaire_bundle] = nil
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ require_relative '../cql_test'
2
+ module DaVinciDTRTestKit
3
+ class PayerStaticFormExtensionsTest < Inferno::Test
4
+ include DaVinciDTRTestKit::CQLTest
5
+
6
+ id :dtr_v201_payer_static_form_extensions_test
7
+ title 'Questionnaire(s) contains extensions necessary for pre-population'
8
+ description %(
9
+ Inferno checks that the payer server response has appropriate extensions and references to libraries within
10
+ those extensions.
11
+ )
12
+
13
+ run do
14
+ skip_if retrieval_method == 'Adaptive', 'Performing only adaptive flow tests - only one flow is required.'
15
+ skip_if scratch[:questionnaire_bundle].nil?, 'No questionnaire bundle returned.'
16
+ questionnaire_extensions_test(scratch[:questionnaire_bundle])
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ require_relative '../urls'
2
+ require_relative '../validation_test'
3
+ module DaVinciDTRTestKit
4
+ class StaticRFormRequestTest < Inferno::Test
5
+ include URLs
6
+ title 'Validate the questionnaires returned by the payer server'
7
+ description %(
8
+ Inferno will validate questionnaires returned by the payer server.
9
+ )
10
+ id :dtr_v201_payer_static_questionnaire_request_test
11
+ config options: { accepts_multiple_requests: false }
12
+
13
+ run do
14
+ skip_if retrieval_method == 'Adaptive', 'Performing only adaptive flow tests - only one flow is required.'
15
+ pass_if !initial_static_questionnaire_request.nil?,
16
+ 'Proceeding with manually provided resources.'
17
+ skip_if access_token.nil?, 'Please provide an access token or all request resources as inputs.'
18
+ wait(
19
+ identifier: access_token,
20
+ message: %(
21
+ **Static Form Testing**
22
+
23
+ Invoke the DTR Questionnaire Package operation by sending a POST request to
24
+
25
+ `#{questionnaire_package_url}`
26
+
27
+ A set of questionnaire packages generated by Inferno will be returned. Each of the following tests
28
+ will validate all resources, marking messages in the order they are received.
29
+ )
30
+ )
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,46 @@
1
+ require_relative '../urls'
2
+ require_relative '../validation_test'
3
+ module DaVinciDTRTestKit
4
+ class PayerStaticFormRequestValidationTest < Inferno::Test
5
+ include DaVinciDTRTestKit::ValidationTest
6
+ include URLs
7
+ id :dtr_v201_payer_static_form_request_validation_test
8
+ title '[USER INPUT VALIDATION] Client sends payer server a request for a static form'
9
+ description %(
10
+ Inferno will validate that the request to the payer server conforms to the
11
+ [Input Parameters profile](http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-input-parameters).
12
+
13
+ It verifies the presence of mandatory elements and that elements with required bindings contain appropriate
14
+ values. CodeableConcept element bindings will fail if none of their codings have a code/system belonging
15
+ to the bound ValueSet. Quantity, Coding, and code element bindings will fail if their code/system
16
+ are not found in the valueset.
17
+
18
+ This test may process multiple resources, labeling messages with the corresponding tested resources
19
+ in the order that they were received.
20
+ )
21
+
22
+ run do
23
+ skip_if retrieval_method == 'Adaptive', 'Performing only adaptive flow tests - only one flow is required.'
24
+ if initial_static_questionnaire_request.nil?
25
+ using_manual_entry = false
26
+ skip_if access_token.nil?, 'No access token provided - required for client flow.'
27
+ resources = load_tagged_requests(QUESTIONNAIRE_TAG)
28
+ skip_if resources.nil?, 'No request resource received from the client.'
29
+ perform_request_validation_test(
30
+ resources,
31
+ :parameters,
32
+ 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-input-parameters',
33
+ questionnaire_package_url,
34
+ using_manual_entry
35
+ )
36
+ else
37
+ skip_if initial_static_questionnaire_request.nil?, 'No request resource was provided - required for manual flow'
38
+ request = FHIR.from_contents(initial_static_questionnaire_request)
39
+ assert_valid_resource(resource: request, profile_url: 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-input-parameters')
40
+ end
41
+ rescue Inferno::Exceptions::AssertionException => e
42
+ msg = e.message.to_s.strip
43
+ skip msg
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,50 @@
1
+ require_relative '../urls'
2
+ require_relative '../validation_test'
3
+ module DaVinciDTRTestKit
4
+ class PayerStaticFormResponseTest < Inferno::Test
5
+ include URLs
6
+ include DaVinciDTRTestKit::ValidationTest
7
+ id :dtr_v201_payer_static_form_response_test
8
+ title 'Validate that the static response conforms to the Output Parameters profile'
9
+ description %(
10
+ Inferno will validate that the payer server response conforms to the
11
+ [Output Parameters profile](http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-output-parameters).
12
+
13
+ It verifies the presence of mandatory elements and that elements with required bindings contain appropriate
14
+ values. CodeableConcept element bindings will fail if none of their codings have a code/system belonging
15
+ to the bound ValueSet. Quantity, Coding, and code element bindings will fail if their code/system are not found in
16
+ the valueset.
17
+
18
+ This test may process multiple resources, labeling messages with the corresponding tested resources
19
+ in the order that they were received.
20
+ )
21
+
22
+ run do
23
+ skip_if retrieval_method == 'Adaptive', 'Performing only adaptive flow tests - only one flow is required.'
24
+
25
+ if initial_static_questionnaire_request.nil?
26
+ skip_if access_token.nil?, 'No access token provided - required for client flow.'
27
+ resources = load_tagged_requests(QUESTIONNAIRE_TAG)
28
+ skip_if resources.nil?, 'No request resource received from the client.'
29
+ scratch[:questionnaire_bundle] = resources
30
+ perform_response_validation_test(
31
+ resources,
32
+ :parameters,
33
+ 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-output-parameters'
34
+ )
35
+ else
36
+ FHIR.from_contents(initial_static_questionnaire_request)
37
+ fhir_operation("#{url}/Questionnaire/$questionnaire-package",
38
+ body: JSON.parse(initial_static_questionnaire_request),
39
+ headers: { 'Content-Type': 'application/json' })
40
+ scratch[:questionnaire_bundle] = resource
41
+
42
+ assert_response_status(200)
43
+ assert_resource_type(:parameters)
44
+ questionnaire_bundle = resource.parameter.find { |param| param.name == 'return' }&.resource
45
+ assert questionnaire_bundle, 'No questionnaire bundle found in the response'
46
+ assert_valid_resource(resource: questionnaire_bundle, profile_url: 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/DTR-QPackageBundle')
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DaVinciDTRTestKit
4
+ QUESTIONNAIRE_TAG = 'payer_server_questionnaire_package'
5
+ NEXT_TAG = 'payer_server_adaptive_questionnaire_package'
6
+ QUESTIONNAIRE_PACKAGE_TAG = 'dtr_questionnaire_package'
7
+ SMART_APP_EHR_REQUEST_TAG = 'dtr_smart_app_ehr_request'
8
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DaVinciDTRTestKit
4
+ TOKEN_PATH = '/mock_auth/token'
5
+ QUESTIONNAIRE_PACKAGE_PATH = '/fhir/Questionnaire/$questionnaire-package'
6
+ NEXT_PATH = '/fhir/Questionnaire/$next-question'
7
+ QUESTIONNAIRE_RESPONSE_PATH = '/fhir/QuestionnaireResponse'
8
+ RESUME_PASS_PATH = '/resume_pass'
9
+ RESUME_FAIL_PATH = '/resume_fail'
10
+ FHIR_RESOURCE_PATH = '/fhir/:resource/:id'
11
+ FHIR_SEARCH_PATH = '/fhir/:resource'
12
+
13
+ module URLs
14
+ def base_url
15
+ @base_url ||= "#{Inferno::Application['base_url']}/custom/#{suite_id}"
16
+ end
17
+
18
+ def token_url
19
+ @token_url ||= base_url + TOKEN_PATH
20
+ end
21
+
22
+ def questionnaire_package_url
23
+ @questionnaire_package_url ||= base_url + QUESTIONNAIRE_PACKAGE_PATH
24
+ end
25
+
26
+ def next_url
27
+ @next_url ||= base_url + NEXT_PATH
28
+ end
29
+
30
+ def questionnaire_response_url
31
+ @questionnaire_response_url ||= base_url + QUESTIONNAIRE_RESPONSE_PATH
32
+ end
33
+
34
+ def fhir_base_url
35
+ @fhir_base_url ||= "#{base_url}/fhir"
36
+ end
37
+
38
+ def resume_pass_url
39
+ @resume_pass_url ||= base_url + RESUME_PASS_PATH
40
+ end
41
+
42
+ def resume_fail_url
43
+ @resume_fail_url ||= base_url + RESUME_FAIL_PATH
44
+ end
45
+
46
+ def suite_id
47
+ self.class.suite.id
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,72 @@
1
+ module DaVinciDTRTestKit
2
+ module ValidationTest
3
+ def tests_failed
4
+ @tests_failed ||= {}
5
+ end
6
+
7
+ def validate_resource(fhir_resource, resource_type, profile_url, index)
8
+ assert fhir_resource.present?, 'Resource does not contain a recognized FHIR object'
9
+ begin
10
+ assert_resource_type(resource_type, resource: fhir_resource)
11
+ assert_valid_resource(resource: fhir_resource,
12
+ profile_url:)
13
+ rescue StandardError => e
14
+ messages.each do |message|
15
+ message[:message].prepend("[Resource #{index + 1}] ")
16
+ end
17
+ if tests_failed[profile_url].blank?
18
+ tests_failed[profile_url] = [e]
19
+ else
20
+ tests_failed[profile_url] << e
21
+ end
22
+ return false
23
+ end
24
+ true
25
+ end
26
+
27
+ def perform_request_validation_test(
28
+ resources,
29
+ resource_type,
30
+ profile_url,
31
+ resource_url,
32
+ using_manual_entry
33
+ )
34
+ omit_if resources.blank?,
35
+ "No #{resource_type} resources provided so the #{profile_url} profile does not apply"
36
+ resources = JSON.parse(resources) if using_manual_entry
37
+ resources = [resources] unless resources.is_a?(Array)
38
+ resources.each_with_index do |resource, index|
39
+ if using_manual_entry
40
+ assert_valid_json(resource.to_json)
41
+ fhir_resource = FHIR.from_contents(resource.to_json)
42
+ else
43
+ assert resource.url == resource_url,
44
+ "Request made to wrong URL: #{resource.request[:url]}. Should instead be to #{resource_url}"
45
+ assert_valid_json(resource.request[:body])
46
+ fhir_resource = FHIR.from_contents(resource.request[:body])
47
+ end
48
+ validate_resource(fhir_resource, resource_type, profile_url, index)
49
+ end
50
+ return if tests_failed[profile_url].blank?
51
+
52
+ raise tests_failed[profile_url][0]
53
+ end
54
+
55
+ def perform_response_validation_test(
56
+ resources,
57
+ resource_type,
58
+ profile_url
59
+ )
60
+ omit_if resources.blank?,
61
+ "No #{resource_type} resources provided so the #{profile_url} profile does not apply"
62
+ resources.each_with_index do |resource, index|
63
+ fhir_resource = FHIR.from_contents(resource.response[:body])
64
+ assert_response_status([200, 202], request: resource, response: resource.response)
65
+ validate_resource(fhir_resource, resource_type, profile_url, index)
66
+ end
67
+ return if tests_failed[profile_url].blank?
68
+
69
+ raise tests_failed[profile_url][0]
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DaVinciDTRTestKit
4
+ VERSION = '0.9.0'.freeze
5
+ end
@@ -0,0 +1,4 @@
1
+ require_relative 'davinci_dtr_test_kit/dtr_payer_server_suite'
2
+ require_relative 'davinci_dtr_test_kit/dtr_smart_app_suite'
3
+ # require_relative 'davinci_dtr_test_kit/dtr_full_ehr_suite'
4
+ # require_relative 'davinci_dtr_test_kit/dtr_light_ehr_suite'