diff --git a/.gitignore b/.gitignore
index 26674d9c3..680204130 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,4 +12,3 @@ coverage
tmp/*
.vscode/*
resources/terminology/*
-.ruby-version
diff --git a/.ruby-version b/.ruby-version
new file mode 100644
index 000000000..1b03fe63d
--- /dev/null
+++ b/.ruby-version
@@ -0,0 +1 @@
+2.5.6
\ No newline at end of file
diff --git a/.tool-versions b/.tool-versions
new file mode 100644
index 000000000..789ef3502
--- /dev/null
+++ b/.tool-versions
@@ -0,0 +1 @@
+ruby 2.5.6
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 8b1e9ffb5..a3a89f791 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,9 +1,6 @@
language: ruby
services:
- docker
-rvm:
- - 2.5
- - 2.6
before_install:
- gem update --system
- gem install bundler
diff --git a/Dockerfile b/Dockerfile
index be8a0e645..fc3297976 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,8 +1,28 @@
-FROM ruby:2.5
+FROM ruby:2.5.6
-# Install gems into a temporary directory
-COPY Gemfile* ./
-RUN gem install bundler && bundle install
+WORKDIR /var/www/inferno
-# Expose the port
+### Install dependencies
+
+COPY Gemfile* /var/www/inferno/
+RUN gem install bundler
+# Throw an error if Gemfile & Gemfile.lock are out of sync
+RUN bundle config --global frozen 1
+RUN bundle install
+
+### Install Inferno
+
+RUN mkdir data
+COPY public /var/www/inferno/public
+COPY resources /var/www/inferno/resources
+COPY config* /var/www/inferno/
+COPY Rakefile /var/www/inferno/
+COPY test /var/www/inferno/test
+COPY lib /var/www/inferno/lib
+
+### Set up environment
+
+ENV APP_ENV=production
EXPOSE 4567
+
+CMD ["bundle", "exec", "rackup", "-o", "0.0.0.0"]
diff --git a/Gemfile b/Gemfile
index 102c78d38..3962bf7bd 100644
--- a/Gemfile
+++ b/Gemfile
@@ -13,17 +13,19 @@ gem 'json-jwt'
gem 'kramdown'
gem 'pry'
gem 'pry-byebug'
-gem 'rack-test'
gem 'rake'
gem 'rb-readline'
gem 'rest-client'
-gem 'rubocop', require: false
gem 'selenium-webdriver'
gem 'sinatra'
gem 'sinatra-contrib'
gem 'sqlite3'
gem 'thin'
gem 'time_difference'
-gem 'webmock'
-gem 'simplecov', require: false, group: :test
+group :test do
+ gem 'rack-test'
+ gem 'rubocop', require: false
+ gem 'simplecov', require: false
+ gem 'webmock'
+end
diff --git a/README.md b/README.md
index 5b59878a9..c233fc8a2 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-
+
[![Build Status](https://travis-ci.org/onc-healthit/inferno.svg?branch=master)](https://travis-ci.org/onc-healthit/inferno)
@@ -82,7 +82,7 @@ bundle exec rake test
## Inspecting and Exporting Tests
Tests are written to be easily understood, even by those who aren't familiar with Ruby. They can be
-viewed directly [in this repository](https://github.com/onc-healthit/inferno/tree/master/lib/app/sequences).
+viewed directly [in this repository](https://github.com/onc-healthit/inferno/tree/master/lib/app/modules).
Tests contain metadata that provide additional details and traceability to standards. The active tests and related metadata can be exported into CSV format and saved to a file named `testlist.csv` with the following command:
diff --git a/config.yml b/config.yml
index df35e4f9d..12a2e9783 100644
--- a/config.yml
+++ b/config.yml
@@ -5,9 +5,6 @@ app_name: Inferno
# There are a few exceptions, such as "/" and "/landing".
base_path: "inferno"
-# Show or hide tutorials
-show_tutorial: true
-
# Useful during development to purge the database on each reload
purge_database_on_reload: false
diff --git a/docker-compose.yml b/docker-compose.yml
index a67bf89a8..d4e4f0669 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,19 +1,12 @@
version: '3'
services:
- # the main ruby server
ruby_server:
- # build the image from ./Dockerfile (this installs the dependencies into the image)
build:
context: ./
- # map the project directory into the running container
volumes:
- - .:/var/www/inferno
- # expose the internal application to direct HTTP requests
- #ports:
- # - "4567:8080"
- # run the application
- working_dir: /var/www/inferno
- command: rackup -o 0.0.0.0
+ - ./config.yml:/var/www/inferno/config.yml
+ ports:
+ - "4567:8080"
nginx_server:
image: nginx
volumes:
@@ -24,4 +17,4 @@ services:
links:
- ruby_server:ruby_server
depends_on:
- - ruby_server
\ No newline at end of file
+ - ruby_server
diff --git a/generators/uscore-r4/generator.rb b/generators/uscore-r4/generator.rb
index ab6d4ed03..58637deb1 100644
--- a/generators/uscore-r4/generator.rb
+++ b/generators/uscore-r4/generator.rb
@@ -6,9 +6,17 @@
require 'net/http'
require 'fhir_models'
require_relative './metadata_extractor'
+require_relative '../../lib/app/utils/validation'
-OUT_PATH = '../../lib/app/modules'
-RESOURCE_PATH = '../../resources/us_core_r4/'
+OUT_PATH = File.expand_path('../../lib/app/modules', __dir__)
+RESOURCE_PATH = File.expand_path('../../resources/us_core_r4', __dir__)
+
+PROFILE_URIS = Inferno::ValidationUtil::US_CORE_R4_URIS
+
+def validation_profile_uri(sequence)
+ profile_uri = PROFILE_URIS.key(sequence[:profile])
+ "Inferno::ValidationUtil::US_CORE_R4_URIS[:#{profile_uri}]" if profile_uri
+end
def run
redownload_files = (ARGV&.first == '-d')
@@ -31,8 +39,15 @@ def generate_search_validators(metadata)
end
def generate_tests(metadata)
+ # first isolate the profiles that don't have patient searches
+ mark_delayed_sequences(metadata)
+
metadata[:sequences].each do |sequence|
puts "Generating test #{sequence[:name]}"
+
+ # read reference if sequence contains no search sequences
+ create_read_test(sequence) if sequence[:delayed_sequence]
+
# authorization test
create_authorization_test(sequence)
@@ -52,6 +67,7 @@ def generate_tests(metadata)
.each do |interaction|
# specific edge cases
interaction[:code] = 'history' if interaction[:code] == 'history-instance'
+ next if interaction[:code] == 'read' && sequence[:delayed_sequence]
create_interaction_test(sequence, interaction)
end
@@ -62,16 +78,44 @@ def generate_tests(metadata)
end
end
+def mark_delayed_sequences(metadata)
+ metadata[:sequences].each do |sequence|
+ sequence[:delayed_sequence] = sequence[:resource] != 'Patient' && sequence[:searches].none? { |search| search[:names].include? 'patient' }
+ end
+ metadata[:delayed_sequences] = metadata[:sequences].select { |seq| seq[:delayed_sequence] }
+ metadata[:non_delayed_sequences] = metadata[:sequences].reject { |seq| seq[:delayed_sequence] }
+end
+
+def find_first_search(sequence)
+ sequence[:searches].find { |search_param| search_param[:expectation] == 'SHALL' } ||
+ sequence[:searches].find { |search_param| search_param[:expectation] == 'SHOULD' }
+end
+
def generate_sequence(sequence)
puts "Generating #{sequence[:name]}\n"
file_name = OUT_PATH + '/us_core_r4/' + sequence[:name].downcase + '_sequence.rb'
- template = ERB.new(File.read('./templates/sequence.rb.erb'))
+ template = ERB.new(File.read(File.join(__dir__, 'templates/sequence.rb.erb')))
output = template.result_with_hash(sequence)
FileUtils.mkdir_p(OUT_PATH + '/us_core_r4') unless File.directory?(OUT_PATH + '/us_core_r4')
File.write(file_name, output)
end
+def create_read_test(sequence)
+ read_test = {
+ tests_that: "Can read #{sequence[:resource]} from the server",
+ index: sequence[:tests].length + 1,
+ link: 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ }
+
+ read_test[:test_code] = %(
+ #{sequence[:resource].downcase}_id = @instance.resource_references.find { |reference| reference.resource_type == '#{sequence[:resource]}' }&.resource_id
+ skip 'No #{sequence[:resource]} references found from the prior searches' if #{sequence[:resource].downcase}_id.nil?
+ @#{sequence[:resource].downcase} = fetch_resource('#{sequence[:resource]}', #{sequence[:resource].downcase}_id)
+ @resources_found = !@#{sequence[:resource].downcase}.nil?)
+ sequence[:tests] << read_test
+end
+
def create_authorization_test(sequence)
authorization_test = {
tests_that: "Server rejects #{sequence[:resource]} search without authorization",
@@ -79,8 +123,7 @@ def create_authorization_test(sequence)
link: 'http://www.fhir.org/guides/argonaut/r2/Conformance-server.html'
}
- first_search = sequence[:searches].find { |search_param| search_param[:expectation] == 'SHALL' } ||
- sequence[:searches].find { |search_param| search_param[:expectation] == 'SHOULD' }
+ first_search = find_first_search(sequence)
return if first_search.nil?
authorization_test[:test_code] = %(
@@ -98,10 +141,17 @@ def create_search_test(sequence, search_param)
search_test = {
tests_that: "Server returns expected results from #{sequence[:resource]} search by #{search_param[:names].join('+')}",
index: sequence[:tests].length + 1,
- link: 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ link: 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html',
+ optional: search_param[:expectation] != 'SHALL'
}
- is_first_search = search_test[:index] == 2 # if first search - fix this check later
+ is_first_search = search_param == find_first_search(sequence)
+ save_resource_ids_in_bundle_arguments = [
+ "versioned_resource_class('#{sequence[:resource]}')",
+ 'reply',
+ validation_profile_uri(sequence)
+ ].compact.join(', ')
+
search_test[:test_code] =
if is_first_search
%(#{get_search_params(search_param[:names], sequence)}
@@ -116,7 +166,8 @@ def create_search_test(sequence, search_param)
@#{sequence[:resource].downcase} = reply.try(:resource).try(:entry).try(:first).try(:resource)
@#{sequence[:resource].downcase}_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
- save_resource_ids_in_bundle(versioned_resource_class('#{sequence[:resource]}'), reply)
+ save_resource_ids_in_bundle(#{save_resource_ids_in_bundle_arguments})
+ save_delayed_sequence_references(@#{sequence[:resource].downcase})
validate_search_reply(versioned_resource_class('#{sequence[:resource]}'), reply, search_params))
else
%(
@@ -216,7 +267,7 @@ def create_resource_profile_test(sequence)
}
test[:test_code] = %(
skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
- test_resources_against_profile('#{sequence[:resource]}'))
+ test_resources_against_profile('#{sequence[:resource]}'#{', ' + validation_profile_uri(sequence) if validation_profile_uri(sequence)}))
sequence[:tests] << test
end
@@ -259,6 +310,8 @@ def get_value_path_by_type(type)
'.code'
when 'HumanName'
'.family'
+ when 'Address'
+ '.city'
else
''
end
@@ -334,14 +387,13 @@ def get_comparator_searches(search_params, sequence)
def search_param_constants(search_parameters, sequence)
return "patient: @instance.patient_id, category: 'assess-plan'" if search_parameters == ['patient', 'category'] && sequence[:resource] == 'CarePlan'
return "patient: @instance.patient_id, status: 'active'" if search_parameters == ['patient', 'status'] && sequence[:resource] == 'CareTeam'
- return "patient: @instance.patient_id, name: 'Boston'" if search_parameters == ['name'] && (['Location', 'Organization'].include? sequence[:resource])
return "'_id': @instance.patient_id" if search_parameters == ['_id'] && sequence[:resource] == 'Patient'
- return "patient: @instance.patient_id, code: '72166-2'" if search_parameters == ['patient', 'code'] && sequence[:profile] == 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-smokingstatus.json'
- return "patient: @instance.patient_id, category: 'laboratory'" if search_parameters == ['patient', 'category'] && sequence[:profile] == 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-observation-lab.json'
- return "patient: @instance.patient_id, code: '77606-2'" if search_parameters == ['patient', 'code'] && sequence[:profile] == 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-pediatric-weight-for-height.json'
- return "patient: @instance.patient_id, code: '59576-9'" if search_parameters == ['patient', 'code'] && sequence[:profile] == 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-pediatric-bmi-for-age.json'
- return "patient: @instance.patient_id, category: 'LAB'" if search_parameters == ['patient', 'category'] && sequence[:profile] == 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-diagnosticreport-lab.json'
- return "patient: @instance.patient_id, code: 'LP29684-5'" if search_parameters == ['patient', 'category'] && sequence[:profile] == 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-diagnosticreport-note.json'
+ return "patient: @instance.patient_id, code: '72166-2'" if search_parameters == ['patient', 'code'] && sequence[:profile] == PROFILE_URIS[:smoking_status]
+ return "patient: @instance.patient_id, category: 'laboratory'" if search_parameters == ['patient', 'category'] && sequence[:profile] == PROFILE_URIS[:lab_results]
+ return "patient: @instance.patient_id, code: '77606-2'" if search_parameters == ['patient', 'code'] && sequence[:profile] == PROFILE_URIS[:pediatric_weight_height]
+ return "patient: @instance.patient_id, code: '59576-9'" if search_parameters == ['patient', 'code'] && sequence[:profile] == PROFILE_URIS[:pediatric_bmi_age]
+ return "patient: @instance.patient_id, category: 'LAB'" if search_parameters == ['patient', 'category'] && sequence[:profile] == PROFILE_URIS[:diagnostic_report_lab]
+ return "patient: @instance.patient_id, code: 'LP29684-5'" if search_parameters == ['patient', 'category'] && sequence[:profile] == PROFILE_URIS[:diagnostic_report_note]
end
def create_search_validation(sequence)
@@ -418,7 +470,7 @@ def validate_resource_item(resource, property, value)
def generate_module(module_info)
file_name = OUT_PATH + '/us_core_module.yml'
- template = ERB.new(File.read('./templates/module.yml.erb'))
+ template = ERB.new(File.read(File.join(__dir__, 'templates/module.yml.erb')))
output = template.result_with_hash(module_info)
File.write(file_name, output)
diff --git a/generators/uscore-r4/metadata_extractor.rb b/generators/uscore-r4/metadata_extractor.rb
index 210e9c0d0..675cbd684 100644
--- a/generators/uscore-r4/metadata_extractor.rb
+++ b/generators/uscore-r4/metadata_extractor.rb
@@ -1,19 +1,23 @@
# frozen_string_literal: true
class MetadataExtractor
- CAPABILITY_STATEMENT_URI = 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.json'
+ CAPABILITY_STATEMENT_URI = 'https://www.hl7.org/fhir/us/core/CapabilityStatement-us-core-server.json'
def profile_uri(profile)
- "https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-#{profile}.json"
+ "http://hl7.org/fhir/us/core/StructureDefinition/#{profile}"
+ end
+
+ def profile_json_uri(profile)
+ "https://www.hl7.org/fhir/us/core/StructureDefinition-#{profile}.json"
end
def search_param_uri(resource, param)
param = 'id' if param == '_id'
- "https://build.fhir.org/ig/HL7/US-Core-R4/SearchParameter-us-core-#{resource.downcase}-#{param}.json"
+ "https://www.hl7.org/fhir/us/core/SearchParameter-us-core-#{resource.downcase}-#{param}.json"
end
def get_json_from_uri(uri)
- filename = RESOURCE_PATH + uri.split('/').last
+ filename = File.join(RESOURCE_PATH, uri.split('/').last)
unless File.exist?(filename)
puts "Downloading #{uri}\n"
json_result = Net::HTTP.get(URI(uri))
@@ -33,7 +37,7 @@ def extract_metadata
def build_new_sequence(resource, profile)
base_name = profile.split('StructureDefinition/')[1]
- profile_json = get_json_from_uri(profile_uri(base_name))
+ profile_json = get_json_from_uri(profile_json_uri(base_name))
profile_title = profile_json['title'].gsub(/US\s*Core\s*/, '').gsub(/\s*Profile/, '').strip
{
name: base_name.tr('-', '_'),
@@ -44,6 +48,7 @@ def build_new_sequence(resource, profile)
.gsub('UsCore', 'USCoreR4') + 'Sequence',
resource: resource['type'],
profile: profile_uri(base_name), # link in capability statement is incorrect,
+ profile_json: profile_json_uri(base_name),
title: profile_title,
interactions: [],
searches: [],
@@ -67,7 +72,7 @@ def extract_metadata_from_resources(resources)
add_combo_searches(resource, new_sequence)
add_interactions(resource, new_sequence)
- profile_definition = get_json_from_uri(new_sequence[:profile])
+ profile_definition = get_json_from_uri(new_sequence[:profile_json])
add_must_support_elements(profile_definition, new_sequence)
add_search_param_descriptions(profile_definition, new_sequence)
add_element_definitions(profile_definition, new_sequence)
@@ -203,9 +208,9 @@ def add_element_definitions(profile_definition, sequence)
def add_special_cases
category_first_profiles = [
- 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-diagnosticreport-lab.json',
- 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-observation-lab.json',
- 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-diagnosticreport-note.json'
+ PROFILE_URIS[:diagnostic_report_lab],
+ PROFILE_URIS[:lab_results],
+ PROFILE_URIS[:diagnostic_report_note]
]
# search by patient first
diff --git a/generators/uscore-r4/templates/module.yml.erb b/generators/uscore-r4/templates/module.yml.erb
index cde8a380b..efe5656b7 100644
--- a/generators/uscore-r4/templates/module.yml.erb
+++ b/generators/uscore-r4/templates/module.yml.erb
@@ -18,9 +18,10 @@ test_sets:
- ManualRegistrationSequence
- StandaloneLaunchSequence
- EHRLaunchSequence
- - name: US Core R4
+ - name: US Core R4 Patient Based Profiles
run_all: true
- sequences:<% sequences.each do |sequence| %>
+ sequences:<% non_delayed_sequences.each do |sequence| %>
- <%=sequence[:classname]%><% end %>
- R4ProvenanceSequence
- - USCoreR4ClinicalNotesSequence
+ - USCoreR4ClinicalNotesSequence<% delayed_sequences.each do |sequence| %>
+ - <%=sequence[:classname]%><% end %>
diff --git a/generators/uscore-r4/templates/sequence.rb.erb b/generators/uscore-r4/templates/sequence.rb.erb
index cc15d93a0..175db2e24 100644
--- a/generators/uscore-r4/templates/sequence.rb.erb
+++ b/generators/uscore-r4/templates/sequence.rb.erb
@@ -11,8 +11,9 @@ module Inferno
test_id_prefix '<%=resource%>' # change me
- requires :token, :patient_id
- conformance_supports :<%=resource%>
+ requires :token<%=", :patient_id" unless delayed_sequence%>
+ conformance_supports :<%=resource%><%="
+ delayed_sequence" if delayed_sequence%>
<%=search_validator%>
details %(
@@ -26,7 +27,8 @@ module Inferno
test '<%=test[:tests_that]%>' do
metadata do
id '<%=format('%02d', test[:index])%>'
- link '<%=test[:link]%>'
+ link '<%=test[:link]%>'<%if test[:optional]%>
+ optional<%end%>
desc %(
)
versions :r4
diff --git a/lib/app/endpoint.rb b/lib/app/endpoint.rb
index 03e71dabc..9c446e0fa 100644
--- a/lib/app/endpoint.rb
+++ b/lib/app/endpoint.rb
@@ -20,6 +20,7 @@ class Endpoint < Sinatra::Base
Inferno::EXTRAS = settings.include_extras
if settings.logging_enabled
+ $stdout.sync = true # output in Docker is heavily delayed without this
Inferno.logger =
if ENV['RACK_ENV'] == 'test'
FileUtils.mkdir_p 'tmp'
diff --git a/lib/app/helpers/configuration.rb b/lib/app/helpers/configuration.rb
index 47f4782c6..7f514c336 100644
--- a/lib/app/helpers/configuration.rb
+++ b/lib/app/helpers/configuration.rb
@@ -40,10 +40,6 @@ def valid_json?(json)
def tls_testing_supported?
TlsTester.testing_supported?
end
-
- def show_tutorial
- settings.show_tutorial
- end
end
end
end
diff --git a/lib/app/models/server_capabilities.rb b/lib/app/models/server_capabilities.rb
index cfa01e894..61d45ee7c 100644
--- a/lib/app/models/server_capabilities.rb
+++ b/lib/app/models/server_capabilities.rb
@@ -11,6 +11,8 @@ class ServerCapabilities
belongs_to :testing_instance
+ SMART_EXTENSION_URL = 'http://fhir-registry.smarthealthit.org/StructureDefinition/capabilities'
+
def supported_resources
statement.rest.each_with_object(Set.new) do |rest, resources|
rest.resource.each { |resource| resources << resource.type }
@@ -28,12 +30,34 @@ def supported_interactions
end
end
+ def operation_supported?(operation_name)
+ statement.rest.any? { |rest| rest.operation.any? { |operation| operation.name == operation_name } }
+ end
+
+ def smart_support?
+ smart_extensions.present?
+ end
+
+ def smart_capabilities
+ smart_extensions.map(&:valueCode)
+ end
+
private
def statement
@statement ||= FHIR::CapabilityStatement.new(capabilities)
end
+ def security_extensions
+ @security_extensions ||=
+ statement&.rest&.flat_map { |rest| rest&.security&.extension }&.compact || []
+ end
+
+ def smart_extensions
+ @smart_extensions ||=
+ security_extensions.select { |extension| extension.url == SMART_EXTENSION_URL }
+ end
+
def interaction_display(interaction)
if interaction.code == 'search-type'
'search'
diff --git a/lib/app/modules/argonaut/argonaut_conformance_sequence.rb b/lib/app/modules/argonaut/argonaut_conformance_sequence.rb
index daed723a8..c27034b53 100644
--- a/lib/app/modules/argonaut/argonaut_conformance_sequence.rb
+++ b/lib/app/modules/argonaut/argonaut_conformance_sequence.rb
@@ -86,7 +86,8 @@ class ArgonautConformanceSequence < CapabilityStatementSequence
)
end
- assert @conformance.class == versioned_conformance_class, 'Expected valid Conformance resource'
+ assert_valid_conformance
+
formats = ['json', 'applcation/json', 'application/json+fhir', 'application/fhir+json']
assert formats.any? { |format| @conformance.format.include? format }, 'Conformance does not state support for json.'
end
@@ -115,20 +116,17 @@ class ArgonautConformanceSequence < CapabilityStatementSequence
'permission-patient',
'permission-user']
- assert @conformance.class == versioned_conformance_class, 'Expected valid Conformance resource'
+ assert_valid_conformance
+
+ assert @server_capabilities.smart_support?, 'No SMART capabilities listed in conformance.'
- extensions = @conformance.try(:rest).try(:first).try(:security).try(:extension)
- assert !extensions.nil?, 'No SMART capabilities listed in conformance.'
- capabilities = extensions.select { |x| x.url == 'http://fhir-registry.smarthealthit.org/StructureDefinition/capabilities' }
- assert !capabilities.nil?, 'No SMART capabilities listed in conformance.'
- available_capabilities = capabilities.map(&:valueCode)
- missing_capabilities = (required_capabilities - available_capabilities)
+ missing_capabilities = (required_capabilities - @server_capabilities.smart_capabilities)
assert missing_capabilities.empty?, "Conformance statement does not list required SMART capabilties: #{missing_capabilities.join(', ')}"
end
test 'Conformance Statement lists supported Argonaut profiles, operations and search parameters' do
metadata do
- id '05'
+ id '06'
link 'https://www.fhir.org/guides/argonaut/r2/Conformance-server.html'
desc %(
The Argonaut Data Query Implementation Guide states:
@@ -140,16 +138,7 @@ class ArgonautConformanceSequence < CapabilityStatementSequence
)
end
- assert @conformance.class == versioned_conformance_class, 'Expected valid Conformance resource'
-
- begin
- Inferno::Models::ServerCapabilities.create(
- testing_instance_id: @instance.id,
- capabilities: @conformance.as_json
- )
- rescue StandardError
- assert false, 'Conformance Statement could not be parsed.'
- end
+ assert_valid_conformance
assert @instance.conformance_supported?(:Patient, [:read]), 'Patient resource with read interaction is not listed in conformance statement.'
end
diff --git a/lib/app/modules/bulk_data/bulk_data_capability_statement_sequence.rb b/lib/app/modules/bulk_data/bulk_data_capability_statement_sequence.rb
new file mode 100644
index 000000000..8b4b36202
--- /dev/null
+++ b/lib/app/modules/bulk_data/bulk_data_capability_statement_sequence.rb
@@ -0,0 +1,176 @@
+# frozen_string_literal: true
+
+require_relative '../core/capability_statement_sequence'
+
+module Inferno
+ module Sequence
+ class BulkDataCapabilityStatementSequence < CapabilityStatementSequence
+ extends_sequence CapabilityStatementSequence
+
+ title 'Capability Statement'
+
+ test_id_prefix 'C'
+
+ requires :url
+ defines :oauth_authorize_endpoint, :oauth_token_endpoint, :oauth_register_endpoint
+
+ description 'Retrieve information about supported server functionality in the Capability Statement.'
+ details %(
+ # Background
+ The #{title} Sequence tests a FHIR server's ability to formally describe features
+ supported by the API by using the [Capability Statement](https://www.hl7.org/fhir/capabilitystatement.html) resource.
+ The features described in the Capability Statement must be consistent with the required capabilities of an
+ Argonaut server. The Capability Statement must also advertise the location of the required SMART on FHIR endpoints
+ that enable authenticated access to the FHIR server resources.
+
+ Not all servers are expected to implement all possible queries and data elements described in the Argonaut API.
+ For example, the Argonaut specification requires that the Patient resource and only one other Argonaut resource are required.
+ Implementing the Capability Statement resource allows clients to dynamically determine which of these resources
+ are supported at runtime, instead of having to specifically write the application to accomidate every known server implementation
+ at development time. Similarly, by providing information about the location of SMART on FHIR OAuth 2.0 endpoints,
+ the client does not have to be hard-coded with information about the authorization services associated with
+ every FHIR API.
+
+ Note that the name of this resource changed to 'Capability Statement' in STU3 to better describe the intent of this resource.
+ This test refers to it as the Capability Statement as that is what it was called in DSTU2.
+
+ # Test Methodology
+
+ This test suite accesses the server endpoint at `/metadata` using a `GET` request. It parses the Capability Statement and
+ verifies that the server claims support of following features:
+
+ * JSON encoding of resources
+ * Patient resource
+ * At least one of the other resources that form the basis of Argonaut profiles
+ * SMART on FHIR authorization
+
+ It collects the following information that is saved in the testing session for use by later tests:
+
+ * List of resources supported
+ * List of queries parameters supported
+ * SMART on FHIR endpoints
+
+ For more information of the Capability Statement, visit these links:
+
+ * [Capability](https://www.hl7.org/fhir/capabilitystatement.html)
+ * [Argonaut Capability Requirements](http://hl7.org/fhir/us/core/2019Jan/CapabilityStatement-us-core-server.html)
+ * [SMART on FHIR Conformance](http://hl7.org/fhir/smart-app-launch/conformance/index.html)
+ )
+
+ def assert_operation(op_name); end
+
+ test 'FHIR server capability states JSON support' do
+ metadata do
+ id '04'
+ link 'http://hl7.org/fhir/us/core/2019Jan/CapabilityStatement-us-core-server.html'
+ desc %(
+
+ FHIR provides multiple [representation formats](https://www.hl7.org/fhir/DSTU2/formats.html) for resources, including JSON and XML.
+ Argonaut profiles require servers to use the JSON representation:
+
+ ```
+ The Argonaut Data Query Server shall support JSON resource format for all Argonaut Data Query interactions.
+ ```
+ [http://hl7.org/fhir/us/core/2019Jan/CapabilityStatement-us-core-server.html](http://hl7.org/fhir/us/core/2019Jan/CapabilityStatement-us-core-server.html)
+
+ The FHIR capability interaction require servers to describe which formats are available for clients to use. The server must
+ explicitly state that JSON is supported. This is located in the [format element](https://www.hl7.org/fhir/capabilitystatement-definitions.html#CapabilityStatement.format)
+ of the Capability Resource.
+
+ This test checks that one of the following values are located in the [format field](https://www.hl7.org/fhir/DSTU2/json.html).
+
+ * json
+ * application/json
+ * application/json+fhir
+
+ Note that FHIR changed the FHIR-specific JSON mime type to `application/fhir+json` in later versions of the specification.
+
+ )
+ end
+
+ assert @conformance.class == versioned_conformance_class, 'Expected valid Conformance resource'
+ formats = ['json', 'applcation/json', 'application/json+fhir', 'application/fhir+json']
+ assert formats.any? { |format| @conformance.format.include? format }, 'Conformance does not state support for json.'
+ end
+
+ test 'FHIR server capability SHOULD instantiate from CapabilityStatment-bulk-data' do
+ metadata do
+ id '05'
+ link 'https://build.fhir.org/ig/HL7/bulk-data/operations/index.html'
+ desc %(
+
+ To declare conformance with this IG, a server should include the following URL in its own CapabilityStatement.instantiates:
+ http://www.hl7.org/fhir/bulk-data/CapabilityStatement-bulk-data.html
+
+ )
+ optional
+ end
+
+ assert @conformance.instantiates&.include?('http://www.hl7.org/fhir/bulk-data/CapabilityStatement-bulk-data.html'), 'CapabilityStatement did not instantiate from "http://www.hl7.org/fhir/bulk-data/CapabilityStatement-bulk-data.html"'
+ end
+
+ test 'FHIR server capability SHOULD have export operation' do
+ metadata do
+ id '06'
+ link 'https://build.fhir.org/ig/HL7/bulk-data/operations/index.html'
+ desc %(
+
+ These OperationDefinitions have been defined for this implementation guide.
+ * Export: export any data from a FHIR server
+ * Patient Export: export patient data from a FHIR server
+ * Group Export: export data for groups of patients from a FHIR server
+
+ )
+ optional
+ end
+
+ begin
+ Inferno::Models::ServerCapabilities.create(
+ testing_instance_id: @instance.id,
+ capabilities: @conformance.as_json
+ )
+ rescue StandardError
+ assert false, 'Capability Statement could not be parsed.'
+ end
+
+ assert_operation_supported(@instance.server_capabilities, 'export')
+ end
+
+ test 'FHIR server capability SHOULD have export operation' do
+ metadata do
+ id '07'
+ link 'https://build.fhir.org/ig/HL7/bulk-data/operations/index.html'
+ desc %(
+
+ These OperationDefinitions have been defined for this implementation guide.
+ * Export: export any data from a FHIR server
+ * Patient Export: export patient data from a FHIR server
+ * Group Export: export data for groups of patients from a FHIR server
+
+ )
+ optional
+ end
+
+ assert_operation_supported(@instance.server_capabilities, 'patient-export')
+ end
+
+ test 'FHIR server capability SHOULD have group-export operation' do
+ metadata do
+ id '07'
+ link 'https://build.fhir.org/ig/HL7/bulk-data/operations/index.html'
+ desc %(
+
+ These OperationDefinitions have been defined for this implementation guide.
+ * Export: export any data from a FHIR server
+ * Patient Export: export patient data from a FHIR server
+ * Group Export: export data for groups of patients from a FHIR server
+
+ )
+ optional
+ end
+
+ assert_operation_supported(@instance.server_capabilities, 'group-export')
+ end
+ end
+ end
+end
diff --git a/lib/app/modules/bulk_data/bulk_data_patient_export_sequence.rb b/lib/app/modules/bulk_data/bulk_data_patient_export_sequence.rb
new file mode 100644
index 000000000..7f0ae69eb
--- /dev/null
+++ b/lib/app/modules/bulk_data/bulk_data_patient_export_sequence.rb
@@ -0,0 +1,143 @@
+# frozen_string_literal: true
+
+module Inferno
+ module Sequence
+ class BulkDataPatientExportSequence < SequenceBase
+ group 'Bulk Data Patient Export'
+
+ title 'Patient Tests'
+
+ description 'Verify that Patient resources on the Bulk Data server follow the Bulk Data Access Implementation Guide'
+
+ test_id_prefix 'Patient'
+
+ requires :token
+ conformance_supports :Patient
+
+ def assert_export_kick_off(klass)
+ reply = export_kick_off(klass)
+
+ assert_response_accepted(reply)
+ @content_location = reply.response[:headers]['content-location']
+
+ assert @content_location.present?, 'Export response header did not include "Content-Location"'
+ end
+
+ def assert_export_status(url, timeout: 180)
+ reply = export_status_check(url, timeout)
+
+ # server response status code could be 202 (still processing), 200 (complete) or 4xx/5xx error code
+ # export_status_check processes reponses with status 202 code
+ # and returns server response when status code is not 202 or timed out
+
+ skip "Server took more than #{timeout} seconds to process the request." if reply.code == 202
+
+ assert reply.code == 200, "Bad response code: expected 200, 202, but found #{reply.code}."
+
+ assert_response_content_type(reply, 'application/json')
+
+ response_body = JSON.parse(reply.body)
+
+ assert_status_reponse_required_field(response_body)
+
+ @output = response_body['output']
+ end
+
+ details %(
+
+ The #{title} Sequence tests `#{title}` operations. The operation steps will be checked for consistency against the
+ [Bulk Data Access Implementation Guide](https://build.fhir.org/ig/HL7/bulk-data/)
+
+ )
+
+ @resources_found = false
+
+ test 'Server rejects $export request without authorization' do
+ metadata do
+ id '01'
+ link 'https://build.fhir.org/ig/HL7/bulk-data/export/index.html#bulk-data-kick-off-request'
+ desc %(
+ )
+ end
+
+ @client.set_no_auth
+ skip 'Could not verify this functionality when bearer token is not set' if @instance.token.blank?
+
+ reply = export_kick_off('Patient')
+ @client.set_bearer_token(@instance.token)
+ assert_response_unauthorized reply
+ end
+
+ test 'Server shall return "202 Accepted" and "Content-location" for $export operation' do
+ metadata do
+ id '02'
+ link 'https://build.fhir.org/ig/HL7/bulk-data/export/index.html#bulk-data-kick-off-request'
+ desc %(
+ )
+ end
+
+ assert_export_kick_off('Patient')
+ end
+
+ test 'Server shall return "202 Accepted" or "200 OK"' do
+ metadata do
+ id '03'
+ link 'https://build.fhir.org/ig/HL7/bulk-data/export/index.html#bulk-data-status-request'
+ desc %(
+ )
+ end
+
+ assert_export_status(@content_location)
+ end
+
+ private
+
+ def export_kick_off(klass)
+ headers = { accept: 'application/fhir+json', prefer: 'respond-async' }
+
+ url = ''
+ url += "/#{klass}" if klass.present?
+ url += '/$export'
+
+ @client.get(url, @client.fhir_headers(headers))
+ end
+
+ def export_status_check(url, timeout)
+ wait_time = 1
+ reply = nil
+ headers = { accept: 'application/json' }
+ start = Time.now
+
+ loop do
+ reply = @client.get(url, @client.fhir_headers(headers))
+
+ wait_time = get_wait_time(wait_time, reply)
+ seconds_used = Time.now - start + wait_time
+
+ break if reply.code != 202 || seconds_used > timeout
+
+ sleep wait_time
+ end
+
+ reply
+ end
+
+ def get_wait_time(wait_time, reply)
+ retry_after = reply.response[:headers]['retry-after']
+ retry_after_int = (retry_after.presence || 0).to_i
+
+ if retry_after_int.positive?
+ retry_after_int
+ else
+ wait_time * 2
+ end
+ end
+
+ def assert_status_reponse_required_field(response_body)
+ ['transactionTime', 'request', 'requiresAccessToken', 'output', 'error'].each do |key|
+ assert response_body.key?(key), "Complete Status response did not contain \"#{key}\" as required"
+ end
+ end
+ end
+ end
+end
diff --git a/lib/app/modules/bulk_data_module.yml b/lib/app/modules/bulk_data_module.yml
new file mode 100644
index 000000000..07803092a
--- /dev/null
+++ b/lib/app/modules/bulk_data_module.yml
@@ -0,0 +1,16 @@
+name: bulk_data
+title: FHIR Bulk Data Access Implementation Guide STU1
+description: Bulk Data Access Testing
+fhir_version: stu3
+default_test_set: developer
+test_sets:
+ developer:
+ view: default
+ tests:
+ - name: Discovery
+ sequences:
+ - BulkDataCapabilityStatementSequence
+ - name: Patient export
+ sequences:
+ - BulkDataPatientExportSequence
+
diff --git a/lib/app/modules/core/capability_statement_sequence.rb b/lib/app/modules/core/capability_statement_sequence.rb
index ba8a27d91..8ead86db8 100644
--- a/lib/app/modules/core/capability_statement_sequence.rb
+++ b/lib/app/modules/core/capability_statement_sequence.rb
@@ -105,8 +105,22 @@ class CapabilityStatementSequence < SequenceBase
[http://hl7.org/fhir/DSTU2/http.html#conformance](http://hl7.org/fhir/DSTU2/http.html#conformance)
+ for STU3 FHIR:
+
+ > Applications SHALL return a Capability Statement that specifies which resource types and interactions are supported for the GET command.
+
+ [http://hl7.org/fhir/STU3/http.html#capabilities](http://hl7.org/fhir/STU3/http.html#capabilities)
+
+ or for R4 FHIR:
+
+ > Applications SHALL return a resource that describes the functionality of the server end-point.
+
+ [http://hl7.org/fhir/R4/http.html#capabilities](http://hl7.org/fhir/R4/http.html#capabilities)
+
It does this by checking that the server responds with an HTTP OK 200 status code and that the body of the
- response contains a valid [DSTU2 Conformance resource](http://hl7.org/fhir/DSTU2/conformance.html).
+ response contains a valid [DSTU2 Conformance resource](http://hl7.org/fhir/DSTU2/conformance.html),
+ [STU3 CapabilityStatement resource](http://hl7.org/fhir/STU3/capabilitystatement.html), or
+ [R4 CapabilityStatement resource](http://hl7.org/fhir/R4/capabilitystatement.html).
This test does not inspect the content of the Conformance resource to see if it contains the required information.
It only checks to see if the RESTful interaction is supported and returns a valid Conformance resource.
@@ -120,7 +134,16 @@ class CapabilityStatementSequence < SequenceBase
@conformance = @client.conformance_statement
assert_response_ok @client.reply
- assert @conformance.class == versioned_conformance_class, 'Expected valid Conformance resource.'
+ assert_valid_conformance
+
+ begin
+ @server_capabilities = Inferno::Models::ServerCapabilities.create(
+ testing_instance_id: @instance.id,
+ capabilities: @conformance.as_json
+ )
+ rescue StandardError
+ assert false, 'Capability Statement could not be parsed.'
+ end
end
end
end
diff --git a/lib/app/modules/onc_program/onc_standalone_launch_sequence.rb b/lib/app/modules/onc_program/onc_standalone_launch_sequence.rb
index c3b1f1b49..5a88248b5 100644
--- a/lib/app/modules/onc_program/onc_standalone_launch_sequence.rb
+++ b/lib/app/modules/onc_program/onc_standalone_launch_sequence.rb
@@ -11,7 +11,7 @@ class OncStandaloneLaunchSequence < StandaloneLaunchSequence
description 'Demonstrate the ONC SMART Standalone Launch Sequence.'
- test_id_prefix 'OELS'
+ test_id_prefix 'OSLS'
requires :client_id, :confidential_client, :client_secret, :oauth_authorize_endpoint, :oauth_token_endpoint, :scopes, :initiate_login_uri, :redirect_uris
diff --git a/lib/app/modules/us_core_module.yml b/lib/app/modules/us_core_module.yml
index e700775e1..cfb5e4225 100644
--- a/lib/app/modules/us_core_module.yml
+++ b/lib/app/modules/us_core_module.yml
@@ -18,7 +18,7 @@ test_sets:
- ManualRegistrationSequence
- StandaloneLaunchSequence
- EHRLaunchSequence
- - name: US Core R4
+ - name: US Core R4 Patient Based Profiles
run_all: true
sequences:
- USCoreR4AllergyintoleranceSequence
@@ -32,18 +32,18 @@ test_sets:
- USCoreR4EncounterSequence
- USCoreR4GoalSequence
- USCoreR4ImmunizationSequence
- - USCoreR4LocationSequence
- - USCoreR4MedicationSequence
- USCoreR4MedicationrequestSequence
- USCoreR4MedicationstatementSequence
- USCoreR4SmokingstatusSequence
- PediatricWeightForHeightSequence
- USCoreR4ObservationLabSequence
- PediatricBmiForAgeSequence
- - USCoreR4OrganizationSequence
- USCoreR4PatientSequence
- - USCoreR4PractitionerSequence
- - USCoreR4PractitionerroleSequence
- USCoreR4ProcedureSequence
- R4ProvenanceSequence
- USCoreR4ClinicalNotesSequence
+ - USCoreR4LocationSequence
+ - USCoreR4MedicationSequence
+ - USCoreR4OrganizationSequence
+ - USCoreR4PractitionerSequence
+ - USCoreR4PractitionerroleSequence
diff --git a/lib/app/modules/us_core_r4/pediatric_bmi_for_age_sequence.rb b/lib/app/modules/us_core_r4/pediatric_bmi_for_age_sequence.rb
index 072736d10..46815dbdf 100644
--- a/lib/app/modules/us_core_r4/pediatric_bmi_for_age_sequence.rb
+++ b/lib/app/modules/us_core_r4/pediatric_bmi_for_age_sequence.rb
@@ -45,7 +45,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [PediatricBmiForAge Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-pediatric-bmi-for-age)
+ returned will be checked for consistency against the [PediatricBmiForAge Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/pediatric-bmi-for-age)
)
@@ -92,7 +92,8 @@ def validate_resource_item(resource, property, value)
@observation = reply.try(:resource).try(:entry).try(:first).try(:resource)
@observation_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
- save_resource_ids_in_bundle(versioned_resource_class('Observation'), reply)
+ save_resource_ids_in_bundle(versioned_resource_class('Observation'), reply, Inferno::ValidationUtil::US_CORE_R4_URIS[:pediatric_bmi_age])
+ save_delayed_sequence_references(@observation)
validate_search_reply(versioned_resource_class('Observation'), reply, search_params)
end
@@ -153,6 +154,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '05'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -184,6 +186,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '06'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -251,14 +254,14 @@ def validate_resource_item(resource, property, value)
test 'Observation resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '10'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-pediatric-bmi-for-age.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/pediatric-bmi-for-age'
desc %(
)
versions :r4
end
skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
- test_resources_against_profile('Observation')
+ test_resources_against_profile('Observation', Inferno::ValidationUtil::US_CORE_R4_URIS[:pediatric_bmi_age])
end
test 'At least one of every must support element is provided in any Observation for this patient.' do
diff --git a/lib/app/modules/us_core_r4/pediatric_weight_for_height_sequence.rb b/lib/app/modules/us_core_r4/pediatric_weight_for_height_sequence.rb
index 472da6498..2224b7511 100644
--- a/lib/app/modules/us_core_r4/pediatric_weight_for_height_sequence.rb
+++ b/lib/app/modules/us_core_r4/pediatric_weight_for_height_sequence.rb
@@ -45,7 +45,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [PediatricWeightForHeight Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-pediatric-weight-for-height)
+ returned will be checked for consistency against the [PediatricWeightForHeight Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/pediatric-weight-for-height)
)
@@ -92,7 +92,8 @@ def validate_resource_item(resource, property, value)
@observation = reply.try(:resource).try(:entry).try(:first).try(:resource)
@observation_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
- save_resource_ids_in_bundle(versioned_resource_class('Observation'), reply)
+ save_resource_ids_in_bundle(versioned_resource_class('Observation'), reply, Inferno::ValidationUtil::US_CORE_R4_URIS[:pediatric_weight_height])
+ save_delayed_sequence_references(@observation)
validate_search_reply(versioned_resource_class('Observation'), reply, search_params)
end
@@ -153,6 +154,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '05'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -184,6 +186,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '06'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -251,14 +254,14 @@ def validate_resource_item(resource, property, value)
test 'Observation resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '10'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-pediatric-weight-for-height.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/pediatric-weight-for-height'
desc %(
)
versions :r4
end
skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
- test_resources_against_profile('Observation')
+ test_resources_against_profile('Observation', Inferno::ValidationUtil::US_CORE_R4_URIS[:pediatric_weight_height])
end
test 'At least one of every must support element is provided in any Observation for this patient.' do
diff --git a/lib/app/modules/us_core_r4/us_core_allergyintolerance_sequence.rb b/lib/app/modules/us_core_r4/us_core_allergyintolerance_sequence.rb
index 1ce0d3e01..31af9bc12 100644
--- a/lib/app/modules/us_core_r4/us_core_allergyintolerance_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_allergyintolerance_sequence.rb
@@ -31,7 +31,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Allergyintolerance Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-allergyintolerance)
+ returned will be checked for consistency against the [Allergyintolerance Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-allergyintolerance)
)
@@ -51,6 +51,7 @@ def validate_resource_item(resource, property, value)
patient_val = @instance.patient_id
search_params = { 'patient': patient_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('AllergyIntolerance'), search_params)
@client.set_bearer_token(@instance.token)
@@ -82,6 +83,7 @@ def validate_resource_item(resource, property, value)
@allergyintolerance = reply.try(:resource).try(:entry).try(:first).try(:resource)
@allergyintolerance_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('AllergyIntolerance'), reply)
+ save_delayed_sequence_references(@allergyintolerance)
validate_search_reply(versioned_resource_class('AllergyIntolerance'), reply, search_params)
end
@@ -89,6 +91,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '03'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -155,7 +158,7 @@ def validate_resource_item(resource, property, value)
test 'AllergyIntolerance resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '07'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-allergyintolerance.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-allergyintolerance'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_careplan_sequence.rb b/lib/app/modules/us_core_r4/us_core_careplan_sequence.rb
index 14ac40341..e91f0f73f 100644
--- a/lib/app/modules/us_core_r4/us_core_careplan_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_careplan_sequence.rb
@@ -41,7 +41,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Careplan Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-careplan)
+ returned will be checked for consistency against the [Careplan Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-careplan)
)
@@ -89,6 +89,7 @@ def validate_resource_item(resource, property, value)
@careplan = reply.try(:resource).try(:entry).try(:first).try(:resource)
@careplan_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('CarePlan'), reply)
+ save_delayed_sequence_references(@careplan)
validate_search_reply(versioned_resource_class('CarePlan'), reply, search_params)
end
@@ -96,6 +97,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '03'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -119,6 +121,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '04'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -151,6 +154,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '05'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -226,7 +230,7 @@ def validate_resource_item(resource, property, value)
test 'CarePlan resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '09'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-careplan.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-careplan'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_careteam_sequence.rb b/lib/app/modules/us_core_r4/us_core_careteam_sequence.rb
index b88f600cc..507bb20fb 100644
--- a/lib/app/modules/us_core_r4/us_core_careteam_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_careteam_sequence.rb
@@ -31,7 +31,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Careteam Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-careteam)
+ returned will be checked for consistency against the [Careteam Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-careteam)
)
@@ -79,6 +79,7 @@ def validate_resource_item(resource, property, value)
@careteam = reply.try(:resource).try(:entry).try(:first).try(:resource)
@careteam_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('CareTeam'), reply)
+ save_delayed_sequence_references(@careteam)
validate_search_reply(versioned_resource_class('CareTeam'), reply, search_params)
end
@@ -130,7 +131,7 @@ def validate_resource_item(resource, property, value)
test 'CareTeam resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '06'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-careteam.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-careteam'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_condition_sequence.rb b/lib/app/modules/us_core_r4/us_core_condition_sequence.rb
index 27615ebfe..68c76b689 100644
--- a/lib/app/modules/us_core_r4/us_core_condition_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_condition_sequence.rb
@@ -45,7 +45,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Condition Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-condition)
+ returned will be checked for consistency against the [Condition Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition)
)
@@ -65,6 +65,7 @@ def validate_resource_item(resource, property, value)
patient_val = @instance.patient_id
search_params = { 'patient': patient_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('Condition'), search_params)
@client.set_bearer_token(@instance.token)
@@ -96,6 +97,7 @@ def validate_resource_item(resource, property, value)
@condition = reply.try(:resource).try(:entry).try(:first).try(:resource)
@condition_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('Condition'), reply)
+ save_delayed_sequence_references(@condition)
validate_search_reply(versioned_resource_class('Condition'), reply, search_params)
end
@@ -103,6 +105,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '03'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -133,6 +136,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '04'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -155,6 +159,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '05'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -177,6 +182,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '06'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -243,7 +249,7 @@ def validate_resource_item(resource, property, value)
test 'Condition resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '10'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-condition.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_device_sequence.rb b/lib/app/modules/us_core_r4/us_core_device_sequence.rb
index 18ac82ea1..fc099f4dd 100644
--- a/lib/app/modules/us_core_r4/us_core_device_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_device_sequence.rb
@@ -31,7 +31,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Device Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-device)
+ returned will be checked for consistency against the [Device Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-device)
)
@@ -51,6 +51,7 @@ def validate_resource_item(resource, property, value)
patient_val = @instance.patient_id
search_params = { 'patient': patient_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('Device'), search_params)
@client.set_bearer_token(@instance.token)
@@ -82,6 +83,7 @@ def validate_resource_item(resource, property, value)
@device = reply.try(:resource).try(:entry).try(:first).try(:resource)
@device_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('Device'), reply)
+ save_delayed_sequence_references(@device)
validate_search_reply(versioned_resource_class('Device'), reply, search_params)
end
@@ -89,6 +91,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '03'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -155,7 +158,7 @@ def validate_resource_item(resource, property, value)
test 'Device resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '07'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-device.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-device'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_diagnosticreport_lab_sequence.rb b/lib/app/modules/us_core_r4/us_core_diagnosticreport_lab_sequence.rb
index abcbfd3e9..6760be109 100644
--- a/lib/app/modules/us_core_r4/us_core_diagnosticreport_lab_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_diagnosticreport_lab_sequence.rb
@@ -45,7 +45,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [DiagnosticreportLab Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-diagnosticreport-lab)
+ returned will be checked for consistency against the [DiagnosticreportLab Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-diagnosticreport-lab)
)
@@ -92,7 +92,8 @@ def validate_resource_item(resource, property, value)
@diagnosticreport = reply.try(:resource).try(:entry).try(:first).try(:resource)
@diagnosticreport_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
- save_resource_ids_in_bundle(versioned_resource_class('DiagnosticReport'), reply)
+ save_resource_ids_in_bundle(versioned_resource_class('DiagnosticReport'), reply, Inferno::ValidationUtil::US_CORE_R4_URIS[:diagnostic_report_lab])
+ save_delayed_sequence_references(@diagnosticreport)
validate_search_reply(versioned_resource_class('DiagnosticReport'), reply, search_params)
end
@@ -153,6 +154,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '05'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -184,6 +186,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '06'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -206,6 +209,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '07'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -225,6 +229,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '08'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -315,14 +320,14 @@ def validate_resource_item(resource, property, value)
test 'DiagnosticReport resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '13'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-diagnosticreport-lab.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-diagnosticreport-lab'
desc %(
)
versions :r4
end
skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
- test_resources_against_profile('DiagnosticReport')
+ test_resources_against_profile('DiagnosticReport', Inferno::ValidationUtil::US_CORE_R4_URIS[:diagnostic_report_lab])
end
test 'At least one of every must support element is provided in any DiagnosticReport for this patient.' do
diff --git a/lib/app/modules/us_core_r4/us_core_diagnosticreport_note_sequence.rb b/lib/app/modules/us_core_r4/us_core_diagnosticreport_note_sequence.rb
index f5004464a..f423aadd5 100644
--- a/lib/app/modules/us_core_r4/us_core_diagnosticreport_note_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_diagnosticreport_note_sequence.rb
@@ -45,7 +45,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [DiagnosticreportNote Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-diagnosticreport-note)
+ returned will be checked for consistency against the [DiagnosticreportNote Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-diagnosticreport-note)
)
@@ -92,7 +92,8 @@ def validate_resource_item(resource, property, value)
@diagnosticreport = reply.try(:resource).try(:entry).try(:first).try(:resource)
@diagnosticreport_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
- save_resource_ids_in_bundle(versioned_resource_class('DiagnosticReport'), reply)
+ save_resource_ids_in_bundle(versioned_resource_class('DiagnosticReport'), reply, Inferno::ValidationUtil::US_CORE_R4_URIS[:diagnostic_report_note])
+ save_delayed_sequence_references(@diagnosticreport)
validate_search_reply(versioned_resource_class('DiagnosticReport'), reply, search_params)
end
@@ -153,6 +154,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '05'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -184,6 +186,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '06'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -206,6 +209,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '07'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -225,6 +229,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '08'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -315,14 +320,14 @@ def validate_resource_item(resource, property, value)
test 'DiagnosticReport resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '13'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-diagnosticreport-note.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-diagnosticreport-note'
desc %(
)
versions :r4
end
skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
- test_resources_against_profile('DiagnosticReport')
+ test_resources_against_profile('DiagnosticReport', Inferno::ValidationUtil::US_CORE_R4_URIS[:diagnostic_report_note])
end
test 'At least one of every must support element is provided in any DiagnosticReport for this patient.' do
diff --git a/lib/app/modules/us_core_r4/us_core_documentreference_sequence.rb b/lib/app/modules/us_core_r4/us_core_documentreference_sequence.rb
index a24f08210..a901a219b 100644
--- a/lib/app/modules/us_core_r4/us_core_documentreference_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_documentreference_sequence.rb
@@ -53,7 +53,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Documentreference Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-documentreference)
+ returned will be checked for consistency against the [Documentreference Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-documentreference)
)
@@ -73,6 +73,7 @@ def validate_resource_item(resource, property, value)
patient_val = @instance.patient_id
search_params = { 'patient': patient_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('DocumentReference'), search_params)
@client.set_bearer_token(@instance.token)
@@ -104,6 +105,7 @@ def validate_resource_item(resource, property, value)
@documentreference = reply.try(:resource).try(:entry).try(:first).try(:resource)
@documentreference_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('DocumentReference'), reply)
+ save_delayed_sequence_references(@documentreference)
validate_search_reply(versioned_resource_class('DocumentReference'), reply, search_params)
end
@@ -199,6 +201,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '07'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -221,6 +224,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '08'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -311,7 +315,7 @@ def validate_resource_item(resource, property, value)
test 'DocumentReference resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '13'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-documentreference.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-documentreference'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_encounter_sequence.rb b/lib/app/modules/us_core_r4/us_core_encounter_sequence.rb
index ec408e5a9..d196b2c4e 100644
--- a/lib/app/modules/us_core_r4/us_core_encounter_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_encounter_sequence.rb
@@ -53,7 +53,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Encounter Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-encounter)
+ returned will be checked for consistency against the [Encounter Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter)
)
@@ -73,6 +73,7 @@ def validate_resource_item(resource, property, value)
patient_val = @instance.patient_id
search_params = { 'patient': patient_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('Encounter'), search_params)
@client.set_bearer_token(@instance.token)
@@ -104,6 +105,7 @@ def validate_resource_item(resource, property, value)
@encounter = reply.try(:resource).try(:entry).try(:first).try(:resource)
@encounter_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('Encounter'), reply)
+ save_delayed_sequence_references(@encounter)
validate_search_reply(versioned_resource_class('Encounter'), reply, search_params)
end
@@ -162,6 +164,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '05'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -183,6 +186,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '06'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -205,6 +209,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '07'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -227,6 +232,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '08'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -293,7 +299,7 @@ def validate_resource_item(resource, property, value)
test 'Encounter resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '12'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-encounter.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_goal_sequence.rb b/lib/app/modules/us_core_r4/us_core_goal_sequence.rb
index 033e8f5f4..9c155df24 100644
--- a/lib/app/modules/us_core_r4/us_core_goal_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_goal_sequence.rb
@@ -37,7 +37,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Goal Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-goal)
+ returned will be checked for consistency against the [Goal Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-goal)
)
@@ -57,6 +57,7 @@ def validate_resource_item(resource, property, value)
patient_val = @instance.patient_id
search_params = { 'patient': patient_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('Goal'), search_params)
@client.set_bearer_token(@instance.token)
@@ -88,6 +89,7 @@ def validate_resource_item(resource, property, value)
@goal = reply.try(:resource).try(:entry).try(:first).try(:resource)
@goal_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('Goal'), reply)
+ save_delayed_sequence_references(@goal)
validate_search_reply(versioned_resource_class('Goal'), reply, search_params)
end
@@ -95,6 +97,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '03'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -125,6 +128,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '04'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -191,7 +195,7 @@ def validate_resource_item(resource, property, value)
test 'Goal resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '08'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-goal.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-goal'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_immunization_sequence.rb b/lib/app/modules/us_core_r4/us_core_immunization_sequence.rb
index f20b53d88..fae1ad326 100644
--- a/lib/app/modules/us_core_r4/us_core_immunization_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_immunization_sequence.rb
@@ -37,7 +37,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Immunization Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-immunization)
+ returned will be checked for consistency against the [Immunization Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-immunization)
)
@@ -57,6 +57,7 @@ def validate_resource_item(resource, property, value)
patient_val = @instance.patient_id
search_params = { 'patient': patient_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('Immunization'), search_params)
@client.set_bearer_token(@instance.token)
@@ -88,6 +89,7 @@ def validate_resource_item(resource, property, value)
@immunization = reply.try(:resource).try(:entry).try(:first).try(:resource)
@immunization_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('Immunization'), reply)
+ save_delayed_sequence_references(@immunization)
validate_search_reply(versioned_resource_class('Immunization'), reply, search_params)
end
@@ -95,6 +97,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '03'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -125,6 +128,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '04'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -191,7 +195,7 @@ def validate_resource_item(resource, property, value)
test 'Immunization resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '08'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-immunization.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-immunization'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_location_sequence.rb b/lib/app/modules/us_core_r4/us_core_location_sequence.rb
index 00881a850..30e308a3d 100644
--- a/lib/app/modules/us_core_r4/us_core_location_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_location_sequence.rb
@@ -11,8 +11,9 @@ class USCoreR4LocationSequence < SequenceBase
test_id_prefix 'Location' # change me
- requires :token, :patient_id
+ requires :token
conformance_supports :Location
+ delayed_sequence
def validate_resource_item(resource, property, value)
case property
@@ -22,7 +23,7 @@ def validate_resource_item(resource, property, value)
assert value_found, 'name on resource does not match name requested'
when 'address'
- value_found = can_resolve_path(resource, 'address') { |value_in_resource| value_in_resource == value }
+ value_found = can_resolve_path(resource, 'address.city') { |value_in_resource| value_in_resource == value }
assert value_found, 'address on resource does not match address requested'
when 'address-city'
@@ -43,15 +44,30 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Location Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-location)
+ returned will be checked for consistency against the [Location Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-location)
)
@resources_found = false
- test 'Server rejects Location search without authorization' do
+ test 'Can read Location from the server' do
metadata do
id '01'
+ link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ desc %(
+ )
+ versions :r4
+ end
+
+ location_id = @instance.resource_references.find { |reference| reference.resource_type == 'Location' }&.resource_id
+ skip 'No Location references found from the prior searches' if location_id.nil?
+ @location = fetch_resource('Location', location_id)
+ @resources_found = !@location.nil?
+ end
+
+ test 'Server rejects Location search without authorization' do
+ metadata do
+ id '02'
link 'http://www.fhir.org/guides/argonaut/r2/Conformance-server.html'
desc %(
)
@@ -61,7 +77,9 @@ def validate_resource_item(resource, property, value)
@client.set_no_auth
skip 'Could not verify this functionality when bearer token is not set' if @instance.token.blank?
- search_params = { patient: @instance.patient_id, name: 'Boston' }
+ name_val = resolve_element_from_path(@location, 'name')
+ search_params = { 'name': name_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('Location'), search_params)
@client.set_bearer_token(@instance.token)
@@ -70,14 +88,16 @@ def validate_resource_item(resource, property, value)
test 'Server returns expected results from Location search by name' do
metadata do
- id '02'
+ id '03'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
desc %(
)
versions :r4
end
- search_params = { patient: @instance.patient_id, name: 'Boston' }
+ name_val = resolve_element_from_path(@location, 'name')
+ search_params = { 'name': name_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('Location'), search_params)
assert_response_ok(reply)
@@ -91,12 +111,13 @@ def validate_resource_item(resource, property, value)
@location = reply.try(:resource).try(:entry).try(:first).try(:resource)
@location_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('Location'), reply)
+ save_delayed_sequence_references(@location)
validate_search_reply(versioned_resource_class('Location'), reply, search_params)
end
test 'Server returns expected results from Location search by address' do
metadata do
- id '03'
+ id '04'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
desc %(
)
@@ -106,7 +127,7 @@ def validate_resource_item(resource, property, value)
skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
assert !@location.nil?, 'Expected valid Location resource to be present'
- address_val = resolve_element_from_path(@location, 'address')
+ address_val = resolve_element_from_path(@location, 'address.city')
search_params = { 'address': address_val }
search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
@@ -117,8 +138,9 @@ def validate_resource_item(resource, property, value)
test 'Server returns expected results from Location search by address-city' do
metadata do
- id '04'
+ id '05'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -138,8 +160,9 @@ def validate_resource_item(resource, property, value)
test 'Server returns expected results from Location search by address-state' do
metadata do
- id '05'
+ id '06'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -159,8 +182,9 @@ def validate_resource_item(resource, property, value)
test 'Server returns expected results from Location search by address-postalcode' do
metadata do
- id '06'
+ id '07'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -178,21 +202,6 @@ def validate_resource_item(resource, property, value)
assert_response_ok(reply)
end
- test 'Location read resource supported' do
- metadata do
- id '07'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
- desc %(
- )
- versions :r4
- end
-
- skip_if_not_supported(:Location, [:read])
- skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
-
- validate_read_reply(@location, versioned_resource_class('Location'))
- end
-
test 'Location vread resource supported' do
metadata do
id '08'
@@ -226,7 +235,7 @@ def validate_resource_item(resource, property, value)
test 'Location resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '10'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-location.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-location'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_medication_sequence.rb b/lib/app/modules/us_core_r4/us_core_medication_sequence.rb
index 6543d5242..42ed88a8c 100644
--- a/lib/app/modules/us_core_r4/us_core_medication_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_medication_sequence.rb
@@ -11,19 +11,20 @@ class USCoreR4MedicationSequence < SequenceBase
test_id_prefix 'Medication' # change me
- requires :token, :patient_id
+ requires :token
conformance_supports :Medication
+ delayed_sequence
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Medication Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-medication)
+ returned will be checked for consistency against the [Medication Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-medication)
)
@resources_found = false
- test 'Medication read resource supported' do
+ test 'Can read Medication from the server' do
metadata do
id '01'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
@@ -32,10 +33,10 @@ class USCoreR4MedicationSequence < SequenceBase
versions :r4
end
- skip_if_not_supported(:Medication, [:read])
- skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
-
- validate_read_reply(@medication, versioned_resource_class('Medication'))
+ medication_id = @instance.resource_references.find { |reference| reference.resource_type == 'Medication' }&.resource_id
+ skip 'No Medication references found from the prior searches' if medication_id.nil?
+ @medication = fetch_resource('Medication', medication_id)
+ @resources_found = !@medication.nil?
end
test 'Medication vread resource supported' do
@@ -71,7 +72,7 @@ class USCoreR4MedicationSequence < SequenceBase
test 'Medication resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '04'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-medication.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-medication'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_medicationrequest_sequence.rb b/lib/app/modules/us_core_r4/us_core_medicationrequest_sequence.rb
index 7c5cf4b96..289efd0c9 100644
--- a/lib/app/modules/us_core_r4/us_core_medicationrequest_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_medicationrequest_sequence.rb
@@ -35,7 +35,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Medicationrequest Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-medicationrequest)
+ returned will be checked for consistency against the [Medicationrequest Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-medicationrequest)
)
@@ -55,6 +55,7 @@ def validate_resource_item(resource, property, value)
patient_val = @instance.patient_id
search_params = { 'patient': patient_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('MedicationRequest'), search_params)
@client.set_bearer_token(@instance.token)
@@ -86,6 +87,7 @@ def validate_resource_item(resource, property, value)
@medicationrequest = reply.try(:resource).try(:entry).try(:first).try(:resource)
@medicationrequest_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('MedicationRequest'), reply)
+ save_delayed_sequence_references(@medicationrequest)
validate_search_reply(versioned_resource_class('MedicationRequest'), reply, search_params)
end
@@ -115,6 +117,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '04'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -181,7 +184,7 @@ def validate_resource_item(resource, property, value)
test 'MedicationRequest resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '08'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-medicationrequest.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-medicationrequest'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_medicationstatement_sequence.rb b/lib/app/modules/us_core_r4/us_core_medicationstatement_sequence.rb
index 5081eb44d..b18841b65 100644
--- a/lib/app/modules/us_core_r4/us_core_medicationstatement_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_medicationstatement_sequence.rb
@@ -37,7 +37,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Medicationstatement Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-medicationstatement)
+ returned will be checked for consistency against the [Medicationstatement Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-medicationstatement)
)
@@ -57,6 +57,7 @@ def validate_resource_item(resource, property, value)
patient_val = @instance.patient_id
search_params = { 'patient': patient_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('MedicationStatement'), search_params)
@client.set_bearer_token(@instance.token)
@@ -88,6 +89,7 @@ def validate_resource_item(resource, property, value)
@medicationstatement = reply.try(:resource).try(:entry).try(:first).try(:resource)
@medicationstatement_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('MedicationStatement'), reply)
+ save_delayed_sequence_references(@medicationstatement)
validate_search_reply(versioned_resource_class('MedicationStatement'), reply, search_params)
end
@@ -95,6 +97,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '03'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -125,6 +128,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '04'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -191,7 +195,7 @@ def validate_resource_item(resource, property, value)
test 'MedicationStatement resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '08'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-medicationstatement.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-medicationstatement'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_observation_lab_sequence.rb b/lib/app/modules/us_core_r4/us_core_observation_lab_sequence.rb
index a2b658ad0..83288e8c8 100644
--- a/lib/app/modules/us_core_r4/us_core_observation_lab_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_observation_lab_sequence.rb
@@ -45,7 +45,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [ObservationLab Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-observation-lab)
+ returned will be checked for consistency against the [ObservationLab Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-lab)
)
@@ -92,7 +92,8 @@ def validate_resource_item(resource, property, value)
@observation = reply.try(:resource).try(:entry).try(:first).try(:resource)
@observation_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
- save_resource_ids_in_bundle(versioned_resource_class('Observation'), reply)
+ save_resource_ids_in_bundle(versioned_resource_class('Observation'), reply, Inferno::ValidationUtil::US_CORE_R4_URIS[:lab_results])
+ save_delayed_sequence_references(@observation)
validate_search_reply(versioned_resource_class('Observation'), reply, search_params)
end
@@ -153,6 +154,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '05'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -184,6 +186,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '06'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -251,14 +254,14 @@ def validate_resource_item(resource, property, value)
test 'Observation resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '10'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-observation-lab.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-lab'
desc %(
)
versions :r4
end
skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
- test_resources_against_profile('Observation')
+ test_resources_against_profile('Observation', Inferno::ValidationUtil::US_CORE_R4_URIS[:lab_results])
end
test 'At least one of every must support element is provided in any Observation for this patient.' do
diff --git a/lib/app/modules/us_core_r4/us_core_organization_sequence.rb b/lib/app/modules/us_core_r4/us_core_organization_sequence.rb
index 474d93d13..2084fef6b 100644
--- a/lib/app/modules/us_core_r4/us_core_organization_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_organization_sequence.rb
@@ -11,8 +11,9 @@ class USCoreR4OrganizationSequence < SequenceBase
test_id_prefix 'Organization' # change me
- requires :token, :patient_id
+ requires :token
conformance_supports :Organization
+ delayed_sequence
def validate_resource_item(resource, property, value)
case property
@@ -22,7 +23,7 @@ def validate_resource_item(resource, property, value)
assert value_found, 'name on resource does not match name requested'
when 'address'
- value_found = can_resolve_path(resource, 'address') { |value_in_resource| value_in_resource == value }
+ value_found = can_resolve_path(resource, 'address.city') { |value_in_resource| value_in_resource == value }
assert value_found, 'address on resource does not match address requested'
end
@@ -31,15 +32,30 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Organization Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-organization)
+ returned will be checked for consistency against the [Organization Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-organization)
)
@resources_found = false
- test 'Server rejects Organization search without authorization' do
+ test 'Can read Organization from the server' do
metadata do
id '01'
+ link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ desc %(
+ )
+ versions :r4
+ end
+
+ organization_id = @instance.resource_references.find { |reference| reference.resource_type == 'Organization' }&.resource_id
+ skip 'No Organization references found from the prior searches' if organization_id.nil?
+ @organization = fetch_resource('Organization', organization_id)
+ @resources_found = !@organization.nil?
+ end
+
+ test 'Server rejects Organization search without authorization' do
+ metadata do
+ id '02'
link 'http://www.fhir.org/guides/argonaut/r2/Conformance-server.html'
desc %(
)
@@ -49,7 +65,9 @@ def validate_resource_item(resource, property, value)
@client.set_no_auth
skip 'Could not verify this functionality when bearer token is not set' if @instance.token.blank?
- search_params = { patient: @instance.patient_id, name: 'Boston' }
+ name_val = resolve_element_from_path(@organization, 'name')
+ search_params = { 'name': name_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('Organization'), search_params)
@client.set_bearer_token(@instance.token)
@@ -58,14 +76,16 @@ def validate_resource_item(resource, property, value)
test 'Server returns expected results from Organization search by name' do
metadata do
- id '02'
+ id '03'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
desc %(
)
versions :r4
end
- search_params = { patient: @instance.patient_id, name: 'Boston' }
+ name_val = resolve_element_from_path(@organization, 'name')
+ search_params = { 'name': name_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('Organization'), search_params)
assert_response_ok(reply)
@@ -79,12 +99,13 @@ def validate_resource_item(resource, property, value)
@organization = reply.try(:resource).try(:entry).try(:first).try(:resource)
@organization_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('Organization'), reply)
+ save_delayed_sequence_references(@organization)
validate_search_reply(versioned_resource_class('Organization'), reply, search_params)
end
test 'Server returns expected results from Organization search by address' do
metadata do
- id '03'
+ id '04'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
desc %(
)
@@ -94,7 +115,7 @@ def validate_resource_item(resource, property, value)
skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
assert !@organization.nil?, 'Expected valid Organization resource to be present'
- address_val = resolve_element_from_path(@organization, 'address')
+ address_val = resolve_element_from_path(@organization, 'address.city')
search_params = { 'address': address_val }
search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
@@ -103,21 +124,6 @@ def validate_resource_item(resource, property, value)
assert_response_ok(reply)
end
- test 'Organization read resource supported' do
- metadata do
- id '04'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
- desc %(
- )
- versions :r4
- end
-
- skip_if_not_supported(:Organization, [:read])
- skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
-
- validate_read_reply(@organization, versioned_resource_class('Organization'))
- end
-
test 'Organization vread resource supported' do
metadata do
id '05'
@@ -151,7 +157,7 @@ def validate_resource_item(resource, property, value)
test 'Organization resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '07'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-organization.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-organization'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_patient_sequence.rb b/lib/app/modules/us_core_r4/us_core_patient_sequence.rb
index 05a662335..71fcf848e 100644
--- a/lib/app/modules/us_core_r4/us_core_patient_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_patient_sequence.rb
@@ -60,7 +60,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Patient Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-patient)
+ returned will be checked for consistency against the [Patient Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient)
)
@@ -108,6 +108,7 @@ def validate_resource_item(resource, property, value)
@patient = reply.try(:resource).try(:entry).try(:first).try(:resource)
@patient_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('Patient'), reply)
+ save_delayed_sequence_references(@patient)
validate_search_reply(versioned_resource_class('Patient'), reply, search_params)
end
@@ -201,6 +202,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '07'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -223,6 +225,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '08'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -289,7 +292,7 @@ def validate_resource_item(resource, property, value)
test 'Patient resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '12'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-patient.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_practitioner_sequence.rb b/lib/app/modules/us_core_r4/us_core_practitioner_sequence.rb
index cba4f623a..ed8fc3ec5 100644
--- a/lib/app/modules/us_core_r4/us_core_practitioner_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_practitioner_sequence.rb
@@ -11,8 +11,9 @@ class USCoreR4PractitionerSequence < SequenceBase
test_id_prefix 'Practitioner' # change me
- requires :token, :patient_id
+ requires :token
conformance_supports :Practitioner
+ delayed_sequence
def validate_resource_item(resource, property, value)
case property
@@ -38,15 +39,30 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Practitioner Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-practitioner)
+ returned will be checked for consistency against the [Practitioner Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner)
)
@resources_found = false
- test 'Server rejects Practitioner search without authorization' do
+ test 'Can read Practitioner from the server' do
metadata do
id '01'
+ link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ desc %(
+ )
+ versions :r4
+ end
+
+ practitioner_id = @instance.resource_references.find { |reference| reference.resource_type == 'Practitioner' }&.resource_id
+ skip 'No Practitioner references found from the prior searches' if practitioner_id.nil?
+ @practitioner = fetch_resource('Practitioner', practitioner_id)
+ @resources_found = !@practitioner.nil?
+ end
+
+ test 'Server rejects Practitioner search without authorization' do
+ metadata do
+ id '02'
link 'http://www.fhir.org/guides/argonaut/r2/Conformance-server.html'
desc %(
)
@@ -56,8 +72,9 @@ def validate_resource_item(resource, property, value)
@client.set_no_auth
skip 'Could not verify this functionality when bearer token is not set' if @instance.token.blank?
- name_val = @practitioner&.name&.first&.family
+ name_val = resolve_element_from_path(@practitioner, 'name.family')
search_params = { 'name': name_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('Practitioner'), search_params)
@client.set_bearer_token(@instance.token)
@@ -66,7 +83,7 @@ def validate_resource_item(resource, property, value)
test 'Server returns expected results from Practitioner search by name' do
metadata do
- id '02'
+ id '03'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
desc %(
)
@@ -89,12 +106,13 @@ def validate_resource_item(resource, property, value)
@practitioner = reply.try(:resource).try(:entry).try(:first).try(:resource)
@practitioner_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('Practitioner'), reply)
+ save_delayed_sequence_references(@practitioner)
validate_search_reply(versioned_resource_class('Practitioner'), reply, search_params)
end
test 'Server returns expected results from Practitioner search by identifier' do
metadata do
- id '03'
+ id '04'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
desc %(
)
@@ -113,21 +131,6 @@ def validate_resource_item(resource, property, value)
assert_response_ok(reply)
end
- test 'Practitioner read resource supported' do
- metadata do
- id '04'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
- desc %(
- )
- versions :r4
- end
-
- skip_if_not_supported(:Practitioner, [:read])
- skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
-
- validate_read_reply(@practitioner, versioned_resource_class('Practitioner'))
- end
-
test 'Practitioner vread resource supported' do
metadata do
id '05'
@@ -161,7 +164,7 @@ def validate_resource_item(resource, property, value)
test 'Practitioner resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '07'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-practitioner.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_practitionerrole_sequence.rb b/lib/app/modules/us_core_r4/us_core_practitionerrole_sequence.rb
index 0d38b973f..b22d017a3 100644
--- a/lib/app/modules/us_core_r4/us_core_practitionerrole_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_practitionerrole_sequence.rb
@@ -11,8 +11,9 @@ class USCoreR4PractitionerroleSequence < SequenceBase
test_id_prefix 'PractitionerRole' # change me
- requires :token, :patient_id
+ requires :token
conformance_supports :PractitionerRole
+ delayed_sequence
def validate_resource_item(resource, property, value)
case property
@@ -31,15 +32,30 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Practitionerrole Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-practitionerrole)
+ returned will be checked for consistency against the [Practitionerrole Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitionerrole)
)
@resources_found = false
- test 'Server rejects PractitionerRole search without authorization' do
+ test 'Can read PractitionerRole from the server' do
metadata do
id '01'
+ link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ desc %(
+ )
+ versions :r4
+ end
+
+ practitionerrole_id = @instance.resource_references.find { |reference| reference.resource_type == 'PractitionerRole' }&.resource_id
+ skip 'No PractitionerRole references found from the prior searches' if practitionerrole_id.nil?
+ @practitionerrole = fetch_resource('PractitionerRole', practitionerrole_id)
+ @resources_found = !@practitionerrole.nil?
+ end
+
+ test 'Server rejects PractitionerRole search without authorization' do
+ metadata do
+ id '02'
link 'http://www.fhir.org/guides/argonaut/r2/Conformance-server.html'
desc %(
)
@@ -49,8 +65,9 @@ def validate_resource_item(resource, property, value)
@client.set_no_auth
skip 'Could not verify this functionality when bearer token is not set' if @instance.token.blank?
- specialty_val = @practitionerrole&.specialty&.coding&.first&.code
+ specialty_val = resolve_element_from_path(@practitionerrole, 'specialty.coding.code')
search_params = { 'specialty': specialty_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('PractitionerRole'), search_params)
@client.set_bearer_token(@instance.token)
@@ -59,7 +76,7 @@ def validate_resource_item(resource, property, value)
test 'Server returns expected results from PractitionerRole search by specialty' do
metadata do
- id '02'
+ id '03'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
desc %(
)
@@ -82,12 +99,13 @@ def validate_resource_item(resource, property, value)
@practitionerrole = reply.try(:resource).try(:entry).try(:first).try(:resource)
@practitionerrole_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('PractitionerRole'), reply)
+ save_delayed_sequence_references(@practitionerrole)
validate_search_reply(versioned_resource_class('PractitionerRole'), reply, search_params)
end
test 'Server returns expected results from PractitionerRole search by practitioner' do
metadata do
- id '03'
+ id '04'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
desc %(
)
@@ -106,21 +124,6 @@ def validate_resource_item(resource, property, value)
assert_response_ok(reply)
end
- test 'PractitionerRole read resource supported' do
- metadata do
- id '04'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
- desc %(
- )
- versions :r4
- end
-
- skip_if_not_supported(:PractitionerRole, [:read])
- skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
-
- validate_read_reply(@practitionerrole, versioned_resource_class('PractitionerRole'))
- end
-
test 'PractitionerRole vread resource supported' do
metadata do
id '05'
@@ -154,7 +157,7 @@ def validate_resource_item(resource, property, value)
test 'PractitionerRole resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '07'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-practitionerrole.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitionerrole'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_procedure_sequence.rb b/lib/app/modules/us_core_r4/us_core_procedure_sequence.rb
index 732d469d7..408c510cd 100644
--- a/lib/app/modules/us_core_r4/us_core_procedure_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_procedure_sequence.rb
@@ -41,7 +41,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Procedure Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-procedure)
+ returned will be checked for consistency against the [Procedure Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-procedure)
)
@@ -61,6 +61,7 @@ def validate_resource_item(resource, property, value)
patient_val = @instance.patient_id
search_params = { 'patient': patient_val }
+ search_params.each { |param, value| skip "Could not resolve #{param} in given resource" if value.nil? }
reply = get_resource_by_params(versioned_resource_class('Procedure'), search_params)
@client.set_bearer_token(@instance.token)
@@ -92,6 +93,7 @@ def validate_resource_item(resource, property, value)
@procedure = reply.try(:resource).try(:entry).try(:first).try(:resource)
@procedure_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
save_resource_ids_in_bundle(versioned_resource_class('Procedure'), reply)
+ save_delayed_sequence_references(@procedure)
validate_search_reply(versioned_resource_class('Procedure'), reply, search_params)
end
@@ -129,6 +131,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '04'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -160,6 +163,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '05'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -226,7 +230,7 @@ def validate_resource_item(resource, property, value)
test 'Procedure resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '09'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-procedure.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-procedure'
desc %(
)
versions :r4
diff --git a/lib/app/modules/us_core_r4/us_core_r4_capability_statement_sequence.rb b/lib/app/modules/us_core_r4/us_core_r4_capability_statement_sequence.rb
index 537aa16ec..7905c0a73 100644
--- a/lib/app/modules/us_core_r4/us_core_r4_capability_statement_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_r4_capability_statement_sequence.rb
@@ -86,7 +86,8 @@ class UsCoreR4CapabilityStatementSequence < CapabilityStatementSequence
)
end
- assert @conformance.class == versioned_conformance_class, 'Expected valid Conformance resource'
+ assert_valid_conformance
+
formats = ['json', 'applcation/json', 'application/json+fhir', 'application/fhir+json']
assert formats.any? { |format| @conformance.format.include? format }, 'Conformance does not state support for json.'
end
@@ -115,14 +116,11 @@ class UsCoreR4CapabilityStatementSequence < CapabilityStatementSequence
'permission-patient',
'permission-user']
- assert @conformance.class == versioned_conformance_class, 'Expected valid Capability resource'
+ assert_valid_conformance
+
+ assert @server_capabilities.smart_support?, 'No SMART capabilities listed in conformance.'
- extensions = @conformance.try(:rest).try(:first).try(:security).try(:extension)
- assert !extensions.nil?, 'No SMART capabilities listed in conformance.'
- capabilities = extensions.select { |x| x.url == 'http://fhir-registry.smarthealthit.org/StructureDefinition/capabilities' }
- assert !capabilities.nil?, 'No SMART capabilities listed in capability.'
- available_capabilities = capabilities.map(&:valueCode)
- missing_capabilities = (required_capabilities - available_capabilities)
+ missing_capabilities = (required_capabilities - @server_capabilities.smart_capabilities)
assert missing_capabilities.empty?, "Conformance statement does not list required SMART capabilties: #{missing_capabilities.join(', ')}"
end
@@ -140,16 +138,7 @@ class UsCoreR4CapabilityStatementSequence < CapabilityStatementSequence
)
end
- assert @conformance.class == versioned_conformance_class, 'Expected valid Capability resource'
-
- begin
- Inferno::Models::ServerCapabilities.create(
- testing_instance_id: @instance.id,
- capabilities: @conformance.as_json
- )
- rescue StandardError
- assert false, 'Capability Statement could not be parsed.'
- end
+ assert_valid_conformance
assert @instance.conformance_supported?(:Patient, [:read]), 'Patient resource with read interaction is not listed in capability statement.'
end
diff --git a/lib/app/modules/us_core_r4/us_core_smokingstatus_sequence.rb b/lib/app/modules/us_core_r4/us_core_smokingstatus_sequence.rb
index f629acdee..7b112f01a 100644
--- a/lib/app/modules/us_core_r4/us_core_smokingstatus_sequence.rb
+++ b/lib/app/modules/us_core_r4/us_core_smokingstatus_sequence.rb
@@ -45,7 +45,7 @@ def validate_resource_item(resource, property, value)
details %(
The #{title} Sequence tests `#{title.gsub(/\s+/, '')}` resources associated with the provided patient. The resources
- returned will be checked for consistency against the [Smokingstatus Argonaut Profile](https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-smokingstatus)
+ returned will be checked for consistency against the [Smokingstatus Argonaut Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-smokingstatus)
)
@@ -92,7 +92,8 @@ def validate_resource_item(resource, property, value)
@observation = reply.try(:resource).try(:entry).try(:first).try(:resource)
@observation_ary = reply&.resource&.entry&.map { |entry| entry&.resource }
- save_resource_ids_in_bundle(versioned_resource_class('Observation'), reply)
+ save_resource_ids_in_bundle(versioned_resource_class('Observation'), reply, Inferno::ValidationUtil::US_CORE_R4_URIS[:smoking_status])
+ save_delayed_sequence_references(@observation)
validate_search_reply(versioned_resource_class('Observation'), reply, search_params)
end
@@ -153,6 +154,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '05'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -184,6 +186,7 @@ def validate_resource_item(resource, property, value)
metadata do
id '06'
link 'https://build.fhir.org/ig/HL7/US-Core-R4/CapabilityStatement-us-core-server.html'
+ optional
desc %(
)
versions :r4
@@ -251,14 +254,14 @@ def validate_resource_item(resource, property, value)
test 'Observation resources associated with Patient conform to US Core R4 profiles' do
metadata do
id '10'
- link 'https://build.fhir.org/ig/HL7/US-Core-R4/StructureDefinition-us-core-smokingstatus.json'
+ link 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-smokingstatus'
desc %(
)
versions :r4
end
skip 'No resources appear to be available for this patient. Please use patients with more information.' unless @resources_found
- test_resources_against_profile('Observation')
+ test_resources_against_profile('Observation', Inferno::ValidationUtil::US_CORE_R4_URIS[:smoking_status])
end
test 'At least one of every must support element is provided in any Observation for this patient.' do
diff --git a/lib/app/sequence_base.rb b/lib/app/sequence_base.rb
index e972b12d6..e997773b2 100644
--- a/lib/app/sequence_base.rb
+++ b/lib/app/sequence_base.rb
@@ -11,6 +11,7 @@
require_relative 'utils/terminology'
require_relative 'utils/result_statuses'
require_relative 'utils/search_validation'
+require_relative 'models/testing_instance'
require 'bloomer'
require 'bloomer/msgpackable'
@@ -41,6 +42,7 @@ class SequenceBase
@@optional = []
@@show_uris = []
+ @@delayed_sequences = []
@@test_id_prefixes = {}
@@ -264,6 +266,10 @@ def self.versions(*versions)
@@versions[sequence_name] || FHIR::VERSIONS
end
+ def self.delayed_sequence
+ @@delayed_sequences << sequence_name
+ end
+
def self.missing_requirements(instance, recurse = false)
return [] unless @@requires.key?(sequence_name)
@@ -350,7 +356,6 @@ def self.preconditions_met_for?(instance)
def self.extends_sequence(klass)
@@test_metadata[klass.sequence_name].each do |metadata|
@@test_metadata[sequence_name] << metadata
- @@test_metadata[sequence_name].last[:test_index] = @@test_metadata[sequence_name].length - 1
define_method metadata[:method_name], metadata[:method]
end
end
@@ -723,6 +728,22 @@ def validate_reference_resolutions(resource)
assert(problems.empty?, problems.join("
\n"))
end
+ def save_delayed_sequence_references(resource)
+ delayed_resource_types = @@conformance_supports.select { |sequence, _resources| @@delayed_sequences.include? sequence }.values.flatten
+ walk_resource(resource) do |value, meta, _path|
+ next if meta['type'] != 'Reference'
+
+ if value.relative?
+ begin
+ resource_class = value.resource_class.name.demodulize
+ @instance.save_resource_reference(resource_class, value.reference.split('/').last) if delayed_resource_types.include? resource_class.to_sym
+ rescue NameError
+ next
+ end
+ end
+ end
+ end
+
def check_resource_against_profile(resource, resource_type, specified_profile = nil)
assert resource.is_a?("FHIR::DSTU2::#{resource_type}".constantize),
"Expected resource to be of type #{resource_type}"
diff --git a/lib/app/utils/assertions.rb b/lib/app/utils/assertions.rb
index dcd67cea7..7e601a5b2 100644
--- a/lib/app/utils/assertions.rb
+++ b/lib/app/utils/assertions.rb
@@ -25,37 +25,43 @@ def assert_equal(expected, actual, message = '', data = '')
def assert_response_ok(response, error_message = '')
return if assertion_negated([200, 201].include?(response.code))
- raise AssertionException, "Bad response code: expected 200, 201, but found #{response.code}.#{' ' + error_message}" # ,response.body
+ raise AssertionException, "Bad response code: expected 200, 201, but found #{response.code}. #{error_message}"
+ end
+
+ def assert_response_accepted(response)
+ return if assertion_negated([202].include?(response.code))
+
+ raise AssertionException, "Bad response code: expected 202, but found #{response.code}"
end
def assert_response_not_found(response)
return if assertion_negated([404].include?(response.code))
- raise AssertionException, "Bad response code: expected 404, but found #{response.code}" # ,response.body
+ raise AssertionException, "Bad response code: expected 404, but found #{response.code}"
end
def assert_response_unauthorized(response)
return if assertion_negated([401, 406].include?(response.code))
- raise AssertionException, "Bad response code: expected 401 or 406, but found #{response.code}" # ,response.body
+ raise AssertionException, "Bad response code: expected 401 or 406, but found #{response.code}"
end
def assert_response_bad_or_unauthorized(response)
return if assertion_negated([400, 401].include?(response.code))
- raise AssertionException, "Bad response code: expected 400 or 401, but found #{response.code}" # ,response.body
+ raise AssertionException, "Bad response code: expected 400 or 401, but found #{response.code}"
end
def assert_response_bad(response)
return if assertion_negated([400].include?(response.code))
- raise AssertionException, "Bad response code: expected 400, but found #{response.code}" # ,response.body
+ raise AssertionException, "Bad response code: expected 400, but found #{response.code}"
end
def assert_response_conflict(response)
return if assertion_negated([409, 412].include?(response.code))
- raise AssertionException, "Bad response code: expected 409 or 412, but found #{response.code}" # ,response.body
+ raise AssertionException, "Bad response code: expected 409 or 412, but found #{response.code}"
end
def assert_navigation_links(bundle)
@@ -74,7 +80,7 @@ def assert_bundle_response(response)
rescue StandardError
found = nil
end
- raise AssertionException, "Expected FHIR Bundle but found: #{found.class.name.demodulize}" # ,response.body
+ raise AssertionException, "Expected FHIR Bundle but found: #{found.class.name.demodulize}"
end
def assert_bundle_transactions_okay(response)
@@ -90,14 +96,14 @@ def assert_bundle_transactions_okay(response)
end
end
- def assert_resource_content_type(client_reply, content_type)
+ def assert_response_content_type(client_reply, content_type)
header = client_reply.response[:headers]['content-type']
response_content_type = header
response_content_type = header[0, header.index(';')] unless header.index(';').nil?
- return if assertion_negated(response_content_type == "application/fhir+#{content_type}")
+ return if assertion_negated(response_content_type == content_type)
- raise AssertionException.new "Expected content-type application/fhir+#{content_type} but found #{response_content_type}", response_content_type
+ raise AssertionException.new "Expected content-type #{content_type} but found #{response_content_type}", response_content_type
end
# Based on MIME Types defined in
@@ -138,13 +144,13 @@ def assert_valid_content_location_present(client_reply)
def assert_response_code(response, code)
return if assertion_negated(code.to_s == response.code.to_s)
- raise AssertionException, "Bad response code: expected #{code}, but found #{response.code}" # ,response.body
+ raise AssertionException, "Bad response code: expected #{code}, but found #{response.code}"
end
def assert_resource_type(response, resource_type)
return if assertion_negated(!response.resource.nil? && response.resource.class == resource_type)
- raise AssertionException, "Bad response type: expected #{resource_type}, but found #{response.resource.class}." # ,response.body
+ raise AssertionException, "Bad response type: expected #{resource_type}, but found #{response.resource.class}."
end
def assertion_negated(expression)
@@ -267,5 +273,17 @@ def assert_valid_http_uri(uri, message = nil)
error_message = message || "\"#{uri}\" is not a valid URI"
assert (uri =~ /\A#{URI.regexp(['http', 'https'])}\z/), error_message
end
+
+ def assert_operation_supported(server_capabilities, op_name)
+ assert server_capabilities.operation_supported?(op_name), "FHIR server capability statement did not support #{op_name} operation"
+ end
+
+ def assert_valid_conformance(conformance = @conformance)
+ conformance_resource_name = versioned_conformance_class.name.demodulize
+ assert(
+ conformance.class == versioned_conformance_class,
+ "Expected valid #{conformance_resource_name} resource."
+ )
+ end
end
end
diff --git a/lib/app/utils/validation.rb b/lib/app/utils/validation.rb
index ee58a3fae..723a9f678 100644
--- a/lib/app/utils/validation.rb
+++ b/lib/app/utils/validation.rb
@@ -19,7 +19,7 @@ def self.get_resource(json, version)
RESOURCES = { dstu2: {}, stu3: {}, r4: {} }
VALUESETS = {}
- VERSION_MAP = { '1.0.2' => :dstu2, '3.0.1' => :stu3, '4.0.0' => :r4 }
+ VERSION_MAP = { '1.0.2' => :dstu2, '3.0.1' => :stu3, '4.0.0' => :r4 }.freeze
Dir.glob(validation_packs).each do |definition|
json = File.read(definition)
@@ -54,6 +54,15 @@ def self.get_resource(json, version)
snf: 'https://bluebutton.cms.gov/assets/ig/StructureDefinition-bluebutton-snf-claim'
}.freeze
+ US_CORE_R4_URIS = {
+ smoking_status: 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-smokingstatus',
+ diagnostic_report_lab: 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-diagnosticreport-lab',
+ diagnostic_report_note: 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-diagnosticreport-note',
+ lab_results: 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-lab',
+ pediatric_bmi_age: 'http://hl7.org/fhir/us/core/StructureDefinition/pediatric-bmi-for-age',
+ pediatric_weight_height: 'http://hl7.org/fhir/us/core/StructureDefinition/pediatric-weight-for-height'
+ }.freeze
+
def self.guess_profile(resource, version)
# if the profile is given, we don't need to guess
if resource&.meta&.profile&.present?
@@ -133,7 +142,23 @@ def self.guess_r4_profile(resource)
return if resource.blank?
candidates = RESOURCES[:r4][resource.resourceType]
- return candidates.first if candidates.present?
+ return if candidates.blank?
+
+ if resource.resourceType == 'Observation'
+ return DEFINITIONS[US_CORE_R4_URIS[:smoking_status]] if resource&.code&.coding&.any? { |coding| coding&.code == '72166-2' }
+
+ return DEFINITIONS[US_CORE_R4_URIS[:lab_results]] if resource&.category&.first&.coding&.any? { |coding| coding&.code == 'laboratory' }
+
+ return DEFINITIONS[US_CORE_R4_URIS[:pediatric_bmi_age]] if resource&.code&.coding&.any? { |coding| coding&.code == '59576-9' }
+
+ return DEFINITIONS[US_CORE_R4_URIS[:pediatric_weight_height]] if resource&.code&.coding&.any? { |coding| coding&.code == '77606-2' }
+ elsif resource.resourceType == 'DiagnosticReport'
+ return DEFINITIONS[US_CORE_R4_URIS[:diagnostic_report_lab]] if resource&.category&.first&.coding&.any? { |coding| coding&.code == 'LAB' }
+
+ return DEFINITIONS[US_CORE_R4_URIS[:diagnostic_report_note]]
+ end
+
+ candidates.first
end
end
end
diff --git a/lib/app/views/default.erb b/lib/app/views/default.erb
index 8c460aa37..d4f530de4 100644
--- a/lib/app/views/default.erb
+++ b/lib/app/views/default.erb
@@ -222,7 +222,6 @@
instance: instance,
value: instance.id_token,
})%>
-
<%= erb(:prerequisite_field,{},{prerequisite: :refresh_token,
label: 'Refresh Token',
instance: instance,
diff --git a/lib/app/views/report.erb b/lib/app/views/report.erb
index 57a82014a..e057f49f9 100644
--- a/lib/app/views/report.erb
+++ b/lib/app/views/report.erb
@@ -145,14 +145,14 @@
-