google_distance_matrix 0.4.0 → 0.6.3
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 +5 -5
- data/.editorconfig +16 -0
- data/.rubocop.yml +6 -0
- data/.ruby-version +1 -1
- data/.travis.yml +4 -6
- data/CHANGELOG.md +40 -0
- data/Gemfile +2 -0
- data/README.md +0 -3
- data/Rakefile +9 -4
- data/google_distance_matrix.gemspec +21 -19
- data/lib/google_distance_matrix.rb +25 -23
- data/lib/google_distance_matrix/client.rb +32 -18
- data/lib/google_distance_matrix/client_cache.rb +9 -3
- data/lib/google_distance_matrix/configuration.rb +39 -24
- data/lib/google_distance_matrix/errors.rb +6 -3
- data/lib/google_distance_matrix/log_subscriber.rb +14 -14
- data/lib/google_distance_matrix/logger.rb +7 -5
- data/lib/google_distance_matrix/matrix.rb +45 -22
- data/lib/google_distance_matrix/place.rb +37 -28
- data/lib/google_distance_matrix/places.rb +5 -4
- data/lib/google_distance_matrix/polyline_encoder.rb +2 -2
- data/lib/google_distance_matrix/polyline_encoder/delta.rb +4 -2
- data/lib/google_distance_matrix/polyline_encoder/value_encoder.rb +13 -5
- data/lib/google_distance_matrix/railtie.rb +4 -1
- data/lib/google_distance_matrix/route.rb +22 -15
- data/lib/google_distance_matrix/routes_finder.rb +27 -29
- data/lib/google_distance_matrix/url_builder.rb +44 -16
- data/lib/google_distance_matrix/url_builder/polyline_encoder_buffer.rb +3 -0
- data/lib/google_distance_matrix/version.rb +3 -1
- data/spec/lib/google_distance_matrix/client_cache_spec.rb +27 -11
- data/spec/lib/google_distance_matrix/client_spec.rb +40 -30
- data/spec/lib/google_distance_matrix/configuration_spec.rb +36 -24
- data/spec/lib/google_distance_matrix/log_subscriber_spec.rb +13 -44
- data/spec/lib/google_distance_matrix/logger_spec.rb +16 -13
- data/spec/lib/google_distance_matrix/matrix_spec.rb +90 -57
- data/spec/lib/google_distance_matrix/place_spec.rb +38 -25
- data/spec/lib/google_distance_matrix/places_spec.rb +29 -28
- data/spec/lib/google_distance_matrix/polyline_encoder/delta_spec.rb +5 -3
- data/spec/lib/google_distance_matrix/polyline_encoder_spec.rb +7 -2
- data/spec/lib/google_distance_matrix/route_spec.rb +11 -9
- data/spec/lib/google_distance_matrix/routes_finder_spec.rb +124 -81
- data/spec/lib/google_distance_matrix/url_builder_spec.rb +97 -48
- data/spec/spec_helper.rb +3 -1
- metadata +46 -18
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GoogleDistanceMatrix
|
4
|
+
# Class integrating with rails
|
2
5
|
class Railtie < Rails::Railtie
|
3
|
-
initializer
|
6
|
+
initializer 'google_distance_matrix.logger_setup' do
|
4
7
|
GoogleDistanceMatrix.configure_defaults do |config|
|
5
8
|
config.logger = Rails.logger
|
6
9
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GoogleDistanceMatrix
|
2
4
|
# Public: Thin wrapper class for an element in the matrix.
|
3
5
|
#
|
@@ -15,10 +17,9 @@ module GoogleDistanceMatrix
|
|
15
17
|
duration_in_traffic_text duration_in_traffic_in_seconds
|
16
18
|
].freeze
|
17
19
|
|
18
|
-
attr_reader
|
19
|
-
|
20
|
-
delegate *(STATUSES.map { |s| s + '?' }), to: :status, allow_nil: true
|
20
|
+
attr_reader(*ATTRIBUTES)
|
21
21
|
|
22
|
+
delegate(*(STATUSES.map { |s| s + '?' }), to: :status, allow_nil: true)
|
22
23
|
|
23
24
|
def initialize(attributes = {})
|
24
25
|
attributes = attributes.with_indifferent_access
|
@@ -28,25 +29,31 @@ module GoogleDistanceMatrix
|
|
28
29
|
|
29
30
|
@status = ActiveSupport::StringInquirer.new attributes[:status].downcase
|
30
31
|
|
31
|
-
if ok?
|
32
|
-
|
33
|
-
@distance_in_meters = attributes[:distance][:value]
|
34
|
-
@duration_text = attributes[:duration][:text]
|
35
|
-
@duration_in_seconds = attributes[:duration][:value]
|
32
|
+
assign attributes if ok?
|
33
|
+
end
|
36
34
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
35
|
+
def inspect
|
36
|
+
attrs = ATTRIBUTES.reject do |a|
|
37
|
+
public_send(a).blank?
|
41
38
|
end
|
39
|
+
|
40
|
+
inspection = attrs.map { |a| "#{a}: #{public_send(a).inspect}" }.join ', '
|
41
|
+
|
42
|
+
"#<#{self.class} #{inspection}>"
|
42
43
|
end
|
43
44
|
|
45
|
+
private
|
44
46
|
|
47
|
+
def assign(attributes)
|
48
|
+
@distance_text = attributes[:distance][:text]
|
49
|
+
@distance_in_meters = attributes[:distance][:value]
|
50
|
+
@duration_text = attributes[:duration][:text]
|
51
|
+
@duration_in_seconds = attributes[:duration][:value]
|
45
52
|
|
46
|
-
|
47
|
-
inspection = ATTRIBUTES.reject { |a| public_send(a).blank? }.map { |a| "#{a}: #{public_send(a).inspect}" }.join ', '
|
53
|
+
return unless attributes.key? :duration_in_traffic
|
48
54
|
|
49
|
-
|
55
|
+
@duration_in_traffic_text = attributes[:duration_in_traffic][:text]
|
56
|
+
@duration_in_traffic_in_seconds = attributes[:duration_in_traffic][:value]
|
50
57
|
end
|
51
58
|
end
|
52
59
|
end
|
@@ -1,17 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GoogleDistanceMatrix
|
2
4
|
# Public: Has logic for doing finder operations on a matrix.
|
5
|
+
#
|
6
|
+
# rubocop:disable Metrics/ClassLength
|
3
7
|
class RoutesFinder
|
4
|
-
|
5
8
|
attr_reader :matrix
|
6
9
|
delegate :data, :origins, :destinations, :configuration, to: :matrix
|
7
10
|
|
8
|
-
|
9
11
|
def initialize(matrix)
|
10
12
|
@matrix = matrix
|
11
13
|
end
|
12
14
|
|
13
|
-
|
14
|
-
|
15
15
|
# Public: Finds routes for given place.
|
16
16
|
#
|
17
17
|
# place - Either an origin or destination, or an object which you built the place from
|
@@ -25,7 +25,7 @@ module GoogleDistanceMatrix
|
|
25
25
|
elsif destinations.include? place
|
26
26
|
routes_for_destination place
|
27
27
|
else
|
28
|
-
|
28
|
+
raise ArgumentError, 'Given place not an origin nor destination.'
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -41,11 +41,11 @@ module GoogleDistanceMatrix
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
|
45
44
|
# Public: Finds a route for you based on one origin and destination
|
46
45
|
#
|
47
46
|
# origin - A place representing the origin, or an object which you built the origin from
|
48
|
-
# destination - A place representing the destination, or an object which you built the
|
47
|
+
# destination - A place representing the destination, or an object which you built the
|
48
|
+
# destination from
|
49
49
|
#
|
50
50
|
# A Route for given origin and destination
|
51
51
|
def route_for(options = {})
|
@@ -54,9 +54,7 @@ module GoogleDistanceMatrix
|
|
54
54
|
origin = ensure_place options[:origin]
|
55
55
|
destination = ensure_place options[:destination]
|
56
56
|
|
57
|
-
if origin.nil? || destination.nil?
|
58
|
-
fail ArgumentError, "Must provide origin and destination"
|
59
|
-
end
|
57
|
+
raise ArgumentError, 'Must provide origin and destination' if origin.nil? || destination.nil?
|
60
58
|
|
61
59
|
routes_for(origin).detect { |route| route.destination == destination }
|
62
60
|
end
|
@@ -71,7 +69,6 @@ module GoogleDistanceMatrix
|
|
71
69
|
end
|
72
70
|
end
|
73
71
|
|
74
|
-
|
75
72
|
# Public: Finds shortes route by distance to a place.
|
76
73
|
#
|
77
74
|
# place - The place, or object place was built from, you want the shortest route to
|
@@ -79,7 +76,7 @@ module GoogleDistanceMatrix
|
|
79
76
|
# Returns shortest route, or nil if no routes had status ok
|
80
77
|
def shortest_route_by_distance_to(place_or_object_place_was_built_from)
|
81
78
|
routes = routes_for place_or_object_place_was_built_from
|
82
|
-
select_ok_routes(routes).min_by
|
79
|
+
select_ok_routes(routes).min_by(&:distance_in_meters)
|
83
80
|
end
|
84
81
|
|
85
82
|
# Public: Finds shortes route by distance to a place.
|
@@ -88,7 +85,7 @@ module GoogleDistanceMatrix
|
|
88
85
|
#
|
89
86
|
# Returns shortest route, fails if any of the routes are not ok
|
90
87
|
def shortest_route_by_distance_to!(place_or_object_place_was_built_from)
|
91
|
-
routes_for!(place_or_object_place_was_built_from).min_by
|
88
|
+
routes_for!(place_or_object_place_was_built_from).min_by(&:distance_in_meters)
|
92
89
|
end
|
93
90
|
|
94
91
|
# Public: Finds shortes route by duration to a place.
|
@@ -98,7 +95,7 @@ module GoogleDistanceMatrix
|
|
98
95
|
# Returns shortest route, or nil if no routes had status ok
|
99
96
|
def shortest_route_by_duration_to(place_or_object_place_was_built_from)
|
100
97
|
routes = routes_for place_or_object_place_was_built_from
|
101
|
-
select_ok_routes(routes).min_by
|
98
|
+
select_ok_routes(routes).min_by(&:duration_in_seconds)
|
102
99
|
end
|
103
100
|
|
104
101
|
# Public: Finds shortes route by duration to a place.
|
@@ -107,7 +104,7 @@ module GoogleDistanceMatrix
|
|
107
104
|
#
|
108
105
|
# Returns shortest route, fails if any of the routes are not ok
|
109
106
|
def shortest_route_by_duration_to!(place_or_object_place_was_built_from)
|
110
|
-
routes_for!(place_or_object_place_was_built_from).min_by
|
107
|
+
routes_for!(place_or_object_place_was_built_from).min_by(&:duration_in_seconds)
|
111
108
|
end
|
112
109
|
|
113
110
|
# Public: Finds shortes route by duration in traffic to a place.
|
@@ -122,7 +119,7 @@ module GoogleDistanceMatrix
|
|
122
119
|
ensure_driving_and_departure_time_or_fail!
|
123
120
|
|
124
121
|
routes = routes_for place_or_object_place_was_built_from
|
125
|
-
select_ok_routes(routes).min_by
|
122
|
+
select_ok_routes(routes).min_by(&:duration_in_traffic_in_seconds)
|
126
123
|
end
|
127
124
|
|
128
125
|
# Public: Finds shortes route by duration in traffic to a place.
|
@@ -136,39 +133,39 @@ module GoogleDistanceMatrix
|
|
136
133
|
def shortest_route_by_duration_in_traffic_to!(place_or_object_place_was_built_from)
|
137
134
|
ensure_driving_and_departure_time_or_fail!
|
138
135
|
|
139
|
-
routes_for!(place_or_object_place_was_built_from).min_by
|
136
|
+
routes_for!(place_or_object_place_was_built_from).min_by(&:duration_in_traffic_in_seconds)
|
140
137
|
end
|
141
138
|
|
142
|
-
|
143
|
-
|
144
139
|
private
|
145
140
|
|
146
141
|
def ensure_place(object)
|
147
142
|
if object.is_a? Place
|
148
143
|
object
|
149
144
|
else
|
145
|
+
object = object.with_indifferent_access if object.is_a? Hash
|
146
|
+
|
150
147
|
find_place_for_object(origins, object) ||
|
151
|
-
|
148
|
+
find_place_for_object(destinations, object)
|
152
149
|
end
|
153
150
|
end
|
154
151
|
|
155
152
|
def find_place_for_object(collection, object)
|
156
153
|
collection.detect do |place|
|
157
154
|
place.extracted_attributes_from.present? &&
|
158
|
-
|
155
|
+
place.extracted_attributes_from == object
|
159
156
|
end
|
160
157
|
end
|
161
158
|
|
162
159
|
def routes_for_origin(origin)
|
163
160
|
index = origins.index origin
|
164
|
-
|
161
|
+
raise ArgumentError, 'Given origin is not i matrix.' if index.nil?
|
165
162
|
|
166
163
|
data[index]
|
167
164
|
end
|
168
165
|
|
169
166
|
def routes_for_destination(destination)
|
170
167
|
index = destinations.index destination
|
171
|
-
|
168
|
+
raise ArgumentError, 'Given destination is not i matrix.' if index.nil?
|
172
169
|
|
173
170
|
[].tap do |routes|
|
174
171
|
data.each { |row| routes << row[index] }
|
@@ -180,24 +177,25 @@ module GoogleDistanceMatrix
|
|
180
177
|
destination_index = destinations.index destination
|
181
178
|
|
182
179
|
if origin_index.nil? || destination_index.nil?
|
183
|
-
|
180
|
+
raise ArgumentError, 'Given origin or destination is not i matrix.'
|
184
181
|
end
|
185
182
|
|
186
183
|
[data[origin_index][destination_index]]
|
187
184
|
end
|
188
185
|
|
189
186
|
def fail_unless_route_is_ok(route)
|
190
|
-
|
187
|
+
raise InvalidRoute, route unless route.ok?
|
191
188
|
end
|
192
189
|
|
193
190
|
def select_ok_routes(routes)
|
194
|
-
routes.select
|
191
|
+
routes.select(&:ok?)
|
195
192
|
end
|
196
193
|
|
197
194
|
def ensure_driving_and_departure_time_or_fail!
|
198
|
-
if configuration.mode
|
199
|
-
|
200
|
-
|
195
|
+
return if configuration.mode == 'driving' && configuration.departure_time.present?
|
196
|
+
|
197
|
+
raise InvalidQuery, 'Matrix must be in mode driving and a departure_time must be set'
|
201
198
|
end
|
202
199
|
end
|
200
|
+
# rubocop:enable Metrics/ClassLength
|
203
201
|
end
|
@@ -1,9 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'url_builder/polyline_encoder_buffer'
|
2
4
|
|
3
5
|
module GoogleDistanceMatrix
|
6
|
+
# Takes care of building the url for given matrix
|
4
7
|
class UrlBuilder
|
5
|
-
BASE_URL =
|
6
|
-
DELIMITER = CGI.escape(
|
8
|
+
BASE_URL = 'maps.googleapis.com/maps/api/distancematrix/json'
|
9
|
+
DELIMITER = CGI.escape('|')
|
7
10
|
MAX_URL_SIZE = 2048
|
8
11
|
|
9
12
|
attr_reader :matrix
|
@@ -12,41 +15,62 @@ module GoogleDistanceMatrix
|
|
12
15
|
def initialize(matrix)
|
13
16
|
@matrix = matrix
|
14
17
|
|
15
|
-
|
18
|
+
raise InvalidMatrix, matrix if matrix.invalid?
|
16
19
|
end
|
17
20
|
|
18
|
-
|
19
|
-
|
21
|
+
# Returns the URL we'll call Google API with
|
22
|
+
#
|
23
|
+
# This URL contains key and signature and is therefor
|
24
|
+
# sensitive.
|
25
|
+
#
|
26
|
+
# @return String
|
27
|
+
# @see filtered_url
|
28
|
+
def sensitive_url
|
29
|
+
@sensitive_url ||= build_url
|
20
30
|
end
|
21
31
|
|
32
|
+
# Returns the URL filtered as the configuration of the matrix dictates
|
33
|
+
#
|
34
|
+
# @return String
|
35
|
+
def filtered_url
|
36
|
+
filter_url sensitive_url
|
37
|
+
end
|
22
38
|
|
23
39
|
private
|
24
40
|
|
25
41
|
def build_url
|
26
|
-
url = [protocol, BASE_URL,
|
42
|
+
url = [protocol, BASE_URL, '?', query_params_string].join
|
27
43
|
|
28
44
|
if sign_url?
|
29
|
-
url = GoogleBusinessApiUrlSigner.add_signature(
|
45
|
+
url = GoogleBusinessApiUrlSigner.add_signature(
|
46
|
+
url, configuration.google_business_api_private_key
|
47
|
+
)
|
30
48
|
end
|
31
49
|
|
32
|
-
if url.length > MAX_URL_SIZE
|
33
|
-
|
50
|
+
raise MatrixUrlTooLong.new url, MAX_URL_SIZE if url.length > MAX_URL_SIZE
|
51
|
+
|
52
|
+
url
|
53
|
+
end
|
54
|
+
|
55
|
+
def filter_url(url)
|
56
|
+
configuration.filter_parameters_in_logged_url.each do |param|
|
57
|
+
url = url.gsub(/(#{param})=.*?(&|$)/, '\1=[FILTERED]\2')
|
34
58
|
end
|
35
59
|
|
36
60
|
url
|
37
61
|
end
|
38
62
|
|
39
63
|
def sign_url?
|
40
|
-
configuration.google_business_api_client_id.present?
|
41
|
-
|
64
|
+
configuration.google_business_api_client_id.present? &&
|
65
|
+
configuration.google_business_api_private_key.present?
|
42
66
|
end
|
43
67
|
|
44
68
|
def include_api_key?
|
45
69
|
configuration.google_api_key.present?
|
46
70
|
end
|
47
71
|
|
48
|
-
def
|
49
|
-
params.to_a.map { |key_value| key_value.join(
|
72
|
+
def query_params_string
|
73
|
+
params.to_a.map { |key_value| key_value.join('=') }.join('&')
|
50
74
|
end
|
51
75
|
|
52
76
|
def params
|
@@ -56,8 +80,10 @@ module GoogleDistanceMatrix
|
|
56
80
|
)
|
57
81
|
end
|
58
82
|
|
83
|
+
# rubocop:disable Metrics/MethodLength
|
84
|
+
# rubocop:disable Metrics/AbcSize
|
59
85
|
def places_to_param(places)
|
60
|
-
places_to_param_config = {lat_lng_scale: configuration.lat_lng_scale}
|
86
|
+
places_to_param_config = { lat_lng_scale: configuration.lat_lng_scale }
|
61
87
|
|
62
88
|
out = []
|
63
89
|
polyline_encode_buffer = PolylineEncoderBuffer.new
|
@@ -67,7 +93,7 @@ module GoogleDistanceMatrix
|
|
67
93
|
polyline_encode_buffer << place.lat_lng
|
68
94
|
else
|
69
95
|
polyline_encode_buffer.flush to: out
|
70
|
-
out << escape(place.to_param
|
96
|
+
out << escape(place.to_param(places_to_param_config))
|
71
97
|
end
|
72
98
|
end
|
73
99
|
|
@@ -75,9 +101,11 @@ module GoogleDistanceMatrix
|
|
75
101
|
|
76
102
|
out.join(DELIMITER)
|
77
103
|
end
|
104
|
+
# rubocop:enable Metrics/MethodLength
|
105
|
+
# rubocop:enable Metrics/AbcSize
|
78
106
|
|
79
107
|
def protocol
|
80
|
-
configuration.protocol +
|
108
|
+
configuration.protocol + '://'
|
81
109
|
end
|
82
110
|
|
83
111
|
def escape(string)
|
@@ -1,25 +1,41 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
2
4
|
|
3
5
|
describe GoogleDistanceMatrix::ClientCache do
|
4
|
-
let(:
|
5
|
-
let(:
|
6
|
+
let(:config) { GoogleDistanceMatrix::Configuration.new }
|
7
|
+
let(:url) { 'http://www.example.com' }
|
8
|
+
let(:options) { { hello: :options, configuration: config } }
|
6
9
|
|
7
|
-
let(:client) { double get:
|
10
|
+
let(:client) { double get: 'data' }
|
8
11
|
let(:cache) { double }
|
9
12
|
|
10
13
|
subject { described_class.new client, cache }
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
# rubocop:disable Metrics/LineLength
|
16
|
+
describe '::key' do
|
17
|
+
it 'returns a digest of given URL' do
|
18
|
+
key = described_class.key 'some url with secret parts', config
|
19
|
+
expect(key).to eq 'e90595434d4e321da6b01d2b99d77419ddaa8861d83c5971c4a119ee76bb80a7003915cc16e6966615f205b4a1d5411bb5d4a0d907f611b3fe4cc8d9049f4f9c'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#get' do
|
24
|
+
it 'returns from cache if it hits' do
|
25
|
+
expect(cache)
|
26
|
+
.to receive(:fetch)
|
27
|
+
.with('2f7d4c4d8a51afd0f9efb9edfda07591591cccc3704130328ad323d3cb5bf7ff19df5e895b402c99217d27d5f4547618094d47069c9ba58370ed8e26cc1de114')
|
28
|
+
.and_return 'cached-data'
|
29
|
+
|
30
|
+
expect(subject.get(url, options)).to eq 'cached-data'
|
16
31
|
end
|
32
|
+
# rubocop:enable Metrics/LineLength
|
17
33
|
|
18
|
-
it
|
19
|
-
expect(client).to receive(:get).with(url, options).and_return
|
34
|
+
it 'asks client when cache miss' do
|
35
|
+
expect(client).to receive(:get).with(url, options).and_return 'api-data'
|
20
36
|
expect(cache).to receive(:fetch) { |&block| block.call }
|
21
37
|
|
22
|
-
expect(subject.get(url, options)).to eq
|
38
|
+
expect(subject.get(url, options)).to eq 'api-data'
|
23
39
|
end
|
24
40
|
end
|
25
41
|
end
|
@@ -1,66 +1,76 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
2
4
|
|
3
5
|
describe GoogleDistanceMatrix::Client, :request_recordings do
|
4
|
-
let(:origin_1) { GoogleDistanceMatrix::Place.new address:
|
5
|
-
let(:destination_1) { GoogleDistanceMatrix::Place.new address:
|
6
|
-
let(:matrix)
|
6
|
+
let(:origin_1) { GoogleDistanceMatrix::Place.new address: 'Karl Johans gate, Oslo' }
|
7
|
+
let(:destination_1) { GoogleDistanceMatrix::Place.new address: 'Drammensveien 1, Oslo' }
|
8
|
+
let(:matrix) do
|
9
|
+
GoogleDistanceMatrix::Matrix.new(origins: [origin_1], destinations: [destination_1])
|
10
|
+
end
|
7
11
|
|
8
12
|
let(:url_builder) { GoogleDistanceMatrix::UrlBuilder.new matrix }
|
9
|
-
let(:url) { url_builder.
|
13
|
+
let(:url) { url_builder.sensitive_url }
|
10
14
|
|
11
15
|
subject { GoogleDistanceMatrix::Client.new }
|
12
16
|
|
13
|
-
describe
|
17
|
+
describe 'success' do
|
14
18
|
before { stub_request(:get, url).to_return body: recorded_request_for(:success) }
|
15
19
|
|
16
|
-
it
|
17
|
-
expect(subject.get(url_builder.
|
20
|
+
it 'makes the request' do
|
21
|
+
expect(subject.get(url_builder.sensitive_url).body).to eq recorded_request_for(:success).read
|
18
22
|
end
|
19
23
|
end
|
20
24
|
|
21
|
-
describe
|
22
|
-
describe
|
23
|
-
it
|
24
|
-
stub_request(:get, url).to_return status: [400,
|
25
|
-
expect { subject.get(url_builder.
|
25
|
+
describe 'client errors' do
|
26
|
+
describe 'server issues 4xx client error' do
|
27
|
+
it 'wraps the error http response' do
|
28
|
+
stub_request(:get, url).to_return status: [400, 'Client error']
|
29
|
+
expect { subject.get(url_builder.sensitive_url) }
|
30
|
+
.to raise_error GoogleDistanceMatrix::ClientError
|
26
31
|
end
|
27
32
|
|
28
|
-
it
|
29
|
-
stub_request(:get, url).to_return status: [414,
|
30
|
-
expect { subject.get(url_builder.
|
33
|
+
it 'wraps uri too long error' do
|
34
|
+
stub_request(:get, url).to_return status: [414, 'Client error']
|
35
|
+
expect { subject.get(url_builder.sensitive_url) }
|
36
|
+
.to raise_error GoogleDistanceMatrix::MatrixUrlTooLong
|
31
37
|
end
|
32
38
|
end
|
33
39
|
|
34
40
|
described_class::CLIENT_ERRORS.each do |error|
|
35
41
|
it "wraps '#{error}' client error" do
|
36
|
-
stub_request(:get, url).to_return body: JSON.generate(
|
37
|
-
expect { subject.get(url_builder.
|
42
|
+
stub_request(:get, url).to_return body: JSON.generate(status: error)
|
43
|
+
expect { subject.get(url_builder.sensitive_url) }
|
44
|
+
.to raise_error GoogleDistanceMatrix::ClientError
|
38
45
|
end
|
39
46
|
end
|
40
47
|
end
|
41
48
|
|
42
|
-
describe
|
43
|
-
describe
|
44
|
-
before { stub_request(:get, url).to_return status: [500,
|
49
|
+
describe 'request errors' do
|
50
|
+
describe 'server error' do
|
51
|
+
before { stub_request(:get, url).to_return status: [500, 'Internal Server Error'] }
|
45
52
|
|
46
|
-
it
|
47
|
-
expect { subject.get(url_builder.
|
53
|
+
it 'wraps the error http response' do
|
54
|
+
expect { subject.get(url_builder.sensitive_url) }
|
55
|
+
.to raise_error GoogleDistanceMatrix::ServerError
|
48
56
|
end
|
49
57
|
end
|
50
58
|
|
51
|
-
describe
|
59
|
+
describe 'timeout' do
|
52
60
|
before { stub_request(:get, url).to_timeout }
|
53
61
|
|
54
|
-
it
|
55
|
-
expect { subject.get(url_builder.
|
62
|
+
it 'wraps the error from Net::HTTP' do
|
63
|
+
expect { subject.get(url_builder.sensitive_url).body }
|
64
|
+
.to raise_error GoogleDistanceMatrix::ServerError
|
56
65
|
end
|
57
66
|
end
|
58
67
|
|
59
|
-
describe
|
60
|
-
before { stub_request(:get, url).to_return status: [999,
|
68
|
+
describe 'server error' do
|
69
|
+
before { stub_request(:get, url).to_return status: [999, 'Unknown'] }
|
61
70
|
|
62
|
-
it
|
63
|
-
expect { subject.get(url_builder.
|
71
|
+
it 'wraps the error http response' do
|
72
|
+
expect { subject.get(url_builder.sensitive_url) }
|
73
|
+
.to raise_error GoogleDistanceMatrix::ServerError
|
64
74
|
end
|
65
75
|
end
|
66
76
|
end
|