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