firstclasspostcodes 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.dependabot/config.yml +12 -0
- data/.github/workflows/gem.yml +53 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +78 -0
- data/Gemfile +25 -0
- data/LICENSE +21 -0
- data/Rakefile +11 -0
- data/firstclasspostcodes.gemspec +54 -0
- data/lib/firstclasspostcodes.rb +33 -0
- data/lib/firstclasspostcodes/client.rb +81 -0
- data/lib/firstclasspostcodes/configuration.rb +156 -0
- data/lib/firstclasspostcodes/events.rb +27 -0
- data/lib/firstclasspostcodes/operations.rb +4 -0
- data/lib/firstclasspostcodes/operations/get_lookup.rb +52 -0
- data/lib/firstclasspostcodes/operations/get_postcode.rb +40 -0
- data/lib/firstclasspostcodes/operations/methods/format_address.rb +38 -0
- data/lib/firstclasspostcodes/operations/methods/list_addresses.rb +29 -0
- data/lib/firstclasspostcodes/response_error.rb +29 -0
- data/lib/firstclasspostcodes/version.rb +5 -0
- data/spec/firstclasspostcodes/client_spec.rb +94 -0
- data/spec/firstclasspostcodes/events_spec.rb +41 -0
- data/spec/firstclasspostcodes/operations/get_lookup_spec.rb +103 -0
- data/spec/firstclasspostcodes/operations/get_postcode_spec.rb +58 -0
- data/spec/firstclasspostcodes/operations/methods/format_address_spec.rb +106 -0
- data/spec/firstclasspostcodes/operations/methods/list_addresses_spec.rb +75 -0
- data/spec/firstclasspostcodes/response_error_spec.rb +43 -0
- data/spec/firstclasspostcodes/version_spec.rb +9 -0
- data/spec/firstclasspostcodes_spec.rb +108 -0
- data/spec/spec_helper.rb +42 -0
- data/spec/support/events_examples.rb +11 -0
- metadata +123 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Firstclasspostcodes::Operations::GetPostcode do
|
6
|
+
class TestGetPostcode
|
7
|
+
attr_accessor :config
|
8
|
+
|
9
|
+
include Firstclasspostcodes::Operations::GetPostcode
|
10
|
+
|
11
|
+
def emit(event_name, properties); end
|
12
|
+
|
13
|
+
def request(params); end
|
14
|
+
end
|
15
|
+
|
16
|
+
subject { TestGetPostcode.new }
|
17
|
+
|
18
|
+
let(:operation_params) { { path: "/postcode", method: :get } }
|
19
|
+
|
20
|
+
let(:config) { double(geo_json?: false, debug?: true, logger: double(debug: nil)) }
|
21
|
+
|
22
|
+
before(:each) { allow(subject).to receive(:emit).with(anything, anything).and_return(true) }
|
23
|
+
|
24
|
+
before(:each) { subject.config = config }
|
25
|
+
|
26
|
+
specify { expect(subject).respond_to?(:get_postcode) }
|
27
|
+
|
28
|
+
describe "when the request is valid" do
|
29
|
+
before(:each) { allow(subject).to receive(:request).and_return(double) }
|
30
|
+
|
31
|
+
let(:postcode) { "test" }
|
32
|
+
|
33
|
+
it "returns the correct response" do
|
34
|
+
expect(subject).to receive(:request).with(operation_params.merge(
|
35
|
+
query_params: {
|
36
|
+
search: postcode,
|
37
|
+
}
|
38
|
+
))
|
39
|
+
response = subject.get_postcode(postcode)
|
40
|
+
expect(response).respond_to?(:list_addresses)
|
41
|
+
expect(response).respond_to?(:format_address)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "when the request is invalid" do
|
46
|
+
describe "when there are no parameters" do
|
47
|
+
it "raises an error" do
|
48
|
+
expect { subject.get_postcode(23_456) }.to raise_error(StandardError)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "when there is an empty string" do
|
53
|
+
it "raises an error" do
|
54
|
+
expect { subject.get_postcode("") }.to raise_error(StandardError)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Firstclasspostcodes::Operations::Methods::FormatAddress do
|
6
|
+
class TestFormatAddress < Hash
|
7
|
+
include Firstclasspostcodes::Operations::Methods::FormatAddress
|
8
|
+
end
|
9
|
+
|
10
|
+
subject { TestFormatAddress[] }
|
11
|
+
|
12
|
+
let(:index) { "numbers:0" }
|
13
|
+
|
14
|
+
before(:each) do
|
15
|
+
subject.merge!(
|
16
|
+
numbers: [
|
17
|
+
{
|
18
|
+
number: 1,
|
19
|
+
street: "A Street",
|
20
|
+
},
|
21
|
+
{
|
22
|
+
number: "Flat A",
|
23
|
+
building: "Crescent",
|
24
|
+
street: "A Street",
|
25
|
+
},
|
26
|
+
],
|
27
|
+
streets: [
|
28
|
+
"A Street",
|
29
|
+
"B Avenue",
|
30
|
+
],
|
31
|
+
locality: "locality",
|
32
|
+
city: "city",
|
33
|
+
county: "county",
|
34
|
+
region: "region",
|
35
|
+
country: "country",
|
36
|
+
postcode: "postcode"
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
specify { expect(subject.respond_to?(:format_address)) }
|
41
|
+
|
42
|
+
describe "when the type is invalid" do
|
43
|
+
let(:index) { "dadwadada:0" }
|
44
|
+
|
45
|
+
it "throws an error" do
|
46
|
+
expect { subject.format_address(index) }.to raise_error(StandardError)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'when the "postcode" type is passed in' do
|
51
|
+
let(:index) { "postcode:0" }
|
52
|
+
|
53
|
+
it "returns a formatted postcode" do
|
54
|
+
expect(subject.format_address(index)).to eq(
|
55
|
+
locality: "city",
|
56
|
+
region: "county",
|
57
|
+
postcode: "postcode",
|
58
|
+
country: "country"
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe 'when the "streets" type is passed in' do
|
64
|
+
let(:index) { "streets:1" }
|
65
|
+
|
66
|
+
it "returns a formatted street" do
|
67
|
+
expect(subject.format_address(index)).to eq(
|
68
|
+
address: "B Avenue",
|
69
|
+
locality: "city",
|
70
|
+
region: "county",
|
71
|
+
postcode: "postcode",
|
72
|
+
country: "country"
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "when there are no streets" do
|
77
|
+
before(:each) { subject[:streets] = nil }
|
78
|
+
|
79
|
+
it "throws an error" do
|
80
|
+
expect { subject.format_address(index) }.to raise_error(StandardError)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'when the "numbers" type is passed in' do
|
86
|
+
let(:index) { "numbers:1" }
|
87
|
+
|
88
|
+
it "returns a formatted number" do
|
89
|
+
expect(subject.format_address(index)).to eq(
|
90
|
+
address: "Flat A, Crescent, A Street",
|
91
|
+
locality: "city",
|
92
|
+
region: "county",
|
93
|
+
postcode: "postcode",
|
94
|
+
country: "country"
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "when there are no numbers" do
|
99
|
+
before(:each) { subject[:numbers] = nil }
|
100
|
+
|
101
|
+
it "throws an error" do
|
102
|
+
expect { subject.format_address(index) }.to raise_error(StandardError)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Firstclasspostcodes::Operations::Methods::ListAddresses do
|
6
|
+
class TestListAddresses < Hash
|
7
|
+
include Firstclasspostcodes::Operations::Methods::ListAddresses
|
8
|
+
end
|
9
|
+
|
10
|
+
subject { TestListAddresses[] }
|
11
|
+
|
12
|
+
specify { expect(subject.respond_to?(:list_addresses)) }
|
13
|
+
|
14
|
+
describe "when there are no numbers or streets" do
|
15
|
+
before(:each) do
|
16
|
+
subject.merge!(
|
17
|
+
numbers: [],
|
18
|
+
streets: [],
|
19
|
+
locality: "locality",
|
20
|
+
city: "city",
|
21
|
+
postcode: "postcode"
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns a postcode option" do
|
26
|
+
expect(subject.list_addresses).to eq([
|
27
|
+
["postcode:0", "city, postcode"],
|
28
|
+
])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "when there are only streets" do
|
33
|
+
before(:each) do
|
34
|
+
subject.merge!(
|
35
|
+
numbers: [],
|
36
|
+
streets: ["A Street", "B Avenue"],
|
37
|
+
locality: "locality",
|
38
|
+
city: "city",
|
39
|
+
postcode: "postcode"
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns equal number of street options" do
|
44
|
+
expect(subject.list_addresses).to eq([
|
45
|
+
["streets:0", "A Street, city, postcode"],
|
46
|
+
["streets:1", "B Avenue, city, postcode"],
|
47
|
+
])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "when there are streets and numbers" do
|
52
|
+
before(:each) do
|
53
|
+
subject.merge!(
|
54
|
+
numbers: [
|
55
|
+
{
|
56
|
+
number: 1,
|
57
|
+
street: "A Street",
|
58
|
+
},
|
59
|
+
{
|
60
|
+
number: "Flat A",
|
61
|
+
building: "Crescent",
|
62
|
+
street: "A Street",
|
63
|
+
},
|
64
|
+
],
|
65
|
+
streets: ["A Street", "B Avenue"],
|
66
|
+
locality: "locality",
|
67
|
+
city: "city",
|
68
|
+
postcode: "postcode"
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns equal number of street options" do
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Firstclasspostcodes::ResponseError do
|
6
|
+
describe "when the error is a hash" do
|
7
|
+
let(:error_object) do
|
8
|
+
{
|
9
|
+
message: "message",
|
10
|
+
docUrl: "https://google.com/some-doc",
|
11
|
+
type: "type",
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
subject { Firstclasspostcodes::ResponseError.new(error_object) }
|
16
|
+
|
17
|
+
specify { expect(subject.message).to include error_object[:message] }
|
18
|
+
|
19
|
+
specify { expect(subject.type).to include error_object[:type] }
|
20
|
+
|
21
|
+
specify { expect(subject.message).to include error_object[:docUrl] }
|
22
|
+
|
23
|
+
specify { expect(subject.type).to eq error_object[:type] }
|
24
|
+
|
25
|
+
specify { expect(subject.doc_url).to eq error_object[:docUrl] }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "when the error is a message" do
|
29
|
+
let(:error_message) { "message" }
|
30
|
+
|
31
|
+
let(:error_type) { "type" }
|
32
|
+
|
33
|
+
subject { Firstclasspostcodes::ResponseError.new(error_message, error_type) }
|
34
|
+
|
35
|
+
specify { expect(subject.type).to eq(error_type) }
|
36
|
+
|
37
|
+
specify { expect(subject.message).to include error_message }
|
38
|
+
|
39
|
+
specify { expect(subject.message).to include error_type }
|
40
|
+
|
41
|
+
specify { expect(subject.doc_url).to include error_type }
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Firstclasspostcodes do
|
6
|
+
describe "#content" do
|
7
|
+
let(:config) { Firstclasspostcodes::Configuration.new }
|
8
|
+
|
9
|
+
it "defaults to json" do
|
10
|
+
expect(Firstclasspostcodes::Configuration.default.content).to eq("json")
|
11
|
+
expect(config.content).to eq("json")
|
12
|
+
end
|
13
|
+
|
14
|
+
# it 'raises when an invalid type is passed' do
|
15
|
+
# expect { config.content = "awdgfde" }.to raise_error(StandardError)
|
16
|
+
# end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#configure" do
|
20
|
+
it "calls a configuration block" do
|
21
|
+
expect { |b| Firstclasspostcodes.configure(&b) }.to yield_control
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#protocol" do
|
26
|
+
it "removes :// from the protocol" do
|
27
|
+
Firstclasspostcodes.configure { |c| c.protocol = "https://" }
|
28
|
+
expect(Firstclasspostcodes::Configuration.default.protocol).to eq("https")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#host" do
|
33
|
+
it "removes http from host" do
|
34
|
+
Firstclasspostcodes.configure { |c| c.host = "http://example.com" }
|
35
|
+
expect(Firstclasspostcodes::Configuration.default.host).to eq("example.com")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "removes https from host" do
|
39
|
+
Firstclasspostcodes.configure { |c| c.host = "https://wookiee.com" }
|
40
|
+
expect(Firstclasspostcodes::Configuration.default.host).to eq("wookiee.com")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "removes trailing path from host" do
|
44
|
+
Firstclasspostcodes.configure { |c| c.host = "hobo.com/v4" }
|
45
|
+
expect(Firstclasspostcodes::Configuration.default.host).to eq("hobo.com")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#base_path" do
|
50
|
+
it "prepends a slash to base_path" do
|
51
|
+
Firstclasspostcodes.configure { |c| c.base_path = "v4/dog" }
|
52
|
+
expect(Firstclasspostcodes::Configuration.default.base_path).to eq("/v4/dog")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "doesn't prepend a slash if one is already there" do
|
56
|
+
Firstclasspostcodes.configure { |c| c.base_path = "/v4/dog" }
|
57
|
+
expect(Firstclasspostcodes::Configuration.default.base_path).to eq("/v4/dog")
|
58
|
+
end
|
59
|
+
|
60
|
+
it "ends up as a blank string if nil" do
|
61
|
+
Firstclasspostcodes.configure { |c| c.base_path = nil }
|
62
|
+
expect(Firstclasspostcodes::Configuration.default.base_path).to eq("")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#geo_json?" do
|
67
|
+
let(:config) { Firstclasspostcodes::Configuration.new }
|
68
|
+
|
69
|
+
it "defaults to false" do
|
70
|
+
expect(Firstclasspostcodes::Configuration.default.geo_json?).to be_falsey
|
71
|
+
expect(config.geo_json?).to be_falsey
|
72
|
+
end
|
73
|
+
|
74
|
+
it "can be customized" do
|
75
|
+
config.content = "geo+json"
|
76
|
+
expect(config.geo_json?).to be_truthy
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#debug?" do
|
81
|
+
let(:config) { Firstclasspostcodes::Configuration.new }
|
82
|
+
|
83
|
+
it "defaults to false" do
|
84
|
+
expect(Firstclasspostcodes::Configuration.default.debug?).to be_falsey
|
85
|
+
expect(config.debug?).to be_falsey
|
86
|
+
end
|
87
|
+
|
88
|
+
it "can be customized" do
|
89
|
+
config.debug = true
|
90
|
+
expect(config.debug?).to be_truthy
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "timeout in #build_request" do
|
95
|
+
let(:config) { Firstclasspostcodes::Configuration.new }
|
96
|
+
|
97
|
+
it "defaults to 0" do
|
98
|
+
expect(Firstclasspostcodes::Configuration.default.timeout).to eq(0)
|
99
|
+
expect(config.timeout).to eq(0)
|
100
|
+
expect(config.to_request_params[:timeout]).to eq(0)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "can be customized" do
|
104
|
+
config.timeout = 100
|
105
|
+
expect(config.to_request_params[:timeout]).to eq(100)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "uri"
|
4
|
+
require "simplecov"
|
5
|
+
|
6
|
+
SimpleCov.start
|
7
|
+
|
8
|
+
if ENV["CI"] == "true"
|
9
|
+
require "codecov"
|
10
|
+
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
11
|
+
end
|
12
|
+
|
13
|
+
# load the gem
|
14
|
+
require "firstclasspostcodes"
|
15
|
+
|
16
|
+
API_URL = ENV["API_URL"]
|
17
|
+
|
18
|
+
API_KEY = ENV["API_KEY"]
|
19
|
+
|
20
|
+
RSpec.configure do |config|
|
21
|
+
config.expect_with :rspec do |expectations|
|
22
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
23
|
+
end
|
24
|
+
|
25
|
+
config.mock_with :rspec do |mocks|
|
26
|
+
mocks.verify_partial_doubles = true
|
27
|
+
end
|
28
|
+
|
29
|
+
config.before(:each) do
|
30
|
+
Typhoeus::Expectation.clear
|
31
|
+
|
32
|
+
uri = URI.parse(API_URL)
|
33
|
+
|
34
|
+
Firstclasspostcodes.configure do |c|
|
35
|
+
c.api_key = API_KEY
|
36
|
+
c.base_path = uri.path
|
37
|
+
c.protocol = uri.scheme
|
38
|
+
c.host = uri.host
|
39
|
+
c.host = "#{uri.host}:#{uri.port}" if uri.port
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|