davinci_dtr_test_kit 0.12.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) 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 -28
  15. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_smart_app_dinner_questionnaire_package_request_test.rb +14 -17
  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/full_ehr/dtr_full_ehr_questionnaire_response_conformance_test.rb +19 -0
  22. data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_questionnaire_response_correctness_test.rb +37 -0
  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 +7 -7
  29. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_pre_population_test.rb +16 -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 +114 -172
  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 +34 -0
  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 +101 -23
  43. data/lib/davinci_dtr_test_kit/dtr_options.rb +7 -0
  44. data/lib/davinci_dtr_test_kit/dtr_payer_server_suite.rb +9 -20
  45. data/lib/davinci_dtr_test_kit/dtr_questionnaire_response_validation.rb +126 -75
  46. data/lib/davinci_dtr_test_kit/dtr_smart_app_suite.rb +32 -56
  47. data/lib/davinci_dtr_test_kit/endpoints/cors.rb +20 -0
  48. data/lib/davinci_dtr_test_kit/endpoints/mock_authorization/authorize_endpoint.rb +32 -0
  49. data/lib/davinci_dtr_test_kit/endpoints/mock_authorization/simple_token_endpoint.rb +19 -0
  50. data/lib/davinci_dtr_test_kit/endpoints/mock_authorization/token_endpoint.rb +116 -0
  51. data/lib/davinci_dtr_test_kit/endpoints/mock_authorization.rb +83 -0
  52. data/lib/davinci_dtr_test_kit/endpoints/mock_ehr/fhir_get_endpoint.rb +95 -0
  53. data/lib/davinci_dtr_test_kit/endpoints/mock_ehr/questionnaire_response_endpoint.rb +22 -0
  54. data/lib/davinci_dtr_test_kit/endpoints/mock_ehr.rb +25 -0
  55. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_next_question_endpoint.rb +11 -0
  56. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_questionnaire_package_endpoint.rb +11 -0
  57. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/next_question_endpoint.rb +162 -0
  58. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/next_question_proxy_endpoint.rb +36 -0
  59. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/questionnaire_package_endpoint.rb +62 -0
  60. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/questionnaire_package_proxy_endpoint.rb +38 -0
  61. data/lib/davinci_dtr_test_kit/endpoints/mock_payer.rb +36 -0
  62. data/lib/davinci_dtr_test_kit/fixture_loader.rb +6 -84
  63. data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_burrito.json +10 -2
  64. data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_hamburger.json +10 -2
  65. data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_initial.json +10 -2
  66. data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/questionnaire_dinner_order_adaptive.json +4 -3
  67. data/lib/davinci_dtr_test_kit/fixtures.rb +64 -46
  68. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_libraries_test.rb +2 -2
  69. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_questionnaire_expressions_test.rb +4 -3
  70. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_questionnaire_extensions_test.rb +3 -2
  71. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_next_questionnaire_expressions_test.rb +8 -8
  72. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_next_questionnaire_extensions_test.rb +6 -5
  73. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_group.rb +2 -2
  74. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_request_validation_test.rb +2 -1
  75. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_bundles_validation_test.rb +6 -9
  76. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_search_validation_test.rb +15 -12
  77. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_validation_test.rb +33 -22
  78. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_next_request_validation_test.rb +1 -1
  79. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_next_response_complete_test.rb +4 -4
  80. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_next_response_validation_test.rb +16 -12
  81. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_libraries_test.rb +2 -2
  82. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_questionnaire_expressions_test.rb +5 -4
  83. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_questionnaire_extensions_test.rb +4 -3
  84. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_request_validation_test.rb +2 -1
  85. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_response_validation_test.rb +32 -23
  86. data/lib/davinci_dtr_test_kit/profiles/communication_request/communication_request_read.rb +29 -0
  87. data/lib/davinci_dtr_test_kit/profiles/communication_request/communication_request_validation.rb +35 -0
  88. data/lib/davinci_dtr_test_kit/profiles/communication_request_group.rb +39 -0
  89. data/lib/davinci_dtr_test_kit/profiles/coverage/coverage_read.rb +29 -0
  90. data/lib/davinci_dtr_test_kit/profiles/coverage/coverage_validation.rb +35 -0
  91. data/lib/davinci_dtr_test_kit/profiles/coverage_group.rb +38 -0
  92. data/lib/davinci_dtr_test_kit/profiles/device_request/device_request_read.rb +29 -0
  93. data/lib/davinci_dtr_test_kit/profiles/device_request/device_request_validation.rb +35 -0
  94. data/lib/davinci_dtr_test_kit/profiles/device_request_group.rb +39 -0
  95. data/lib/davinci_dtr_test_kit/profiles/encounter/encounter_read.rb +29 -0
  96. data/lib/davinci_dtr_test_kit/profiles/encounter/encounter_validation.rb +35 -0
  97. data/lib/davinci_dtr_test_kit/profiles/encounter_group.rb +39 -0
  98. data/lib/davinci_dtr_test_kit/profiles/medication_request/medication_request_read.rb +29 -0
  99. data/lib/davinci_dtr_test_kit/profiles/medication_request/medication_request_validation.rb +35 -0
  100. data/lib/davinci_dtr_test_kit/profiles/medication_request_group.rb +39 -0
  101. data/lib/davinci_dtr_test_kit/profiles/nutrition_order/nutrition_order_read.rb +29 -0
  102. data/lib/davinci_dtr_test_kit/profiles/nutrition_order/nutrition_order_validation.rb +35 -0
  103. data/lib/davinci_dtr_test_kit/profiles/nutrition_order_group.rb +39 -0
  104. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_context_search.rb +35 -0
  105. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_create.rb +26 -0
  106. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_patient_search.rb +55 -0
  107. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_read.rb +22 -0
  108. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_update.rb +26 -0
  109. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_validation.rb +37 -0
  110. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response_group.rb +66 -0
  111. data/lib/davinci_dtr_test_kit/profiles/service_request/service_request_read.rb +29 -0
  112. data/lib/davinci_dtr_test_kit/profiles/service_request/service_request_validation.rb +35 -0
  113. data/lib/davinci_dtr_test_kit/profiles/service_request_group.rb +39 -0
  114. data/lib/davinci_dtr_test_kit/profiles/task/task_create.rb +26 -0
  115. data/lib/davinci_dtr_test_kit/profiles/task/task_read.rb +29 -0
  116. data/lib/davinci_dtr_test_kit/profiles/task/task_update.rb +26 -0
  117. data/lib/davinci_dtr_test_kit/profiles/task/task_validation.rb +35 -0
  118. data/lib/davinci_dtr_test_kit/profiles/task_group.rb +52 -0
  119. data/lib/davinci_dtr_test_kit/profiles/vision_prescription/vision_prescription_read.rb +29 -0
  120. data/lib/davinci_dtr_test_kit/profiles/vision_prescription/vision_prescription_validation.rb +35 -0
  121. data/lib/davinci_dtr_test_kit/profiles/vision_prescription_group.rb +39 -0
  122. data/lib/davinci_dtr_test_kit/read_test.rb +22 -0
  123. data/lib/davinci_dtr_test_kit/tags.rb +5 -6
  124. data/lib/davinci_dtr_test_kit/update_test.rb +25 -0
  125. data/lib/davinci_dtr_test_kit/urls.rb +13 -10
  126. data/lib/davinci_dtr_test_kit/validation_test.rb +21 -5
  127. data/lib/davinci_dtr_test_kit/version.rb +1 -1
  128. data/lib/davinci_dtr_test_kit.rb +1 -1
  129. metadata +129 -24
  130. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_full_ehr_prepopulation_representation_attestation_test.rb +0 -33
  131. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_full_ehr_questionnaire_workflow_group.rb +0 -19
  132. data/lib/davinci_dtr_test_kit/ext/inferno_core/record_response_route.rb +0 -98
  133. data/lib/davinci_dtr_test_kit/ext/inferno_core/request.rb +0 -19
  134. data/lib/davinci_dtr_test_kit/ext/inferno_core/runnable.rb +0 -35
  135. data/lib/davinci_dtr_test_kit/mock_auth_server.rb +0 -145
  136. data/lib/davinci_dtr_test_kit/mock_ehr.rb +0 -97
  137. data/lib/davinci_dtr_test_kit/mock_payer.rb +0 -123
  138. /data/lib/davinci_dtr_test_kit/fixtures/{pre_populated_questionnaire_response.json → respiratory_assist_device/pre_populated_questionnaire_response.json} +0 -0
  139. /data/lib/davinci_dtr_test_kit/fixtures/{questionnaire_package.json → respiratory_assist_device/questionnaire_package.json} +0 -0
@@ -14,25 +14,21 @@ module DaVinciDTRTestKit
14
14
  end
15
15
 
16
16
  def cqf_reference_libraries
17
- @cqf_reference_libraries ||= Set.new
17
+ scratch[:cqf_reference_libraries] ||= Set.new
18
18
  end
19
19
 
20
20
  def library_urls
21
- @@library_urls ||= Set.new
21
+ scratch[:library_urls] ||= Set.new
22
22
  end
23
23
 
24
24
  def library_names
25
- @@library_names ||= Set.new
25
+ scratch[:library_names] ||= Set.new
26
26
  end
27
27
 
28
28
  def found_questionnaire
29
29
  @found_questionnaire ||= false
30
30
  end
31
31
 
32
- def found_bad_library_reference
33
- @@found_bad_library_reference ||= false
34
- end
35
-
36
32
  def found_duplicate_library_name
37
33
  @found_duplicate_library_name ||= false
38
34
  end
@@ -52,97 +48,20 @@ module DaVinciDTRTestKit
52
48
  extension_presence.each_key { |k| extension_presence[k] = false }
53
49
  end
54
50
 
55
- def questionnaire_extensions_test(response)
56
- resource = process_response(response)
57
- assert !resource.nil?, 'Response is null or not a valid type.'
58
- found_questionnaire = false
59
- if resource.instance_of? Array
60
- resource.each do |individual_resource|
61
- next unless individual_resource.resourceType == 'QuestionnaireResponse'
62
-
63
- individual_resource.contained.each_with_index do |questionnaire, q_index|
64
- # Do out put parameters have a bundle?
65
- next unless questionnaire.resourceType == 'Questionnaire'
66
-
67
- # check the libraries first so references in questionnaires can be checked after
68
- found_questionnaire = true
69
- check_questionnaire_extensions(questionnaire, q_index)
70
- end
71
- end
72
- elsif resource.resourceType == 'Parameters'
73
- resource.parameter.each do |param|
74
- # Do out put parameters have a bundle?
75
- next unless param.resource.resourceType == 'Bundle'
76
-
77
- param.resource.entry.each_with_index do |entry, q_index|
78
- # check questionnaire extensions
79
- next unless entry.resource.resourceType == 'Questionnaire'
80
-
81
- found_questionnaire = true
82
- check_questionnaire_extensions(entry.resource, q_index)
83
- ## NEED TO FIGURE OUT HOW TO FAIL TEST WHEN POORLY FORMATTED EXPRESSIONS FOUND
84
- end
85
- end
86
- end
51
+ def verify_questionnaire_extensions(questionnaires)
52
+ assert questionnaires&.any? && questionnaires.all? { |q| q.is_a? FHIR::Questionnaire }, 'No questionnaires found.'
53
+ questionnaires.each_with_index { |q, q_index| check_questionnaire_extensions(q, q_index) }
87
54
  check_library_references
88
- assert found_questionnaire, 'No questionnaires found.'
89
55
  assert extension_presence.value?(true), 'No extensions found. Questionnaire must demonstrate prepopulation.'
90
56
  assert cql_presence['variable'], 'Variable expression logic not written in CQL.'
91
57
  assert cql_presence['launch_context'], 'Launch context expression logic not written in CQL.'
92
58
  assert cql_presence['pop_context'], 'Population context expression logic not written in CQL.'
93
59
  end
94
60
 
95
- def questionnaire_items_test(response, final_cql_test)
96
- resource = process_response(response)
97
- assert !resource.nil?, 'Response is null or not a valid type.'
98
- found_bundle = found_questionnaire = false
99
- # are extensions present in any questionnaire?
100
- if resource.instance_of? Array
101
- resource.each_with_index do |individual_resource, q_index|
102
- next unless individual_resource.resourceType == 'QuestionnaireResponse'
103
-
104
- individual_resource.contained.each do |questionnaire|
105
- # Do out put parameters have a bundle?
106
- next unless questionnaire.resourceType == 'Questionnaire'
107
-
108
- # check the libraries first so references in questionnaires can be checked after
109
- found_questionnaire = true
110
- check_questionnaire_items(questionnaire, q_index)
111
- end
112
- end
113
- elsif resource.resourceType == 'Parameters'
114
- resource.parameter.each do |param|
115
- # Do out put parameters have a bundle?
116
- next unless param.resource.resourceType == 'Bundle'
117
-
118
- found_bundle = true
119
- # check the libraries first so references in questionnaires can be checked after
120
- param.resource.entry.each_with_index do |entry, q_index|
121
- if entry.resource.resourceType == 'Questionnaire'
122
- found_questionnaire = true
123
- check_questionnaire_items(entry.resource, q_index)
124
- end
125
- end
126
- end
127
- assert found_bundle, 'No questionnaire bundles found.'
128
- end
129
- begin
130
- assert found_questionnaire, 'No questionnaires found.'
131
- assert !found_non_cql_expression, 'Found non-cql expression.'
132
- assert !found_bad_library_reference, 'Found expression with no or incorrect reference to library name.'
133
- assert extension_presence.value?(true), 'No extensions found. Questionnaire must demonstrate prepopulation.'
134
- assert cql_presence['init_expression'], 'Initial expression logic not written in CQL.'
135
- assert cql_presence['candidate_expression'], 'Candidate expression logic not written in CQL.'
136
- assert cql_presence['context_expression'], 'Context expression logic not written in CQL.'
137
- ensure
138
- reset_cql_tests if final_cql_test
139
- end
140
- end
141
-
142
61
  def check_questionnaire_extensions(questionnaire, q_index)
143
62
  # are extensions present in this questionnaire?
144
63
  found_launch_context = found_variable = found_pop_context = found_cqf_lib = false
145
- cqf_count = 0
64
+ cqf_count = total_cqf_libs(questionnaire.extension)
146
65
  misformatted_expressions = []
147
66
  questionnaire.extension.each_with_index do |extension, index|
148
67
  if extension.url == 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-launchContext'
@@ -165,13 +84,35 @@ module DaVinciDTRTestKit
165
84
  end
166
85
  next unless extension.url == 'http://hl7.org/fhir/StructureDefinition/cqf-library'
167
86
 
168
- cqf_count += 1
169
87
  cqf_reference_libraries.add(extension.valueCanonical)
170
88
  found_cqf_lib = true
171
89
  extension_presence['found_min_cqf_lib'] = true
172
90
 
173
91
  check_for_cql(extension, '', index, q_index, extension.url)
174
92
  end
93
+ add_launch_context_messages(found_launch_context, found_variable, found_pop_context, found_cqf_lib, q_index)
94
+ return if cqf_count < 1
95
+
96
+ add_formatting_messages(misformatted_expressions, q_index)
97
+ assert misformatted_expressions.compact.empty?, 'Expression in questionnaire misformatted.'
98
+ end
99
+
100
+ def verify_questionnaire_items(questionnaires, final_cql_test: false)
101
+ assert questionnaires&.any? && questionnaires.all? { |q| q.is_a? FHIR::Questionnaire }, 'No questionnaires found.'
102
+ questionnaires.each_with_index { |q, q_index| check_questionnaire_items(q, q_index) }
103
+
104
+ begin
105
+ assert !found_non_cql_expression, 'Found non-cql expression.'
106
+ assert extension_presence.value?(true), 'No extensions found. Questionnaire must demonstrate prepopulation.'
107
+ assert cql_presence['init_expression'], 'Initial expression logic not written in CQL.'
108
+ assert cql_presence['candidate_expression'], 'Candidate expression logic not written in CQL.'
109
+ assert cql_presence['context_expression'], 'Context expression logic not written in CQL.'
110
+ ensure
111
+ reset_cql_tests if final_cql_test
112
+ end
113
+ end
114
+
115
+ def add_launch_context_messages(found_launch_context, found_variable, found_pop_context, found_cqf_lib, q_index)
175
116
  unless found_launch_context
176
117
  messages << { type: 'info',
177
118
  message: format_markdown("[questionnaire #{q_index + 1}] included no launch context.") }
@@ -186,19 +127,44 @@ module DaVinciDTRTestKit
186
127
  message: format_markdown("[questionnaire #{q_index + 1}]
187
128
  included no item population context.") }
188
129
  end
189
- unless found_cqf_lib
190
- messages << { type: 'info',
191
- message: format_markdown("[questionnaire #{q_index + 1}]
130
+ return if found_cqf_lib
131
+
132
+ messages << { type: 'info',
133
+ message: format_markdown("[questionnaire #{q_index + 1}]
192
134
  included no cqf library.") }
193
- end
194
- return if cqf_count < 1
135
+ end
195
136
 
137
+ def add_formatting_messages(misformatted_expressions, q_index)
196
138
  misformatted_expressions.compact.each do |idx|
197
139
  messages << { type: 'info',
198
140
  message: format_markdown("[expression #{idx + 1}] in [questionnaire #{q_index + 1}]
199
141
  does not begin with a reference to an included library name.") }
200
142
  end
201
- assert misformatted_expressions.compact.empty?, 'Expression in questionnaire misformatted.'
143
+ end
144
+
145
+ def total_cqf_libs(extensions)
146
+ cqf_count = 0
147
+ extensions.each do |extension|
148
+ next unless extension.url == 'http://hl7.org/fhir/StructureDefinition/cqf-library'
149
+
150
+ cqf_count += 1
151
+ end
152
+ cqf_count
153
+ end
154
+
155
+ def add_item_messages(found_item_expressions, q_index)
156
+ unless found_item_expressions['found_candidate_expression']
157
+ messages << { type: 'info',
158
+ message: format_markdown("[questionnaire #{q_index + 1}] included no candidate expression.") }
159
+ end
160
+ unless found_item_expressions['found_init_expression']
161
+ messages << { type: 'info',
162
+ message: format_markdown("[questionnaire #{q_index + 1}] included no initial expression.") }
163
+ end
164
+ return if found_item_expressions['found_context_expression']
165
+
166
+ messages << { type: 'info',
167
+ message: format_markdown("[questionnaire #{q_index + 1}] included no context expression.") }
202
168
  end
203
169
 
204
170
  def check_questionnaire_items(questionnaire, q_index)
@@ -206,13 +172,9 @@ module DaVinciDTRTestKit
206
172
  found_item_expressions = { 'found_init_expression' => false,
207
173
  'found_candidate_expression' => false,
208
174
  'found_context_expression' => false }
209
- cqf_count = 0
175
+ cqf_count = total_cqf_libs(questionnaire.extension)
210
176
  misformatted_expressions = []
211
- questionnaire.extension.each do |extension|
212
- next unless extension.url == 'http://hl7.org/fhir/StructureDefinition/cqf-library'
213
177
 
214
- cqf_count += 1
215
- end
216
178
  # check questionnaire items
217
179
  questionnaire.item.each_with_index do |item, index|
218
180
  misformatted_expressions.concat(check_nested_items(item, index, q_index, found_item_expressions, item.linkId))
@@ -222,18 +184,8 @@ module DaVinciDTRTestKit
222
184
  index, q_index, found_item_expressions, item.linkId)
223
185
  end
224
186
  end
225
- unless found_item_expressions['found_candidate_expression']
226
- messages << { type: 'info',
227
- message: format_markdown("[questionnaire #{q_index + 1}] included no candidate expression.") }
228
- end
229
- unless found_item_expressions['found_init_expression']
230
- messages << { type: 'info',
231
- message: format_markdown("[questionnaire #{q_index + 1}] included no initial expression.") }
232
- end
233
- unless found_item_expressions['found_context_expression']
234
- messages << { type: 'info',
235
- message: format_markdown("[questionnaire #{q_index + 1}] included no context expression.") }
236
- end
187
+ add_item_messages(found_item_expressions, q_index)
188
+ # only care about formatting when there are multiple cqf libs
237
189
  return if cqf_count < 1
238
190
 
239
191
  misformatted_expressions.compact.to_set.each do |idx|
@@ -244,51 +196,43 @@ module DaVinciDTRTestKit
244
196
  assert misformatted_expressions.compact.to_set.empty?, 'Expression in questionnaire misformatted.'
245
197
  end
246
198
 
247
- def check_libraries(payer_response)
248
- resource = process_response(payer_response)
249
- assert !resource.nil?, 'Response is null or not a valid type.'
250
- found_bundle = found_libraries = false
251
- # are extensions present in any questionnaire?
252
- resource.parameter.each do |param|
253
- # Do out put parameters have a bundle?
254
- next unless param.resource.resourceType == 'Bundle'
255
-
256
- found_bundle = true
257
- # check the libraries first so references in questionnaires can be checked after
258
- param.resource.entry.each_with_index do |entry, index|
259
- next unless entry.resource.resourceType == 'Library'
260
-
261
- found_libraries = true
262
- found_cql = found_elm = false
263
- library_urls.add(entry.resource.url) unless entry.resource.url.nil?
264
- entry.resource.content.each do |content|
265
- if content.data.nil?
266
- messages << { type: 'info',
267
- message: format_markdown("[library #{index + 1}] content element included no data.") }
268
- end
269
- if content.contentType == 'text/cql'
270
- found_cql = true
271
- elsif content.contentType == 'application/elm+json'
272
- found_elm = true
273
- else
274
- messages << { type: 'info',
275
- message: format_markdown("[library #{index + 1}] has non-cql/elm content.") }
276
- true
277
- end
278
- next unless library_names.include? entry.resource.name
279
-
280
- found_duplicate_library_name = true
281
- messages << { type: 'info', message: format_markdown("[library #{index + 1}] has a name,
282
- #{entry.resource.name}, that is already included in the bundle.") }
283
- assert !found_duplicate_library_name, 'Found duplicate library names - all names must be unique.'
284
- end
285
- library_names.add(entry.resource.name)
286
- assert found_cql, "[library #{index + 1}] does not include CQL."
287
- assert found_elm, "[library #{index + 1}] does not include ELM."
199
+ def evaluate_library(library)
200
+ found_cql = found_elm = false
201
+ library.content.each do |content|
202
+ if content.data.nil?
203
+ messages << { type: 'info',
204
+ message: format_markdown("[library #{library.url}] content element included no data.") }
205
+ end
206
+ if content.contentType == 'text/cql'
207
+ found_cql = true
208
+ elsif content.contentType == 'application/elm+json'
209
+ found_elm = true
210
+ else
211
+ messages << { type: 'info',
212
+ message: format_markdown("[library #{library.url}] has non-cql/elm content.") }
213
+ true
288
214
  end
289
- assert found_libraries, 'No Libraries found.'
215
+ next unless library_names.include? library.name
216
+
217
+ found_duplicate_library_name = true
218
+ messages << { type: 'info', message: format_markdown("[library #{library.url}] has a name,
219
+ #{library.name}, that is already included in the bundle.") }
220
+ assert !found_duplicate_library_name, 'Found duplicate library names - all names must be unique.'
221
+ end
222
+ assert found_cql, "[library #{library.url}] does not include CQL."
223
+ assert found_elm, "[library #{library.url}] does not include ELM."
224
+ end
225
+
226
+ def check_libraries(questionnaire_bundles)
227
+ libraries = extract_libraries_from_bundles(questionnaire_bundles)
228
+
229
+ assert libraries.any?, 'No Libraries found.'
230
+
231
+ libraries.each do |lib|
232
+ library_urls.add(lib.url) unless lib.url.nil?
233
+ evaluate_library(lib)
234
+ library_names.add(lib.name)
290
235
  end
291
- assert found_bundle, 'No questionnaire bundles found.'
292
236
  end
293
237
 
294
238
  def check_library_references
@@ -364,24 +308,22 @@ module DaVinciDTRTestKit
364
308
  end
365
309
  end
366
310
 
367
- def process_response(response)
368
- if response.instance_of?(FHIR::Parameters) || response.instance_of?(FHIR::QuestionnaireResponse)
369
- return response
370
- elsif response.instance_of? Array
371
- questionnaire_responses = []
372
- response.each do |resource|
373
- fhir_resource = FHIR.from_contents(resource.response_body)
374
- questionnaire_responses << fhir_resource if fhir_resource.resourceType == 'QuestionnaireResponse'
375
- next unless resource.instance_of? Inferno::Entities::Request
376
-
377
- if fhir_resource.resourceType == 'Questionnaire' || fhir_resource.resourceType == 'Parameters'
378
- return fhir_resource
379
- end
380
- end
381
- return questionnaire_responses
382
- end
311
+ def extract_contained_questionnaires(questionnaire_responses)
312
+ questionnaire_responses&.filter_map do |qr|
313
+ qr.contained&.filter { |resource| resource.is_a?(FHIR::Questionnaire) }
314
+ end&.flatten&.compact
315
+ end
316
+
317
+ def extract_questionnaires_from_bundles(questionnaire_bundles)
318
+ questionnaire_bundles.filter_map do |qb|
319
+ qb.entry.filter_map { |entry| entry.resource if entry.resource.is_a?(FHIR::Questionnaire) }
320
+ end&.flatten&.compact
321
+ end
383
322
 
384
- nil
323
+ def extract_libraries_from_bundles(questionnaire_bundles)
324
+ questionnaire_bundles.filter_map do |qb|
325
+ qb.entry.filter_map { |entry| entry.resource if entry&.resource.is_a?(FHIR::Library) }
326
+ end&.flatten&.compact
385
327
  end
386
328
  end
387
329
  end
@@ -0,0 +1,25 @@
1
+ module DaVinciDTRTestKit
2
+ module CreateTest
3
+ def perform_create_test(create_resources, resource_type)
4
+ skip_if(create_resources.blank?, "No `#{resource_type}` resources to create provided, skipping test.")
5
+ assert_valid_json(create_resources)
6
+ create_resources_list = JSON.parse(create_resources)
7
+ skip_if(!create_resources_list.is_a?(Array), 'Resources to create not inputted in list format, skipping test.')
8
+
9
+ valid_create_resources =
10
+ create_resources_list
11
+ .compact_blank
12
+ .map { |resource| FHIR.from_contents(resource.to_json) }
13
+ .select { |resource| resource.resourceType == resource_type }
14
+ .select { |resource| resource_is_valid?(resource:) }
15
+
16
+ skip_if(valid_create_resources.blank?,
17
+ %(No valid #{resource_type} resources were provided to send in Create requests, skipping test.))
18
+
19
+ valid_create_resources.each do |create_resource|
20
+ fhir_create(create_resource)
21
+ assert_response_status(201)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -13,32 +13,38 @@ requirements and may change the test validation logic.
13
13
  ## Test Methodology
14
14
 
15
15
  Inferno will simulate a DTR payer server that will response to
16
- requests for questionnaires for the EHR under test to interact with.
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
- course of these interactions, Inferno will seek to observe conformant handling of
18
+ course of these interactions, Inferno will seek to observe conformant handling of
19
19
  DTR workflows and requirements around the retrieval, completion, and storage of
20
20
  questionnaires.
21
21
 
22
22
  Tests within this suite are associated with specific questionnaires that the EHR will
23
23
  demonstrate completion of. In each case, the EHR under test will initiate a request to
24
- the payer server simulated by Inferno for a questionnaire using the
24
+ the payer server simulated by Inferno for a questionnaire using the
25
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 it must
27
- be conformant. The EHR will then be asked to complete the questionnaire, including
28
- - Pre-populating answers based on directives in the 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:
29
+
30
+ - Pre-populating answers based on directives in the questionnaire.
29
31
  - Rendering the questionnaire for users and allowing them to make additional updates.
30
32
  These tests can include specific directions on details to include in the completed
31
33
  questionnaire.
34
+ - For adaptive questionnaires only, getting additional questions using the `$next-question`
35
+ operation until the questionnaire is complete.
32
36
  - Storing the completed questionnaire for future use as a FHIR QuestionnaireResponse.
33
37
 
34
38
  EHRs will be required to complete all questionnaires in the suite, which in aggregate
35
39
  contain all questionnaire features that apps must support. Currently, the suite includes
36
40
  one questionnaire:
37
- 1. A fictious "dinner" questionnaire created for these tests. It tests basic
38
- item rendering and pre-population.
39
- Additional questionnaires will be added in the future.
40
41
 
41
- All requests sent by the app will be checked
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.
44
+
45
+ Additional questionnaires covering further features will be added in the future.
46
+
47
+ All requests sent by the app will be checked
42
48
  for conformance to the DTR IG requirements individually and used in aggregate to determine
43
49
  whether required features and functionality are present. HL7® FHIR® resources are
44
50
  validated with the Java validator using `tx.fhir.org` as the terminology server.
@@ -49,28 +55,28 @@ validated with the Java validator using `tx.fhir.org` as the terminology server.
49
55
 
50
56
  In order to run these tests, EHRs must be configured to interact with Inferno's simulated
51
57
  payer server endpoint. The endpoint will be `[URL prefix]/custom/dtr_full_ehr/fhir` where
52
- `[URL prefix]` can be inferred from the URL of the test session which will be of the form
58
+ `[URL prefix]` can be inferred from the URL of the test session which will be of the form
53
59
  `[URL prefix]/dtr_full_ehr/[session id]`.
54
60
 
55
61
  In order for Inferno to associate requests sent to locations under these base URLs with this session,
56
- it needs to know the bearer token that the EHR will send on requests, for which
62
+ it needs to know the bearer token that the EHR will send on requests, for which
57
63
  there are two options.
58
64
 
59
65
  1. If you want to choose your own bearer token, then
60
- 1. Select the "2. Basic Workflows" test from the list on the left (or other target test).
61
- 2. Click the '*Run All Tests*' button on the right.
62
- 3. In the "access_token" field, enter the bearer token that will be sent by the client
63
- under test (as part of the Authorization header - `Bearer <provided value>`).
64
- 4. Click the '*Submit*' button at the bottom of the dialog.
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.
65
71
  2. If you want to use a client_id to obtain an access token, then
66
- 1. Click the '*Run All Tests*' button on the right.
67
- 2. Provide the EHR's registered id "client_id" field of the input (NOTE, Inferno
68
- doesn't support the registration API, so this must be obtained from another
69
- system or configured manually).
70
- 3. Click the '*Submit*' button at the bottom of the dialog.
71
- 4. Make a token request that includes the specified client id to the
72
- `[URL prefix]/custom/dtr_full_ehr/mock_auth/token` endpoint to get
73
- an access token to use on the request of the requests.
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.
74
80
 
75
81
  In either case, the tests will continue from that point. Further executions of tests under
76
82
  this session will also use the selected bearer token.
@@ -85,21 +91,30 @@ to make requests against Inferno. This does not include the capability to render
85
91
  questionnaires, but does have samples of correctly and incorrectly completed QuestionnaireResponses.
86
92
  To run the tests using this approach:
87
93
 
94
+ #### Setup
88
95
  1. Install [postman](https://www.postman.com/downloads/).
89
96
  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
+
98
+ #### Startup
90
99
  1. Start a Da Vinci DTR Full EHR Test Suite Session.
91
100
  1. Update the postman collection configuration variables found by opening the "DTR Full EHR
92
101
  Tests Postman Demo" collection and selecting the "Variables" tab.
93
- - **base_url**: corresponds to the where the test suite session is running. Defaults to
94
- `inferno.healthit.gov`. If running in another location, see guidance on the "Overview" tab
95
- of the postman collection.
102
+ - **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
104
+ of the postman collection.
96
105
  - **access_token**: note the "Current value" (update if desired) for use later.
97
- 1. Return to Inferno and in the test list at the left, select *2 Static Questionnaire Workflow*.
106
+
107
+ #### Dinner Questionnaire (Standard)
108
+
109
+ For the standard (static) questionnaire demo, use the requests in the _Static Dinner_ folder in the
110
+ Postman collection.
111
+
112
+ 1. Return to the Inferno test session and in the test list at the left, select _2 Static Questionnaire Workflow_.
98
113
  1. Click the "Run All Tests" button in the upper right.
99
114
  1. Add the **access_token** configured in postman to the Inferno input with the same name
100
115
  1. Click the "Submit" button in Inferno.
101
116
  1. Attest that the EHR has launched its DTR workflow in Inferno by clicking the link for the **true** response.
102
- 1. Once the next wait dialog has appeared within Inferno asking for a `$questionnaire-package`
117
+ 1. Once the next wait dialog has appeared within Inferno asking for a `$questionnaire-package`
103
118
  request, use postman to submit the "Questionnaire Package for Dinner (Static)" request. Confirm
104
119
  that the response that looks similar to the "Example Working Response" in postman
105
120
  and click the link to continue the tests.
@@ -107,21 +122,64 @@ To run the tests using this approach:
107
122
  with an actual EHR implementation. To see what a valid QuestionnaireResponse looks like, see
108
123
  the "Sample QuestionnaireResponse for Dinner (Static) ..." request in postman.
109
124
 
125
+ #### Dinner Questionnaire (Adaptive)
126
+
127
+ For the adaptive questionnaire demo, use the requests in the _Adaptive Dinner_ folder in the
128
+ Postman collection.
129
+
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.
134
+ 1. Attest that the EHR has launched its DTR workflow in Inferno by clicking the link for the **true** response.
135
+ 1. Once the **Adaptive Questionnaire Retrieval** wait dialog has appeared within Inferno asking
136
+ for `$questionnaire-package` and `$next-question`
137
+ requests, use postman to submit the "Questionnaire Package for Dinner" request followed by the
138
+ "Initial Next Question" request. Confirm
139
+ that the response that looks similar to the "Example Response" in postman
140
+ and click the link to continue the tests.
141
+ 1. Attest to the next several attestation wait dialogs as desired to get a sense for what is involved
142
+ in testing with an actual EHR implementation.
143
+ 1. Once the **Follow-up Next Question Request** wait dialog has appeared within Inferno asking for
144
+ another `$next-question` request, use postman to submit the "Second Next Question" request. Confirm
145
+ that the response that looks similar to the "Example Response" in postman
146
+ and click the link to continue the tests.
147
+ 1. Once the **Last Next Question Request** wait dialog has appeared within Inferno asking for
148
+ another `$next-question` request, use postman to submit the "Final Next Question" request. Confirm
149
+ that the response that looks similar to the "Example Response" in postman
150
+ and click the link to continue the tests.
151
+
110
152
  ## Limitations
111
153
 
112
154
  The DTR IG is a complex specification and these tests currently validate conformance to only
113
155
  a subset of IG requirements. Future versions of the test suite will test further
114
156
  features. A few specific features of interest are listed below.
115
157
 
116
- ### Heavy Reliance on Attestations
158
+ ### Questionnaire Response Verification
159
+
160
+ Currently, these test kits do not have enough information about the data stored on
161
+ the EHR to evaluate whether CQL evaluation populated data correctly. However, Inferno
162
+ does ask testers to make sure that the target patient meets certain requirements and
163
+ directs them to perform certain actions while filling out forms that allow Inferno to
164
+ check that calculation is occuring and that the system is correctly keeping track of
165
+ items that were pre-populated. This approach may change in future versions of these tests.
166
+
167
+ ### Questionnaire Response Access
168
+
169
+ For standard (static) questionnaires, Full EHRs are not required by the DTR specification
170
+ to store or expose the completed form as a FHIR QuestionnaireResponse instance, though they
171
+ are required to store the form in some way and be able to send the QuestionnaireResponse
172
+ representation to other systems. Currently, testers are required to provide a
173
+ QuestionnaireResponse as an input to the tests once they have completed their workflow.
174
+ Future versions of these tests will provide additional options for making that information
175
+ available that are more in-line with expected system capabilities.
117
176
 
118
- Currently, these test kits do not have access to the QuestionnaireResponse and so validation
119
- that the EHR performed CQL calculations and generated a conformant QuestionnaireResponse
120
- based on pre-population and manual answers is left to a user attestation rather than a
121
- mechanical check. Some level of mechanical checks are expected to be added in the future.
177
+ For adaptive questionnaires, the completed QuestionnaireResponse will be present in the
178
+ last `$next-question` invocation by the EHR, so this limitation does not apply to those
179
+ cases.
122
180
 
123
181
  ### Questionnaire Feature Coverage
124
182
 
125
183
  Not all questionnaire features that are must support within the DTR IG are currently represented
126
- in questionnaires tested by the IG. Adaptive questionnaires are a notable omission.
127
- Additional questionnaires testing additional features will be added in the future.
184
+ in questionnaires tested by the IG. Additional questionnaires testing additional features will
185
+ be added in the future.
@@ -0,0 +1,34 @@
1
+ The Da Vinci DTR Test Kit Light EHR Suite validates the conformance of SMART apps
2
+ to the STU 2 version of the HL7® FHIR®
3
+ [Da Vinci Documentation Templates and Rules (DTR) Implementation Guide](https://hl7.org/fhir/us/davinci-dtr/STU2/).
4
+
5
+ ## Scope
6
+
7
+ These tests are a **DRAFT** intended to allow app implementers to perform
8
+ preliminary checks of their systems against DTR IG requirements and [provide
9
+ feedback](https://github.com/inferno-framework/davinci-dtr-test-kit/issues)
10
+ on the tests. Future versions of these tests may validate other
11
+ requirements and may change the test validation logic.
12
+
13
+ ## Test Methodology
14
+
15
+ Inferno will simulate a DTR SMART App that will connect to the DTR Light EHR system under test. The tester will need to launch Inferno using either an EHR launch or a Standalone launch. Once the connection between Inferno's simulated DTR SMART App and the DTR Light EHR under test is established, tests within this suite will make FHIR API requests corresponding to capabilities required by the [Light DTR EHR Capability Statement](https://hl7.org/fhir/us/davinci-dtr/STU2/CapabilityStatement-light-dtr-ehr) and check that the EHR's responses are conformant.
16
+
17
+ ## Running the Tests
18
+
19
+ If you would like to try out the tests but don't have a DTR Light EHR implementation, you can run these tests against the [public instance of the Inferno Reference Server](https://inferno.healthit.gov/reference-server/r4/) by using the Inferno Reference Server preset in the test suite. In order to get the Inferno Reference Server to do an EHR launch, navigate to https://inferno.healthit.gov/reference-server/app/app-launch and use https://inferno.healthit.gov/suites/custom/smart/launch as the App Launch URL. When using the Inferno Reference Server preset for the DTR Light EHR test suite, note that the sample patient used for testing (`dtr_bundle_patient_pat015.json`) is focused on DTR-specific data and does not have the complete set of US Core data needed to pass all the US Core tests. In addition, this preset does not test the `create` or `update` tests for DTR QuestionnaireResponse resources and PAS Task resources.
20
+
21
+ ## Limitations
22
+
23
+ The DTR IG is a complex specification and these tests currently validate conformance to only
24
+ a subset of IG requirements. Future versions of the test suite will test further
25
+ features.
26
+
27
+ ## DTR 2.0.1 Corrections
28
+
29
+ The DTR 2.0.1 version of the [Light EHR CapabilityStatement](http://hl7.org/fhir/us/davinci-dtr/CapabilityStatement/light-dtr-ehr) includes two pieces of missing or misleading information that have been corrected:
30
+
31
+ - The 2.0.1 CapabilityStatement indicates that support for the [Coverage resource type](https://hl7.org/fhir/us/davinci-dtr/STU2/CapabilityStatement-light-dtr-ehr.html#coverage) is required when the [QuestionnaireResponse resource type was intended](https://build.fhir.org/ig/HL7/davinci-dtr/CapabilityStatement-light-dtr-ehr-311.html#questionnaireresponse) (note specifically that the `context` search parameters are not present on the Coverage resource type but is on the QuestionnaireResponse resource type).
32
+ - The 2.0.1 CapabilityStatement does not indicate a target profile for the [Task resource type](https://hl7.org/fhir/us/davinci-dtr/STU2/CapabilityStatement-light-dtr-ehr.html#task) but the current version [clarifies](https://build.fhir.org/ig/HL7/davinci-dtr/CapabilityStatement-light-dtr-ehr-311.html#task) that the [PAS Task Profile](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-task) is intended.
33
+
34
+ This test suite verifies systems according to these corrections. Additionally, it verifies the `read` interaction for the Coverage resource type.