restforce 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of restforce might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b5ecae4e8e7e8b52ae216ad1b0505000eebb2a4f
4
- data.tar.gz: 27125a8223a2bf25ec80cc0dff6020021a8f0505
3
+ metadata.gz: c67387ede73e74537b9a9350642597ce127e65da
4
+ data.tar.gz: 5a467ccbed367d30f5ad7e5d7ac560c768bd8a2c
5
5
  SHA512:
6
- metadata.gz: c829bf4711eadbadcb26b5db972a4ecc71d08181e124e64dfaf3663713f0e74d1490eee4617d71d3c29827e2c943319eb2ab5a0b0c26ed4f314ebfcc5cec748f
7
- data.tar.gz: 90292fda7e4053b90f6de1a4d73ac1df40fa9f4867765fb6082e326de314e27577c1079920f1a04d547dbf1b4f4c9562e695210b842ed3ad294ef8aef131dd2f
6
+ metadata.gz: e3733f5db2df0daa8a00adee9b483d5927f7cafe808df32f2518c2c1fcfebb83eadf0408825ce68cd02dfaf54e3da61fea0d28e3cd0756ee7fdc08b3639d7d31
7
+ data.tar.gz: a009788abb56352ef24e8e6681877769df80f27aedecbac5ad18ac8f8ab6f7a51302f594c1e86558a6b9a19241c53c038e867874c53ca447aaec53e30f5e6e25
data/.travis.yml CHANGED
@@ -2,11 +2,12 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
- - 2.1.2
6
- - 2.2.0
5
+ - 2.1
6
+ - 2.2
7
7
  - jruby-19mode
8
8
  - rbx-2
9
9
  gemfile:
10
10
  - Gemfile.travis
11
11
  script:
12
12
  - bundle exec rubocop
13
+ - bundle exec rspec spec
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 2.1.0 (Jun 29, 2015)
2
+
3
+ * Added support for `query_all`, `explain` and `limits` API calls (which require a newer `api_version` than the default of 26.0) (@theSteveMitchell, @zenchild)
4
+ * Added support for `recent` API call (@davebrace)
5
+ * Changed `PROXY_URI` environment variable to `SALESFORCE_PROXY_URI` (with warning to `STDOUT` if the old variable is set) (@timrogers)
6
+ * Implemented `version_guard` in `Restforce::Concerns::API` to standardise behaviour of API calls which require a particular version of the Salesforce API (@zenchild)
7
+ * Fixed bug with construction of `Faraday::Error::ClientError` exceptions (@debussyman)
8
+ * Added support for specifying SSL options to be passed to Faraday (@jonathanrico)
9
+ * Added support for specifying a custom logger and log level (@ilyakatz)
10
+ * Improved experience for contributors to the gem with bootstrapping process (@rafalchmiel)
11
+
12
+
1
13
  ## 2.0.0 (Jun 27, 2015)
2
14
 
3
15
  * Drop support for versions of Ruby earlier than 1.9.3, which were [end-of-lifed](https://www.ruby-lang.org/en/news/2014/07/01/eol-for-1-8-7-and-1-9-2/) long ago
data/Gemfile CHANGED
@@ -6,4 +6,5 @@ gem 'jruby-openssl', :platforms => :jruby
6
6
 
7
7
  group :development do
8
8
  gem 'guard-rspec'
9
+ gem 'guard-rubocop'
9
10
  end
data/Guardfile CHANGED
@@ -1,11 +1,13 @@
1
- # A sample Guardfile
2
- # More info at https://github.com/guard/guard#readme
3
-
4
- guard 'rspec', all_on_start: false, all_after_pass: false do
1
+ guard 'rspec', cmd: 'bundle exec rspec', all_on_start: false, all_after_pass: false do
5
2
  watch(%r{^spec/.+_spec\.rb$})
6
- watch('spec/spec_helper.rb') { "spec" }
3
+ watch('spec/spec_helper.rb') { "spec" }
4
+
5
+ watch(%r{^lib/restforce/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
6
+ watch(%r{^lib/restforce/(.+)\.rb$}) { |m| "spec/integration/#{m[1]}_spec.rb" }
7
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
8
+ end
7
9
 
8
- watch(%r{^lib/restforce/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
9
- watch(%r{^lib/restforce/(.+)\.rb$}) { |m| "spec/integration/#{m[1]}_spec.rb" }
10
- watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
10
+ guard :rubocop, all_on_start: false do
11
+ watch(%r{.+\.rb$})
12
+ watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
11
13
  end
data/README.md CHANGED
@@ -103,7 +103,7 @@ client = Restforce.new
103
103
 
104
104
  ### Proxy Support
105
105
 
106
- You can specify a HTTP proxy using the `proxy_uri` option, as follows, or by setting the `PROXY_URI` environment variable:
106
+ You can specify a HTTP proxy using the `proxy_uri` option, as follows, or by setting the `SALESFORCE_PROXY_URI` environment variable:
107
107
 
108
108
  ```ruby
109
109
  client = Restforce.new :username => 'foo',
@@ -137,6 +137,28 @@ Restforce.configure do |config|
137
137
  end
138
138
  ```
139
139
 
140
+ ### API versions
141
+
142
+ By default, the gem defaults to using version 26.0 (Winter '13) of the Salesforce API.
143
+ Some more recent API endpoints will not be available without moving to a more recent
144
+ version - if you're trying to use a method that is unavailable with your API version,
145
+ Restforce will raise an `APIVersionError`.
146
+
147
+ You can change the `api_version` setting from the default either on a per-client basis:
148
+
149
+ ```ruby
150
+ client = Restforce.new api_version: "32.0" # ...
151
+ ```
152
+
153
+ or, you may set it globally for Restofrce as a whole:
154
+
155
+ ```ruby
156
+ Restforce.configure do |config|
157
+ config.api_version = "32.0"
158
+ # ...
159
+ end
160
+ ```
161
+
140
162
  ### Bang! methods
141
163
 
142
164
  All the CRUD methods (`create`, `update`, `upsert`, `destroy`) have equivalent methods with
@@ -170,6 +192,29 @@ account.destroy
170
192
  # => true
171
193
  ```
172
194
 
195
+ ### query_all
196
+
197
+ ```ruby
198
+ accounts = client.query_all("select Id, Something__c from Account where isDeleted = true")
199
+ # => #<Restforce::Collection >
200
+
201
+ query_all allows you to include results from your query that Salesforce hides in the default "query" method. These include soft-deleted records and archived records (e.g. Task and Event records which are usually archived automatically after they are a year old).
202
+
203
+ *Only available in [version 29.0](#api-versions) and later of the Salesforce API.*
204
+
205
+ ### explain
206
+
207
+ `explain` takes the same parameters as `query` and returns a query plan in JSON format.
208
+ For the nitty-gritty details on the response meanings visit the
209
+ [Salesforce Query Explain](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_query_explain.htm) page.
210
+
211
+ ```ruby
212
+ accounts = client.explain("select Id, Something__c from Account where Id = 'someid'")
213
+ # => #<Restforce::Mash >
214
+ ```
215
+
216
+ *Only available in [version 30.0](#api-versions) and later of the Salesforce API.*
217
+
173
218
  ### find
174
219
 
175
220
  ```ruby
@@ -249,7 +294,7 @@ client.describe('Account')
249
294
 
250
295
  ```ruby
251
296
  # Get layouts for an sobject type
252
- client.describe_layout('Account')
297
+ client.describe_layouts('Account')
253
298
  # => { ... }
254
299
 
255
300
  # Get the details for a specific layout by its ID
@@ -257,6 +302,8 @@ client.describe_layouts('Account', '012E0000000RHEp')
257
302
  # => { ... }
258
303
  ```
259
304
 
305
+ *Only available in [version 28.0](#api-versions) and later of the Salesforce API.*
306
+
260
307
  ### picklist\_values
261
308
 
262
309
 
@@ -280,6 +327,22 @@ client.user_info
280
327
  # => #<Restforce::Mash active=true display_name="Chatty Sassy" email="user@example.com" ... >
281
328
  ```
282
329
 
330
+ ### limits
331
+
332
+ `limits` returns the API limits for the currently connected organization. This includes information such as **Daily API calls** and **Daily Bulk API calls**. More information can be found on the
333
+ [Salesforce Limits](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_limits.htm) page.
334
+
335
+ ```ruby
336
+ # Get the current limit info
337
+ limits = client.limits
338
+ # => #<Restforce::Mash >
339
+
340
+ limits["DailyApiRequests"]
341
+ # => {"Max"=>15000, "Remaining"=>14746}
342
+ ```
343
+
344
+ *Only available in [version 29.0](#api-versions) and later of the Salesforce API.*
345
+
283
346
  * * *
284
347
 
285
348
  ### authenticate!
@@ -435,11 +498,19 @@ end
435
498
 
436
499
  ### Logging/Debugging/Instrumenting
437
500
 
438
- You can easily inspect what Restforce is sending/receiving by setting
439
- `Restforce.log = true`.
501
+ You can easily inspect what Restforce is sending/receiving by enabling logging, either
502
+ globally (as below) or on a per-client basis.
440
503
 
441
504
  ```ruby
442
505
  Restforce.log = true
506
+
507
+ # Restforce will log to STDOUT with the `:debug` log level by default, or you can
508
+ # optionally set your own logger and log level
509
+ Restforce.configure do |config|
510
+ config.logger = Logger.new("/tmp/log/restforce.log")
511
+ config.log_level = :info
512
+ end
513
+
443
514
  client = Restforce.new.query('select Id, Name from Account')
444
515
  ```
445
516
 
@@ -482,6 +553,34 @@ If you need a full Active Record experience, may be you can use
482
553
  Restforce and adds Associations, Query Building (like AREL), Validations and
483
554
  Callbacks.
484
555
 
556
+ ## Development
557
+
558
+ If you want to hack on Restforce locally, we try to make [bootstrapping the project](http://wynnnetherland.com/linked/2013012801/bootstrapping-consistency) as painless as possible. Just clone and run:
559
+
560
+ ```bash
561
+ $ script/bootstrap
562
+ ```
563
+
564
+ This will install project dependencies and get you up and running. If you want to run a Ruby console to poke on Restforce, you can crank one up with:
565
+
566
+ ```bash
567
+ $ script/console
568
+ ```
569
+
570
+ In order to run the specs, use:
571
+
572
+ ```bash
573
+ $ script/test
574
+ ```
575
+
576
+ Alternatively, use Guard which will run the specs on file changes:
577
+
578
+ ```bash
579
+ $ script/guard
580
+ ```
581
+
582
+ Using the scripts in `./script` instead of `bundle exec rspec`, `bundle console`, etc. ensures your dependencies are up-to-date.
583
+
485
584
  ## Contributing
486
585
 
487
586
  1. Fork it
data/lib/restforce.rb CHANGED
@@ -39,6 +39,7 @@ module Restforce
39
39
  Error = Class.new(StandardError)
40
40
  AuthenticationError = Class.new(Error)
41
41
  UnauthorizedError = Class.new(Error)
42
+ APIVersionError = Class.new(Error)
42
43
 
43
44
  class << self
44
45
  # Alias for Restforce::Data::Client.new
@@ -71,3 +72,9 @@ module Restforce
71
72
  end
72
73
  Object.send :include, Restforce::CoreExtensions unless Object.respond_to? :tap
73
74
  end
75
+
76
+ if ENV['PROXY_URI']
77
+ warn "[restforce] You must now use the SALESFORCE_PROXY_URI environment variable (as " \
78
+ "opposed to PROXY_URI) to set a proxy server for Restforce. Please update your " \
79
+ "environment's configuration."
80
+ end
@@ -55,6 +55,15 @@ module Restforce
55
55
  describe.collect { |sobject| sobject['name'] }
56
56
  end
57
57
 
58
+ # Public: Get info about limits in the connected organization
59
+ #
60
+ # Only available in version 29.0 and later of the Salesforce API.
61
+ #
62
+ # Returns an Array of String names for each SObject.
63
+ def limits
64
+ version_guard(29.0) { api_get("limits").body }
65
+ end
66
+
58
67
  # Public: Returns a detailed describe result for the specified sobject
59
68
  #
60
69
  # sobject - Stringish name of the sobject (default: nil).
@@ -82,7 +91,7 @@ module Restforce
82
91
  # specified sobject type, or URIs for layouts if the sobject has
83
92
  # multiple Record Types.
84
93
  #
85
- # This resource was introduced in version 28.0.
94
+ # Only available in version 28.0 and later of the Salesforce API.
86
95
  #
87
96
  # Examples:
88
97
  # # get the layouts for the sobject
@@ -95,10 +104,12 @@ module Restforce
95
104
  #
96
105
  # Returns the Hash representation of the describe_layouts result
97
106
  def describe_layouts(sobject, layout_id = nil)
98
- if layout_id
99
- api_get("sobjects/#{sobject}/describe/layouts/#{layout_id}").body
100
- else
101
- api_get("sobjects/#{sobject}/describe/layouts").body
107
+ version_guard(28.0) do
108
+ if layout_id
109
+ api_get("sobjects/#{sobject}/describe/layouts/#{layout_id}").body
110
+ else
111
+ api_get("sobjects/#{sobject}/describe/layouts").body
112
+ end
102
113
  end
103
114
  end
104
115
 
@@ -132,6 +143,48 @@ module Restforce
132
143
  mashify? ? response.body : response.body['records']
133
144
  end
134
145
 
146
+ # Public: Explain a SOQL query execution plan.
147
+ #
148
+ # Only available in version 30.0 and later of the Salesforce API.
149
+ #
150
+ # soql - A SOQL expression.
151
+ #
152
+ # Examples
153
+ #
154
+ # # Find the names of all Accounts
155
+ # client.explain('select Name from Account')
156
+ #
157
+ # Returns a Hash in the form {:plans => [Array of plan data]}
158
+ # See: https://www.salesforce.com/us/developer/docs/api_rest/Content/dome_query_expl
159
+ # ain.htm
160
+ def explain(soql)
161
+ version_guard(30.0) { api_get("query", explain: soql).body }
162
+ end
163
+
164
+ # Public: Executes a SOQL query and returns the result. Unlike the Query resource,
165
+ # QueryAll will return records that have been deleted because of a merge or delete.
166
+ # QueryAll will also return information about archived Task and Event records.
167
+ #
168
+ # Only available in version 29.0 and later of the Salesforce API.
169
+ #
170
+ # soql - A SOQL expression.
171
+ #
172
+ # Examples
173
+ #
174
+ # # Find the names of all Accounts
175
+ # client.query_all('select Name from Account').map(&:Name)
176
+ # # => ['Foo Bar Inc.', 'Whizbang Corp']
177
+ #
178
+ # Returns a Restforce::Collection if Restforce.configuration.mashify is true.
179
+ # Returns an Array of Hash for each record in the result if
180
+ # Restforce.configuration.mashify is false.
181
+ def query_all(soql)
182
+ version_guard(29.0) do
183
+ response = api_get 'queryAll', q: soql
184
+ mashify? ? response.body : response.body['records']
185
+ end
186
+ end
187
+
135
188
  # Public: Perform a SOSL search
136
189
  #
137
190
  # sosl - A SOSL expression.
@@ -338,6 +391,21 @@ module Restforce
338
391
  api_get(path).body
339
392
  end
340
393
 
394
+ # Public: Finds recently viewed items for the logged-in user.
395
+ #
396
+ # limit - An optional limit that specifies the maximum number of records to be
397
+ # returned.
398
+ # If this parameter is not specified, the default maximum number of records
399
+ # returned is the maximum number of entries in RecentlyViewed, which is 200
400
+ # records per object.
401
+ #
402
+ # Returns an array of the recently viewed Restforce::SObject records.
403
+ def recent(limit = nil)
404
+ path = limit ? "recent?limit=#{limit}" : "recent"
405
+
406
+ api_get(path).body
407
+ end
408
+
341
409
  private
342
410
 
343
411
  # Internal: Returns a path to an api endpoint
@@ -350,6 +418,20 @@ module Restforce
350
418
  "/services/data/v#{options[:api_version]}/#{path}"
351
419
  end
352
420
 
421
+ # Internal: Ensures that the `api_version` set for the Restforce client is at least
422
+ # the provided version before performing a particular action
423
+ def version_guard(version)
424
+ if version.to_f <= options[:api_version].to_f
425
+ yield
426
+ else
427
+ raise APIVersionError, "You must set an `api_version` of at least #{version} " \
428
+ "to use this feature in the Salesforce API. Set the " \
429
+ "`api_version` option when configuring the client - " \
430
+ "see https://github.com/ejholmes/restforce/blob/master" \
431
+ "/README.md#api-versions"
432
+ end
433
+ end
434
+
353
435
  # Internal: Errors that should be rescued from in non-bang methods
354
436
  def exceptions
355
437
  [Faraday::Error::ClientError]
@@ -66,7 +66,8 @@ module Restforce
66
66
  { request: {
67
67
  timeout: options[:timeout],
68
68
  open_timeout: options[:timeout] },
69
- proxy: options[:proxy_uri]
69
+ proxy: options[:proxy_uri],
70
+ ssl: options[:ssl]
70
71
  }
71
72
  end
72
73
 
@@ -32,7 +32,7 @@ module Restforce
32
32
 
33
33
  def log(message)
34
34
  return unless Restforce.log?
35
- Restforce.configuration.logger.send :debug, message
35
+ configuration.logger.send(configuration.log_level, message)
36
36
  end
37
37
  end
38
38
 
@@ -133,15 +133,19 @@ module Restforce
133
133
  # Faraday adapter to use. Defaults to Faraday.default_adapter.
134
134
  option :adapter, default: lambda { Faraday.default_adapter }
135
135
 
136
- # TODO: Rename this to `SALESFORCE_PROXY_URI` in next major version
137
- option :proxy_uri, default: lambda { ENV['PROXY_URI'] }
136
+ option :proxy_uri, default: lambda { ENV['SALESFORCE_PROXY_URI'] }
138
137
 
139
138
  # A Proc that is called with the response body after a successful authentication.
140
139
  option :authentication_callback
141
140
 
142
- def logger
143
- @logger ||= ::Logger.new STDOUT
144
- end
141
+ # Set SSL options
142
+ option :ssl, default: {}
143
+
144
+ # Set a logger for when Restforce.log is set to true, defaulting to STDOUT
145
+ option :logger, default: ::Logger.new(STDOUT)
146
+
147
+ # Set a log level for logging when Restforce.log is set to true, defaulting to :debug
148
+ option :log_level, default: :debug
145
149
 
146
150
  def options
147
151
  self.class.options
@@ -9,9 +9,9 @@ module Restforce
9
9
  raise Restforce::UnauthorizedError, message
10
10
  when 413
11
11
  raise Faraday::Error::ClientError.new("HTTP 413 - Request Entity Too Large",
12
- env[:response])
12
+ response_values)
13
13
  when 400...600
14
- raise Faraday::Error::ClientError.new(message, env[:response])
14
+ raise Faraday::Error::ClientError.new(message, response_values)
15
15
  end
16
16
  end
17
17
 
@@ -22,5 +22,13 @@ module Restforce
22
22
  def body
23
23
  JSON.parse(@env[:body])
24
24
  end
25
+
26
+ def response_values
27
+ {
28
+ status: @env[:status],
29
+ headers: @env[:response_headers],
30
+ body: @env[:body]
31
+ }
32
+ end
25
33
  end
26
34
  end
@@ -1,3 +1,3 @@
1
1
  module Restforce
2
- VERSION = '2.0.0'
2
+ VERSION = '2.1.0'
3
3
  end
data/restforce.gemspec CHANGED
@@ -7,6 +7,7 @@ Gem::Specification.new do |gem|
7
7
  gem.description = %q{A lightweight ruby client for the Salesforce REST API.}
8
8
  gem.summary = %q{A lightweight ruby client for the Salesforce REST API.}
9
9
  gem.homepage = "https://github.com/ejholmes/restforce"
10
+ gem.license = "MIT"
10
11
 
11
12
  gem.files = `git ls-files`.split($\)
12
13
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
data/script/bootstrap ADDED
@@ -0,0 +1,5 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ bundle install --quiet "$@"
data/script/console ADDED
@@ -0,0 +1,11 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ dir=`pwd`
6
+
7
+ echo "===> Bundling..."
8
+ script/bootstrap
9
+
10
+ echo "===> Launching console..."
11
+ bundle console
data/script/guard ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+
5
+ echo "===> Bundling..."
6
+ script/bootstrap
7
+
8
+ echo "===> Running Guard..."
9
+ bundle exec guard
data/script/test ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+
5
+ echo "===> Bundling..."
6
+ script/bootstrap --quiet
7
+
8
+ echo "===> Running specs..."
9
+ bundle exec rspec
10
+
11
+ echo "===> Running Rubocop..."
12
+ bundle exec rubocop
@@ -29,6 +29,42 @@ describe Restforce::Concerns::API do
29
29
  it { should eq ['foo'] }
30
30
  end
31
31
 
32
+ describe '.limits' do
33
+ subject { client.limits }
34
+
35
+ it 'returns the limits for an organization' do
36
+ limits = double('limits')
37
+ limits.stub(:body).and_return({})
38
+ client.should_receive(:api_get).with("limits").and_return(limits)
39
+ client.should_receive(:options).and_return(api_version: 29.0)
40
+ expect(client.limits).to eq({})
41
+ end
42
+
43
+ it "raises an exception if we aren't at version 29.0 or above" do
44
+ client.should_receive(:options).at_least(:once).and_return(api_version: 24.0)
45
+ expect { client.limits }.to raise_error(Restforce::APIVersionError)
46
+ end
47
+ end
48
+
49
+ describe '.explain' do
50
+ let(:soql) { 'Select Id from Account' }
51
+ subject(:results) { client.explain(soql) }
52
+
53
+ it "returns an execute plan for this SOQL" do
54
+ plans = double("plans")
55
+ plans.stub(:body).and_return("plans" => [])
56
+ client.should_receive(:api_get).with("query", explain: soql).
57
+ and_return(plans)
58
+ client.should_receive(:options).and_return(api_version: 30.0)
59
+ expect(results).to eq("plans" => [])
60
+ end
61
+
62
+ it "raises an exception if we aren't at version 30.0 or above" do
63
+ client.should_receive(:options).at_least(:once).and_return(api_version: 24.0)
64
+ expect { results }.to raise_error(Restforce::APIVersionError)
65
+ end
66
+ end
67
+
32
68
  describe '.describe' do
33
69
  subject(:describe) { client.describe }
34
70
 
@@ -56,24 +92,36 @@ describe Restforce::Concerns::API do
56
92
  describe '.describe_layouts' do
57
93
  subject(:describe_layouts) { client.describe_layouts('Whizbang') }
58
94
 
59
- it 'returns the layouts for the sobject' do
60
- client.should_receive(:api_get).
61
- with('sobjects/Whizbang/describe/layouts').
62
- and_return(response)
63
- expect(describe_layouts).to eq response.body
64
- end
65
-
66
- context 'when given the id of a layout' do
67
- subject(:describe_layouts) do
68
- client.describe_layouts('Whizbang', '012E0000000RHEp')
69
- end
95
+ context "API version where describe_layouts is supported" do
96
+ before { client.should_receive(:options).and_return(api_version: 28.0) }
70
97
 
71
- it 'returns the describe for the specified layout' do
98
+ it 'returns the layouts for the sobject' do
72
99
  client.should_receive(:api_get).
73
- with('sobjects/Whizbang/describe/layouts/012E0000000RHEp').
100
+ with('sobjects/Whizbang/describe/layouts').
74
101
  and_return(response)
75
102
  expect(describe_layouts).to eq response.body
76
103
  end
104
+
105
+ context 'when given the id of a layout' do
106
+ subject(:describe_layouts) do
107
+ client.describe_layouts('Whizbang', '012E0000000RHEp')
108
+ end
109
+
110
+ it 'returns the describe for the specified layout' do
111
+ client.should_receive(:api_get).
112
+ with('sobjects/Whizbang/describe/layouts/012E0000000RHEp').
113
+ and_return(response)
114
+ expect(describe_layouts).to eq response.body
115
+ end
116
+ end
117
+ end
118
+
119
+ context "an API version where describe_layouts is not supported" do
120
+ before { client.should_receive(:options).and_return(api_version: 24.0) }
121
+
122
+ it "raises a error" do
123
+ expect { describe_layouts }.to raise_error(Restforce::APIVersionError)
124
+ end
77
125
  end
78
126
  end
79
127
 
@@ -124,6 +172,49 @@ describe Restforce::Concerns::API do
124
172
  end
125
173
  end
126
174
 
175
+ describe '.query_all' do
176
+ let(:soql) { 'Select Id from Account' }
177
+ subject(:results) { client.query_all(soql) }
178
+
179
+ context "with supported api_version" do
180
+ before { client.should_receive(:options).and_return(api_version: 31.0) }
181
+
182
+ context 'with mashify middleware' do
183
+ before { client.stub(mashify?: true) }
184
+
185
+ it 'returns the body' do
186
+ client.should_receive(:api_get).with('queryAll', q: soql).
187
+ and_return(response)
188
+ expect(results).to eq(response.body)
189
+ end
190
+ end
191
+
192
+ context 'without mashify middleware' do
193
+ before do
194
+ client.stub(mashify?: false)
195
+ end
196
+
197
+ it 'returns the records attribute of the body' do
198
+ records = double('records')
199
+ response.body.stub(:[]).with('records').and_return(records)
200
+ client.should_receive(:api_get).with('queryAll', q: soql).
201
+ and_return(response)
202
+ expect(results).to eq(records)
203
+ end
204
+ end
205
+ end
206
+
207
+ context "with unsupported api_version" do
208
+ before { client.should_receive(:options).and_return(api_version: 26.0) }
209
+
210
+ subject(:query_all) { client.query_all(soql) }
211
+
212
+ it "raises an error" do
213
+ expect { query_all }.to raise_error(Restforce::APIVersionError)
214
+ end
215
+ end
216
+ end
217
+
127
218
  describe '.search' do
128
219
  let(:sosl) { 'FIND {bar}' }
129
220
  subject(:results) { client.search(sosl) }
@@ -308,4 +399,25 @@ describe Restforce::Concerns::API do
308
399
  end
309
400
  end
310
401
  end
402
+
403
+ describe "#recent" do
404
+ let(:limit) { nil }
405
+ subject(:result) { client.recent(limit) }
406
+
407
+ context "given no limit is specified" do
408
+ it "returns the most recently viewed items for the logged-in user" do
409
+ client.should_receive(:api_get).with('recent').and_return(response)
410
+ expect(result).to eq response.body
411
+ end
412
+ end
413
+
414
+ context "given a limit is specified" do
415
+ let(:limit) { 10 }
416
+
417
+ it "returns up to the limit specified results" do
418
+ client.should_receive(:api_get).with('recent?limit=10').and_return(response)
419
+ expect(result).to eq response.body
420
+ end
421
+ end
422
+ end
311
423
  end
@@ -12,6 +12,15 @@ describe Restforce::Concerns::Connection do
12
12
  it { should eq builder }
13
13
  end
14
14
 
15
+ describe "#connection_options" do
16
+ let(:options) { { ssl: { verify: false } } }
17
+ before { client.stub(options: options) }
18
+
19
+ it "picks up passed-in SSL options" do
20
+ expect(client.send(:connection_options)).to include(options)
21
+ end
22
+ end
23
+
15
24
  describe 'private #connection' do
16
25
  describe ':mashify option' do
17
26
  let(:options) { { adapter: Faraday.default_adapter } }
@@ -23,6 +23,7 @@ describe Restforce do
23
23
  its(:host) { should eq 'login.salesforce.com' }
24
24
  its(:authentication_retries) { should eq 3 }
25
25
  its(:adapter) { should eq Faraday.default_adapter }
26
+ its(:ssl) { should eq({}) }
26
27
  [:username, :password, :security_token, :client_id, :client_secret,
27
28
  :oauth_token, :refresh_token, :instance_url, :compress, :timeout,
28
29
  :proxy_uri, :authentication_callback, :mashify].each do |attr|
@@ -37,7 +38,7 @@ describe Restforce do
37
38
  'SALESFORCE_SECURITY_TOKEN' => 'foobar',
38
39
  'SALESFORCE_CLIENT_ID' => 'client id',
39
40
  'SALESFORCE_CLIENT_SECRET' => 'client secret',
40
- 'PROXY_URI' => 'proxy',
41
+ 'SALESFORCE_PROXY_URI' => 'proxy',
41
42
  'SALESFORCE_HOST' => 'test.host.com' }.
42
43
  each { |var, value| ENV.stub(:[]).with(var).and_return(value) }
43
44
  end
@@ -55,7 +56,8 @@ describe Restforce do
55
56
  describe '#configure' do
56
57
  [:username, :password, :security_token, :client_id, :client_secret, :compress,
57
58
  :timeout, :oauth_token, :refresh_token, :instance_url, :api_version, :host, :mashify,
58
- :authentication_retries, :proxy_uri, :authentication_callback].each do |attr|
59
+ :authentication_retries, :proxy_uri, :authentication_callback, :ssl, :log_level,
60
+ :logger].each do |attr|
59
61
  it "allows #{attr} to be set" do
60
62
  Restforce.configure do |config|
61
63
  config.send("#{attr}=", 'foobar')
@@ -86,14 +88,40 @@ describe Restforce do
86
88
  end
87
89
 
88
90
  context 'with logging enabled' do
89
- before do
90
- Restforce.stub log?: true
91
- Restforce.configuration.logger.should_receive(:debug).with('foobar')
92
- end
91
+ before { Restforce.stub(log?: true) }
93
92
 
94
93
  it 'logs something' do
94
+ Restforce.configuration.logger.should_receive(:debug).with('foobar')
95
95
  Restforce.log 'foobar'
96
96
  end
97
+
98
+ context "with a custom logger" do
99
+ let(:fake_logger) { double(debug: true) }
100
+
101
+ before do
102
+ Restforce.configure do |config|
103
+ config.logger = fake_logger
104
+ end
105
+ end
106
+
107
+ it "logs using the provided logger" do
108
+ fake_logger.should_receive(:debug).with('foobar')
109
+ Restforce.log('foobar')
110
+ end
111
+ end
112
+
113
+ context "with a custom log_level" do
114
+ before do
115
+ Restforce.configure do |config|
116
+ config.log_level = :info
117
+ end
118
+ end
119
+
120
+ it 'logs with the provided log_level' do
121
+ Restforce.configuration.logger.should_receive(:info).with('foobar')
122
+ Restforce.log 'foobar'
123
+ end
124
+ end
97
125
  end
98
126
  end
99
127
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restforce
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric J. Holmes
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-06-27 00:00:00.000000000 Z
12
+ date: 2015-06-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -204,6 +204,10 @@ files:
204
204
  - lib/restforce/upload_io.rb
205
205
  - lib/restforce/version.rb
206
206
  - restforce.gemspec
207
+ - script/bootstrap
208
+ - script/console
209
+ - script/guard
210
+ - script/test
207
211
  - spec/fixtures/auth_error_response.json
208
212
  - spec/fixtures/auth_success_response.json
209
213
  - spec/fixtures/blob.jpg
@@ -272,7 +276,8 @@ files:
272
276
  - spec/unit/sobject_spec.rb
273
277
  - spec/unit/tooling/client_spec.rb
274
278
  homepage: https://github.com/ejholmes/restforce
275
- licenses: []
279
+ licenses:
280
+ - MIT
276
281
  metadata: {}
277
282
  post_install_message:
278
283
  rdoc_options: []