From facbf4130798b4772877f69ff6a6dbff605ea8e3 Mon Sep 17 00:00:00 2001 From: Thomas Leese Date: Mon, 16 Dec 2024 18:48:42 +0000 Subject: [PATCH] Raise NHS::PDS::TooManyMatches This updates the PDS search client code to handle getting a too many matches error response and raise a suitable exception. This doesn't handle the error, as we need to decide how to handle this case, but having its own error means we can easily filter these out in Sentry. --- app/lib/nhs/pds.rb | 31 ++++++-- spec/fixtures/files/pds/too-many-matches.json | 19 +++++ spec/lib/nhs/pds_spec.rb | 72 +++++++++++++------ 3 files changed, 93 insertions(+), 29 deletions(-) create mode 100644 spec/fixtures/files/pds/too-many-matches.json diff --git a/app/lib/nhs/pds.rb b/app/lib/nhs/pds.rb index c82043326..9d0f9e494 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( @@ -52,18 +55,32 @@ 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 end private - 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