Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FI-2186 Coverage Optional _lastUpdated #19

Closed
wants to merge 8 commits into from
1 change: 1 addition & 0 deletions lib/carin_for_blue_button_test_kit/carin_search_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def run_search_test(param_value, include_search: false, resource_id: nil)
search_params[search_param_names[0]] = param_value

fhir_search(resource_type, params: search_params)

assert_response_status(200)
assert_resource_type(:bundle)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ class CoverageLastupdatedSearchTest < Inferno::Test
)

id :c4bb_v200devnonfinancial_coverage__lastUpdated_search_test
optional


input :c4bb_v200devnonfinancial_coverage__lastUpdated_search_test_param,
title: 'Coverage search parameter for _lastUpdated
',
type: 'text',
description: 'Coverage search parameter: _lastUpdated
'
',
optional: true

def self.properties
@properties ||= SearchTestProperties.new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ class CoverageLastupdatedSearchTest < Inferno::Test
)

id :c4bb_v200_coverage__lastUpdated_search_test
optional


input :c4bb_v200_coverage__lastUpdated_search_test_param,
title: 'Coverage search parameter for _lastUpdated
',
type: 'text',
description: 'Coverage search parameter: _lastUpdated
'
',
optional: true

def self.properties
@properties ||= SearchTestProperties.new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def required_comparators
end

def optional?
conformance_expectation != 'SHALL' || !search_metadata[:must_support_or_mandatory]
conformance_expectation != 'SHALL' || (!search_metadata[:must_support_or_mandatory].nil? && !search_metadata[:must_support_or_mandatory])
end

def search_definition(name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ module CarinForBlueButtonTestKit
<%= description %>
)

id :<%= test_id %>
id :<%= test_id %><% if optional? %>
optional
<% end %>

input :<%=test_id%>_param,
title: '<%=input_title%>',
type: 'text',
description: '<%=input_description%>'
description: '<%=input_description%>'<%if optional?%>,
optional: true<% end %>

def self.properties
@properties ||= SearchTestProperties.new(
Expand Down
151 changes: 151 additions & 0 deletions spec/carin_for_blue_button/carin_search_test_last_updated.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# frozen_string_literal: true

RSpec.describe CarinForBlueButtonTestKit::CarinSearchTest do
let(:coverage_json_string) do
File.read(File.join(__dir__, '..', 'fixtures', 'c4bb_coverage_example.json'))
end

let(:eob_json_string) do
File.read(File.join(__dir__, '..', 'fixtures', 'c4bb_eob_inpatient_example.json'))
end

let(:suite) { Inferno::Repositories::TestSuites.new.find('c4bb_v200') }
let(:session_data_repo) { Inferno::Repositories::SessionData.new }
let(:test_session) { repo_create(:test_session, test_suite_id: suite.id) }
let(:url) { 'http://example.com/fhir' }
let(:error_outcome) { FHIR::OperationOutcome.new(issue: [{ severity: 'error' }]) }

def run(runnable, inputs = {})
test_run_params = { test_session_id: test_session.id }.merge(runnable.reference_hash)
test_run = Inferno::Repositories::TestRuns.new.create(test_run_params)
inputs.each do |name, value|
session_data_repo.save(
test_session_id: test_session.id,
name:,
value:,
type: runnable.config.input_type(name)
)
end
Inferno::TestRunner.new(test_session:, test_run:).run(runnable)
end

def setup_mock_test(coverage_test, coverage_resource)
allow_any_instance_of(coverage_test).to receive(:scratch_resources).and_return(
{
all: [coverage_resource]
}
)
end

describe 'carin coverage search optional _lastUpdated' do
let(:coverage_last_updated_search_test) do
Class.new(CarinForBlueButtonTestKit::CARIN4BBV200::CoverageLastupdatedSearchTest) do
fhir_client { url :url }
input :url
end
end

let(:coverage) { FHIR.from_contents(coverage_json_string) }
let(:last_updated) { '2022-09-17' }
let(:bundle) do
FHIR::Bundle.new(entry: [{ resource: coverage }])
end

before do
Inferno::Repositories::Tests.new.insert(coverage_last_updated_search_test)
setup_mock_test(coverage_last_updated_search_test, coverage)
end

it 'passes if _lastUpdated is passed in and 200 is received' do
stub_request(:get, "#{url}/Coverage?_lastUpdated=#{last_updated}")
.to_return(status: 200, body: bundle.to_json)

result = run(
coverage_last_updated_search_test,
c4bb_v200_coverage__lastUpdated_search_test_param: last_updated,
url:
)
expect(result.result).to eq('pass')
end

it 'skips if _lastUpdated is passed in and 400 is received' do
stub_request(:get, "#{url}/Coverage?_lastUpdated=#{last_updated}")
.to_return(status: 400, body: error_outcome.to_json)
result = run(
coverage_last_updated_search_test,
c4bb_v200_coverage__lastUpdated_search_test_param: last_updated,
url:
)
expect(result.result).to eq('skip')
expect(result.result_message).to eq('_lastUpdated search query was unsuccessful and did not respond with a 200 status')
end

it 'skips if _lastUpdated is not passed in' do
result = run(
coverage_last_updated_search_test,
url:
)
expect(result.result).to eq('skip')
expect(result.result_message).to eq('_lastUpdated optional and not provided')
end
end

describe 'carin eob search required _lastUpdated' do
let(:eob_last_updated_search_test) do
Class.new(CarinForBlueButtonTestKit::CARIN4BBV200::ExplanationOfBenefitLastupdatedSearchTest) do
fhir_client { url :url }
input :url
end
end

let(:eob) { FHIR.from_contents(eob_json_string) }
let(:last_updated) { '2020-04-28' }
let(:bundle) do
FHIR::Bundle.new(entry: [{ resource: eob }])
end

before do
Inferno::Repositories::Tests.new.insert(eob_last_updated_search_test)
setup_mock_test(eob_last_updated_search_test, eob)
end

it 'passes if _lastUpdated is passed in and 200 is received' do
stub_request(:get, "#{url}/ExplanationOfBenefit?_lastUpdated=#{last_updated}")
.to_return(status: 200, body: bundle.to_json)

result = run(
eob_last_updated_search_test,
c4bb_v200_explanation_of_benefit__lastUpdated_search_test_param: last_updated,
url:
)
expect(result.result).to eq('pass')
end

it 'fails if lastUpdated is passed in and 400 is received' do
stub_request(:get, "#{url}/ExplanationOfBenefit?_lastUpdated=#{last_updated}")
.to_return(status: 400, body: error_outcome.to_json)

result = run(
eob_last_updated_search_test,
c4bb_v200_explanation_of_benefit__lastUpdated_search_test_param: last_updated,
url:
)
expect(result.result).to eq('fail')
expect(result.result_message).to eq('Unexpected response status: expected 200, but received 400')
end

it 'fails if lastUpdated is not passed in' do
stub_request(:get, "#{url}/ExplanationOfBenefit?_lastUpdated")
.to_return(status: 400, body: error_outcome.to_json)

result = run(
eob_last_updated_search_test,
url:
)
expect(result.result).to eq('fail')
expect(result.result_message).to eq('Unexpected response status: expected 200, but received 400')
end
end


end
99 changes: 99 additions & 0 deletions spec/fixtures/c4bb_coverage_example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
{
"resourceType": "Coverage",
"id": "Coverage2",
"meta": {
"versionId": "1",
"lastUpdated": "2022-09-17T20:32:39.267+00:00",
"source": "#h78CuLSfdxHlUkyZ",
"profile": [
"http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Coverage|2.0.0"
]
},
"language": "en-US",
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative: Coverage</b><a name=\"Coverage2\"> </a></p><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">Resource Coverage &quot;Coverage2&quot; Updated &quot;2020-10-30 09:48:01-0400&quot; (Language &quot;en-US&quot;) </p><p style=\"margin-bottom: 0px\">Profile: <a href=\"StructureDefinition-C4BB-Coverage.html\">C4BB Coverage (version 2.0.0)</a></p></div><p><b>identifier</b>: An identifier for the insured of an insurance policy (this insured always has a subscriber), usually assigned by the insurance carrier.: 88800933501</p><p><b>status</b>: active</p><p><b>policyHolder</b>: <a href=\"Patient-Patient1.html\">Patient/Patient1</a> &quot; EXAMPLE1&quot;</p><p><b>subscriber</b>: <a href=\"Patient-Patient1.html\">Patient/Patient1</a> &quot; EXAMPLE1&quot;</p><p><b>subscriberId</b>: 888009335</p><p><b>beneficiary</b>: <a href=\"Patient-Patient1.html\">Patient/Patient1</a> &quot; EXAMPLE1&quot;</p><p><b>dependent</b>: 01</p><p><b>relationship</b>: Self <span style=\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\"> (<a href=\"http://terminology.hl7.org/4.0.0/CodeSystem-subscriber-relationship.html\">SubscriberPolicyholder Relationship Codes</a>#self)</span></p><p><b>period</b>: 2017-01-01 --&gt; 2017-06-30</p><p><b>payor</b>: <a href=\"Organization-Payer2.html\">Organization/Payer2: UPMC Health Plan</a> &quot;UPMC Health Plan&quot;</p><blockquote><p><b>class</b></p><p><b>type</b>: An employee group <span style=\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\"> (<a href=\"http://terminology.hl7.org/4.0.0/CodeSystem-coverage-class.html\">Coverage Class Codes</a>#group &quot;Group&quot;)</span></p><p><b>value</b>: MCHMO1</p><p><b>name</b>: MEDICARE HMO PLAN</p></blockquote><blockquote><p><b>class</b></p><p><b>type</b>: A specific suite of benefits. <span style=\"background: LightGoldenRodYellow; margin: 4px; border: 1px solid khaki\"> (<a href=\"http://terminology.hl7.org/4.0.0/CodeSystem-coverage-class.html\">Coverage Class Codes</a>#plan &quot;Plan&quot;)</span></p><p><b>value</b>: GI8</p><p><b>name</b>: GI8-HMO DEDUCTIBLE</p></blockquote><p><b>network</b>: GI8-HMO DEDUCTIBLE</p></div>"
},
"identifier": [
{
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
"code": "MB",
"display": "Member Number"
}
],
"text": "An identifier for the insured of an insurance policy (this insured always has a subscriber), usually assigned by the insurance carrier."
},
"system": "https://www.upmchealthplan.com/fhir/memberidentifier",
"value": "88800933501",
"assigner": {
"reference": "Organization/Payer2",
"display": "UPMC Health Plan"
}
}
],
"status": "active",
"policyHolder": {
"reference": "Patient/Patient1"
},
"subscriber": {
"reference": "Patient/Patient1"
},
"subscriberId": "888009335",
"beneficiary": {
"reference": "Patient/Patient1"
},
"dependent": "01",
"relationship": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/subscriber-relationship",
"code": "self"
}
],
"text": "Self"
},
"period": {
"start": "2017-01-01",
"end": "2017-06-30"
},
"payor": [
{
"reference": "Organization/Payer2",
"display": "UPMC Health Plan"
}
],
"class": [
{
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/coverage-class",
"code": "group",
"display": "Group"
}
],
"text": "An employee group"
},
"value": "MCHMO1",
"name": "MEDICARE HMO PLAN"
},
{
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/coverage-class",
"code": "plan",
"display": "Plan"
}
],
"text": "A specific suite of benefits."
},
"value": "GI8",
"name": "GI8-HMO DEDUCTIBLE"
}
],
"network": "GI8-HMO DEDUCTIBLE"
}