my_john_deere_api 0.3.0 → 0.4.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 +4 -4
- data/lib/my_john_deere_api/client.rb +1 -1
- data/lib/my_john_deere_api/consumer.rb +88 -84
- data/lib/my_john_deere_api/errors/access_token_error.rb +12 -0
- data/lib/my_john_deere_api/errors.rb +2 -11
- data/lib/my_john_deere_api/helpers/case_conversion.rb +27 -0
- data/lib/my_john_deere_api/helpers.rb +1 -0
- data/lib/my_john_deere_api/model/field.rb +13 -0
- data/lib/my_john_deere_api/model/flag.rb +51 -0
- data/lib/my_john_deere_api/model/organization.rb +14 -1
- data/lib/my_john_deere_api/model.rb +1 -0
- data/lib/my_john_deere_api/request/collection/base.rb +83 -0
- data/lib/my_john_deere_api/request/{fields.rb → collection/fields.rb} +1 -1
- data/lib/my_john_deere_api/request/collection/flags.rb +19 -0
- data/lib/my_john_deere_api/request/{organizations.rb → collection/organizations.rb} +1 -1
- data/lib/my_john_deere_api/request/collection.rb +5 -82
- data/lib/my_john_deere_api/request.rb +0 -2
- data/lib/my_john_deere_api/version.rb +1 -1
- data/test/lib/my_john_deere_api/errors/test_access_token_error.rb +13 -0
- data/test/lib/my_john_deere_api/helpers/test_case_conversion.rb +56 -0
- data/test/lib/my_john_deere_api/model/test_flag.rb +52 -0
- data/test/lib/my_john_deere_api/request/collection/test_base.rb +28 -0
- data/test/lib/my_john_deere_api/request/{test_fields.rb → collection/test_fields.rb} +3 -3
- data/test/lib/my_john_deere_api/request/collection/test_flags.rb +90 -0
- data/test/lib/my_john_deere_api/request/{test_organizations.rb → collection/test_organizations.rb} +2 -2
- data/test/lib/my_john_deere_api/request/test_collection.rb +11 -18
- data/test/lib/my_john_deere_api/test_errors.rb +9 -0
- data/test/lib/my_john_deere_api/test_helpers.rb +4 -0
- data/test/lib/my_john_deere_api/test_model.rb +4 -0
- data/test/lib/my_john_deere_api/test_request.rb +0 -8
- data/test/support/vcr/get_flags.yml +47 -0
- metadata +17 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5005d82b1ef3ac1363022c0a4344000cd823bef860301bc9a067f3d5ac200cbc
|
4
|
+
data.tar.gz: df32f8ea65db2bb668f23fa1a9c7e48db055abf6fc85dbeb84b51d97db777050
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85b45d83f40727e26a7259c4237abe4d876a4eb6edb9c73eca3764ceb3253d5220729ac4fa52ab7b03e3e9fad4fbf2efbc3d97c91a80f7f57e17704b69cc89fe
|
7
|
+
data.tar.gz: 6511158e47fc47504f0143569ad435f00e45cd9cfa24a52be526bfd20f22d9f606bed14d22246fa1f0308865bebb92ad8b449dd41476fe269511011bb7ea5318
|
@@ -46,7 +46,7 @@ class MyJohnDeereApi::Client
|
|
46
46
|
|
47
47
|
def organizations
|
48
48
|
return @organizations if defined?(@organizations)
|
49
|
-
@organizations = MyJohnDeereApi::Request::Organizations.new(accessor).all
|
49
|
+
@organizations = MyJohnDeereApi::Request::Collection::Organizations.new(accessor).all
|
50
50
|
end
|
51
51
|
|
52
52
|
private
|
@@ -1,85 +1,89 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
1
|
+
module MyJohnDeereApi
|
2
|
+
class Consumer
|
3
|
+
include Helpers::CaseConversion
|
4
|
+
|
5
|
+
attr_reader :api_key, :api_secret, :environment, :base_url
|
6
|
+
|
7
|
+
# valid API urls
|
8
|
+
URLS = {
|
9
|
+
sandbox: 'https://sandboxapi.deere.com',
|
10
|
+
production: 'https://api.soa-proxy.deere.com',
|
11
|
+
}
|
12
|
+
|
13
|
+
DEFAULTS = {
|
14
|
+
environment: :production
|
15
|
+
}
|
16
|
+
|
17
|
+
def initialize(api_key, api_secret, options={})
|
18
|
+
options = DEFAULTS.merge(options)
|
19
|
+
|
20
|
+
@api_key = api_key
|
21
|
+
@api_secret = api_secret
|
22
|
+
|
23
|
+
@environment = options[:environment]
|
24
|
+
@base_url = options[:base_url] || URLS[@environment]
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# oAuth Consumer which uses just the base url, for
|
29
|
+
# app-wide, non user-specific GET requests.
|
30
|
+
|
31
|
+
def app_get
|
32
|
+
@app_get ||= consumer(base_url)
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# oAuth Consumer which uses the proper url for user-specific GET requests.
|
37
|
+
|
38
|
+
def user_get
|
39
|
+
@user_get ||= consumer("#{base_url}/platform")
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def consumer(site)
|
45
|
+
OAuth::Consumer.new(
|
46
|
+
api_key,
|
47
|
+
api_secret,
|
48
|
+
site: site,
|
49
|
+
header: header,
|
50
|
+
http_method: :get,
|
51
|
+
request_token_url: links[:request_token],
|
52
|
+
access_token_url: links[:access_token],
|
53
|
+
authorize_url: links[:authorize_request_token]
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
def links
|
58
|
+
return @links if defined?(@links)
|
59
|
+
|
60
|
+
catalog = OAuth::Consumer.new(api_key, api_secret)
|
61
|
+
.request(
|
62
|
+
:get,
|
63
|
+
"#{base_url}/platform/",
|
64
|
+
nil,
|
65
|
+
{},
|
66
|
+
header
|
67
|
+
).body
|
68
|
+
|
69
|
+
@links = {}
|
70
|
+
|
71
|
+
JSON.parse(catalog)['links'].each do |link|
|
72
|
+
uri = URI.parse(link['uri'])
|
73
|
+
uri.query = nil
|
74
|
+
|
75
|
+
@links[keyify(link['rel'])] = uri.to_s
|
76
|
+
end
|
77
|
+
|
78
|
+
@links
|
79
|
+
end
|
80
|
+
|
81
|
+
def header
|
82
|
+
@header ||= {accept: 'application/vnd.deere.axiom.v3+json'}
|
83
|
+
end
|
84
|
+
|
85
|
+
def keyify key_name
|
86
|
+
underscore(key_name.gsub(/^oauth/, '')).to_sym
|
87
|
+
end
|
84
88
|
end
|
85
|
-
end
|
89
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module MyJohnDeereApi
|
2
|
+
##
|
3
|
+
# This error is used in a context that will fail in the absence of
|
4
|
+
# a valid oAuth access token. We have classes that may only need
|
5
|
+
# access tokens for some use cases.
|
6
|
+
|
7
|
+
class AccessTokenError < StandardError
|
8
|
+
def initialize(message = "A valid oAuth Access Token must be supplied to use this feature.")
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -1,12 +1,3 @@
|
|
1
|
-
module MyJohnDeereApi
|
2
|
-
|
3
|
-
# This error is used in a context that will fail in the absence of
|
4
|
-
# a valid oAuth access token. We have classes that may only need
|
5
|
-
# access tokens for some use cases.
|
6
|
-
|
7
|
-
class AccessTokenError < StandardError
|
8
|
-
def initialize(message = "A valid oAuth Access Token must be supplied to use this feature.")
|
9
|
-
super
|
10
|
-
end
|
11
|
-
end
|
1
|
+
module MyJohnDeereApi::Errors
|
2
|
+
require 'my_john_deere_api/errors/access_token_error'
|
12
3
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module MyJohnDeereApi::Helpers::CaseConversion
|
4
|
+
##
|
5
|
+
# convert a text or camelcase string to underscore
|
6
|
+
|
7
|
+
def underscore(string)
|
8
|
+
string.gsub(/([a-z])([A-Z])/, '\1_\2').gsub(/\s+/, '_').gsub(/_+/, '_').downcase
|
9
|
+
end
|
10
|
+
|
11
|
+
private :underscore
|
12
|
+
|
13
|
+
##
|
14
|
+
# convert text or underscored string to camelcase
|
15
|
+
|
16
|
+
def camelize(string)
|
17
|
+
list = string.strip.split(/[_\s]+/)
|
18
|
+
|
19
|
+
# preserve case of the first element
|
20
|
+
new_list = [list.shift]
|
21
|
+
new_list += list.map(&:capitalize)
|
22
|
+
|
23
|
+
new_list.join('')
|
24
|
+
end
|
25
|
+
|
26
|
+
private :camelize
|
27
|
+
end
|
@@ -4,6 +4,15 @@ module MyJohnDeereApi
|
|
4
4
|
|
5
5
|
attr_reader :name, :id, :links, :accessor
|
6
6
|
|
7
|
+
##
|
8
|
+
# arguments:
|
9
|
+
#
|
10
|
+
# [record] a JSON object of type 'Field', returned from the API.
|
11
|
+
#
|
12
|
+
# [accessor (optional)] a valid oAuth Access Token. This is only
|
13
|
+
# needed if further API requests are going
|
14
|
+
# to be made, as is the case with *flags*.
|
15
|
+
|
7
16
|
def initialize(record, accessor = nil)
|
8
17
|
@accessor = accessor
|
9
18
|
|
@@ -18,6 +27,10 @@ module MyJohnDeereApi
|
|
18
27
|
end
|
19
28
|
end
|
20
29
|
|
30
|
+
##
|
31
|
+
# Since the archived attribute is boolean, we reflect this in the
|
32
|
+
# method name instead of using a standard attr_reader.
|
33
|
+
|
21
34
|
def archived?
|
22
35
|
@archived
|
23
36
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module MyJohnDeereApi
|
4
|
+
class Model::Flag
|
5
|
+
include Helpers::CaseConversion
|
6
|
+
include Helpers::UriPath
|
7
|
+
|
8
|
+
attr_reader :id, :notes, :geometry, :links, :accessor
|
9
|
+
|
10
|
+
##
|
11
|
+
# arguments:
|
12
|
+
#
|
13
|
+
# [record] a JSON object of type 'Flag', returned from the API.
|
14
|
+
#
|
15
|
+
# [accessor (optional)] a valid oAuth Access Token. This is only
|
16
|
+
# needed if further API requests are going
|
17
|
+
# to be made.
|
18
|
+
|
19
|
+
def initialize(record, accessor = nil)
|
20
|
+
@accessor = accessor
|
21
|
+
|
22
|
+
@id = record['id']
|
23
|
+
@notes = record['notes']
|
24
|
+
@geometry =JSON.parse(record['geometry'])
|
25
|
+
@proximity_alert_enabled = record['proximityAlertEnabled']
|
26
|
+
@archived = record['archived']
|
27
|
+
|
28
|
+
@links = {}
|
29
|
+
|
30
|
+
record['links'].each do |association|
|
31
|
+
@links[underscore(association['rel'])] = uri_path(association['uri'])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Since the archived attribute is boolean, we reflect this in the
|
37
|
+
# method name instead of using a standard attr_reader.
|
38
|
+
|
39
|
+
def archived?
|
40
|
+
@archived
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Since the proximity_alert_enabled attribute is boolean, we reflect this
|
45
|
+
# in the method name instead of using a standard attr_reader.
|
46
|
+
|
47
|
+
def proximity_alert_enabled?
|
48
|
+
@proximity_alert_enabled
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -6,6 +6,15 @@ module MyJohnDeereApi
|
|
6
6
|
|
7
7
|
attr_reader :name, :type, :id, :links, :accessor
|
8
8
|
|
9
|
+
##
|
10
|
+
# arguments:
|
11
|
+
#
|
12
|
+
# [record] a JSON object of type 'Organization', returned from the API.
|
13
|
+
#
|
14
|
+
# [accessor (optional)] a valid oAuth Access Token. This is only
|
15
|
+
# needed if further API requests are going
|
16
|
+
# to be made, as is the case with *fields*.
|
17
|
+
|
9
18
|
def initialize(record, accessor = nil)
|
10
19
|
@accessor = accessor
|
11
20
|
|
@@ -21,6 +30,10 @@ module MyJohnDeereApi
|
|
21
30
|
end
|
22
31
|
end
|
23
32
|
|
33
|
+
##
|
34
|
+
# Since the member attribute is boolean, we reflect this in the
|
35
|
+
# method name instead of using a standard attr_reader.
|
36
|
+
|
24
37
|
def member?
|
25
38
|
@member
|
26
39
|
end
|
@@ -32,7 +45,7 @@ module MyJohnDeereApi
|
|
32
45
|
raise AccessTokenError unless accessor
|
33
46
|
|
34
47
|
return @fields if defined?(@fields)
|
35
|
-
@fields = MyJohnDeereApi::Request::Fields.new(accessor, organization: id).all
|
48
|
+
@fields = MyJohnDeereApi::Request::Collection::Fields.new(accessor, organization: id).all
|
36
49
|
end
|
37
50
|
end
|
38
51
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module MyJohnDeereApi
|
2
|
+
class Request::Collection::Base
|
3
|
+
include Enumerable
|
4
|
+
include Helpers::UriPath
|
5
|
+
|
6
|
+
attr_reader :accessor, :associations
|
7
|
+
|
8
|
+
##
|
9
|
+
# accessor is an OAuth::AccessToken object which has the necessary
|
10
|
+
# credentials to make the desired requests.
|
11
|
+
|
12
|
+
def initialize(accessor, associations = {})
|
13
|
+
@accessor = accessor
|
14
|
+
@associations = associations
|
15
|
+
@items = []
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# Iterate lazily through all records in the collection, fetching
|
20
|
+
# additional pages as needed.
|
21
|
+
|
22
|
+
def each(&block)
|
23
|
+
count.times do |index|
|
24
|
+
fetch if @items.size <= index
|
25
|
+
block.call(@items[index])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Return all objects in the collection at once
|
31
|
+
|
32
|
+
def all
|
33
|
+
return @all if defined?(@all)
|
34
|
+
@all = map { |i| i }
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Total count of records, even before pagination
|
39
|
+
|
40
|
+
def count
|
41
|
+
@count ||= first_page['total']
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def first_page
|
47
|
+
return @first_page if defined?(@first_page)
|
48
|
+
|
49
|
+
@first_page = JSON.parse(@accessor.get(resource, headers).body)
|
50
|
+
extract_page_contents(@first_page)
|
51
|
+
|
52
|
+
@first_page
|
53
|
+
end
|
54
|
+
|
55
|
+
def fetch
|
56
|
+
return unless @next_page
|
57
|
+
|
58
|
+
page = JSON.parse(@accessor.get(@next_page, headers).body)
|
59
|
+
extract_page_contents(page)
|
60
|
+
end
|
61
|
+
|
62
|
+
def headers
|
63
|
+
@headers ||= {accept: 'application/vnd.deere.axiom.v3+json'}
|
64
|
+
end
|
65
|
+
|
66
|
+
def extract_page_contents(page)
|
67
|
+
add_items_from_page(page)
|
68
|
+
set_next_page(page)
|
69
|
+
end
|
70
|
+
|
71
|
+
def add_items_from_page(page)
|
72
|
+
@items += page['values'].map{|record| model.new(record, accessor) }
|
73
|
+
end
|
74
|
+
|
75
|
+
def set_next_page(page)
|
76
|
+
if next_page = page['links'].detect{|link| link['rel'] == 'nextPage'}
|
77
|
+
@next_page = uri_path(next_page['uri'])
|
78
|
+
else
|
79
|
+
@next_page = nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module MyJohnDeereApi::Request
|
4
|
+
class Collection::Flags < Collection::Base
|
5
|
+
##
|
6
|
+
# The resource path for the first page in the collection
|
7
|
+
|
8
|
+
def resource
|
9
|
+
"/organizations/#{associations[:organization]}/fields/#{associations[:field]}/flags"
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# This is the class used to model the data
|
14
|
+
|
15
|
+
def model
|
16
|
+
MyJohnDeereApi::Model::Flag
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,83 +1,6 @@
|
|
1
|
-
module MyJohnDeereApi
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
attr_reader :accessor, :associations
|
7
|
-
|
8
|
-
##
|
9
|
-
# accessor is an OAuth::AccessToken object which has the necessary
|
10
|
-
# credentials to make the desired requests.
|
11
|
-
|
12
|
-
def initialize(accessor, associations = {})
|
13
|
-
@accessor = accessor
|
14
|
-
@associations = associations
|
15
|
-
@items = []
|
16
|
-
end
|
17
|
-
|
18
|
-
##
|
19
|
-
# Iterate lazily through all records in the collection, fetching
|
20
|
-
# additional pages as needed.
|
21
|
-
|
22
|
-
def each(&block)
|
23
|
-
count.times do |index|
|
24
|
-
fetch if @items.size <= index
|
25
|
-
block.call(@items[index])
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
##
|
30
|
-
# Return all objects in the collection at once
|
31
|
-
|
32
|
-
def all
|
33
|
-
return @all if defined?(@all)
|
34
|
-
@all = map { |i| i }
|
35
|
-
end
|
36
|
-
|
37
|
-
##
|
38
|
-
# Total count of records, even before pagination
|
39
|
-
|
40
|
-
def count
|
41
|
-
@count ||= first_page['total']
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def first_page
|
47
|
-
return @first_page if defined?(@first_page)
|
48
|
-
|
49
|
-
@first_page = JSON.parse(@accessor.get(resource, headers).body)
|
50
|
-
extract_page_contents(@first_page)
|
51
|
-
|
52
|
-
@first_page
|
53
|
-
end
|
54
|
-
|
55
|
-
def fetch
|
56
|
-
return unless @next_page
|
57
|
-
|
58
|
-
page = JSON.parse(@accessor.get(@next_page, headers).body)
|
59
|
-
extract_page_contents(page)
|
60
|
-
end
|
61
|
-
|
62
|
-
def headers
|
63
|
-
@headers ||= {accept: 'application/vnd.deere.axiom.v3+json'}
|
64
|
-
end
|
65
|
-
|
66
|
-
def extract_page_contents(page)
|
67
|
-
add_items_from_page(page)
|
68
|
-
set_next_page(page)
|
69
|
-
end
|
70
|
-
|
71
|
-
def add_items_from_page(page)
|
72
|
-
@items += page['values'].map{|record| model.new(record, accessor) }
|
73
|
-
end
|
74
|
-
|
75
|
-
def set_next_page(page)
|
76
|
-
if next_page = page['links'].detect{|link| link['rel'] == 'nextPage'}
|
77
|
-
@next_page = uri_path(next_page['uri'])
|
78
|
-
else
|
79
|
-
@next_page = nil
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
1
|
+
module MyJohnDeereApi::Request::Collection
|
2
|
+
autoload :Base, 'my_john_deere_api/request/collection/base'
|
3
|
+
autoload :Organizations, 'my_john_deere_api/request/collection/organizations'
|
4
|
+
autoload :Fields, 'my_john_deere_api/request/collection/fields'
|
5
|
+
autoload :Flags, 'my_john_deere_api/request/collection/flags'
|
83
6
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'support/helper'
|
2
|
+
|
3
|
+
describe 'MyJohnDeereApi::AccessTokenError' do
|
4
|
+
it 'inherits from StandardError' do
|
5
|
+
error = MyJohnDeereApi::AccessTokenError.new
|
6
|
+
assert_kind_of StandardError, error
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'has a default message' do
|
10
|
+
error = MyJohnDeereApi::AccessTokenError.new
|
11
|
+
assert_includes error.message, 'Access Token must be supplied'
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'support/helper'
|
2
|
+
|
3
|
+
class CaseConversionHelperSample
|
4
|
+
include JD::Helpers::CaseConversion
|
5
|
+
end
|
6
|
+
|
7
|
+
describe 'Helpers::CaseConversion' do
|
8
|
+
let(:object) { CaseConversionHelperSample.new }
|
9
|
+
|
10
|
+
describe '#underscore' do
|
11
|
+
it 'converts from camelcase' do
|
12
|
+
string = object.send(:underscore, 'camelCaseExample')
|
13
|
+
assert_equal 'camel_case_example', string
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'handles leading uppercase' do
|
17
|
+
string = object.send(:underscore, 'CamelCaseExample')
|
18
|
+
assert_equal 'camel_case_example', string
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'converts spaces to underscores' do
|
22
|
+
string = object.send(:underscore, 'camel case Example')
|
23
|
+
assert_equal 'camel_case_example', string
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'removes duplicate underscores after processing' do
|
27
|
+
string = object.send(:underscore, 'camel Case Example')
|
28
|
+
assert_equal 'camel_case_example', string
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'is a private method' do
|
32
|
+
assert_raises(NoMethodError) { object.underscore('test') }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#camelize' do
|
37
|
+
it 'converts from underscored' do
|
38
|
+
string = object.send(:camelize, 'this_is_a_test')
|
39
|
+
assert_equal 'thisIsATest', string
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'converts from spaced' do
|
43
|
+
string = object.send(:camelize, 'this is a test')
|
44
|
+
assert_equal 'thisIsATest', string
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'honors original capitalization' do
|
48
|
+
string = object.send(:camelize, 'This is a test')
|
49
|
+
assert_equal 'ThisIsATest', string
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'is a private method' do
|
53
|
+
assert_raises(NoMethodError) { object.camelize('test') }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'support/helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
describe 'MyJohnDeereApi::Model::Flag' do
|
5
|
+
let(:record) do
|
6
|
+
{
|
7
|
+
"@type"=>"Flag",
|
8
|
+
"geometry"=>"{\"type\": \"Point\", \"coordinates\": [-93.14959274063109, 41.66881548411553] }",
|
9
|
+
"archived"=>true,
|
10
|
+
"proximityAlertEnabled"=>true,
|
11
|
+
"notes"=>"Our flag is a very, very, very nice flag!",
|
12
|
+
"id"=>"123456",
|
13
|
+
"links"=>[
|
14
|
+
{"@type"=>"Link", "rel"=>"field", "uri"=>"https://sandboxapi.deere.com/platform/organizations/123456/fields/123456"},
|
15
|
+
{"@type"=>"Link", "rel"=>"createdBy", "uri"=>"https://sandboxapi.deere.com/platform/users/bobsmith"},
|
16
|
+
{"@type"=>"Link", "rel"=>"lastModifiedBy", "uri"=>"https://sandboxapi.deere.com/platform/users/jonsmith"},
|
17
|
+
]
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#initialize' do
|
22
|
+
def link_for label
|
23
|
+
record['links'].detect{|link| link['rel'] == label}['uri'].gsub('https://sandboxapi.deere.com/platform', '')
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'sets the attributes from the given record' do
|
27
|
+
field = JD::Model::Flag.new(record)
|
28
|
+
|
29
|
+
assert_nil field.accessor
|
30
|
+
|
31
|
+
# basic attributes
|
32
|
+
assert_equal JSON.parse(record['geometry']), field.geometry
|
33
|
+
assert_equal record['archived'], field.archived?
|
34
|
+
assert_equal record['proximityAlertEnabled'], field.proximity_alert_enabled?
|
35
|
+
assert_equal record['notes'], field.notes
|
36
|
+
assert_equal record['id'], field.id
|
37
|
+
|
38
|
+
# links to other things
|
39
|
+
assert_kind_of Hash, field.links
|
40
|
+
assert_equal link_for('field'), field.links['field']
|
41
|
+
assert_equal link_for('createdBy'), field.links['created_by']
|
42
|
+
assert_equal link_for('lastModifiedBy'), field.links['last_modified_by']
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'accepts an optional accessor' do
|
46
|
+
accessor = 'mock-accessor'
|
47
|
+
|
48
|
+
field = JD::Model::Flag.new(record, accessor)
|
49
|
+
assert_equal accessor, field.accessor
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'support/helper'
|
2
|
+
|
3
|
+
describe 'MyJohnDeereApi::Request::Collection::Base' do
|
4
|
+
let(:client) { JD::Client.new(API_KEY, API_SECRET, environment: :sandbox, access: [ACCESS_TOKEN, ACCESS_SECRET]) }
|
5
|
+
let(:accessor) { VCR.use_cassette('catalog') { client.send(:accessor) } }
|
6
|
+
|
7
|
+
describe '#initialize(access_token)' do
|
8
|
+
it 'accepts an access token' do
|
9
|
+
collection = JD::Request::Collection::Base.new(accessor)
|
10
|
+
assert_kind_of OAuth::AccessToken, collection.accessor
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'accepts associations' do
|
14
|
+
collection = JD::Request::Collection::Base.new(accessor, organization: '123')
|
15
|
+
|
16
|
+
assert_kind_of Hash, collection.associations
|
17
|
+
assert_equal '123', collection.associations[:organization]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'uses the Enumerable module' do
|
22
|
+
collection = JD::Request::Collection::Base.new(accessor)
|
23
|
+
|
24
|
+
[:each, :first, :map, :detect, :select].each do |method_name|
|
25
|
+
assert collection.respond_to?(method_name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -2,7 +2,7 @@ require 'support/helper'
|
|
2
2
|
require 'yaml'
|
3
3
|
require 'json'
|
4
4
|
|
5
|
-
describe 'MyJohnDeereApi::Request::Fields' do
|
5
|
+
describe 'MyJohnDeereApi::Request::Collection::Fields' do
|
6
6
|
let(:organization_id) do
|
7
7
|
contents = File.read('test/support/vcr/get_organizations.yml')
|
8
8
|
body = YAML.load(contents)['http_interactions'].first['response']['body']['string']
|
@@ -11,7 +11,7 @@ describe 'MyJohnDeereApi::Request::Fields' do
|
|
11
11
|
|
12
12
|
let(:client) { JD::Client.new(API_KEY, API_SECRET, environment: :sandbox, access: [ACCESS_TOKEN, ACCESS_SECRET]) }
|
13
13
|
let(:accessor) { VCR.use_cassette('catalog') { client.send(:accessor) } }
|
14
|
-
let(:collection) { JD::Request::Fields.new(accessor, organization: organization_id) }
|
14
|
+
let(:collection) { JD::Request::Collection::Fields.new(accessor, organization: organization_id) }
|
15
15
|
|
16
16
|
describe '#initialize(access_token)' do
|
17
17
|
it 'accepts an access token' do
|
@@ -19,7 +19,7 @@ describe 'MyJohnDeereApi::Request::Fields' do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'accepts associations' do
|
22
|
-
collection = JD::Request::
|
22
|
+
collection = JD::Request::Collection::Fields.new(accessor, organization: '123')
|
23
23
|
|
24
24
|
assert_kind_of Hash, collection.associations
|
25
25
|
assert_equal '123', collection.associations[:organization]
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'support/helper'
|
2
|
+
require 'yaml'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
describe 'MyJohnDeereApi::Request::Collection::Flags' do
|
6
|
+
let(:organization_id) do
|
7
|
+
contents = File.read('test/support/vcr/get_organizations.yml')
|
8
|
+
body = YAML.load(contents)['http_interactions'].first['response']['body']['string']
|
9
|
+
JSON.parse(body)['values'].first['id']
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:field_id) do
|
13
|
+
contents = File.read('test/support/vcr/get_fields.yml')
|
14
|
+
body = YAML.load(contents)['http_interactions'].first['response']['body']['string']
|
15
|
+
JSON.parse(body)['values'].first['id']
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:client) { JD::Client.new(API_KEY, API_SECRET, environment: :sandbox, access: [ACCESS_TOKEN, ACCESS_SECRET]) }
|
19
|
+
let(:accessor) { VCR.use_cassette('catalog') { client.send(:accessor) } }
|
20
|
+
let(:collection) { JD::Request::Collection::Flags.new(accessor, organization: organization_id, field: field_id) }
|
21
|
+
|
22
|
+
describe '#initialize(access_token)' do
|
23
|
+
it 'accepts an access token' do
|
24
|
+
assert_kind_of OAuth::AccessToken, collection.accessor
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'accepts associations' do
|
28
|
+
collection = JD::Request::Collection::Flags.new(accessor, organization: '123', field: '456')
|
29
|
+
|
30
|
+
assert_kind_of Hash, collection.associations
|
31
|
+
assert_equal '123', collection.associations[:organization]
|
32
|
+
assert_equal '456', collection.associations[:field]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#resource' do
|
37
|
+
it 'returns /organizations/{org_id}/fields/{field_id}/flags' do
|
38
|
+
assert_equal "/organizations/#{organization_id}/fields/#{field_id}/flags", collection.resource
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#all' do
|
43
|
+
it 'returns all records' do
|
44
|
+
all = VCR.use_cassette('get_flags', record: :new_episodes) { collection.all }
|
45
|
+
|
46
|
+
assert_kind_of Array, all
|
47
|
+
assert_equal collection.count, all.size
|
48
|
+
|
49
|
+
all.each do |item|
|
50
|
+
assert_kind_of JD::Model::Flag, item
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#count' do
|
56
|
+
let(:server_response) do
|
57
|
+
contents = File.read('test/support/vcr/get_flags.yml')
|
58
|
+
body = YAML.load(contents)['http_interactions'].first['response']['body']['string']
|
59
|
+
JSON.parse(body)
|
60
|
+
end
|
61
|
+
|
62
|
+
let(:server_count) { server_response['total'] }
|
63
|
+
|
64
|
+
it 'returns the total count of records in the collection' do
|
65
|
+
count = VCR.use_cassette('get_flags') { collection.count }
|
66
|
+
|
67
|
+
assert_equal server_count, count
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'results' do
|
72
|
+
let(:flag_geometries) do
|
73
|
+
contents = File.read('test/support/vcr/get_flags.yml')
|
74
|
+
body = YAML.load(contents)['http_interactions'].first['response']['body']['string']
|
75
|
+
JSON.parse(body)['values'].map{|v| JSON.parse(v['geometry'])}
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'returns all records as a single enumerator' do
|
79
|
+
count = VCR.use_cassette('get_flags') { collection.count }
|
80
|
+
geometries = VCR.use_cassette('get_flags', record: :new_episodes) { collection.map{|item| item.geometry} }
|
81
|
+
|
82
|
+
assert_kind_of Array, geometries
|
83
|
+
assert_equal count, geometries.size
|
84
|
+
|
85
|
+
flag_geometries.each do |expected_geometry|
|
86
|
+
assert_includes geometries, expected_geometry
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/test/lib/my_john_deere_api/request/{test_organizations.rb → collection/test_organizations.rb}
RENAMED
@@ -2,10 +2,10 @@ require 'support/helper'
|
|
2
2
|
require 'yaml'
|
3
3
|
require 'json'
|
4
4
|
|
5
|
-
describe 'MyJohnDeereApi::Request::Organizations' do
|
5
|
+
describe 'MyJohnDeereApi::Request::Collection::Organizations' do
|
6
6
|
let(:client) { JD::Client.new(API_KEY, API_SECRET, environment: :sandbox, access: [ACCESS_TOKEN, ACCESS_SECRET]) }
|
7
7
|
let(:accessor) { VCR.use_cassette('catalog') { client.send(:accessor) } }
|
8
|
-
let(:collection) { JD::Request::Organizations.new(accessor) }
|
8
|
+
let(:collection) { JD::Request::Collection::Organizations.new(accessor) }
|
9
9
|
|
10
10
|
describe '#initialize(access_token)' do
|
11
11
|
it 'accepts an access token' do
|
@@ -1,28 +1,21 @@
|
|
1
1
|
require 'support/helper'
|
2
2
|
|
3
3
|
describe 'MyJohnDeereApi::Request::Collection' do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
describe '#initialize(access_token)' do
|
8
|
-
it 'accepts an access token' do
|
9
|
-
collection = JD::Request::Collection.new(accessor)
|
10
|
-
assert_kind_of OAuth::AccessToken, collection.accessor
|
4
|
+
describe 'loading dependencies' do
|
5
|
+
it 'loads Request::Collection::Base' do
|
6
|
+
assert JD::Request::Collection::Base
|
11
7
|
end
|
12
8
|
|
13
|
-
it '
|
14
|
-
|
15
|
-
|
16
|
-
assert_kind_of Hash, collection.associations
|
17
|
-
assert_equal '123', collection.associations[:organization]
|
9
|
+
it 'loads Request::Collection::Organizations' do
|
10
|
+
assert JD::Request::Collection::Organizations
|
18
11
|
end
|
19
|
-
end
|
20
12
|
|
21
|
-
|
22
|
-
|
13
|
+
it 'loads Request::Collection::Fields' do
|
14
|
+
assert JD::Request::Collection::Fields
|
15
|
+
end
|
23
16
|
|
24
|
-
|
25
|
-
assert
|
17
|
+
it 'loads Request::Collection::Flags' do
|
18
|
+
assert JD::Request::Collection::Flags
|
26
19
|
end
|
27
20
|
end
|
28
|
-
end
|
21
|
+
end
|
@@ -5,13 +5,5 @@ describe 'MyJohnDeereApi::Request' do
|
|
5
5
|
it 'loads Request::Collection' do
|
6
6
|
assert JD::Request::Collection
|
7
7
|
end
|
8
|
-
|
9
|
-
it 'loads Request::Organizations' do
|
10
|
-
assert JD::Request::Organizations
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'loads Request::Fields' do
|
14
|
-
assert JD::Request::Fields
|
15
|
-
end
|
16
8
|
end
|
17
9
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://sandboxapi.deere.com/platform/organizations/444563/fields/11911a5a-ff81-40ef-b10d-0af9457fe474/flags
|
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-wgmADngYCRmfpEbVgSyc709wnyRux5J7PAv8SE7B",
|
18
|
+
oauth_nonce="dRV3ofkbPhDbjsPS2SpKYg5gUuiFuMnyw73JVhlYo", oauth_signature="Ksz7EKYSxTn9aDfwo48wNcUYoCQ%3D",
|
19
|
+
oauth_signature_method="HMAC-SHA1", oauth_timestamp="1578607741", oauth_token="47bbb9c9-41a8-4bec-8127-e3c5760af2f6",
|
20
|
+
oauth_version="1.0"
|
21
|
+
response:
|
22
|
+
status:
|
23
|
+
code: 200
|
24
|
+
message: OK
|
25
|
+
headers:
|
26
|
+
Date:
|
27
|
+
- Thu, 09 Jan 2020 22:09:02 GMT
|
28
|
+
Content-Type:
|
29
|
+
- application/vnd.deere.axiom.v3+json;charset=UTF-8
|
30
|
+
X-Deere-Handling-Server:
|
31
|
+
- ip-10-214-44-105
|
32
|
+
X-Frame-Options:
|
33
|
+
- SAMEORIGIN
|
34
|
+
X-Deere-Elapsed-Ms:
|
35
|
+
- '52'
|
36
|
+
Cache-Control:
|
37
|
+
- no-store
|
38
|
+
Content-Language:
|
39
|
+
- en-US
|
40
|
+
Transfer-Encoding:
|
41
|
+
- chunked
|
42
|
+
body:
|
43
|
+
encoding: UTF-8
|
44
|
+
string: '{"links":[{"rel":"self","uri":"https://sandboxapi.deere.com/platform/organizations/444563/fields"}],"total":1,"values":[{"@type": "Flag","geometry": "{\"type\": \"Point\", \"coordinates\": [-93.14959274063109, 41.66881548411553] }","notes": "A big rock on the left after entering the field","metaData": [{"name": "HARVESTABILITY","value": 1},{"name": "STAND_COUNT","value": 1}],"archived": false,"proximityAlertEnabled": false,"links": [{"rel": "owningOrganization","uri": "https://sandboxapi.deere.com/platform/organizations/1234"},{"rel": "flagCategoryWithPrefrences","uri": "https://sandboxapi.deere.com/platform/flagCategories/47a229fc-aa09-4618-956c-1c29ae884326?embed=preferences"},{"rel": "createdBy","uri": "https://sandboxapi.deere.com/platform/users/johndeeresystem"},{"rel": "lastModifiedBy","uri": "https://sandboxapi.deere.com/platform/users/john"},{"rel": "field","uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/7b387eaa-187f-4bd8-acbc-c81748b6ad3b"}],"id": "688c20bb-9609-4590-95c9-649ba65c06df","createdTime": "2018-07-01T21:00:11Z","lastModifiedTime": "2018-07-01T21:10:10Z"}]}'
|
45
|
+
http_version:
|
46
|
+
recorded_at: Thu, 09 Jan 2020 22:09:02 GMT
|
47
|
+
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: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jaime. Bellmyer
|
@@ -100,25 +100,36 @@ files:
|
|
100
100
|
- lib/my_john_deere_api/client.rb
|
101
101
|
- lib/my_john_deere_api/consumer.rb
|
102
102
|
- lib/my_john_deere_api/errors.rb
|
103
|
+
- lib/my_john_deere_api/errors/access_token_error.rb
|
103
104
|
- lib/my_john_deere_api/helpers.rb
|
105
|
+
- lib/my_john_deere_api/helpers/case_conversion.rb
|
104
106
|
- lib/my_john_deere_api/helpers/uri_path.rb
|
105
107
|
- lib/my_john_deere_api/model.rb
|
106
108
|
- lib/my_john_deere_api/model/field.rb
|
109
|
+
- lib/my_john_deere_api/model/flag.rb
|
107
110
|
- lib/my_john_deere_api/model/organization.rb
|
108
111
|
- lib/my_john_deere_api/request.rb
|
109
112
|
- lib/my_john_deere_api/request/collection.rb
|
110
|
-
- lib/my_john_deere_api/request/
|
111
|
-
- lib/my_john_deere_api/request/
|
113
|
+
- lib/my_john_deere_api/request/collection/base.rb
|
114
|
+
- lib/my_john_deere_api/request/collection/fields.rb
|
115
|
+
- lib/my_john_deere_api/request/collection/flags.rb
|
116
|
+
- lib/my_john_deere_api/request/collection/organizations.rb
|
112
117
|
- lib/my_john_deere_api/version.rb
|
118
|
+
- test/lib/my_john_deere_api/errors/test_access_token_error.rb
|
119
|
+
- test/lib/my_john_deere_api/helpers/test_case_conversion.rb
|
113
120
|
- test/lib/my_john_deere_api/helpers/test_uri_path.rb
|
114
121
|
- test/lib/my_john_deere_api/model/test_field.rb
|
122
|
+
- test/lib/my_john_deere_api/model/test_flag.rb
|
115
123
|
- test/lib/my_john_deere_api/model/test_organization.rb
|
124
|
+
- test/lib/my_john_deere_api/request/collection/test_base.rb
|
125
|
+
- test/lib/my_john_deere_api/request/collection/test_fields.rb
|
126
|
+
- test/lib/my_john_deere_api/request/collection/test_flags.rb
|
127
|
+
- test/lib/my_john_deere_api/request/collection/test_organizations.rb
|
116
128
|
- test/lib/my_john_deere_api/request/test_collection.rb
|
117
|
-
- test/lib/my_john_deere_api/request/test_fields.rb
|
118
|
-
- test/lib/my_john_deere_api/request/test_organizations.rb
|
119
129
|
- test/lib/my_john_deere_api/test_authorize.rb
|
120
130
|
- test/lib/my_john_deere_api/test_client.rb
|
121
131
|
- test/lib/my_john_deere_api/test_consumer.rb
|
132
|
+
- test/lib/my_john_deere_api/test_errors.rb
|
122
133
|
- test/lib/my_john_deere_api/test_helpers.rb
|
123
134
|
- test/lib/my_john_deere_api/test_model.rb
|
124
135
|
- test/lib/my_john_deere_api/test_request.rb
|
@@ -128,6 +139,7 @@ files:
|
|
128
139
|
- test/support/vcr/catalog.yml
|
129
140
|
- test/support/vcr/get_access_token.yml
|
130
141
|
- test/support/vcr/get_fields.yml
|
142
|
+
- test/support/vcr/get_flags.yml
|
131
143
|
- test/support/vcr/get_organizations.yml
|
132
144
|
- test/support/vcr/get_request_token.yml
|
133
145
|
- test/test_my_john_deere_api.rb
|