my_john_deere_api 2.4.1 → 2.5.0

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 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