From 825c9427ca96b7d52a96ed1e599be6cd1d1c6ac1 Mon Sep 17 00:00:00 2001 From: Stephen MacVicar Date: Tue, 5 Nov 2024 10:11:19 -0500 Subject: [PATCH 1/6] update inferno core requirement --- davinci_dtr_test_kit.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/davinci_dtr_test_kit.gemspec b/davinci_dtr_test_kit.gemspec index f12307c..9b2eba0 100644 --- a/davinci_dtr_test_kit.gemspec +++ b/davinci_dtr_test_kit.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |spec| spec.description = 'Test Kit for the Da Vinci Documentation Templates and Rules (DTR) FHIR Implementation Guide' spec.homepage = 'https://github.com/inferno-framework/davinci-dtr-test-kit' spec.license = 'Apache-2.0' - spec.add_dependency 'inferno_core', '~> 0.4.42' + spec.add_dependency 'inferno_core', '~> 0.5.0' spec.add_dependency 'jwt', '~> 2.6' spec.add_dependency 'smart_app_launch_test_kit', '~> 0.4.4' spec.required_ruby_version = Gem::Requirement.new('>= 3.1.2') From 586e8e5bc3267d356257f67188024affa7615420 Mon Sep 17 00:00:00 2001 From: Stephen MacVicar Date: Tue, 5 Nov 2024 10:12:13 -0500 Subject: [PATCH 2/6] update dependencies --- Gemfile.lock | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index f909878..b1a00c9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,14 +2,14 @@ PATH remote: . specs: davinci_dtr_test_kit (0.12.0) - inferno_core (~> 0.4.42) + inferno_core (~> 0.5.0) jwt (~> 2.6) smart_app_launch_test_kit (~> 0.4.4) GEM remote: https://rubygems.org/ specs: - activesupport (6.1.7.8) + activesupport (6.1.7.10) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -66,7 +66,7 @@ GEM zeitwerk (~> 2.6) factory_bot (6.4.6) activesupport (>= 5.0.0) - faraday (1.10.3) + faraday (1.10.4) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -89,13 +89,13 @@ GEM faraday-patron (1.0.0) faraday-rack (1.0.0) faraday-retry (1.0.3) - faraday_middleware (1.2.0) + faraday_middleware (1.2.1) faraday (~> 1.0) - fhir_client (5.0.3) + fhir_client (6.0.0) activesupport (>= 3) addressable (>= 2.3) fhir_dstu2_models (>= 1.1.1) - fhir_models (>= 4.2.1) + fhir_models (>= 5.0.0) fhir_stu3_models (>= 3.1.1) nokogiri (>= 1.10.4) oauth2 (~> 1.1) @@ -107,7 +107,7 @@ GEM date_time_precision (>= 0.8) mime-types (>= 3.0) nokogiri (>= 1.11.4) - fhir_models (4.3.0) + fhir_models (5.0.0) bcp47 (>= 0.3) date_time_precision (>= 0.8) mime-types (>= 3.0) @@ -127,7 +127,7 @@ GEM mustermann (~> 1.0) mustermann-contrib (~> 1.0) rack (~> 2.0) - hanami-utils (2.1.0) + hanami-utils (2.2.0) concurrent-ruby (~> 1.0) dry-core (~> 1.0, < 2) dry-transformer (~> 1.0, < 2) @@ -139,7 +139,7 @@ GEM httpclient (2.8.3) i18n (1.14.6) concurrent-ruby (~> 1.0) - inferno_core (0.4.42) + inferno_core (0.5.0) activesupport (~> 6.1.7.5) base62-rb (= 0.3.1) blueprinter (= 0.25.2) @@ -156,6 +156,7 @@ GEM hanami-controller (= 2.0.0) hanami-router (= 2.0.0) oj (= 3.11.0) + pastel (~> 0.8.0) pry pry-byebug puma (~> 5.6.7) @@ -175,15 +176,17 @@ GEM aes_key_wrap bindata httpclient - jwt (2.9.0) + jwt (2.9.3) base64 kramdown (2.4.0) rexml language_server-protocol (3.17.0.3) + logger (1.6.1) method_source (1.1.0) - mime-types (3.5.2) + mime-types (3.6.0) + logger mime-types-data (~> 3.2015) - mime-types-data (3.2024.0903) + mime-types-data (3.2024.1001) mini_portile2 (2.8.7) minitest (5.25.1) multi_json (1.15.0) @@ -196,7 +199,7 @@ GEM hansi (~> 0.2.0) mustermann (= 1.1.2) netrc (0.11.0) - nio4r (2.7.3) + nio4r (2.7.4) nokogiri (1.16.7) mini_portile2 (~> 2.8.2) racc (~> 1.4) @@ -231,7 +234,7 @@ GEM puma (5.6.9) nio4r (~> 2.0) racc (1.8.1) - rack (2.2.9) + rack (2.2.10) rack-test (1.1.0) rack (>= 1.0, < 3) rainbow (3.1.1) @@ -248,7 +251,7 @@ GEM http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) netrc (~> 0.8) - rexml (3.3.7) + rexml (3.3.9) rouge (4.4.0) rspec (3.13.0) rspec-core (~> 3.13.0) From 95f35745f4aafc87511a3463c62b6235828ebb5b Mon Sep 17 00:00:00 2001 From: Tom Strassner Date: Tue, 5 Nov 2024 15:35:10 -0600 Subject: [PATCH 3/6] FI-3161: ID Token (#24) * Implement ID Token, JWKS endpoint * Fix various OpenID issues, fix fhirContext default input * Respect openid and fhirUser scopes when generating token * Fix postman collection * Revert to SMART STU2.2 fhirContext --- ...Tests Postman Demo.postman_collection.json | 62 ++++++++-- .../dtr_smart_app_suite.rb | 9 +- lib/davinci_dtr_test_kit/mock_auth_server.rb | 107 ++++++++++++++++-- lib/davinci_dtr_test_kit/tags.rb | 1 + lib/davinci_dtr_test_kit/urls.rb | 23 ++-- 5 files changed, 168 insertions(+), 34 deletions(-) diff --git a/config/DTR SMART App Tests Postman Demo.postman_collection.json b/config/DTR SMART App Tests Postman Demo.postman_collection.json index 3bf5f3f..94b8ab5 100644 --- a/config/DTR SMART App Tests Postman Demo.postman_collection.json +++ b/config/DTR SMART App Tests Postman Demo.postman_collection.json @@ -1,10 +1,10 @@ { "info": { - "_postman_id": "53717a07-9778-43ae-a28a-b436d74ba1b2", + "_postman_id": "7541fc56-d4d2-4126-b100-60416d01c5d5", "name": "DTR SMART App Tests Postman Demo", "description": "The variables tab in this collection controls port for inferno and token used to establish a session.\n\n- url_prefix: points to a running instance of inferno. Typical values will be\n \n - Inferno production: [https://inferno.healthit.gov/suites](https://inferno.healthit.gov/suites)\n \n - Inferno QA: [https://inferno-qa.healthit.gov/suites](https://inferno-qa.healthit.gov/suites)\n \n - Local docker: [http://localhost](http://localhost)\n \n - Local development: [http://localhost:4657](http://localhost:4657)\n \n- jwt_with_inferno_client_id: a non-standard jwt with the client_id value for the test present in the \"inferno_client_id\" entry of the payload. See [https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpbmZlcm5vX2NsaWVudF9pZCI6InRlc3QifQ.VvPENMXJqEfG3ShJ4hp4MQblfxcwJuX5o-3wSrGXEi0](https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpbmZlcm5vX2NsaWVudF9pZCI6InRlc3QifQ.VvPENMXJqEfG3ShJ4hp4MQblfxcwJuX5o-3wSrGXEi0) for an example where the client id is `sample` (NOTE: no other details matter). Sent on all questionnaire and clinical requests in the Authorization header as a bearer token (Bearer {{jwt_with_inferno_client_id}} - configured on the Authorization tab).", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", - "_exporter_id": "32597978" + "_exporter_id": "2481890" }, "item": [ { @@ -34,6 +34,48 @@ }, "response": [] }, + { + "name": "OpenID Configuration", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{base_url}}/custom/dtr_smart_app/fhir/.well-known/openid-configuration", + "host": [ + "{{base_url}}" + ], + "path": [ + "custom", + "dtr_smart_app", + "fhir", + ".well-known", + "openid-configuration" + ] + } + }, + "response": [] + }, + { + "name": "JWKS", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{base_url}}/custom/dtr_smart_app/fhir/.well-known/jwks.json", + "host": [ + "{{base_url}}" + ], + "path": [ + "custom", + "dtr_smart_app", + "fhir", + ".well-known", + "jwks.json" + ] + } + }, + "response": [] + }, { "name": "Authorize", "request": { @@ -43,7 +85,7 @@ "method": "GET", "header": [], "url": { - "raw": "{{base_url}}/custom/dtr_smart_app/fhir/mock_auth/authorize?response_type=code&client_id=sample&redirect_uri=http://localhost&launch=1234&scope=launch+patient%2F%2A.rs&state=394a5f8b-735c-4930-8f11-8f4034e3a483&aud={{base_url}}/custom/dtr_smart_app&code_challenge=59acb885e0a8b485df1a48c4d61544e5a0e6aa0209fe131bc64a336cb12aa95f&code_challenge_method=S256", + "raw": "{{base_url}}/custom/dtr_smart_app/fhir/mock_ehr_auth/authorize?response_type=code&client_id=sample&redirect_uri=http://localhost&launch=1234&scope=launch+patient%2F%2A.rs&state=394a5f8b-735c-4930-8f11-8f4034e3a483&aud={{base_url}}/custom/dtr_smart_app&code_challenge=59acb885e0a8b485df1a48c4d61544e5a0e6aa0209fe131bc64a336cb12aa95f&code_challenge_method=S256", "host": [ "{{base_url}}" ], @@ -51,7 +93,7 @@ "custom", "dtr_smart_app", "fhir", - "mock_auth", + "mock_ehr_auth", "authorize" ], "query": [ @@ -111,7 +153,7 @@ }, { "key": "client_id", - "value": "1", + "value": "sample", "type": "text" }, { @@ -126,7 +168,7 @@ }, { "key": "scope", - "value": "openid+user%2F%2A.rs+launch%2Fpatient", + "value": "openid+user%2F%2A.rs+launch%2Fpatient+fhirUser", "type": "text" }, { @@ -152,13 +194,14 @@ ] }, "url": { - "raw": "{{base_url}}/custom/dtr_smart_app/mock_ehr_auth/authorize", + "raw": "{{base_url}}/custom/dtr_smart_app/fhir/mock_ehr_auth/authorize", "host": [ "{{base_url}}" ], "path": [ "custom", "dtr_smart_app", + "fhir", "mock_ehr_auth", "authorize" ] @@ -207,19 +250,20 @@ }, { "key": "client_id", - "value": "1", + "value": "sample", "type": "text" } ] }, "url": { - "raw": "{{base_url}}/custom/dtr_smart_app/mock_ehr_auth/token", + "raw": "{{base_url}}/custom/dtr_smart_app/fhir/mock_ehr_auth/token", "host": [ "{{base_url}}" ], "path": [ "custom", "dtr_smart_app", + "fhir", "mock_ehr_auth", "token" ] diff --git a/lib/davinci_dtr_test_kit/dtr_smart_app_suite.rb b/lib/davinci_dtr_test_kit/dtr_smart_app_suite.rb index 060363c..060a39b 100644 --- a/lib/davinci_dtr_test_kit/dtr_smart_app_suite.rb +++ b/lib/davinci_dtr_test_kit/dtr_smart_app_suite.rb @@ -50,18 +50,21 @@ class DTRSmartAppSuite < Inferno::TestSuite end allow_cors QUESTIONNAIRE_PACKAGE_PATH, QUESTIONNAIRE_RESPONSE_PATH, FHIR_RESOURCE_PATH, FHIR_SEARCH_PATH, - EHR_AUTHORIZE_PATH, EHR_TOKEN_PATH + EHR_AUTHORIZE_PATH, EHR_TOKEN_PATH, JKWS_PATH, OPENID_CONFIG_PATH route(:get, '/fhir/metadata', method(:metadata_handler)) route(:get, SMART_CONFIG_PATH, method(:ehr_smart_config)) + route(:get, OPENID_CONFIG_PATH, method(:ehr_openid_config)) - record_response_route :get, EHR_AUTHORIZE_PATH, 'dtr_smart_app_ehr_authorize', method(:ehr_authorize), + route(:get, JKWS_PATH, method(:auth_server_jwks)) + + record_response_route :get, EHR_AUTHORIZE_PATH, EHR_AUTHORIZE_TAG, method(:ehr_authorize), resumes: ->(_) { false } do |request| DTRSmartAppSuite.extract_client_id_from_query_params(request) end - record_response_route :post, EHR_AUTHORIZE_PATH, 'dtr_smart_app_ehr_authorize', method(:ehr_authorize), + record_response_route :post, EHR_AUTHORIZE_PATH, EHR_AUTHORIZE_TAG, method(:ehr_authorize), resumes: ->(_) { false } do |request| DTRSmartAppSuite.extract_client_id_from_form_params(request) end diff --git a/lib/davinci_dtr_test_kit/mock_auth_server.rb b/lib/davinci_dtr_test_kit/mock_auth_server.rb index 33ab6e3..e445721 100644 --- a/lib/davinci_dtr_test_kit/mock_auth_server.rb +++ b/lib/davinci_dtr_test_kit/mock_auth_server.rb @@ -1,13 +1,37 @@ +# frozen_string_literal: true + require_relative 'urls' module DaVinciDTRTestKit module MockAuthServer + AUTHORIZED_PRACTITIONER_ID = 'pra1234' # Must exist on the FHIR_REFERENCE_SERVER (env var) + + RSA_PRIVATE_KEY = OpenSSL::PKey::RSA.generate(2048) + RSA_PUBLIC_KEY = RSA_PRIVATE_KEY.public_key + SUPPORTED_SCOPES = ['launch', 'patient/*.rs', 'user/*.rs', 'offline_access', 'openid', 'fhirUser'].freeze + + def requests_repo + @requests_repo ||= Inferno::Repositories::Requests.new + end + + def auth_server_jwks(_env) + response_body = { + keys: [ + { + kty: 'RSA', + alg: 'RS256', + n: Base64.urlsafe_encode64(RSA_PUBLIC_KEY.n.to_s(2), padding: false), + e: Base64.urlsafe_encode64(RSA_PUBLIC_KEY.e.to_s(2), padding: false), + use: 'sig' + } + ] + }.to_json + + [200, { 'Content-Type' => 'application/json', 'Access-Control-Allow-Origin' => '*' }, [response_body]] + end + def ehr_smart_config(env) - protocol = env['rack.url_scheme'] - host = env['HTTP_HOST'] - path = env['REQUEST_PATH'] || env['PATH_INFO'] - path.gsub!(%r{#{SMART_CONFIG_PATH}(/)?}, '') - base_url = "#{protocol}://#{host + path}" + base_url = env_base_url(env, SMART_CONFIG_PATH) response_body = { authorization_endpoint: base_url + EHR_AUTHORIZE_PATH, @@ -15,7 +39,7 @@ def ehr_smart_config(env) token_endpoint_auth_methods_supported: ['private_key_jwt'], token_endpoint_auth_signing_alg_values_supported: ['RS256'], grant_types_supported: ['authorization_code'], - scopes_supported: ['launch', 'patient/*.rs', 'user/*.rs', 'offline_access'], + scopes_supported: SUPPORTED_SCOPES, response_types_supported: ['code'], code_challenge_methods_supported: ['S256'], capabilities: [ @@ -31,9 +55,23 @@ def ehr_smart_config(env) [200, { 'Content-Type' => 'application/json', 'Access-Control-Allow-Origin' => '*' }, [response_body]] end + def ehr_openid_config(env) + base_url = env_base_url(env, OPENID_CONFIG_PATH) + response_body = { + issuer: base_url + FHIR_BASE_PATH, + authorization_endpoint: base_url + EHR_AUTHORIZE_PATH, + token_endpoint: base_url + EHR_TOKEN_PATH, + jwks_uri: base_url + JKWS_PATH, + response_types_supported: ['id_token'], + subject_types_supported: ['public'], + id_token_signing_alg_values_supported: ['RS256'] + }.to_json + [200, { 'Content-Type' => 'application/json', 'Access-Control-Allow-Origin' => '*' }, [response_body]] + end + def ehr_authorize(request, _test = nil, _test_result = nil) # Authorization requests can bet GET or POST - params = request.verb == 'get' ? request.query_parameters : URI.decode_www_form(request.request_body)&.to_h + params = params_hash(request) if params['redirect_uri'].present? redirect_uri = "#{params['redirect_uri']}?" \ "code=#{SecureRandom.hex}&" \ @@ -54,8 +92,14 @@ def ehr_authorize(request, _test = nil, _test_result = nil) def ehr_token_response(request, _test = nil, test_result = nil) client_id = extract_client_id_from_token_request(request) - token = JWT.encode({ inferno_client_id: client_id }, nil, 'none') - response = { access_token: token, token_type: 'bearer', expires_in: 3600 } + access_token = JWT.encode({ inferno_client_id: client_id }, nil, 'none') + granted_scopes = SUPPORTED_SCOPES & requested_scopes(test_result.test_session_id) + + response = { access_token:, scope: granted_scopes.join(' '), token_type: 'bearer', expires_in: 3600 } + + if granted_scopes.include?('openid') + response.merge!(id_token: create_id_token(request, client_id, fhir_user: granted_scopes.include?('fhirUser'))) + end fhir_context_input = find_test_input(test_result, 'smart_fhir_context') fhir_context_input_value = fhir_context_input['value'] if fhir_context_input @@ -64,14 +108,18 @@ def ehr_token_response(request, _test = nil, test_result = nil) rescue StandardError fhir_context = nil end - response.merge!({ fhirContext: fhir_context }) if fhir_context + response.merge!(fhirContext: fhir_context) if fhir_context smart_patient_input = find_test_input(test_result, 'smart_patient_id') smart_patient_input_value = smart_patient_input['value'] if smart_patient_input.present? - response.merge!({ patient: smart_patient_input_value }) if smart_patient_input_value + response.merge!(patient: smart_patient_input_value) if smart_patient_input_value request.response_body = response.to_json - request.response_headers = { 'Access-Control-Allow-Origin' => '*' } + request.response_headers = { + 'Cache-Control' => 'no-store', + 'Pragma' => 'no-cache', + 'Access-Control-Allow-Origin' => '*' + } request.status = 200 end @@ -138,8 +186,43 @@ def extract_token_from_query_params(request) request.query_parameters['token'] end + def create_id_token(request, client_id, fhir_user: false) + # No point in mocking an identity provider, just always use known Practitioner as the authorized user + suite_base_url = request.url.split(EHR_TOKEN_PATH).first + id_token_hash = { + iss: suite_base_url + FHIR_BASE_PATH, + sub: AUTHORIZED_PRACTITIONER_ID, + aud: client_id, + exp: Time.now.to_i + (24 * 60 * 60), # 24 hrs + iat: Time.now.to_i + } + id_token_hash.merge!(fhirUser: "#{suite_base_url}/fhir/Practitioner/#{AUTHORIZED_PRACTITIONER_ID}") if fhir_user + + JWT.encode(id_token_hash, RSA_PRIVATE_KEY, 'RS256') + end + + def requested_scopes(test_session_id) + auth_request = requests_repo.tagged_requests(test_session_id, [EHR_AUTHORIZE_TAG]).last + return [] unless auth_request + + scope_str = params_hash(auth_request)&.dig('scope') + scope_str ? URI.decode_www_form_component(scope_str).split : [] + end + def find_test_input(test_result, input_name) JSON.parse(test_result.input_json)&.find { |input| input['name'] == input_name } end + + def params_hash(request) + request.verb == 'get' ? request.query_parameters : URI.decode_www_form(request.request_body)&.to_h + end + + def env_base_url(env, endpoint_path) + protocol = env['rack.url_scheme'] + host = env['HTTP_HOST'] + path = env['REQUEST_PATH'] || env['PATH_INFO'] + path.gsub!(%r{#{endpoint_path}(/)?}, '') + "#{protocol}://#{host + path}" + end end end diff --git a/lib/davinci_dtr_test_kit/tags.rb b/lib/davinci_dtr_test_kit/tags.rb index 2f2134d..0d1b857 100644 --- a/lib/davinci_dtr_test_kit/tags.rb +++ b/lib/davinci_dtr_test_kit/tags.rb @@ -5,4 +5,5 @@ module DaVinciDTRTestKit NEXT_TAG = 'payer_server_adaptive_questionnaire_package' QUESTIONNAIRE_PACKAGE_TAG = 'dtr_questionnaire_package' SMART_APP_EHR_REQUEST_TAG = 'dtr_smart_app_ehr_request' + EHR_AUTHORIZE_TAG = 'dtr_smart_app_ehr_authorize' end diff --git a/lib/davinci_dtr_test_kit/urls.rb b/lib/davinci_dtr_test_kit/urls.rb index a42f75a..04170af 100644 --- a/lib/davinci_dtr_test_kit/urls.rb +++ b/lib/davinci_dtr_test_kit/urls.rb @@ -1,17 +1,20 @@ # frozen_string_literal: true module DaVinciDTRTestKit - SMART_CONFIG_PATH = '/fhir/.well-known/smart-configuration' - EHR_AUTHORIZE_PATH = '/mock_ehr_auth/authorize' - EHR_TOKEN_PATH = '/mock_ehr_auth/token' - PAYER_TOKEN_PATH = '/mock_payer_auth/token' - QUESTIONNAIRE_PACKAGE_PATH = '/fhir/Questionnaire/$questionnaire-package' - NEXT_PATH = '/fhir/Questionnaire/$next-question' - QUESTIONNAIRE_RESPONSE_PATH = '/fhir/QuestionnaireResponse' + FHIR_BASE_PATH = '/fhir' + SMART_CONFIG_PATH = "#{FHIR_BASE_PATH}/.well-known/smart-configuration".freeze + OPENID_CONFIG_PATH = "#{FHIR_BASE_PATH}/.well-known/openid-configuration".freeze + JKWS_PATH = "#{FHIR_BASE_PATH}/.well-known/jwks.json".freeze + EHR_AUTHORIZE_PATH = "#{FHIR_BASE_PATH}/mock_ehr_auth/authorize".freeze + EHR_TOKEN_PATH = "#{FHIR_BASE_PATH}/mock_ehr_auth/token".freeze + PAYER_TOKEN_PATH = "#{FHIR_BASE_PATH}/mock_payer_auth/token".freeze + QUESTIONNAIRE_PACKAGE_PATH = "#{FHIR_BASE_PATH}/Questionnaire/$questionnaire-package".freeze + NEXT_PATH = "#{FHIR_BASE_PATH}/Questionnaire/$next-question".freeze + QUESTIONNAIRE_RESPONSE_PATH = "#{FHIR_BASE_PATH}/QuestionnaireResponse".freeze + FHIR_RESOURCE_PATH = "#{FHIR_BASE_PATH}/:resource/:id".freeze + FHIR_SEARCH_PATH = "#{FHIR_BASE_PATH}/:resource".freeze RESUME_PASS_PATH = '/resume_pass' RESUME_FAIL_PATH = '/resume_fail' - FHIR_RESOURCE_PATH = '/fhir/:resource/:id' - FHIR_SEARCH_PATH = '/fhir/:resource' module URLs def base_url @@ -43,7 +46,7 @@ def questionnaire_response_url end def fhir_base_url - @fhir_base_url ||= "#{base_url}/fhir" + @fhir_base_url ||= base_url + FHIR_BASE_PATH end def resume_pass_url From 44d2e26bdf5c843da495f2336a998ce14d02e570 Mon Sep 17 00:00:00 2001 From: rpassas Date: Thu, 7 Nov 2024 14:28:46 -0500 Subject: [PATCH 4/6] rm stub body spec --- ...uestionnaire_package_group_static_response_validation_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/davinci_dtr_test_kit/dtr_payer_server_questionnaire_package_group_static_response_validation_spec.rb b/spec/davinci_dtr_test_kit/dtr_payer_server_questionnaire_package_group_static_response_validation_spec.rb index 1d7b741..26cbe35 100644 --- a/spec/davinci_dtr_test_kit/dtr_payer_server_questionnaire_package_group_static_response_validation_spec.rb +++ b/spec/davinci_dtr_test_kit/dtr_payer_server_questionnaire_package_group_static_response_validation_spec.rb @@ -89,7 +89,6 @@ def resource_type .with(query: { profile: 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-output-parameters|2.0.1' }) - .with(body: output_params_non_conformant) .to_return(status: 200, body: FHIR::OperationOutcome.new(issue: { severity: 'error' }).to_json) result = run(output_validation_test, test_session, url:, access_token:, retrieval_method:, From 0b0ceb23f18e75b680675eeaf945b3c58f97b9f6 Mon Sep 17 00:00:00 2001 From: rpassas Date: Thu, 7 Nov 2024 14:38:09 -0500 Subject: [PATCH 5/6] changelog --- CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..9fd933d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,31 @@ +# v0.13.0 +* Fix wording in SMART App Launch description by @tstrass in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/18 +* FI-3069: Full EHR QuestionnaireResponse verification by @tstrass in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/19 +* Fi-3231: Add SMART app tests to Light DTR EHR suite by @elsaperelli in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/21 +* FI-3270: CI, Rubocop by @tstrass in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/23 +* FI-3161: ID Token by @tstrass in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/24 +* FI-3410: Update inferno core requirement by @Jammjammjamm in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/25 + +# v0.12.0 +* rm extra assert by @rpassas in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/12 +* Full ehr tests by @karlnaden in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/15 +* FI-3094: Example JWT fix by @tstrass in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/16 +* Release 0.12.0 by @karlnaden in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/17 + +# v0.11.1 +* Pre connectathon fixes by @karlnaden in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/14 + +# v0.11.0 +* FI-2732: Add SMART App Launch capability by @tstrass in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/9 + +# v0.10.0 +* Postman Tweaks by @tstrass in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/5 +* Fi 2821 payer spec tests by @rpassas in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/7 +* migrate to new validator by @karlnaden in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/6 +* fix validator URL for spec tests by @rpassas in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/10 +* Dependency Updates 2024-07-03 by @Jammjammjamm in https://github.com/inferno-framework/davinci-dtr-test-kit/pull/8 + + +# v0.9.0 + +* Initial public release. From d626283a21cd10ac5a648260ce9f904a6a9a423e Mon Sep 17 00:00:00 2001 From: rpassas Date: Thu, 7 Nov 2024 14:38:14 -0500 Subject: [PATCH 6/6] version bump --- Gemfile.lock | 2 +- lib/davinci_dtr_test_kit/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b1a00c9..97d3a8f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - davinci_dtr_test_kit (0.12.0) + davinci_dtr_test_kit (0.13.0) inferno_core (~> 0.5.0) jwt (~> 2.6) smart_app_launch_test_kit (~> 0.4.4) diff --git a/lib/davinci_dtr_test_kit/version.rb b/lib/davinci_dtr_test_kit/version.rb index 7a074cc..50e4750 100644 --- a/lib/davinci_dtr_test_kit/version.rb +++ b/lib/davinci_dtr_test_kit/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module DaVinciDTRTestKit - VERSION = '0.12.0' + VERSION = '0.13.0' end