Skip to content

Commit

Permalink
Fix User Access Brands Brand validation to allow sub-organizations
Browse files Browse the repository at this point in the history
  • Loading branch information
emichaud998 committed Dec 6, 2024
1 parent 10572b3 commit b667f73
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 12 deletions.
49 changes: 41 additions & 8 deletions lib/smart_app_launch/smart_access_brands_validate_brands_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ def find_referenced_endpoint(bundle_resource, endpoint_id_ref)
.select { |endpoint_id| endpoint_id_ref.include? endpoint_id }
end

def find_parent_organization(bundle_resource, org_reference)
bundle_resource
.entry
.map(&:resource)
.select { |resource| resource.resourceType == 'Organization' }
.find { |parent_org| org_reference.include? parent_org.id }
end

def find_extension(extension_array, extension_name)
extension_array.find do |extension|
extension.url.ends_with?(extension_name)
Expand Down Expand Up @@ -78,7 +86,6 @@ def scratch_bundle_resource
resource_is_valid?(resource: organization)

endpoint_references = organization.endpoint.map(&:reference)

if organization.extension.present?
portal_extension = find_extension(organization.extension, '/organization-portal')
if portal_extension.present?
Expand All @@ -87,14 +94,40 @@ def scratch_bundle_resource
end
end

endpoint_references.each do |endpoint_id_ref|
organization_referenced_endpts = find_referenced_endpoint(bundle_resource, endpoint_id_ref)
next unless organization_referenced_endpts.empty?
if organization.endpoint.empty?
if organization.partOf.blank?
add_message('error', %(
Organization with id: #{organization.id} does not have the endpoint or partOf field populated
))
next
end

parent_organization = find_parent_organization(bundle_resource, organization.partOf.reference)

if parent_organization.blank?
add_message('error', %(
Organization with id: #{organization.id} references parent Organization not found in the Bundle:
#{organization.partOf.reference}
))
next
end

add_message('error', %(
Organization with id: #{organization.id} references an Endpoint that is not contained in this
bundle.
))
if parent_organization.endpoint.empty?
add_message('error', %(
Organization with id: #{organization.id} has parent Organization with id: #{parent_organization.id} that
does not have the `endpoint` field populated.
))
end
else
endpoint_references.each do |endpoint_id_ref|
organization_referenced_endpts = find_referenced_endpoint(bundle_resource, endpoint_id_ref)
next unless organization_referenced_endpts.empty?

add_message('error', %(
Organization with id: #{organization.id} references an Endpoint that is not contained in this
bundle.
))
end
end
end

Expand Down
40 changes: 40 additions & 0 deletions spec/fixtures/smart_access_brands_example.json
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,46 @@
],
"address" : "http://example.com/api/FHIR/R4/2"
}
},
{
"fullUrl" : "https://ehr.example.com/Organization/ehchospital",
"resource" : {
"resourceType" : "Organization",
"id" : "ehchospital",
"extension" : [{
"extension" : [{
"url" : "brandLogo",
"valueUrl" : "data:image/svg+xml;base64,PHN2ZyB0aXRsZT0iU3Rld2FydCBNZW1vcmlhbCBIb3Nw...+IDwvc3ZnPgo="
}],
"url" : "http://hl7.org/fhir/StructureDefinition/organization-brand"
}],
"identifier" : [{
"system" : "urn:ietf:rfc:3986",
"value" : "https://ehchospital.example.org"
}],
"active" : true,
"type" : [{
"coding" : [{
"system" : "http://terminology.hl7.org/CodeSystem/organization-type",
"code" : "prov",
"display" : "Healthcare Provider"
}]
}],
"name" : "ExampleHealth Community Hospital",
"alias" : ["GoodHealth Madison"],
"telecom" : [{
"system" : "url",
"value" : "https://www.ehchospital.example.com"
}],
"address" : [{
"city" : "Lake City",
"state" : "IA",
"country" : "US"
}],
"partOf" : {
"reference" : "Organization/examplehospital"
}
}
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def run(runnable, inputs = {})
result = run(test)

expect(result.result).to eq('pass')
expect(validation_request).to have_been_made
expect(validation_request).to have_been_made.times(2)
end

it 'skips if no User Access Brands Bundle requests were made' do
Expand Down Expand Up @@ -117,7 +117,22 @@ def run(runnable, inputs = {})
expect(entity_result_message.message).to match(
'Resource does not conform to profile'
)
expect(validation_request).to have_been_made
expect(validation_request).to have_been_made.times(2)
end

it 'fails if Brand missing endpoint and partOf fields' do
validation_request = stub_request(:post, "#{validator_url}/validate")
.to_return(status: 200, body: operation_outcome_success.to_json)
smart_access_brands_bundle.entry.last.resource.partOf = nil
allow_any_instance_of(test).to receive(:scratch_bundle_resource).and_return(smart_access_brands_bundle)

result = run(test)

expect(result.result).to eq('fail')
expect(entity_result_message.message).to match(
'Organization with id: ehchospital does not have the endpoint or partOf field populated'
)
expect(validation_request).to have_been_made.times(2)
end

it 'fails if Brand contains Endpoint in portal extension but not Organization.endpoint' do
Expand All @@ -131,7 +146,7 @@ def run(runnable, inputs = {})

expect(result.result).to eq('fail')
expect(entity_result_message.message).to match('Portal endpoints must also appear at Organization.endpoint')
expect(validation_request).to have_been_made
expect(validation_request).to have_been_made.times(2)
end

it 'fails if Brand contains Endpoint reference not found in Bundle' do
Expand All @@ -147,7 +162,7 @@ def run(runnable, inputs = {})
expect(entity_result_message.message).to match(
'Organization with id: examplehospital references an Endpoint that is not contained'
)
expect(validation_request).to have_been_made
expect(validation_request).to have_been_made.times(2)
end
end
end

0 comments on commit b667f73

Please sign in to comment.