myjohndeere 0.0.2 → 0.0.3

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
  SHA1:
3
- metadata.gz: 97de75462b83ea9c04fb0910eddf732c5affe625
4
- data.tar.gz: 7484ca74f1e54531717ab252b15b411d9baaf69c
3
+ metadata.gz: 19143fdf01d2f2e3fc3eb61a056784ab48ad13b0
4
+ data.tar.gz: 993ce13479bad9f237f88583a70a8fa3b7110136
5
5
  SHA512:
6
- metadata.gz: f3514ced5a8b3562afd29aa60f46ba4a446b31710ed74c29578761d67d1104ec2823f6df2a4b34efd69214b25761661843b40f7813543d5599ab7399c6c99339
7
- data.tar.gz: 5fce3d3e6c94a6652fde1443e12921c160f84716bcd5870f42a2760af5bb672a272fb9cd3e4c4caa1126eea1a6bb11c56741fcb9960ef6ce60f388ad502f86a7
6
+ metadata.gz: 92af50934686b143601301a29b07ac15cc432751942516dec22a1345eb2202ff1f005d2ed4b4816d65c1e43232dddcbd353d23d8e47c6ae8024a4bc03f248938
7
+ data.tar.gz: 89a9a893e011627cf950349c88201e0e4c061876f278f495775cc29d33299e027139c2ca168855712122670c1b3e0b392fa64a653eb0079bd06f64f3c1c8016a
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- myjohndeere (0.0.1)
4
+ myjohndeere (0.0.2)
5
5
  oauth (>= 0.5.3)
6
6
 
7
7
  GEM
@@ -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
- # if response.code == "401"
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
@@ -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
- response = access_token.execute_request(:post,
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
- response = access_token.execute_request(:post,
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
- response = access_token.execute_request(:post,
28
- build_resouce_base_path!(self.list_resource_path, {field_id: field_id, organization_id: organization_id}),
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, build_resouce_base_path!(self.list_resource_path, options),
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
- "#{build_resouce_base_path!(self.retrieve_resource_path, options)}/#{id}",
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 build_resouce_base_path!(resource_path, options)
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
- return resource_path % base_resources
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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module MyJohnDeere
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -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 is used to make data-driven decisions to maximize your return on every acre. This Ruby Gem is provided as a convenient way to access their API.'
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'
@@ -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")
@@ -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
@@ -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.2
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-14 00:00:00.000000000 Z
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 is used to make data-driven decisions to maximize your
28
- return on every acre. This Ruby Gem is provided as a convenient way to access their
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: []