davinci_dtr_test_kit 0.16.0 → 0.16.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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/config/presets/full_ehr_postman_dinner_order_example.json.erb +41 -0
  3. data/config/presets/full_ehr_postman_respiratory_device_example.json +1 -1
  4. data/config/presets/smart_app_postman_dinner_order_example.json +8 -1
  5. data/config/presets/smart_app_postman_respiratory_device_example.json +1 -1
  6. data/lib/davinci_dtr_test_kit/certs/InfernoCA.key +52 -0
  7. data/lib/davinci_dtr_test_kit/certs/InfernoCA.pem +35 -0
  8. data/lib/davinci_dtr_test_kit/certs/TestKit.pem +32 -0
  9. data/lib/davinci_dtr_test_kit/certs/TestKitPrivateKey.key +28 -0
  10. data/lib/davinci_dtr_test_kit/client_groups/adaptive_questionnaire/custom/dtr_custom_next_question_response_validation_test.rb +95 -0
  11. data/lib/davinci_dtr_test_kit/client_groups/adaptive_questionnaire/custom/dtr_full_ehr_custom_adaptive_request_test.rb +87 -0
  12. data/lib/davinci_dtr_test_kit/client_groups/adaptive_questionnaire/custom/dtr_full_ehr_custom_adaptive_workflow_group.rb +136 -0
  13. data/lib/davinci_dtr_test_kit/client_groups/adaptive_questionnaire/custom/dtr_smart_app_custom_adaptive_request_test.rb +171 -0
  14. data/lib/davinci_dtr_test_kit/client_groups/adaptive_questionnaire/custom/dtr_smart_app_custom_adaptive_workflow_group.rb +146 -0
  15. data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_adaptive_next_question_retrieval_group.rb +3 -3
  16. data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_full_ehr_adaptive_dinner_workflow_group.rb +21 -11
  17. data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_full_ehr_adaptive_initial_retrieval_group.rb +6 -6
  18. data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_smart_app_adaptive_dinner_workflow_group.rb +5 -5
  19. data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_smart_app_adaptive_initial_retrieval_group.rb +5 -5
  20. data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire}/dtr_adaptive_next_question_request_test.rb +9 -24
  21. data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire}/dtr_adaptive_next_question_request_validation_test.rb +36 -17
  22. data/lib/davinci_dtr_test_kit/client_groups/adaptive_questionnaire/dtr_adaptive_response_validation_test.rb +130 -0
  23. data/lib/davinci_dtr_test_kit/client_groups/auth/dtr_client_payer_auth_smart_group.rb +29 -0
  24. data/lib/davinci_dtr_test_kit/client_groups/auth/dtr_client_payer_auth_udap_group.rb +29 -0
  25. data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_full_ehr_custom_static_workflow_group.rb +15 -14
  26. data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_smart_app_custom_static_workflow_group.rb +5 -5
  27. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_full_ehr_static_dinner_workflow_group.rb +14 -10
  28. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_smart_app_static_dinner_workflow_group.rb +1 -1
  29. data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → full_ehr}/dtr_full_ehr_adaptive_request_test.rb +11 -14
  30. data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_questionnaire_package_request_test.rb +9 -17
  31. data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_questionnaire_response_correctness_test.rb +10 -1
  32. data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_store_attestation_test.rb +3 -3
  33. data/lib/davinci_dtr_test_kit/client_groups/light_ehr/fhir_context_references_test.rb +4 -5
  34. data/lib/davinci_dtr_test_kit/client_groups/must_support/dtr_full_ehr_ms_questionnaire_package_request_test.rb +75 -0
  35. data/lib/davinci_dtr_test_kit/client_groups/must_support/dtr_full_ehr_questionnaire_must_support_group.rb +85 -0
  36. data/lib/davinci_dtr_test_kit/client_groups/must_support/dtr_must_support_attestation_test.rb +39 -0
  37. data/lib/davinci_dtr_test_kit/client_groups/must_support/dtr_questionnaire_must_support_test.rb +42 -0
  38. data/lib/davinci_dtr_test_kit/client_groups/must_support/dtr_smart_app_ms_questionnaire_package_request_test.rb +148 -0
  39. data/lib/davinci_dtr_test_kit/client_groups/must_support/dtr_smart_app_questionnaire_must_support_group.rb +85 -0
  40. data/lib/davinci_dtr_test_kit/client_groups/must_support/questionnaire_must_support_elements.rb +55 -0
  41. data/lib/davinci_dtr_test_kit/client_groups/payer_registration/configuration_display_smart_test.rb +35 -0
  42. data/lib/davinci_dtr_test_kit/client_groups/payer_registration/configuration_display_udap_test.rb +35 -0
  43. data/lib/davinci_dtr_test_kit/client_groups/payer_registration/dtr_client_registration_group.rb +48 -0
  44. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_custom_questionnaire_expressions_test.rb +36 -0
  45. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_custom_questionnaire_extensions_test.rb +32 -0
  46. data/lib/davinci_dtr_test_kit/client_groups/{custom_static → shared}/dtr_custom_questionnaire_libraries_test.rb +7 -2
  47. data/lib/davinci_dtr_test_kit/client_groups/{custom_static → shared}/dtr_custom_questionnaire_package_validation_test.rb +6 -2
  48. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_package_request_validation_test.rb +6 -2
  49. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_prepopulation_test.rb +7 -1
  50. data/lib/davinci_dtr_test_kit/client_groups/smart_app/dtr_smart_app_questionnaire_response_correctness_test.rb +4 -3
  51. data/lib/davinci_dtr_test_kit/descriptions.rb +8 -0
  52. data/lib/davinci_dtr_test_kit/docs/dtr_full_ehr_suite_description_v201.md +145 -78
  53. data/lib/davinci_dtr_test_kit/docs/dtr_smart_app_suite_description_v201.md +4 -3
  54. data/lib/davinci_dtr_test_kit/dtr_client_options.rb +13 -0
  55. data/lib/davinci_dtr_test_kit/dtr_full_ehr_suite.rb +47 -7
  56. data/lib/davinci_dtr_test_kit/dtr_questionnaire_response_validation.rb +33 -21
  57. data/lib/davinci_dtr_test_kit/dtr_smart_app_suite.rb +7 -4
  58. data/lib/davinci_dtr_test_kit/endpoints/mock_ehr.rb +1 -1
  59. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_next_question_endpoint.rb +20 -1
  60. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_questionnaire_package_endpoint.rb +21 -1
  61. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/next_question_endpoint.rb +29 -4
  62. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/questionnaire_package_endpoint.rb +1 -1
  63. data/lib/davinci_dtr_test_kit/endpoints/mock_udap_smart_server/token_endpoint.rb +36 -0
  64. data/lib/davinci_dtr_test_kit/requirements/davinci-dtr-test-kit_out_of_scope_requirements.csv +6 -5
  65. data/lib/davinci_dtr_test_kit/requirements/davinci-dtr-test-kit_requirements.csv +10 -9
  66. data/lib/davinci_dtr_test_kit/requirements/generated/davinci-dtr-test-kit_requirements_coverage.csv +21 -21
  67. data/lib/davinci_dtr_test_kit/urls.rb +21 -4
  68. data/lib/davinci_dtr_test_kit/version.rb +2 -2
  69. metadata +59 -21
  70. data/config/presets/full_ehr_postman_dinner_order_example_postman.json +0 -19
  71. data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_custom_questionnaire_expressions_test.rb +0 -22
  72. data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_custom_questionnaire_extensions_test.rb +0 -19
  73. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_response_validation_test.rb +0 -68
  74. /data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_adaptive_completion_group.rb +0 -0
  75. /data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_adaptive_followup_questions_group.rb +0 -0
  76. /data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → smart_app}/dtr_smart_app_adaptive_request_test.rb +0 -0
@@ -0,0 +1,35 @@
1
+ require_relative '../../urls'
2
+
3
+ module DaVinciDTRTestKit
4
+ class DTRPayerRegistrationConfigurationSMARTDisplay < Inferno::Test
5
+ include URLs
6
+
7
+ id :dtr_client_payer_reg_smart_config_display
8
+ title 'Confirm client configuration'
9
+ description %(
10
+ This test provides all the information needed for testers to configure
11
+ the client under test to communicate with Inferno's simulated DTR server
12
+ including SMART endpoints to obtain access tokens.
13
+ )
14
+
15
+ input :client_id
16
+
17
+ run do
18
+ wait(
19
+ identifier: client_id,
20
+ message: %(
21
+ **Inferno Simulated Server Details**:
22
+
23
+ FHIR Base URL: `#{fhir_base_url}`
24
+
25
+ Authentication Details:
26
+ - SMART Client Id: `#{client_id}`
27
+ - Token endpoint: `#{token_url}`
28
+
29
+ [Click here](#{resume_pass_url}?token=#{client_id}) once you have configured
30
+ the client to connect to Inferno at the above endpoints.
31
+ )
32
+ )
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,35 @@
1
+ require_relative '../../urls'
2
+
3
+ module DaVinciDTRTestKit
4
+ class DTRPayerRegistrationConfigurationUDAPDisplay < Inferno::Test
5
+ include URLs
6
+
7
+ id :dtr_client_payer_reg_udap_config_display
8
+ title 'Confirm client configuration'
9
+ description %(
10
+ This test provides all the information needed for testers to configure
11
+ the client under test to communicate with Inferno's simulated PAS server
12
+ including UDAP endpoints to obtain access tokens.
13
+ )
14
+
15
+ input :client_id
16
+
17
+ run do
18
+ wait(
19
+ identifier: client_id,
20
+ message: %(
21
+ **Inferno Simulated Server Details**:
22
+
23
+ FHIR Base URL: `#{fhir_base_url}`
24
+
25
+ Authentication Details:
26
+ - UDAP Client Id: `#{client_id}`
27
+ - Token endpoint: `#{token_url}`
28
+
29
+ [Click here](#{resume_pass_url}?token=#{client_id}) once you have configured
30
+ the client to connect to Inferno at the above endpoints.
31
+ )
32
+ )
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,48 @@
1
+ require 'udap_security_test_kit'
2
+ require 'smart_app_launch_test_kit'
3
+ require_relative '../../dtr_client_options'
4
+ require_relative 'configuration_display_smart_test'
5
+ require_relative 'configuration_display_udap_test'
6
+
7
+ module DaVinciDTRTestKit
8
+ class DTRPayerRegistrationGroup < Inferno::TestGroup
9
+ id :dtr_client_payer_registration
10
+ title 'Client Registration'
11
+ description %(
12
+ Register the client under test with Inferno's simulated DTR Server,
13
+ including configuration of the system under test to hit the correct endpoints and
14
+ enable authentication and authorization of DTR requests.
15
+ )
16
+ run_as_group
17
+
18
+ # smart registration tests
19
+ test from: :smart_client_registration_bsca_verification,
20
+ required_suite_options: {
21
+ client_type: DTRClientOptions::SMART_BACKEND_SERVICES_CONFIDENTIAL_ASYMMETRIC
22
+ }
23
+ test from: :dtr_client_payer_reg_smart_config_display,
24
+ required_suite_options: {
25
+ client_type: DTRClientOptions::SMART_BACKEND_SERVICES_CONFIDENTIAL_ASYMMETRIC
26
+ }
27
+
28
+ # udap registration tests
29
+ test from: :udap_client_registration_interaction,
30
+ required_suite_options: {
31
+ client_type: DTRClientOptions::UDAP_CLIENT_CREDENTIALS
32
+ },
33
+ config: {
34
+ options: { endpoint_suite_id: :dtr_full_ehr }
35
+ }
36
+ test from: :udap_client_registration_cc_verification,
37
+ required_suite_options: {
38
+ client_type: DTRClientOptions::UDAP_CLIENT_CREDENTIALS
39
+ },
40
+ config: {
41
+ options: { endpoint_suite_id: :dtr_full_ehr }
42
+ }
43
+ test from: :dtr_client_payer_reg_udap_config_display,
44
+ required_suite_options: {
45
+ client_type: DTRClientOptions::UDAP_CLIENT_CREDENTIALS
46
+ }
47
+ end
48
+ end
@@ -0,0 +1,36 @@
1
+ require_relative '../../cql_test'
2
+ module DaVinciDTRTestKit
3
+ class DTRCustomQuestionnaireExpressionsTest < Inferno::Test
4
+ include DaVinciDTRTestKit::CQLTest
5
+
6
+ id :dtr_custom_questionnaire_expressions
7
+ title %(
8
+ [USER INPUT VERIFICATION] Custom questionnaire(s) contain items with expressions
9
+ necessary for pre-population
10
+ )
11
+ description %(
12
+ Inferno checks that the custom response has appropriate expressions and that expressions are
13
+ written in cql.
14
+ )
15
+
16
+ def form_type
17
+ config.options[:form_type] || 'static'
18
+ end
19
+
20
+ run do
21
+ questionnaires = nil
22
+ if form_type == 'static'
23
+ skip_if scratch[:"#{form_type}_questionnaire_bundles"].blank?,
24
+ 'No questionnaire bundle found in the custom response'
25
+
26
+ questionnaires = extract_questionnaires_from_bundles(scratch[:"#{form_type}_questionnaire_bundles"])
27
+ else
28
+ assert_valid_json custom_next_question_questionnaires, 'Custom $next-question questionnairee not valid JSON'
29
+ custom_questionnaires = [JSON.parse(custom_next_question_questionnaires)].flatten.compact
30
+ questionnaires = custom_questionnaires.map { |q| FHIR.from_contents(q.to_json) }.compact
31
+ end
32
+
33
+ verify_questionnaire_items(questionnaires, final_cql_test: true)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,32 @@
1
+ require_relative '../../cql_test'
2
+ module DaVinciDTRTestKit
3
+ class DTRCustomQuestionnaireExtensionsTest < Inferno::Test
4
+ include DaVinciDTRTestKit::CQLTest
5
+
6
+ id :dtr_custom_questionnaire_extensions
7
+ title '[USER INPUT VERIFICATION] Custom questionnaire(s) contain extensions necessary for pre-population'
8
+ description %(
9
+ Inferno checks that the custom response has appropriate extensions and references to libraries within
10
+ those extensions.
11
+ )
12
+
13
+ def form_type
14
+ config.options[:form_type] || 'static'
15
+ end
16
+
17
+ run do
18
+ questionnaires = nil
19
+ if form_type == 'static'
20
+ skip_if scratch[:"#{form_type}_questionnaire_bundles"].blank?,
21
+ 'No questionnaire bundle found in the custom package response'
22
+ questionnaires = extract_questionnaires_from_bundles(scratch[:"#{form_type}_questionnaire_bundles"])
23
+ else
24
+ assert_valid_json custom_next_question_questionnaires, 'Custom $next-question questionnaires not valid JSON'
25
+ custom_questionnaires = [JSON.parse(custom_next_question_questionnaires)].flatten.compact
26
+ questionnaires = custom_questionnaires.map { |q| FHIR.from_contents(q.to_json) }.compact
27
+ end
28
+
29
+ verify_questionnaire_extensions(questionnaires)
30
+ end
31
+ end
32
+ end
@@ -13,9 +13,14 @@ module DaVinciDTRTestKit
13
13
  and that libraries contain cql and elm data.
14
14
  )
15
15
 
16
+ def form_type
17
+ config.options[:form_type] || 'static'
18
+ end
19
+
16
20
  run do
17
- skip_if scratch[:static_questionnaire_bundles].blank?, 'No questionnaire bundle found in the custom response'
18
- check_libraries(scratch[:static_questionnaire_bundles])
21
+ skip_if scratch[:"#{form_type}_questionnaire_bundles"].blank?,
22
+ 'No questionnaire bundle found in the custom response'
23
+ check_libraries(scratch[:"#{form_type}_questionnaire_bundles"])
19
24
  end
20
25
  end
21
26
  end
@@ -23,17 +23,21 @@ module DaVinciDTRTestKit
23
23
  input :custom_questionnaire_package_response,
24
24
  title: 'Custom Questionnaire Package Response JSON',
25
25
  description: %(
26
- A JSON PackageBundle may be provided here to replace Inferno's response to the
26
+ A JSON FHIR Bundle may be provided here to replace Inferno's response to the
27
27
  $questionnaire-package request.
28
28
  ),
29
29
  type: 'textarea'
30
30
 
31
+ def form_type
32
+ config.options[:form_type] || 'static'
33
+ end
34
+
31
35
  run do
32
36
  assert_valid_json custom_questionnaire_package_response, 'Custom questionnaire package response is not valid JSON'
33
37
 
34
38
  resource = FHIR.from_contents(custom_questionnaire_package_response)
35
39
 
36
- perform_questionnaire_package_validation(resource, 'static')
40
+ perform_questionnaire_package_validation(resource, form_type)
37
41
  end
38
42
  end
39
43
  end
@@ -19,12 +19,16 @@ module DaVinciDTRTestKit
19
19
  verifies_requirements 'hl7.fhir.us.davinci-dtr_2.0.1@168', 'hl7.fhir.us.davinci-dtr_2.0.1@293',
20
20
  'hl7.fhir.us.davinci-dtr_2.0.1@295'
21
21
 
22
+ def qp_tag
23
+ config.options[:questionnaire_package_tag] || QUESTIONNAIRE_PACKAGE_TAG
24
+ end
25
+
22
26
  run do
23
- load_tagged_requests QUESTIONNAIRE_PACKAGE_TAG
27
+ load_tagged_requests qp_tag
24
28
  skip_if request.blank?, 'A Questionnaire Package request must be made prior to running this test'
25
29
 
26
30
  assert request.url == questionnaire_package_url,
27
- "Request made to wrong URL: #{request.url}. Should instead be to #{questionnaire_package_url}"
31
+ "Request made to wrong URL: #{request.url}. Should instead be to #{questionnaire_package_url}."
28
32
 
29
33
  assert_valid_json(request.request_body)
30
34
  input_params = FHIR.from_contents(request.request_body)
@@ -31,9 +31,15 @@ module DaVinciDTRTestKit
31
31
  if config.options[:adaptive]
32
32
  questionnaire = questionnaire_response.contained.find { |res| res.resourceType == 'Questionnaire' }
33
33
  assert questionnaire, 'Adaptive QuestionnaireResponse must have a contained Questionnaire resource.'
34
- check_origin_sources(questionnaire.item, questionnaire_response.item, expected_overrides: ['PBD.2'])
34
+
35
+ check_missing_origin_sources(questionnaire_response) if config.options[:custom]
36
+
37
+ expected_overrides = config.options[:custom] ? [] : ['PBD.2']
38
+ check_origin_sources(questionnaire.item, questionnaire_response.item, expected_overrides:)
39
+
35
40
  required_link_ids = extract_required_link_ids(questionnaire.item)
36
41
  check_answer_presence(questionnaire_response.item, required_link_ids)
42
+
37
43
  assert(messages.none? { |m| m[:type] == 'error' }, 'QuestionnaireResponse is not correct, see error message(s)')
38
44
  else
39
45
  questionnaire = Fixtures.questionnaire_for_test(id)
@@ -18,10 +18,11 @@ module DaVinciDTRTestKit
18
18
  input :custom_questionnaire_package_response,
19
19
  title: 'Custom Questionnaire Package Response JSON',
20
20
  description: %(
21
- A JSON PackageBundle may be provided here to replace Inferno's response to the
22
- $questionnaire-package request.
21
+ The custom $questionnaire-package response used in the previous tests, if provided.
23
22
  ),
24
- type: 'textarea'
23
+ type: 'textarea',
24
+ optional: true,
25
+ locked: true
25
26
 
26
27
  run do
27
28
  validate_questionnaire_response_correctness(request.request_body, custom_questionnaire_package_response)
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DaVinciDTRTestKit
4
+ INPUT_CLIENT_ID_LOCKED =
5
+ 'If this session has been configured for standards-based authentication, this input ' \
6
+ 'contains the client\'s registered Client Id for use in obtaining access tokens. ' \
7
+ 'Run the **1** Client Registration group to configure standards-based auth.'
8
+ end
@@ -1,4 +1,4 @@
1
- The Da Vinci DTR Test Kit Full EHR Suite validates the conformance of SMART apps
1
+ The Da Vinci DTR Test Kit Full EHR Suite validates the conformance of Full EHRs
2
2
  to the STU 2 version of the HL7® FHIR®
3
3
  [Da Vinci Documentation Templates and Rules (DTR) Implementation Guide](https://hl7.org/fhir/us/davinci-dtr/STU2/).
4
4
 
@@ -12,39 +12,49 @@ requirements and may change the test validation logic.
12
12
 
13
13
  ## Test Methodology
14
14
 
15
- Inferno will simulate a DTR payer server that will response to
15
+ Inferno will simulate a DTR payer server that will respond to
16
16
  requests for questionnaires for the EHR under test to interact with.
17
17
  The EHR will be expected to initiate requests to Inferno to elicit responses. Over the
18
18
  course of these interactions, Inferno will seek to observe conformant handling of
19
- DTR workflows and requirements around the retrieval, completion, and storage of
20
- questionnaires.
21
-
22
- Tests within this suite are associated with specific questionnaires that the EHR will
23
- demonstrate completion of. In each case, the EHR under test will initiate a request to
19
+ DTR workflows and requirements around the retrieval and completion of questionnaires
20
+ and the storage of questionnaire responses.
21
+
22
+ The suite includes two types of tests each with a different source for the response(s)
23
+ that Inferno's simulated payer will return:
24
+ - **Tester-provided Responses**: The tester provides a conformant `$questionnaire-package` response,
25
+ and `$next-question` responses for adaptive questionnaires, that Inferno will echo
26
+ back to the system under test. This allows the tester to demonstrate the DTR
27
+ functionality of the system using questionnaires that they choose.
28
+ - **Inferno-provided Reponses**: This test suite includes several mocked questionnaires
29
+ that will be returned when specific tests are run.
30
+
31
+ Regardless of the type, the EHR under test will initiate a request to
24
32
  the payer server simulated by Inferno for a questionnaire using the
25
- `$questionnaire-package` operation. Inferno will always return the specific questionnaire
26
- for the test being executed regardless of the input provided by the EHR, though Inferno will
27
- check that the input is conformant. The EHR will then be asked to complete the questionnaire,
28
- including:
33
+ `$questionnaire-package` operation and Inferno will return the responses based on the type of test.
34
+ Inferno always returns that specific response associated with the test, whether based on a tester
35
+ input or the Inferno responses associated with that test. The request made by the EHR must be conformant,
36
+ but Inferno is not able to verify that its response is appropriate for the request.
37
+
38
+ The EHR will then be asked to complete the questionnaire, including:
29
39
 
30
40
  - Pre-populating answers based on directives in the questionnaire.
31
41
  - Rendering the questionnaire for users and allowing them to make additional updates.
32
- These tests can include specific directions on details to include in the completed
33
- questionnaire.
42
+ Tests for Inferno-provided responses include specific directions on details to include in the completed
43
+ questionnaire to allow for validation of the [information origin extension](https://hl7.org/fhir/us/davinci-dtr/STU2/StructureDefinition-information-origin.html).
34
44
  - For adaptive questionnaires only, getting additional questions using the `$next-question`
35
45
  operation until the questionnaire is complete.
36
46
  - Storing the completed questionnaire for future use as a FHIR QuestionnaireResponse.
37
47
 
38
- EHRs will be required to complete all questionnaires in the suite, which in aggregate
39
- contain all questionnaire features that apps must support. Currently, the suite includes
40
- one questionnaire:
41
-
42
- 1. Standard and adaptive styles of a fictitious "dinner" questionnaire created for these tests.
43
- They test basic item rendering, control flow, and pre-population.
48
+ EHRs are currently required to complete 5 questionnaires as a part of these tests, though
49
+ future iterations of this test kit may change this set:
50
+ - Tester-provided static and dynamic questionnaires, for workflow demonstration.
51
+ - Inferno-provided static and dynamic questionnaires, for demonstration of [information origin
52
+ extension](https://hl7.org/fhir/us/davinci-dtr/STU2/StructureDefinition-information-origin.html)
53
+ requirements.
54
+ - A feature-complete tester-provided static questionnaire, for demonstration of all
55
+ questionnaire features.
44
56
 
45
- Additional questionnaires covering further features will be added in the future.
46
-
47
- All requests sent by the app will be checked
57
+ All requests sent by the EHR will be checked
48
58
  for conformance to the DTR IG requirements individually and used in aggregate to determine
49
59
  whether required features and functionality are present. HL7® FHIR® resources are
50
60
  validated with the Java validator using `tx.fhir.org` as the terminology server.
@@ -53,35 +63,41 @@ validated with the Java validator using `tx.fhir.org` as the terminology server.
53
63
 
54
64
  ### Quick Start
55
65
 
56
- In order to run these tests, EHRs must be configured to interact with Inferno's simulated
57
- payer server endpoint. The endpoint will be `[URL prefix]/custom/dtr_full_ehr/fhir` where
58
- `[URL prefix]` can be inferred from the URL of the test session which will be of the form
59
- `[URL prefix]/dtr_full_ehr/[session id]`.
60
-
61
- In order for Inferno to associate requests sent to locations under these base URLs with this session,
62
- it needs to know the bearer token that the EHR will send on requests, for which
63
- there are two options.
64
-
65
- 1. If you want to choose your own bearer token, then
66
- 1. Select the "2. Basic Workflows" test from the list on the left (or other target test).
67
- 2. Click the '_Run All Tests_' button on the right.
68
- 3. In the "access_token" field, enter the bearer token that will be sent by the client
69
- under test (as part of the Authorization header - `Bearer <provided value>`).
70
- 4. Click the '_Submit_' button at the bottom of the dialog.
71
- 2. If you want to use a client_id to obtain an access token, then
72
- 1. Click the '_Run All Tests_' button on the right.
73
- 2. Provide the EHR's registered id "client_id" field of the input (NOTE, Inferno
74
- doesn't support the registration API, so this must be obtained from another
75
- system or configured manually).
76
- 3. Click the '_Submit_' button at the bottom of the dialog.
77
- 4. Make a token request that includes the specified client id to the
78
- `[URL prefix]/custom/dtr_full_ehr/mock_auth/token` endpoint to get
79
- an access token to use on the request of the requests.
80
-
81
- In either case, the tests will continue from that point. Further executions of tests under
82
- this session will also use the selected bearer token.
83
-
84
- Note: authentication options for these tests have not been finalized and are subject to change.
66
+ Inferno's simulated payer endpoints require authentication using the OAuth flows
67
+ conforming either to the
68
+ - SMART Backend Services flow, or
69
+ - UDAP Business-to-Business Client Credentials flow
70
+
71
+ When creating a test session, select the Client Security Type corresponding to an
72
+ authentication approach supported by the EHR. Then start by running the Client Registration
73
+ group which will guide you through the registration process.
74
+ See the *Auth Configuration Details* section below for details.
75
+
76
+ Once registration is complete, execute the Dinner Order Static Questionnaire Workflow tests
77
+ using the following steps:
78
+ 1. Select group **3.1.1** Retrieving the Static Questionnaire from the list on the left, click
79
+ "RUN TESTS" in the upper right, and click "SUBMIT" in the input dialog that appears.
80
+ 1. A "User Action Required" dialog will appear asking for DTR to be launched for a patient
81
+ meeting specific criteria. Once you have launched DTR from the EHR, click one of the
82
+ attestation links to continue the tests. NOTE: Inferno will not respond to `$questionnaire-package`
83
+ requests during this step.
84
+ 1. A new "User Action Required" dialog will appear directing you to make a `$questionnaire-package`
85
+ request. Take actions in the EHR to trigger this request. Before beginning to fill out the
86
+ questionnaire, click the link in the dialog to continue the tests.
87
+ 1. Select group **3.1.2** Filling Out the Static Questionnaire from the list on the left. A series
88
+ of "User Action Required" dialogs will appear asking you to confirm details of the rendered
89
+ questionnaire and actions taken while filling it out. Refer to and complete these attestations
90
+ as you fill out the questionnaire within the EHR.
91
+ 1. Complete the questionnaire, save the response in the EHR, and access the saved response in
92
+ its FHIR QuestionnaireResponse JSON form, which will be needed in the next step.
93
+ 1. Select group **3.1.3** Saving the QuestionnaireResponse from the list on the left and click
94
+ "RUN TESTS" in the upper right. An input dialog will appear asking for the
95
+ **Completed QuestionnaireResponse**. Put the FHIR QuestionnaireResponse JSON obtained
96
+ in the last step and click "SUBMIT".
97
+ 1. Attest that this QuestionnaireResponse was stored in the EHR to complete the tests.
98
+
99
+ Other workflows can be executed in a similar manner, but will include additional inputs and/or
100
+ different steps.
85
101
 
86
102
  ### Postman-based Demo
87
103
 
@@ -95,42 +111,65 @@ To run the tests using this approach:
95
111
  1. Install [postman](https://www.postman.com/downloads/).
96
112
  1. Import [this Postman collection](https://github.com/inferno-framework/davinci-dtr-test-kit/blob/main/config/DTR%20Full%20EHR%20Tests%20Postman%20Demo.postman_collection.json).
97
113
 
98
- #### Startup
99
- 1. Start a Da Vinci DTR Full EHR Test Suite Session.
114
+ #### Startup and Client Registration
115
+ 1. Start a Da Vinci DTR Full EHR Test suite session choosing SMART Backend Services for the Client Security Type.
116
+ 1. Select the "Dinner Order Questionnaire Example (Postman)" preset from the dropdown in the upper left.
117
+ 1. Select the Client Registration group from the list at the left, click "RUN TEST" in the upper right,
118
+ and click "SUBMIT" in the input dialog that appears. A "User Action Required" wait dialog will appear.
119
+ 1. In another tab, start a SMART App Launch STU2.2 suite session. Select the Backend Services group,
120
+ click "RUN TESTS", and provide the following inputs before clicking "SUBMIT":
121
+ - **FHIR Endpoint**: the "FHIR Base URL" displayed in the wait dialog in the DTR tests.
122
+ - **Scopes**: `system/*.rs`
123
+ - **Client ID**: the "SMART Client Id" displayed in the wait dialog in the DTR tests.
124
+ 1. Find the access token to use for the data access request by opening test **3.2.05** Authorization
125
+ request succeeds when supplied correct information, click on the "REQUESTS" tab, clicking on the "DETAILS"
126
+ button, and expanding the "Response Body". Copy the "access_token" value, which will be a ~100 character
127
+ string of letters and numbers (e.g., eyJjbGllbnRfaWQiOiJzbWFydF9jbGllbnRfdGVzdF9kZW1vIiwiZXhwaXJhdGlvbiI6MTc0MzUxNDk4Mywibm9uY2UiOiJlZDI5MWIwNmZhMTE4OTc4In0)
100
128
  1. Update the postman collection configuration variables found by opening the "DTR Full EHR
101
129
  Tests Postman Demo" collection and selecting the "Variables" tab.
102
130
  - **base_url**: corresponds to the where the test suite session is running. Defaults to
103
- `inferno.healthit.gov`. If running in another location, see guidance on the "Overview" tab
131
+ `inferno.healthit.gov`. If running on another server, see guidance on the "Overview" tab
104
132
  of the postman collection.
105
- - **access_token**: note the "Current value" (update if desired) for use later.
133
+ - **access_token**: the access token extracted in the previous step.
134
+ 1. Confirm that registration is complete by clicking the link in the DTR tests to complete the registration tests.
135
+
136
+ ##### UDAP Alternative
137
+
138
+ To demonstrate the use of UDAP authentication for the DTR EHR, perform the above startup steps with the following changes
139
+ - In step 1 when starting the DTR Full EHR test suite session, choose UDAP B2B Client Credentials for the Client Security Type.
140
+ - In step 4, start a UDAP Security test suite session instead. Select the "Demo: Run Against the UDAP Security Client Suite"
141
+ preset, then choose the UDAP Client Credentials Flow group, click "RUN TESTS", and update the following inputs before clicking "SUBMIT":
142
+ - **FHIR Server Base URL**: change to the FHIR server indicated in the wait dialog in the DTR tests.
143
+ - In step 5, the access token (same format as described above) can be found in test **2.3.01** OAuth token exchange request succeeds when supplied correct information.
144
+ - In step 7, there will be two attestations to complete.
145
+
146
+ All other steps below will be the same.
106
147
 
107
148
  #### Dinner Questionnaire (Standard)
108
149
 
109
150
  For the standard (static) questionnaire demo, use the requests in the _Static Dinner_ folder in the
110
- Postman collection.
151
+ Postman collection. Follow the quick start instructions above with the following modifications:
152
+ - Use postman to submit the "Questionnaire Package for Dinner (Static)" request when Inferno
153
+ is waiting for a `$questionnaire-package` request. Note that the response that looks similar
154
+ to the "Example Working Response" in postman.
155
+ - Copy the contents of the "Sample QuestionnaireResponse for Dinner (Static) ..." postman request,
156
+ replace the string `{{base_url}}` with the value of the **base_url** postman variable, and enter the result
157
+ as the **Completed QuestionnaireResponse** input in Inferno.
111
158
 
112
- 1. Return to the Inferno test session and in the test list at the left, select _2 Static Questionnaire Workflow_.
113
- 1. Click the "Run All Tests" button in the upper right.
114
- 1. Add the **access_token** configured in postman to the Inferno input with the same name
115
- 1. Click the "Submit" button in Inferno.
116
- 1. Attest that the EHR has launched its DTR workflow in Inferno by clicking the link for the **true** response.
117
- 1. Once the next wait dialog has appeared within Inferno asking for a `$questionnaire-package`
118
- request, use postman to submit the "Questionnaire Package for Dinner (Static)" request. Confirm
119
- that the response that looks similar to the "Example Working Response" in postman
120
- and click the link to continue the tests.
121
- 1. Attest to the remainder of the tests as desired to get a sense for what is involved in testing
122
- with an actual EHR implementation. To see what a valid QuestionnaireResponse looks like, see
123
- the "Sample QuestionnaireResponse for Dinner (Static) ..." request in postman.
159
+ The "Dinner Order Questionnaire Example (Postman)" preset also populates the same questionnaire as the
160
+ tester-provided questionnaire to use in the Basic Workflows -> Static Questionnaire Workflow group. You
161
+ can execute that group as well in a similar manner to see how tester-provided questionnaire tests are
162
+ different.
163
+
164
+ These tests are not expected to fully pass due to known issues in the example FHIR instances.
124
165
 
125
166
  #### Dinner Questionnaire (Adaptive)
126
167
 
127
168
  For the adaptive questionnaire demo, use the requests in the _Adaptive Dinner_ folder in the
128
169
  Postman collection.
129
170
 
130
- 1. Return to the Inferno test session and in the test list at the left, select _3 Adaptive Questionnaire Workflow_.
131
- 1. Click the "Run All Tests" button in the upper right.
132
- 1. Add the **access_token** configured in postman to the Inferno input with the same name (if not already present)
133
- 1. Click the "Submit" button in Inferno.
171
+ 1. Return to the Inferno test session and in the test list at the left, select **3.2** Dinner Order Adaptive
172
+ Questionnaire Workflow, click the "RUN ALL TESTS" button in the upper right, and click "SUBMIT" in the input dialog.
134
173
  1. Attest that the EHR has launched its DTR workflow in Inferno by clicking the link for the **true** response.
135
174
  1. Once the **Adaptive Questionnaire Retrieval** wait dialog has appeared within Inferno asking
136
175
  for `$questionnaire-package` and `$next-question`
@@ -149,6 +188,40 @@ Postman collection.
149
188
  that the response that looks similar to the "Example Response" in postman
150
189
  and click the link to continue the tests.
151
190
 
191
+ The "Dinner Order Questionnaire Example (Postman)" preset also populates the same questionnaire as the
192
+ tester-provided questionnaire to use in the Basic Workflows -> Adaptive Questionnaire Workflow group. You
193
+ can execute that group as well in a similar manner (note that all `$next-question` requests are made
194
+ within a single wait test) to see how tester-provided questionnaire tests are different.
195
+
196
+ These tests are not expected to fully pass due to known issues in the example FHIR instances.
197
+
198
+ #### Review Authentication Interactions
199
+
200
+ Anytime after executing one of the questionnaire test groups, you can execute the Review Authentication Interactions
201
+ group to verify the conformance of access token requests against the SMART Backend Services flow.
202
+
203
+ These tests are not expected to fully pass due to invalid token requests purposefully sent by the SMART server tests.
204
+
205
+ ## Auth Configuration Details
206
+
207
+ When running these tests there are 2 options for authentication, which also allows
208
+ Inferno to identify which session the requests are for. The choice is made when the
209
+ session is created with the selected Client Security Type option, which determines
210
+ what details the tester needs to provide during the Client Registration tests:
211
+
212
+ - **SMART Backend Services**: the system under test will manually register
213
+ with Inferno and request access token used to access FHIR endpoints
214
+ as per the SMART Backend Services specification. It requires the
215
+ **SMART JSON Web Key Set (JWKS)** input to be populated with either a URL that resolves
216
+ to a JWKS or a raw JWKS in JSON format. Additionally, testers may provide
217
+ a **Client Id** if they want their client assigned a specific one.
218
+ - **UDAP B2B Client Credentials**: the system under test will dynamically register
219
+ with Inferno and request access tokens used to access FHIR endpoints
220
+ as per the UDAP specification. It requires the **UDAP Client URI** input
221
+ to be populated with the URI that the client will use when dynamically
222
+ registering with Inferno. This will be used to generate a client id (each
223
+ unique UDAP Client URI will always get the same client id).
224
+
152
225
  ## Limitations
153
226
 
154
227
  The DTR IG is a complex specification and these tests currently validate conformance to only
@@ -177,9 +250,3 @@ available that are more in-line with expected system capabilities.
177
250
  For adaptive questionnaires, the completed QuestionnaireResponse will be present in the
178
251
  last `$next-question` invocation by the EHR, so this limitation does not apply to those
179
252
  cases.
180
-
181
- ### Questionnaire Feature Coverage
182
-
183
- Not all questionnaire features that are must support within the DTR IG are currently represented
184
- in questionnaires tested by the IG. Additional questionnaires testing additional features will
185
- be added in the future.
@@ -112,12 +112,13 @@ If you do not have a DTR SMART app but would like to try the tests out, you can
112
112
  [this Postman collection](https://github.com/inferno-framework/davinci-dtr-test-kit/blob/main/config/DTR%20SMART%20App%20Tests%20Postman%20Demo.postman_collection.json)
113
113
  to make requests against Inferno. This does not include the capability to render the complete
114
114
  questionnaires, but does have samples of correctly and incorrectly completed QuestionnaireResponses.
115
- The following is a list of tests with the Postman requests that can be used with them:
115
+ After starting the session, choose the "Dinner Order Questionnaire Example" preset. The following
116
+ is a list of tests with the Postman requests that can be used with them:
116
117
 
117
- - **Standalone launch sequence**: use requests in the `SMART App Launch` folder during
118
+ - **Standalone launch sequence**: optionally use requests in the `SMART App Launch` folder during
118
119
  tests **1.1.1.01** or **2.1.1.01** to simulate the SMART Launch flow and obtain an access
119
120
  token to use for subsequent requests. See the collection's Overview for details on the
120
- access token's generation.
121
+ access token's generation. You can also skip this step and leave the existing postman variable as is.
121
122
  - **1.1** _Static Questionnaire Workflow_: use requests in the `Static Dinner` folder
122
123
  - **1.1.1.01** _Invoke the DTR Questionnaire Package operation_: submit request `Questionnaire Package for Dinner (Static)` while this test is waiting.
123
124
  - **1.1.3.01** _Save the QuestionnaireResponse after completing it_: submit request `Save QuestionnaireResponse for Dinner (Static)` while this test is waiting. If you want to see a failure, submit request `Save QuestionnaireResponse for Dinner (Static) - missing origin extension` instead.
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'smart_app_launch_test_kit'
4
+ require 'udap_security_test_kit'
5
+
6
+ module DaVinciDTRTestKit
7
+ module DTRClientOptions
8
+ SMART_BACKEND_SERVICES_CONFIDENTIAL_ASYMMETRIC =
9
+ SMARTAppLaunch::SMARTClientOptions::SMART_BACKEND_SERVICES_CONFIDENTIAL_ASYMMETRIC
10
+ UDAP_CLIENT_CREDENTIALS =
11
+ UDAPSecurityTestKit::UDAPClientOptions::UDAP_CLIENT_CREDENTIALS
12
+ end
13
+ end