Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FI-3584: Allow User Provided Questionnaire Package Responses #44

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
module DaVinciDTRTestKit
class DTRCustomQuestionnairePackageValidationTest < Inferno::Test
id :dtr_custom_questionnaire_package_validation
title 'Custom Questionnaire Package response is valid'
description %(
Inferno will validate that the user provided response to the questionnaire-package operation is conformant
to the
[Questionnaire Package operation definition](https://hl7.org/fhir/us/davinci-dtr/STU2/OperationDefinition-questionnaire-package.html).
This includes verifying that the response conforms to the
[DTR Questionnaire Package Bundle profile](https://hl7.org/fhir/us/davinci-dtr/STU2/StructureDefinition-DTR-QPackageBundle.html)
and, in the event that the server includes that Bundle in a Parameters object, the
[DTR Questionnaire Package Output Parameters profile](https://hl7.org/fhir/us/davinci-dtr/STU2/StructureDefinition-dtr-qpackage-output-parameters.html).

It verifies the presence of mandatory elements and that elements with required bindings contain appropriate
values. CodeableConcept element bindings will fail if none of their codings have a code/system belonging
to the bound ValueSet. Quantity, Coding, and code element bindings will fail if their code/system are not found in
the valueset.
)

input :custom_questionnaire_package_response,
title: 'Custom Questionnaire Package Response JSON',
description: %(
A JSON PackageBundle may be provided here to replace Inferno's response to the
$questionnaire-package request.
),
type: 'textarea',
optional: true

run do
omit_if custom_questionnaire_package_response.blank?, 'Custom response was not provided'

assert_valid_json custom_questionnaire_package_response

resource = FHIR.from_contents(custom_questionnaire_package_response)
if resource&.resourceType == 'Parameters'
scratch[:static_questionnaire_bundles] = resource.parameter&.filter_map do |param|
param.resource if param.resource&.resourceType == 'Bundle'
end
assert_valid_resource(resource:,
profile_url: 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-output-parameters|2.0.1')
questionnaire_bundle = resource.parameter.find { |param| param.resource.resourceType == 'Bundle' }&.resource
assert questionnaire_bundle, 'No questionnaire bundle found in the response'
elsif resource&.resourceType == 'Bundle'
scratch[:static_questionnaire_bundles] = [resource]
assert_valid_resource(resource:,
profile_url: 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/DTR-QPackageBundle|2.0.1')
else
assert(false, "Unexpected resourceType: #{resource&.resourceType}. Expected Parameters or Bundle")
end
end
end
end
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
require_relative '../full_ehr/dtr_full_ehr_launch_attestation_test'
require_relative '../full_ehr/dtr_full_ehr_questionnaire_package_request_test'
require_relative '../shared/dtr_questionnaire_package_request_validation_test'
require_relative '../full_ehr/dtr_full_ehr_prepopulation_attestation_test'
require_relative '../full_ehr/dtr_full_ehr_rendering_enabled_questions_attestation_test'
require_relative '../full_ehr/dtr_full_ehr_prepopulation_override_attestation_test'
require_relative '../shared/dtr_prepopulation_attestation_test'
require_relative '../shared/dtr_rendering_enabled_questions_attestation_test'
require_relative '../shared/dtr_prepopulation_override_attestation_test'
require_relative '../full_ehr/dtr_full_ehr_saving_questionnaire_response_group'
require_relative 'dtr_custom_questionnaire_package_validation_test'
require_relative '../../payer_server_groups/static_form_libraries_test'
require_relative '../../payer_server_groups/static_form_questionnaire_extensions_test'
require_relative '../../payer_server_groups/static_form_questionnaire_expressions_test'

module DaVinciDTRTestKit
class DTRFullEHRStaticDinnerQuestionnaireWorkflowGroup < Inferno::TestGroup
id :dtr_full_ehr_static_dinner_questionnaire_workflow
title 'Static Questionnaire Workflow'
description %(
This test validates that a DTR Full EHR client can perform a full DTR Static Questionnaire workflow
using a mocked questionnaire requesting what a patient wants for dinner. The client system must
This test validates that a DTR Full EHR client can perform a full DTR Static Questionnaire workflow.
Users have the option to either use a mocked questionnaire requesting what a patient wants for dinner
or provide a custom questionnaire package of their choice for the test. The client system must
demonstrate its ability to:

1. Fetch the static questionnaire package
([DinnerOrderStatic](https://github.com/inferno-framework/davinci-dtr-test-kit/blob/main/lib/davinci_dtr_test_kit/fixtures/dinner_static/questionnaire_dinner_order_static.json))
or the custom questionnaire package
2. Render and pre-populate the questionnaire appropriately, including:
- pre-populate data as directed by the questionnaire
- display questions only when they are enabled by other answers
Expand All @@ -33,11 +39,46 @@ class DTRFullEHRStaticDinnerQuestionnaireWorkflowGroup < Inferno::TestGroup
)
run_as_group

input_order :access_token, :custom_questionnaire_package_response

def retrieval_method
'Static'
end

# Test 0: attest to launch
test from: :dtr_full_ehr_launch_attestation
# Test 1: wait for the $questionnaire-package request
# Test 1: validate the user provided $questionnaire-package response
test from: :dtr_custom_questionnaire_package_validation
# Test 2: verify the custom response has the necessary libraries for pre-population
test from: :dtr_v201_payer_static_form_libraries_test do
title 'Custom Questionnaire Package response parameters contain libraries necessary for pre-population'
description %(
Inferno check that the custom response contains no duplicate library names
and that libraries contain cql and elm data.
)
end
tstrass marked this conversation as resolved.
Show resolved Hide resolved

# Test 3: verify the custom response has the necessaru extensions for pre-population
test from: :dtr_v201_payer_static_form_extensions_test do
title 'Custom static questionnaire(s) contain extensions necessary for pre-population'
description %(
Inferno checks that the custom response has appropriate extensions and references to libraries within
those extensions.
)
end

# Test 4: verify custom response has necessary expressions for pre-population
test from: :dtr_v201_payer_static_form_expressions_test do
title 'Custom static questionnaire(s) contain items with expressions necessary for pre-population'
description %(
Inferno checks that the custom response has appropriate expressions and that expressions are
written in cql.
)
config(options: { client: true })
end
# Test 5: wait for the $questionnaire-package request
test from: :dtr_full_ehr_questionnaire_package_request
# Test 2: validate the $questionnaire-package body
# Test 6: validate the $questionnaire-package body
test from: :dtr_questionnaire_package_request_validation
end

Expand All @@ -53,11 +94,11 @@ class DTRFullEHRStaticDinnerQuestionnaireWorkflowGroup < Inferno::TestGroup
run_as_group

# Test 1: attest to the pre-population of the name fields
test from: :dtr_full_ehr_prepopulation_attestation
test from: :dtr_prepopulation_attestation
# Test 2: attest to the pre-population and edit of the first name field
test from: :dtr_full_ehr_prepopulation_override_attestation
# Test 3: attest to the display of the toppings questions only when a dinner answer is selected
test from: :dtr_full_ehr_rendering_enabled_questions_attestation
test from: :dtr_prepopulation_override_attestation
# Test 3: attest to proper display of enabled question(s)
test from: :dtr_rendering_enabled_questions_attestation
end

group from: :dtr_full_ehr_saving_questionnaire_response,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class DTRSmartAppDinnerQuestionnairePackageRequestTest < Inferno::Test
instance present will be available for retrieval from Inferno at the endpoint:
<fhir-base>/<resource type>/<instance id>
)
input :custom_questionnaire_package_response, optional: true

def example_client_jwt_payload_part
Base64.strict_encode64({ inferno_client_id: client_id }.to_json).delete('=')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
require_relative 'dtr_smart_app_dinner_questionnaire_package_request_test'
require_relative '../shared/dtr_questionnaire_package_request_validation_test'
require_relative '../smart_app/dtr_smart_app_prepopulation_attestation_test'
require_relative '../smart_app/dtr_smart_app_prepopulation_override_attestation_test'
require_relative '../smart_app/dtr_smart_app_rendering_enabled_questions_attestation_test'
require_relative '../shared/dtr_prepopulation_attestation_test'
require_relative '../shared/dtr_rendering_enabled_questions_attestation_test'
require_relative '../shared/dtr_prepopulation_override_attestation_test'
require_relative '../smart_app/dtr_smart_app_saving_questionnaire_response_group'
require_relative 'dtr_custom_questionnaire_package_validation_test'
require_relative '../../payer_server_groups/static_form_libraries_test'
require_relative '../../payer_server_groups/static_form_questionnaire_extensions_test'
require_relative '../../payer_server_groups/static_form_questionnaire_expressions_test'

module DaVinciDTRTestKit
class DTRSmartAppStaticDinnerQuestionnaireWorkflowGroup < Inferno::TestGroup
id :dtr_smart_app_static_dinner_questionnaire_workflow
title 'Static Questionnaire Workflow'
description %(
This test validates that a DTR SMART App client can perform a full DTR Static Questionnaire workflow
using a mocked questionnaire requesting what a patient wants for dinner. The client system must
demonstrate their ability to:
This test validates that a DTR SMART App client can perform a full DTR Static Questionnaire workflow.
Users have the option to either use a mocked questionnaire requesting what a patient wants for dinner
or provide a custom questionnaire package of their choice for the test. The client system must
demonstrate its ability to:

1. Fetch the static questionnaire package
([DinnerOrderStatic](https://github.com/inferno-framework/davinci-dtr-test-kit/blob/main/lib/davinci_dtr_test_kit/fixtures/dinner_static/questionnaire_dinner_order_static.json))
or the custom questionnaire package
2. Render and pre-populate the questionnaire appropriately, including:
- fetch additional data needed for pre-population
- pre-populate data as directed by the questionnaire
Expand All @@ -34,9 +40,42 @@ class DTRSmartAppStaticDinnerQuestionnaireWorkflowGroup < Inferno::TestGroup
)
run_as_group

# Test 1: wait for the $questionnaire-package request
def retrieval_method
'Static'
end

# Test 1: validate the user provided $questionnaire-package response
test from: :dtr_custom_questionnaire_package_validation
# Test 2: verify the custom response has the necessary libraries for pre-population
test from: :dtr_v201_payer_static_form_libraries_test do
title 'Custom Questionnaire Package response parameters contain libraries necessary for pre-population'
description %(
Inferno check that the custom response contains no duplicate library names
and that libraries contain cql and elm data.
)
end

# Test 3: verify the custom response has the necessaru extensions for pre-population
test from: :dtr_v201_payer_static_form_extensions_test do
title 'Custom static questionnaire(s) contain extensions necessary for pre-population'
description %(
Inferno checks that the custom response has appropriate extensions and references to libraries within
those extensions.
)
end

# Test 4: verify custom response has necessary expressions for pre-population
test from: :dtr_v201_payer_static_form_expressions_test do
title 'Custom static questionnaire(s) contain items with expressions necessary for pre-population'
description %(
Inferno checks that the custom response has appropriate expressions and that expressions are
written in cql.
)
config(options: { client: true })
end
# Test 5: wait for the $questionnaire-package request
test from: :dtr_smart_app_dinner_questionnaire_package_request
# Test 2: validate the $questionnaire-package body
# Test 6: validate the $questionnaire-package body
test from: :dtr_questionnaire_package_request_validation
end

Expand All @@ -56,11 +95,11 @@ class DTRSmartAppStaticDinnerQuestionnaireWorkflowGroup < Inferno::TestGroup
# since the questionnaire asks them to
# TODO: once Tom has gotten the reference server hooked up
# Test 2: attest to the pre-population of the name fields
test from: :dtr_smart_app_prepopulation_attestation
test from: :dtr_prepopulation_attestation
# Test 3: attest to the pre-population and edit of the location field
test from: :dtr_smart_app_prepopulation_override_attestation
# Test 4: attest to the display of the toppings questions only when a dinner answer is selected
test from: :dtr_smart_app_rendering_enabled_questions_attestation
test from: :dtr_prepopulation_override_attestation
# Test 4: attest to proper display of enabled question(s)
test from: :dtr_rendering_enabled_questions_attestation
end

group from: :dtr_smart_app_saving_questionnaire_response
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@ class DTRFullEHRPrepopulationAttestationTest < Inferno::Test
id :dtr_full_ehr_prepopulation_attestation
title 'Check that the client pre-populates the questionnaire (Attestation)'
description %(
Validate that pre-population of patient name information occurs as expected.
Validate that pre-population of patient's information occurs as expected.
)
run do
random_id = SecureRandom.uuid
wait(
identifier: random_id,
message: %(
I attest that the DTR application pre-populates the following questions with the respective
value for the official name of the patient:
- Last Name
- First Name
I attest that the DTR application is able to pre-populate questions on the questionnaire
with relevant information.

[Click here](#{resume_pass_url}?token=#{random_id}) if the above statement is **true**.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class DTRFullEHRPrepopulationOverrideAttestationTest < Inferno::Test
wait(
identifier: random_id,
message: %(
I attest that I have changed the prepopulated value in the First Name field to a new value.
I attest that I have changed the prepopulated value in a questionnaire field to a new value.

[Click here](#{resume_pass_url}?token=#{random_id}) if the above statement is **true**.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class DTRFullEHRQuestionnairePackageRequestTest < Inferno::Test
`Authorization` header of each HTTP request to Inferno. Inferno
will look for this value to associate requests with this session.
)
input :custom_questionnaire_package_response, optional: true

run do
wait(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
require_relative '../../dtr_questionnaire_response_validation'
require_relative '../../cql_test'

module DaVinciDTRTestKit
class DTRFullEHRQuestionnaireResponseCorrectnessTest < Inferno::Test
include DTRQuestionnaireResponseValidation
include DaVinciDTRTestKit::CQLTest

id :dtr_full_ehr_questionnaire_response_correctness
title 'QuestionnaireResponse is correct for the workflow'
description %(
The QuestionnaireResponse aligns with the following expectations for the workflow. This includes checks for
the presence of the following answers and their appropriate origin source extensions:

- `PBD.1` (Last Name) and `LOC.1` (Location): `auto`
- PBD.2 (First Name): `override`
- `3` (all nested dinner questions): `manual`
This test verifies that all the QuestionnaireResponse.item have the appropriate
origin source extensions and that all required questions have been answered.
)

run do
skip_if questionnaire_response.nil?, 'Completed QuestionnaireResponse input was blank'
skip_if questionnaire_response.blank?, 'Completed QuestionnaireResponse input was blank'
check_is_questionnaire_response(questionnaire_response)

qr = FHIR.from_contents(questionnaire_response)
questionnaire = if config.options[:adaptive]
qr.contained.find do |res|
res.resourceType == 'Questionnaire'
end
else
questionnaire = if scratch[:static_questionnaire_bundles].nil?
tstrass marked this conversation as resolved.
Show resolved Hide resolved
Fixtures.questionnaire_for_test(id)
else
questionnaires = extract_questionnaires_from_bundles(scratch[:static_questionnaire_bundles])
questionnaires.find { |q| qr.questionnaire.end_with?(q.id) }
end
# questionnaire = Fixtures.find_questionnaire('DinnerOrderStatic')
check_origin_sources(questionnaire.item, qr.item, expected_overrides: ['PBD.2'])

skip_if questionnaire.blank?, "Couldn't find Questionnaire #{qr.questionnaire} to check the QuestionnaireResponse"

expected_overrides = scratch[:static_questionnaire_bundles].nil? ? [] : ['PBD.2']
tstrass marked this conversation as resolved.
Show resolved Hide resolved
scratch[:static_questionnaire_bundles] = nil

check_origin_sources(questionnaire.item, qr.item, expected_overrides:)
required_link_ids = extract_required_link_ids(questionnaire.item)
check_answer_presence(qr.item, required_link_ids)
assert(messages.none? { |m| m[:type] == 'error' }, 'QuestionnaireResponse is not correct, see error message(s)')
Expand Down

This file was deleted.

Loading
Loading