my_john_deere_api 0.6.0 → 0.7.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: 665f892689c1c31ee6b43ac8e65dba58b2bcd9a06f19cb9f7b35ccbcc30447e3
4
- data.tar.gz: ab2b50c05845e8761b31bc6e53f19deb7e1a8bd5190f9802a2ee7ec9a934f722
3
+ metadata.gz: d022fff0506123f5684e53e1365c9c72cd55225368bb7303db30f74e8c3bc651
4
+ data.tar.gz: d6ab2cabe0386168c984ddfcfbf6aa7ff1ac4a73b8cde4cd379ba9849fbe4e96
5
5
  SHA512:
6
- metadata.gz: bca934fa2c21390923cf0c8c336a06da67f11679215958b44b98633c3aff6a7145b3f5ebdbdd91f2db361bb4def13d29402493c23311db93af9b3f41fbca2f42
7
- data.tar.gz: 894f593caf3c98841303be7eab6922d9e2a8737a5d3b9749221d53b8e82ab16ab2de37f758a82c8ae8cb8c92d4c6c0d936d50d11a2241187d38739edbb494896
6
+ metadata.gz: 0d0815d5d7634f901741c073680769d663161cc3d959cbf914bfef8fd1f799603bb38fd2e9964700b1d421fc10929fb9ae869c763058998eff091a131ad25ae5
7
+ data.tar.gz: 496c89a2ff02d8eb0ea3edd05f03889863b6c444f4aea19d3752d69dae6904bb530ee1e6d58c1f3aab3cd9c432138f35b045d58b71eb556a74b60ecf9e69e8a7
@@ -2,10 +2,6 @@ require 'json'
2
2
 
3
3
  module MyJohnDeereApi
4
4
  class Request::Create::Asset < Request::Create::Base
5
- attr_reader :accessor, :attributes, :errors, :response
6
-
7
- REQUIRED_ATTRIBUTES = [:organization_id, :contribution_definition_id, :title]
8
-
9
5
  VALID_CATEGORIES = {
10
6
  'DEVICE' => {
11
7
  'SENSOR' => ['GRAIN_BIN', 'ENVIRONMENTAL', 'IRRIGATION_PIVOT', 'OTHER']
@@ -17,78 +13,46 @@ module MyJohnDeereApi
17
13
  },
18
14
  }
19
15
 
20
- ##
21
- # Accepts a valid oAuth AccessToken, and a hash of attributes.
22
- #
23
- # Required attributes:
24
- # - organization_id
25
- # - contribution_definition_id
26
- # - title
27
- # - asset_category
28
- # - asset_type
29
- # - asset_sub_type
30
- #
31
- # category/type/subtype must be a recognized combination as defined above.
32
-
33
- def initialize(accessor, attributes)
34
- @accessor = accessor
35
- @attributes = attributes
36
- @errors = {}
37
- end
16
+ private
38
17
 
39
18
  ##
40
- # Object created by request
41
-
42
- def object
43
- return @object if defined?(@object)
44
-
45
- request unless response
19
+ # attributes that must be specified
46
20
 
47
- object_id = response['location'].split('/').last
48
- result = accessor.get("/assets/#{object_id}", headers)
49
-
50
- @object = Model::Asset.new(JSON.parse(result.body), accessor)
21
+ def required_attributes
22
+ [:organization_id, :contribution_definition_id, :title]
51
23
  end
52
24
 
53
25
  ##
54
- # Make the request, if the instance is valid
26
+ # Retrieve newly created record
27
+
28
+ def fetch_record
29
+ path = response['location'].split('/platform').last
30
+ result = accessor.get(path, headers)
55
31
 
56
- def request
57
- validate!
58
- @response = accessor.post(resource, request_body.to_json, headers)
32
+ JSON.parse(result.body)
59
33
  end
60
34
 
61
35
  ##
62
- # Raises an error if the record is invalid. Passes the errors hash
63
- # to the error, in order to build a useful message string.
36
+ # This is the class used to model the data
64
37
 
65
- def validate!
66
- raise(InvalidRecordError, errors) unless valid?
38
+ def model
39
+ Model::Asset
67
40
  end
68
41
 
69
42
  ##
70
- # Runs validations, adding to the errors hash as needed. Returns true
71
- # if the errors hash is still empty after all validations have been run.
72
-
73
- def valid?
74
- return @is_valid if defined?(@is_valid)
75
-
76
- validate_required
43
+ # Handle any custom validation for this model that may not apply to others
77
44
 
45
+ def validate_attributes
78
46
  unless valid_categories?(attributes[:asset_category], attributes[:asset_type], attributes[:asset_sub_type])
79
47
  errors[:asset_category] = 'requires valid combination of category/type/subtype'
80
48
  end
81
-
82
- @is_valid = errors.empty?
83
49
  end
84
50
 
85
- private
86
-
87
51
  ##
88
52
  # Path supplied to API
89
53
 
90
54
  def resource
91
- @path ||= "/organizations/#{attributes[:organization_id]}/assets"
55
+ @resource ||= "/organizations/#{attributes[:organization_id]}/assets"
92
56
  end
93
57
 
94
58
  ##
@@ -97,7 +61,6 @@ module MyJohnDeereApi
97
61
  def request_body
98
62
  return @body if defined?(@body)
99
63
 
100
-
101
64
  @body = {
102
65
  title: attributes[:title],
103
66
  assetCategory: attributes[:asset_category],
@@ -113,30 +76,11 @@ module MyJohnDeereApi
113
76
  }
114
77
  end
115
78
 
116
- ##
117
- # Validates required attributes
118
-
119
- def validate_required
120
- REQUIRED_ATTRIBUTES.each do |attr|
121
- errors[attr] = 'is required' unless attributes.keys.include?(attr)
122
- end
123
- end
124
-
125
79
  ##
126
80
  # Returns boolean, true if this combination is valid
127
81
 
128
82
  def valid_categories?(category, type, subtype)
129
83
  VALID_CATEGORIES.dig(category, type).to_a.include?(subtype)
130
84
  end
131
-
132
- ##
133
- # Headers for POST request
134
-
135
- def headers
136
- @headers ||= {
137
- 'Accept' => 'application/vnd.deere.axiom.v3+json',
138
- 'Content-Type' => 'application/vnd.deere.axiom.v3+json'
139
- }
140
- end
141
85
  end
142
86
  end
@@ -1,5 +1,118 @@
1
+ require 'date'
2
+
1
3
  module MyJohnDeereApi
2
4
  class Request::Create::AssetLocation < Request::Create::Base
5
+ private
6
+
7
+ ##
8
+ # Request body
9
+
10
+ def request_body
11
+ return @body if defined?(@body)
12
+
13
+ @body = [
14
+ {
15
+ timestamp: timestamp,
16
+ geometry: geometry,
17
+ measurementData: attributes[:measurement_data]
18
+ }
19
+ ]
20
+ end
21
+
22
+ ##
23
+ # Parsed timestamp
24
+
25
+ def timestamp
26
+ return @timestamp if defined?(@timestamp)
27
+
28
+ @timestamp = attributes[:timestamp].is_a?(String) ?
29
+ attributes[:timestamp] :
30
+ attributes[:timestamp].strftime('%Y-%m-%dT%H:%M:%SZ')
31
+ end
32
+
33
+ ##
34
+ # Parse geometry
35
+
36
+ def geometry
37
+ return @geometry if defined?(@geometry)
38
+
39
+ @geometry = attributes[:geometry].is_a?(String) ?
40
+ attributes[:geometry] :
41
+ attributes[:geometry].to_json
42
+ end
43
+
44
+ ##
45
+ # Path supplied to API
46
+
47
+ def resource
48
+ @resource ||= "/assets/#{attributes[:asset_id]}/locations"
49
+ end
50
+
51
+ ##
52
+ # Required attributes for this class
53
+
54
+ def required_attributes
55
+ [:asset_id, :timestamp, :geometry, :measurement_data]
56
+ end
57
+
58
+ ##
59
+ # Retrieve newly created record
60
+
61
+ def fetch_record
62
+ # There is no way to fetch a single location by id, because locations
63
+ # don't have IDs. You have to fetch them in bulk via the asset, but
64
+ # there could be thousands. We limit to just the record created with
65
+ # our timestamp, which must be unique.
66
+
67
+ path = response['location'].split('/platform').last
68
+ start_date = timestamp_add(timestamp, -1)
69
+ end_date = timestamp_add(timestamp, 1)
70
+ path += "?startDate=#{start_date}&endDate=#{end_date}"
71
+ result = accessor.get(path, headers)
72
+
73
+ parsed_stamp = DateTime.parse(timestamp)
74
+
75
+ JSON.parse(result.body)['values'].detect do |record|
76
+ parsed_stamp == DateTime.parse(record['timestamp'])
77
+ end
78
+ end
79
+
80
+ ##
81
+ # Create a new timestamp adjusted by X minutes
82
+
83
+ def timestamp_add(timestamp, seconds)
84
+ stamp = DateTime.parse(timestamp).to_time + seconds
85
+ stamp.to_datetime.strftime('%Y-%m-%dT%H:%M:%SZ')
86
+ end
87
+
88
+ ##
89
+ # This is the class used to model the data
90
+
91
+ def model
92
+ Model::AssetLocation
93
+ end
94
+
95
+ ##
96
+ # Custom validations for this class
97
+
98
+ def validate_attributes
99
+ validate_measurement_data
100
+ end
101
+
102
+ def validate_measurement_data
103
+ unless attributes[:measurement_data].is_a?(Array)
104
+ errors[:measurement_data] ||= 'must be an array'
105
+ return
106
+ end
3
107
 
108
+ attributes[:measurement_data].each do |measurement|
109
+ [:name, :value, :unit].each do |attr|
110
+ unless measurement.has_key?(attr)
111
+ errors[:measurement_data] ||= "must include #{attr}"
112
+ return
113
+ end
114
+ end
115
+ end
116
+ end
4
117
  end
5
118
  end
@@ -1,5 +1,102 @@
1
+ require 'json'
2
+
1
3
  module MyJohnDeereApi
2
4
  class Request::Create::Base
5
+ attr_reader :accessor, :attributes, :errors, :response
6
+
7
+ ##
8
+ # Accepts a valid oAuth AccessToken, and a hash of attributes.
9
+ #
10
+ # Required attributes:
11
+ # - organization_id
12
+ # - contribution_definition_id
13
+ # - title
14
+ # - asset_category
15
+ # - asset_type
16
+ # - asset_sub_type
17
+ #
18
+ # category/type/subtype must be a recognized combination as defined above.
19
+
20
+ def initialize(accessor, attributes)
21
+ @accessor = accessor
22
+ @attributes = attributes
23
+
24
+ @errors = {}
25
+ end
26
+
27
+ ##
28
+ # Make the request, if the instance is valid
29
+
30
+ def request
31
+ validate!
32
+ @response = accessor.post(resource, request_body.to_json, headers)
33
+ end
34
+
35
+ ##
36
+ # Object created by request
37
+
38
+ def object
39
+ return @object if defined?(@object)
40
+
41
+ request unless response
42
+
43
+ @object = model.new(fetch_record, accessor)
44
+ end
45
+
46
+ ##
47
+ # Runs validations, adding to the errors hash as needed. Returns true
48
+ # if the errors hash is still empty after all validations have been run.
49
+
50
+ def valid?
51
+ return @is_valid if defined?(@is_valid)
52
+
53
+ validate_required
54
+ validate_attributes
55
+
56
+ @is_valid = errors.empty?
57
+ end
58
+
59
+ ##
60
+ # Run validations unique to a given model. This should be overridden
61
+ # by children where needed.
62
+
63
+ def validate_attributes
64
+ end
65
+
66
+ ##
67
+ # Raises an error if the record is invalid. Passes the errors hash
68
+ # to the error, in order to build a useful message string.
69
+
70
+ def validate!
71
+ raise(InvalidRecordError, errors) unless valid?
72
+ end
73
+
74
+ private
75
+
76
+ ##
77
+ # Attributes that must be specified, override in child class
78
+
79
+ def required_attributes
80
+ []
81
+ end
82
+
83
+ ##
84
+ # Validates required attributes
85
+
86
+ def validate_required
87
+ required_attributes.each do |attr|
88
+ errors[attr] = 'is required' unless attributes.keys.include?(attr)
89
+ end
90
+ end
91
+
92
+ ##
93
+ # Headers for POST request
3
94
 
95
+ def headers
96
+ @headers ||= {
97
+ 'Accept' => 'application/vnd.deere.axiom.v3+json',
98
+ 'Content-Type' => 'application/vnd.deere.axiom.v3+json'
99
+ }
100
+ end
4
101
  end
5
102
  end
@@ -1,3 +1,3 @@
1
1
  module MyJohnDeereApi
2
- VERSION='0.6.0'
2
+ VERSION='0.7.0'
3
3
  end
@@ -1,10 +1,178 @@
1
1
  require 'support/helper'
2
+ require 'date'
2
3
 
3
4
  describe 'MyJohnDeereApi::Request::Create::AssetLocation' do
5
+ def attributes_without(*keys)
6
+ keys = keys.to_a
7
+ attributes.reject{|k,v| keys.include?(k)}
8
+ end
9
+
4
10
  let(:client) { JD::Client.new(API_KEY, API_SECRET, environment: :sandbox, access: [ACCESS_TOKEN, ACCESS_SECRET]) }
5
11
  let(:accessor) { VCR.use_cassette('catalog') { client.send(:accessor) } }
6
12
 
13
+ let(:asset_id) { ENV['ASSET_ID'] }
14
+ let(:timestamp) { DateTime.parse(timestamp_string) }
15
+ let(:timestamp_string) { '2020-01-18T00:31:00Z' }
16
+
17
+ let(:geometry) do
18
+ {
19
+ type: 'Point',
20
+ coordinates: [-103.115633, 41.670166]
21
+ }
22
+ end
23
+
24
+ let(:measurement_data) do
25
+ [
26
+ {
27
+ name: 'Temperature',
28
+ value: '68.0',
29
+ unit: 'F'
30
+ }
31
+ ]
32
+ end
33
+
34
+ let(:valid_attributes) do
35
+ {
36
+ asset_id: asset_id,
37
+ timestamp: timestamp,
38
+ geometry: geometry,
39
+ measurement_data: measurement_data
40
+ }
41
+ end
42
+
43
+ let(:attributes) { valid_attributes }
44
+
7
45
  describe '#initialize(access_token, attributes)' do
46
+ it 'accepts an accessor and attributes' do
47
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes)
48
+
49
+ assert_equal accessor, object.accessor
50
+ assert_equal attributes, object.attributes
51
+ end
52
+
53
+ it 'creates an empty error hash' do
54
+ object = JD::Request::Create::AssetLocation.new(accessor, {})
55
+ assert_equal({}, object.errors)
56
+ end
57
+ end
58
+
59
+ describe '#valid?' do
60
+ it 'returns true when all required attributes are present' do
61
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes)
62
+
63
+ assert object.valid?
64
+ assert_empty object.errors
65
+ end
66
+
67
+ it 'requires asset_id' do
68
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes_without(:asset_id))
69
+
70
+ refute object.valid?
71
+ assert_equal 'is required', object.errors[:asset_id]
72
+ end
73
+
74
+ it 'requires timestamp' do
75
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes_without(:timestamp))
76
+
77
+ refute object.valid?
78
+ assert_equal 'is required', object.errors[:timestamp]
79
+ end
80
+
81
+ it 'requires geometry' do
82
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes_without(:geometry))
83
+
84
+ refute object.valid?
85
+ assert_equal 'is required', object.errors[:geometry]
86
+ end
87
+
88
+ it 'requires measurement_data' do
89
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes_without(:measurement_data))
90
+
91
+ refute object.valid?
92
+ assert_equal 'is required', object.errors[:measurement_data]
93
+ end
94
+
95
+ describe 'validating measurement_data' do
96
+ it 'must be an array' do
97
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes.merge(measurement_data: 'something'))
98
+
99
+ refute object.valid?
100
+ assert_equal 'must be an array', object.errors[:measurement_data]
101
+ end
102
+
103
+ it 'must include a name' do
104
+ without_attr = [measurement_data.first.reject{|k,v| k == :name}]
105
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes.merge(measurement_data: without_attr))
106
+
107
+ refute object.valid?
108
+ assert_equal 'must include name', object.errors[:measurement_data]
109
+ end
110
+
111
+ it 'must include a value' do
112
+ without_attr = [measurement_data.first.reject{|k,v| k == :value}]
113
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes.merge(measurement_data: without_attr))
114
+
115
+ refute object.valid?
116
+ assert_equal 'must include value', object.errors[:measurement_data]
117
+ end
118
+
119
+ it 'must include a unit' do
120
+ without_attr = [measurement_data.first.reject{|k,v| k == :unit}]
121
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes.merge(measurement_data: without_attr))
122
+
123
+ refute object.valid?
124
+ assert_equal 'must include unit', object.errors[:measurement_data]
125
+ end
126
+ end
127
+ end
128
+
129
+ describe '#validate!' do
130
+ it 'raises an error when invalid' do
131
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes_without(:asset_id))
132
+
133
+ exception = assert_raises(JD::InvalidRecordError) { object.validate! }
134
+ assert_includes exception.message, 'Record is invalid'
135
+ assert_includes exception.message, 'asset_id is required'
136
+ end
137
+ end
138
+
139
+ describe '#request_body' do
140
+ it 'properly forms the request body' do
141
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes)
142
+ body = object.send(:request_body)
143
+
144
+ assert_kind_of Array, body
145
+ assert_equal timestamp_string, body.first[:timestamp]
146
+ assert_equal geometry.to_json, body.first[:geometry]
147
+ assert_equal measurement_data, body.first[:measurementData]
148
+ end
149
+ end
150
+
151
+ describe '#request' do
152
+ it 'makes the request' do
153
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes)
154
+ VCR.use_cassette('post_asset_locations') { object.request }
155
+
156
+ assert_kind_of Net::HTTPCreated, object.response
157
+ end
158
+ end
159
+
160
+ describe '#object' do
161
+ it 'returns the asset location model instance' do
162
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes)
163
+ result = VCR.use_cassette('post_asset_locations') { object.object }
164
+
165
+ assert_kind_of JD::Model::AssetLocation, result
166
+
167
+ # API returns seconds with decimals, even though they're always zero
168
+ integer_stamp = DateTime.parse(result.timestamp).strftime('%Y-%m-%dT%H:%M:%SZ')
169
+
170
+ # API returns string keys and an extra '@type' key
171
+ result_measurement_data = result.measurement_data.first.transform_keys{|k| k.to_sym}.slice(:name, :value, :unit)
8
172
 
173
+ assert_equal timestamp_string, integer_stamp
174
+ assert_equal geometry.to_json, result.geometry.to_json
175
+ assert_equal measurement_data.first, result_measurement_data
176
+ end
9
177
  end
10
178
  end
@@ -171,23 +171,10 @@ describe 'MyJohnDeereApi::Request::Create::Asset' do
171
171
  end
172
172
  end
173
173
 
174
- describe '#headers' do
175
- it 'sets the accept and content-type headers' do
176
- object = JD::Request::Create::Asset.new(accessor, attributes)
177
- headers = object.send(:headers)
178
-
179
- expected = 'application/vnd.deere.axiom.v3+json'
180
-
181
- assert_kind_of Hash, headers
182
- assert_equal expected, headers['Accept']
183
- assert_equal expected, headers['Content-Type']
184
- end
185
- end
186
-
187
174
  describe '#request' do
188
175
  it 'makes the request' do
189
176
  object = JD::Request::Create::Asset.new(accessor, attributes)
190
- result = VCR.use_cassette('post_assets') { object.request }
177
+ VCR.use_cassette('post_assets') { object.request }
191
178
 
192
179
  assert_kind_of Net::HTTPCreated, object.response
193
180
  end
@@ -3,8 +3,32 @@ require 'support/helper'
3
3
  describe 'MyJohnDeereApi::Request::Create::Base' do
4
4
  let(:client) { JD::Client.new(API_KEY, API_SECRET, environment: :sandbox, access: [ACCESS_TOKEN, ACCESS_SECRET]) }
5
5
  let(:accessor) { VCR.use_cassette('catalog') { client.send(:accessor) } }
6
+ let(:attributes) { {} }
6
7
 
7
8
  describe '#initialize(access_token, attributes)' do
9
+ it 'accepts an accessor and attributes' do
10
+ object = JD::Request::Create::AssetLocation.new(accessor, attributes)
8
11
 
12
+ assert_equal accessor, object.accessor
13
+ assert_equal attributes, object.attributes
14
+ end
15
+
16
+ it 'creates an empty error hash' do
17
+ object = JD::Request::Create::AssetLocation.new(accessor, {})
18
+ assert_equal({}, object.errors)
19
+ end
20
+ end
21
+
22
+ describe '#headers' do
23
+ it 'sets the accept and content-type headers' do
24
+ object = JD::Request::Create::Asset.new(accessor, attributes)
25
+ headers = object.send(:headers)
26
+
27
+ expected = 'application/vnd.deere.axiom.v3+json'
28
+
29
+ assert_kind_of Hash, headers
30
+ assert_equal expected, headers['Accept']
31
+ assert_equal expected, headers['Content-Type']
32
+ end
9
33
  end
10
34
  end
@@ -0,0 +1,95 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://sandboxapi.deere.com/platform/assets/029c288a-14d9-459f-8ee6-b4e840e672a1/locations
6
+ body:
7
+ encoding: UTF-8
8
+ string: '[{"timestamp":"2020-01-18T00:31:00Z","geometry":"{\"type\":\"Point\",\"coordinates\":[-103.115633,41.670166]}","measurementData":[{"name":"Temperature","value":"68.0","unit":"F"}]}]'
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
+ - '181'
20
+ Authorization:
21
+ - OAuth oauth_body_hash="iiLtEEcE%2B8AM8XC5NLttAeL92i4%3D", oauth_consumer_key="johndeere-wgmADngYCRmfpEbVgSyc709wnyRux5J7PAv8SE7B",
22
+ oauth_nonce="hMwIfcVWHIyjE51AQcMztDSCm0AWilBe4LTFZvuI", oauth_signature="ibSHPRsXfeazw1%2F5I%2BZlcipIZRk%3D",
23
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1579308624", oauth_token="47bbb9c9-41a8-4bec-8127-e3c5760af2f6",
24
+ oauth_version="1.0"
25
+ response:
26
+ status:
27
+ code: 201
28
+ message: Created
29
+ headers:
30
+ Date:
31
+ - Sat, 18 Jan 2020 00:50:24 GMT
32
+ Content-Type:
33
+ - application/vnd.deere.axiom.v3+json
34
+ X-Deere-Handling-Server:
35
+ - ip-10-214-45-182
36
+ X-Frame-Options:
37
+ - SAMEORIGIN
38
+ Location:
39
+ - https://sandboxapi.deere.com/platform/assets/029c288a-14d9-459f-8ee6-b4e840e672a1/locations
40
+ X-Deere-Elapsed-Ms:
41
+ - '59'
42
+ Transfer-Encoding:
43
+ - chunked
44
+ body:
45
+ encoding: ASCII-8BIT
46
+ string: ''
47
+ http_version:
48
+ recorded_at: Sat, 18 Jan 2020 00:50:24 GMT
49
+ - request:
50
+ method: get
51
+ uri: https://sandboxapi.deere.com/platform/assets/029c288a-14d9-459f-8ee6-b4e840e672a1/locations?endDate=2020-01-18T00:31:01Z&startDate=2020-01-18T00:30:59Z
52
+ body:
53
+ encoding: US-ASCII
54
+ string: ''
55
+ headers:
56
+ Accept:
57
+ - application/vnd.deere.axiom.v3+json
58
+ Content-Type:
59
+ - application/vnd.deere.axiom.v3+json
60
+ Accept-Encoding:
61
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
62
+ User-Agent:
63
+ - OAuth gem v0.5.4
64
+ Authorization:
65
+ - OAuth oauth_consumer_key="johndeere-wgmADngYCRmfpEbVgSyc709wnyRux5J7PAv8SE7B",
66
+ oauth_nonce="hStGJCzcb5OY7HwmEsQwNX253TTZ85FurItAwDuxvdQ", oauth_signature="LEKTEGOy%2FmqrsGuEqvASGBYk7gY%3D",
67
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1579308624", oauth_token="47bbb9c9-41a8-4bec-8127-e3c5760af2f6",
68
+ oauth_version="1.0"
69
+ response:
70
+ status:
71
+ code: 200
72
+ message: OK
73
+ headers:
74
+ Date:
75
+ - Sat, 18 Jan 2020 00:50:25 GMT
76
+ Content-Type:
77
+ - application/vnd.deere.axiom.v3+json;charset=UTF-8
78
+ X-Deere-Handling-Server:
79
+ - ip-10-214-45-182
80
+ X-Frame-Options:
81
+ - SAMEORIGIN
82
+ X-Deere-Elapsed-Ms:
83
+ - '44'
84
+ Cache-Control:
85
+ - no-store
86
+ Content-Language:
87
+ - en-US
88
+ Transfer-Encoding:
89
+ - chunked
90
+ body:
91
+ encoding: ASCII-8BIT
92
+ string: '{"links":[{"rel":"self","uri":"https://sandboxapi.deere.com/platform/assets/029c288a-14d9-459f-8ee6-b4e840e672a1/locations?startDate=2020-01-18T00:30:59Z&endDate=2020-01-18T00:31:01Z"}],"total":1,"values":[{"@type":"ContributedAssetLocation","timestamp":"2020-01-18T00:31:00.000Z","geometry":"{\"type\":\"Point\",\"coordinates\":[-103.115633,41.670166]}","measurementData":[{"@type":"BasicMeasurement","name":"Temperature","value":"68.0","unit":"F"}],"links":[]}]}'
93
+ http_version:
94
+ recorded_at: Sat, 18 Jan 2020 00:50:25 GMT
95
+ recorded_with: VCR 5.0.0
@@ -36,7 +36,7 @@ http_interactions:
36
36
  X-Frame-Options:
37
37
  - SAMEORIGIN
38
38
  Location:
39
- - https://sandboxapi.deere.com/platform/assets/911772e9-03c5-4a02-8acf-6d7574672558
39
+ - https://sandboxapi.deere.com/platform/assets/029c288a-14d9-459f-8ee6-b4e840e672a1
40
40
  X-Deere-Elapsed-Ms:
41
41
  - '131'
42
42
  Transfer-Encoding:
@@ -44,11 +44,11 @@ http_interactions:
44
44
  body:
45
45
  encoding: ASCII-8BIT
46
46
  string: ''
47
- http_version:
47
+ http_version:
48
48
  recorded_at: Fri, 17 Jan 2020 20:05:46 GMT
49
49
  - request:
50
50
  method: get
51
- uri: https://sandboxapi.deere.com/platform/assets/911772e9-03c5-4a02-8acf-6d7574672558
51
+ uri: https://sandboxapi.deere.com/platform/assets/029c288a-14d9-459f-8ee6-b4e840e672a1
52
52
  body:
53
53
  encoding: US-ASCII
54
54
  string: ''
@@ -89,7 +89,7 @@ http_interactions:
89
89
  - chunked
90
90
  body:
91
91
  encoding: ASCII-8BIT
92
- string: '{"@type":"ContributedAsset","title":"i like turtles","assetCategory":"DEVICE","assetType":"SENSOR","assetSubType":"ENVIRONMENTAL","lastModifiedDate":"2020-01-17T20:05:45.961Z","id":"911772e9-03c5-4a02-8acf-6d7574672558","links":[{"@type":"Link","rel":"self","uri":"https://sandboxapi.deere.com/platform/assets/911772e9-03c5-4a02-8acf-6d7574672558"},{"@type":"Link","rel":"contributionDefinition","uri":"https://sandboxapi.deere.com/platform/contributionDefinitions/d93611c7-6f74-474f-9569-2cf88f866a32"},{"@type":"Link","rel":"organization","uri":"https://sandboxapi.deere.com/platform/organizations/444563"},{"@type":"Link","rel":"locations","uri":"https://sandboxapi.deere.com/platform/assets/911772e9-03c5-4a02-8acf-6d7574672558/locations"},{"@type":"Link","rel":"lastKnownLocation","uri":"https://sandboxapi.deere.com/platform/assets/911772e9-03c5-4a02-8acf-6d7574672558/locations?lastKnown=true"}]}'
93
- http_version:
92
+ string: '{"@type":"ContributedAsset","title":"i like turtles","assetCategory":"DEVICE","assetType":"SENSOR","assetSubType":"ENVIRONMENTAL","lastModifiedDate":"2020-01-17T20:05:45.961Z","id":"029c288a-14d9-459f-8ee6-b4e840e672a1","links":[{"@type":"Link","rel":"self","uri":"https://sandboxapi.deere.com/platform/assets/911772e9-03c5-4a02-8acf-6d7574672558"},{"@type":"Link","rel":"contributionDefinition","uri":"https://sandboxapi.deere.com/platform/contributionDefinitions/d93611c7-6f74-474f-9569-2cf88f866a32"},{"@type":"Link","rel":"organization","uri":"https://sandboxapi.deere.com/platform/organizations/444563"},{"@type":"Link","rel":"locations","uri":"https://sandboxapi.deere.com/platform/assets/911772e9-03c5-4a02-8acf-6d7574672558/locations"},{"@type":"Link","rel":"lastKnownLocation","uri":"https://sandboxapi.deere.com/platform/assets/911772e9-03c5-4a02-8acf-6d7574672558/locations?lastKnown=true"}]}'
93
+ http_version:
94
94
  recorded_at: Fri, 17 Jan 2020 20:05:46 GMT
95
95
  recorded_with: VCR 5.0.0
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: my_john_deere_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaime. Bellmyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-17 00:00:00.000000000 Z
11
+ date: 2020-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: vcr
@@ -167,6 +167,7 @@ files:
167
167
  - test/support/vcr/get_flags.yml
168
168
  - test/support/vcr/get_organizations.yml
169
169
  - test/support/vcr/get_request_token.yml
170
+ - test/support/vcr/post_asset_locations.yml
170
171
  - test/support/vcr/post_assets.yml
171
172
  - test/support/vcr/post_flag_categories.yml
172
173
  homepage: https://github.com/Intellifarm/my_john_deere_api