-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add code to assign an area to an address through postcode
- Loading branch information
Showing
11 changed files
with
288 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
app/services/waste_carriers_engine/assign_site_details_service.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
module WasteCarriersEngine | ||
class AssignSiteDetailsService < BaseService | ||
attr_reader :address | ||
|
||
delegate :postcode, :area, to: :address | ||
|
||
def run(address:) | ||
@address = address | ||
|
||
assign_area_from_postcode | ||
end | ||
|
||
private | ||
|
||
def assign_area_from_postcode | ||
return if area.present? | ||
return unless postcode.present? | ||
|
||
x, y = DetermineEastingAndNorthingService.run(postcode: postcode).values | ||
|
||
address.area = DetermineAreaService.run(easting: x, northing: y) | ||
end | ||
end | ||
end |
20 changes: 20 additions & 0 deletions
20
app/services/waste_carriers_engine/determine_area_service.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
module WasteCarriersEngine | ||
class DetermineAreaService < BaseService | ||
def run(easting:, northing:) | ||
response = DefraRuby::Area::PublicFaceAreaService.run(easting, northing) | ||
|
||
return response.areas.first.long_name if response.successful? | ||
return "Outside England" if response.error.instance_of?(DefraRuby::Area::NoMatchError) | ||
|
||
handle_error(response.error, easting, northing) | ||
"Not found" | ||
end | ||
|
||
private | ||
|
||
def handle_error(error, easting, northing) | ||
Airbrake.notify(error, easting: easting, northing: northing) if defined? Airbrake | ||
Rails.logger.error "Area lookup failed:\n #{error}" | ||
end | ||
end | ||
end |
56 changes: 56 additions & 0 deletions
56
app/services/waste_carriers_engine/determine_easting_and_northing_service.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
module WasteCarriersEngine | ||
class DetermineEastingAndNorthingService < BaseService | ||
def run(postcode:) | ||
@result = { easting: nil, northing: nil } | ||
|
||
easting_and_northing_from_postcode(postcode) | ||
|
||
@result | ||
end | ||
|
||
private | ||
|
||
def easting_and_northing_from_postcode(postcode) | ||
return if postcode.blank? | ||
|
||
response = AddressLookupService.run(postcode) | ||
|
||
if response.successful? | ||
apply_result_coordinates(response.results.first) | ||
elsif response.error.is_a?(DefraRuby::Address::NoMatchError) | ||
no_match_from_postcode_lookup(postcode) | ||
else | ||
error_from_postcode_lookup(postcode, response.error) | ||
end | ||
end | ||
|
||
def apply_result_coordinates(result) | ||
@result[:easting] = result["x"].to_f | ||
@result[:northing] = result["y"].to_f | ||
end | ||
|
||
def handle_error(error, message, metadata) | ||
Airbrake.notify(error, metadata) if defined?(Airbrake) | ||
Rails.logger.error(message) | ||
end | ||
|
||
def no_match_from_postcode_lookup(postcode) | ||
default_do_not_fetch_again_coordinates | ||
|
||
message = "Postcode to easting and northing returned no results" | ||
handle_error(StandardError.new(message), message, postcode: postcode) | ||
end | ||
|
||
def error_from_postcode_lookup(postcode, error) | ||
default_do_not_fetch_again_coordinates | ||
|
||
message = "Postcode to easting and northing errored: #{error.message}" | ||
handle_error(StandardError.new(message), message, postcode: postcode) | ||
end | ||
|
||
def default_do_not_fetch_again_coordinates | ||
@result[:easting] = 0.00 | ||
@result[:northing] = 0.00 | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
spec/services/waste_carriers_engine/assign_site_details_service_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
require 'rails_helper' | ||
|
||
require 'rails_helper' | ||
|
||
module WasteCarriersEngine | ||
RSpec.describe AssignSiteDetailsService, type: :service do | ||
describe '#run' do | ||
let(:x) { 123456 } | ||
let(:y) { 654321 } | ||
let(:area) { 'Area Name' } | ||
|
||
context 'when address has a postcode and area is not present' do | ||
let(:address) { build(:address, :has_required_data) } | ||
|
||
before do | ||
allow(DetermineEastingAndNorthingService).to receive(:run).and_return(easting: x, northing: y) | ||
allow(DetermineAreaService).to receive(:run).and_return(area) | ||
end | ||
|
||
it 'assigns area' do | ||
described_class.run(address: address) | ||
expect(address.area).to eq(area) | ||
end | ||
end | ||
|
||
context 'when address has an area' do | ||
let(:address) { build(:address, :has_required_data, area: area) } | ||
|
||
it 'does not change the area' do | ||
expect(DetermineEastingAndNorthingService).not_to receive(:run) | ||
expect(DetermineAreaService).not_to receive(:run) | ||
|
||
described_class.run(address: address) | ||
|
||
expect(address.area).to eq(area) | ||
end | ||
end | ||
|
||
context 'when address does not have a postcode' do | ||
let(:address) { build(:address, :has_required_data, postcode: nil) } | ||
|
||
it 'does not assign area' do | ||
expect(DetermineEastingAndNorthingService).not_to receive(:run) | ||
expect(DetermineAreaService).not_to receive(:run) | ||
|
||
described_class.run(address: address) | ||
|
||
expect(address.area).to be_nil | ||
end | ||
end | ||
end | ||
end | ||
end |
63 changes: 63 additions & 0 deletions
63
spec/services/waste_carriers_engine/determine_area_service_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# frozen_string_literal: true | ||
|
||
require "rails_helper" | ||
require "defra_ruby/area" | ||
|
||
module WasteCarriersEngine | ||
RSpec.describe DetermineAreaService do | ||
describe ".run" do | ||
let(:coordinates) { { easting: 358_205.03, northing: 172_708.07 } } | ||
|
||
before do | ||
allow(DefraRuby::Area::PublicFaceAreaService) | ||
.to receive(:run) | ||
.with(coordinates[:easting], coordinates[:northing]) | ||
.and_return(response) | ||
end | ||
|
||
context "when the lookup is successful" do | ||
let(:response) do | ||
instance_double(DefraRuby::Area::Response, successful?: true, areas: [instance_double(DefraRuby::Area::Area, long_name: "Wessex")]) | ||
end | ||
|
||
it "returns the matching area" do | ||
expect(described_class.run(coordinates)).to eq "Wessex" | ||
end | ||
|
||
it "does not notify Airbrake of the error" do | ||
allow(Airbrake).to receive(:notify) | ||
|
||
described_class.run(coordinates) | ||
|
||
expect(Airbrake).not_to have_received(:notify) | ||
end | ||
end | ||
|
||
context "when the lookup is unsuccessful" do | ||
context "with no match found" do | ||
let(:response) { instance_double(DefraRuby::Area::Response, successful?: false, error: DefraRuby::Area::NoMatchError.new) } | ||
|
||
it "returns 'Outside England'" do | ||
expect(described_class.run(coordinates)).to eq "Outside England" | ||
end | ||
end | ||
|
||
context "with a failure" do | ||
let(:response) { instance_double(DefraRuby::Area::Response, successful?: false, error: StandardError.new) } | ||
|
||
it "returns 'Not found'" do | ||
expect(described_class.run(coordinates)).to eq "Not found" | ||
end | ||
|
||
it "uses Airbrake to notify Errbit of the error" do | ||
allow(Airbrake).to receive(:notify) | ||
|
||
described_class.run(coordinates) | ||
|
||
expect(Airbrake).to have_received(:notify) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
61 changes: 61 additions & 0 deletions
61
spec/services/waste_carriers_engine/determine_easting_and_northing_service_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# spec/services/waste_carriers_engine/determine_easting_and_northing_service_spec.rb | ||
|
||
require 'rails_helper' | ||
|
||
module WasteCarriersEngine | ||
RSpec.describe DetermineEastingAndNorthingService, type: :service do | ||
let(:service) { DetermineEastingAndNorthingService.new } | ||
let(:valid_postcode) { 'SW1A 1AA' } | ||
let(:invalid_postcode) { 'INVALID' } | ||
|
||
describe '#run' do | ||
context 'when given a valid postcode' do | ||
before do | ||
# Stub AddressLookupService to return a valid response | ||
allow(AddressLookupService).to receive(:run).with(valid_postcode).and_return( | ||
instance_double(DefraRuby::Address::Response, successful?: true, results: [{ "x" => 529_090, "y" => 179_645 }]) | ||
) | ||
end | ||
|
||
it 'returns the correct easting and northing values' do | ||
result = service.run(postcode: valid_postcode) | ||
|
||
expect(result[:easting]).to eq(529_090.0) | ||
expect(result[:northing]).to eq(179_645.0) | ||
end | ||
end | ||
|
||
context 'when given an invalid postcode' do | ||
before do | ||
# Stub AddressLookupService to return a NoMatchError | ||
allow(AddressLookupService).to receive(:run).with(invalid_postcode).and_return( | ||
instance_double(DefraRuby::Address::Response, successful?: false, error: DefraRuby::Address::NoMatchError.new) | ||
) | ||
end | ||
|
||
it 'returns the default easting and northing values' do | ||
result = service.run(postcode: invalid_postcode) | ||
|
||
expect(result[:easting]).to eq(0.0) | ||
expect(result[:northing]).to eq(0.0) | ||
end | ||
end | ||
|
||
context 'when the postcode lookup service returns an error' do | ||
before do | ||
# Stub AddressLookupService to return a generic error | ||
allow(AddressLookupService).to receive(:run).with(invalid_postcode).and_return( | ||
instance_double(DefraRuby::Address::Response, successful?: false, error: StandardError.new('An error occurred')) | ||
) | ||
end | ||
|
||
it 'returns the default easting and northing values' do | ||
result = service.run(postcode: invalid_postcode) | ||
|
||
expect(result[:easting]).to eq(0.0) | ||
expect(result[:northing]).to eq(0.0) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters