my_john_deere_api 0.4.1 → 0.5.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/lib/my_john_deere_api/helpers/case_conversion.rb +2 -4
  4. data/lib/my_john_deere_api/helpers/uri_helpers.rb +19 -0
  5. data/lib/my_john_deere_api/helpers.rb +1 -1
  6. data/lib/my_john_deere_api/model/asset.rb +43 -0
  7. data/lib/my_john_deere_api/model/asset_location.rb +27 -0
  8. data/lib/my_john_deere_api/model/field.rb +2 -4
  9. data/lib/my_john_deere_api/model/flag.rb +1 -1
  10. data/lib/my_john_deere_api/model/organization.rb +11 -1
  11. data/lib/my_john_deere_api/model.rb +2 -0
  12. data/lib/my_john_deere_api/request/collection/asset_locations.rb +19 -0
  13. data/lib/my_john_deere_api/request/collection/assets.rb +19 -0
  14. data/lib/my_john_deere_api/request/collection/base.rb +1 -1
  15. data/lib/my_john_deere_api/request/collection.rb +3 -1
  16. data/lib/my_john_deere_api/version.rb +1 -1
  17. data/test/lib/my_john_deere_api/{test_authorize.rb → authorize_test.rb} +0 -0
  18. data/test/lib/my_john_deere_api/{test_client.rb → client_test.rb} +0 -0
  19. data/test/lib/my_john_deere_api/{test_consumer.rb → consumer_test.rb} +0 -0
  20. data/test/lib/my_john_deere_api/errors/{test_access_token_error.rb → access_token_error_test.rb} +0 -0
  21. data/test/lib/my_john_deere_api/{test_errors.rb → errors_test.rb} +0 -0
  22. data/test/lib/my_john_deere_api/helpers/{test_case_conversion.rb → case_conversion_test.rb} +12 -2
  23. data/test/lib/my_john_deere_api/helpers/uri_helpers_test.rb +58 -0
  24. data/test/lib/my_john_deere_api/{test_helpers.rb → helpers_test.rb} +2 -2
  25. data/test/lib/my_john_deere_api/model/asset_location_test.rb +57 -0
  26. data/test/lib/my_john_deere_api/model/asset_test.rb +79 -0
  27. data/test/lib/my_john_deere_api/model/{test_field.rb → field_test.rb} +7 -0
  28. data/test/lib/my_john_deere_api/model/{test_flag.rb → flag_test.rb} +0 -0
  29. data/test/lib/my_john_deere_api/model/{test_organization.rb → organization_test.rb} +21 -0
  30. data/test/lib/my_john_deere_api/{test_model.rb → model_test.rb} +8 -0
  31. data/test/lib/my_john_deere_api/request/collection/asset_locations_test.rb +85 -0
  32. data/test/lib/my_john_deere_api/request/collection/assets_test.rb +83 -0
  33. data/test/lib/my_john_deere_api/request/collection/{test_base.rb → base_test.rb} +0 -0
  34. data/test/lib/my_john_deere_api/request/collection/{test_fields.rb → fields_test.rb} +0 -0
  35. data/test/lib/my_john_deere_api/request/collection/{test_flags.rb → flags_test.rb} +0 -0
  36. data/test/lib/my_john_deere_api/request/collection/{test_organizations.rb → organizations_test.rb} +0 -0
  37. data/test/lib/my_john_deere_api/request/{test_collection.rb → collection_test.rb} +8 -0
  38. data/test/lib/my_john_deere_api/{test_request.rb → request_test.rb} +0 -0
  39. data/test/lib/my_john_deere_api/{test_version.rb → version_test.rb} +0 -0
  40. data/test/{test_my_john_deere_api.rb → my_john_deere_api_test.rb} +0 -0
  41. data/test/support/vcr/get_asset_locations.yml +55 -0
  42. data/test/support/vcr/get_assets.yml +48 -0
  43. metadata +32 -22
  44. data/lib/my_john_deere_api/helpers/uri_path.rb +0 -9
  45. data/test/lib/my_john_deere_api/helpers/test_uri_path.rb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 308f6c3b51f2e879f9df9bb1b616947867acd261363aa72e98458f5e6234aa37
4
- data.tar.gz: '09257f1b9559a3a5b631f724bf4767151d49b0c6a9ddbc6ded2b024c3063bb8b'
3
+ metadata.gz: 8f27839609fe2e86e82d918edae99dd77d78cb9d7dad78c061d8ab198837953d
4
+ data.tar.gz: b302429624cc3f1a504e77235c105f94af9363bc075809f46f1659bf1b59859c
5
5
  SHA512:
6
- metadata.gz: 6a9f7d5b8303090de1101531ae6b9be02534c1c8d71179117ee5714238ae1ce4d067987a4a324e3a59316a95d7a613ab532c85989c4451109dc6236946be4195
7
- data.tar.gz: 369e58fbca78c338cf6e79935037cb154ba1fd5a44385e2623d62ef8a213bb9f60a3c74035efbad066b6a6b414a06e95828702844460890d757b4b6c51fa97d7
6
+ metadata.gz: 3b2509a126cf7aef80dc4984865660eb20285a4ccbb5aaec61a622449eebc3eb0628d1a44f3de78bfc95af42f639bbecd5a5796219b3d8be3ea4be7612e90b96
7
+ data.tar.gz: 2b401cacbc5c4fc8e9b224c89639689ceb681d8b697dfdd1b1f3ff62b1b91c5ea40508a2de61ade9ad8744773a90358067e9240faaa3f4088803c3caac1eb196
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rake/testtask'
2
2
 
3
3
  Rake::TestTask.new do |t|
4
4
  t.libs << 'test'
5
- t.pattern = 'test/**/test*.rb'
5
+ t.pattern = 'test/**/*_test.rb'
6
6
  end
7
7
 
8
8
  desc "Run tests"
@@ -1,6 +1,8 @@
1
1
  require 'uri'
2
2
 
3
3
  module MyJohnDeereApi::Helpers::CaseConversion
4
+ private
5
+
4
6
  ##
5
7
  # convert a text or camelcase string to underscore
6
8
 
@@ -8,8 +10,6 @@ module MyJohnDeereApi::Helpers::CaseConversion
8
10
  string.gsub(/([a-z])([A-Z])/, '\1_\2').gsub(/\s+/, '_').gsub(/_+/, '_').downcase
9
11
  end
10
12
 
11
- private :underscore
12
-
13
13
  ##
14
14
  # convert text or underscored string to camelcase
15
15
 
@@ -22,6 +22,4 @@ module MyJohnDeereApi::Helpers::CaseConversion
22
22
 
23
23
  new_list.join('')
24
24
  end
25
-
26
- private :camelize
27
25
  end
@@ -0,0 +1,19 @@
1
+ require 'uri'
2
+
3
+ module MyJohnDeereApi::Helpers::UriHelpers
4
+ private
5
+
6
+ ##
7
+ # extract just the path from the uri, excluding the platform prefix
8
+ def uri_path(uri)
9
+ URI.parse(uri).path.gsub(/^\/platform/, '')
10
+ end
11
+
12
+ ##
13
+ # infer id from uri
14
+
15
+ def id_from_uri(uri, label)
16
+ parts = uri.split('/')
17
+ parts[parts.index(label.to_s) + 1]
18
+ end
19
+ end
@@ -1,4 +1,4 @@
1
1
  module MyJohnDeereApi::Helpers
2
- autoload :UriPath, 'my_john_deere_api/helpers/uri_path'
2
+ autoload :UriHelpers, 'my_john_deere_api/helpers/uri_helpers'
3
3
  autoload :CaseConversion, 'my_john_deere_api/helpers/case_conversion'
4
4
  end
@@ -0,0 +1,43 @@
1
+ module MyJohnDeereApi
2
+ class Model::Asset
3
+ include Helpers::UriHelpers
4
+
5
+ attr_reader :accessor, :id, :title, :asset_category, :asset_type, :asset_sub_type, :last_modified_date, :links
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
+
16
+ def initialize(record, accessor = nil)
17
+ @accessor = accessor
18
+
19
+ @id = record['id']
20
+ @title = record['title']
21
+ @asset_category = record['assetCategory']
22
+ @asset_type = record['assetType']
23
+ @asset_sub_type = record['assetSubType']
24
+ @last_modified_date = record['lastModifiedDate']
25
+
26
+ @links = {}
27
+
28
+ record['links'].each do |association|
29
+ @links[association['rel']] = uri_path(association['uri'])
30
+ end
31
+ end
32
+
33
+ ##
34
+ # locations associated with this asset
35
+
36
+ def locations
37
+ raise AccessTokenError unless accessor
38
+
39
+ return @locations if defined?(@locations)
40
+ @locations = MyJohnDeereApi::Request::Collection::AssetLocations.new(accessor, asset: id).all
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,27 @@
1
+ require 'json'
2
+
3
+ module MyJohnDeereApi
4
+ class Model::AssetLocation
5
+ include Helpers::UriHelpers
6
+
7
+ attr_reader :accessor, :timestamp, :geometry, :measurement_data, :links
8
+
9
+ ##
10
+ # arguments:
11
+ #
12
+ # [record] a JSON object of type 'Field', 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 *flags*.
17
+
18
+ def initialize(record, accessor = nil)
19
+ @accessor = accessor
20
+
21
+ @timestamp = record['timestamp']
22
+ @geometry = JSON.parse(record['geometry'])
23
+ @measurement_data = record['measurementData']
24
+ @links = {}
25
+ end
26
+ end
27
+ end
@@ -1,6 +1,6 @@
1
1
  module MyJohnDeereApi
2
2
  class Model::Field
3
- include Helpers::UriPath
3
+ include Helpers::UriHelpers
4
4
 
5
5
  attr_reader :name, :id, :links, :accessor
6
6
 
@@ -52,9 +52,7 @@ module MyJohnDeereApi
52
52
 
53
53
  def organization_id
54
54
  return @organization_id if defined?(@organization_id)
55
-
56
- parts = links['self'].split('/')
57
- @organization_id = parts[parts.index('organizations') + 1]
55
+ @organization_id = id_from_uri(links['self'], :organizations)
58
56
  end
59
57
  end
60
58
  end
@@ -3,7 +3,7 @@ require 'json'
3
3
  module MyJohnDeereApi
4
4
  class Model::Flag
5
5
  include Helpers::CaseConversion
6
- include Helpers::UriPath
6
+ include Helpers::UriHelpers
7
7
 
8
8
  attr_reader :id, :notes, :geometry, :links, :accessor
9
9
 
@@ -2,7 +2,7 @@ require 'uri'
2
2
 
3
3
  module MyJohnDeereApi
4
4
  class Model::Organization
5
- include Helpers::UriPath
5
+ include Helpers::UriHelpers
6
6
 
7
7
  attr_reader :name, :type, :id, :links, :accessor
8
8
 
@@ -47,5 +47,15 @@ module MyJohnDeereApi
47
47
  return @fields if defined?(@fields)
48
48
  @fields = MyJohnDeereApi::Request::Collection::Fields.new(accessor, organization: id).all
49
49
  end
50
+
51
+ ##
52
+ # assets associated with this organization
53
+
54
+ def assets
55
+ raise AccessTokenError unless accessor
56
+
57
+ return @assets if defined?(@assets)
58
+ @assets = MyJohnDeereApi::Request::Collection::Assets.new(accessor, organization: id).all
59
+ end
50
60
  end
51
61
  end
@@ -1,4 +1,6 @@
1
1
  module MyJohnDeereApi::Model
2
+ autoload :Asset, 'my_john_deere_api/model/asset'
3
+ autoload :AssetLocation, 'my_john_deere_api/model/asset_location'
2
4
  autoload :Organization, 'my_john_deere_api/model/organization'
3
5
  autoload :Field, 'my_john_deere_api/model/field'
4
6
  autoload :Flag, 'my_john_deere_api/model/flag'
@@ -0,0 +1,19 @@
1
+ require 'json'
2
+
3
+ module MyJohnDeereApi::Request
4
+ class Collection::AssetLocations < Collection::Base
5
+ ##
6
+ # The resource path for the first page in the collection
7
+
8
+ def resource
9
+ "/assets/#{associations[:asset]}/locations"
10
+ end
11
+
12
+ ##
13
+ # This is the class used to model the data
14
+
15
+ def model
16
+ MyJohnDeereApi::Model::AssetLocation
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'json'
2
+
3
+ module MyJohnDeereApi::Request
4
+ class Collection::Assets < Collection::Base
5
+ ##
6
+ # The resource path for the first page in the collection
7
+
8
+ def resource
9
+ "/organizations/#{associations[:organization]}/assets"
10
+ end
11
+
12
+ ##
13
+ # This is the class used to model the data
14
+
15
+ def model
16
+ MyJohnDeereApi::Model::Asset
17
+ end
18
+ end
19
+ end
@@ -1,7 +1,7 @@
1
1
  module MyJohnDeereApi
2
2
  class Request::Collection::Base
3
3
  include Enumerable
4
- include Helpers::UriPath
4
+ include Helpers::UriHelpers
5
5
 
6
6
  attr_reader :accessor, :associations
7
7
 
@@ -1,6 +1,8 @@
1
1
  module MyJohnDeereApi::Request::Collection
2
2
  autoload :Base, 'my_john_deere_api/request/collection/base'
3
+ autoload :Assets, 'my_john_deere_api/request/collection/assets'
4
+ autoload :AssetLocations, 'my_john_deere_api/request/collection/asset_locations'
3
5
  autoload :Organizations, 'my_john_deere_api/request/collection/organizations'
4
6
  autoload :Fields, 'my_john_deere_api/request/collection/fields'
5
- autoload :Flags, 'my_john_deere_api/request/collection/flags'
7
+ autoload :Flags, 'my_john_deere_api/request/collection/flags'
6
8
  end
@@ -1,3 +1,3 @@
1
1
  module MyJohnDeereApi
2
- VERSION='0.4.1'
2
+ VERSION='0.5.0'
3
3
  end
@@ -2,6 +2,10 @@ require 'support/helper'
2
2
 
3
3
  class CaseConversionHelperSample
4
4
  include JD::Helpers::CaseConversion
5
+
6
+ def test
7
+ 'test'
8
+ end
5
9
  end
6
10
 
7
11
  describe 'Helpers::CaseConversion' do
@@ -29,7 +33,8 @@ describe 'Helpers::CaseConversion' do
29
33
  end
30
34
 
31
35
  it 'is a private method' do
32
- assert_raises(NoMethodError) { object.underscore('test') }
36
+ exception = assert_raises(NoMethodError) { object.underscore('test') }
37
+ assert_includes exception.message, 'private method'
33
38
  end
34
39
  end
35
40
 
@@ -50,7 +55,12 @@ describe 'Helpers::CaseConversion' do
50
55
  end
51
56
 
52
57
  it 'is a private method' do
53
- assert_raises(NoMethodError) { object.camelize('test') }
58
+ exception = assert_raises(NoMethodError) { object.camelize('test') }
59
+ assert_includes exception.message, 'private method'
54
60
  end
55
61
  end
62
+
63
+ it "preserves the public nature of the including class's other methods" do
64
+ assert_equal 'test', object.test
65
+ end
56
66
  end
@@ -0,0 +1,58 @@
1
+ require 'support/helper'
2
+
3
+ class UriHelpersHelperSample
4
+ include JD::Helpers::UriHelpers
5
+
6
+ def test
7
+ 'test'
8
+ end
9
+ end
10
+
11
+ describe 'UriHelpers' do
12
+ let(:object) { UriHelpersHelperSample.new }
13
+
14
+ describe '#uri_path' do
15
+ it 'extracts the path from the uri' do
16
+ path = object.send(:uri_path, 'https://example.com/turtles')
17
+ assert_equal '/turtles', path
18
+ end
19
+
20
+ it 'removes leading /platform from the path' do
21
+ path = object.send(:uri_path, 'https://example.com/platform/turtles')
22
+ assert_equal '/turtles', path
23
+ end
24
+
25
+ it 'preserves /platform in any other part of the path' do
26
+ path = object.send(:uri_path, 'https://example.com/platform/turtles/platform')
27
+ assert_equal '/turtles/platform', path
28
+ end
29
+
30
+ it 'is a private method' do
31
+ exception = assert_raises(NoMethodError) { object.uri_path('https://example.com/turtles')}
32
+ assert_includes exception.message, 'private method'
33
+ end
34
+ end
35
+
36
+ describe '#id_from_uri(uri, label)' do
37
+ it 'extracts the id immediately following a given label' do
38
+ uri = 'https://example.com/cows/123/pigs/456/turtles/789/birds/012'
39
+ assert_equal '789', object.send(:id_from_uri, uri, 'turtles')
40
+ end
41
+
42
+ it 'accepts a symbol for the label' do
43
+ uri = 'https://example.com/cows/123/pigs/456/turtles/789/birds/012'
44
+ assert_equal '789', object.send(:id_from_uri, uri, :turtles)
45
+ end
46
+
47
+ it 'is a private method' do
48
+ uri = 'https://example.com/cows/123/pigs/456/turtles/789/birds/012'
49
+
50
+ exception = assert_raises(NoMethodError) { object.id_from_uri(uri, 'turtles') }
51
+ assert_includes exception.message, 'private method'
52
+ end
53
+ end
54
+
55
+ it "preserves the public nature of the including class's other methods" do
56
+ assert_equal 'test', object.test
57
+ end
58
+ end
@@ -2,8 +2,8 @@ require 'support/helper'
2
2
 
3
3
  describe 'MyJohnDeereApi::Helpers' do
4
4
  describe 'loading dependencies' do
5
- it 'loads Helpers::UriPath' do
6
- assert JD::Helpers::UriPath
5
+ it 'loads Helpers::UriHelpers' do
6
+ assert JD::Helpers::UriHelpers
7
7
  end
8
8
 
9
9
  it 'loads Helpers::CaseConversion' do
@@ -0,0 +1,57 @@
1
+ require 'support/helper'
2
+ require 'json'
3
+
4
+ describe 'MyJohnDeereApi::Model::AssetLocation' do
5
+ let(:record) do
6
+ {
7
+ "@type"=>"ContributedAssetLocation",
8
+ "timestamp"=>"2017-09-20T21:30:59.000Z",
9
+ "geometry"=>"{\"type\": \"Feature\",\"geometry\": {\"geometries\": [{\"coordinates\": [ -103.115633, 41.670166],\"type\": \"Point\"}],\"type\": \"GeometryCollection\"}}",
10
+ "measurementData"=>[
11
+ {
12
+ "@type"=>"BasicMeasurement",
13
+ "name"=>"[1 Foot](https://app.realmfive.com/map?device=0x0080CDEF)",
14
+ "value"=>"82",
15
+ "unit"=>"cB"
16
+ }, {
17
+ "@type"=>"BasicMeasurement",
18
+ "name"=>"[2 Feet](https://app.realmfive.com/map?device=0x0080CDEF)",
19
+ "value"=>"31",
20
+ "unit"=>"cB"
21
+ }
22
+ ],
23
+ "links"=>[]
24
+ }
25
+ end
26
+
27
+ let(:client) { JD::Client.new(API_KEY, API_SECRET, environment: :sandbox, access: [ACCESS_TOKEN, ACCESS_SECRET]) }
28
+ let(:accessor) { VCR.use_cassette('catalog') { client.send(:accessor) } }
29
+
30
+ describe '#initialize' do
31
+ def link_for label
32
+ record['links'].detect{|link| link['rel'] == label}['uri'].gsub('https://sandboxapi.deere.com/platform', '')
33
+ end
34
+
35
+ it 'sets the attributes from the given record' do
36
+ location = JD::Model::AssetLocation.new(record)
37
+
38
+ assert_nil location.accessor
39
+
40
+ # basic attributes
41
+ assert_equal record['timestamp'], location.timestamp
42
+ assert_equal JSON.parse(record['geometry']), location.geometry
43
+ assert_equal record['measurementData'], location.measurement_data
44
+
45
+ # links to other things
46
+ assert_kind_of Hash, location.links
47
+ assert_equal 0, location.links.size
48
+ end
49
+
50
+ it 'accepts an optional accessor' do
51
+ accessor = 'mock-accessor'
52
+
53
+ location = JD::Model::AssetLocation.new(record, accessor)
54
+ assert_equal accessor, location.accessor
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,79 @@
1
+ require 'support/helper'
2
+
3
+ describe 'MyJohnDeereApi::Model::Asset' do
4
+ let(:record) do
5
+ {
6
+ "@type"=>"ContributedAsset",
7
+ "title"=>"Happy Device",
8
+ "assetCategory"=>"DEVICE",
9
+ "assetType"=>"SENSOR",
10
+ "assetSubType"=>"OTHER",
11
+ "id"=>"123456",
12
+ "lastModifiedDate"=>"2018-01-31T20:36:16.727Z",
13
+ "links"=>[
14
+ {"@type"=>"Link", "rel"=>"self", "uri"=>"https://sandboxapi.deere.com/platform/assets/123456"},
15
+ {"@type"=>"Link", "rel"=>"organization", "uri"=>"https://sandboxapi.deere.com/platform/organizations/234567"},
16
+ {"@type"=>"Link", "rel"=>"locations", "uri"=>"https://sandboxapi.deere.com/platform/assets/123456/locations"},
17
+ ]
18
+ }
19
+ end
20
+
21
+ let(:client) { JD::Client.new(API_KEY, API_SECRET, environment: :sandbox, access: [ACCESS_TOKEN, ACCESS_SECRET]) }
22
+ let(:accessor) { VCR.use_cassette('catalog') { client.send(:accessor) } }
23
+
24
+ describe '#initialize' do
25
+ def link_for label
26
+ record['links'].detect{|link| link['rel'] == label}['uri'].gsub('https://sandboxapi.deere.com/platform', '')
27
+ end
28
+
29
+ it 'sets the attributes from the given record' do
30
+ asset = JD::Model::Asset.new(record)
31
+
32
+ assert_nil asset.accessor
33
+
34
+ # basic attributes
35
+ assert_equal record['id'], asset.id
36
+ assert_equal record['title'], asset.title
37
+ assert_equal record['assetCategory'], asset.asset_category
38
+ assert_equal record['assetType'], asset.asset_type
39
+ assert_equal record['assetSubType'], asset.asset_sub_type
40
+ assert_equal record['lastModifiedDate'], asset.last_modified_date
41
+
42
+ # links to other things
43
+ assert_kind_of Hash, asset.links
44
+
45
+ ['self', 'organization', 'locations'].each do |association|
46
+ assert_equal link_for(association), asset.links[association]
47
+ end
48
+ end
49
+
50
+ it 'accepts an optional accessor' do
51
+ accessor = 'mock-accessor'
52
+
53
+ asset = JD::Model::Asset.new(record, accessor)
54
+ assert_equal accessor, asset.accessor
55
+ end
56
+ end
57
+
58
+ describe '#locations' do
59
+ it 'returns a collection of locations for this asset' do
60
+ accessor
61
+ organization = VCR.use_cassette('get_organizations') { client.organizations.first }
62
+ asset = VCR.use_cassette('get_assets') { organization.assets.first }
63
+ locations = VCR.use_cassette('get_asset_locations') { asset.locations }
64
+
65
+ assert_kind_of Array, locations
66
+
67
+ locations.each do |location|
68
+ assert_kind_of JD::Model::AssetLocation, location
69
+ end
70
+ end
71
+
72
+ it 'raises an exception if an accessor is not available' do
73
+ asset = JD::Model::Asset.new(record)
74
+
75
+ exception = assert_raises(JD::AccessTokenError) { asset.locations }
76
+ assert_includes exception.message, 'Access Token must be supplied'
77
+ end
78
+ end
79
+ end
@@ -71,4 +71,11 @@ describe 'MyJohnDeereApi::Model::Field' do
71
71
  assert_includes exception.message, 'Access Token must be supplied'
72
72
  end
73
73
  end
74
+
75
+ describe 'private #organization_id' do
76
+ it "infers the organization_id from links" do
77
+ field = JD::Model::Field.new(record)
78
+ assert_equal '123456', field.send(:organization_id)
79
+ end
80
+ end
74
81
  end
@@ -83,4 +83,25 @@ describe 'MyJohnDeereApi::Model::Organization' do
83
83
  assert_includes exception.message, 'Access Token must be supplied'
84
84
  end
85
85
  end
86
+
87
+ describe '#assets' do
88
+ it 'returns a collection of assets for this organization' do
89
+ accessor
90
+ organization = VCR.use_cassette('get_organizations') { client.organizations.first }
91
+ assets = VCR.use_cassette('get_assets') { organization.assets }
92
+
93
+ assert_kind_of Array, assets
94
+
95
+ assets.each do |assets|
96
+ assert_kind_of JD::Model::Asset, assets
97
+ end
98
+ end
99
+
100
+ it 'raises an exception if an accessor is not available' do
101
+ organization = JD::Model::Organization.new(record)
102
+
103
+ exception = assert_raises(JD::AccessTokenError) { organization.assets }
104
+ assert_includes exception.message, 'Access Token must be supplied'
105
+ end
106
+ end
86
107
  end
@@ -2,6 +2,14 @@ require 'support/helper'
2
2
 
3
3
  describe 'MyJohnDeereApi::Model' do
4
4
  describe 'loading dependencies' do
5
+ it 'loads Model::Asset' do
6
+ assert JD::Model::Asset
7
+ end
8
+
9
+ it 'loads Model::AssetLocation' do
10
+ assert JD::Model::AssetLocation
11
+ end
12
+
5
13
  it 'loads Model::Organization' do
6
14
  assert JD::Model::Organization
7
15
  end
@@ -0,0 +1,85 @@
1
+ require 'support/helper'
2
+ require 'yaml'
3
+ require 'json'
4
+
5
+ describe 'MyJohnDeereApi::Request::Collection::AssetLocations' do
6
+ let(:asset_id) do
7
+ contents = File.read('test/support/vcr/get_assets.yml')
8
+ body = YAML.load(contents)['http_interactions'].first['response']['body']['string']
9
+ JSON.parse(body)['values'].first['id']
10
+ end
11
+
12
+ let(:client) { JD::Client.new(API_KEY, API_SECRET, environment: :sandbox, access: [ACCESS_TOKEN, ACCESS_SECRET]) }
13
+ let(:accessor) { VCR.use_cassette('catalog') { client.send(:accessor) } }
14
+ let(:collection) { JD::Request::Collection::AssetLocations.new(accessor, asset: asset_id) }
15
+
16
+ describe '#initialize(access_token)' do
17
+ it 'accepts an access token' do
18
+ assert_kind_of OAuth::AccessToken, collection.accessor
19
+ end
20
+
21
+ it 'accepts associations' do
22
+ collection = JD::Request::Collection::AssetLocations.new(accessor, asset: '123')
23
+
24
+ assert_kind_of Hash, collection.associations
25
+ assert_equal '123', collection.associations[:asset]
26
+ end
27
+ end
28
+
29
+ describe '#resource' do
30
+ it 'returns /assets/{asset_id}/locations' do
31
+ assert_equal "/assets/#{asset_id}/locations", collection.resource
32
+ end
33
+ end
34
+
35
+ describe '#all' do
36
+ it 'returns all records' do
37
+ all = VCR.use_cassette('get_asset_locations', record: :new_episodes) { collection.all }
38
+
39
+ assert_kind_of Array, all
40
+ assert_equal collection.count, all.size
41
+ assert all.size > 0
42
+
43
+ all.each do |item|
44
+ assert_kind_of JD::Model::AssetLocation, item
45
+ end
46
+ end
47
+ end
48
+
49
+ describe '#count' do
50
+ let(:server_response) do
51
+ contents = File.read('test/support/vcr/get_asset_locations.yml')
52
+ body = YAML.load(contents)['http_interactions'].first['response']['body']['string']
53
+ JSON.parse(body)
54
+ end
55
+
56
+ let(:server_count) { server_response['total'] }
57
+
58
+ it 'returns the total count of records in the collection' do
59
+ count = VCR.use_cassette('get_asset_locations') { collection.count }
60
+
61
+ assert_equal server_count, count
62
+ end
63
+ end
64
+
65
+ describe 'results' do
66
+ let(:location_timestamps) do
67
+ contents = File.read('test/support/vcr/get_asset_locations.yml')
68
+ body = YAML.load(contents)['http_interactions'].first['response']['body']['string']
69
+ JSON.parse(body)['values'].map{|v| v['timestamp']}
70
+ end
71
+
72
+ it 'returns all records as a single enumerator' do
73
+ count = VCR.use_cassette('get_asset_locations') { collection.count }
74
+ timestamps = VCR.use_cassette('get_asset_locations', record: :new_episodes) { collection.map(&:timestamp) }
75
+
76
+ assert_kind_of Array, timestamps
77
+ assert_equal count, timestamps.size
78
+ assert timestamps.size > 0
79
+
80
+ location_timestamps.each do |expected_timestamp|
81
+ assert_includes timestamps, expected_timestamp
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,83 @@
1
+ require 'support/helper'
2
+ require 'yaml'
3
+ require 'json'
4
+
5
+ describe 'MyJohnDeereApi::Request::Collection::Assets' 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(:client) { JD::Client.new(API_KEY, API_SECRET, environment: :sandbox, access: [ACCESS_TOKEN, ACCESS_SECRET]) }
13
+ let(:accessor) { VCR.use_cassette('catalog') { client.send(:accessor) } }
14
+ let(:collection) { JD::Request::Collection::Assets.new(accessor, organization: organization_id) }
15
+
16
+ describe '#initialize(access_token)' do
17
+ it 'accepts an access token' do
18
+ assert_kind_of OAuth::AccessToken, collection.accessor
19
+ end
20
+
21
+ it 'accepts associations' do
22
+ collection = JD::Request::Collection::Assets.new(accessor, organization: '123')
23
+
24
+ assert_kind_of Hash, collection.associations
25
+ assert_equal '123', collection.associations[:organization]
26
+ end
27
+ end
28
+
29
+ describe '#resource' do
30
+ it 'returns /organizations/{org_id}/assets' do
31
+ assert_equal "/organizations/#{organization_id}/assets", collection.resource
32
+ end
33
+ end
34
+
35
+ describe '#all' do
36
+ it 'returns all records' do
37
+ all = VCR.use_cassette('get_assets', record: :new_episodes) { collection.all }
38
+
39
+ assert_kind_of Array, all
40
+ assert_equal collection.count, all.size
41
+
42
+ all.each do |item|
43
+ assert_kind_of JD::Model::Asset, item
44
+ end
45
+ end
46
+ end
47
+
48
+ describe '#count' do
49
+ let(:server_response) do
50
+ contents = File.read('test/support/vcr/get_assets.yml')
51
+ body = YAML.load(contents)['http_interactions'].first['response']['body']['string']
52
+ JSON.parse(body)
53
+ end
54
+
55
+ let(:server_count) { server_response['total'] }
56
+
57
+ it 'returns the total count of records in the collection' do
58
+ count = VCR.use_cassette('get_assets') { collection.count }
59
+
60
+ assert_equal server_count, count
61
+ end
62
+ end
63
+
64
+ describe 'results' do
65
+ let(:asset_titles) do
66
+ contents = File.read('test/support/vcr/get_assets.yml')
67
+ body = YAML.load(contents)['http_interactions'].first['response']['body']['string']
68
+ JSON.parse(body)['values'].map{|v| v['title']}
69
+ end
70
+
71
+ it 'returns all records as a single enumerator' do
72
+ count = VCR.use_cassette('get_assets') { collection.count }
73
+ titles = VCR.use_cassette('get_assets', record: :new_episodes) { collection.map(&:title) }
74
+
75
+ assert_kind_of Array, titles
76
+ assert_equal count, titles.size
77
+
78
+ asset_titles.each do |expected_title|
79
+ assert_includes titles, expected_title
80
+ end
81
+ end
82
+ end
83
+ end
@@ -6,6 +6,14 @@ describe 'MyJohnDeereApi::Request::Collection' do
6
6
  assert JD::Request::Collection::Base
7
7
  end
8
8
 
9
+ it 'loads Request::Collection::Assets' do
10
+ assert JD::Request::Collection::Assets
11
+ end
12
+
13
+ it 'loads Request::Collection::AssetLocations' do
14
+ assert JD::Request::Collection::AssetLocations
15
+ end
16
+
9
17
  it 'loads Request::Collection::Organizations' do
10
18
  assert JD::Request::Collection::Organizations
11
19
  end
@@ -0,0 +1,55 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://sandboxapi.deere.com/platform/assets/029c288a-14d9-459f-8ee6-b4e840e672a1/locations
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="qTv5xV20gMbjd7IiRtg8xZlNfZHXX7Dmo1JrfP6xY1A", oauth_signature="exY2Q9m%2FlxXM%2BryRe6b9P7FmT1c%3D",
19
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1578698931", 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
+ - Fri, 10 Jan 2020 23:28:51 GMT
28
+ Content-Type:
29
+ - application/vnd.deere.axiom.v3+json;charset=UTF-8
30
+ X-Deere-Handling-Server:
31
+ - ip-10-214-44-15
32
+ X-Frame-Options:
33
+ - SAMEORIGIN
34
+ X-Deere-Elapsed-Ms:
35
+ - '58'
36
+ Cache-Control:
37
+ - no-store
38
+ Content-Language:
39
+ - en-US
40
+ Transfer-Encoding:
41
+ - chunked
42
+ body:
43
+ encoding: ASCII-8BIT
44
+ string: '{"links":[{"rel":"self","uri":"https://sandboxapi.deere.com/platform/assets/029c288a-14d9-459f-8ee6-b4e840e672a1/locations"}],"total":2,"values":[{"@type":"ContributedAssetLocation","timestamp":"2017-09-20T21:30:59.000Z","geometry":"{\"type\":
45
+ \"Feature\",\"geometry\": {\"geometries\": [{\"coordinates\": [ -103.115633,
46
+ 41.670166],\"type\": \"Point\"}],\"type\": \"GeometryCollection\"}}","measurementData":[{"@type":"BasicMeasurement","name":"[1
47
+ Foot](https://app.realmfive.com/map?device=0x0080CDEF)","value":"82","unit":"cB"},{"@type":"BasicMeasurement","name":"[2
48
+ Feet](https://app.realmfive.com/map?device=0x0080CDEF)","value":"31","unit":"cB"}],"links":[]},{"@type":"ContributedAssetLocation","timestamp":"2017-09-20T21:29:59.000Z","geometry":"{\"type\":
49
+ \"Feature\",\"geometry\": {\"geometries\": [{\"coordinates\": [ -103.115633,
50
+ 41.670166],\"type\": \"Point\"}],\"type\": \"GeometryCollection\"}}","measurementData":[{"@type":"BasicMeasurement","name":"[Moisture
51
+ - 1 Foot](https://app.realmfive.com/map?device=0x0080CDEF)","value":"82","unit":"cB"},{"@type":"BasicMeasurement","name":"[Moisture
52
+ - 2 Feet](https://app.realmfive.com/map?device=0x0080CDEF)","value":"31","unit":"cB"}],"links":[]}]}'
53
+ http_version:
54
+ recorded_at: Fri, 10 Jan 2020 23:28:52 GMT
55
+ recorded_with: VCR 5.0.0
@@ -0,0 +1,48 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://sandboxapi.deere.com/platform/organizations/444563/assets
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="6Q43mOlqL5POK9tW4g378nTYY2NzAPxtWCpE6ngfM", oauth_signature="ECsBHW1vv01ybBLwrHTne421c%2Bw%3D",
19
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1578694864", 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
+ - Fri, 10 Jan 2020 22:21:04 GMT
28
+ Content-Type:
29
+ - application/vnd.deere.axiom.v3+json;charset=UTF-8
30
+ X-Deere-Handling-Server:
31
+ - ip-10-214-44-225
32
+ X-Frame-Options:
33
+ - SAMEORIGIN
34
+ X-Deere-Elapsed-Ms:
35
+ - '32'
36
+ Cache-Control:
37
+ - no-store
38
+ Content-Language:
39
+ - en-US
40
+ Transfer-Encoding:
41
+ - chunked
42
+ body:
43
+ encoding: ASCII-8BIT
44
+ string: '{"links":[{"rel":"self","uri":"https://sandboxapi.deere.com/platform/organizations/444563/assets"}],"total":3,"values":[{"@type":"ContributedAsset","title":"Flex
45
+ (Watermark)","assetCategory":"DEVICE","assetType":"SENSOR","assetSubType":"ENVIRONMENTAL","lastModifiedDate":"2019-09-20T21:13:38.232Z","id":"029c288a-14d9-459f-8ee6-b4e840e672a1","links":[{"@type":"Link","rel":"self","uri":"https://sandboxapi.deere.com/platform/assets/029c288a-14d9-459f-8ee6-b4e840e672a1"},{"@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/029c288a-14d9-459f-8ee6-b4e840e672a1/locations"},{"@type":"Link","rel":"lastKnownLocation","uri":"https://sandboxapi.deere.com/platform/assets/029c288a-14d9-459f-8ee6-b4e840e672a1/locations?lastKnown=true"}]},{"@type":"ContributedAsset","title":"Pivot","assetCategory":"DEVICE","assetType":"SENSOR","assetSubType":"IRRIGATION_PIVOT","lastModifiedDate":"2019-09-20T21:14:13.931Z","id":"900b3657-0868-46b7-8322-70f204d44281","links":[{"@type":"Link","rel":"self","uri":"https://sandboxapi.deere.com/platform/assets/900b3657-0868-46b7-8322-70f204d44281"},{"@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/900b3657-0868-46b7-8322-70f204d44281/locations"},{"@type":"Link","rel":"lastKnownLocation","uri":"https://sandboxapi.deere.com/platform/assets/900b3657-0868-46b7-8322-70f204d44281/locations?lastKnown=true"}]},{"@type":"ContributedAsset","title":"Float","assetCategory":"DEVICE","assetType":"SENSOR","assetSubType":"ENVIRONMENTAL","lastModifiedDate":"2019-09-20T21:13:58.799Z","id":"da668043-a366-4dac-bfc9-3aeafe1175dd","links":[{"@type":"Link","rel":"self","uri":"https://sandboxapi.deere.com/platform/assets/da668043-a366-4dac-bfc9-3aeafe1175dd"},{"@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/da668043-a366-4dac-bfc9-3aeafe1175dd/locations"},{"@type":"Link","rel":"lastKnownLocation","uri":"https://sandboxapi.deere.com/platform/assets/da668043-a366-4dac-bfc9-3aeafe1175dd/locations?lastKnown=true"}]}]}'
46
+ http_version:
47
+ recorded_at: Fri, 10 Jan 2020 22:21:05 GMT
48
+ 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.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaime. Bellmyer
@@ -103,46 +103,56 @@ files:
103
103
  - lib/my_john_deere_api/errors/access_token_error.rb
104
104
  - lib/my_john_deere_api/helpers.rb
105
105
  - lib/my_john_deere_api/helpers/case_conversion.rb
106
- - lib/my_john_deere_api/helpers/uri_path.rb
106
+ - lib/my_john_deere_api/helpers/uri_helpers.rb
107
107
  - lib/my_john_deere_api/model.rb
108
+ - lib/my_john_deere_api/model/asset.rb
109
+ - lib/my_john_deere_api/model/asset_location.rb
108
110
  - lib/my_john_deere_api/model/field.rb
109
111
  - lib/my_john_deere_api/model/flag.rb
110
112
  - lib/my_john_deere_api/model/organization.rb
111
113
  - lib/my_john_deere_api/request.rb
112
114
  - lib/my_john_deere_api/request/collection.rb
115
+ - lib/my_john_deere_api/request/collection/asset_locations.rb
116
+ - lib/my_john_deere_api/request/collection/assets.rb
113
117
  - lib/my_john_deere_api/request/collection/base.rb
114
118
  - lib/my_john_deere_api/request/collection/fields.rb
115
119
  - lib/my_john_deere_api/request/collection/flags.rb
116
120
  - lib/my_john_deere_api/request/collection/organizations.rb
117
121
  - 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
120
- - test/lib/my_john_deere_api/helpers/test_uri_path.rb
121
- - test/lib/my_john_deere_api/model/test_field.rb
122
- - test/lib/my_john_deere_api/model/test_flag.rb
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
128
- - test/lib/my_john_deere_api/request/test_collection.rb
129
- - test/lib/my_john_deere_api/test_authorize.rb
130
- - test/lib/my_john_deere_api/test_client.rb
131
- - test/lib/my_john_deere_api/test_consumer.rb
132
- - test/lib/my_john_deere_api/test_errors.rb
133
- - test/lib/my_john_deere_api/test_helpers.rb
134
- - test/lib/my_john_deere_api/test_model.rb
135
- - test/lib/my_john_deere_api/test_request.rb
136
- - test/lib/my_john_deere_api/test_version.rb
122
+ - test/lib/my_john_deere_api/authorize_test.rb
123
+ - test/lib/my_john_deere_api/client_test.rb
124
+ - test/lib/my_john_deere_api/consumer_test.rb
125
+ - test/lib/my_john_deere_api/errors/access_token_error_test.rb
126
+ - test/lib/my_john_deere_api/errors_test.rb
127
+ - test/lib/my_john_deere_api/helpers/case_conversion_test.rb
128
+ - test/lib/my_john_deere_api/helpers/uri_helpers_test.rb
129
+ - test/lib/my_john_deere_api/helpers_test.rb
130
+ - test/lib/my_john_deere_api/model/asset_location_test.rb
131
+ - test/lib/my_john_deere_api/model/asset_test.rb
132
+ - test/lib/my_john_deere_api/model/field_test.rb
133
+ - test/lib/my_john_deere_api/model/flag_test.rb
134
+ - test/lib/my_john_deere_api/model/organization_test.rb
135
+ - test/lib/my_john_deere_api/model_test.rb
136
+ - test/lib/my_john_deere_api/request/collection/asset_locations_test.rb
137
+ - test/lib/my_john_deere_api/request/collection/assets_test.rb
138
+ - test/lib/my_john_deere_api/request/collection/base_test.rb
139
+ - test/lib/my_john_deere_api/request/collection/fields_test.rb
140
+ - test/lib/my_john_deere_api/request/collection/flags_test.rb
141
+ - test/lib/my_john_deere_api/request/collection/organizations_test.rb
142
+ - test/lib/my_john_deere_api/request/collection_test.rb
143
+ - test/lib/my_john_deere_api/request_test.rb
144
+ - test/lib/my_john_deere_api/version_test.rb
145
+ - test/my_john_deere_api_test.rb
137
146
  - test/support/helper.rb
138
147
  - test/support/vcr/app_consumer.yml
139
148
  - test/support/vcr/catalog.yml
140
149
  - test/support/vcr/get_access_token.yml
150
+ - test/support/vcr/get_asset_locations.yml
151
+ - test/support/vcr/get_assets.yml
141
152
  - test/support/vcr/get_fields.yml
142
153
  - test/support/vcr/get_flags.yml
143
154
  - test/support/vcr/get_organizations.yml
144
155
  - test/support/vcr/get_request_token.yml
145
- - test/test_my_john_deere_api.rb
146
156
  homepage: https://github.com/Intellifarm/my_john_deere_api
147
157
  licenses:
148
158
  - MIT
@@ -1,9 +0,0 @@
1
- require 'uri'
2
-
3
- module MyJohnDeereApi::Helpers::UriPath
4
- def uri_path(uri)
5
- URI.parse(uri).path.gsub(/^\/platform/, '')
6
- end
7
-
8
- private :uri_path
9
- end
@@ -1,28 +0,0 @@
1
- require 'support/helper'
2
-
3
- class UriPathHelperSample
4
- include JD::Helpers::UriPath
5
- end
6
-
7
- describe 'UriPath' do
8
- let(:object) { UriPathHelperSample.new }
9
-
10
- it 'extracts the path from the uri' do
11
- path = object.send(:uri_path, 'https://example.com/turtles')
12
- assert_equal '/turtles', path
13
- end
14
-
15
- it 'removes leading /platform from the path' do
16
- path = object.send(:uri_path, 'https://example.com/platform/turtles')
17
- assert_equal '/turtles', path
18
- end
19
-
20
- it 'preserves /platform in any other part of the path' do
21
- path = object.send(:uri_path, 'https://example.com/platform/turtles/platform')
22
- assert_equal '/turtles/platform', path
23
- end
24
-
25
- it 'is a private method' do
26
- assert_raises(NoMethodError) { object.uri_path('https://example.com/turtles')}
27
- end
28
- end