-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from inferno-framework/fi-3154-full-ehr-adapti…
…ve-questionnaire-tests FI-3154: Full EHR Adaptive Questionnaire Tests
- Loading branch information
Showing
58 changed files
with
2,731 additions
and
237 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
FHIR_RESOURCE_VALIDATOR_URL=http://localhost/hl7validatorapi | ||
REDIS_URL=redis://localhost:6379/0 | ||
FHIR_REFERENCE_SERVER=http://localhost:8080/reference-server/r4 | ||
FHIRPATH_URL=http://localhost/fhirpath |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
REDIS_URL=redis://redis:6379/0 | ||
FHIR_RESOURCE_VALIDATOR_URL=http://hl7_validator_service:3500 | ||
FHIR_REFERENCE_SERVER=https://inferno.healthit.gov/reference-server/r4 | ||
FHIRPATH_URL=http://fhirpath:6789 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
FHIR_RESOURCE_VALIDATOR_URL=https://example.com/validatorapi | ||
ASYNC_JOBS=false | ||
FHIR_REFERENCE_SERVER=http://example.com/reference-server/r4 | ||
FHIRPATH_URL=https://example.com/fhirpath |
334 changes: 330 additions & 4 deletions
334
config/DTR Full EHR Tests Postman Demo.postman_collection.json
Large diffs are not rendered by default.
Oops, something went wrong.
416 changes: 361 additions & 55 deletions
416
config/DTR SMART App Tests Postman Demo.postman_collection.json
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
...dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_completion_group.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
require_relative 'dtr_adaptive_questionnaire_next_question_retrieval_group' | ||
|
||
module DaVinciDTRTestKit | ||
class DTRAdaptiveQuestionnaireCompletionGroup < Inferno::TestGroup | ||
id :dtr_adaptive_questionnaire_completion | ||
title 'Completing the Adaptive Questionnaire' | ||
description %( | ||
The client makes a final $next-question call, including the answers to all required questions asked so far. | ||
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) | ||
and will update the status of the QuestionnaireResponse resource parameter to `complete`. | ||
Inferno will also validate the completed QuestionnaireResponse conformance. | ||
) | ||
|
||
config( | ||
options: { | ||
next_question_prompt_title: 'Last Next Question Request' | ||
} | ||
) | ||
run_as_group | ||
|
||
group from: :dtr_adaptive_questionnaire_next_question_retrieval | ||
end | ||
end |
26 changes: 26 additions & 0 deletions
26
..._kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_followup_questions_group.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
require_relative 'dtr_adaptive_questionnaire_next_question_retrieval_group' | ||
|
||
module DaVinciDTRTestKit | ||
class DTRAdaptiveQuestionnaireFollowupQuestionsGroup < Inferno::TestGroup | ||
id :dtr_adaptive_questionnaire_followup_questions | ||
title 'Retrieving the Next Question' | ||
description %( | ||
The client makes a subsequent call to request the next question or set of questions | ||
using the $next-question operation, and including the answers to all required questions | ||
in the questionnaire to this point. | ||
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) | ||
and will provide the next questions accordingly for the tester to complete and attest to pre-population | ||
and questionnaire rendering. | ||
) | ||
|
||
config( | ||
options: { | ||
next_question_prompt_title: 'Follow-up Next Question Request' | ||
} | ||
) | ||
|
||
run_as_group | ||
|
||
group from: :dtr_adaptive_questionnaire_next_question_retrieval | ||
end | ||
end |
93 changes: 93 additions & 0 deletions
93
...it/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_next_question_request_test.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
require_relative '../../urls' | ||
|
||
module DaVinciDTRTestKit | ||
class DTRAdaptiveQuestionnaireNextQuestionRequestTest < Inferno::Test | ||
include URLs | ||
|
||
id :dtr_adaptive_questionnaire_next_question_request | ||
title 'Invoke the $next-question operation' | ||
description %( | ||
Inferno will wait for the client to invoke the $next-question operation to retrieve the next question | ||
or set of questions. | ||
Inferno will validate the request body and update the contained Questionnaire to include | ||
the next question or set of questions. | ||
) | ||
|
||
input :access_token | ||
|
||
def example_client_jwt_payload_part | ||
Base64.strict_encode64({ inferno_client_id: access_token }.to_json).delete('=') | ||
end | ||
|
||
def request_identification | ||
if config.options[:smart_app] | ||
"eyJhbGciOiJub25lIn0.#{example_client_jwt_payload_part}" | ||
else | ||
access_token | ||
end | ||
end | ||
|
||
def cont_test_description | ||
<<~DESCRIPTION | ||
### Continuing the Tests | ||
When the DTR application has finished loading the Questionnaire, | ||
including any clinical data requests to support pre-population, | ||
[Click here](#{resume_pass_url}?token=#{access_token}) to continue. | ||
DESCRIPTION | ||
end | ||
|
||
def next_question_prompt_title | ||
config.options[:next_question_prompt_title] | ||
end | ||
|
||
def next_question_prompt | ||
if next_question_prompt_title&.include?('Initial') | ||
'Invoke the $next-question operation by sending a POST request to' | ||
elsif next_question_prompt_title&.include?('Last') | ||
'Answer the remaining questions and then make a final next-question request by sending a POST request to' | ||
else | ||
"Answer the 'What do you want for dinner' question and then make a next-question request by sending a POST " \ | ||
'request to' | ||
end | ||
end | ||
|
||
def prompt_cont | ||
if next_question_prompt_title&.include?('Initial') | ||
%(Upon receipt, Inferno will provide the first set of questions to complete.) | ||
elsif next_question_prompt_title&.include?('Last') | ||
%(Upon receipt, Inferno will update the status of the QuestionnaireResponse | ||
resource parameter to `complete`.) | ||
else | ||
%(Upon receipt, Inferno will provide the next set of questions to complete | ||
based on previous answers.) | ||
end | ||
end | ||
|
||
run do | ||
wait( | ||
identifier: access_token, | ||
message: <<~MESSAGE | ||
### #{next_question_prompt_title} | ||
#{next_question_prompt} | ||
`#{next_url}` | ||
#{prompt_cont} | ||
### Request Identification | ||
In order to identify requests for this session, Inferno will look for | ||
an `Authorization` header with value: | ||
``` | ||
Bearer #{request_identification} | ||
``` | ||
#{cont_test_description if config.options[:accepts_multiple_requests]} | ||
MESSAGE | ||
) | ||
end | ||
end | ||
end |
62 changes: 62 additions & 0 deletions
62
...roups/dinner_adaptive/dtr_adaptive_questionnaire_next_question_request_validation_test.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
require_relative '../../urls' | ||
|
||
module DaVinciDTRTestKit | ||
class DTRAdaptiveQuestionnaireNextQuestionRequestValidationTest < Inferno::Test | ||
include URLs | ||
|
||
id :dtr_next_question_request_validation | ||
title '$next-question request is valid' | ||
description %( | ||
Per the [OperationDefinition: Adaptive questionnaire next question](https://build.fhir.org/ig/HL7/sdc/OperationDefinition-Questionnaire-next-question.html#root) | ||
section in the [Structured Data Capture IG](http://hl7.org/fhir/uv/sdc/ImplementationGuide/hl7.fhir.uv.sdc), | ||
the request body for the `$next-question` operation should be a FHIR Parameters resource containing a | ||
single parameter with: | ||
- name: `questionnaire-response` | ||
- resource: A `QuestionnaireResponse` resource | ||
As outlined in the [FHIR Operation Request](https://hl7.org/fhir/r4/operations.html#request) section of the | ||
FHIR specification, if an operation has exactly one input parameter of type Resource, it can also be invoked via | ||
a POST request using that resource as the body (with no additional URL parameters). | ||
This test validates the structure of the `$next-question` request body. It confirms that the body is either a | ||
Parameters resource or a QuestionnaireResponse resource. | ||
If it is a Parameters resource, it must contain one parameter named `questionnaire-response` | ||
with a `resource` attribute set to a FHIR QuestionnaireResponse instance, as specified above. | ||
The QuestionnaireResponse resource's structure and conformance will be validated | ||
in the following test ('Adaptive QuestionnaireResponse is valid'). | ||
) | ||
|
||
def assert_valid_resource_type(resource) | ||
type = resource.resourceType | ||
valid = ['Parameters', 'QuestionnaireResponse'].include?(type) | ||
assert valid, "Request body not valid. Expected Parameters or QuestionnaireResponse, got #{type}" | ||
end | ||
|
||
def next_request_tag | ||
config.options[:next_tag] | ||
end | ||
|
||
run do | ||
load_tagged_requests next_request_tag | ||
skip_if request.blank?, 'A $next-question request must be made prior to running this test' | ||
|
||
assert request.url == next_url, "Request made to wrong URL: #{request.url}. Should instead be to #{next_url}" | ||
assert_valid_json(request.request_body) | ||
input_params = FHIR.from_contents(request.request_body) | ||
assert input_params.present?, 'Request does not contain a recognized FHIR object' | ||
assert_valid_resource_type(input_params) | ||
|
||
if input_params.is_a?(FHIR::Parameters) | ||
questionnaire_response_params = input_params.parameter.select { |param| param.name == 'questionnaire-response' } | ||
qr_params_count = questionnaire_response_params.length | ||
assert qr_params_count == 1, | ||
"Input parameter must contain one `parameter:questionnaire-response` slice. Found #{qr_params_count}" | ||
|
||
questionnaire_response = questionnaire_response_params.first.resource | ||
assert_resource_type(:questionnaire_response, resource: questionnaire_response) | ||
end | ||
end | ||
end | ||
end |
23 changes: 23 additions & 0 deletions
23
...client_groups/dinner_adaptive/dtr_adaptive_questionnaire_next_question_retrieval_group.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
require_relative 'dtr_adaptive_questionnaire_next_question_request_test' | ||
require_relative 'dtr_adaptive_questionnaire_next_question_request_validation_test' | ||
require_relative 'dtr_adaptive_questionnaire_response_validation_test' | ||
|
||
module DaVinciDTRTestKit | ||
class DTRAdaptiveQuestionnaireNextQuestionRetrievalGroup < Inferno::TestGroup | ||
id :dtr_adaptive_questionnaire_next_question_retrieval | ||
title 'Next Question Request and Validation' | ||
description %( | ||
Inferno will wait for the client system to request the next question (or set of questions) using the | ||
$next-question operation and will return an updated QuestionnaireResponse with a contained Questionnaire | ||
that includes the next question (or set of questions) for the tester to complete. | ||
Inferno will then validate the conformance of the request. | ||
) | ||
|
||
# Test 1: wait for the $next-question request | ||
test from: :dtr_adaptive_questionnaire_next_question_request | ||
# Test 2: validate the $next-question request | ||
test from: :dtr_next_question_request_validation | ||
# Test 3: validate the QuestionnaireResponse in the input parameter | ||
test from: :dtr_adaptive_questionnaire_response_validation | ||
end | ||
end |
66 changes: 66 additions & 0 deletions
66
..._kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_response_validation_test.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
require_relative '../../urls' | ||
require_relative '../../dtr_questionnaire_response_validation' | ||
|
||
module DaVinciDTRTestKit | ||
class DTRAdaptiveQuestionnaireResponseValidationTest < Inferno::Test | ||
include URLs | ||
include DTRQuestionnaireResponseValidation | ||
|
||
id :dtr_adaptive_questionnaire_response_validation | ||
title 'Adaptive QuestionnaireResponse is valid' | ||
description %( | ||
This test validates the conformance of the Adative QuestionnaireResponse to the | ||
[SDCQuestionnaireResponseAdapt](http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse-adapt) | ||
structure. It verifies the presence of mandatory elements and that elements | ||
with required bindings contain appropriate values. | ||
It also ensures that all required questions are answered, and that the `origin.source` | ||
extension is correct for each answer: | ||
- `PBD.1` (Last Name) and `LOC.1` (Location): `auto` | ||
- `PBD.2` (First Name): `override` | ||
- `3` (all nested dinner questions): `manual` | ||
Note: For the initial next-question request, only the conformance to the profile is checked | ||
since neither the QuestionnaireResponse nor the contained Questionnaire will have any items, | ||
as no questions are yet known. | ||
) | ||
|
||
def profile_url | ||
'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse-adapt' | ||
end | ||
|
||
def next_request_tag | ||
config.options[:next_tag] | ||
end | ||
|
||
run do | ||
load_tagged_requests next_request_tag | ||
skip_if request.blank?, 'A $next-question request must be made prior to running this test' | ||
|
||
assert request.url == next_url, "Request made to wrong URL: #{request.url}. Should instead be to #{next_url}" | ||
assert_valid_json(request.request_body) | ||
input_params = FHIR.from_contents(request.request_body) | ||
skip_if input_params.blank?, 'Request does not contain a recognized FHIR object' | ||
|
||
questionnaire_response = nil | ||
if input_params.is_a?(FHIR::QuestionnaireResponse) | ||
questionnaire_response = input_params | ||
elsif input_params.is_a?(FHIR::Parameters) | ||
questionnaire_response = input_params.parameter&.find do |param| | ||
param.name == 'questionnaire-response' | ||
end&.resource | ||
end | ||
|
||
skip_if questionnaire_response.nil?, 'QuestionnaireResponse resource not provided.' | ||
verify_basic_conformance(questionnaire_response.to_json, profile_url) | ||
|
||
questionnaire = questionnaire_response.contained.find { |res| res.resourceType == 'Questionnaire' } | ||
check_origin_sources(questionnaire.item, questionnaire_response.item, expected_overrides: ['PBD.2']) | ||
|
||
required_link_ids = extract_required_link_ids(questionnaire.item) | ||
check_answer_presence(questionnaire_response.item, required_link_ids) | ||
|
||
assert(messages.none? { |m| m[:type] == 'error' }, 'QuestionnaireResponse is not correct, see error message(s)') | ||
end | ||
end | ||
end |
Oops, something went wrong.