From b8df232ba2933018522bf0668bc396b8bc210223 Mon Sep 17 00:00:00 2001 From: Stephen MacVicar Date: Thu, 2 Feb 2023 07:58:48 -0500 Subject: [PATCH] FI-1888: Update profile support test (#103) * remove profile checks and add optional resource check to profile support test * add specs for profile support test --- .../profile_support_test.rb | 31 ++-- .../v3.1.1/capability_statement_group.rb | 2 +- .../v4.0.0/capability_statement_group.rb | 2 +- .../v5.0.1/capability_statement_group.rb | 2 +- spec/us_core/profile_support_test_spec.rb | 163 ++++++++++++++++++ 5 files changed, 180 insertions(+), 20 deletions(-) create mode 100644 spec/us_core/profile_support_test_spec.rb diff --git a/lib/us_core_test_kit/custom_groups/capability_statement/profile_support_test.rb b/lib/us_core_test_kit/custom_groups/capability_statement/profile_support_test.rb index a37aada5..e0dc0d3f 100644 --- a/lib/us_core_test_kit/custom_groups/capability_statement/profile_support_test.rb +++ b/lib/us_core_test_kit/custom_groups/capability_statement/profile_support_test.rb @@ -9,7 +9,9 @@ class ProfileSupportTest < Inferno::Test The US Core Server SHALL: 1. Support the US Core Patient resource profile. 2. Support at least one additional resource profile from the list of US - Core Profiles. + Core Profiles. + + In order to support USCDI, servers must support all USCDI resources. ``` ) uses_request :capability_statement @@ -23,30 +25,25 @@ class ProfileSupportTest < Inferno::Test &.each_with_object([]) do |rest, resources| rest.resource.each { |resource| resources << resource.type } end.uniq - supported_profiles = - capability_statement.rest - &.flat_map(&:resource) - &.flat_map { |resource| resource.supportedProfile + [resource.profile] } - &.compact || [] - supported_profiles.map! { |profile_url| profile_url.split('|').first } assert supported_resources.include?('Patient'), 'US Core Patient profile not supported' - target_profiles = config.options[:target_profiles] + us_core_resources = config.options[:us_core_resources] - other_resources = target_profiles.keys.reject { |resource_type| resource_type == 'Patient' } + other_resources = us_core_resources.reject { |resource_type| resource_type == 'Patient' } other_resources_supported = other_resources.any? { |resource| supported_resources.include? resource } assert other_resources_supported, 'No US Core resources other than Patient are supported' - target_profiles.each do |resource_type, profiles| - next unless supported_resources.include? resource_type + if config.options[:required_resources].present? + missing_resources = config.options[:required_resources] - supported_resources + + missing_resource_list = + missing_resources + .map { |resource| "`#{resource}`" } + .join(', ') - profiles.each do |profile| - warning do - assert supported_profiles&.include?(profile), - "CapabilityStatement does not claim support for US Core #{resource_type} profile: #{profile}" - end - end + assert missing_resources.empty?, + "The CapabilityStatement did not list support for the following resources: #{missing_resource_list}" end end end diff --git a/lib/us_core_test_kit/custom_groups/v3.1.1/capability_statement_group.rb b/lib/us_core_test_kit/custom_groups/v3.1.1/capability_statement_group.rb index 45455c22..080ed150 100644 --- a/lib/us_core_test_kit/custom_groups/v3.1.1/capability_statement_group.rb +++ b/lib/us_core_test_kit/custom_groups/v3.1.1/capability_statement_group.rb @@ -102,7 +102,7 @@ class CapabilityStatementGroup < Inferno::TestGroup test from: :us_core_profile_support do config( - options: { target_profiles: PROFILES } + options: { us_core_resources: PROFILES.keys } ) end end diff --git a/lib/us_core_test_kit/custom_groups/v4.0.0/capability_statement_group.rb b/lib/us_core_test_kit/custom_groups/v4.0.0/capability_statement_group.rb index b4341f67..8a3ac3f0 100644 --- a/lib/us_core_test_kit/custom_groups/v4.0.0/capability_statement_group.rb +++ b/lib/us_core_test_kit/custom_groups/v4.0.0/capability_statement_group.rb @@ -106,7 +106,7 @@ class CapabilityStatementGroup < Inferno::TestGroup test from: :us_core_profile_support do config( - options: { target_profiles: PROFILES } + options: { us_core_resources: PROFILES.keys } ) end diff --git a/lib/us_core_test_kit/custom_groups/v5.0.1/capability_statement_group.rb b/lib/us_core_test_kit/custom_groups/v5.0.1/capability_statement_group.rb index f561bc74..07a470ae 100644 --- a/lib/us_core_test_kit/custom_groups/v5.0.1/capability_statement_group.rb +++ b/lib/us_core_test_kit/custom_groups/v5.0.1/capability_statement_group.rb @@ -118,7 +118,7 @@ class CapabilityStatementGroup < Inferno::TestGroup test from: :us_core_profile_support do config( - options: { target_profiles: PROFILES } + options: { us_core_resources: PROFILES.keys } ) end diff --git a/spec/us_core/profile_support_test_spec.rb b/spec/us_core/profile_support_test_spec.rb new file mode 100644 index 00000000..42915158 --- /dev/null +++ b/spec/us_core/profile_support_test_spec.rb @@ -0,0 +1,163 @@ +require_relative '../../lib/us_core_test_kit/custom_groups/capability_statement/profile_support_test' + +RSpec.describe USCoreTestKit::ProfileSupportTest do + 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: name, + value: value, + type: runnable.config.input_type(name) || 'text' + ) + end + Inferno::TestRunner.new(test_session: test_session, test_run: test_run).run(runnable) + end + + let(:session_data_repo) { Inferno::Repositories::SessionData.new } + let(:test_session) { repo_create(:test_session, test_suite_id: suite.id) } + let(:suite) { Inferno::Repositories::TestSuites.new.find('us_core_v311') } + let(:test) { described_class } + let(:url) { 'http://example.com/fhir' } + + context 'with no required resources' do + before do + allow_any_instance_of(test).to receive(:config).and_return( + OpenStruct.new( + options: { + us_core_resources: ['Patient', 'Condition', 'Observation'] + } + ) + ) + end + + it 'fails if Patient is not supported' do + response_body = + FHIR::CapabilityStatement.new( + rest: [ + { + resource: [ + { + type: 'Condition' + } + ] + } + ] + ).to_json + repo_create(:request, response_body:, name: 'capability_statement', test_session_id: test_session.id) + + result = run(test, url:) + + expect(result.result).to eq('fail') + expect(result.result_message).to eq('US Core Patient profile not supported') + end + + it 'fails if only the Patient resource is supported' do + response_body = + FHIR::CapabilityStatement.new( + rest: [ + { + resource: [ + { + type: 'Patient' + } + ] + } + ] + ).to_json + repo_create(:request, response_body:, name: 'capability_statement', test_session_id: test_session.id) + + result = run(test, url:) + + expect(result.result).to eq('fail') + expect(result.result_message).to eq('No US Core resources other than Patient are supported') + end + + it 'passes if Patient and one other resource are supported' do + response_body = + FHIR::CapabilityStatement.new( + rest: [ + { + resource: [ + { + type: 'Patient' + }, + { + type: 'Observation' + } + ] + } + ] + ).to_json + repo_create(:request, response_body:, name: 'capability_statement', test_session_id: test_session.id) + + result = run(test, url:) + + expect(result.result).to eq('pass') + end + end + + context 'with required resources' do + before do + allow_any_instance_of(test).to receive(:config).and_return( + OpenStruct.new( + options: { + us_core_resources: ['Patient', 'Condition', 'Observation'], + required_resources: ['Patient', 'Condition', 'Observation'] + } + ) + ) + end + + it 'fails if not all required resources are supported' do + response_body = + FHIR::CapabilityStatement.new( + rest: [ + { + resource: [ + { + type: 'Patient' + }, + { + type: 'Observation' + } + ] + } + ] + ).to_json + repo_create(:request, response_body:, name: 'capability_statement', test_session_id: test_session.id) + + result = run(test, url:) + + expect(result.result).to eq('fail') + expect(result.result_message).to include('Condition') + end + + it 'passes if not required resources are supported' do + response_body = + FHIR::CapabilityStatement.new( + rest: [ + { + resource: [ + { + type: 'Patient' + }, + { + type: 'Observation' + }, + { + type: 'Condition' + } + ] + } + ] + ).to_json + repo_create(:request, response_body:, name: 'capability_statement', test_session_id: test_session.id) + + result = run(test, url:) + + expect(result.result).to eq('pass') + end + end +end