diff --git a/app/lib/nhs/pds.rb b/app/lib/nhs/pds.rb index 248289e78..1385f23c2 100644 --- a/app/lib/nhs/pds.rb +++ b/app/lib/nhs/pds.rb @@ -26,6 +26,9 @@ class InvalidNHSNumber < StandardError class PatientNotFound < StandardError end + class TooManyMatches < StandardError + end + class << self def get_patient(nhs_number) NHS::API.connection.get( @@ -54,10 +57,17 @@ def search_patients(attributes) raise "Unrecognised attributes: #{missing_attrs.join(", ")}" end - NHS::API.connection.get( - "personal-demographics/FHIR/R4/Patient", - attributes - ) + response = + NHS::API.connection.get( + "personal-demographics/FHIR/R4/Patient", + attributes + ) + + if is_error?(response, "TOO_MANY_MATCHES") + raise TooManyMatches + else + response + end rescue Faraday::BadRequestError => e add_sentry_breadcrumb(e) raise @@ -75,10 +85,17 @@ def add_sentry_breadcrumb(error) Sentry.add_breadcrumb(crumb) end - def is_error?(error, code) - response = JSON.parse(error.response_body) + def is_error?(error_or_response, code) + response = + if error_or_response.is_a?(Faraday::ClientError) + JSON.parse(error_or_response.response_body) + elsif error_or_response.is_a?(Faraday::Response) + error_or_response.body + end + + return false if (issues = response["issue"]).blank? - response["issue"].any? do |issue| + issues.any? do |issue| issue["details"]["coding"].any? { |coding| coding["code"] == code } end end diff --git a/spec/fixtures/files/pds/too-many-matches.json b/spec/fixtures/files/pds/too-many-matches.json new file mode 100644 index 000000000..468363ce5 --- /dev/null +++ b/spec/fixtures/files/pds/too-many-matches.json @@ -0,0 +1,19 @@ +{ + "issue": [ + { + "code": "multiple-matches", + "details": { + "coding": [ + { + "code": "TOO_MANY_MATCHES", + "display": "Too Many Matches", + "system": "https://fhir.nhs.uk/R4/CodeSystem/Spine-ErrorOrWarningCode", + "version": "1" + } + ] + }, + "severity": "information" + } + ], + "resourceType": "OperationOutcome" +} diff --git a/spec/lib/nhs/pds_spec.rb b/spec/lib/nhs/pds_spec.rb index d9969e417..ead873553 100644 --- a/spec/lib/nhs/pds_spec.rb +++ b/spec/lib/nhs/pds_spec.rb @@ -82,33 +82,61 @@ end describe "#search_patients" do - before do - stub_request( - :get, - "https://sandbox.api.service.nhs.uk/personal-demographics/FHIR/R4/Patient" - ).with( - query: { - birthdate: "eq1939-01-09", - family: "Lawman", - gender: "female" - } - ).to_return( - body: file_fixture("pds/search-patients-response.json"), - headers: { - "Content-Type" => "application/fhir+json" - } + subject(:search_patients) do + described_class.search_patients( + family: "Lawman", + gender: "female", + birthdate: "eq1939-01-09" ) end - it "sends a GET request to with the provided attributes" do - response = - described_class.search_patients( - family: "Lawman", - gender: "female", - birthdate: "eq1939-01-09" + context "with a successful response" do + before do + stub_request( + :get, + "https://sandbox.api.service.nhs.uk/personal-demographics/FHIR/R4/Patient" + ).with( + query: { + birthdate: "eq1939-01-09", + family: "Lawman", + gender: "female" + } + ).to_return( + body: file_fixture("pds/search-patients-response.json"), + headers: { + "Content-Type" => "application/fhir+json" + } ) + end + + it "sends a GET request to with the provided attributes" do + response = search_patients + expect(response.body).to include("total" => 1) + end + end - expect(response.body).to include("total" => 1) + context "with a too many matches response" do + before do + stub_request( + :get, + "https://sandbox.api.service.nhs.uk/personal-demographics/FHIR/R4/Patient" + ).with( + query: { + birthdate: "eq1939-01-09", + family: "Lawman", + gender: "female" + } + ).to_return( + body: file_fixture("pds/too-many-matches.json"), + headers: { + "Content-Type" => "application/fhir+json" + } + ) + end + + it "raises an error" do + expect { search_patients }.to raise_error(NHS::PDS::TooManyMatches) + end end it "raises an error if an unrecognised attribute is provided" do