myjohndeere 0.0.2 → 0.0.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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/myjohndeere/access_token.rb +2 -7
- data/lib/myjohndeere/errors.rb +51 -0
- data/lib/myjohndeere/file_resource.rb +1 -11
- data/lib/myjohndeere/map_layer.rb +1 -6
- data/lib/myjohndeere/map_layer_summary.rb +2 -11
- data/lib/myjohndeere/rest_methods.rb +24 -5
- data/lib/myjohndeere/util.rb +31 -0
- data/lib/myjohndeere/version.rb +1 -1
- data/myjohndeere.gemspec +1 -1
- data/test/test_access_token.rb +10 -0
- data/test/test_map_layer.rb +2 -1
- data/test/test_rest_methods.rb +13 -0
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19143fdf01d2f2e3fc3eb61a056784ab48ad13b0
|
4
|
+
data.tar.gz: 993ce13479bad9f237f88583a70a8fa3b7110136
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92af50934686b143601301a29b07ac15cc432751942516dec22a1345eb2202ff1f005d2ed4b4816d65c1e43232dddcbd353d23d8e47c6ae8024a4bc03f248938
|
7
|
+
data.tar.gz: 89a9a893e011627cf950349c88201e0e4c061876f278f495775cc29d33299e027139c2ca168855712122670c1b3e0b392fa64a653eb0079bd06f64f3c1c8016a
|
data/Gemfile.lock
CHANGED
@@ -59,6 +59,7 @@ module MyJohnDeere
|
|
59
59
|
body: options[:body],
|
60
60
|
etag: options[:etag])
|
61
61
|
response = nil
|
62
|
+
MyJohnDeere.logger.debug("Sending request with body: #{body}\n headers: #{headers}")
|
62
63
|
if REQUEST_METHODS_TO_PUT_PARAMS_IN_URL.include?(method)
|
63
64
|
response = self.oauth_access_token.send(method, path, headers)
|
64
65
|
else
|
@@ -66,13 +67,7 @@ module MyJohnDeere
|
|
66
67
|
response = self.oauth_access_token.send(method, path, body, headers)
|
67
68
|
end
|
68
69
|
MyJohnDeere.logger.info("JohnDeere token response: #{response.body}")
|
69
|
-
|
70
|
-
# self.notify_on_destroy = true
|
71
|
-
# # we are no longer authorized
|
72
|
-
# self.destroy
|
73
|
-
# logger.info("JohnDeere token destroyed: #{self.persisted?}, errors: #{self.errors.full_messages}")
|
74
|
-
# end
|
75
|
-
# return response
|
70
|
+
Util.handle_response_error_codes(response)
|
76
71
|
return Response.new(response)
|
77
72
|
end
|
78
73
|
end
|
data/lib/myjohndeere/errors.rb
CHANGED
@@ -2,9 +2,60 @@ module MyJohnDeere
|
|
2
2
|
# MyJohnDeereError is the base error from which all other more specific MyJohnError
|
3
3
|
# errors derive.
|
4
4
|
class MyJohnDeereError < StandardError
|
5
|
+
attr_reader :message
|
6
|
+
|
7
|
+
# These fields are now available as part of #response and that usage should
|
8
|
+
# be preferred.
|
9
|
+
attr_reader :http_body
|
10
|
+
attr_reader :http_headers
|
11
|
+
attr_reader :http_status
|
12
|
+
|
13
|
+
attr_accessor :response
|
14
|
+
# Initializes a MyJohnDeereError.
|
15
|
+
def initialize(message=nil, http_status: nil, http_body: nil,
|
16
|
+
http_headers: nil, my_john_deere_response: nil)
|
17
|
+
@message = message
|
18
|
+
if my_john_deere_response.is_a?(MyJohnDeere::Response) then
|
19
|
+
self.response = my_john_deere_response
|
20
|
+
http_status = my_john_deere_response.http_status
|
21
|
+
http_body = my_john_deere_response.http_body
|
22
|
+
http_headers = my_john_deere_response.http_headers
|
23
|
+
end
|
24
|
+
@http_status = http_status
|
25
|
+
@http_body = http_body
|
26
|
+
@http_headers = http_headers || {}
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
status_string = @http_status.nil? ? "" : "(Status #{@http_status}) "
|
31
|
+
id_string = @request_id.nil? ? "" : "(Request #{@request_id}) "
|
32
|
+
"#{status_string}#{id_string}#{@message}"
|
33
|
+
end
|
5
34
|
end
|
6
35
|
|
7
36
|
# Configuration error is raised when configuration hasn't been properly done
|
8
37
|
class ConfigurationError < MyJohnDeereError
|
9
38
|
end
|
39
|
+
|
40
|
+
# AuthenticationError is raised when invalid credentials are used to connect
|
41
|
+
# to MyJohnDeere's servers or if your credentials have expired.
|
42
|
+
class AuthenticationError < MyJohnDeereError
|
43
|
+
end
|
44
|
+
|
45
|
+
# Raised when accessing resources you don't have access to. Generally just need to
|
46
|
+
# avoid making this request
|
47
|
+
class PermissionError < MyJohnDeereError
|
48
|
+
end
|
49
|
+
|
50
|
+
# Raised when too many requests are being made
|
51
|
+
class RateLimitError < MyJohnDeereError
|
52
|
+
end
|
53
|
+
|
54
|
+
# Raised when something goes wrong with MyJohnDeere API
|
55
|
+
class InternalServerError < MyJohnDeereError
|
56
|
+
end
|
57
|
+
|
58
|
+
# Raised when the server is busy
|
59
|
+
class ServerBusyError < MyJohnDeereError
|
60
|
+
end
|
10
61
|
end
|
@@ -30,17 +30,7 @@ module MyJohnDeere
|
|
30
30
|
metadata: metadata.map { |m| m.to_hash }
|
31
31
|
}
|
32
32
|
|
33
|
-
|
34
|
-
build_resouce_base_path!(self.list_resource_path, {map_layer_id: map_layer_id}),
|
35
|
-
body: body
|
36
|
-
)
|
37
|
-
#{"Content-Type"=>"text/plain", "X-Deere-Handling-Server"=>"ldxtc3", "X-Frame-Options"=>"SAMEORIGIN", "Location"=>"https://sandboxapi.deere.com/platform/mapLayers/e2711205-c5df-445e-aad5-81eaf9090e6c", "X-Deere-Elapsed-Ms"=>"162", "Vary"=>"Accept-Encoding", "Expires"=>"Thu, 14 Sep 2017 15:52:24 GMT", "Cache-Control"=>"max-age=0, no-cache", "Pragma"=>"no-cache", "Date"=>"Thu, 14 Sep 2017 15:52:24 GMT", "Transfer-Encoding"=>"chunked", "Connection"=>"close, Transfer-Encoding"}
|
38
|
-
id = get_created_id_from_response_headers(self.base_jd_resource, response)
|
39
|
-
if id.nil? then
|
40
|
-
return nil
|
41
|
-
else
|
42
|
-
return self.new(HashUtils.deep_stringify_keys({"id" => id}.merge(body)))
|
43
|
-
end
|
33
|
+
return send_create(access_token, body, {map_layer_id: map_layer_id})
|
44
34
|
end
|
45
35
|
|
46
36
|
def self.upload_file(access_token, file_resource_id, file_path)
|
@@ -30,12 +30,7 @@ module MyJohnDeere
|
|
30
30
|
}
|
31
31
|
}
|
32
32
|
|
33
|
-
|
34
|
-
build_resouce_base_path!(self.list_resource_path, {map_layer_summary_id: map_layer_summary_id}),
|
35
|
-
body: body
|
36
|
-
)
|
37
|
-
#{"Content-Type"=>"text/plain", "X-Deere-Handling-Server"=>"ldxtc3", "X-Frame-Options"=>"SAMEORIGIN", "Location"=>"https://sandboxapi.deere.com/platform/mapLayers/e2711205-c5df-445e-aad5-81eaf9090e6c", "X-Deere-Elapsed-Ms"=>"162", "Vary"=>"Accept-Encoding", "Expires"=>"Thu, 14 Sep 2017 15:52:24 GMT", "Cache-Control"=>"max-age=0, no-cache", "Pragma"=>"no-cache", "Date"=>"Thu, 14 Sep 2017 15:52:24 GMT", "Transfer-Encoding"=>"chunked", "Connection"=>"close, Transfer-Encoding"}
|
38
|
-
return get_created_id_from_response_headers(self.base_jd_resource, response)
|
33
|
+
return send_create(access_token, body, {map_layer_summary_id: map_layer_summary_id})
|
39
34
|
end
|
40
35
|
end
|
41
36
|
end
|
@@ -24,17 +24,8 @@ module MyJohnDeere
|
|
24
24
|
metadata: metadata.map { |md| md.to_hash },
|
25
25
|
dateCreated: (date_created || Time.now).strftime("%Y-%m-%dT%H:%M:%S.%LZ")
|
26
26
|
}
|
27
|
-
|
28
|
-
|
29
|
-
body: body
|
30
|
-
)
|
31
|
-
#{"Content-Type"=>"text/plain", "X-Deere-Handling-Server"=>"ldxtc4", "X-Frame-Options"=>"SAMEORIGIN", "Location"=>"https://sandboxapi.deere.com/platform/mapLayerSummaries/c5e9317e-eda6-48d3-acc8-c3bca3424858", "X-Deere-Elapsed-Ms"=>"362", "Vary"=>"Accept-Encoding", "Expires"=>"Wed, 13 Sep 2017 22:00:45 GMT", "Cache-Control"=>"max-age=0, no-cache", "Pragma"=>"no-cache", "Date"=>"Wed, 13 Sep 2017 22:00:45 GMT", "Transfer-Encoding"=>"chunked", "Connection"=>"close, Transfer-Encoding"}
|
32
|
-
id = get_created_id_from_response_headers(self.base_jd_resource, response)
|
33
|
-
if id.nil?
|
34
|
-
return nil
|
35
|
-
else
|
36
|
-
return self.new(HashUtils.deep_stringify_keys({"id" => id}.merge(body)))
|
37
|
-
end
|
27
|
+
|
28
|
+
return send_create(access_token, body, {field_id: field_id, organization_id: organization_id})
|
38
29
|
end
|
39
30
|
end
|
40
31
|
end
|
@@ -15,7 +15,7 @@ module MyJohnDeere
|
|
15
15
|
options[:body][sbp] = options[sbp]
|
16
16
|
end
|
17
17
|
|
18
|
-
response = access_token.execute_request(:get,
|
18
|
+
response = access_token.execute_request(:get, build_resource_base_path!(self.list_resource_path, options),
|
19
19
|
options
|
20
20
|
)
|
21
21
|
return ListObject.new(
|
@@ -31,25 +31,44 @@ module MyJohnDeere
|
|
31
31
|
def retrieve(access_token, id, options={})
|
32
32
|
validate_access_token(access_token)
|
33
33
|
response = access_token.execute_request(:get,
|
34
|
-
"#{
|
34
|
+
"#{build_resource_base_path!(self.retrieve_resource_path, options)}/#{id}",
|
35
35
|
options)
|
36
36
|
|
37
37
|
return new(response.data, access_token)
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
40
|
+
def build_resource_base_path!(resource_path, options = {})
|
41
|
+
expected_definitions = resource_path.scan(/%{(.+?)}/)
|
42
|
+
return resource_path if expected_definitions.empty?
|
41
43
|
base_resources = {}
|
42
44
|
options.each do |key, val|
|
43
45
|
base_resources[key] = options.delete(key) if key.match(/_id\Z/)
|
44
46
|
end
|
45
|
-
return resource_path if base_resources.nil? || base_resources.empty?
|
46
47
|
MyJohnDeere.logger.info("Building resource path: #{resource_path}, with ids: #{base_resources}")
|
47
|
-
|
48
|
+
begin
|
49
|
+
return resource_path % base_resources
|
50
|
+
rescue KeyError
|
51
|
+
raise ArgumentError.new("You must specify #{expected_definitions.join(", ")} as part of this request path")
|
52
|
+
end
|
48
53
|
end
|
49
54
|
|
50
55
|
def validate_access_token(access_token)
|
51
56
|
raise ArgumentError.new("The first argument must be an #{AccessToken}") if !access_token.is_a?(AccessToken)
|
52
57
|
end
|
58
|
+
|
59
|
+
def send_create(access_token, body, path_builder_options = {})
|
60
|
+
response = access_token.execute_request(:post,
|
61
|
+
build_resource_base_path!(self.list_resource_path, path_builder_options),
|
62
|
+
body: body
|
63
|
+
)
|
64
|
+
#{"Content-Type"=>"text/plain", "X-Deere-Handling-Server"=>"ldxtc3", "X-Frame-Options"=>"SAMEORIGIN", "Location"=>"https://sandboxapi.deere.com/platform/mapLayers/e2711205-c5df-445e-aad5-81eaf9090e6c", "X-Deere-Elapsed-Ms"=>"162", "Vary"=>"Accept-Encoding", "Expires"=>"Thu, 14 Sep 2017 15:52:24 GMT", "Cache-Control"=>"max-age=0, no-cache", "Pragma"=>"no-cache", "Date"=>"Thu, 14 Sep 2017 15:52:24 GMT", "Transfer-Encoding"=>"chunked", "Connection"=>"close, Transfer-Encoding"}
|
65
|
+
id = get_created_id_from_response_headers(self.base_jd_resource, response)
|
66
|
+
if id.nil? then
|
67
|
+
return nil
|
68
|
+
else
|
69
|
+
return self.new(HashUtils.deep_stringify_keys({"id" => id}.merge(body)))
|
70
|
+
end
|
71
|
+
end
|
53
72
|
end
|
54
73
|
|
55
74
|
module InstanceMethods
|
data/lib/myjohndeere/util.rb
CHANGED
@@ -50,5 +50,36 @@ module MyJohnDeere
|
|
50
50
|
|
51
51
|
return path, headers, body
|
52
52
|
end
|
53
|
+
|
54
|
+
def self.handle_response_error_codes(response)
|
55
|
+
headers = response.to_hash
|
56
|
+
code = response.code.to_i
|
57
|
+
body = response.body
|
58
|
+
error = nil
|
59
|
+
case code
|
60
|
+
when 503
|
61
|
+
error = ServerBusyError
|
62
|
+
when 400, 404
|
63
|
+
error = InvalidRequestError
|
64
|
+
when 401
|
65
|
+
error = AuthenticationError
|
66
|
+
when 403
|
67
|
+
error = PermissionError
|
68
|
+
when 429
|
69
|
+
error = RateLimitError
|
70
|
+
when 500
|
71
|
+
error = InternalServerError
|
72
|
+
end
|
73
|
+
|
74
|
+
if error.nil? then
|
75
|
+
return
|
76
|
+
else
|
77
|
+
error = error.new(
|
78
|
+
http_status: code, http_body: body,
|
79
|
+
http_headers: headers)
|
80
|
+
error.response = response
|
81
|
+
raise error
|
82
|
+
end
|
83
|
+
end
|
53
84
|
end
|
54
85
|
end
|
data/lib/myjohndeere/version.rb
CHANGED
data/myjohndeere.gemspec
CHANGED
@@ -7,7 +7,7 @@ spec = Gem::Specification.new do |s|
|
|
7
7
|
s.version = MyJohnDeere::VERSION
|
8
8
|
s.required_ruby_version = '>= 1.9.3'
|
9
9
|
s.summary = 'Ruby bindings for the MyJohnDeere API'
|
10
|
-
s.description = ' MyJohnDeere
|
10
|
+
s.description = ' MyJohnDeere allows you to access your John Deere Financial account, JDLink, Operations Center and many other applications from one convenient place. This Ruby Gem is provided as a convenient way to access their API.'
|
11
11
|
s.author = 'Paul Susmarski'
|
12
12
|
s.email = 'paul@susmarski.com'
|
13
13
|
s.homepage = 'https://github.com/psusmars/myjohndeere'
|
data/test/test_access_token.rb
CHANGED
@@ -47,6 +47,16 @@ class TestAccessToken < Minitest::Test
|
|
47
47
|
assert_equal expected_secret, at.secret
|
48
48
|
end
|
49
49
|
|
50
|
+
def test_send_request_with_bad_responses
|
51
|
+
at = default_access_token()
|
52
|
+
stub_request(:get, "https://sandboxapi.deere.com/platform/").
|
53
|
+
to_return(status: 403, body: "Stuff")
|
54
|
+
|
55
|
+
assert_raises MyJohnDeere::PermissionError do
|
56
|
+
at.execute_request(:get, "/")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
50
60
|
def test_send_get_request
|
51
61
|
at = default_access_token()
|
52
62
|
expected_json = API_FIXTURES.fetch("api_catalog")
|
data/test/test_map_layer.rb
CHANGED
@@ -48,6 +48,7 @@ class TestMapLayer < Minitest::Test
|
|
48
48
|
title: "blah",
|
49
49
|
map_layer_id: "foo", map_legend_items: [MyJohnDeere::MapLegendItem.new("bar", 1, 2, "#0BA74A", 15.0)]
|
50
50
|
)
|
51
|
-
assert_equal MAP_LAYER_ID, response
|
51
|
+
assert_equal MAP_LAYER_ID, response.id
|
52
|
+
assert_equal ORGANIZATION_ID, response.organization_id
|
52
53
|
end
|
53
54
|
end
|
data/test/test_rest_methods.rb
CHANGED
@@ -24,6 +24,19 @@ class TestRestMethods < Minitest::Test
|
|
24
24
|
assert_equal "something", organizations.etag
|
25
25
|
end
|
26
26
|
|
27
|
+
def test_build_resource_base_path
|
28
|
+
resource_path = "blah"
|
29
|
+
assert_equal "blah", MyJohnDeere::Organization.build_resource_base_path!("blah", {})
|
30
|
+
resource_path = "blah%{x_id}"
|
31
|
+
options = {x: 5, x_id: 1}
|
32
|
+
assert_equal "blah1", MyJohnDeere::Organization.build_resource_base_path!(resource_path, options)
|
33
|
+
assert_equal({x: 5}, options)
|
34
|
+
|
35
|
+
assert_raises ArgumentError do
|
36
|
+
MyJohnDeere::Organization.build_resource_base_path!(resource_path, {})
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
27
40
|
def test_list_with_body
|
28
41
|
stub_request(:get, /organizations;start=0;count=1/).
|
29
42
|
with(query: {embed: "boundaries"}).
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: myjohndeere
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Susmarski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oauth
|
@@ -24,9 +24,9 @@ dependencies:
|
|
24
24
|
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.5.3
|
27
|
-
description: ' MyJohnDeere
|
28
|
-
|
29
|
-
API.'
|
27
|
+
description: ' MyJohnDeere allows you to access your John Deere Financial account,
|
28
|
+
JDLink, Operations Center and many other applications from one convenient place.
|
29
|
+
This Ruby Gem is provided as a convenient way to access their API.'
|
30
30
|
email: paul@susmarski.com
|
31
31
|
executables: []
|
32
32
|
extensions: []
|