generated from inferno-framework/inferno-template
-
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.
FI-2723 Fix backend services discovery test versioning error (#29)
* Test structure refactor * Bulk Data V1 SMART Discovery Test contents implementation * Removed commented out code * Refactor to issue warnings for everything but token_endpoint * Removed run_as_group and optional configs * spec test for bulk data v1 discovery contents test * Fixed run_as_group so auth tests are bundled * Checked for failure messages in discovery v1 contents spec test * Used consistent versioning syntax * Versioning syntax in class names * V2 syntax fixes as well * Use assert_valid_http_uri to test correct URI format * Test requires proper format/values for optional claims that are present
- Loading branch information
1 parent
04b4367
commit 8c8c5cf
Showing
7 changed files
with
229 additions
and
9 deletions.
There are no files selected for viewing
21 changes: 21 additions & 0 deletions
21
lib/bulk_data_test_kit/v1.0.1/bulk_data_smart_backend_services_v101_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,21 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'smart_app_launch/smart_stu2_suite' | ||
require_relative 'bulk_data_smart_discovery_v101_group' | ||
|
||
module BulkDataTestKit | ||
module BulkDataV101 | ||
class BulkDataSmartBackendServicesV101Group < Inferno::TestGroup | ||
title 'SMART Backend Services' | ||
id :bulk_data_smart_backend_services_v101 | ||
optional | ||
|
||
group from: :bulk_data_smart_discovery_v101, | ||
config: { | ||
inputs: { url: { name: :bulk_server_url } } | ||
} | ||
|
||
group from: :backend_services_authorization, run_as_group: true | ||
end | ||
end | ||
end |
77 changes: 77 additions & 0 deletions
77
lib/bulk_data_test_kit/v1.0.1/bulk_data_smart_discovery_v101_contents_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,77 @@ | ||
require 'pry' | ||
module BulkDataTestKit | ||
module BulkDataV101 | ||
class BulkDataSmartDiscoveryV101ContentsTest < Inferno::Test | ||
title 'Well-known configuration contains the required fields' | ||
id :bulk_data_smart_discovery_v101_contents | ||
|
||
description %( | ||
The [Bulk Data v1.0.1 SMART Backend Services IG](https://hl7.org/fhir/uv/bulkdata/STU1.0.1/authorization/index.html#advertising-server-conformance-with-smart-backend-services) states: | ||
> A server MAY advertise its conformance with SMART Backend Services, by hosting a Well-Known Uniform Resource | ||
> Identifiers (URIs) (RFC5785) JSON document as described at SMART App Launch Authorization Discovery. If | ||
> advertising support, a server’s /.well-known/smart-configuration endpoint SHOULD include token_endpoint, | ||
> scopes_supported, token_endpoint_auth_methods_supported (with values that include private_key_jwt), and | ||
> token_endpoint_auth_signing_alg_values_supported (with values that include at least one of RS384, ES384) | ||
> attributes for backend services. The response is a JSON document using the application/json mime type. | ||
This test requires a valid `token_endpoint` claim to pass but issue a warning for any other recommended claims | ||
that are not present. | ||
However, any included claim must have the proper format and/or values indicated by the IG. | ||
) | ||
|
||
input :well_known_configuration | ||
|
||
output :smart_token_url | ||
|
||
def test_key(config, key, type) | ||
assert config[key].present?, "Well-known configuration field `#{key}` is blank" | ||
assert config[key].is_a?(type), "Well-known `#{key}` must be type: #{type.to_s.downcase}" | ||
end | ||
|
||
run do | ||
config = JSON.parse(well_known_configuration) | ||
|
||
# token_endpoint must be output for downstream tests to work | ||
assert config.key?('token_endpoint'), 'Well-known configuration does not include `token_endpoint`' | ||
test_key(config, 'token_endpoint', String) | ||
token_endpoint = config['token_endpoint'] | ||
assert_valid_http_uri(token_endpoint, "`#{token_endpoint}` is not a valid URI") | ||
|
||
output smart_token_url: token_endpoint | ||
|
||
recommended_capabilities = [ | ||
'token_endpoint_auth_methods_supported', | ||
'token_endpoint_auth_signing_alg_values_supported', | ||
'scopes_supported' | ||
] | ||
|
||
present_capabilities = [] | ||
recommended_capabilities.each do |key| | ||
if config.key?(key) then present_capabilities.append(key) | ||
else | ||
warning do | ||
assert config.key?(key), "Well-known configuration does not include `#{key}`" | ||
end | ||
end | ||
end | ||
|
||
present_capabilities.each do |key| | ||
test_key(config, key, Array) | ||
end | ||
|
||
if present_capabilities.include?('token_endpoint_auth_methods_supported') | ||
assert config['token_endpoint_auth_methods_supported'].include?('private_key_jwt'), | ||
'`token_endpoint_auth_methods_supported` does not include the value `private_key_jwt`' | ||
end | ||
|
||
if present_capabilities.include?('token_endpoint_auth_methods_supported') | ||
supports_RS384 = config['token_endpoint_auth_signing_alg_values_supported'].include? 'RS384' | ||
supports_ES384 = config['token_endpoint_auth_signing_alg_values_supported'].include? 'ES384' | ||
|
||
assert (supports_RS384 || supports_ES384), | ||
'`token_endpoint_auth_signing_alg_values_supported` does not include values for `RS384` or `ES384`' | ||
end | ||
end | ||
end | ||
end | ||
end |
15 changes: 15 additions & 0 deletions
15
lib/bulk_data_test_kit/v1.0.1/bulk_data_smart_discovery_v101_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,15 @@ | ||
require 'smart_app_launch/well_known_endpoint_test' | ||
require_relative 'bulk_data_smart_discovery_v101_contents_test' | ||
|
||
module BulkDataTestKit | ||
module BulkDataV101 | ||
class BulkDataSmartDiscoveryV101Group < Inferno::TestGroup | ||
title 'SMART on FHIR Discovery' | ||
id :bulk_data_smart_discovery_v101 | ||
run_as_group | ||
|
||
test from: :well_known_endpoint | ||
test from: :bulk_data_smart_discovery_v101_contents | ||
end | ||
end | ||
end |
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
109 changes: 109 additions & 0 deletions
109
spec/bulk_data_test_kit/bulk_data_smart_discovery_v101_contents_test_spec.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,109 @@ | ||
require_relative '../../lib/bulk_data_test_kit/v1.0.1/bulk_data_smart_discovery_v101_contents_test' | ||
require 'pry' | ||
|
||
RSpec.describe BulkDataTestKit::BulkDataV101::BulkDataSmartDiscoveryV101ContentsTest do | ||
let(:runnable) { Inferno::Repositories::Tests.new.find('bulk_data_smart_discovery_v101_contents') } | ||
let(:session_data_repo) { Inferno::Repositories::SessionData.new } | ||
let(:results_repo) { Inferno::Repositories::Results.new } | ||
let(:test_session) { repo_create(:test_session, test_suite_id: 'bulk_data_v101') } | ||
let(:correct_metadata) { | ||
{ | ||
'token_endpoint' => 'https://example.org/auth/token', | ||
'token_endpoint_auth_methods_supported' => ['private_key_jwt'], | ||
'token_endpoint_auth_signing_alg_values_supported' => [ 'RS384', 'ES384' ], | ||
'scopes_supported' => ['system/*.read'] | ||
} | ||
} | ||
|
||
let(:recommended_capabilities) { | ||
[ | ||
'token_endpoint_auth_methods_supported', | ||
'token_endpoint_auth_signing_alg_values_supported', | ||
'scopes_supported' | ||
] | ||
} | ||
def run(runnable, inputs = {}) | ||
test_run_params = { test_session_id: test_session.id }.merge(runnable.reference_hash) | ||
test_run = Inferno::Repositories::TestRuns.new.create(test_run_params) | ||
inputs.each do |name, value| | ||
session_data_repo.save( | ||
test_session_id: test_session.id, | ||
name:, | ||
value:, | ||
type: runnable.config.input_type(name) | ||
) | ||
end | ||
Inferno::TestRunner.new(test_session:, test_run:).run(runnable) | ||
end | ||
|
||
it 'skips if well-known metadata is not present' do | ||
result = run(runnable, well_known_configuration: '') | ||
|
||
expect(result.result).to eq('skip') | ||
end | ||
|
||
it 'passes with all required and recommended fields' do | ||
result = run(runnable, well_known_configuration: JSON.generate(correct_metadata)) | ||
|
||
expect(result.result).to eq('pass') | ||
end | ||
|
||
it 'passes with required field but missing recommended fields' do | ||
recommended_capabilities.each do |key| | ||
metadata = correct_metadata | ||
metadata.delete(key) | ||
result = run(runnable, well_known_configuration: JSON.generate(metadata)) | ||
expect(result.result).to eq('pass') | ||
end | ||
end | ||
|
||
it 'fails when token_endpoint field is missing' do | ||
metadata = correct_metadata | ||
metadata.delete('token_endpoint') | ||
result = run(runnable, well_known_configuration: JSON.generate(metadata)) | ||
expect(result.result).to eq('fail') | ||
expect(result.result_message).to match(/does not include `token_endpoint`/) | ||
end | ||
|
||
it 'fails with incorrect token_endpoint contents' do | ||
incorrect_token_endpoint_values = { | ||
'' => '`token_endpoint` is blank', | ||
'not_a_uri' => 'not a valid URI', | ||
['https://example.org/auth/token'] => '`token_endpoint` must be type' | ||
} | ||
|
||
metadata = correct_metadata | ||
|
||
incorrect_token_endpoint_values.each do |key, value| | ||
metadata['token_endpoint'] = key | ||
result = run(runnable, well_known_configuration: JSON.generate(metadata)) | ||
expect(result.result).to eq('fail') | ||
expect(result.result_message).to match(value) | ||
end | ||
end | ||
|
||
it 'fails when recommended claims are present but have improper format' do | ||
recommended_capabilities.each do |key| | ||
metadata = correct_metadata.clone | ||
# should be an array for all | ||
metadata[key] = '' | ||
result = run(runnable, well_known_configuration: JSON.generate(metadata)) | ||
expect(result.result).to eq('fail') | ||
expect(result.result_message).to match(key) | ||
end | ||
end | ||
|
||
it 'fails when token_endpoint_auth_methods_supported value is incorrect' do | ||
correct_metadata['token_endpoint_auth_methods_supported'] = ['invalid'] | ||
result = run(runnable, well_known_configuration: JSON.generate(correct_metadata)) | ||
expect(result.result).to eq('fail') | ||
expect(result.result_message).to match('private_key_jwt') | ||
end | ||
|
||
it 'fails when token_endpoint_auth_signing_alg_values_supported value is incorrect' do | ||
correct_metadata['token_endpoint_auth_signing_alg_values_supported'] = ['invalid'] | ||
result = run(runnable, well_known_configuration: JSON.generate(correct_metadata)) | ||
expect(result.result).to eq('fail') | ||
expect(result.result_message).to match('`RS384` or `ES384`') | ||
end | ||
end |