defra_ruby_address 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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