my_john_deere_api 0.5.3 → 0.6.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: 601608699538179bc7ddc8d1254e7eb8372330454ec4efca84888124c0e9a6d8
4
- data.tar.gz: 283de34a0dc91842e298006a454d10359e8c6e24636fc867c813be6704d32633
3
+ metadata.gz: 665f892689c1c31ee6b43ac8e65dba58b2bcd9a06f19cb9f7b35ccbcc30447e3
4
+ data.tar.gz: ab2b50c05845e8761b31bc6e53f19deb7e1a8bd5190f9802a2ee7ec9a934f722
5
5
  SHA512:
6
- metadata.gz: 4d722923f80db0b4d69afc7119062ad0b1b60baf8ed1ba7d6cf07b3fcc1316649c9f71372fa37e81864d5b1b9df0886c2d002da364ff2d912b45d8a3bab0f9b6
7
- data.tar.gz: 178540687735cd42fdb64bb699eb16eed4f976aee180185789ae5268a16ca18f246a1be5ab730458e5b0ca1bf7ba364ee0c7a6cfa382581354b6821b47022224
6
+ metadata.gz: bca934fa2c21390923cf0c8c336a06da67f11679215958b44b98633c3aff6a7145b3f5ebdbdd91f2db361bb4def13d29402493c23311db93af9b3f41fbca2f42
7
+ data.tar.gz: 894f593caf3c98841303be7eab6922d9e2a8737a5d3b9749221d53b8e82ab16ab2de37f758a82c8ae8cb8c92d4c6c0d936d50d11a2241187d38739edbb494896
@@ -42,7 +42,7 @@ class MyJohnDeereApi::Client
42
42
  end
43
43
 
44
44
  ##
45
- # generic user-specific POSST request method that returns JSON
45
+ # generic user-specific POST request method that returns JSON
46
46
 
47
47
  def post resource, body
48
48
  resource = resource.to_s
@@ -1,4 +1,5 @@
1
1
  module MyJohnDeereApi::Errors
2
2
  require 'my_john_deere_api/errors/access_token_error'
3
+ require 'my_john_deere_api/errors/invalid_record_error'
3
4
  require 'my_john_deere_api/errors/type_mismatch_error'
4
5
  end
@@ -0,0 +1,29 @@
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 InvalidRecordError < StandardError
8
+
9
+ ##
10
+ # argument is a hash of attributes and their error messages,
11
+ # which will be built into the raised message.
12
+
13
+ def initialize(errors = {})
14
+ message = 'Record is invalid'
15
+
16
+ unless errors.empty?
17
+ attribute_messages = []
18
+
19
+ errors.each do |attribute, message|
20
+ attribute_messages << "#{attribute} #{message}"
21
+ end
22
+
23
+ message = "#{message}: #{attribute_messages.join('; ')}"
24
+ end
25
+
26
+ super(message)
27
+ end
28
+ end
29
+ end
@@ -15,5 +15,13 @@ module MyJohnDeereApi::Request
15
15
  def model
16
16
  MyJohnDeereApi::Model::Asset
17
17
  end
18
+
19
+ ##
20
+ # Create a new asset
21
+
22
+ def create(attributes)
23
+ attributes.merge!(organization_id: associations[:organization])
24
+ Create::Asset.new(accessor, attributes).object
25
+ end
18
26
  end
19
27
  end
@@ -1,10 +1,142 @@
1
+ require 'json'
2
+
1
3
  module MyJohnDeereApi
2
4
  class Request::Create::Asset < Request::Create::Base
3
- attr_reader :accessor, :attributes
5
+ attr_reader :accessor, :attributes, :errors, :response
6
+
7
+ REQUIRED_ATTRIBUTES = [:organization_id, :contribution_definition_id, :title]
8
+
9
+ VALID_CATEGORIES = {
10
+ 'DEVICE' => {
11
+ 'SENSOR' => ['GRAIN_BIN', 'ENVIRONMENTAL', 'IRRIGATION_PIVOT', 'OTHER']
12
+ },
13
+
14
+ 'EQUIPMENT' => {
15
+ 'MACHINE' => ['PICKUP_TRUCK', 'UTILITY_VEHICLE'],
16
+ 'OTHER' => ['ANHYDROUS_AMMONIA_TANK', 'NURSE_TRUCK', 'NURSE_WAGON', 'TECHNICIAN_TRUCK']
17
+ },
18
+ }
19
+
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.
4
32
 
5
33
  def initialize(accessor, attributes)
6
34
  @accessor = accessor
7
35
  @attributes = attributes
36
+ @errors = {}
37
+ end
38
+
39
+ ##
40
+ # Object created by request
41
+
42
+ def object
43
+ return @object if defined?(@object)
44
+
45
+ request unless response
46
+
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)
51
+ end
52
+
53
+ ##
54
+ # Make the request, if the instance is valid
55
+
56
+ def request
57
+ validate!
58
+ @response = accessor.post(resource, request_body.to_json, headers)
59
+ end
60
+
61
+ ##
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.
64
+
65
+ def validate!
66
+ raise(InvalidRecordError, errors) unless valid?
67
+ end
68
+
69
+ ##
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
77
+
78
+ unless valid_categories?(attributes[:asset_category], attributes[:asset_type], attributes[:asset_sub_type])
79
+ errors[:asset_category] = 'requires valid combination of category/type/subtype'
80
+ end
81
+
82
+ @is_valid = errors.empty?
83
+ end
84
+
85
+ private
86
+
87
+ ##
88
+ # Path supplied to API
89
+
90
+ def resource
91
+ @path ||= "/organizations/#{attributes[:organization_id]}/assets"
92
+ end
93
+
94
+ ##
95
+ # Request body
96
+
97
+ def request_body
98
+ return @body if defined?(@body)
99
+
100
+
101
+ @body = {
102
+ title: attributes[:title],
103
+ assetCategory: attributes[:asset_category],
104
+ assetType: attributes[:asset_type],
105
+ assetSubType: attributes[:asset_sub_type],
106
+ links: [
107
+ {
108
+ '@type' => 'Link',
109
+ 'rel' => 'contributionDefinition',
110
+ 'uri' => "#{accessor.consumer.site}/contributionDefinitions/#{attributes[:contribution_definition_id]}"
111
+ }
112
+ ]
113
+ }
114
+ end
115
+
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
+ ##
126
+ # Returns boolean, true if this combination is valid
127
+
128
+ def valid_categories?(category, type, subtype)
129
+ VALID_CATEGORIES.dig(category, type).to_a.include?(subtype)
130
+ 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
+ }
8
140
  end
9
141
  end
10
142
  end
@@ -1,3 +1,3 @@
1
1
  module MyJohnDeereApi
2
- VERSION='0.5.3'
2
+ VERSION='0.6.0'
3
3
  end
@@ -0,0 +1,26 @@
1
+ require 'support/helper'
2
+
3
+ describe 'MyJohnDeereApi::InvalidRecordError' do
4
+ it 'inherits from StandardError' do
5
+ error = MyJohnDeereApi::InvalidRecordError.new
6
+ assert_kind_of StandardError, error
7
+ end
8
+
9
+ it 'has a default message' do
10
+ error = MyJohnDeereApi::InvalidRecordError.new
11
+ assert_includes error.message, 'Record is invalid'
12
+ end
13
+
14
+ it 'accepts a hash of errors, and includes them in message' do
15
+ errors = {
16
+ name: 'must be specified',
17
+ age: 'must be greater than 21'
18
+ }
19
+
20
+ message = MyJohnDeereApi::InvalidRecordError.new(errors).message
21
+
22
+ assert_includes message, 'Record is invalid'
23
+ assert_includes message, 'name must be specified'
24
+ assert_includes message, 'age must be greater than 21'
25
+ end
26
+ end
@@ -6,6 +6,10 @@ describe 'MyJohnDeereApi Errors' do
6
6
  assert JD::AccessTokenError
7
7
  end
8
8
 
9
+ it 'loads InvalidRecordError' do
10
+ assert JD::InvalidRecordError
11
+ end
12
+
9
13
  it 'loads TypeMismatchError' do
10
14
  assert JD::TypeMismatchError
11
15
  end
@@ -45,6 +45,31 @@ describe 'MyJohnDeereApi::Request::Collection::Assets' do
45
45
  end
46
46
  end
47
47
 
48
+ describe '#create(attributes)' do
49
+ let(:title) { 'i like turtles' }
50
+ let(:category) { 'DEVICE' }
51
+ let(:type) { 'SENSOR' }
52
+ let(:subtype) { 'ENVIRONMENTAL' }
53
+
54
+ it 'creates a new asset with the given attributes' do
55
+ attributes = {
56
+ contribution_definition_id: ENV['CONTRIBUTION_DEFINITION_ID'],
57
+ title: title,
58
+ asset_category: category,
59
+ asset_type: type,
60
+ asset_sub_type: subtype
61
+ }
62
+
63
+ object = VCR.use_cassette('post_assets') { collection.create(attributes) }
64
+
65
+ assert_kind_of JD::Model::Asset, object
66
+ assert_equal title, object.title
67
+ assert_equal category, object.asset_category
68
+ assert_equal type, object.asset_type
69
+ assert_equal subtype, object.asset_sub_type
70
+ end
71
+ end
72
+
48
73
  describe '#count' do
49
74
  let(:server_response) do
50
75
  contents = File.read('test/support/vcr/get_assets.yml')
@@ -1,16 +1,212 @@
1
1
  require 'support/helper'
2
2
 
3
3
  describe 'MyJohnDeereApi::Request::Create::Asset' do
4
+ def attributes_without(*keys)
5
+ keys = keys.to_a
6
+ attributes.reject{|k,v| keys.include?(k)}
7
+ end
8
+
4
9
  let(:client) { JD::Client.new(API_KEY, API_SECRET, environment: :sandbox, access: [ACCESS_TOKEN, ACCESS_SECRET]) }
5
10
  let(:accessor) { VCR.use_cassette('catalog') { client.send(:accessor) } }
6
11
 
12
+ let(:organization_id) { ENV['ORGANIZATION_ID']}
13
+ let(:contribution_definition_id) { ENV['CONTRIBUTION_DEFINITION_ID']}
14
+ let(:title) { 'i like turtles' }
15
+ let(:category) { 'DEVICE' }
16
+ let(:type) { 'SENSOR' }
17
+ let(:subtype) { 'ENVIRONMENTAL' }
18
+
19
+ let(:valid_attributes) do
20
+ {
21
+ organization_id: organization_id,
22
+ contribution_definition_id: contribution_definition_id,
23
+ title: title,
24
+ asset_category: category,
25
+ asset_type: type,
26
+ asset_sub_type: subtype,
27
+ }
28
+ end
29
+
30
+ let(:attributes) { valid_attributes }
31
+
7
32
  describe '#initialize(access_token, attributes)' do
8
33
  it 'accepts an accessor and attributes' do
9
- attributes = {attribute: 'value'}
10
34
  object = JD::Request::Create::Asset.new(accessor, attributes)
11
35
 
12
36
  assert_equal accessor, object.accessor
13
37
  assert_equal attributes, object.attributes
14
38
  end
39
+
40
+ it 'creates an empty error hash' do
41
+ object = JD::Request::Create::Asset.new(accessor, {})
42
+ assert_equal({}, object.errors)
43
+ end
44
+ end
45
+
46
+ describe '#valid?' do
47
+ it 'returns true when all required attributes are present' do
48
+ object = JD::Request::Create::Asset.new(accessor, attributes)
49
+
50
+ assert object.valid?
51
+ assert_empty object.errors
52
+ end
53
+
54
+ it 'requires organization_id' do
55
+ object = JD::Request::Create::Asset.new(accessor, attributes_without(:organization_id))
56
+
57
+ refute object.valid?
58
+ assert_equal 'is required', object.errors[:organization_id]
59
+ end
60
+
61
+ it 'requires contribution_definition_id' do
62
+ object = JD::Request::Create::Asset.new(accessor, attributes_without(:contribution_definition_id))
63
+
64
+ refute object.valid?
65
+ assert_equal 'is required', object.errors[:contribution_definition_id]
66
+ end
67
+
68
+ it 'requires title' do
69
+ object = JD::Request::Create::Asset.new(accessor, attributes_without(:title))
70
+
71
+ refute object.valid?
72
+ assert_equal 'is required', object.errors[:title]
73
+ end
74
+
75
+ it 'requires a valid category' do
76
+ object = JD::Request::Create::Asset.new(accessor, attributes.merge(asset_category: 'TURTLES'))
77
+
78
+ refute object.valid?
79
+ assert_equal 'requires valid combination of category/type/subtype', object.errors[:asset_category]
80
+ end
81
+
82
+ it 'requires a valid type' do
83
+ object = JD::Request::Create::Asset.new(accessor, attributes.merge(asset_type: 'TURTLES'))
84
+
85
+ refute object.valid?
86
+ assert_equal 'requires valid combination of category/type/subtype', object.errors[:asset_category]
87
+ end
88
+
89
+ it 'requires a valid subtype' do
90
+ object = JD::Request::Create::Asset.new(accessor, attributes.merge(asset_sub_type: 'TURTLES'))
91
+
92
+ refute object.valid?
93
+ assert_equal 'requires valid combination of category/type/subtype', object.errors[:asset_category]
94
+ end
95
+ end
96
+
97
+ describe '#validate!' do
98
+ it 'raises an error when invalid' do
99
+ object = JD::Request::Create::Asset.new(accessor, attributes_without(:organization_id))
100
+
101
+ exception = assert_raises(JD::InvalidRecordError) { object.validate! }
102
+ assert_includes exception.message, 'Record is invalid'
103
+ assert_includes exception.message, 'organization_id is required'
104
+ end
105
+ end
106
+
107
+ describe '#valid_categories?(category, type, subtype)' do
108
+ it 'only allows pre-defined combinations' do
109
+ object = JD::Request::Create::Asset.new(accessor, {})
110
+
111
+ valid_combos = [
112
+ ['DEVICE', 'SENSOR', 'ENVIRONMENTAL'],
113
+ ['DEVICE', 'SENSOR', 'GRAIN_BIN'],
114
+ ['DEVICE', 'SENSOR', 'IRRIGATION_PIVOT'],
115
+ ['DEVICE', 'SENSOR', 'OTHER'],
116
+ ['EQUIPMENT', 'MACHINE', 'PICKUP_TRUCK'],
117
+ ['EQUIPMENT', 'MACHINE', 'UTILITY_VEHICLE'],
118
+ ['EQUIPMENT', 'OTHER', 'ANHYDROUS_AMMONIA_TANK'],
119
+ ['EQUIPMENT', 'OTHER', 'NURSE_TRUCK'],
120
+ ['EQUIPMENT', 'OTHER', 'NURSE_WAGON'],
121
+ ['EQUIPMENT', 'OTHER', 'TECHNICIAN_TRUCK']
122
+ ]
123
+
124
+ # cycle through all possible permutations, only proving valid if
125
+ # listed above
126
+
127
+ ['DEVICE', 'EQUIPMENT', 'RANDOM_INVALID'].each do |category|
128
+ ['MACHINE', 'OTHER', 'SENSOR', 'RANDOM_INVALID'].each do |type|
129
+ [
130
+ 'ANHYDROUS_AMMONIA_TANK', 'ENVIRONMENTAL', 'GRAIN_BIN',
131
+ 'IRRIGATION_PIVOT', 'NURSE_TRUCK', 'NURSE_WAGON',
132
+ 'OTHER', 'PICKUP_TRUCK', 'TECHNICIAN_TRUCK',
133
+ 'UTILITY_VEHICLE', 'RANDOM_INVALID'
134
+ ].each do |subtype|
135
+ if valid_combos.include?([category, type, subtype])
136
+ assert object.send(:valid_categories?, category, type, subtype)
137
+ else
138
+ refute object.send(:valid_categories?, category, type, subtype)
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ describe '#resource' do
147
+ it 'is built from the organization id' do
148
+ object = JD::Request::Create::Asset.new(accessor, attributes)
149
+ assert_equal "/organizations/#{organization_id}/assets", object.send(:resource)
150
+ end
151
+ end
152
+
153
+ describe '#request_body' do
154
+ it 'properly forms the request body' do
155
+ object = JD::Request::Create::Asset.new(accessor, attributes)
156
+ body = object.send(:request_body)
157
+
158
+ assert_equal title, body[:title]
159
+ assert_equal category, body[:assetCategory]
160
+ assert_equal type, body[:assetType]
161
+ assert_equal subtype, body[:assetSubType]
162
+
163
+ assert_kind_of Array, body[:links]
164
+ assert_equal 1, body[:links].size
165
+
166
+ assert_kind_of Hash, body[:links].first
167
+ assert_equal 'Link', body[:links].first['@type']
168
+ assert_equal 'contributionDefinition', body[:links].first['rel']
169
+ assert_equal "#{ENV['BASE_URL']}/platform/contributionDefinitions/#{contribution_definition_id}",
170
+ body[:links].first['uri']
171
+ end
172
+ end
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
+ describe '#request' do
188
+ it 'makes the request' do
189
+ object = JD::Request::Create::Asset.new(accessor, attributes)
190
+ result = VCR.use_cassette('post_assets') { object.request }
191
+
192
+ assert_kind_of Net::HTTPCreated, object.response
193
+ end
194
+ end
195
+
196
+ describe '#object' do
197
+ it 'returns the asset model instance' do
198
+ object = JD::Request::Create::Asset.new(accessor, attributes)
199
+ result = VCR.use_cassette('post_assets') { object.object }
200
+
201
+ assert_kind_of JD::Model::Asset, result
202
+
203
+ expected_id = object.response['location'].split('/').last
204
+
205
+ assert_equal expected_id, result.id
206
+ assert_equal title, result.title
207
+ assert_equal category, result.asset_category
208
+ assert_equal type, result.asset_type
209
+ assert_equal subtype, result.asset_sub_type
210
+ end
15
211
  end
16
212
  end
@@ -0,0 +1,95 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://sandboxapi.deere.com/platform/organizations/444563/assets
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"title":"i like turtles","assetCategory":"DEVICE","assetType":"SENSOR","assetSubType":"ENVIRONMENTAL","links":[{"@type":"Link","rel":"contributionDefinition","uri":"https://sandboxapi.deere.com/platform/contributionDefinitions/d93611c7-6f74-474f-9569-2cf88f866a32"}]}'
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
+ - '268'
20
+ Authorization:
21
+ - OAuth oauth_body_hash="PjBPXHLlnKAk9CUdRHMhCt1iip8%3D", oauth_consumer_key="johndeere-wgmADngYCRmfpEbVgSyc709wnyRux5J7PAv8SE7B",
22
+ oauth_nonce="CP7ToNVMHHGpgJv80WPbJGVFT2MJ6pfHLgGo4xKHKQ", oauth_signature="A40yQoVjRtQIlSbj42uS1mhMLz4%3D",
23
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1579291545", 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
+ - Fri, 17 Jan 2020 20:05:45 GMT
32
+ Content-Type:
33
+ - application/vnd.deere.axiom.v3+json
34
+ X-Deere-Handling-Server:
35
+ - ip-10-214-45-254
36
+ X-Frame-Options:
37
+ - SAMEORIGIN
38
+ Location:
39
+ - https://sandboxapi.deere.com/platform/assets/911772e9-03c5-4a02-8acf-6d7574672558
40
+ X-Deere-Elapsed-Ms:
41
+ - '131'
42
+ Transfer-Encoding:
43
+ - chunked
44
+ body:
45
+ encoding: ASCII-8BIT
46
+ string: ''
47
+ http_version:
48
+ recorded_at: Fri, 17 Jan 2020 20:05:46 GMT
49
+ - request:
50
+ method: get
51
+ uri: https://sandboxapi.deere.com/platform/assets/911772e9-03c5-4a02-8acf-6d7574672558
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="qmM0zNnCBY1uaQfxgg6vsfQRpMRVXvPDnEaKP7v8", oauth_signature="o7648ovph6mRarq6EKJ22pWcIQs%3D",
67
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1579291546", 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
+ - Fri, 17 Jan 2020 20:05:46 GMT
76
+ Content-Type:
77
+ - application/vnd.deere.axiom.v3+json;charset=UTF-8
78
+ X-Deere-Handling-Server:
79
+ - ip-10-214-44-217
80
+ X-Frame-Options:
81
+ - SAMEORIGIN
82
+ X-Deere-Elapsed-Ms:
83
+ - '76'
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: '{"@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:
94
+ recorded_at: Fri, 17 Jan 2020 20:05:46 GMT
95
+ 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.5.3
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaime. Bellmyer
@@ -101,6 +101,7 @@ files:
101
101
  - lib/my_john_deere_api/consumer.rb
102
102
  - lib/my_john_deere_api/errors.rb
103
103
  - lib/my_john_deere_api/errors/access_token_error.rb
104
+ - lib/my_john_deere_api/errors/invalid_record_error.rb
104
105
  - lib/my_john_deere_api/errors/type_mismatch_error.rb
105
106
  - lib/my_john_deere_api/helpers.rb
106
107
  - lib/my_john_deere_api/helpers/case_conversion.rb
@@ -129,6 +130,7 @@ files:
129
130
  - test/lib/my_john_deere_api/client_test.rb
130
131
  - test/lib/my_john_deere_api/consumer_test.rb
131
132
  - test/lib/my_john_deere_api/errors/access_token_error_test.rb
133
+ - test/lib/my_john_deere_api/errors/invalid_record_error_test.rb
132
134
  - test/lib/my_john_deere_api/errors/type_mismatch_error_test.rb
133
135
  - test/lib/my_john_deere_api/errors_test.rb
134
136
  - test/lib/my_john_deere_api/helpers/case_conversion_test.rb
@@ -165,6 +167,7 @@ files:
165
167
  - test/support/vcr/get_flags.yml
166
168
  - test/support/vcr/get_organizations.yml
167
169
  - test/support/vcr/get_request_token.yml
170
+ - test/support/vcr/post_assets.yml
168
171
  - test/support/vcr/post_flag_categories.yml
169
172
  homepage: https://github.com/Intellifarm/my_john_deere_api
170
173
  licenses: