my_john_deere_api 2.4.1 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75b86b9b093f4aa0cc586ce56fb961654b1b91577947acf48392d8d2294c85b9
4
- data.tar.gz: b5879b20c85891180747ba42657ffa399da981596820c813a7049d680240dd39
3
+ metadata.gz: ba69ef151796a688f69eba0f6a396d277baa893aa9e589922f2f2eac7b4e3a6a
4
+ data.tar.gz: e0539d88ae84a348113be06e9f81299b64a5c74598428e9d2a33ec00b0b49584
5
5
  SHA512:
6
- metadata.gz: 6a8c729311baa853f8ae1039573f673cb01cc084d0fc9b662ce592dd1b907a85b153f04d07ebd6bf346558efb708242f5c13f3464f3c4c5b03a4c21a2479c2d9
7
- data.tar.gz: cf5dd0b1e590baeb06ead7ffeffb4a7501de17b8b56596a297797186f1bc85aa33b196f58f19162f6027e40a27b023f9ad18ad3aa25e07b61fcd383612c0bbaa
6
+ metadata.gz: 9a40c8720b6e44da21bb5c2d0247055cf8b4f7d04e5b6d9e5d6db03778af368e64b5d2ba375aa02aa671aebdbf3d64d87c8090beb958bb7dc83ef5b1da52196e
7
+ data.tar.gz: 77bac482b0518e59b534d1916b9155c2a59e75308cc71e93354c9a3d071fa10c35362ee836f3eb456b15f612b73d503f06c735d7af942d220415a39c6943c606
@@ -1,2 +1,4 @@
1
1
  require 'my_john_deere_api/net_http_retry/decorator'
2
+
3
+ require 'my_john_deere_api/net_http_retry/invalid_response_error'
2
4
  require 'my_john_deere_api/net_http_retry/max_retries_exceeded_error'
@@ -1,30 +1,35 @@
1
1
  module MyJohnDeereApi
2
2
  module NetHttpRetry
3
3
  class Decorator
4
- attr_reader :object, :request_methods, :retry_delay_exponent, :max_retries, :response_codes
4
+ attr_reader :object, :request_methods, :retry_delay_exponent, :max_retries, :retry_codes, :valid_codes
5
5
 
6
6
  DEFAULTS = {
7
7
  request_methods: [:get, :post, :put, :delete],
8
8
  retry_delay_exponent: 2,
9
9
  max_retries: 12,
10
- response_codes: ['429', '503']
10
+ retry_codes: ['429', '503'],
11
+ valid_codes: ['200', '201', '204'],
11
12
  }
12
13
 
13
14
  def initialize(object, options={})
14
15
  @object = object
15
16
 
17
+ # defaults that can be used as-is
16
18
  [:request_methods, :retry_delay_exponent, :max_retries].each do |option|
17
19
  instance_variable_set(:"@#{option}", options[option] || DEFAULTS[option])
18
20
  end
19
21
 
20
- @response_codes = (options[:response_codes] || DEFAULTS[:response_codes]).map(&:to_s)
22
+ # defaults that require casting as string arrays
23
+ [:retry_codes, :valid_codes].each do |option|
24
+ instance_variable_set(:"@#{option}", (options[option] || DEFAULTS[option]).map(&:to_s))
25
+ end
21
26
  end
22
27
 
23
28
  def request(method_name, *args)
24
29
  retries = 0
25
30
  result = object.send(method_name, *args)
26
31
 
27
- while response_codes.include?(result.code)
32
+ while retry_codes.include?(result.code)
28
33
  if retries >= max_retries
29
34
  raise MaxRetriesExceededError.new(method_name, "#{result.code} #{result.message}")
30
35
  end
@@ -36,6 +41,10 @@ module MyJohnDeereApi
36
41
  retries += 1
37
42
  end
38
43
 
44
+ unless valid_codes.include?(result.code)
45
+ raise InvalidResponseError.new(result)
46
+ end
47
+
39
48
  result
40
49
  end
41
50
 
@@ -0,0 +1,23 @@
1
+ module MyJohnDeereApi
2
+ module NetHttpRetry
3
+ ##
4
+ # This error is used when a single request has exceeded
5
+ # the number of retries allowed by NetHttpRetry::Decorator::MAX_RETRIES.
6
+
7
+ class InvalidResponseError < StandardError
8
+
9
+ ##
10
+ # argument is a string which describes the attempted request
11
+
12
+ def initialize(response)
13
+ message = {
14
+ code: response.code,
15
+ message: response.message,
16
+ body: response.body,
17
+ }.to_json
18
+
19
+ super(message)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module MyJohnDeereApi
2
- VERSION='2.4.1'
2
+ VERSION='2.5.0'
3
3
  end
@@ -18,14 +18,16 @@ describe 'JD::NetHttpRetry::Decorator' do
18
18
  request_methods: request_methods,
19
19
  retry_delay_exponent: retry_delay_exponent,
20
20
  max_retries: max_retries,
21
- response_codes: response_codes
21
+ retry_codes: retry_codes,
22
+ valid_codes: valid_codes
22
23
  }
23
24
  end
24
25
 
25
26
  let(:request_methods) { nil }
26
27
  let(:retry_delay_exponent) { nil }
27
28
  let(:max_retries) { nil }
28
- let(:response_codes) { nil }
29
+ let(:retry_codes) { nil }
30
+ let(:valid_codes) { nil }
29
31
 
30
32
  let(:retry_values) { [13, 17, 19, 23] }
31
33
  let(:exponential_retries) { (0..klass::DEFAULTS[:max_retries]-1).map{|i| 2 ** i} }
@@ -77,25 +79,50 @@ describe 'JD::NetHttpRetry::Decorator' do
77
79
  end
78
80
  end
79
81
 
80
- describe 'when response_codes are specified' do
81
- let(:response_codes) { ['200', '201'] }
82
+ describe 'when retry_codes are specified' do
83
+ let(:retry_codes) { ['200', '201'] }
82
84
 
83
85
  it 'uses the supplied values' do
84
- assert_equal response_codes, object.response_codes
86
+ assert_equal retry_codes, object.retry_codes
85
87
  end
86
88
  end
87
89
 
88
- describe 'when response_codes are specified as integers' do
89
- let(:response_codes) { [200, 201] }
90
+ describe 'when retry_codes are specified as integers' do
91
+ let(:retry_codes) { [200, 201] }
90
92
 
91
93
  it 'uses the stringified versions of the supplied values' do
92
- assert_equal response_codes.map(&:to_s), object.response_codes
94
+ assert_equal retry_codes.map(&:to_s), object.retry_codes
93
95
  end
94
96
  end
95
97
 
96
- describe 'when response_codes are not specified' do
98
+ describe 'when retry_codes are not specified' do
97
99
  it 'uses the default values' do
98
- assert_equal klass::DEFAULTS[:response_codes], object.response_codes
100
+ assert_equal klass::DEFAULTS[:retry_codes], object.retry_codes
101
+ end
102
+ end
103
+
104
+ describe 'when valid_codes are specified' do
105
+ let(:valid_codes) { ['123', '234'] }
106
+
107
+ it 'uses the supplied values' do
108
+ assert_equal valid_codes, object.valid_codes
109
+ end
110
+ end
111
+
112
+ describe 'when valid_codes are specified as integers' do
113
+ let(:valid_codes) { [123, 234] }
114
+
115
+ it 'uses the stringified versions of the supplied values' do
116
+ assert_equal valid_codes.map(&:to_s), object.valid_codes
117
+ end
118
+ end
119
+
120
+ describe 'when valid_codes are not specified' do
121
+ it 'uses the default values' do
122
+ assert_kind_of Array, klass::DEFAULTS[:valid_codes]
123
+ refute klass::DEFAULTS[:valid_codes].empty?
124
+
125
+ assert_equal klass::DEFAULTS[:valid_codes], object.valid_codes
99
126
  end
100
127
  end
101
128
  end
@@ -160,4 +187,22 @@ describe 'JD::NetHttpRetry::Decorator' do
160
187
  end
161
188
  end
162
189
  end
190
+
191
+ describe 'when an invalid response code is returned' do
192
+ REQUEST_METHODS.each do |request_method|
193
+ it "returns an error for #{request_method.to_s.upcase} requests" do
194
+ exception = assert_raises(JD::NetHttpRetry::InvalidResponseError) do
195
+ VCR.use_cassette("accessor/#{request_method}_invalid") do
196
+ accessor.send(request_method, REQUESTS[request_method])
197
+ end
198
+ end
199
+
200
+ exception_json = JSON.parse(exception.message)
201
+
202
+ assert_equal '500', exception_json['code']
203
+ assert_equal 'Internal Error', exception_json['message']
204
+ assert_equal 'You Have Died of Dysentery', exception_json['body']
205
+ end
206
+ end
207
+ end
163
208
  end
@@ -0,0 +1,19 @@
1
+ require 'support/helper'
2
+
3
+ describe 'JD::NetHttpRetry::InvalidResponseError' do
4
+ let(:klass) { JD::NetHttpRetry::InvalidResponseError }
5
+ let(:response) { stub(response_content) }
6
+ let(:response_content) { {code: '123', message: 'failed', body: 'body'} }
7
+
8
+ it 'inherits from StandardError' do
9
+ error = klass.new(response)
10
+ assert_kind_of StandardError, error
11
+ end
12
+
13
+ it 'accepts a response object, and includes pertinent info' do
14
+ expected_message = response_content.to_json
15
+ actual_message = klass.new(response).message
16
+
17
+ assert_equal expected_message, actual_message
18
+ end
19
+ end
@@ -0,0 +1,39 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: delete
5
+ uri: https://sandboxapi.deere.com/platform/assets/00000000-0000-0000-0000-000000000000
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/vnd.deere.axiom.v3+json
12
+ Accept-Encoding:
13
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
14
+ User-Agent:
15
+ - OAuth gem v0.5.4
16
+ Authorization:
17
+ - OAuth oauth_consumer_key="johndeere-0000000000000000000000000000000000000000",
18
+ oauth_nonce="000000000000000000000000000000000000000000", oauth_signature="0000000000000000000000000000",
19
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1581334172", oauth_token="00000000-0000-0000-0000-000000000000",
20
+ oauth_version="1.0"
21
+ response:
22
+ status:
23
+ code: 500
24
+ message: Internal Error
25
+ headers:
26
+ Date:
27
+ - Mon, 10 Feb 2020 17:29:36 GMT
28
+ X-Deere-Handling-Server:
29
+ - ip-10-214-45-99
30
+ X-Frame-Options:
31
+ - SAMEORIGIN
32
+ X-Deere-Elapsed-Ms:
33
+ - '96'
34
+ body:
35
+ encoding: UTF-8
36
+ string: You Have Died of Dysentery
37
+ http_version:
38
+ recorded_at: Mon, 10 Feb 2020 17:29:36 GMT
39
+ recorded_with: VCR 5.0.0
@@ -0,0 +1,46 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://sandboxapi.deere.com/platform/
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/vnd.deere.axiom.v3+json
12
+ Accept-Encoding:
13
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
14
+ User-Agent:
15
+ - OAuth gem v0.5.4
16
+ Authorization:
17
+ - OAuth oauth_consumer_key="johndeere-0000000000000000000000000000000000000000",
18
+ oauth_nonce="000000000000000000000000000000000000000000", oauth_signature="0000000000000000000000000000",
19
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1581334172", oauth_version="1.0"
20
+ response:
21
+ status:
22
+ code: 500
23
+ message: Internal Error
24
+ headers:
25
+ Date:
26
+ - Mon, 10 Feb 2020 17:29:28 GMT
27
+ Content-Type:
28
+ - application/vnd.deere.axiom.v3+json;charset=UTF-8
29
+ X-Deere-Handling-Server:
30
+ - ip-10-214-44-28
31
+ X-Frame-Options:
32
+ - SAMEORIGIN
33
+ X-Deere-Elapsed-Ms:
34
+ - '11'
35
+ Cache-Control:
36
+ - no-store
37
+ Content-Language:
38
+ - en-US
39
+ Transfer-Encoding:
40
+ - chunked
41
+ body:
42
+ encoding: ASCII-8BIT
43
+ string: You Have Died of Dysentery
44
+ http_version:
45
+ recorded_at: Mon, 10 Feb 2020 17:29:28 GMT
46
+ recorded_with: VCR 5.0.0
@@ -0,0 +1,49 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://sandboxapi.deere.com/platform/organizations/000000/assets
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"title":"Asset Title","assetCategory":"DEVICE","assetType":"SENSOR","assetSubType":"ENVIRONMENTAL","links":[{"@type":"Link","rel":"contributionDefinition","uri":"https://sandboxapi.deere.com/platform/contributionDefinitions/00000000-0000-0000-0000-000000000000"}]}'
9
+ headers:
10
+ Accept:
11
+ - application/vnd.deere.axiom.v3+json
12
+ Content-Type:
13
+ - application/vnd.deere.axiom.v3+json
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ User-Agent:
17
+ - OAuth gem v0.5.4
18
+ Content-Length:
19
+ - '265'
20
+ Authorization:
21
+ - OAuth oauth_body_hash="hObY6LROUn9S1WS8S28eTTfqmWk%3D", oauth_consumer_key="johndeere-0000000000000000000000000000000000000000",
22
+ oauth_nonce="000000000000000000000000000000000000000000", oauth_signature="0000000000000000000000000000",
23
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1581334172", oauth_token="00000000-0000-0000-0000-000000000000",
24
+ oauth_version="1.0"
25
+ response:
26
+ status:
27
+ code: 500
28
+ message: Internal Error
29
+ headers:
30
+ Date:
31
+ - Mon, 10 Feb 2020 17:29:25 GMT
32
+ Content-Type:
33
+ - application/vnd.deere.axiom.v3+json
34
+ X-Deere-Handling-Server:
35
+ - ip-10-214-45-213
36
+ X-Frame-Options:
37
+ - SAMEORIGIN
38
+ Location:
39
+ - https://sandboxapi.deere.com/platform/assets/00000000-0000-0000-0000-000000000000
40
+ X-Deere-Elapsed-Ms:
41
+ - '121'
42
+ Transfer-Encoding:
43
+ - chunked
44
+ body:
45
+ encoding: ASCII-8BIT
46
+ string: You Have Died of Dysentery
47
+ http_version:
48
+ recorded_at: Mon, 10 Feb 2020 17:29:26 GMT
49
+ recorded_with: VCR 5.0.0
@@ -0,0 +1,44 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: put
5
+ uri: https://sandboxapi.deere.com/platform/assets/00000000-0000-0000-0000-000000000000
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"assetCategory":"DEVICE","assetType":"SENSOR","assetSubType":"ENVIRONMENTAL","title":"i
9
+ REALLY like turtles!","links":[{"@type":"Link","rel":"contributionDefinition","uri":"https://sandboxapi.deere.com/contributionDefinitions/00000000-0000-0000-0000-000000000000"}]}'
10
+ headers:
11
+ Accept:
12
+ - application/vnd.deere.axiom.v3+json
13
+ Content-Type:
14
+ - application/vnd.deere.axiom.v3+json
15
+ Accept-Encoding:
16
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
17
+ User-Agent:
18
+ - OAuth gem v0.5.4
19
+ Content-Length:
20
+ - '267'
21
+ Authorization:
22
+ - OAuth oauth_body_hash="JXqhMr0ayK5gfHyej3M1xuUfSbw%3D", oauth_consumer_key="johndeere-0000000000000000000000000000000000000000",
23
+ oauth_nonce="000000000000000000000000000000000000000000", oauth_signature="0000000000000000000000000000",
24
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1581334172", oauth_token="00000000-0000-0000-0000-000000000000",
25
+ oauth_version="1.0"
26
+ response:
27
+ status:
28
+ code: 500
29
+ message: Internal Error
30
+ headers:
31
+ Date:
32
+ - Mon, 10 Feb 2020 17:29:30 GMT
33
+ X-Deere-Handling-Server:
34
+ - ip-10-214-44-33
35
+ X-Frame-Options:
36
+ - SAMEORIGIN
37
+ X-Deere-Elapsed-Ms:
38
+ - '185'
39
+ body:
40
+ encoding: UTF-8
41
+ string: You Have Died of Dysentery
42
+ http_version:
43
+ recorded_at: Mon, 10 Feb 2020 17:29:30 GMT
44
+ recorded_with: VCR 5.0.0
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: my_john_deere_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.1
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaime Bellmyer
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-07-21 00:00:00.000000000 Z
12
+ date: 2020-07-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: vcr
@@ -128,6 +128,7 @@ files:
128
128
  - lib/my_john_deere_api/model/organization.rb
129
129
  - lib/my_john_deere_api/net_http_retry.rb
130
130
  - lib/my_john_deere_api/net_http_retry/decorator.rb
131
+ - lib/my_john_deere_api/net_http_retry/invalid_response_error.rb
131
132
  - lib/my_john_deere_api/net_http_retry/max_retries_exceeded_error.rb
132
133
  - lib/my_john_deere_api/request.rb
133
134
  - lib/my_john_deere_api/request/collection.rb
@@ -162,7 +163,6 @@ files:
162
163
  - test/lib/my_john_deere_api/client_test.rb
163
164
  - test/lib/my_john_deere_api/consumer_test.rb
164
165
  - test/lib/my_john_deere_api/errors/invalid_record_error_test.rb
165
- - test/lib/my_john_deere_api/errors/max_retries_exceeded_error_test.rb
166
166
  - test/lib/my_john_deere_api/errors/missing_contribution_definition_id_error_test.rb
167
167
  - test/lib/my_john_deere_api/errors/not_yet_implemented_error_test.rb
168
168
  - test/lib/my_john_deere_api/errors/type_mismatch_error_test.rb
@@ -183,6 +183,8 @@ files:
183
183
  - test/lib/my_john_deere_api/model/organization_test.rb
184
184
  - test/lib/my_john_deere_api/model_test.rb
185
185
  - test/lib/my_john_deere_api/net_http_retry/decorator_test.rb
186
+ - test/lib/my_john_deere_api/net_http_retry/invalid_response_error_test.rb
187
+ - test/lib/my_john_deere_api/net_http_retry/max_retries_exceeded_error_test.rb
186
188
  - test/lib/my_john_deere_api/request/collection/asset_locations_test.rb
187
189
  - test/lib/my_john_deere_api/request/collection/assets_test.rb
188
190
  - test/lib/my_john_deere_api/request/collection/base_test.rb
@@ -215,18 +217,22 @@ files:
215
217
  - test/my_john_deere_api_test.rb
216
218
  - test/support/helper.rb
217
219
  - test/support/vcr/accessor/delete_failed.yml
220
+ - test/support/vcr/accessor/delete_invalid.yml
218
221
  - test/support/vcr/accessor/delete_max_failed.yml
219
222
  - test/support/vcr/accessor/delete_retry.yml
220
223
  - test/support/vcr/accessor/delete_retry_too_soon.yml
221
224
  - test/support/vcr/accessor/get_failed.yml
225
+ - test/support/vcr/accessor/get_invalid.yml
222
226
  - test/support/vcr/accessor/get_max_failed.yml
223
227
  - test/support/vcr/accessor/get_retry.yml
224
228
  - test/support/vcr/accessor/get_retry_too_soon.yml
225
229
  - test/support/vcr/accessor/post_failed.yml
230
+ - test/support/vcr/accessor/post_invalid.yml
226
231
  - test/support/vcr/accessor/post_max_failed.yml
227
232
  - test/support/vcr/accessor/post_retry.yml
228
233
  - test/support/vcr/accessor/post_retry_too_soon.yml
229
234
  - test/support/vcr/accessor/put_failed.yml
235
+ - test/support/vcr/accessor/put_invalid.yml
230
236
  - test/support/vcr/accessor/put_max_failed.yml
231
237
  - test/support/vcr/accessor/put_retry.yml
232
238
  - test/support/vcr/accessor/put_retry_too_soon.yml