firstclasspostcodes 0.0.1
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.
- 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
|