davinci_dtr_test_kit 0.13.0 → 0.14.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.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_completion_group.rb +23 -0
  3. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_followup_questions_group.rb +26 -0
  4. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_next_question_request_test.rb +93 -0
  5. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_next_question_request_validation_test.rb +62 -0
  6. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_next_question_retrieval_group.rb +23 -0
  7. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_response_validation_test.rb +66 -0
  8. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_full_ehr_adaptive_dinner_questionnaire_workflow_group.rb +76 -0
  9. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_full_ehr_adaptive_questionnaire_initial_retrieval_group.rb +27 -0
  10. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_full_ehr_adaptive_questionnaire_request_test.rb +63 -0
  11. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_smart_app_adaptive_questionnaire_initial_retrieval_group.rb +24 -0
  12. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_smart_app_adaptive_questionnaire_request_test.rb +148 -0
  13. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_smart_app_questionnaire_workflow_group.rb +75 -0
  14. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_full_ehr_questionnaire_workflow_group.rb +22 -38
  15. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_smart_app_dinner_questionnaire_package_request_test.rb +13 -16
  16. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_smart_app_questionnaire_workflow_group.rb +9 -31
  17. data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → full_ehr}/dtr_full_ehr_launch_attestation_test.rb +7 -6
  18. data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → full_ehr}/dtr_full_ehr_prepopulation_attestation_test.rb +7 -7
  19. data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → full_ehr}/dtr_full_ehr_prepopulation_override_attestation_test.rb +7 -7
  20. data/lib/davinci_dtr_test_kit/client_groups/{dinner_static/dtr_full_ehr_dinner_questionnaire_package_request_test.rb → full_ehr/dtr_full_ehr_questionnaire_package_request_test.rb} +2 -3
  21. data/lib/davinci_dtr_test_kit/client_groups/{dinner_static/dtr_full_ehr_dinner_static_questionnaire_response_conformance_test.rb → full_ehr/dtr_full_ehr_questionnaire_response_conformance_test.rb} +7 -3
  22. data/lib/davinci_dtr_test_kit/client_groups/{dinner_static/dtr_full_ehr_dinner_static_questionnaire_response_correctness_test.rb → full_ehr/dtr_full_ehr_questionnaire_response_correctness_test.rb} +14 -7
  23. data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → full_ehr}/dtr_full_ehr_rendering_enabled_questions_attestation_test.rb +7 -7
  24. data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_saving_questionnaire_response_group.rb +29 -0
  25. data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → full_ehr}/dtr_full_ehr_store_attestation_test.rb +7 -7
  26. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_rendering_attestation_test.rb +7 -6
  27. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_resp_questionnaire_package_request_test.rb +15 -18
  28. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_basic_conformance_test.rb +5 -1
  29. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_pre_population_test.rb +12 -5
  30. data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → smart_app}/dtr_smart_app_prepopulation_attestation_test.rb +7 -7
  31. data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → smart_app}/dtr_smart_app_prepopulation_override_attestation_test.rb +7 -6
  32. data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → smart_app}/dtr_smart_app_questionnaire_response_save_test.rb +17 -7
  33. data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → smart_app}/dtr_smart_app_rendering_enabled_questions_attestation_test.rb +7 -7
  34. data/lib/davinci_dtr_test_kit/client_groups/smart_app/dtr_smart_app_saving_questionnaire_response_group.rb +27 -0
  35. data/lib/davinci_dtr_test_kit/cql_test.rb +37 -140
  36. data/lib/davinci_dtr_test_kit/create_test.rb +25 -0
  37. data/lib/davinci_dtr_test_kit/docs/dtr_full_ehr_suite_description_v201.md +95 -37
  38. data/lib/davinci_dtr_test_kit/docs/dtr_light_ehr_suite_description_v201.md +11 -6
  39. data/lib/davinci_dtr_test_kit/docs/dtr_payer_server_suite_description_v201.md +32 -29
  40. data/lib/davinci_dtr_test_kit/docs/dtr_smart_app_suite_description_v201.md +48 -32
  41. data/lib/davinci_dtr_test_kit/dtr_full_ehr_suite.rb +13 -17
  42. data/lib/davinci_dtr_test_kit/dtr_light_ehr_suite.rb +67 -2
  43. data/lib/davinci_dtr_test_kit/dtr_payer_server_suite.rb +9 -20
  44. data/lib/davinci_dtr_test_kit/dtr_questionnaire_response_validation.rb +18 -10
  45. data/lib/davinci_dtr_test_kit/dtr_smart_app_suite.rb +32 -59
  46. data/lib/davinci_dtr_test_kit/endpoints/cors.rb +20 -0
  47. data/lib/davinci_dtr_test_kit/endpoints/mock_authorization/authorize_endpoint.rb +32 -0
  48. data/lib/davinci_dtr_test_kit/endpoints/mock_authorization/simple_token_endpoint.rb +19 -0
  49. data/lib/davinci_dtr_test_kit/endpoints/mock_authorization/token_endpoint.rb +116 -0
  50. data/lib/davinci_dtr_test_kit/endpoints/mock_authorization.rb +83 -0
  51. data/lib/davinci_dtr_test_kit/endpoints/mock_ehr/fhir_get_endpoint.rb +95 -0
  52. data/lib/davinci_dtr_test_kit/endpoints/mock_ehr/questionnaire_response_endpoint.rb +22 -0
  53. data/lib/davinci_dtr_test_kit/endpoints/mock_ehr.rb +25 -0
  54. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_next_question_endpoint.rb +11 -0
  55. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_questionnaire_package_endpoint.rb +11 -0
  56. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/next_question_endpoint.rb +162 -0
  57. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/next_question_proxy_endpoint.rb +36 -0
  58. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/questionnaire_package_endpoint.rb +62 -0
  59. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/questionnaire_package_proxy_endpoint.rb +38 -0
  60. data/lib/davinci_dtr_test_kit/endpoints/mock_payer.rb +36 -0
  61. data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_burrito.json +10 -2
  62. data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_hamburger.json +10 -2
  63. data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_initial.json +10 -2
  64. data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/questionnaire_dinner_order_adaptive.json +4 -3
  65. data/lib/davinci_dtr_test_kit/fixtures.rb +24 -1
  66. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_libraries_test.rb +2 -2
  67. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_questionnaire_expressions_test.rb +4 -3
  68. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_questionnaire_extensions_test.rb +3 -2
  69. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_next_questionnaire_expressions_test.rb +6 -6
  70. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_next_questionnaire_extensions_test.rb +6 -5
  71. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_group.rb +2 -2
  72. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_bundles_validation_test.rb +6 -9
  73. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_search_validation_test.rb +15 -12
  74. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_validation_test.rb +33 -23
  75. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_next_response_complete_test.rb +4 -4
  76. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_next_response_validation_test.rb +16 -12
  77. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_libraries_test.rb +2 -2
  78. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_questionnaire_expressions_test.rb +5 -4
  79. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_questionnaire_extensions_test.rb +4 -3
  80. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_response_validation_test.rb +32 -25
  81. data/lib/davinci_dtr_test_kit/profiles/communication_request/communication_request_read.rb +29 -0
  82. data/lib/davinci_dtr_test_kit/profiles/communication_request/communication_request_validation.rb +35 -0
  83. data/lib/davinci_dtr_test_kit/profiles/communication_request_group.rb +39 -0
  84. data/lib/davinci_dtr_test_kit/profiles/coverage/coverage_read.rb +29 -0
  85. data/lib/davinci_dtr_test_kit/profiles/coverage/coverage_validation.rb +35 -0
  86. data/lib/davinci_dtr_test_kit/profiles/coverage_group.rb +38 -0
  87. data/lib/davinci_dtr_test_kit/profiles/device_request/device_request_read.rb +29 -0
  88. data/lib/davinci_dtr_test_kit/profiles/device_request/device_request_validation.rb +35 -0
  89. data/lib/davinci_dtr_test_kit/profiles/device_request_group.rb +39 -0
  90. data/lib/davinci_dtr_test_kit/profiles/encounter/encounter_read.rb +29 -0
  91. data/lib/davinci_dtr_test_kit/profiles/encounter/encounter_validation.rb +35 -0
  92. data/lib/davinci_dtr_test_kit/profiles/encounter_group.rb +39 -0
  93. data/lib/davinci_dtr_test_kit/profiles/medication_request/medication_request_read.rb +29 -0
  94. data/lib/davinci_dtr_test_kit/profiles/medication_request/medication_request_validation.rb +35 -0
  95. data/lib/davinci_dtr_test_kit/profiles/medication_request_group.rb +39 -0
  96. data/lib/davinci_dtr_test_kit/profiles/nutrition_order/nutrition_order_read.rb +29 -0
  97. data/lib/davinci_dtr_test_kit/profiles/nutrition_order/nutrition_order_validation.rb +35 -0
  98. data/lib/davinci_dtr_test_kit/profiles/nutrition_order_group.rb +39 -0
  99. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_context_search.rb +35 -0
  100. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_create.rb +26 -0
  101. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_patient_search.rb +55 -0
  102. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_read.rb +22 -0
  103. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_update.rb +26 -0
  104. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_validation.rb +37 -0
  105. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response_group.rb +66 -0
  106. data/lib/davinci_dtr_test_kit/profiles/service_request/service_request_read.rb +29 -0
  107. data/lib/davinci_dtr_test_kit/profiles/service_request/service_request_validation.rb +35 -0
  108. data/lib/davinci_dtr_test_kit/profiles/service_request_group.rb +39 -0
  109. data/lib/davinci_dtr_test_kit/profiles/task/task_create.rb +26 -0
  110. data/lib/davinci_dtr_test_kit/profiles/task/task_read.rb +29 -0
  111. data/lib/davinci_dtr_test_kit/profiles/task/task_update.rb +26 -0
  112. data/lib/davinci_dtr_test_kit/profiles/task/task_validation.rb +35 -0
  113. data/lib/davinci_dtr_test_kit/profiles/task_group.rb +52 -0
  114. data/lib/davinci_dtr_test_kit/profiles/vision_prescription/vision_prescription_read.rb +29 -0
  115. data/lib/davinci_dtr_test_kit/profiles/vision_prescription/vision_prescription_validation.rb +35 -0
  116. data/lib/davinci_dtr_test_kit/profiles/vision_prescription_group.rb +39 -0
  117. data/lib/davinci_dtr_test_kit/read_test.rb +22 -0
  118. data/lib/davinci_dtr_test_kit/tags.rb +5 -7
  119. data/lib/davinci_dtr_test_kit/update_test.rb +25 -0
  120. data/lib/davinci_dtr_test_kit/validation_test.rb +19 -4
  121. data/lib/davinci_dtr_test_kit/version.rb +1 -1
  122. metadata +109 -20
  123. data/lib/davinci_dtr_test_kit/ext/inferno_core/record_response_route.rb +0 -98
  124. data/lib/davinci_dtr_test_kit/ext/inferno_core/request.rb +0 -19
  125. data/lib/davinci_dtr_test_kit/ext/inferno_core/runnable.rb +0 -35
  126. data/lib/davinci_dtr_test_kit/mock_auth_server.rb +0 -228
  127. data/lib/davinci_dtr_test_kit/mock_ehr.rb +0 -105
  128. data/lib/davinci_dtr_test_kit/mock_payer.rb +0 -100
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a072f135a4057afa53b8836a3436fab457fc8c1ab15199e19608732b16d16cb
4
- data.tar.gz: e4942f1af9755743eab89b7a0cc8b559929ad8b4be4bed00e7e1a33b4de1b0bd
3
+ metadata.gz: ae91fb5204116f970359bf64adea2ee147946908cad1c0c2924af282b60b6881
4
+ data.tar.gz: 3b03d29e31aa196709ff778838cad35713a07dbc62da4d7b30b4cdfb2c78cff5
5
5
  SHA512:
6
- metadata.gz: aae323b007b88a564283b1fc946490e3c2330d6b3081de4783c0611c25afd732327e631d7e782743bab1fe1cab797dad84bcd9403accedcdb21f464278d05f0f
7
- data.tar.gz: e68f011efaa3f0785d94c7a1f683a9986474dc887f3b99492b62ccdaf5f3ecb92387be39c909872a6f6448dfc6cb8dc1520de971557d8325cf725b3fe6853771
6
+ metadata.gz: 8309214d76c859a568d6787cb04fdb973d87ca4c6e2fd1f49c0c373ed5984e468fe473b291bd98aff4af735ba7065b0fd55555f14baa532d49f7f578427213b4
7
+ data.tar.gz: 130304858f630e00eec87b24c03bf9e303d97a3d5d42624a722da74e7f1ba6aad14e91c70d914af0c5193278190a7eaf5a88dba24eda0ff3a6533aaee4a69421
@@ -0,0 +1,23 @@
1
+ require_relative 'dtr_adaptive_questionnaire_next_question_retrieval_group'
2
+
3
+ module DaVinciDTRTestKit
4
+ class DTRAdaptiveQuestionnaireCompletionGroup < Inferno::TestGroup
5
+ id :dtr_adaptive_questionnaire_completion
6
+ title 'Completing the Adaptive Questionnaire'
7
+ description %(
8
+ The client makes a final $next-question call, including the answers to all required questions asked so far.
9
+ Inferno will validate that the request conforms to the [next question operation input parameters profile](http://hl7.org/fhir/uv/sdc/StructureDefinition/parameters-questionnaire-next-question-in)
10
+ and will update the status of the QuestionnaireResponse resource parameter to `complete`.
11
+ Inferno will also validate the completed QuestionnaireResponse conformance.
12
+ )
13
+
14
+ config(
15
+ options: {
16
+ next_question_prompt_title: 'Last Next Question Request'
17
+ }
18
+ )
19
+ run_as_group
20
+
21
+ group from: :dtr_adaptive_questionnaire_next_question_retrieval
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'dtr_adaptive_questionnaire_next_question_retrieval_group'
2
+
3
+ module DaVinciDTRTestKit
4
+ class DTRAdaptiveQuestionnaireFollowupQuestionsGroup < Inferno::TestGroup
5
+ id :dtr_adaptive_questionnaire_followup_questions
6
+ title 'Retrieving the Next Question'
7
+ description %(
8
+ The client makes a subsequent call to request the next question or set of questions
9
+ using the $next-question operation, and including the answers to all required questions
10
+ in the questionnaire to this point.
11
+ Inferno will validate that the request conforms to the [next question operation input parameters profile](http://hl7.org/fhir/uv/sdc/StructureDefinition/parameters-questionnaire-next-question-in)
12
+ and will provide the next questions accordingly for the tester to complete and attest to pre-population
13
+ and questionnaire rendering.
14
+ )
15
+
16
+ config(
17
+ options: {
18
+ next_question_prompt_title: 'Follow-up Next Question Request'
19
+ }
20
+ )
21
+
22
+ run_as_group
23
+
24
+ group from: :dtr_adaptive_questionnaire_next_question_retrieval
25
+ end
26
+ end
@@ -0,0 +1,93 @@
1
+ require_relative '../../urls'
2
+
3
+ module DaVinciDTRTestKit
4
+ class DTRAdaptiveQuestionnaireNextQuestionRequestTest < Inferno::Test
5
+ include URLs
6
+
7
+ id :dtr_adaptive_questionnaire_next_question_request
8
+ title 'Invoke the $next-question operation'
9
+ description %(
10
+ Inferno will wait for the client to invoke the $next-question operation to retrieve the next question
11
+ or set of questions.
12
+ Inferno will validate the request body and update the contained Questionnaire to include
13
+ the next question or set of questions.
14
+ )
15
+
16
+ input :access_token
17
+
18
+ def example_client_jwt_payload_part
19
+ Base64.strict_encode64({ inferno_client_id: access_token }.to_json).delete('=')
20
+ end
21
+
22
+ def request_identification
23
+ if config.options[:smart_app]
24
+ "eyJhbGciOiJub25lIn0.#{example_client_jwt_payload_part}"
25
+ else
26
+ access_token
27
+ end
28
+ end
29
+
30
+ def cont_test_description
31
+ <<~DESCRIPTION
32
+ ### Continuing the Tests
33
+
34
+ When the DTR application has finished loading the Questionnaire,
35
+ including any clinical data requests to support pre-population,
36
+ [Click here](#{resume_pass_url}?token=#{access_token}) to continue.
37
+ DESCRIPTION
38
+ end
39
+
40
+ def next_question_prompt_title
41
+ config.options[:next_question_prompt_title]
42
+ end
43
+
44
+ def next_question_prompt
45
+ if next_question_prompt_title&.include?('Initial')
46
+ 'Invoke the $next-question operation by sending a POST request to'
47
+ elsif next_question_prompt_title&.include?('Last')
48
+ 'Answer the remaining questions and then make a final next-question request by sending a POST request to'
49
+ else
50
+ "Answer the 'What do you want for dinner' question and then make a next-question request by sending a POST " \
51
+ 'request to'
52
+ end
53
+ end
54
+
55
+ def prompt_cont
56
+ if next_question_prompt_title&.include?('Initial')
57
+ %(Upon receipt, Inferno will provide the first set of questions to complete.)
58
+ elsif next_question_prompt_title&.include?('Last')
59
+ %(Upon receipt, Inferno will update the status of the QuestionnaireResponse
60
+ resource parameter to `complete`.)
61
+ else
62
+ %(Upon receipt, Inferno will provide the next set of questions to complete
63
+ based on previous answers.)
64
+ end
65
+ end
66
+
67
+ run do
68
+ wait(
69
+ identifier: access_token,
70
+ message: <<~MESSAGE
71
+ ### #{next_question_prompt_title}
72
+
73
+ #{next_question_prompt}
74
+
75
+ `#{next_url}`
76
+
77
+ #{prompt_cont}
78
+
79
+ ### Request Identification
80
+
81
+ In order to identify requests for this session, Inferno will look for
82
+ an `Authorization` header with value:
83
+
84
+ ```
85
+ Bearer #{request_identification}
86
+ ```
87
+
88
+ #{cont_test_description if config.options[:accepts_multiple_requests]}
89
+ MESSAGE
90
+ )
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,62 @@
1
+ require_relative '../../urls'
2
+
3
+ module DaVinciDTRTestKit
4
+ class DTRAdaptiveQuestionnaireNextQuestionRequestValidationTest < Inferno::Test
5
+ include URLs
6
+
7
+ id :dtr_next_question_request_validation
8
+ title '$next-question request is valid'
9
+ description %(
10
+ Per the [OperationDefinition: Adaptive questionnaire next question](https://build.fhir.org/ig/HL7/sdc/OperationDefinition-Questionnaire-next-question.html#root)
11
+ section in the [Structured Data Capture IG](http://hl7.org/fhir/uv/sdc/ImplementationGuide/hl7.fhir.uv.sdc),
12
+ the request body for the `$next-question` operation should be a FHIR Parameters resource containing a
13
+ single parameter with:
14
+ - name: `questionnaire-response`
15
+ - resource: A `QuestionnaireResponse` resource
16
+
17
+ As outlined in the [FHIR Operation Request](https://hl7.org/fhir/r4/operations.html#request) section of the
18
+ FHIR specification, if an operation has exactly one input parameter of type Resource, it can also be invoked via
19
+ a POST request using that resource as the body (with no additional URL parameters).
20
+
21
+ This test validates the structure of the `$next-question` request body. It confirms that the body is either a
22
+ Parameters resource or a QuestionnaireResponse resource.
23
+
24
+ If it is a Parameters resource, it must contain one parameter named `questionnaire-response`
25
+ with a `resource` attribute set to a FHIR QuestionnaireResponse instance, as specified above.
26
+
27
+ The QuestionnaireResponse resource's structure and conformance will be validated
28
+ in the following test ('Adaptive QuestionnaireResponse is valid').
29
+ )
30
+
31
+ def assert_valid_resource_type(resource)
32
+ type = resource.resourceType
33
+ valid = ['Parameters', 'QuestionnaireResponse'].include?(type)
34
+ assert valid, "Request body not valid. Expected Parameters or QuestionnaireResponse, got #{type}"
35
+ end
36
+
37
+ def next_request_tag
38
+ config.options[:next_tag]
39
+ end
40
+
41
+ run do
42
+ load_tagged_requests next_request_tag
43
+ skip_if request.blank?, 'A $next-question request must be made prior to running this test'
44
+
45
+ assert request.url == next_url, "Request made to wrong URL: #{request.url}. Should instead be to #{next_url}"
46
+ assert_valid_json(request.request_body)
47
+ input_params = FHIR.from_contents(request.request_body)
48
+ assert input_params.present?, 'Request does not contain a recognized FHIR object'
49
+ assert_valid_resource_type(input_params)
50
+
51
+ if input_params.is_a?(FHIR::Parameters)
52
+ questionnaire_response_params = input_params.parameter.select { |param| param.name == 'questionnaire-response' }
53
+ qr_params_count = questionnaire_response_params.length
54
+ assert qr_params_count == 1,
55
+ "Input parameter must contain one `parameter:questionnaire-response` slice. Found #{qr_params_count}"
56
+
57
+ questionnaire_response = questionnaire_response_params.first.resource
58
+ assert_resource_type(:questionnaire_response, resource: questionnaire_response)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'dtr_adaptive_questionnaire_next_question_request_test'
2
+ require_relative 'dtr_adaptive_questionnaire_next_question_request_validation_test'
3
+ require_relative 'dtr_adaptive_questionnaire_response_validation_test'
4
+
5
+ module DaVinciDTRTestKit
6
+ class DTRAdaptiveQuestionnaireNextQuestionRetrievalGroup < Inferno::TestGroup
7
+ id :dtr_adaptive_questionnaire_next_question_retrieval
8
+ title 'Next Question Request and Validation'
9
+ description %(
10
+ Inferno will wait for the client system to request the next question (or set of questions) using the
11
+ $next-question operation and will return an updated QuestionnaireResponse with a contained Questionnaire
12
+ that includes the next question (or set of questions) for the tester to complete.
13
+ Inferno will then validate the conformance of the request.
14
+ )
15
+
16
+ # Test 1: wait for the $next-question request
17
+ test from: :dtr_adaptive_questionnaire_next_question_request
18
+ # Test 2: validate the $next-question request
19
+ test from: :dtr_next_question_request_validation
20
+ # Test 3: validate the QuestionnaireResponse in the input parameter
21
+ test from: :dtr_adaptive_questionnaire_response_validation
22
+ end
23
+ end
@@ -0,0 +1,66 @@
1
+ require_relative '../../urls'
2
+ require_relative '../../dtr_questionnaire_response_validation'
3
+
4
+ module DaVinciDTRTestKit
5
+ class DTRAdaptiveQuestionnaireResponseValidationTest < Inferno::Test
6
+ include URLs
7
+ include DTRQuestionnaireResponseValidation
8
+
9
+ id :dtr_adaptive_questionnaire_response_validation
10
+ title 'Adaptive QuestionnaireResponse is valid'
11
+ description %(
12
+ This test validates the conformance of the Adative QuestionnaireResponse to the
13
+ [SDCQuestionnaireResponseAdapt](http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse-adapt)
14
+ structure. It verifies the presence of mandatory elements and that elements
15
+ with required bindings contain appropriate values.
16
+
17
+ It also ensures that all required questions are answered, and that the `origin.source`
18
+ extension is correct for each answer:
19
+ - `PBD.1` (Last Name) and `LOC.1` (Location): `auto`
20
+ - `PBD.2` (First Name): `override`
21
+ - `3` (all nested dinner questions): `manual`
22
+
23
+ Note: For the initial next-question request, only the conformance to the profile is checked
24
+ since neither the QuestionnaireResponse nor the contained Questionnaire will have any items,
25
+ as no questions are yet known.
26
+ )
27
+
28
+ def profile_url
29
+ 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse-adapt'
30
+ end
31
+
32
+ def next_request_tag
33
+ config.options[:next_tag]
34
+ end
35
+
36
+ run do
37
+ load_tagged_requests next_request_tag
38
+ skip_if request.blank?, 'A $next-question request must be made prior to running this test'
39
+
40
+ assert request.url == next_url, "Request made to wrong URL: #{request.url}. Should instead be to #{next_url}"
41
+ assert_valid_json(request.request_body)
42
+ input_params = FHIR.from_contents(request.request_body)
43
+ skip_if input_params.blank?, 'Request does not contain a recognized FHIR object'
44
+
45
+ questionnaire_response = nil
46
+ if input_params.is_a?(FHIR::QuestionnaireResponse)
47
+ questionnaire_response = input_params
48
+ elsif input_params.is_a?(FHIR::Parameters)
49
+ questionnaire_response = input_params.parameter&.find do |param|
50
+ param.name == 'questionnaire-response'
51
+ end&.resource
52
+ end
53
+
54
+ skip_if questionnaire_response.nil?, 'QuestionnaireResponse resource not provided.'
55
+ verify_basic_conformance(questionnaire_response.to_json, profile_url)
56
+
57
+ questionnaire = questionnaire_response.contained.find { |res| res.resourceType == 'Questionnaire' }
58
+ check_origin_sources(questionnaire.item, questionnaire_response.item, expected_overrides: ['PBD.2'])
59
+
60
+ required_link_ids = extract_required_link_ids(questionnaire.item)
61
+ check_answer_presence(questionnaire_response.item, required_link_ids)
62
+
63
+ assert(messages.none? { |m| m[:type] == 'error' }, 'QuestionnaireResponse is not correct, see error message(s)')
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,76 @@
1
+ require_relative '../../tags'
2
+ require_relative 'dtr_full_ehr_adaptive_questionnaire_initial_retrieval_group'
3
+ require_relative '../full_ehr/dtr_full_ehr_prepopulation_attestation_test'
4
+ require_relative '../full_ehr/dtr_full_ehr_prepopulation_override_attestation_test'
5
+ require_relative 'dtr_adaptive_questionnaire_followup_questions_group'
6
+ require_relative 'dtr_adaptive_questionnaire_completion_group'
7
+
8
+ module DaVinciDTRTestKit
9
+ class DTRFullEHRAdaptiveDinnerQuestionnaireWorkflowGroup < Inferno::TestGroup
10
+ id :dtr_full_ehr_adaptive_dinner_questionnaire_workflow
11
+ title 'Adaptive Questionnaire Workflow'
12
+ description %(
13
+ This test validates that a DTR Full EHR client can perform a full DTR Adaptive Questionnaire workflow
14
+ using a mocked questionnaire requesting what a patient wants for dinner. The client system must
15
+ demonstrate their ability to:
16
+
17
+ 1. Fetch the adaptive questionnaire package
18
+ ([DinnerOrderAdaptive](https://github.com/inferno-framework/davinci-dtr-test-kit/blob/main/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/questionnaire_dinner_order_adaptive.json))
19
+ 2. Fetch the first set of questions and render and pre-populate them appropriately, including:
20
+ - pre-populate data as directed by the questionnaire
21
+ - display questions only when they are enabled
22
+ 3. Answer the initial questions and request additional questions
23
+ 4. Complete the questionnaire and provide the completed QuestionnaireResponse
24
+ with appropriate indicators for pre-populated and manually-entered data.
25
+ )
26
+
27
+ group do
28
+ id :dtr_full_ehr_adaptive_questionnaire_retrieval
29
+ title 'Retrieving the Adaptive Questionnaire'
30
+ description %(
31
+ After DTR launch, Inferno will wait for the client system to request a questionnaire using the
32
+ $questionnaire-package operation and follow up with an initial $next-question request to retrieve
33
+ the first set of questions.
34
+
35
+ The initial set of questions will be returned for the tester to complete and attest to pre-population
36
+ and questionnaire rendering.
37
+
38
+ Inferno will also validate the conformance of the requests.
39
+ )
40
+ run_as_group
41
+
42
+ group from: :dtr_full_ehr_adaptive_questionnaire_initial_retrieval
43
+ group do
44
+ id :dtr_full_ehr_initial_questionnaire_rendering
45
+ title 'Filling Out the Questionnaire'
46
+ description %(
47
+ The tester will interact with the questionnaire within their client system
48
+ such that pre-population steps are taken, the qustionnaire is rendered, and
49
+ they are able to fill it out. The tester will attest that questionnaire pre-population
50
+ and rendering directives were followed.
51
+ )
52
+
53
+ # Test 1: attest to the pre-population of the name fields
54
+ test from: :dtr_full_ehr_prepopulation_attestation
55
+ # Test 2: attest to the pre-population and edit of the first name field
56
+ test from: :dtr_full_ehr_prepopulation_override_attestation
57
+ end
58
+ end
59
+
60
+ group from: :dtr_adaptive_questionnaire_followup_questions,
61
+ config: {
62
+ options: {
63
+ accepts_multiple_requests: true,
64
+ next_tag: "followup_#{CLIENT_NEXT_TAG}"
65
+ }
66
+ }
67
+
68
+ group from: :dtr_adaptive_questionnaire_completion,
69
+ config: {
70
+ options: {
71
+ accepts_multiple_requests: true,
72
+ next_tag: "completion_#{CLIENT_NEXT_TAG}"
73
+ }
74
+ }
75
+ end
76
+ end
@@ -0,0 +1,27 @@
1
+ require_relative '../../tags'
2
+ require_relative '../full_ehr/dtr_full_ehr_launch_attestation_test'
3
+ require_relative 'dtr_full_ehr_adaptive_questionnaire_request_test'
4
+ require_relative '../shared/dtr_questionnaire_package_request_validation_test'
5
+ require_relative 'dtr_adaptive_questionnaire_next_question_request_validation_test'
6
+ require_relative 'dtr_adaptive_questionnaire_response_validation_test'
7
+
8
+ module DaVinciDTRTestKit
9
+ class DTRFullEHRAdaptiveQuestionnaireInitialRetrievalGroup < Inferno::TestGroup
10
+ id :dtr_full_ehr_adaptive_questionnaire_initial_retrieval
11
+ title 'Adaptive Questionnaire Package and Initial Questions Retrieval'
12
+
13
+ config(options: { next_tag: "initial_#{CLIENT_NEXT_TAG}" })
14
+ run_as_group
15
+
16
+ # Test 0: attest to launch
17
+ test from: :dtr_full_ehr_launch_attestation
18
+ # Test 1: wait for the $questionnaire-package request and initial $next-question request
19
+ test from: :dtr_full_ehr_adaptive_questionnaire_request
20
+ # Test 2: validate the $questionnaire-package request body
21
+ test from: :dtr_questionnaire_package_request_validation
22
+ # Test 3: validate the $next-question request body
23
+ test from: :dtr_next_question_request_validation
24
+ # Test 4: validate the QuestionnaireResponse in the input parameter
25
+ test from: :dtr_adaptive_questionnaire_response_validation
26
+ end
27
+ end
@@ -0,0 +1,63 @@
1
+ require_relative '../../urls'
2
+
3
+ module DaVinciDTRTestKit
4
+ class DTRFullEHRAdaptiveQuestionnaireRequestTest < Inferno::Test
5
+ include URLs
6
+
7
+ id :dtr_full_ehr_adaptive_questionnaire_request
8
+ title 'Invoke the Questionnaire Package and Initial Next Question Operation'
9
+ description %(
10
+ This test waits for two sequential client requests:
11
+
12
+ 1. **Questionnaire Package Request**: The client should first invoke the `$questionnaire-package` operation
13
+ to retrieve the adaptive questionnaire package. Inferno will respond to this request with an empty adaptive
14
+ questionnaire.
15
+
16
+ 2. **Initial Next Question Request**: After receiving the package, the client should invoke the
17
+ `$next-question` operation. Inferno will respond by providing the first set of questions.
18
+ )
19
+
20
+ config options: { accepts_multiple_requests: true }
21
+ input :access_token
22
+
23
+ run do
24
+ wait(
25
+ identifier: access_token,
26
+ message: %(
27
+ ### Adaptive Questionnaire Retrieval
28
+
29
+ 1. **Questionnaire Package Request**:
30
+ - Invoke the `$questionnaire-package` operation by sending a POST request to the following
31
+ endpoint to retrieve the adaptive questionnaire package:
32
+
33
+ `#{questionnaire_package_url}`.
34
+
35
+ - Inferno will respond with an empty adaptive questionnaire.
36
+
37
+ 2. **Initial Next Question Request**:
38
+ - After receiving the questionnaire package, invoke the `$next-question` operation by sending
39
+ a POST request to the following endpoint to retrieve the first set of questions:
40
+
41
+ `#{next_url}`.
42
+
43
+ - Inferno will respond with the initial set of questions.
44
+
45
+ Inferno will wait for both of these requests to be made.
46
+
47
+ ### Request Identification
48
+
49
+ In order to identify requests for this session, Inferno will look for
50
+ an `Authorization` header with value:
51
+
52
+ ```
53
+ Bearer #{access_token}
54
+ ```
55
+
56
+ ### Continuing the Tests
57
+
58
+ When both requests have been made, [Click here](#{resume_pass_url}?token=#{access_token}) to continue.
59
+ )
60
+ )
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,24 @@
1
+ require_relative '../../tags'
2
+ require_relative 'dtr_smart_app_adaptive_questionnaire_request_test'
3
+ require_relative '../shared/dtr_questionnaire_package_request_validation_test'
4
+ require_relative 'dtr_adaptive_questionnaire_next_question_request_validation_test'
5
+ require_relative 'dtr_adaptive_questionnaire_response_validation_test'
6
+
7
+ module DaVinciDTRTestKit
8
+ class DTRSmartAppAdaptiveQuestionnaireInitialRetrievalGroup < Inferno::TestGroup
9
+ id :dtr_smart_app_adaptive_questionnaire_initial_retrieval
10
+ title 'Adaptive Questionnaire Package and Initial Questions Retrieval'
11
+
12
+ config(options: { next_tag: "initial_#{CLIENT_NEXT_TAG}" })
13
+ run_as_group
14
+
15
+ # Test 1: wait for the $questionnaire-package request and initial $next-question request
16
+ test from: :dtr_smart_app_adaptive_questionnaire_request
17
+ # Test 2: validate the $questionnaire-package request body
18
+ test from: :dtr_questionnaire_package_request_validation
19
+ # Test 3: validate the $next-question request body
20
+ test from: :dtr_next_question_request_validation
21
+ # Test 4: validate the QuestionnaireResponse in the input parameter
22
+ test from: :dtr_adaptive_questionnaire_response_validation
23
+ end
24
+ end
@@ -0,0 +1,148 @@
1
+ require_relative '../../urls'
2
+
3
+ module DaVinciDTRTestKit
4
+ class DTRSmartAppAdaptiveQuestionnaireRequestTest < Inferno::Test
5
+ include URLs
6
+
7
+ id :dtr_smart_app_adaptive_questionnaire_request
8
+ title 'Invoke the Questionnaire Package and Initial Next Question Operation'
9
+ description %(
10
+ This test waits for two sequential client requests:
11
+
12
+ 1. **Questionnaire Package Request**: The client should first invoke the `$questionnaire-package` operation
13
+ to retrieve the adaptive questionnaire package. Inferno will respond to this request with an empty adaptive
14
+ questionnaire.
15
+
16
+ 2. **Initial Next Question Request**: After receiving the package, the client should invoke the
17
+ `$next-question` operation. Inferno will respond by providing the first set of questions.
18
+ )
19
+
20
+ config options: { accepts_multiple_requests: true }
21
+ input :smart_app_launch,
22
+ type: 'radio',
23
+ title: 'SMART App Launch',
24
+ description: 'How will the DTR SMART App launch?',
25
+ options: { list_options: [{ label: 'EHR Launch from Inferno', value: 'ehr' },
26
+ { label: 'Standalone Launch', value: 'standalone' }] }
27
+ input :client_id
28
+ input :launch_uri,
29
+ optional: true,
30
+ description: 'Required if "Launch from Inferno" is selected'
31
+ input :adaptive_smart_patient_id,
32
+ optional: true,
33
+ title: 'SMART App Launch Patient ID (Dinner Adaptive)',
34
+ type: 'text',
35
+ description: %(
36
+ Patient instance ID to be provided by Inferno as the patient as a part of the SMART App Launch.
37
+ ),
38
+ default: 'pat015'
39
+ input :adaptive_smart_fhir_context,
40
+ optional: true,
41
+ title: 'SMART App Launch fhirContext (Dinner Adaptive)',
42
+ type: 'textarea',
43
+ description: %(
44
+ References to be provided by Inferno as the fhirContext as a part of the SMART App
45
+ Launch. These references help determine the behavior of the app. Referenced instances
46
+ may be provided in the "EHR-available resources" input.
47
+ ),
48
+ default: JSON.pretty_generate([{ reference: 'Coverage/cov015' },
49
+ { reference: 'DeviceRequest/devreqe0470' }])
50
+ input :adaptive_ehr_bundle,
51
+ optional: true,
52
+ title: 'EHR-available resources (Dinner Adaptive)',
53
+ type: 'textarea',
54
+ description: %(
55
+ Resources available from the EHR needed to drive the dinner adaptive workflow.
56
+ Formatted as a FHIR bundle that contains resources, each with an ID property populated. Each
57
+ instance present will be available for retrieval from Inferno at the endpoint:
58
+ <fhir-base>/<resource type>/<instance id>
59
+ )
60
+
61
+ def example_client_jwt_payload_part
62
+ Base64.strict_encode64({ inferno_client_id: client_id }.to_json).delete('=')
63
+ end
64
+
65
+ run do
66
+ # validate relevant inputs and provide warnings if they are bad
67
+ warning do
68
+ if adaptive_smart_fhir_context
69
+ assert_valid_json(adaptive_smart_fhir_context,
70
+ 'The **SMART App Launch fhirContext** input is not valid JSON, so it will not be included in
71
+ the access token response.')
72
+ end
73
+ end
74
+
75
+ warning do
76
+ if adaptive_ehr_bundle
77
+ assert_valid_json(adaptive_ehr_bundle,
78
+ 'The **EHR-available resources** input is not valid JSON, so no tester-specified instances
79
+ will be available to access from Inferno.')
80
+ assert(FHIR.from_contents(adaptive_ehr_bundle).is_a?(FHIR::Bundle),
81
+ 'The **EHR-available resources** input does not contain a FHIR Bundle, so no tester-specified instances
82
+ will be available to access from Inferno.')
83
+ end
84
+ end
85
+
86
+ launch_prompt = if smart_app_launch == 'ehr'
87
+ %(Launch the DTR SMART App from Inferno by right clicking
88
+ [this link](#{launch_uri}?iss=#{fhir_base_url}&launch=#{launch_uri})
89
+ and selecting "Open in new window" or "Open in new tab".)
90
+ else
91
+ %(Launch the SMART App from your EHR.)
92
+ end
93
+ inferno_prompt_cont = %(As the DTR app steps through the launch steps, Inferno will wait and respond to the app's
94
+ requests for SMART configuration, authorization and access token.)
95
+
96
+ wait(
97
+ identifier: client_id,
98
+ message: %(
99
+ ### SMART App Launch
100
+
101
+ #{launch_prompt}
102
+
103
+ #{inferno_prompt_cont if smart_app_launch == 'ehr'}
104
+
105
+ ### Adaptive Questionnaire Retrieval
106
+
107
+ 1. **Questionnaire Package Request**:
108
+ - Inferno will expect the SMART App to invoke the DTR Questionnaire Package operation by sending a POST
109
+ request to
110
+
111
+ `#{questionnaire_package_url}`
112
+
113
+ - Inferno will respond with an empty adaptive questionnaire.
114
+
115
+ 2. **Initial Next Question Request**:
116
+ - After receiving the questionnaire package, invoke the `$next-question` operation by sending
117
+ a POST request to the following endpoint to retrieve the first set of questions:
118
+
119
+ `#{next_url}`.
120
+
121
+ - Inferno will respond with the initial set of questions.
122
+
123
+ ### Pre-population
124
+
125
+ Inferno will then wait for the client to complete Questionnaire pre-population. The client should make FHIR
126
+ GET requests using service base path:
127
+
128
+ `#{fhir_base_url}`
129
+
130
+ ### Request Identification
131
+
132
+ In order to identify requests for this session, Inferno will look for
133
+ an `Authorization` header with value:
134
+
135
+ ```
136
+ Bearer eyJhbGciOiJub25lIn0.#{example_client_jwt_payload_part}.
137
+ ```
138
+
139
+ ### Continuing the Tests
140
+
141
+ When the DTR application has finished loading the Questionnaire,
142
+ including any clinical data requests to support pre-population,
143
+ [Click here](#{resume_pass_url}?client_id=#{client_id}) to continue.
144
+ )
145
+ )
146
+ end
147
+ end
148
+ end