smartcar 0.1.1 → 1.0.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: 77763e723a789174f3bab09883c2c4770019d73f6984acc2a20ab5580b71683d
4
- data.tar.gz: 72ea1a37d4864c8f1e2251e15afcb8510ed07a910bdffe12abba2e6b17ff48fe
3
+ metadata.gz: 9d9a7ac2f2c91af854e62d5c52e799ac7948e2904a4997341847fd8845ffade3
4
+ data.tar.gz: 23557ce0dbd44d4df30eae96c1ad12557ebd4514e839e3ff59e16cbc120102e4
5
5
  SHA512:
6
- metadata.gz: c8ca779368dc98843d5e623b1faa52fda1503077b932727da4ac84fd6ce2d9b35670e15c82427ee4074ea821fc025a46158ac42d63e9441eb5af25d8a12d26ad
7
- data.tar.gz: 55c56eb58615e9ef19dfff70a8d25ec4cd61b3ac90152b63555ceb7218b15230a533302887d827b502d8b0b6f06dc3010412ae13d66e9d6757cd71aefcfaeaf7
6
+ metadata.gz: 4592facfcef32121f865d424bf57ac42e9954150d652f1b1183bea553df60f1d5e569e4bc2933cc5e188b26655f65fd1395e457ebad440a2bc5488d3b1a629d3
7
+ data.tar.gz: 0ca054815ce5849735181bf513ff52bd8df81bc2732e185281b2257dd6ec0a879222187f95cfea410e7113406ff62fda4a87835f05a2991f46931df1cc4bcd65
@@ -0,0 +1,2 @@
1
+ --markup=markdown
2
+ --no-private
@@ -1,41 +1,47 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- smartcar (0.1.1)
4
+ smartcar (1.0.0)
5
5
  oauth2 (~> 1.4)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- byebug (11.0.1)
10
+ byebug (11.1.3)
11
+ childprocess (3.0.0)
11
12
  diff-lcs (1.3)
12
- faraday (0.17.0)
13
+ faraday (1.0.1)
13
14
  multipart-post (>= 1.2, < 3)
14
15
  jwt (2.2.1)
15
16
  multi_json (1.14.1)
16
17
  multi_xml (0.6.0)
17
18
  multipart-post (2.1.1)
18
- oauth2 (1.4.2)
19
+ oauth2 (1.4.4)
19
20
  faraday (>= 0.8, < 2.0)
20
21
  jwt (>= 1.0, < 3.0)
21
22
  multi_json (~> 1.3)
22
23
  multi_xml (~> 0.5)
23
24
  rack (>= 1.2, < 3)
24
- rack (2.0.8)
25
- rake (13.0.1)
26
- rspec (3.8.0)
27
- rspec-core (~> 3.8.0)
28
- rspec-expectations (~> 3.8.0)
29
- rspec-mocks (~> 3.8.0)
30
- rspec-core (3.8.2)
31
- rspec-support (~> 3.8.0)
32
- rspec-expectations (3.8.4)
25
+ rack (2.2.2)
26
+ rake (12.3.3)
27
+ redcarpet (3.5.0)
28
+ rspec (3.9.0)
29
+ rspec-core (~> 3.9.0)
30
+ rspec-expectations (~> 3.9.0)
31
+ rspec-mocks (~> 3.9.0)
32
+ rspec-core (3.9.2)
33
+ rspec-support (~> 3.9.3)
34
+ rspec-expectations (3.9.2)
33
35
  diff-lcs (>= 1.2.0, < 2.0)
34
- rspec-support (~> 3.8.0)
35
- rspec-mocks (3.8.1)
36
+ rspec-support (~> 3.9.0)
37
+ rspec-mocks (3.9.1)
36
38
  diff-lcs (>= 1.2.0, < 2.0)
37
- rspec-support (~> 3.8.0)
38
- rspec-support (3.8.2)
39
+ rspec-support (~> 3.9.0)
40
+ rspec-support (3.9.3)
41
+ rubyzip (2.3.0)
42
+ selenium-webdriver (3.142.7)
43
+ childprocess (>= 0.5, < 4.0)
44
+ rubyzip (>= 1.2.2)
39
45
 
40
46
  PLATFORMS
41
47
  ruby
@@ -43,8 +49,10 @@ PLATFORMS
43
49
  DEPENDENCIES
44
50
  bundler (~> 2.0)
45
51
  byebug (~> 11.0)
46
- rake (>= 12.3.3)
52
+ rake (~> 12.3, >= 12.3.3)
53
+ redcarpet
47
54
  rspec (~> 3.0)
55
+ selenium-webdriver (~> 3.142)
48
56
  smartcar!
49
57
 
50
58
  BUNDLED WITH
data/README.md CHANGED
@@ -1,7 +1,57 @@
1
1
 
2
+ # Smartcar Ruby SDK [![Gem Version][gem-url]][gem-image]
2
3
 
3
4
  Ruby gem library to quickly get started with the Smartcar API.
4
5
 
6
+ ## Overview
7
+
8
+ The [Smartcar API](https://smartcar.com/docs) lets you read vehicle data
9
+ (location, odometer) and send commands to vehicles (lock, unlock) using HTTP requests.
10
+
11
+ To make requests to a vehicle from a web or mobile application, the end user
12
+ must connect their vehicle using
13
+ [Smartcar Connect](https://smartcar.com/docs/api#smartcar-connect).
14
+ This flow follows the OAuth spec and will return a `code` which can be used to
15
+ obtain an access token from Smartcar.
16
+
17
+ The Smartcar Ruby Gem provides methods to:
18
+
19
+ 1. Generate the link to redirect to Connect.
20
+ 2. Make a request to Smartcar with the `code` obtained from Connect to obtain an
21
+ access and refresh token
22
+ 3. Make requests to the Smartcar API to read vehicle data and send commands to
23
+ vehicles using the access token obtained in step 2.
24
+
25
+ Before integrating with Smartcar's SDK, you'll need to register an application
26
+ in the [Smartcar Developer portal](https://developer.smartcar.com). If you do
27
+ not have access to the dashboard, please
28
+ [request access](https://smartcar.com/subscribe).
29
+
30
+ ### Flow
31
+
32
+ - Create a new `AuthClient` object with your `clientId`, `clientSecret`,
33
+ `redirectUri`, and required `scope`.
34
+ - Redirect the user to Smartcar Connect using `getAuthUrl` or one
35
+ of our frontend SDKs.
36
+ - The user will login, and then accept or deny your `scope`'s permissions.
37
+ - Handle the get request to `redirectUri`.
38
+ - If the user accepted your permissions, `req.query.code` will contain an
39
+ authorization code.
40
+ - Use `exchangeCode` with this code to obtain an access object
41
+ containing an access token (lasting 2 hours) and a refresh token
42
+ (lasting 60 days).
43
+ - Save this access object.
44
+ - If the user denied your permissions, `req.query.error` will be set
45
+ to `"access_denied"`.
46
+ - If you passed a state parameter to `getAuthUrl`, `req.query.state` will
47
+ contain the state value.
48
+ - Get the user's vehicles with `getVehicleIds`.
49
+ - Create a new `Vehicle` object using a `vehicleId` from the previous response,
50
+ and the `access_token`.
51
+ - Make requests to the Smartcar API.
52
+ - Use `exchangeRefreshToken` on your saved `refreshToken` to retrieve a new token
53
+ when your `accessToken` expires.
54
+
5
55
  ## Installation
6
56
 
7
57
  Add this line to your application's Gemfile:
@@ -20,29 +70,38 @@ Or install it yourself as:
20
70
 
21
71
  ## Usage
22
72
 
23
- Setup the environment variables for CLIENT_ID and CLIENT_SECRET.
73
+ Setup the environment variables for CLIENT_ID and CLIENT_SECRET.
24
74
  ```bash
25
75
  # Get your API keys from https://dashboard.smartcar.com/signup
26
76
  export CLIENT_ID=<client id>
27
77
  export CLIENT_SECRET=<client secret>
28
- ```
78
+ ```
29
79
 
30
80
  Example Usage for calling the reports API with oAuth token
31
81
  ```ruby
32
- 2.5.5 :003 > require 'smartcar'
82
+ 2.5.7 :001 > require 'smartcar'
33
83
  => true
34
- 2.5.5 :009 > ids = Smartcar::Vehicle.all_vehicle_ids(token: token)
35
- => ["35e8a7c4-9e5c-4eb6-b552-7509e371669a", "c3332c35-fdeb-4780-a84b-706b7364979a", "d10ad5cf-5469-467e-972e-90427981873f", "fab5a744-6488-40d8-a6dd-41f0a804d44f"]
36
- 2.5.5 :010 > vehicle = Smartcar::Vehicle.new(token: token, id: ids.first)
37
- => #<Smartcar::Vehicle:0x00007fbad71aa2b8 @token="56801a5e-6a0b-4d05-a43e-52a4d5e6648f", @id="35e8a7c4-9e5c-4eb6-b552-7509e371669a", @unit_system="imperial">
38
- 2.5.5 :011 > vehicle.permissions
39
- => ["control_security", "read_battery", "read_charge", "read_location", "read_odometer", "read_vehicle_info", "read_vin"]
40
- 2.5.5 :012 > vehicle.odometer
41
- => #<Smartcar::Odometer:0x00007fbad718a3f0 @distance=74988.44443760936>
42
- 2.5.5 :013 > vehicle.battery
43
- => #<Smartcar::Battery:0x00007fbad50f4c80 @range=134.35, @percentRemaining=0.02>
44
- 2.5.5 :014 > vehicle.charge
45
- => #<Smartcar::Charge:0x00007fbad787e620 @state="FULLY_CHARGED", @isPluggedIn=true>
84
+ 2.5.7 :003 > ids = Smartcar::Vehicle.all_vehicle_ids(token: token)
85
+ => ["4bb777b2-bde7-4305-8952-25956f8c0868"]
86
+ 2.5.7 :004 > vehicle = Smartcar::Vehicle.new(token: token, id: ids.first)
87
+ => #<Smartcar::Vehicle:0x00005564211a7c48 @token="5ae77cb0-7c1a-486a-ac20-00c76d2fd1aa", @id="4bb777b2-bde7-4305-8952-25956f8c0868", @unit_system="imperial">
88
+ 2.5.7 :006 > vehicle.odometer
89
+ => #<Smartcar::Odometer:0x00005564211330f0 @distance=17966.94802354251, @meta={"date"=>"Fri, 12 Jun 2020 06:04:32 GMT", "content-type"=>"application/json; charset=utf-8", "content-length"=>"30", "connection"=>"keep-alive", "access-control-allow-origin"=>"*", "sc-data-age"=>"2020-06-12T06:04:28.843Z", "sc-unit-system"=>"imperial", "sc-request-id"=>"3c447e9e-4cf7-43cb-b688-fba8db3d3582"}>
90
+ 2.5.7 :007 > vehicle.battery
91
+ => #<Smartcar::Battery:0x00005564210fcb18 @range=105.63, @percentRemaining=0.98, @meta={"date"=>"Fri, 12 Jun 2020 06:04:44 GMT", "content-type"=>"application/json; charset=utf-8", "content-length"=>"40", "connection"=>"keep-alive", "access-control-allow-origin"=>"*", "sc-data-age"=>"2020-06-12T06:04:28.843Z", "sc-unit-system"=>"imperial", "sc-request-id"=>"455ed4b0-b768-4961-86d7-436ad71cf0fa"}>
92
+ 2.5.7 :009 > vehicle.lock!
93
+ => true
94
+ 2.5.7 :010 > vehicle.batch(["charge","battery"])
95
+ => {:charge=>#<Smartcar::Charge:0x000055853d1fd7c8 @state="NOT_CHARGING", @isPluggedIn=false, @meta={"sc-data-age"=>"2020-06-12T06:18:50.581Z"}>, :battery=>#<Smartcar::Battery:0x000055853d1fd638 @range=105.63, @percentRemaining=0.98, @meta={"sc-data-age"=>"2020-06-12T06:18:50.581Z", "sc-unit-system"=>"imperial"}>}
96
+ 2.5.7 :011 > vehicle.start_charge!
97
+ Traceback (most recent call last):
98
+ 5: from /usr/share/rvm/rubies/ruby-2.5.7/bin/irb:11:in `<main>'
99
+ 4: from (irb):5
100
+ 3: from /home/st-2vgpnn2/.rvm/gems/ruby-2.5.7/gems/smartcar-1.0.0/lib/smartcar/vehicle.rb:118:in `start_charge!'
101
+ 2: from /home/st-2vgpnn2/.rvm/gems/ruby-2.5.7/gems/smartcar-1.0.0/lib/smartcar/vehicle.rb:290:in `start_or_stop_charge!'
102
+ 1: from /home/st-2vgpnn2/.rvm/gems/ruby-2.5.7/gems/smartcar-1.0.0/lib/smartcar/base.rb:39:in `block (2 levels) in <class:Base>'
103
+ Smartcar::ExternalServiceError (API error - {"error":"vehicle_state_error","message":"Charging plug is not connected to the vehicle.","code":"VS_004"})
104
+
46
105
  ```
47
106
 
48
107
  Example Usage for oAuth -
@@ -73,3 +132,6 @@ To contribute, please:
73
132
  1. Open an issue for the feature (or bug) you would like to resolve.
74
133
  2. Resolve the issue and add tests in your feature branch.
75
134
  3. Open a PR from your feature branch into `develop` that tags the issue.
135
+
136
+ [gem-image]: https://badge.fury.io/rb/smartcar
137
+ [gem-url]: https://badge.fury.io/rb/smartcar.svg
@@ -15,22 +15,38 @@ require "smartcar/vehicle"
15
15
  require "smartcar/user"
16
16
 
17
17
 
18
- module Smartcar
18
+ # Main Smartcar umbrella module
19
+ module Smartcar
20
+ # Error raised when a config is not found
19
21
  class ConfigNotFound < StandardError; end
22
+ # Error raised when Smartcar returns non 400, 404, 401, 200 or 204 response
20
23
  class ExternalServiceError < StandardError; end
24
+ # Error raised when Smartcar returns 404
21
25
  class ServiceUnavailableError < ExternalServiceError; end
26
+ # Error raised when Smartcar returns Authentication Error with status 401
22
27
  class AuthenticationError < ExternalServiceError; end
23
- class ParserError < ExternalServiceError; end
28
+ # Error raised when Smartcar returns 400 response
24
29
  class BadRequestError < ExternalServiceError; end
30
+ # Smartcar API version being used
25
31
  API_VERSION = "v1.0".freeze
32
+ # Host to connect to smartcar
26
33
  SITE = "https://api.smartcar.com/".freeze
27
34
 
28
35
  # Path for smartcar oauth
29
36
  OAUTH_PATH = "https://connect.smartcar.com/oauth/authorize".freeze
30
37
  %w(success code test live force auto metric imperial).each do |constant|
38
+ # Constant to represent the value
31
39
  const_set(constant.upcase, constant.freeze)
32
40
  end
41
+
42
+ # Lock value sent in request body
33
43
  LOCK = "LOCK".freeze
44
+ # Unlock value sent in request body
34
45
  UNLOCK = "UNLOCK".freeze
46
+ # Start charge value sent in request body
47
+ START_CHARGE = "START".freeze
48
+ # Stop charge value sent in request body
49
+ STOP_CHARGE = "STOP".freeze
50
+ # Constant for units
35
51
  UNITS = [IMPERIAL,METRIC]
36
52
  end
@@ -3,21 +3,24 @@ require 'base64'
3
3
  module Smartcar
4
4
  # The Base class for all of the other class.
5
5
  # Let other classes inherit from here and put common methods here.
6
- #
7
- # @author [ashwin]
8
- #
9
6
  class Base
7
+ include Utils
8
+
9
+ # Error raised when an invalid parameter is passed.
10
10
  class InvalidParameterValue < StandardError; end
11
+ # Constant for Bearer auth type
11
12
  BEARER = 'BEARER'.freeze
13
+ # Constant for Basic auth type
12
14
  BASIC = 'BASIC'.freeze
13
15
 
14
- attr_accessor :token
15
- # meta programming and define all Restful methods.
16
- # @param path [String] the path to hit for the request.
17
- # @param token [String] the access token to be used.
18
- #
19
- # @return [Hash] The response Json parsed as a hash.
16
+ attr_accessor :token, :error, :meta
17
+
20
18
  %i{get post patch put delete}.each do |verb|
19
+ # meta programming and define all Restful methods.
20
+ # @param path [String] the path to hit for the request.
21
+ # @param data [Hash] request body if needed.
22
+ #
23
+ # @return [Hash] The response Json parsed as a hash.
21
24
  define_method verb do |path, data=nil|
22
25
  response = service.send(verb) do |request|
23
26
  request.headers['Authorization'] = "BEARER #{token}"
@@ -29,21 +32,19 @@ module Smartcar
29
32
  request.url complete_path, data
30
33
  else
31
34
  request.url complete_path
32
- request.body = data if data
35
+ request.body = data.to_json if data
33
36
  end
34
37
  end
35
- status = response.status
36
- raise ServiceUnavailableError.new, "Service Unavailable - #{response.body}" if status == 404
37
- raise BadRequestError.new, "Bad Request - #{response.body}" if status == 400
38
- raise AuthenticationError.new, "Authentication error" if status == 401
39
- raise ExternalServiceError.new, "API error - #{response.body}" unless [200,204].include?(status)
40
- JSON.parse(response.body)
38
+ error = get_error(response)
39
+ raise error if error
40
+ [JSON.parse(response.body), response.headers]
41
41
  end
42
42
  end
43
43
 
44
44
  # This requires a proc 'PATH' to be defined in the class
45
- # @param token [String] Access token
46
- # @param token [String] Vechicle ID
45
+ # @param path [String] resource path
46
+ # @param options [Hash] query params
47
+ # @param auth [String] type of auth
47
48
  #
48
49
  # @return [Object]
49
50
  def fetch(path: , options: {}, auth: 'BEARER')
@@ -58,15 +59,14 @@ module Smartcar
58
59
  #
59
60
  # @return [String] Base64 encoding of CLIENT:SECRET
60
61
  def get_basic_auth
61
- Base64.strict_encode64("#{ENV['CLIENT_ID']}:#{ENV['CLIENT_SECRET']}")
62
+ Base64.strict_encode64("#{get_config('CLIENT_ID')}:#{get_config('CLIENT_SECRET')}")
62
63
  end
63
64
 
64
65
  # gets a smartcar API service/client
65
- # @param token [String] Access token.
66
66
  #
67
67
  # @return [OAuth2::AccessToken] An initialized AccessToken instance that acts as service client
68
68
  def service
69
69
  @service ||= Faraday.new(url: SITE)
70
70
  end
71
71
  end
72
- end
72
+ end
@@ -1,12 +1,11 @@
1
1
  module Smartcar
2
- # class to represent battery info
3
- #
4
- # @author [ashwin]
5
- #
2
+ # class to represent Battery info
3
+ #@attr [Number] percentRemaining Decimal value representing the remaining charge percent.
4
+ #@attr [Number] range Remaining range of the vehicle.
6
5
  class Battery < Base
7
- include Utils
6
+ # Path Proc for hitting battery end point
8
7
  PATH = Proc.new{|id| "/vehicles/#{id}/battery"}
9
- attr_accessor :percentRemaining, :range
8
+ attr_reader :percentRemaining, :range
10
9
 
11
10
  # just to have Ruby-esque method names
12
11
  alias_method :percentage_remaining, :percentRemaining
@@ -1,12 +1,11 @@
1
1
  module Smartcar
2
2
  # class to represent Charge info
3
- #
4
- # @author [ashwin]
5
- #
3
+ #@attr [Boolean] isPluggedIn Specifies if the vehicle is plugged in.
4
+ #@attr [String] state Charging state of the vehicle.
6
5
  class Charge < Base
7
- include Utils
6
+ # Path Proc for hitting charge end point
8
7
  PATH = Proc.new{|id| "/vehicles/#{id}/charge"}
9
- attr_accessor :isPluggedIn, :state
8
+ attr_reader :isPluggedIn, :state
10
9
 
11
10
  # just to have Ruby-esque method names
12
11
  alias_method :is_plugged_in?, :isPluggedIn
@@ -1,12 +1,10 @@
1
1
  module Smartcar
2
- # class to represent Engine oil life
3
- #
4
- # @author [ashwin]
5
- #
2
+ # class to represent Engine oil info
3
+ #@attr [Number] lifeRemaining Remaining life of the engine oil
6
4
  class EngineOil < Base
7
- include Utils
5
+ # Path Proc for hitting engine oil end point
8
6
  PATH = Proc.new{|id| "/vehicles/#{id}/engine/oil"}
9
- attr_accessor :lifeRemaining
7
+ attr_reader :lifeRemaining
10
8
 
11
9
  # just to have Ruby-esque method names
12
10
  alias_method :life_remaining, :lifeRemaining
@@ -1,12 +1,12 @@
1
1
  module Smartcar
2
2
  # class to represent Fuel info
3
- #
4
- # @author [ashwin]
5
- #
3
+ #@attr [Number] amountRemaining Amount of fuel remaining.
4
+ #@attr [Number] percentageRemaining Decimal value representing the remaining fuel percent.
5
+ #@attr [Number] range Remaining range of the vehicle.
6
6
  class Fuel < Base
7
- include Utils
7
+ # Path Proc for hitting fuel end point
8
8
  PATH = Proc.new{|id| "/vehicles/#{id}/fuel"}
9
- attr_accessor :amountRemaining, :percentRemaining, :range
9
+ attr_reader :amountRemaining, :percentRemaining, :range
10
10
 
11
11
  # just to have Ruby-esque method names
12
12
  alias_method :amount_remaining, :amountRemaining
@@ -1,11 +1,10 @@
1
1
  module Smartcar
2
2
  # class to represent Location info
3
- #
4
- # @author [ashwin]
5
- #
3
+ #@attr [Number] latitude Latitude of last recorded location.
4
+ #@attr [Number] longitude Longitude of last recorded location.
6
5
  class Location < Base
7
- include Utils
6
+ # Path Proc for hitting location end point
8
7
  PATH = Proc.new{|id| "/vehicles/#{id}/location"}
9
- attr_accessor :latitude, :longitude
8
+ attr_reader :latitude, :longitude
10
9
  end
11
10
  end
@@ -1,9 +1,8 @@
1
1
  module Smartcar
2
2
  # Oauth class to take care of the Oauth 2.0 with genomelink APIs
3
3
  #
4
- # @author [ashwin]
5
- #
6
4
  class Oauth < Base
5
+ extend Utils
7
6
  class << self
8
7
  # Generate the OAuth authorization URL.
9
8
  #
@@ -13,19 +12,19 @@ module Smartcar
13
12
  # approval_prompt to `force`.
14
13
  #
15
14
  # @param options [Hash]
16
- # @param options[:state] [String] - OAuth state parameter passed to the
15
+ # @option options[:state] [String] - OAuth state parameter passed to the
17
16
  # redirect uri. This parameter may be used for identifying the user who
18
17
  # initiated the request.
19
- # @param options[:test_mode] [Boolean] - Setting this to 'true' runs it in test mode.
20
- # @param options[:force_prompt] [Boolean] - Setting `force_prompt` to
18
+ # @option options[:test_mode] [Boolean] - Setting this to 'true' runs it in test mode.
19
+ # @option options[:force_prompt] [Boolean] - Setting `force_prompt` to
21
20
  # `true` will show the permissions approval screen on every authentication
22
21
  # attempt, even if the user has previously consented to the exact scope of
23
22
  # permissions.
24
- # @param options[:make] [String] - `make' is an optional parameter that allows
23
+ # @option options[:make] [String] - `make' is an optional parameter that allows
25
24
  # users to bypass the car brand selection screen.
26
25
  # For a complete list of supported makes, please see our
27
26
  # [API Reference](https://smartcar.com/docs/api#authorization) documentation.
28
- # @param options[:scope] [Array of Strings] - array of scopes that specify what the user can access
27
+ # @option options[:scope] [Array of Strings] - array of scopes that specify what the user can access
29
28
  # EXAMPLE : ['read_odometer', 'read_vehicle_info', 'required:read_location']
30
29
  # For further details refer to https://smartcar.com/docs/guides/scope/
31
30
  #
@@ -41,12 +40,12 @@ module Smartcar
41
40
  %I(state make).each do |parameter|
42
41
  parameters[:parameter] = options[:parameter] unless options[:parameter].nil?
43
42
  end
44
-
43
+
45
44
  client.auth_code.authorize_url(parameters)
46
45
  end
47
46
 
48
47
  # [get_token description]
49
- # @param auth_code [String] This is the code that is returned after use
48
+ # @param auth_code [String] This is the code that is returned after use r
50
49
  # visits and authorizes on the authorization URL.
51
50
  #
52
51
  # @return [Hash] Hash of token, refresh token, expiry info and token type
@@ -79,15 +78,6 @@ module Smartcar
79
78
  :site => OAUTH_PATH
80
79
  )
81
80
  end
82
-
83
- # gets a given env variable, checks for existence and throws exception if not present
84
- # @param config_name [String] key of the env variable
85
- #
86
- # @return [String] value of the env variable
87
- def get_config(config_name)
88
- raise ConfigNotFound, "Environment variable #{config_name} not found !" unless ENV[config_name]
89
- ENV[config_name]
90
- end
91
81
  end
92
82
  end
93
83
  end
@@ -1,11 +1,9 @@
1
1
  module Smartcar
2
- # class to get Charge info
3
- #
4
- # @author [ashwin]
5
- #
2
+ # class to represent Odometer
3
+ #@attr [Number] distanceLast recorded odometer reading.
6
4
  class Odometer < Base
7
- include Utils
5
+ # Path Proc for hitting odometer end point
8
6
  PATH = Proc.new{|id| "/vehicles/#{id}/odometer"}
9
- attr_accessor :distance
7
+ attr_reader :distance
10
8
  end
11
9
  end
@@ -1,11 +1,9 @@
1
1
  module Smartcar
2
- # class to get Charge info
3
- #
4
- # @author [ashwin]
5
- #
6
- class Permissions
7
- include Utils
2
+ # class to represent permissions response
3
+ #@attr [Array] permissions Array of permissions granted on the vehicle.
4
+ class Permissions < Base
5
+ # Path Proc for hitting permissions end point
8
6
  PATH = Proc.new{|id| "/vehicles/#{id}/permissions"}
9
- attr_accessor :permissions
7
+ attr_reader :permissions
10
8
  end
11
9
  end
@@ -1,12 +1,14 @@
1
1
  module Smartcar
2
- # class to represent Engine oil life
3
- #
4
- # @author [ashwin]
5
- #
2
+ # class to represent Tire Pressure response
3
+ #@attr [Number] back_left Last recorded tire pressure of the back left tire.
4
+ #@attr [Number] back_right Last recorded tire pressure of the back right tire.
5
+ #@attr [Number] front_left Last recorded tire pressure of the front left tire.
6
+ #@attr [Number] front_right Last recorded tire pressure of the front right tire.
7
+
6
8
  class TirePressure < Base
7
- include Utils
9
+ # Path Proc for hitting tire pressure end point
8
10
  PATH = Proc.new{|id| "/vehicles/#{id}/tires/pressure"}
9
- attr_accessor :backLeft, :backRight, :frontLeft, :frontRight
11
+ attr_reader :backLeft, :backRight, :frontLeft, :frontRight
10
12
 
11
13
  # just to have Ruby-esque method names
12
14
  alias_method :back_left, :backLeft
@@ -1,11 +1,11 @@
1
1
  module Smartcar
2
2
  # Class to get to user API.
3
- #
4
- # @author [ashwin]
5
- #
3
+ #@attr [String] id Smartcar user id.
4
+ #@attr [String] token Access token used to connect to Smartcar API.
6
5
  class User < Base
6
+ # Path for hitting user end point
7
7
  USER_PATH = '/user'.freeze
8
- attr_accessor :id, :token
8
+ attr_reader :id, :token
9
9
 
10
10
  def initialize(token:)
11
11
  raise InvalidParameterValue.new, "Access Token(token) is a required field" if token.nil?
@@ -21,6 +21,6 @@ module Smartcar
21
21
  def self.user_id(token:)
22
22
  new(token: token).get(USER_PATH)['id']
23
23
  end
24
-
24
+
25
25
  end
26
26
  end
@@ -1,11 +1,35 @@
1
- module Utils
2
- # A constructor to take a hash and assign it to the instance variables
3
- # @param options = {} [Hash] Could by any class's hash, but the first level keys should be defined in the class
4
- #
5
- # @return [Subclass os Base] Returns object of any subclass like Report
6
- def initialize(options = {})
7
- options.each do |attribute, value|
8
- instance_variable_set("@#{attribute}", value)
9
- end
1
+ # Utils module , provides utility methods to underlying classes
2
+ module Utils
3
+ # A constructor to take a hash and assign it to the instance variables
4
+ # @param options = {} [Hash] Could by any class's hash, but the first level keys should be defined in the class
5
+ #
6
+ # @return [Subclass os Base] Returns object of any subclass like Report
7
+ def initialize(options = {})
8
+ options.each do |attribute, value|
9
+ instance_variable_set("@#{attribute}", value)
10
10
  end
11
- end
11
+ end
12
+
13
+ # gets a given env variable, checks for existence and throws exception if not present
14
+ # @param config_name [String] key of the env variable
15
+ #
16
+ # @return [String] value of the env variable
17
+ def get_config(config_name)
18
+ config_name = "INTEGRATION_#{config_name}" if ENV['MODE'] == 'test'
19
+ raise Smartcar::ConfigNotFound, "Environment variable #{config_name} not found !" unless ENV[config_name]
20
+ ENV[config_name]
21
+ end
22
+
23
+ # Given the response from smartcar API, returns an error object if needed
24
+ # @param response [Object] response Object with status and body
25
+ #
26
+ # @return [Object] nil OR Error object
27
+ def get_error(response)
28
+ status = response.status
29
+ return nil if [200,204].include?(status)
30
+ return Smartcar::ServiceUnavailableError.new("Service Unavailable - #{response.body}") if status == 404
31
+ return Smartcar::BadRequestError.new("Bad Request - #{response.body}") if status == 400
32
+ return Smartcar::AuthenticationError.new("Authentication error") if status == 401
33
+ return Smartcar::ExternalServiceError.new("API error - #{response.body}")
34
+ end
35
+ end
@@ -4,14 +4,21 @@ module Smartcar
4
4
  # For Ex. Vehicle object will be treate as an entity and doing vehicle_object.
5
5
  # Battery should return Battery object.
6
6
  #
7
- # @author [ashwin]
8
- #
7
+ #@attr [String] token Access token used to connect to Smartcar API.
8
+ #@attr [String] id Smartcar vehicle ID.
9
+ #@attr [String] unit_system unit system to represent the data in.
9
10
  class Vehicle < Base
11
+ include Utils
12
+
10
13
 
14
+ # Path for hitting compatibility end point
11
15
  COMPATIBLITY_PATH = '/compatibility'.freeze
16
+
17
+ # Path for hitting vehicle ids end point
12
18
  PATH = Proc.new{|id| "/vehicles/#{id}"}
13
- attr_accessor :token, :id, :unit_system
14
19
 
20
+ attr_reader :id
21
+ attr_accessor :token, :unit_system
15
22
 
16
23
  def initialize(token:, id:, unit_system: IMPERIAL)
17
24
  raise InvalidParameterValue.new, "Invalid Units provided : #{unit_system}" unless UNITS.include?(unit_system)
@@ -22,13 +29,6 @@ module Smartcar
22
29
  @unit_system = unit_system
23
30
  end
24
31
 
25
- # Accessor method for vehicle attributes.
26
- %I(make model year).each do |method_name|
27
- define_method method_name do
28
- vehicle_attributes.send(method_name)
29
- end
30
- end
31
-
32
32
  # Class method Used to get all the vehicles in the app. This only returns
33
33
  # API - https://smartcar.com/docs/api#get-all-vehicles
34
34
  # @param token [String] - Access token
@@ -36,10 +36,11 @@ module Smartcar
36
36
  #
37
37
  # @return [Array] of vehicle IDs(Strings)
38
38
  def self.all_vehicle_ids(token:, options: {})
39
- new(token: token, id: 'none').fetch(
39
+ response, meta = new(token: token, id: 'none').fetch(
40
40
  path: PATH.call(''),
41
41
  options: options
42
- )['vehicles']
42
+ )
43
+ response['vehicles']
43
44
  end
44
45
 
45
46
  # Class method Used to check compatiblity for VIN and scope
@@ -52,13 +53,26 @@ module Smartcar
52
53
  raise InvalidParameterValue.new, "vin is a required field" if vin.nil?
53
54
  raise InvalidParameterValue.new, "scope is a required field" if scope.nil?
54
55
 
55
- new(token: 'none', id: 'none').fetch(path: COMPATIBLITY_PATH,
56
+ response, meta = new(token: 'none', id: 'none').fetch(path: COMPATIBLITY_PATH,
56
57
  options: {
57
58
  vin: vin,
58
59
  scope: scope.join(' ')
59
60
  },
60
61
  auth: BASIC
61
- )['compatible']
62
+ )
63
+ response['compatible']
64
+ end
65
+
66
+ # Method to get batch requests
67
+ # API - https://smartcar.com/docs/api#post-batch-request
68
+ # @param attributes [Array] Array of strings or symbols of attributes to be fetched together
69
+ #
70
+ # @return [Hash] Hash wth key as requested attribute(symbol) and value as Error OR Object of the requested attribute
71
+ def batch(attributes = [])
72
+ raise InvalidParameterValue.new, "vin is a required field" if attributes.nil?
73
+ request_body = get_batch_request_body(attributes)
74
+ response, _meta = post(PATH.call(id) + "/batch", request_body)
75
+ process_batch_response(response)
62
76
  end
63
77
 
64
78
  # Fetch the list of permissions that this application has been granted for
@@ -68,10 +82,7 @@ module Smartcar
68
82
  #
69
83
  # @return [Array] of permissions (Strings)
70
84
  def permissions(options: {})
71
- Permissions.new(fetch(
72
- path: Permissions::PATH.call(id),
73
- options: options
74
- )).permissions
85
+ get_attribute(Permissions)
75
86
  end
76
87
 
77
88
  # Method Used toRevoke access for the current requesting application
@@ -83,104 +94,201 @@ module Smartcar
83
94
  response['status'] == SUCCESS
84
95
  end
85
96
 
86
- # Methods Used lock or unlock car
97
+ # Methods Used to lock car
87
98
  # API - https://smartcar.com/docs/api#post-security
88
99
  #
89
100
  # @return [Boolean] true if success
90
- %w(lock unlock).each do |method_name|
91
- define_method "#{method_name}!" do
92
- lock_or_unlock!(action: Smartcar.const_get(method_name.upcase))
93
- end
101
+ def lock!
102
+ lock_or_unlock!(action: Smartcar::LOCK)
94
103
  end
95
104
 
96
- # Following section defined methods using meta programing to fetch various
97
- # details of a vehicle. The key is the method name, and value is Class that
98
- # wraps the data.
99
- {
100
- # Returns the state of charge (SOC) and remaining range of an electric or
101
- # plug-in hybrid vehicle's battery.
102
- # API - https://smartcar.com/docs/api#get-ev-battery
103
- #
104
- # @return [Battery] object
105
- battery: Battery,
106
- # Returns the current charge status of the vehicle.
107
- # API - https://smartcar.com/docs/api#get-ev-battery
108
- #
109
- # @return [Charge] object
110
- charge: Charge,
111
- # Returns the remaining life span of a vehicle's engine oil
112
- # API - https://smartcar.com/docs/api#get-engine-oil-life
113
- #
114
- # @return [EngineOil] object
115
- engine_oil: EngineOil,
116
- # Returns the status of the fuel remaining in the vehicle's gas tank.
117
- # API - https://smartcar.com/docs/api#get-fuel-tank
118
- #
119
- # @return [Fuel] object
120
- fuel: Fuel,
121
- # Returns the last known location of the vehicle in geographic coordinates.
122
- # API - https://smartcar.com/docs/api#get-location
123
- #
124
- # @return [Location] object
125
- location: Location,
126
- # Returns the vehicle's last known odometer reading.
127
- # API - https://smartcar.com/docs/api#get-odometer
128
- #
129
- # @return [Odometer] object
130
- odometer: Odometer,
131
- # Returns the air pressure of each of the vehicle's tires.
132
- # API - https://smartcar.com/docs/api#get-tire-pressure
133
- #
134
- # @return [TirePressure] object
135
- tire_pressure: TirePressure,
136
- }.each do |method_name, klass|
137
- define_method method_name do
138
- klass.new(
139
- fetch(
140
- path: klass::PATH.call(id)
141
- )
142
- )
143
- end
105
+ # Methods Used to unlock car
106
+ # API - https://smartcar.com/docs/api#post-security
107
+ #
108
+ # @return [Boolean] true if success
109
+ def unlock!
110
+ lock_or_unlock!(action: Smartcar::UNLOCK)
144
111
  end
145
112
 
146
- #NOTE : The following two also could be defined by metaprogramming,
147
- # But these are items that dont change and hence can be cached in the
148
- # vehicle object.
113
+ # Method used to start charging a car
114
+ #
115
+ #
116
+ # @return [Boolean] true if success
117
+ def start_charge!
118
+ start_or_stop_charge!(action: Smartcar::START_CHARGE)
119
+ end
149
120
 
150
- # Returns the vehicle's manufacturer identifier.
151
- # API - https://smartcar.com/docs/api#get-vin
121
+ # Method used to stop charging a car
152
122
  #
153
- # @return [Vin] object
154
- def vin
155
- @vin ||= Vin.new(
156
- fetch(
157
- path: Vin::PATH.call(id)
158
- )
159
- ).vin
123
+ #
124
+ # @return [Boolean] true if success
125
+ def stop_charge!
126
+ start_or_stop_charge!(action: Smartcar::STOP_CHARGE)
160
127
  end
161
128
 
162
- # Returns the vehicle's model make and year.
163
- # API - https://smartcar.com/docs/api#get-vehicle-attributes
129
+ # Returns make model year and id of the vehicle
130
+ # API - https://smartcar.com/api#get-vehicle-attributes
164
131
  #
165
132
  # @return [VehicleAttributes] object
166
133
  def vehicle_attributes
167
- @vehicle_attributes ||= VehicleAttributes.new(
168
- fetch(
169
- path: PATH.call(id)
170
- )
171
- )
134
+ get_attribute(VehicleAttributes)
135
+ end
136
+
137
+ # Returns the state of charge (SOC) and remaining range of an electric or
138
+ # plug-in hybrid vehicle's battery.
139
+ # API - https://smartcar.com/docs/api#get-ev-battery
140
+ #
141
+ # @return [Battery] object
142
+ def battery
143
+ get_attribute(Battery)
144
+ end
145
+
146
+ # Returns the current charge status of the vehicle.
147
+ # API - https://smartcar.com/docs/api#get-ev-battery
148
+ #
149
+ # @return [Charge] object
150
+ def charge
151
+ get_attribute(Charge)
152
+ end
153
+
154
+ # Returns the remaining life span of a vehicle's engine oil
155
+ # API - https://smartcar.com/docs/api#get-engine-oil-life
156
+ #
157
+ # @return [EngineOil] object
158
+ def engine_oil
159
+ get_attribute(EngineOil)
160
+ end
161
+
162
+ # Returns the status of the fuel remaining in the vehicle's gas tank.
163
+ # API - https://smartcar.com/docs/api#get-fuel-tank
164
+ #
165
+ # @return [Fuel] object
166
+ def fuel
167
+ get_attribute(Fuel)
168
+ end
169
+
170
+ # Returns the last known location of the vehicle in geographic coordinates.
171
+ # API - https://smartcar.com/docs/api#get-location
172
+ #
173
+ # @return [Location] object
174
+ def location
175
+ get_attribute(Location)
176
+ end
177
+
178
+ # Returns the vehicle's last known odometer reading.
179
+ # API - https://smartcar.com/docs/api#get-odometer
180
+ #
181
+ # @return [Odometer] object
182
+ def odometer
183
+ get_attribute(Odometer)
184
+ end
185
+
186
+ # Returns the air pressure of each of the vehicle's tires.
187
+ # API - https://smartcar.com/docs/api#get-tire-pressure
188
+ #
189
+ # @return [TirePressure] object
190
+ def tire_pressure
191
+ get_attribute(TirePressure)
192
+ end
193
+
194
+ # Returns the vehicle's manufacturer identifier (VIN).
195
+ # API - https://smartcar.com/docs/api#get-vin
196
+ #
197
+ # @return [String] Vin of the vehicle.
198
+ def vin
199
+ _object = get_attribute(Vin)
200
+ @vin ||= _object.vin
172
201
  end
173
202
 
174
203
  private
175
204
 
205
+ def allowed_attributes
206
+ @allowed_attributes ||= {
207
+ battery: get_path(Battery),
208
+ charge: get_path(Charge),
209
+ engine_oil: get_path(EngineOil),
210
+ fuel: get_path(Fuel),
211
+ location: get_path(Location),
212
+ odometer: get_path(Odometer),
213
+ permissions: get_path(Permissions),
214
+ tire_pressure: get_path(TirePressure),
215
+ vin: get_path(Vin),
216
+ }
217
+ end
218
+
219
+ def path_to_class
220
+ @path_to_class ||= {
221
+ get_path(Battery) => Battery,
222
+ get_path(Charge) => Charge,
223
+ get_path(EngineOil) => EngineOil,
224
+ get_path(Fuel) => Fuel,
225
+ get_path(Location) => Location,
226
+ get_path(Odometer) => Odometer,
227
+ get_path(Permissions) => Permissions,
228
+ get_path(TirePressure) => TirePressure,
229
+ get_path(Vin) => Vin,
230
+ }
231
+ end
232
+
233
+ # @private
234
+ BatchItemResponse = Struct.new(:body, :status, :headers) do
235
+ def body_with_meta
236
+ body.merge(meta: headers)
237
+ end
238
+ end
239
+
240
+ def get_batch_request_body(attributes)
241
+ attributes = validated_attributes(attributes)
242
+ requests = attributes.each_with_object([]) do |item, requests|
243
+ requests << { path: allowed_attributes[item] }
244
+ end
245
+ { requests: requests }
246
+ end
247
+
248
+ def process_batch_response(responses)
249
+ inverted_map = allowed_attributes.invert
250
+ responses["responses"].each_with_object({}) do |response, result|
251
+ item_response = BatchItemResponse.new(response["body"], response["code"], response["headers"])
252
+ error = get_error(item_response)
253
+ path = response["path"]
254
+ result[inverted_map[path]] = error || get_object(path_to_class[path], item_response.body_with_meta)
255
+ end
256
+ end
257
+
258
+ def validated_attributes(attributes)
259
+ attributes.map!(&:to_sym)
260
+ unsupported_attributes = (attributes - allowed_attributes.keys) || []
261
+ unless unsupported_attributes.empty?
262
+ message = "Unsupported attribute(s) requested in batch - #{unsupported_attributes.join(',')}"
263
+ raise InvalidParameterValue.new, message
264
+ end
265
+ attributes
266
+ end
267
+
268
+ def get_attribute(klass)
269
+ body, meta = fetch(
270
+ path: klass::PATH.call(id)
271
+ )
272
+ get_object(klass, body.merge(meta: meta))
273
+ end
274
+
275
+ def get_object(klass, data)
276
+ klass.new(data)
277
+ end
278
+
279
+ def get_path(klass)
280
+ path = klass::PATH.call(id)
281
+ path.split("/vehicles/#{id}").last
282
+ end
283
+
176
284
  def lock_or_unlock!(action:)
177
- response = post(PATH.call(id) + "/security", {action: action}.to_json)
285
+ response, meta = post(PATH.call(id) + "/security", { action: action })
178
286
  response['status'] == SUCCESS
179
287
  end
180
288
 
181
- class VehicleAttributes
182
- include Utils
183
- attr_accessor :id, :make, :model, :year
289
+ def start_or_stop_charge!(action:)
290
+ response, meta = post(PATH.call(id) + "/charge", { action: action })
291
+ response['status'] == SUCCESS
184
292
  end
185
293
  end
186
294
  end
@@ -0,0 +1,12 @@
1
+ module Smartcar
2
+ # class to represent Vehicle attributes like make model year
3
+ #@attr [String] id Smartcar vehicle ID
4
+ #@attr [String] make Manufacturer of the vehicle.
5
+ #@attr [String] model Model of the vehicle.
6
+ #@attr [Number] year Model year of the vehicle.
7
+ class VehicleAttributes < Base
8
+ # Path Proc for hitting vehicle attributes end point
9
+ PATH = Proc.new{|id| "/vehicles/#{id}"}
10
+ attr_accessor :id, :make, :model, :year
11
+ end
12
+ end
@@ -1,3 +1,4 @@
1
1
  module Smartcar
2
- VERSION = "0.1.1"
2
+ # Gem current version number
3
+ VERSION = "1.0.0"
3
4
  end
@@ -1,11 +1,10 @@
1
1
  module Smartcar
2
- # class to represent Engine oil life
3
- #
4
- # @author [ashwin]
2
+ # Hidden class to represent vin
5
3
  #
4
+ #@attr [String] vin Vin of the vehicle
6
5
  class Vin < Base
7
- include Utils
6
+ # Path Proc for hitting vin end point
8
7
  PATH = Proc.new{|id| "/vehicles/#{id}/vin"}
9
- attr_accessor :vin
8
+ attr_reader :vin
10
9
  end
11
10
  end
@@ -3,24 +3,27 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
  require "smartcar/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = "smartcar"
7
- spec.version = Smartcar::VERSION
8
- spec.authors = ["Ashwin Subramanian"]
9
- spec.email = ["sshwin.subramanian@smartcar.com"]
10
- spec.homepage = 'https://rubygems.org/gems/smartcar'
11
- spec.summary = %q{Ruby Gem to access smartcar APIs (https://smartcar.com/docs/)}
12
- spec.description = %q{This is a ruby gem to access the smartcar APIs. It includes the API classes and the OAuth system.}
13
- spec.license = "MIT"
14
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
6
+ spec.name = "smartcar"
7
+ spec.version = Smartcar::VERSION
8
+ spec.required_ruby_version = ">= 2.5.0"
9
+ spec.authors = ["Ashwin Subramanian"]
10
+ spec.email = ["ashwin.subramanian@smartcar.com"]
11
+ spec.homepage = 'https://rubygems.org/gems/smartcar'
12
+ spec.summary = %q{Ruby Gem to access smartcar APIs (https://smartcar.com/docs/)}
13
+ spec.description = %q{This is a ruby gem to access the smartcar APIs. It includes the API classes and the OAuth system.}
14
+ spec.license = "MIT"
15
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
15
16
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
17
  end
17
- spec.bindir = "exe"
18
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
20
  spec.require_paths = ["lib"]
20
21
 
21
22
  spec.add_development_dependency "bundler", "~> 2.0"
22
23
  spec.add_development_dependency 'rake', '~> 12.3', '>= 12.3.3'
23
24
  spec.add_development_dependency "rspec", "~> 3.0"
24
25
  spec.add_development_dependency "byebug", "~> 11.0"
26
+ spec.add_development_dependency "redcarpet", "~> 3.5.0"
27
+ spec.add_development_dependency "selenium-webdriver", "~> 3.142"
25
28
  spec.add_dependency "oauth2", "~> 1.4"
26
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smartcar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ashwin Subramanian
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-04-12 00:00:00.000000000 Z
11
+ date: 2020-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -72,6 +72,34 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '11.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: redcarpet
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 3.5.0
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 3.5.0
89
+ - !ruby/object:Gem::Dependency
90
+ name: selenium-webdriver
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '3.142'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '3.142'
75
103
  - !ruby/object:Gem::Dependency
76
104
  name: oauth2
77
105
  requirement: !ruby/object:Gem::Requirement
@@ -89,7 +117,7 @@ dependencies:
89
117
  description: This is a ruby gem to access the smartcar APIs. It includes the API classes
90
118
  and the OAuth system.
91
119
  email:
92
- - sshwin.subramanian@smartcar.com
120
+ - ashwin.subramanian@smartcar.com
93
121
  executables: []
94
122
  extensions: []
95
123
  extra_rdoc_files: []
@@ -97,6 +125,7 @@ files:
97
125
  - ".gitignore"
98
126
  - ".rspec"
99
127
  - ".travis.yml"
128
+ - ".yardopts"
100
129
  - CODE_OF_CONDUCT.md
101
130
  - Gemfile
102
131
  - Gemfile.lock
@@ -119,6 +148,7 @@ files:
119
148
  - lib/smartcar/user.rb
120
149
  - lib/smartcar/utils.rb
121
150
  - lib/smartcar/vehicle.rb
151
+ - lib/smartcar/vehicle_attributes.rb
122
152
  - lib/smartcar/version.rb
123
153
  - lib/smartcar/vin.rb
124
154
  - ruby-sdk.gemspec
@@ -134,14 +164,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
134
164
  requirements:
135
165
  - - ">="
136
166
  - !ruby/object:Gem::Version
137
- version: '0'
167
+ version: 2.5.0
138
168
  required_rubygems_version: !ruby/object:Gem::Requirement
139
169
  requirements:
140
170
  - - ">="
141
171
  - !ruby/object:Gem::Version
142
172
  version: '0'
143
173
  requirements: []
144
- rubygems_version: 3.1.2
174
+ rubygems_version: 3.0.6
145
175
  signing_key:
146
176
  specification_version: 4
147
177
  summary: Ruby Gem to access smartcar APIs (https://smartcar.com/docs/)