defra_ruby_address 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +8 -0
  3. data/README.md +233 -0
  4. data/Rakefile +33 -0
  5. data/bin/console +14 -0
  6. data/bin/setup +8 -0
  7. data/lib/defra_ruby.rb +7 -0
  8. data/lib/defra_ruby/address.rb +28 -0
  9. data/lib/defra_ruby/address/configuration.rb +15 -0
  10. data/lib/defra_ruby/address/ea_address_facade_request.rb +49 -0
  11. data/lib/defra_ruby/address/no_match_error.rb +11 -0
  12. data/lib/defra_ruby/address/response.rb +33 -0
  13. data/lib/defra_ruby/address/services/base_service.rb +14 -0
  14. data/lib/defra_ruby/address/services/ea_address_facade_v1_1_service.rb +16 -0
  15. data/lib/defra_ruby/address/services/ea_address_facade_v1_service.rb +16 -0
  16. data/lib/defra_ruby/address/services/os_places_address_lookup_service.rb +51 -0
  17. data/lib/defra_ruby/address/version.rb +7 -0
  18. data/spec/defra_ruby/address/configuration_spec.rb +18 -0
  19. data/spec/defra_ruby/address/response_spec.rb +70 -0
  20. data/spec/defra_ruby/address/services/ea_address_facade_v1_1_service_spec.rb +73 -0
  21. data/spec/defra_ruby/address/services/ea_address_facade_v1_service_spec.rb +73 -0
  22. data/spec/defra_ruby/address/services/os_places_address_lookup_service_spec.rb +72 -0
  23. data/spec/defra_ruby/address_spec.rb +30 -0
  24. data/spec/examples.txt +27 -0
  25. data/spec/fixtures/ea_address_facade_v1_1_blank.json +8 -0
  26. data/spec/fixtures/ea_address_facade_v1_1_not_found.json +14 -0
  27. data/spec/fixtures/ea_address_facade_v1_1_valid.json +83 -0
  28. data/spec/fixtures/ea_address_facade_v1_blank.json +13 -0
  29. data/spec/fixtures/ea_address_facade_v1_not_found.json +8 -0
  30. data/spec/fixtures/ea_address_facade_v1_valid.json +45 -0
  31. data/spec/fixtures/os_places_address_lookup_blank.json +5 -0
  32. data/spec/fixtures/os_places_address_lookup_not_found.json +6 -0
  33. data/spec/fixtures/os_places_address_lookup_valid.json +56 -0
  34. data/spec/spec_helper.rb +83 -0
  35. data/spec/support/defra_ruby_address.rb +4 -0
  36. data/spec/support/dotenv.rb +4 -0
  37. data/spec/support/pry.rb +7 -0
  38. data/spec/support/shared_examples/handle_request_errors.rb +32 -0
  39. data/spec/support/simplecov.rb +17 -0
  40. data/spec/support/webmock.rb +4 -0
  41. metadata +248 -0
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "rest-client"
5
+
6
+ module DefraRuby
7
+ module Address
8
+ class BaseService
9
+ def self.run(attrs = nil)
10
+ new.run(attrs)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Address
5
+ class EaAddressFacadeV11Service < BaseService
6
+
7
+ PARAM_NAME = "query-string"
8
+
9
+ def run(postcode)
10
+ request = EaAddressFacadeRequest.new(PARAM_NAME)
11
+ request.execute(postcode)
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Address
5
+ class EaAddressFacadeV1Service < BaseService
6
+
7
+ PARAM_NAME = "postcode"
8
+
9
+ def run(postcode)
10
+ request = EaAddressFacadeRequest.new(PARAM_NAME)
11
+ request.execute(postcode)
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Address
5
+ class OsPlacesAddressLookupService < BaseService
6
+
7
+ def run(postcode)
8
+ @postcode = postcode
9
+ Response.new(response_exe)
10
+ end
11
+
12
+ private
13
+
14
+ OS_PLACES_ADDRESS_LOOKUP_NO_MATCH_ERROR_MSG = "Parameters are not valid"
15
+
16
+ attr_reader :postcode
17
+
18
+ def url
19
+ File.join(
20
+ DefraRuby::Address.configuration.host,
21
+ "/addresses?postcode=#{postcode}"
22
+ )
23
+ end
24
+
25
+ def response_exe
26
+ lambda do
27
+ begin
28
+ response = RestClient::Request.execute(
29
+ method: :get,
30
+ url: url,
31
+ timeout: DefraRuby::Address.configuration.timeout
32
+ )
33
+ JSON.parse(response)
34
+ rescue RestClient::BadRequest => e
35
+ raise process_error(e)
36
+ end
37
+ end
38
+ end
39
+
40
+ def process_error(error)
41
+ if JSON.parse(error.response)["error"]["message"] == OS_PLACES_ADDRESS_LOOKUP_NO_MATCH_ERROR_MSG
42
+ error = NoMatchError.new
43
+ end
44
+ rescue StandardError
45
+ error
46
+ ensure
47
+ error
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Address
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module DefraRuby
6
+ module Address
7
+ RSpec.describe Configuration do
8
+ it "sets the appropriate default config settings" do
9
+ fresh_config = described_class.new
10
+
11
+ expect(fresh_config.timeout).to eq(3)
12
+ expect(fresh_config.host).to be_nil
13
+ expect(fresh_config.client_id).to eq(0)
14
+ expect(fresh_config.key).to eq("client1")
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module DefraRuby
6
+ module Address
7
+ RSpec.describe Response do
8
+ subject(:response) { described_class.new(response_exe) }
9
+
10
+ let(:successful) { -> { [{ "postcode" => "BS1 5AH" }] } }
11
+ let(:errored) { -> { raise "Boom!" } }
12
+
13
+ describe "#successful?" do
14
+ context "when the response throws an error" do
15
+ let(:response_exe) { errored }
16
+
17
+ it "returns false" do
18
+ expect(response).to_not be_successful
19
+ end
20
+ end
21
+
22
+ context "when the response doesn't throw an error" do
23
+ let(:response_exe) { successful }
24
+
25
+ it "returns true" do
26
+ expect(response).to be_successful
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "#results" do
32
+ context "when the response throws an error" do
33
+ let(:response_exe) { errored }
34
+
35
+ it "returns an empty array" do
36
+ expect(response.results).to eq([])
37
+ end
38
+ end
39
+
40
+ context "when the response does not throw an error" do
41
+ let(:response_exe) { successful }
42
+
43
+ it "returns a JSON array" do
44
+ expect(response.results).to be_instance_of(Array)
45
+ expect(response.results[0]).to be_instance_of(Hash)
46
+ expect(response.results[0]["postcode"]).to eq("BS1 5AH")
47
+ end
48
+ end
49
+ end
50
+
51
+ describe "#error" do
52
+ context "when the response throws an error" do
53
+ let(:response_exe) { errored }
54
+
55
+ it "returns the error" do
56
+ expect(response.error).to be_a(StandardError)
57
+ end
58
+ end
59
+
60
+ context "when the response don't throw an error" do
61
+ let(:response_exe) { successful }
62
+
63
+ it "returns a nil object" do
64
+ expect(response.error).to be_nil
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module DefraRuby
6
+ module Address
7
+ RSpec.describe EaAddressFacadeV11Service do
8
+ describe "#run" do
9
+ before do
10
+ DefraRuby::Address.configure { |c| c.host = "http://localhost:8005/" }
11
+ stub_request(:get, url).to_return(status: code, body: body)
12
+ end
13
+
14
+ let(:client_id) { DefraRuby::Address.configuration.client_id }
15
+ let(:key) { DefraRuby::Address.configuration.key }
16
+ let(:postcode) { "BS1 5AH" }
17
+ let(:url) { "http://localhost:8005/address-service/v1/addresses/postcode?client-id=#{client_id}&key=#{key}&query-string=#{postcode}" }
18
+ let(:code) { 200 }
19
+ let(:body) { File.read("spec/fixtures/ea_address_facade_v1_1_valid.json") }
20
+
21
+ include_examples "handle request errors"
22
+
23
+ context "when the postcode is valid" do
24
+
25
+ it "returns a successful response" do
26
+ response = described_class.run(postcode)
27
+
28
+ expect(a_request(:get, url)).to have_been_made.at_most_once
29
+
30
+ expect(response).to be_a(Response)
31
+ expect(response.successful?).to eq(true)
32
+ expect(response.results).not_to be_empty
33
+ end
34
+ end
35
+
36
+ context "when the postcode is invalid" do
37
+ context "because it is not found" do
38
+ let(:postcode) { "BS1 9XX" }
39
+ let(:body) { File.read("spec/fixtures/ea_address_facade_v1_1_not_found.json") }
40
+
41
+ it "returns a 'NoMatchError'" do
42
+ response = described_class.run(postcode)
43
+
44
+ expect(a_request(:get, url)).to have_been_made.at_most_once
45
+
46
+ expect(response).to be_a(Response)
47
+ expect(response).to_not be_successful
48
+ expect(response.results).to be_empty
49
+ expect(response.error).to be_an_instance_of(DefraRuby::Address::NoMatchError)
50
+ end
51
+ end
52
+
53
+ context "because it is blank" do
54
+ let(:postcode) { "" }
55
+ let(:code) { 400 }
56
+ let(:body) { File.read("spec/fixtures/ea_address_facade_v1_1_blank.json") }
57
+
58
+ it "returns a failed response" do
59
+ response = described_class.run(postcode)
60
+
61
+ expect(a_request(:get, url)).to have_been_made.at_most_once
62
+
63
+ expect(response).to be_a(Response)
64
+ expect(response).to_not be_successful
65
+ expect(response.results).to be_empty
66
+ expect(response.error).to be_an_instance_of(RestClient::BadRequest)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module DefraRuby
6
+ module Address
7
+ RSpec.describe EaAddressFacadeV1Service do
8
+ describe "#run" do
9
+ before do
10
+ DefraRuby::Address.configure { |c| c.host = "http://localhost:8005/" }
11
+ stub_request(:get, url).to_return(status: code, body: body)
12
+ end
13
+
14
+ let(:client_id) { DefraRuby::Address.configuration.client_id }
15
+ let(:key) { DefraRuby::Address.configuration.key }
16
+ let(:postcode) { "BS1 5AH" }
17
+ let(:url) { "http://localhost:8005/address-service/v1/addresses/postcode?client-id=#{client_id}&key=#{key}&postcode=#{postcode}" }
18
+ let(:code) { 200 }
19
+ let(:body) { File.read("spec/fixtures/ea_address_facade_v1_valid.json") }
20
+
21
+ include_examples "handle request errors"
22
+
23
+ context "when the postcode is valid" do
24
+
25
+ it "returns a successful response" do
26
+ response = described_class.run(postcode)
27
+
28
+ expect(a_request(:get, url)).to have_been_made.at_most_once
29
+
30
+ expect(response).to be_a(Response)
31
+ expect(response.successful?).to eq(true)
32
+ expect(response.results).not_to be_empty
33
+ end
34
+ end
35
+
36
+ context "when the postcode is invalid" do
37
+ context "because it is not found" do
38
+ let(:postcode) { "BS1 9XX" }
39
+ let(:body) { File.read("spec/fixtures/ea_address_facade_v1_not_found.json") }
40
+
41
+ it "returns a 'NoMatchError'" do
42
+ response = described_class.run(postcode)
43
+
44
+ expect(a_request(:get, url)).to have_been_made.at_most_once
45
+
46
+ expect(response).to be_a(Response)
47
+ expect(response).to_not be_successful
48
+ expect(response.results).to be_empty
49
+ expect(response.error).to be_an_instance_of(DefraRuby::Address::NoMatchError)
50
+ end
51
+ end
52
+
53
+ context "because it is blank" do
54
+ let(:postcode) { "" }
55
+ let(:code) { 400 }
56
+ let(:body) { File.read("spec/fixtures/ea_address_facade_v1_blank.json") }
57
+
58
+ it "returns a failed response" do
59
+ response = described_class.run(postcode)
60
+
61
+ expect(a_request(:get, url)).to have_been_made.at_most_once
62
+
63
+ expect(response).to be_a(Response)
64
+ expect(response).to_not be_successful
65
+ expect(response.results).to be_empty
66
+ expect(response.error).to be_an_instance_of(RestClient::BadRequest)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module DefraRuby
6
+ module Address
7
+ RSpec.describe OsPlacesAddressLookupService do
8
+ describe "#run" do
9
+ before do
10
+ DefraRuby::Address.configure { |c| c.host = "http://localhost:8005/" }
11
+ stub_request(:get, url).to_return(status: code, body: body)
12
+ end
13
+
14
+ let(:postcode) { "BS1 5AH" }
15
+ let(:url) { "http://localhost:8005/addresses?postcode=#{postcode}" }
16
+ let(:code) { 200 }
17
+ let(:body) { File.read("spec/fixtures/os_places_address_lookup_valid.json") }
18
+
19
+ include_examples "handle request errors"
20
+
21
+ context "when the postcode is valid" do
22
+
23
+ it "returns a successful response" do
24
+ response = described_class.run(postcode)
25
+
26
+ expect(a_request(:get, url)).to have_been_made.at_most_once
27
+
28
+ expect(response).to be_a(Response)
29
+ expect(response.successful?).to eq(true)
30
+ expect(response.results).not_to be_empty
31
+ end
32
+ end
33
+
34
+ context "when the postcode is invalid" do
35
+ let(:code) { 400 }
36
+
37
+ context "because it is not found" do
38
+ let(:postcode) { "BS1 9XX" }
39
+ let(:body) { File.read("spec/fixtures/os_places_address_lookup_not_found.json") }
40
+
41
+ it "returns a 'NoMatchError'" do
42
+ response = described_class.run(postcode)
43
+
44
+ expect(a_request(:get, url)).to have_been_made.at_most_once
45
+
46
+ expect(response).to be_a(Response)
47
+ expect(response).to_not be_successful
48
+ expect(response.results).to be_empty
49
+ expect(response.error).to be_an_instance_of(DefraRuby::Address::NoMatchError)
50
+ end
51
+ end
52
+
53
+ context "because it is blank" do
54
+ let(:postcode) { "" }
55
+ let(:body) { File.read("spec/fixtures/os_places_address_lookup_blank.json") }
56
+
57
+ it "returns a failed response" do
58
+ response = described_class.run(postcode)
59
+
60
+ expect(a_request(:get, url)).to have_been_made.at_most_once
61
+
62
+ expect(response).to be_a(Response)
63
+ expect(response).to_not be_successful
64
+ expect(response.results).to be_empty
65
+ expect(response.error).to be_an_instance_of(RestClient::BadRequest)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe DefraRuby::Address do
6
+ describe "VERSION" do
7
+ it "is a version string in the correct format" do
8
+ expect(DefraRuby::Address::VERSION).to be_a(String)
9
+ expect(DefraRuby::Address::VERSION).to match(/\d+\.\d+\.\d+/)
10
+ end
11
+ end
12
+
13
+ describe "#configuration" do
14
+ context "when the host app has not provided configuration" do
15
+ it "returns a DefraRuby::Address::Configuration instance" do
16
+ expect(described_class.configuration).to be_an_instance_of(DefraRuby::Address::Configuration)
17
+ end
18
+ end
19
+
20
+ context "when the host app has provided configuration" do
21
+ let(:host) { "http://localhost:9012" }
22
+
23
+ it "returns an DefraRuby::Address::Configuration instance with a matching host" do
24
+ described_class.configure { |config| config.host = host }
25
+
26
+ expect(described_class.configuration.host).to eq(host)
27
+ end
28
+ end
29
+ end
30
+ end