my_john_deere_api 2.4.1

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.
Files changed (153) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +813 -0
  3. data/Rakefile +9 -0
  4. data/lib/my_john_deere_api.rb +17 -0
  5. data/lib/my_john_deere_api/authorize.rb +69 -0
  6. data/lib/my_john_deere_api/client.rb +151 -0
  7. data/lib/my_john_deere_api/consumer.rb +90 -0
  8. data/lib/my_john_deere_api/errors.rb +7 -0
  9. data/lib/my_john_deere_api/errors/invalid_record_error.rb +29 -0
  10. data/lib/my_john_deere_api/errors/missing_contribution_definition_id_error.rb +12 -0
  11. data/lib/my_john_deere_api/errors/not_yet_implemented_error.rb +12 -0
  12. data/lib/my_john_deere_api/errors/type_mismatch_error.rb +12 -0
  13. data/lib/my_john_deere_api/errors/unsupported_environment_error.rb +18 -0
  14. data/lib/my_john_deere_api/helpers.rb +6 -0
  15. data/lib/my_john_deere_api/helpers/case_conversion.rb +37 -0
  16. data/lib/my_john_deere_api/helpers/environment_helper.rb +25 -0
  17. data/lib/my_john_deere_api/helpers/uri_helpers.rb +19 -0
  18. data/lib/my_john_deere_api/helpers/validate_contribution_definition.rb +18 -0
  19. data/lib/my_john_deere_api/model.rb +10 -0
  20. data/lib/my_john_deere_api/model/asset.rb +69 -0
  21. data/lib/my_john_deere_api/model/asset_location.rb +19 -0
  22. data/lib/my_john_deere_api/model/base.rb +97 -0
  23. data/lib/my_john_deere_api/model/contribution_definition.rb +15 -0
  24. data/lib/my_john_deere_api/model/contribution_product.rb +33 -0
  25. data/lib/my_john_deere_api/model/field.rb +40 -0
  26. data/lib/my_john_deere_api/model/flag.rb +36 -0
  27. data/lib/my_john_deere_api/model/organization.rb +43 -0
  28. data/lib/my_john_deere_api/net_http_retry.rb +2 -0
  29. data/lib/my_john_deere_api/net_http_retry/decorator.rb +53 -0
  30. data/lib/my_john_deere_api/net_http_retry/max_retries_exceeded_error.rb +20 -0
  31. data/lib/my_john_deere_api/request.rb +6 -0
  32. data/lib/my_john_deere_api/request/collection.rb +10 -0
  33. data/lib/my_john_deere_api/request/collection/asset_locations.rb +27 -0
  34. data/lib/my_john_deere_api/request/collection/assets.rb +34 -0
  35. data/lib/my_john_deere_api/request/collection/base.rb +91 -0
  36. data/lib/my_john_deere_api/request/collection/contribution_definitions.rb +26 -0
  37. data/lib/my_john_deere_api/request/collection/contribution_products.rb +26 -0
  38. data/lib/my_john_deere_api/request/collection/fields.rb +26 -0
  39. data/lib/my_john_deere_api/request/collection/flags.rb +33 -0
  40. data/lib/my_john_deere_api/request/collection/organizations.rb +26 -0
  41. data/lib/my_john_deere_api/request/create.rb +5 -0
  42. data/lib/my_john_deere_api/request/create/asset.rb +57 -0
  43. data/lib/my_john_deere_api/request/create/asset_location.rb +110 -0
  44. data/lib/my_john_deere_api/request/create/base.rb +67 -0
  45. data/lib/my_john_deere_api/request/individual.rb +8 -0
  46. data/lib/my_john_deere_api/request/individual/asset.rb +19 -0
  47. data/lib/my_john_deere_api/request/individual/base.rb +52 -0
  48. data/lib/my_john_deere_api/request/individual/contribution_definition.rb +19 -0
  49. data/lib/my_john_deere_api/request/individual/contribution_product.rb +19 -0
  50. data/lib/my_john_deere_api/request/individual/field.rb +19 -0
  51. data/lib/my_john_deere_api/request/individual/organization.rb +19 -0
  52. data/lib/my_john_deere_api/request/update.rb +4 -0
  53. data/lib/my_john_deere_api/request/update/asset.rb +40 -0
  54. data/lib/my_john_deere_api/request/update/base.rb +67 -0
  55. data/lib/my_john_deere_api/validators.rb +5 -0
  56. data/lib/my_john_deere_api/validators/asset.rb +35 -0
  57. data/lib/my_john_deere_api/validators/asset_location.rb +34 -0
  58. data/lib/my_john_deere_api/validators/base.rb +67 -0
  59. data/lib/my_john_deere_api/version.rb +3 -0
  60. data/test/lib/my_john_deere_api/authorize_test.rb +81 -0
  61. data/test/lib/my_john_deere_api/client_test.rb +225 -0
  62. data/test/lib/my_john_deere_api/consumer_test.rb +58 -0
  63. data/test/lib/my_john_deere_api/errors/invalid_record_error_test.rb +26 -0
  64. data/test/lib/my_john_deere_api/errors/max_retries_exceeded_error_test.rb +13 -0
  65. data/test/lib/my_john_deere_api/errors/missing_contribution_definition_id_error_test.rb +14 -0
  66. data/test/lib/my_john_deere_api/errors/not_yet_implemented_error_test.rb +13 -0
  67. data/test/lib/my_john_deere_api/errors/type_mismatch_error_test.rb +13 -0
  68. data/test/lib/my_john_deere_api/errors/unsupported_environment_error_test.rb +18 -0
  69. data/test/lib/my_john_deere_api/errors_test.rb +25 -0
  70. data/test/lib/my_john_deere_api/helpers/case_conversion_test.rb +100 -0
  71. data/test/lib/my_john_deere_api/helpers/environment_helper_test.rb +67 -0
  72. data/test/lib/my_john_deere_api/helpers/uri_helpers_test.rb +58 -0
  73. data/test/lib/my_john_deere_api/helpers/validate_contribution_definition_test.rb +74 -0
  74. data/test/lib/my_john_deere_api/helpers_test.rb +21 -0
  75. data/test/lib/my_john_deere_api/model/asset_location_test.rb +38 -0
  76. data/test/lib/my_john_deere_api/model/asset_test.rb +133 -0
  77. data/test/lib/my_john_deere_api/model/base_test.rb +76 -0
  78. data/test/lib/my_john_deere_api/model/contribution_definition_test.rb +52 -0
  79. data/test/lib/my_john_deere_api/model/contribution_product_test.rb +82 -0
  80. data/test/lib/my_john_deere_api/model/field_test.rb +65 -0
  81. data/test/lib/my_john_deere_api/model/flag_test.rb +48 -0
  82. data/test/lib/my_john_deere_api/model/organization_test.rb +84 -0
  83. data/test/lib/my_john_deere_api/model_test.rb +37 -0
  84. data/test/lib/my_john_deere_api/net_http_retry/decorator_test.rb +163 -0
  85. data/test/lib/my_john_deere_api/request/collection/asset_locations_test.rb +102 -0
  86. data/test/lib/my_john_deere_api/request/collection/assets_test.rb +99 -0
  87. data/test/lib/my_john_deere_api/request/collection/base_test.rb +27 -0
  88. data/test/lib/my_john_deere_api/request/collection/contribution_definitions_test.rb +88 -0
  89. data/test/lib/my_john_deere_api/request/collection/contribution_products_test.rb +88 -0
  90. data/test/lib/my_john_deere_api/request/collection/fields_test.rb +86 -0
  91. data/test/lib/my_john_deere_api/request/collection/flags_test.rb +92 -0
  92. data/test/lib/my_john_deere_api/request/collection/organizations_test.rb +87 -0
  93. data/test/lib/my_john_deere_api/request/collection_test.rb +37 -0
  94. data/test/lib/my_john_deere_api/request/create/asset_location_test.rb +163 -0
  95. data/test/lib/my_john_deere_api/request/create/asset_test.rb +182 -0
  96. data/test/lib/my_john_deere_api/request/create/base_test.rb +29 -0
  97. data/test/lib/my_john_deere_api/request/create_test.rb +17 -0
  98. data/test/lib/my_john_deere_api/request/individual/asset_test.rb +33 -0
  99. data/test/lib/my_john_deere_api/request/individual/base_test.rb +18 -0
  100. data/test/lib/my_john_deere_api/request/individual/contribution_definition_test.rb +33 -0
  101. data/test/lib/my_john_deere_api/request/individual/contribution_product_test.rb +33 -0
  102. data/test/lib/my_john_deere_api/request/individual/field_test.rb +37 -0
  103. data/test/lib/my_john_deere_api/request/individual/organization_test.rb +33 -0
  104. data/test/lib/my_john_deere_api/request/individual_test.rb +29 -0
  105. data/test/lib/my_john_deere_api/request/update/asset_test.rb +99 -0
  106. data/test/lib/my_john_deere_api/request/update/base_test.rb +60 -0
  107. data/test/lib/my_john_deere_api/request/update_test.rb +13 -0
  108. data/test/lib/my_john_deere_api/request_test.rb +21 -0
  109. data/test/lib/my_john_deere_api/validators/asset_location_test.rb +61 -0
  110. data/test/lib/my_john_deere_api/validators/asset_test.rb +93 -0
  111. data/test/lib/my_john_deere_api/validators/base_test.rb +92 -0
  112. data/test/lib/my_john_deere_api/validators_test.rb +17 -0
  113. data/test/lib/my_john_deere_api/version_test.rb +9 -0
  114. data/test/my_john_deere_api_test.rb +37 -0
  115. data/test/support/helper.rb +97 -0
  116. data/test/support/vcr/accessor/delete_failed.yml +327 -0
  117. data/test/support/vcr/accessor/delete_max_failed.yml +615 -0
  118. data/test/support/vcr/accessor/delete_retry.yml +191 -0
  119. data/test/support/vcr/accessor/delete_retry_too_soon.yml +191 -0
  120. data/test/support/vcr/accessor/get_failed.yml +390 -0
  121. data/test/support/vcr/accessor/get_max_failed.yml +734 -0
  122. data/test/support/vcr/accessor/get_retry.yml +226 -0
  123. data/test/support/vcr/accessor/get_retry_too_soon.yml +226 -0
  124. data/test/support/vcr/accessor/post_failed.yml +417 -0
  125. data/test/support/vcr/accessor/post_max_failed.yml +785 -0
  126. data/test/support/vcr/accessor/post_retry.yml +241 -0
  127. data/test/support/vcr/accessor/post_retry_too_soon.yml +241 -0
  128. data/test/support/vcr/accessor/put_failed.yml +372 -0
  129. data/test/support/vcr/accessor/put_max_failed.yml +700 -0
  130. data/test/support/vcr/accessor/put_retry.yml +216 -0
  131. data/test/support/vcr/accessor/put_retry_too_soon.yml +216 -0
  132. data/test/support/vcr/catalog.yml +89 -0
  133. data/test/support/vcr/delete_asset.yml +82 -0
  134. data/test/support/vcr/get_access_token.yml +41 -0
  135. data/test/support/vcr/get_asset.yml +144 -0
  136. data/test/support/vcr/get_asset_locations.yml +196 -0
  137. data/test/support/vcr/get_assets.yml +152 -0
  138. data/test/support/vcr/get_contribution_definition.yml +90 -0
  139. data/test/support/vcr/get_contribution_definitions.yml +91 -0
  140. data/test/support/vcr/get_contribution_product.yml +91 -0
  141. data/test/support/vcr/get_contribution_products.yml +91 -0
  142. data/test/support/vcr/get_field.yml +144 -0
  143. data/test/support/vcr/get_fields.yml +146 -0
  144. data/test/support/vcr/get_flags.yml +47 -0
  145. data/test/support/vcr/get_organization.yml +90 -0
  146. data/test/support/vcr/get_organizations.yml +149 -0
  147. data/test/support/vcr/get_request_token.yml +83 -0
  148. data/test/support/vcr/post_asset_locations.yml +244 -0
  149. data/test/support/vcr/post_assets.yml +192 -0
  150. data/test/support/vcr/put_asset.yml +87 -0
  151. data/test/support/vcr/warning.txt +28 -0
  152. data/test/support/vcr_setup.rb +488 -0
  153. metadata +277 -0
@@ -0,0 +1,48 @@
1
+ require 'support/helper'
2
+ require 'json'
3
+
4
+ describe 'MyJohnDeereApi::Model::Flag' do
5
+ let(:klass) { JD::Model::Flag }
6
+
7
+ let(:record) do
8
+ {
9
+ "@type"=>"Flag",
10
+ "geometry"=>"{\"type\": \"Point\", \"coordinates\": [-93.14959274063109, 41.66881548411553] }",
11
+ "archived"=>true,
12
+ "proximityAlertEnabled"=>true,
13
+ "notes"=>"Our flag is a very, very, very nice flag!",
14
+ "id"=>"123456",
15
+ "links"=>[
16
+ {"@type"=>"Link", "rel"=>"field", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/fields/#{field_id}"},
17
+ {"@type"=>"Link", "rel"=>"createdBy", "uri"=>"https://sandboxapi.deere.com/platform/users/bobsmith"},
18
+ {"@type"=>"Link", "rel"=>"lastModifiedBy", "uri"=>"https://sandboxapi.deere.com/platform/users/jonsmith"},
19
+ ]
20
+ }
21
+ end
22
+
23
+ describe '#initialize' do
24
+ def link_for label
25
+ record['links'].detect{|link| link['rel'] == label}['uri'].gsub('https://sandboxapi.deere.com/platform', '')
26
+ end
27
+
28
+ it 'sets the attributes from the given record' do
29
+ flag = klass.new(client, record)
30
+
31
+ assert_equal client, flag.client
32
+ assert_equal accessor, flag.accessor
33
+
34
+ # basic attributes
35
+ assert_equal JSON.parse(record['geometry']), flag.geometry
36
+ assert_equal record['archived'], flag.archived?
37
+ assert_equal record['proximityAlertEnabled'], flag.proximity_alert_enabled?
38
+ assert_equal record['notes'], flag.notes
39
+ assert_equal record['id'], flag.id
40
+
41
+ # links to other things
42
+ assert_kind_of Hash, flag.links
43
+ assert_equal link_for('field'), flag.links['field']
44
+ assert_equal link_for('createdBy'), flag.links['created_by']
45
+ assert_equal link_for('lastModifiedBy'), flag.links['last_modified_by']
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,84 @@
1
+ require 'support/helper'
2
+
3
+ describe 'MyJohnDeereApi::Model::Organization' do
4
+ let(:klass) { JD::Model::Organization }
5
+
6
+ let(:record) do
7
+ {
8
+ "@type"=>"Organization",
9
+ "name"=>"Century Farms",
10
+ "type"=>"customer",
11
+ "member"=>true,
12
+ "id"=>"123456",
13
+ "links"=>[
14
+ {"@type"=>"Link", "rel"=>"self", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}"},
15
+ {"@type"=>"Link", "rel"=>"machines", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/machines"},
16
+ {"@type"=>"Link", "rel"=>"wdtCapableMachines", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/machines?capability=wdt"},
17
+ {"@type"=>"Link", "rel"=>"files", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/files"},
18
+ {"@type"=>"Link", "rel"=>"transferableFiles", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/files?transferable=true"},
19
+ {"@type"=>"Link", "rel"=>"uploadFile", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/files"},
20
+ {"@type"=>"Link", "rel"=>"sendFileToMachine", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/fileTransfers"},
21
+ {"@type"=>"Link", "rel"=>"addMachine", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/machines"},
22
+ {"@type"=>"Link", "rel"=>"addField", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/fields"},
23
+ {"@type"=>"Link", "rel"=>"assets", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/assets"},
24
+ {"@type"=>"Link", "rel"=>"fields", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/fields"},
25
+ {"@type"=>"Link", "rel"=>"farms", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/farms"},
26
+ {"@type"=>"Link", "rel"=>"boundaries", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/boundaries"},
27
+ {"@type"=>"Link", "rel"=>"clients", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/clients"},
28
+ {"@type"=>"Link", "rel"=>"controllers", "uri"=>"https://sandboxapi.deere.com/platform/organizations/#{organization_id}/orgController"}
29
+ ]
30
+ }
31
+ end
32
+
33
+ describe '#initialize(record, client = nil)' do
34
+ def link_for label
35
+ record['links'].detect{|link| link['rel'] == label}['uri'].gsub('https://sandboxapi.deere.com/platform', '')
36
+ end
37
+
38
+ it 'sets the attributes from the given record' do
39
+ organization = klass.new(client, record)
40
+
41
+ assert_equal client, organization.client
42
+ assert_equal accessor, organization.accessor
43
+
44
+ # basic attributes
45
+ assert_equal record['name'], organization.name
46
+ assert_equal record['type'], organization.type
47
+ assert_equal record['member'], organization.member?
48
+ assert_equal record['id'], organization.id
49
+
50
+ # links to other things
51
+ assert_kind_of Hash, organization.links
52
+
53
+ ['fields', 'machines', 'files', 'assets', 'farms', 'boundaries', 'clients', 'controllers'].each do |association|
54
+ assert_equal link_for(association), organization.links[association]
55
+ end
56
+ end
57
+ end
58
+
59
+ describe '#fields' do
60
+ it 'returns a collection of fields for this organization' do
61
+ organization = VCR.use_cassette('get_organizations') { client.organizations.first }
62
+ fields = VCR.use_cassette('get_fields') { organization.fields.all }
63
+
64
+ assert_kind_of Array, fields
65
+
66
+ fields.each do |field|
67
+ assert_kind_of JD::Model::Field, field
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#assets' do
73
+ it 'returns a collection of assets for this organization' do
74
+ organization = VCR.use_cassette('get_organizations') { client.organizations.first }
75
+ assets = VCR.use_cassette('get_assets') { organization.assets.all; organization.assets }
76
+
77
+ assert_kind_of JD::Request::Collection::Assets, assets
78
+
79
+ assets.each do |assets|
80
+ assert_kind_of JD::Model::Asset, assets
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,37 @@
1
+ require 'support/helper'
2
+
3
+ describe 'MyJohnDeereApi::Model' do
4
+ describe 'loading dependencies' do
5
+ it 'loads Model::Base' do
6
+ assert JD::Model::Base
7
+ end
8
+
9
+ it 'loads Model::Asset' do
10
+ assert JD::Model::Asset
11
+ end
12
+
13
+ it 'loads Model::AssetLocation' do
14
+ assert JD::Model::AssetLocation
15
+ end
16
+
17
+ it 'loads Model::ContributionProduct' do
18
+ assert JD::Model::ContributionProduct
19
+ end
20
+
21
+ it 'loads Model::ContributionDefinition' do
22
+ assert JD::Model::ContributionDefinition
23
+ end
24
+
25
+ it 'loads Model::Organization' do
26
+ assert JD::Model::Organization
27
+ end
28
+
29
+ it 'loads Model::Field' do
30
+ assert JD::Model::Field
31
+ end
32
+
33
+ it 'loads Model::Flag' do
34
+ assert JD::Model::Flag
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,163 @@
1
+ require 'support/helper'
2
+
3
+ describe 'JD::NetHttpRetry::Decorator' do
4
+ REQUESTS = {
5
+ get: '/',
6
+ post: '/organizations/000000/assets',
7
+ put: '/assets/00000000-0000-0000-0000-000000000000',
8
+ delete: '/assets/00000000-0000-0000-0000-000000000000'
9
+ }
10
+
11
+ REQUEST_METHODS = REQUESTS.keys
12
+
13
+ let(:klass) { JD::NetHttpRetry::Decorator }
14
+ let(:object) { klass.new(mock, options) }
15
+
16
+ let(:options) do
17
+ {
18
+ request_methods: request_methods,
19
+ retry_delay_exponent: retry_delay_exponent,
20
+ max_retries: max_retries,
21
+ response_codes: response_codes
22
+ }
23
+ end
24
+
25
+ let(:request_methods) { nil }
26
+ let(:retry_delay_exponent) { nil }
27
+ let(:max_retries) { nil }
28
+ let(:response_codes) { nil }
29
+
30
+ let(:retry_values) { [13, 17, 19, 23] }
31
+ let(:exponential_retries) { (0..klass::DEFAULTS[:max_retries]-1).map{|i| 2 ** i} }
32
+
33
+ it 'wraps a "net-http"-responsive object' do
34
+ assert_kind_of OAuth::AccessToken, accessor.object
35
+ end
36
+
37
+ describe '#initialize' do
38
+ describe 'when request methods are specified' do
39
+ let(:request_methods) { [:banana, :fana, :fofana] }
40
+
41
+ it 'uses the supplied values' do
42
+ assert_equal request_methods, object.request_methods
43
+ end
44
+ end
45
+
46
+ describe 'when request methods are not specified' do
47
+ it 'uses the default values' do
48
+ assert_equal klass::DEFAULTS[:request_methods], object.request_methods
49
+ end
50
+ end
51
+
52
+ describe 'when retry_delay_exponent is specified' do
53
+ let(:retry_delay_exponent) { 42 }
54
+
55
+ it 'uses the supplied value' do
56
+ assert_equal retry_delay_exponent, object.retry_delay_exponent
57
+ end
58
+ end
59
+
60
+ describe 'when retry_delay_exponent is not specified' do
61
+ it 'uses the default value' do
62
+ assert_equal klass::DEFAULTS[:retry_delay_exponent], object.retry_delay_exponent
63
+ end
64
+ end
65
+
66
+ describe 'when max_retries is specified' do
67
+ let(:max_retries) { 42 }
68
+
69
+ it 'uses the supplied value' do
70
+ assert_equal max_retries, object.max_retries
71
+ end
72
+ end
73
+
74
+ describe 'when max_retries is not specified' do
75
+ it 'uses the default value' do
76
+ assert_equal klass::DEFAULTS[:max_retries], object.max_retries
77
+ end
78
+ end
79
+
80
+ describe 'when response_codes are specified' do
81
+ let(:response_codes) { ['200', '201'] }
82
+
83
+ it 'uses the supplied values' do
84
+ assert_equal response_codes, object.response_codes
85
+ end
86
+ end
87
+
88
+ describe 'when response_codes are specified as integers' do
89
+ let(:response_codes) { [200, 201] }
90
+
91
+ it 'uses the stringified versions of the supplied values' do
92
+ assert_equal response_codes.map(&:to_s), object.response_codes
93
+ end
94
+ end
95
+
96
+ describe 'when response_codes are not specified' do
97
+ it 'uses the default values' do
98
+ assert_equal klass::DEFAULTS[:response_codes], object.response_codes
99
+ end
100
+ end
101
+ end
102
+
103
+ describe "honors Retry-After headers" do
104
+ REQUEST_METHODS.each do |request_method|
105
+ it "in #{request_method.to_s.upcase} requests" do
106
+ retry_values.each do |retry_seconds|
107
+ accessor.expects(:sleep).with(retry_seconds)
108
+ end
109
+
110
+ VCR.use_cassette("accessor/#{request_method}_retry") do
111
+ accessor.send(request_method, REQUESTS[request_method])
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ describe 'employs exponential wait times for automatic retries' do
118
+ REQUEST_METHODS.each do |request_method|
119
+ it "in #{request_method.to_s.upcase} requests" do
120
+ exponential_retries[0,8].each do |retry_seconds|
121
+ accessor.expects(:sleep).with(retry_seconds)
122
+ end
123
+
124
+ VCR.use_cassette("accessor/#{request_method}_failed") do
125
+ accessor.send(request_method, REQUESTS[request_method])
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ describe 'when Retry-After is shorter than exponential wait time' do
132
+ REQUEST_METHODS.each do |request_method|
133
+ it "chooses longer exponential time in #{request_method.to_s.upcase} requests" do
134
+ exponential_retries[0,4].each do |retry_seconds|
135
+ accessor.expects(:sleep).with(retry_seconds)
136
+ end
137
+
138
+ VCR.use_cassette("accessor/#{request_method}_retry_too_soon") do
139
+ accessor.send(request_method, REQUESTS[request_method])
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ describe 'when max retries have been reached' do
146
+ REQUEST_METHODS.each do |request_method|
147
+ it "returns an error for #{request_method.to_s.upcase} requests" do
148
+ exponential_retries.each do |retry_seconds|
149
+ accessor.expects(:sleep).with(retry_seconds)
150
+ end
151
+
152
+ exception = assert_raises(JD::NetHttpRetry::MaxRetriesExceededError) do
153
+ VCR.use_cassette("accessor/#{request_method}_max_failed") do
154
+ accessor.send(request_method, REQUESTS[request_method])
155
+ end
156
+ end
157
+
158
+ expected_error = "Max retries exceeded for #{request_method.to_s.upcase} request: 429 Too Many Requests"
159
+ assert_equal expected_error, exception.message
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,102 @@
1
+ require 'support/helper'
2
+ require 'yaml'
3
+ require 'json'
4
+
5
+ describe 'MyJohnDeereApi::Request::Collection::AssetLocations' do
6
+ let(:klass) { JD::Request::Collection::AssetLocations }
7
+ let(:collection) { klass.new(client, asset: asset_id) }
8
+ let(:object) { collection }
9
+
10
+ inherits_from JD::Request::Collection::Base
11
+
12
+ describe '#initialize(client)' do
13
+ it 'accepts a client' do
14
+ assert_equal client, collection.client
15
+ end
16
+
17
+ it 'accepts associations' do
18
+ collection = klass.new(client, asset: asset_id)
19
+
20
+ assert_kind_of Hash, collection.associations
21
+ assert_equal asset_id, collection.associations[:asset]
22
+ end
23
+ end
24
+
25
+ describe '#resource' do
26
+ it 'returns /assets/{asset_id}/locations' do
27
+ assert_equal "/assets/#{asset_id}/locations", collection.resource
28
+ end
29
+ end
30
+
31
+ describe '#all' do
32
+ it 'returns all records' do
33
+ all = VCR.use_cassette('get_asset_locations') { collection.all }
34
+
35
+ assert_kind_of Array, all
36
+ assert_equal collection.count, all.size
37
+ assert all.size > 0
38
+
39
+ all.each do |item|
40
+ assert_kind_of JD::Model::AssetLocation, item
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#create(attributes)' do
46
+ it 'creates a new asset with the given attributes' do
47
+ attributes = CONFIG.asset_location_attributes
48
+
49
+ object = VCR.use_cassette('post_asset_locations') { collection.create(attributes) }
50
+
51
+ assert_kind_of JD::Model::AssetLocation, object
52
+
53
+ # API returns seconds with decimals, even though they're always zero
54
+ integer_stamp = DateTime.parse(object.timestamp).strftime('%Y-%m-%dT%H:%M:%SZ')
55
+ expected_stamp = DateTime.parse(attributes[:timestamp]).strftime('%Y-%m-%dT%H:%M:%SZ')
56
+
57
+ # API returns string keys and an extra '@type' key
58
+ object_measurement_data = object.measurement_data.first.transform_keys{|k| k.to_sym}.slice(:name, :value, :unit)
59
+
60
+ assert_equal expected_stamp, integer_stamp
61
+ assert_equal attributes[:geometry].to_json, object.geometry.to_json
62
+ assert_equal attributes[:measurement_data].first, object_measurement_data
63
+ end
64
+ end
65
+
66
+ describe '#count' do
67
+ let(:server_response) do
68
+ contents = File.read('test/support/vcr/get_asset_locations.yml')
69
+ body = YAML.load(contents)['http_interactions'].last['response']['body']['string']
70
+ JSON.parse(body)
71
+ end
72
+
73
+ let(:server_count) { server_response['total'] }
74
+
75
+ it 'returns the total count of records in the collection' do
76
+ count = VCR.use_cassette('get_asset_locations') { collection.count }
77
+
78
+ assert_equal server_count, count
79
+ end
80
+ end
81
+
82
+ describe 'results' do
83
+ let(:location_timestamps) do
84
+ contents = File.read('test/support/vcr/get_asset_locations.yml')
85
+ body = YAML.load(contents)['http_interactions'].last['response']['body']['string']
86
+ JSON.parse(body)['values'].map{|v| v['timestamp']}
87
+ end
88
+
89
+ it 'returns all records as a single enumerator' do
90
+ count = VCR.use_cassette('get_asset_locations') { collection.count }
91
+ timestamps = VCR.use_cassette('get_asset_locations') { collection.map(&:timestamp) }
92
+
93
+ assert_kind_of Array, timestamps
94
+ assert_equal count, timestamps.size
95
+ assert timestamps.size > 0
96
+
97
+ location_timestamps.each do |expected_timestamp|
98
+ assert_includes timestamps, expected_timestamp
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,99 @@
1
+ require 'support/helper'
2
+ require 'yaml'
3
+ require 'json'
4
+
5
+ describe 'MyJohnDeereApi::Request::Collection::Assets' do
6
+ let(:klass) { JD::Request::Collection::Assets }
7
+ let(:collection) { klass.new(client, organization: organization_id) }
8
+ let(:object) { collection }
9
+
10
+ inherits_from JD::Request::Collection::Base
11
+
12
+ describe '#initialize(client)' do
13
+ it 'accepts a client' do
14
+ assert_equal client, collection.client
15
+ end
16
+
17
+ it 'accepts associations' do
18
+ collection = klass.new(client, organization: organization_id)
19
+
20
+ assert_kind_of Hash, collection.associations
21
+ assert_equal organization_id, collection.associations[:organization]
22
+ end
23
+ end
24
+
25
+ describe '#resource' do
26
+ it 'returns /organizations/{org_id}/assets' do
27
+ assert_equal "/organizations/#{organization_id}/assets", collection.resource
28
+ end
29
+ end
30
+
31
+ describe '#all' do
32
+ it 'returns all records' do
33
+ all = VCR.use_cassette('get_assets') { collection.all }
34
+
35
+ assert_kind_of Array, all
36
+ assert_equal collection.count, all.size
37
+
38
+ all.each do |item|
39
+ assert_kind_of JD::Model::Asset, item
40
+ end
41
+ end
42
+ end
43
+
44
+ describe '#create(attributes)' do
45
+ it 'creates a new asset with the given attributes' do
46
+ attributes = CONFIG.asset_attributes
47
+ object = VCR.use_cassette('post_assets') { collection.create(attributes) }
48
+
49
+ assert_kind_of JD::Model::Asset, object
50
+ assert_equal attributes[:title], object.title
51
+ assert_equal attributes[:asset_category], object.asset_category
52
+ assert_equal attributes[:asset_type], object.asset_type
53
+ assert_equal attributes[:asset_sub_type], object.asset_sub_type
54
+ end
55
+ end
56
+
57
+ describe '#find(asset_id)' do
58
+ it 'retrieves the asset' do
59
+ asset = VCR.use_cassette('get_asset') { collection.find(asset_id) }
60
+ assert_kind_of JD::Model::Asset, asset
61
+ end
62
+ end
63
+
64
+ describe '#count' do
65
+ let(:server_response) do
66
+ contents = File.read('test/support/vcr/get_assets.yml')
67
+ body = YAML.load(contents)['http_interactions'].last['response']['body']['string']
68
+ JSON.parse(body)
69
+ end
70
+
71
+ let(:server_count) { server_response['total'] }
72
+
73
+ it 'returns the total count of records in the collection' do
74
+ count = VCR.use_cassette('get_assets') { collection.count }
75
+
76
+ assert_equal server_count, count
77
+ end
78
+ end
79
+
80
+ describe 'results' do
81
+ let(:asset_titles) do
82
+ contents = File.read('test/support/vcr/get_assets.yml')
83
+ body = YAML.load(contents)['http_interactions'].last['response']['body']['string']
84
+ JSON.parse(body)['values'].map{|v| v['title']}
85
+ end
86
+
87
+ it 'returns all records as a single enumerator' do
88
+ count = VCR.use_cassette('get_assets') { collection.count }
89
+ titles = VCR.use_cassette('get_assets') { collection.map(&:title) }
90
+
91
+ assert_kind_of Array, titles
92
+ assert_equal count, titles.size
93
+
94
+ asset_titles.each do |expected_title|
95
+ assert_includes titles, expected_title
96
+ end
97
+ end
98
+ end
99
+ end