davinci_dtr_test_kit 0.10.0 → 0.11.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_dinner_questionnaire_package_request_test.rb +134 -0
  3. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_questionnaire_response_save_test.rb +2 -2
  4. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_smart_app_questionnaire_workflow_group.rb +3 -2
  5. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/prepopulation_attestation_test.rb +4 -4
  6. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/prepopulation_override_attestation_test.rb +4 -4
  7. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/rendering_enabled_questions_attestation_test.rb +4 -4
  8. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_package_group.rb +2 -2
  9. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_rendering_attestation_test.rb +4 -4
  10. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_response_save_test.rb +2 -2
  11. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_resp_questionnaire_package_request_test.rb +132 -0
  12. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_smart_app_questionnaire_workflow_group.rb +4 -3
  13. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_pre_population_test.rb +1 -0
  14. data/lib/davinci_dtr_test_kit/docs/dtr_payer_server_suite_description_v201.md +2 -2
  15. data/lib/davinci_dtr_test_kit/docs/dtr_smart_app_suite_description_v201.md +106 -42
  16. data/lib/davinci_dtr_test_kit/dtr_full_ehr_suite.rb +4 -3
  17. data/lib/davinci_dtr_test_kit/dtr_payer_server_suite.rb +6 -4
  18. data/lib/davinci_dtr_test_kit/dtr_questionnaire_response_validation.rb +26 -10
  19. data/lib/davinci_dtr_test_kit/dtr_smart_app_suite.rb +33 -11
  20. data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_hamburger.json +1 -1
  21. data/lib/davinci_dtr_test_kit/fixtures/dinner_static/questionnaire_dinner_order_static.json +2 -2
  22. data/lib/davinci_dtr_test_kit/fixtures/questionnaire_package.json +1 -1
  23. data/lib/davinci_dtr_test_kit/mock_auth_server.rb +145 -0
  24. data/lib/davinci_dtr_test_kit/mock_ehr.rb +37 -12
  25. data/lib/davinci_dtr_test_kit/mock_payer.rb +1 -20
  26. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_request_validation_test.rb +1 -0
  27. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_response_validation_test.rb +1 -0
  28. data/lib/davinci_dtr_test_kit/urls.rb +14 -3
  29. data/lib/davinci_dtr_test_kit/validation_test.rb +1 -0
  30. data/lib/davinci_dtr_test_kit/version.rb +1 -1
  31. metadata +19 -3
  32. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_package_request_test.rb +0 -36
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'urls'
4
+
3
5
  module DaVinciDTRTestKit
4
6
  module MockEHR
5
7
  RESOURCE_SERVER_BASE = ENV.fetch('FHIR_REFERENCE_SERVER')
6
8
  RESOURCE_SERVER_BEARER_TOKEN = 'SAMPLE_TOKEN'
7
9
 
8
- RESPONSE_HEADERS = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }.freeze
10
+ RESPONSE_HEADERS = { 'Content-Type' => 'application/json', 'Access-Control-Allow-Origin' => '*' }.freeze
9
11
 
10
12
  def resource_server_client
11
13
  return @resource_server_client if @resource_server_client
@@ -18,13 +20,13 @@ module DaVinciDTRTestKit
18
20
  def metadata_handler(_env)
19
21
  cs = resource_server_client.capability_statement
20
22
  if cs.present?
21
- [200, { 'Content-Type' => 'application/json', 'Access-Control-Allow-Origin' => '*' }, [cs.to_json]]
23
+ [200, RESPONSE_HEADERS, [cs.to_json]]
22
24
  else
23
25
  [500, {}, ['Unexpected error occurred while fetching metadata']]
24
26
  end
25
27
  end
26
28
 
27
- def get_fhir_resource(request, _test = nil, _test_result = nil)
29
+ def get_fhir_resource(request, _test = nil, test_result = nil)
28
30
  resource_type, id = resource_type_and_id_from_url(request.url)
29
31
  request.response_headers = RESPONSE_HEADERS
30
32
 
@@ -34,15 +36,7 @@ module DaVinciDTRTestKit
34
36
  resource_type = nil
35
37
  end
36
38
 
37
- if resource_type.present?
38
- response = if id.present?
39
- resource_server_client.read(fhir_class, id)
40
- else
41
- resource_server_client.search(fhir_class, search: { parameters: request.query_parameters })
42
- end
43
- request.status = response.code
44
- request.response_body = response.body
45
- else
39
+ if resource_type.blank?
46
40
  request.status = 400
47
41
  request.response_headers = { 'Content-Type': 'application/json' }
48
42
  request.response_body = FHIR::OperationOutcome.new(
@@ -51,7 +45,38 @@ module DaVinciDTRTestKit
51
45
  text: 'No recognized resource type in URL'
52
46
  ))
53
47
  ).to_json
48
+ return
49
+ end
50
+
51
+ # Respond with user-inputted resource if there is one that matches the request
52
+ begin
53
+ ehr_bundle_input = JSON.parse(test_result.input_json).find { |input| input['name'] == 'ehr_bundle' }
54
+ ehr_bundle_input_value = ehr_bundle_input_value = ehr_bundle_input['value'] if ehr_bundle_input.present?
55
+ ehr_bundle = FHIR.from_contents(ehr_bundle_input_value) if ehr_bundle_input_value.present?
56
+ rescue StandardError
57
+ ehr_bundle = nil
58
+ end
59
+
60
+ if id.present? && ehr_bundle.present? && ehr_bundle.is_a?(FHIR::Bundle)
61
+ matching_resource = ehr_bundle.entry&.find do |entry|
62
+ entry.resource.is_a?(fhir_class) && entry.resource&.id == id
63
+ end&.resource
64
+ if matching_resource.present?
65
+ request.status = 200
66
+ request.response_headers = { 'Content-Type': 'application/json' }
67
+ request.response_body = matching_resource.to_json
68
+ return
69
+ end
54
70
  end
71
+
72
+ # Proxy resource request to the reference server
73
+ response = if id.present?
74
+ resource_server_client.read(fhir_class, id)
75
+ else
76
+ resource_server_client.search(fhir_class, search: { parameters: request.query_parameters })
77
+ end
78
+ request.status = response.code
79
+ request.response_body = response.body
55
80
  end
56
81
 
57
82
  def questionnaire_response_response(request, _test = nil, _test_result = nil)
@@ -6,13 +6,7 @@ module DaVinciDTRTestKit
6
6
  module MockPayer
7
7
  include Fixtures
8
8
 
9
- RESPONSE_HEADERS = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }.freeze
10
-
11
- def token_response(request, _test = nil, _test_result = nil)
12
- # Placeholder for a more complete mock token endpoint
13
- request.response_body = { access_token: SecureRandom.hex, token_type: 'bearer', expires_in: 300 }.to_json
14
- request.status = 200
15
- end
9
+ RESPONSE_HEADERS = { 'Content-Type' => 'application/json', 'Access-Control-Allow-Origin' => '*' }.freeze
16
10
 
17
11
  def questionnaire_package_response(request, _test = nil, test_result = nil)
18
12
  request.status = 200
@@ -47,19 +41,6 @@ module DaVinciDTRTestKit
47
41
  request.response_body = payer_response.response[:body]
48
42
  end
49
43
 
50
- def extract_client_id(request)
51
- URI.decode_www_form(request.request_body).to_h['client_id']
52
- end
53
-
54
- # Header expected to be a bearer token of the form "Bearer: <token>"
55
- def extract_bearer_token(request)
56
- request.request_header('Authorization')&.value&.split&.last
57
- end
58
-
59
- def extract_token_from_query_params(request)
60
- request.query_parameters['token']
61
- end
62
-
63
44
  def test_resumes?(test)
64
45
  !test.config.options[:accepts_multiple_requests]
65
46
  end
@@ -37,6 +37,7 @@ module DaVinciDTRTestKit
37
37
  else
38
38
  # TODO: fix redundant logic here
39
39
  skip_if initial_static_questionnaire_request.nil?, 'No request resource was provided - required for manual flow'
40
+ assert_valid_json(initial_static_questionnaire_request)
40
41
  request = FHIR.from_contents(initial_static_questionnaire_request)
41
42
  assert assert_valid_resource(resource: request, profile_url: 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-input-parameters')
42
43
  end
@@ -36,6 +36,7 @@ module DaVinciDTRTestKit
36
36
  request = fhir_operation("#{url}/Questionnaire/$questionnaire-package",
37
37
  body: JSON.parse(initial_static_questionnaire_request),
38
38
  headers: { 'Content-Type': 'application/json' })
39
+ assert_valid_json(request.response[:body])
39
40
  resource = FHIR.from_contents(request.response[:body])
40
41
  scratch[:output_parameters] = resource
41
42
  assert_response_status([200, 201], response: request.response)
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DaVinciDTRTestKit
4
- TOKEN_PATH = '/mock_auth/token'
4
+ SMART_CONFIG_PATH = '/fhir/.well-known/smart-configuration'
5
+ EHR_AUTHORIZE_PATH = '/mock_ehr_auth/authorize'
6
+ EHR_TOKEN_PATH = '/mock_ehr_auth/token'
7
+ PAYER_TOKEN_PATH = '/mock_payer_auth/token'
5
8
  QUESTIONNAIRE_PACKAGE_PATH = '/fhir/Questionnaire/$questionnaire-package'
6
9
  NEXT_PATH = '/fhir/Questionnaire/$next-question'
7
10
  QUESTIONNAIRE_RESPONSE_PATH = '/fhir/QuestionnaireResponse'
@@ -15,8 +18,16 @@ module DaVinciDTRTestKit
15
18
  @base_url ||= "#{Inferno::Application['base_url']}/custom/#{suite_id}"
16
19
  end
17
20
 
18
- def token_url
19
- @token_url ||= base_url + TOKEN_PATH
21
+ def ehr_authorize_url
22
+ @ehr_authorize_url ||= base_url + EHR_AUTHORIZE_PATH
23
+ end
24
+
25
+ def ehr_token_url
26
+ @ehr_token_url ||= base_url + EHR_TOKEN_PATH
27
+ end
28
+
29
+ def payer_token_url
30
+ @payer_token_url ||= base_url + PAYER_TOKEN_PATH
20
31
  end
21
32
 
22
33
  def questionnaire_package_url
@@ -60,6 +60,7 @@ module DaVinciDTRTestKit
60
60
  omit_if resources.blank?,
61
61
  "No #{resource_type} resources provided so the #{profile_url} profile does not apply"
62
62
  resources.each_with_index do |resource, index|
63
+ assert_valid_json(resource.response[:body])
63
64
  fhir_resource = FHIR.from_contents(resource.response[:body])
64
65
  assert_response_status([200, 202], request: resource, response: resource.response)
65
66
  validate_resource(fhir_resource, resource_type, profile_url, index)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DaVinciDTRTestKit
4
- VERSION = '0.10.0'
4
+ VERSION = '0.11.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: davinci_dtr_test_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karl Naden
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-07-08 00:00:00.000000000 Z
13
+ date: 2024-07-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: inferno_core
@@ -26,6 +26,20 @@ dependencies:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
28
  version: 0.4.37
29
+ - !ruby/object:Gem::Dependency
30
+ name: jwt
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '2.6'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '2.6'
29
43
  description: Test Kit for the Da Vinci Documentation Templates and Rules (DTR) FHIR
30
44
  Implementation Guide
31
45
  email:
@@ -40,6 +54,7 @@ files:
40
54
  - lib/davinci_dtr_test_kit/auth_groups/token_request_test.rb
41
55
  - lib/davinci_dtr_test_kit/auth_groups/token_validation_test.rb
42
56
  - lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_smart_app_questionnaire_workflow_group.rb
57
+ - lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_dinner_questionnaire_package_request_test.rb
43
58
  - lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_questionnaire_response_save_test.rb
44
59
  - lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_smart_app_questionnaire_workflow_group.rb
45
60
  - lib/davinci_dtr_test_kit/client_groups/dinner_static/prepopulation_attestation_test.rb
@@ -51,8 +66,8 @@ files:
51
66
  - lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_rendering_group.rb
52
67
  - lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_response_group.rb
53
68
  - lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_response_save_test.rb
69
+ - lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_resp_questionnaire_package_request_test.rb
54
70
  - lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_smart_app_questionnaire_workflow_group.rb
55
- - lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_package_request_test.rb
56
71
  - lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_package_request_validation_test.rb
57
72
  - lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_basic_conformance_test.rb
58
73
  - lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_pre_population_test.rb
@@ -77,6 +92,7 @@ files:
77
92
  - lib/davinci_dtr_test_kit/fixtures/dinner_static/questionnaire_response_dinner_order_static.json
78
93
  - lib/davinci_dtr_test_kit/fixtures/pre_populated_questionnaire_response.json
79
94
  - lib/davinci_dtr_test_kit/fixtures/questionnaire_package.json
95
+ - lib/davinci_dtr_test_kit/mock_auth_server.rb
80
96
  - lib/davinci_dtr_test_kit/mock_ehr.rb
81
97
  - lib/davinci_dtr_test_kit/mock_payer.rb
82
98
  - lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_libraries_test.rb
@@ -1,36 +0,0 @@
1
- require_relative '../../urls'
2
-
3
- module DaVinciDTRTestKit
4
- class DTRQuestionnairePackageRequestTest < Inferno::Test
5
- include URLs
6
-
7
- id :dtr_questionnaire_package_request
8
- title 'Invoke the DTR Questionnaire Package operation'
9
- description %(
10
- Inferno will wait for a DTR questionnaire package request from the client. Upon receipt, Inferno will generate and
11
- send a response.
12
- )
13
- input :access_token
14
-
15
- run do
16
- wait(
17
- identifier: access_token,
18
- message: %(
19
- Invoke the DTR Questionnaire Package operation by sending a POST request to
20
-
21
- `#{questionnaire_package_url}`
22
-
23
- A questionnaire package generated by Inferno will be returned.
24
-
25
- Inferno will wait for the client to complete Questionnaire pre-population. The client should make FHIR GET
26
- requests using service base path:
27
-
28
- `#{fhir_base_url}`
29
-
30
- When the DTR application has finished loading the Questionnaire,
31
- [Click here](#{resume_pass_url}?token=#{access_token}) to continue.
32
- )
33
- )
34
- end
35
- end
36
- end