diff --git a/app/services/uprn_client.rb b/app/services/uprn_client.rb index 7c9bf8940..edc91ffb7 100644 --- a/app/services/uprn_client.rb +++ b/app/services/uprn_client.rb @@ -20,7 +20,7 @@ class UprnClient end def result - @result ||= JSON.parse(response.body).dig("results", 0, "DPA") + @result ||= JSON.parse(response.body).dig("results", 0, "DPA") || JSON.parse(response.body).dig("results", 0, "LPI") end private @@ -39,6 +39,7 @@ private params = { uprn:, key: ENV["OS_DATA_KEY"], + dataset: %w[DPA LPI].join(","), } uri.query = URI.encode_www_form(params) uri.to_s diff --git a/app/services/uprn_data_presenter.rb b/app/services/uprn_data_presenter.rb index 5602cbd28..7c70a81e3 100644 --- a/app/services/uprn_data_presenter.rb +++ b/app/services/uprn_data_presenter.rb @@ -8,22 +8,35 @@ class UprnDataPresenter end def postcode - data["POSTCODE"] + result_from_lpi? ? data["POSTCODE_LOCATOR"] : data["POSTCODE"] end def address_line1 - data.values_at( - "PO_BOX_NUMBER", - "ORGANISATION_NAME", - "DEPARTMENT_NAME", - "SUB_BUILDING_NAME", - "BUILDING_NAME", - "BUILDING_NUMBER", - "DEPENDENT_THOROUGHFARE_NAME", - "THOROUGHFARE_NAME", - ).compact - .join(", ") - .titleize + if result_from_lpi? + data.values_at( + "ORGANISATION", + "SAO_TEXT", + "PAO_START_NUMBER", + "STREET_DESCRIPTION", + "LOCALITY_NAME", + "ADMINISTRATIVE_AREA", + ).compact + .join(", ") + .titleize + else + data.values_at( + "PO_BOX_NUMBER", + "ORGANISATION_NAME", + "DEPARTMENT_NAME", + "SUB_BUILDING_NAME", + "BUILDING_NAME", + "BUILDING_NUMBER", + "DEPENDENT_THOROUGHFARE_NAME", + "THOROUGHFARE_NAME", + ).compact + .join(", ") + .titleize + end end def address_line2 @@ -36,6 +49,10 @@ class UprnDataPresenter end def town_or_city - data["POST_TOWN"].titleize + result_from_lpi? ? data["TOWN_NAME"].titleize : data["POST_TOWN"].titleize + end + + def result_from_lpi? + data["LPI_KEY"].present? end end diff --git a/spec/request_helper.rb b/spec/request_helper.rb index 57765d131..0defd1ab7 100644 --- a/spec/request_helper.rb +++ b/spec/request_helper.rb @@ -34,7 +34,7 @@ module RequestHelper ], }.to_json - WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?key=OS_DATA_KEY&uprn=1") + WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?dataset=DPA,LPI&key=OS_DATA_KEY&uprn=1") .to_return(status: 200, body:, headers: {}) body = { @@ -50,7 +50,7 @@ module RequestHelper ], }.to_json - WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?key&uprn=121") + WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?dataset=DPA,LPI&key&uprn=121") .to_return(status: 200, body:, headers: {}) body = { @@ -65,7 +65,7 @@ module RequestHelper ], }.to_json - WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?key=OS_DATA_KEY&uprn=123") + WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?dataset=DPA,LPI&key=OS_DATA_KEY&uprn=123") .to_return(status: 200, body:, headers: {}) body = { @@ -80,10 +80,10 @@ module RequestHelper ], }.to_json - WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?key=OS_DATA_KEY&uprn=12") + WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?dataset=DPA,LPI&key=OS_DATA_KEY&uprn=12") .to_return(status: 200, body:, headers: {}) - WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?key=OS_DATA_KEY&uprn=1234567890123") + WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?dataset=DPA,LPI&key=OS_DATA_KEY&uprn=1234567890123") .to_return(status: 404, body: "", headers: {}) template = Addressable::Template.new "https://api.os.uk/search/places/v1/find?key=OS_DATA_KEY&maxresults=10&minmatch=0.4&query={+address_query}" diff --git a/spec/services/exports/lettings_log_export_service_spec.rb b/spec/services/exports/lettings_log_export_service_spec.rb index 253dc455d..b3f33f24f 100644 --- a/spec/services/exports/lettings_log_export_service_spec.rb +++ b/spec/services/exports/lettings_log_export_service_spec.rb @@ -181,7 +181,7 @@ RSpec.describe Exports::LettingsLogExportService do before do Timecop.freeze(Time.zone.local(2023, 4, 3)) Singleton.__init__(FormHandler) - stub_request(:get, "https://api.os.uk/search/places/v1/uprn?key=OS_DATA_KEY&uprn=100023336956") + stub_request(:get, "https://api.os.uk/search/places/v1/uprn?dataset=DPA,LPI&key=OS_DATA_KEY&uprn=100023336956") .to_return(status: 200, body: '{"status":200,"results":[{"DPA":{ "PO_BOX_NUMBER": "fake", "ORGANISATION_NAME": "org", diff --git a/spec/services/uprn_client_spec.rb b/spec/services/uprn_client_spec.rb index b595b7e76..3189c455b 100644 --- a/spec/services/uprn_client_spec.rb +++ b/spec/services/uprn_client_spec.rb @@ -8,7 +8,7 @@ describe UprnClient do end def stub_api_request(body:, status: 200) - stub_request(:get, "https://api.os.uk/search/places/v1/uprn?key=OS_DATA_KEY&uprn=123") + stub_request(:get, "https://api.os.uk/search/places/v1/uprn?dataset=DPA,LPI&key=OS_DATA_KEY&uprn=123") .to_return(status:, body:, headers: {}) end @@ -37,15 +37,37 @@ describe UprnClient do end end - context "when results empty" do - before do - stub_api_request(body: {}.to_json) + context "when DPA results empty" do + context "and LPI result is present" do + let(:valid_lpi_response) do + { results: [{ LPI: { postcode_locator: "LPI postcode", LPI_KEY: "123" } }] }.to_json + end - client.call + before do + stub_api_request(body: valid_lpi_response, status: 200) + + client.call + end + + it "returns result" do + expect(client.result).to eq({ "postcode_locator" => "LPI postcode", "LPI_KEY" => "123" }) + end + + it "returns no error" do + expect(client.error).to be_nil + end end - it "returns error" do - expect(client.error).to eq("UPRN is not recognised. Check the number, or enter the address") + context "and LPI results empty" do + before do + stub_api_request(body: {}.to_json) + + client.call + end + + it "returns error" do + expect(client.error).to eq("UPRN is not recognised. Check the number, or enter the address") + end end end diff --git a/spec/services/uprn_data_presenter_spec.rb b/spec/services/uprn_data_presenter_spec.rb index 16ae9318f..d7d5549b4 100644 --- a/spec/services/uprn_data_presenter_spec.rb +++ b/spec/services/uprn_data_presenter_spec.rb @@ -1,66 +1,109 @@ require "rails_helper" describe UprnDataPresenter do - let(:data) do - JSON.parse( - '{ - "UPRN": "UPRN", - "UDPRN": "UDPRN", - "ADDRESS": "full address", - "SUB_BUILDING_NAME": "0", - "BUILDING_NAME": "building name", - "THOROUGHFARE_NAME": "thoroughfare", - "POST_TOWN": "posttown", - "POSTCODE": "postcode", - "STATUS": "APPROVED", - "DOUBLE_DEPENDENT_LOCALITY": "double dependent locality", - "DEPENDENT_LOCALITY": "dependent locality", - "CLASSIFICATION_CODE": "classification code", - "LOCAL_CUSTODIAN_CODE_DESCRIPTION": "LONDON BOROUGH OF HARINGEY", - "BLPU_STATE_CODE": "2", - "BLPU_STATE_CODE_DESCRIPTION": "In use", - "LAST_UPDATE_DATE": "31/07/2020", - "ENTRY_DATE": "30/01/2015", - "BLPU_STATE_DATE": "30/01/2015", - "LANGUAGE": "EN", - "MATCH_DESCRIPTION": "EXACT" - }', - ) - end - let(:presenter) { described_class.new(data) } - describe "#postcode" do - it "returns postcode" do - expect(presenter.postcode).to eq("postcode") + describe "DPA data" do + let(:data) do + JSON.parse( + '{ + "UPRN": "UPRN", + "UDPRN": "UDPRN", + "ADDRESS": "full address", + "SUB_BUILDING_NAME": "0", + "BUILDING_NAME": "building name", + "THOROUGHFARE_NAME": "thoroughfare", + "POST_TOWN": "posttown", + "POSTCODE": "postcode", + "STATUS": "APPROVED", + "DOUBLE_DEPENDENT_LOCALITY": "double dependent locality", + "DEPENDENT_LOCALITY": "dependent locality", + "CLASSIFICATION_CODE": "classification code", + "LOCAL_CUSTODIAN_CODE_DESCRIPTION": "LONDON BOROUGH OF HARINGEY", + "BLPU_STATE_CODE": "2", + "BLPU_STATE_CODE_DESCRIPTION": "In use", + "LAST_UPDATE_DATE": "31/07/2020", + "ENTRY_DATE": "30/01/2015", + "BLPU_STATE_DATE": "30/01/2015", + "LANGUAGE": "EN", + "MATCH_DESCRIPTION": "EXACT" + }', + ) end - end - describe "#address_line1" do - it "returns address_line1" do - expect(presenter.address_line1).to eq("0, Building Name, Thoroughfare") + describe "#postcode" do + it "returns postcode" do + expect(presenter.postcode).to eq("postcode") + end end - end - describe "#address_line2" do - it "returns address_line2" do - expect(presenter.address_line2).to eq("Double Dependent Locality, Dependent Locality") + describe "#address_line1" do + it "returns address_line1" do + expect(presenter.address_line1).to eq("0, Building Name, Thoroughfare") + end end - end - describe "#town_or_city" do - it "returns town_or_city" do - expect(presenter.town_or_city).to eq("Posttown") + describe "#address_line2" do + it "returns address_line2" do + expect(presenter.address_line2).to eq("Double Dependent Locality, Dependent Locality") + end + end + + describe "#town_or_city" do + it "returns town_or_city" do + expect(presenter.town_or_city).to eq("Posttown") + end + end + + context "when address_line2 fields are missing" do + let(:data) { {} } + + describe "#address_line2" do + it "returns nil" do + expect(presenter.address_line2).to be_nil + end + end end end - context "when address_line2 fields are missing" do - let(:data) { {} } + describe "LPI data" do + let(:data) do + JSON.parse( + '{ + "UPRN": "UPRN", + "ADDRESS": "flat 1, 22, street name, posttown, postcode", + "SAO_TEXT": "flat 1", + "PAO_START_NUMBER": "22", + "STREET_DESCRIPTION": "street name", + "TOWN_NAME": "posttown", + "POSTCODE_LOCATOR": "postcode", + "LPI_KEY": "LPI_KEY" + }', + ) + end + + describe "#postcode" do + it "returns postcode" do + expect(presenter.postcode).to eq("postcode") + end + end + + describe "#address_line1" do + it "returns address_line1" do + expect(presenter.address_line1).to eq("Flat 1, 22, Street Name") + end + end describe "#address_line2" do - it "returns nil" do + it "returns address_line2" do expect(presenter.address_line2).to be_nil end end + + describe "#town_or_city" do + it "returns town_or_city" do + expect(presenter.town_or_city).to eq("Posttown") + end + end end end