restforce 0.1.4 → 0.1.5
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.
- data/.travis.yml +1 -0
- data/lib/restforce.rb +9 -0
- data/lib/restforce/client.rb +13 -19
- data/lib/restforce/middleware/authentication.rb +14 -1
- data/lib/restforce/middleware/logger.rb +8 -8
- data/lib/restforce/version.rb +1 -1
- data/restforce.gemspec +1 -1
- data/spec/lib/client_spec.rb +63 -63
- data/spec/lib/collection_spec.rb +1 -1
- data/spec/lib/mash_spec.rb +1 -1
- data/spec/lib/middleware/authentication/password_spec.rb +12 -12
- data/spec/lib/middleware/authentication/token_spec.rb +10 -10
- data/spec/lib/middleware/authentication_spec.rb +2 -2
- data/spec/lib/middleware/authorization_spec.rb +2 -2
- data/spec/lib/middleware/gzip_spec.rb +2 -2
- data/spec/lib/middleware/logger_spec.rb +1 -1
- data/spec/lib/middleware/mashify_spec.rb +2 -2
- data/spec/lib/middleware/raise_error_spec.rb +1 -1
- data/spec/lib/sobject_spec.rb +5 -5
- data/spec/support/basic_client.rb +1 -1
- data/spec/support/fixture_helpers.rb +8 -8
- metadata +6 -6
data/.travis.yml
CHANGED
data/lib/restforce.rb
CHANGED
@@ -41,4 +41,13 @@ module Restforce
|
|
41
41
|
|
42
42
|
class AuthenticationError < StandardError; end
|
43
43
|
class UnauthorizedError < StandardError; end
|
44
|
+
|
45
|
+
# Add .tap method in Ruby 1.8
|
46
|
+
module CoreExtensions
|
47
|
+
def tap
|
48
|
+
yield self
|
49
|
+
self
|
50
|
+
end
|
51
|
+
end
|
52
|
+
Object.send :include, Restforce::CoreExtensions unless Object.respond_to? :tap
|
44
53
|
end
|
data/lib/restforce/client.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
module Restforce
|
2
2
|
class Client
|
3
|
+
OPTIONS = [:username, :password, :security_token, :client_id, :client_secret, :host, :compress,
|
4
|
+
:api_version, :oauth_token, :refresh_token, :instance_url, :cache, :authentication_retries]
|
5
|
+
|
3
6
|
# Public: Creates a new client instance
|
4
7
|
#
|
5
|
-
#
|
8
|
+
# opts - A hash of options to be passed in (default: {}).
|
6
9
|
# :username - The String username to use (required for password authentication).
|
7
10
|
# :password - The String password to use (required for password authentication).
|
8
11
|
# :security_token - The String security token to use
|
@@ -55,15 +58,10 @@ module Restforce
|
|
55
58
|
# Restforce::Client.new :oauth_token => 'access token',
|
56
59
|
# :instance_url => 'https://na1.salesforce.com'
|
57
60
|
# # => #<Restforce::Client:0x007f934aab9980 @options={ ... }>
|
58
|
-
def initialize(
|
59
|
-
raise 'Please specify a hash of options' unless
|
60
|
-
@options =
|
61
|
-
|
62
|
-
:api_version, :oauth_token, :refresh_token, :instance_url, :cache, :authentication_retries].each do |option|
|
63
|
-
options[option] = Restforce.configuration.send option
|
64
|
-
end
|
65
|
-
end
|
66
|
-
@options.merge!(options)
|
61
|
+
def initialize(opts = {})
|
62
|
+
raise 'Please specify a hash of options' unless opts.is_a?(Hash)
|
63
|
+
@options = Hash[OPTIONS.map { |option| [option, Restforce.configuration.send(option)] }]
|
64
|
+
@options.merge! opts
|
67
65
|
end
|
68
66
|
|
69
67
|
# Public: Get the names of all sobjects on the org.
|
@@ -96,11 +94,9 @@ module Restforce
|
|
96
94
|
# Returns the Hash representation of the describe call.
|
97
95
|
def describe(sobject=nil)
|
98
96
|
if sobject
|
99
|
-
|
100
|
-
response.body
|
97
|
+
api_get("sobjects/#{sobject.to_s}/describe").body
|
101
98
|
else
|
102
|
-
|
103
|
-
response.body['sobjects']
|
99
|
+
api_get('sobjects').body['sobjects']
|
104
100
|
end
|
105
101
|
end
|
106
102
|
|
@@ -129,7 +125,7 @@ module Restforce
|
|
129
125
|
# Returns a Restforce::Collection if Restforce.configuration.mashify is true.
|
130
126
|
# Returns an Array of Hash for each record in the result if Restforce.configuration.mashify is false.
|
131
127
|
def query(soql)
|
132
|
-
response = api_get 'query', q
|
128
|
+
response = api_get 'query', :q => soql
|
133
129
|
mashify? ? response.body : response.body['records']
|
134
130
|
end
|
135
131
|
|
@@ -150,8 +146,7 @@ module Restforce
|
|
150
146
|
# Returns a Restforce::Collection if Restforce.configuration.mashify is true.
|
151
147
|
# Returns an Array of Hash for each record in the result if Restforce.configuration.mashify is false.
|
152
148
|
def search(sosl)
|
153
|
-
|
154
|
-
response.body
|
149
|
+
api_get('search', :q => sosl).body
|
155
150
|
end
|
156
151
|
|
157
152
|
# Public: Insert a new record.
|
@@ -176,8 +171,7 @@ module Restforce
|
|
176
171
|
# Returns the String Id of the newly created sobject. Raises an error if
|
177
172
|
# something bad happens.
|
178
173
|
def create!(sobject, attrs)
|
179
|
-
|
180
|
-
response.body['id']
|
174
|
+
api_post("sobjects/#{sobject}", attrs).body['id']
|
181
175
|
end
|
182
176
|
alias_method :insert!, :create!
|
183
177
|
|
@@ -19,7 +19,7 @@ module Restforce
|
|
19
19
|
# Internal: Performs the authentication and returns the response body.
|
20
20
|
def authenticate!
|
21
21
|
response = connection.post '/services/oauth2/token' do |req|
|
22
|
-
req.body =
|
22
|
+
req.body = encode_www_form(params)
|
23
23
|
end
|
24
24
|
raise Restforce::AuthenticationError, error_message(response) if response.status != 200
|
25
25
|
@options[:instance_url] = response.body['instance_url']
|
@@ -46,5 +46,18 @@ module Restforce
|
|
46
46
|
def error_message(response)
|
47
47
|
"#{response.body['error']}: #{response.body['error_description']}"
|
48
48
|
end
|
49
|
+
|
50
|
+
# Featured detect form encoding.
|
51
|
+
# URI in 1.8 does not include encode_www_form
|
52
|
+
def encode_www_form(params)
|
53
|
+
if URI.respond_to?(:encode_www_form)
|
54
|
+
URI.encode_www_form(params)
|
55
|
+
else
|
56
|
+
params.map do |k, v|
|
57
|
+
k, v = CGI.escape(k.to_s), CGI.escape(v.to_s)
|
58
|
+
"#{k}=#{v}"
|
59
|
+
end.join('&')
|
60
|
+
end
|
61
|
+
end
|
49
62
|
end
|
50
63
|
end
|
@@ -4,7 +4,7 @@ module Restforce
|
|
4
4
|
class Middleware::Logger < Faraday::Response::Middleware
|
5
5
|
extend Forwardable
|
6
6
|
|
7
|
-
def initialize(app, logger
|
7
|
+
def initialize(app, logger, options)
|
8
8
|
super(app)
|
9
9
|
@options = options
|
10
10
|
@logger = logger || begin
|
@@ -17,19 +17,19 @@ module Restforce
|
|
17
17
|
|
18
18
|
def call(env)
|
19
19
|
debug('request') do
|
20
|
-
dump url
|
21
|
-
method
|
22
|
-
headers
|
23
|
-
body
|
20
|
+
dump :url => env[:url].to_s,
|
21
|
+
:method => env[:method],
|
22
|
+
:headers => env[:request_headers],
|
23
|
+
:body => env[:body]
|
24
24
|
end
|
25
25
|
super
|
26
26
|
end
|
27
27
|
|
28
28
|
def on_complete(env)
|
29
29
|
debug('response') do
|
30
|
-
dump status
|
31
|
-
headers
|
32
|
-
body
|
30
|
+
dump :status => env[:status].to_s,
|
31
|
+
:headers => env[:response_headers],
|
32
|
+
:body => env[:body]
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
data/lib/restforce/version.rb
CHANGED
data/restforce.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |gem|
|
|
20
20
|
gem.add_dependency 'faraday_middleware', '~> 0.8.8'
|
21
21
|
gem.add_dependency 'json', '~> 1.7.5'
|
22
22
|
gem.add_dependency 'hashie', '~> 1.2.0'
|
23
|
-
gem.add_dependency 'faye'
|
23
|
+
gem.add_dependency 'faye', '0.8.3'
|
24
24
|
|
25
25
|
gem.add_development_dependency 'rspec'
|
26
26
|
gem.add_development_dependency 'webmock'
|
data/spec/lib/client_spec.rb
CHANGED
@@ -55,7 +55,7 @@ shared_examples_for 'methods' do
|
|
55
55
|
|
56
56
|
describe '.list_sobjects' do
|
57
57
|
before do
|
58
|
-
@request = stub_api_request :sobjects, with
|
58
|
+
@request = stub_api_request :sobjects, :with => 'sobject/describe_sobjects_success_response'
|
59
59
|
end
|
60
60
|
|
61
61
|
after do
|
@@ -71,7 +71,7 @@ shared_examples_for 'methods' do
|
|
71
71
|
context 'with no arguments' do
|
72
72
|
before do
|
73
73
|
@request = stub_api_request :sobjects,
|
74
|
-
with
|
74
|
+
:with => 'sobject/describe_sobjects_success_response'
|
75
75
|
end
|
76
76
|
|
77
77
|
after do
|
@@ -85,7 +85,7 @@ shared_examples_for 'methods' do
|
|
85
85
|
context 'with an argument' do
|
86
86
|
before do
|
87
87
|
@request = stub_api_request 'sobjects/Whizbang/describe',
|
88
|
-
with
|
88
|
+
:with => 'sobject/sobject_describe_success_response'
|
89
89
|
end
|
90
90
|
|
91
91
|
after do
|
@@ -100,7 +100,7 @@ shared_examples_for 'methods' do
|
|
100
100
|
describe '.query' do
|
101
101
|
before do
|
102
102
|
@request = stub_api_request 'query\?q=SELECT%20some,%20fields%20FROM%20object',
|
103
|
-
with
|
103
|
+
:with => 'sobject/query_success_response'
|
104
104
|
end
|
105
105
|
|
106
106
|
after do
|
@@ -114,7 +114,7 @@ shared_examples_for 'methods' do
|
|
114
114
|
describe '.search' do
|
115
115
|
before do
|
116
116
|
@request = stub_api_request 'search\?q=FIND%20%7Bbar%7D',
|
117
|
-
with
|
117
|
+
:with => 'sobject/search_success_response'
|
118
118
|
end
|
119
119
|
|
120
120
|
after do
|
@@ -129,7 +129,7 @@ shared_examples_for 'methods' do
|
|
129
129
|
describe '.org_id' do
|
130
130
|
before do
|
131
131
|
@request = stub_api_request 'query\?q=select%20id%20from%20Organization',
|
132
|
-
with
|
132
|
+
:with => 'sobject/org_query_response'
|
133
133
|
end
|
134
134
|
|
135
135
|
after do
|
@@ -144,32 +144,32 @@ shared_examples_for 'methods' do
|
|
144
144
|
context 'without multipart' do
|
145
145
|
before do
|
146
146
|
@request = stub_api_request 'sobjects/Account',
|
147
|
-
with
|
148
|
-
method
|
149
|
-
body
|
147
|
+
:with => 'sobject/create_success_response',
|
148
|
+
:method => :post,
|
149
|
+
:body => "{\"Name\":\"Foobar\"}"
|
150
150
|
end
|
151
151
|
|
152
152
|
after do
|
153
153
|
@request.should have_been_requested
|
154
154
|
end
|
155
155
|
|
156
|
-
subject { client.create('Account', Name
|
156
|
+
subject { client.create('Account', :Name => 'Foobar') }
|
157
157
|
it { should eq 'some_id' }
|
158
158
|
end
|
159
159
|
|
160
160
|
context 'with multipart' do
|
161
161
|
before do
|
162
162
|
@request = stub_api_request 'sobjects/Account',
|
163
|
-
with
|
164
|
-
method
|
165
|
-
body
|
163
|
+
:with => 'sobject/create_success_response',
|
164
|
+
:method => :post,
|
165
|
+
:body => %r(----boundary_string\r\nContent-Disposition: form-data; name=\"entity_content\";\r\nContent-Type: application/json\r\n\r\n{\"Name\":\"Foobar\"}\r\n----boundary_string\r\nContent-Disposition: form-data; name=\"Blob\"; filename=\"blob.jpg\"\r\nContent-Length: 42171\r\nContent-Type: image/jpeg\r\nContent-Transfer-Encoding: binary)
|
166
166
|
end
|
167
167
|
|
168
168
|
after do
|
169
169
|
@request.should have_been_requested
|
170
170
|
end
|
171
171
|
|
172
|
-
subject { client.create('Account', Name
|
172
|
+
subject { client.create('Account', :Name => 'Foobar', :Blob => Restforce::UploadIO.new(File.expand_path('../../fixtures/blob.jpg', __FILE__), 'image/jpeg')) }
|
173
173
|
it { should eq 'some_id' }
|
174
174
|
end
|
175
175
|
end
|
@@ -178,49 +178,49 @@ shared_examples_for 'methods' do
|
|
178
178
|
context 'with invalid Id' do
|
179
179
|
before do
|
180
180
|
@request = stub_api_request 'sobjects/Account/001D000000INjVe',
|
181
|
-
with
|
182
|
-
method
|
183
|
-
body
|
184
|
-
status
|
181
|
+
:with => 'sobject/delete_error_response',
|
182
|
+
:method => :patch,
|
183
|
+
:body => "{\"Name\":\"Foobar\"}",
|
184
|
+
:status => 404
|
185
185
|
end
|
186
186
|
|
187
187
|
after do
|
188
188
|
@request.should have_been_requested
|
189
189
|
end
|
190
190
|
|
191
|
-
subject { client.update!('Account', Id
|
191
|
+
subject { client.update!('Account', :Id => '001D000000INjVe', :Name => 'Foobar') }
|
192
192
|
specify { expect { subject }.to raise_error Faraday::Error::ResourceNotFound }
|
193
193
|
end
|
194
194
|
end
|
195
195
|
|
196
196
|
describe '.update' do
|
197
197
|
context 'with missing Id' do
|
198
|
-
subject { client.update('Account', Name
|
198
|
+
subject { client.update('Account', :Name => 'Foobar') }
|
199
199
|
specify { expect { subject }.to raise_error RuntimeError, 'Id field missing.' }
|
200
200
|
end
|
201
201
|
|
202
202
|
context 'with invalid Id' do
|
203
203
|
before do
|
204
204
|
@request = stub_api_request 'sobjects/Account/001D000000INjVe',
|
205
|
-
with
|
206
|
-
method
|
207
|
-
body
|
208
|
-
status
|
205
|
+
:with => 'sobject/delete_error_response',
|
206
|
+
:method => :patch,
|
207
|
+
:body => "{\"Name\":\"Foobar\"}",
|
208
|
+
:status => 404
|
209
209
|
end
|
210
210
|
|
211
211
|
after do
|
212
212
|
@request.should have_been_requested
|
213
213
|
end
|
214
214
|
|
215
|
-
subject { client.update('Account', Id
|
215
|
+
subject { client.update('Account', :Id => '001D000000INjVe', :Name => 'Foobar') }
|
216
216
|
it { should be_false }
|
217
217
|
end
|
218
218
|
|
219
219
|
context 'with success' do
|
220
220
|
before do
|
221
221
|
@request = stub_api_request 'sobjects/Account/001D000000INjVe',
|
222
|
-
method
|
223
|
-
body
|
222
|
+
:method => :patch,
|
223
|
+
:body => "{\"Name\":\"Foobar\"}"
|
224
224
|
end
|
225
225
|
|
226
226
|
after do
|
@@ -228,7 +228,7 @@ shared_examples_for 'methods' do
|
|
228
228
|
end
|
229
229
|
|
230
230
|
context 'with symbol Id key' do
|
231
|
-
subject { client.update('Account', Id
|
231
|
+
subject { client.update('Account', :Id => '001D000000INjVe', :Name => 'Foobar') }
|
232
232
|
it { should be_true }
|
233
233
|
end
|
234
234
|
|
@@ -243,8 +243,8 @@ shared_examples_for 'methods' do
|
|
243
243
|
context 'when updated' do
|
244
244
|
before do
|
245
245
|
@request = stub_api_request 'sobjects/Account/External__c/foobar',
|
246
|
-
method
|
247
|
-
body
|
246
|
+
:method => :patch,
|
247
|
+
:body => "{\"Name\":\"Foobar\"}"
|
248
248
|
end
|
249
249
|
|
250
250
|
after do
|
@@ -252,7 +252,7 @@ shared_examples_for 'methods' do
|
|
252
252
|
end
|
253
253
|
|
254
254
|
context 'with symbol external Id key' do
|
255
|
-
subject { client.upsert!('Account', 'External__c', External__c
|
255
|
+
subject { client.upsert!('Account', 'External__c', :External__c => 'foobar', :Name => 'Foobar') }
|
256
256
|
it { should be_true }
|
257
257
|
end
|
258
258
|
|
@@ -265,9 +265,9 @@ shared_examples_for 'methods' do
|
|
265
265
|
context 'when created' do
|
266
266
|
before do
|
267
267
|
@request = stub_api_request 'sobjects/Account/External__c/foobar',
|
268
|
-
method
|
269
|
-
body
|
270
|
-
with
|
268
|
+
:method => :patch,
|
269
|
+
:body => "{\"Name\":\"Foobar\"}",
|
270
|
+
:with => 'sobject/upsert_created_success_response'
|
271
271
|
end
|
272
272
|
|
273
273
|
after do
|
@@ -275,7 +275,7 @@ shared_examples_for 'methods' do
|
|
275
275
|
end
|
276
276
|
|
277
277
|
context 'with symbol external Id key' do
|
278
|
-
subject { client.upsert!('Account', 'External__c', External__c
|
278
|
+
subject { client.upsert!('Account', 'External__c', :External__c => 'foobar', :Name => 'Foobar') }
|
279
279
|
it { should eq 'foo' }
|
280
280
|
end
|
281
281
|
|
@@ -292,9 +292,9 @@ shared_examples_for 'methods' do
|
|
292
292
|
context 'with invalid Id' do
|
293
293
|
before do
|
294
294
|
@request = stub_api_request 'sobjects/Account/001D000000INjVe',
|
295
|
-
with
|
296
|
-
method
|
297
|
-
status
|
295
|
+
:with => 'sobject/delete_error_response',
|
296
|
+
:method => :delete,
|
297
|
+
:status => 404
|
298
298
|
end
|
299
299
|
|
300
300
|
after do
|
@@ -306,7 +306,7 @@ shared_examples_for 'methods' do
|
|
306
306
|
|
307
307
|
context 'with success' do
|
308
308
|
before do
|
309
|
-
@request = stub_api_request 'sobjects/Account/001D000000INjVe', method
|
309
|
+
@request = stub_api_request 'sobjects/Account/001D000000INjVe', :method => :delete
|
310
310
|
end
|
311
311
|
|
312
312
|
after do
|
@@ -323,9 +323,9 @@ shared_examples_for 'methods' do
|
|
323
323
|
context 'with invalid Id' do
|
324
324
|
before do
|
325
325
|
@request = stub_api_request 'sobjects/Account/001D000000INjVe',
|
326
|
-
with
|
327
|
-
method
|
328
|
-
status
|
326
|
+
:with => 'sobject/delete_error_response',
|
327
|
+
:method => :delete,
|
328
|
+
:status => 404
|
329
329
|
end
|
330
330
|
|
331
331
|
after do
|
@@ -337,7 +337,7 @@ shared_examples_for 'methods' do
|
|
337
337
|
|
338
338
|
context 'with success' do
|
339
339
|
before do
|
340
|
-
@request = stub_api_request 'sobjects/Account/001D000000INjVe', method
|
340
|
+
@request = stub_api_request 'sobjects/Account/001D000000INjVe', :method => :delete
|
341
341
|
end
|
342
342
|
|
343
343
|
after do
|
@@ -350,9 +350,9 @@ shared_examples_for 'methods' do
|
|
350
350
|
|
351
351
|
describe '.authenticate!' do
|
352
352
|
before do
|
353
|
-
@request = stub_login_request(body
|
354
|
-
"client_secret&username=foo&password=barsecurity_token")
|
355
|
-
|
353
|
+
@request = stub_login_request(:body => "grant_type=password&client_id=client_id&client_secret=" \
|
354
|
+
"client_secret&username=foo&password=barsecurity_token").
|
355
|
+
to_return(:status => 200, :body => fixture(:auth_success_response))
|
356
356
|
end
|
357
357
|
|
358
358
|
after do
|
@@ -409,7 +409,7 @@ shared_examples_for 'methods' do
|
|
409
409
|
|
410
410
|
before do
|
411
411
|
@request = stub_api_request 'query\?q=SELECT%20some,%20fields%20FROM%20object',
|
412
|
-
with
|
412
|
+
:with => 'sobject/query_success_response'
|
413
413
|
cache.should_receive(:fetch).never
|
414
414
|
end
|
415
415
|
|
@@ -425,7 +425,7 @@ shared_examples_for 'methods' do
|
|
425
425
|
subject { client.send(:faye) }
|
426
426
|
|
427
427
|
context 'with missing oauth token' do
|
428
|
-
let(:instance_url) { 'foobar' }
|
428
|
+
let(:instance_url) { 'http://foobar' }
|
429
429
|
let(:oauth_token) { nil }
|
430
430
|
specify { expect { subject }.to raise_error RuntimeError, 'OAuth token missing. Call .authenticate! first.' }
|
431
431
|
end
|
@@ -436,7 +436,7 @@ shared_examples_for 'methods' do
|
|
436
436
|
end
|
437
437
|
|
438
438
|
context 'with oauth token and instance url' do
|
439
|
-
let(:instance_url) { '
|
439
|
+
let(:instance_url) { 'http://foobar' }
|
440
440
|
let(:oauth_token) { 'bar' }
|
441
441
|
specify { expect { subject }.to_not raise_error }
|
442
442
|
end
|
@@ -446,11 +446,11 @@ shared_examples_for 'methods' do
|
|
446
446
|
context 'when retries reaches 0' do
|
447
447
|
before do
|
448
448
|
@auth_request = stub_api_request('query\?q=SELECT%20some,%20fields%20FROM%20object',
|
449
|
-
status
|
450
|
-
with
|
451
|
-
@query_request = stub_login_request(body
|
452
|
-
"client_secret&username=foo&password=barsecurity_token")
|
453
|
-
|
449
|
+
:status => 401,
|
450
|
+
:with => 'expired_session_response')
|
451
|
+
@query_request = stub_login_request(:body => "grant_type=password&client_id=client_id&client_secret=" \
|
452
|
+
"client_secret&username=foo&password=barsecurity_token").
|
453
|
+
to_return(:status => 200, :body => fixture(:auth_success_response))
|
454
454
|
end
|
455
455
|
|
456
456
|
subject { client.query('SELECT some, fields FROM object') }
|
@@ -476,14 +476,14 @@ shared_examples_for 'methods' do
|
|
476
476
|
let(:cache) { MockCache.new }
|
477
477
|
|
478
478
|
before do
|
479
|
-
@query = stub_api_request('query\?q=SELECT%20some,%20fields%20FROM%20object')
|
480
|
-
|
481
|
-
|
482
|
-
|
479
|
+
@query = stub_api_request('query\?q=SELECT%20some,%20fields%20FROM%20object').
|
480
|
+
with(:headers => { 'Authorization' => "OAuth #{oauth_token}" }).
|
481
|
+
to_return(:status => 401, :body => fixture('expired_session_response')).then.
|
482
|
+
to_return(:status => 200, :body => fixture('sobject/query_success_response'))
|
483
483
|
|
484
|
-
@login = stub_login_request(body
|
485
|
-
"client_secret&username=foo&password=barsecurity_token")
|
486
|
-
|
484
|
+
@login = stub_login_request(:body => "grant_type=password&client_id=client_id&client_secret=" \
|
485
|
+
"client_secret&username=foo&password=barsecurity_token").
|
486
|
+
to_return(:status => 200, :body => fixture(:auth_success_response))
|
487
487
|
end
|
488
488
|
|
489
489
|
after do
|
@@ -511,8 +511,8 @@ describe 'with mashify middleware' do
|
|
511
511
|
context 'with pagination' do
|
512
512
|
before do
|
513
513
|
@requests = [].tap do |requests|
|
514
|
-
requests << stub_api_request('query\?q', with
|
515
|
-
requests << stub_api_request('query/01gD', with
|
514
|
+
requests << stub_api_request('query\?q', :with => 'sobject/query_paginated_first_page_response')
|
515
|
+
requests << stub_api_request('query/01gD', :with => 'sobject/query_paginated_last_page_response')
|
516
516
|
end
|
517
517
|
end
|
518
518
|
|
data/spec/lib/collection_spec.rb
CHANGED
@@ -39,7 +39,7 @@ describe Restforce::Collection do
|
|
39
39
|
|
40
40
|
describe '.next_page' do
|
41
41
|
before do
|
42
|
-
client.should_receive(:get).and_return(Faraday::Response.new(body
|
42
|
+
client.should_receive(:get).and_return(Faraday::Response.new(:body => Restforce::Collection.new({'records' => []}, client)))
|
43
43
|
end
|
44
44
|
|
45
45
|
subject { records.next_page }
|
data/spec/lib/mash_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe Restforce::Mash do
|
|
5
5
|
subject { described_class.build(input, nil) }
|
6
6
|
|
7
7
|
context 'when array' do
|
8
|
-
let(:input) { [{ foo
|
8
|
+
let(:input) { [{ :foo => 'hello' }, { :bar => 'world' }] }
|
9
9
|
it 'mashifys each child object' do
|
10
10
|
subject.each { |obj| obj.should be_a Restforce::Mash }
|
11
11
|
end
|
@@ -6,25 +6,25 @@ describe Restforce::Middleware::Authentication::Password do
|
|
6
6
|
let(:middleware) { described_class.new app, nil, options }
|
7
7
|
|
8
8
|
let(:options) do
|
9
|
-
{ host
|
10
|
-
username
|
11
|
-
password
|
12
|
-
security_token
|
13
|
-
client_id
|
14
|
-
client_secret
|
9
|
+
{ :host => 'login.salesforce.com',
|
10
|
+
:username => 'foo',
|
11
|
+
:password => 'bar',
|
12
|
+
:security_token => 'security_token',
|
13
|
+
:client_id => 'client_id',
|
14
|
+
:client_secret => 'client_secret' }
|
15
15
|
end
|
16
16
|
|
17
17
|
it_behaves_like 'authentication middleware' do
|
18
18
|
let(:success_request) do
|
19
|
-
stub_login_request(body
|
20
|
-
"client_secret&username=foo&password=barsecurity_token")
|
21
|
-
|
19
|
+
stub_login_request(:body => "grant_type=password&client_id=client_id&client_secret=" \
|
20
|
+
"client_secret&username=foo&password=barsecurity_token").
|
21
|
+
to_return(:status => 200, :body => fixture(:auth_success_response))
|
22
22
|
end
|
23
23
|
|
24
24
|
let(:fail_request) do
|
25
|
-
stub_login_request(body
|
26
|
-
"client_secret&username=foo&password=barsecurity_token")
|
27
|
-
|
25
|
+
stub_login_request(:body => "grant_type=password&client_id=client_id&client_secret=" \
|
26
|
+
"client_secret&username=foo&password=barsecurity_token").
|
27
|
+
to_return(:status => 400, :body => fixture(:auth_error_response))
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -6,23 +6,23 @@ describe Restforce::Middleware::Authentication::Token do
|
|
6
6
|
let(:middleware) { described_class.new app, nil, options }
|
7
7
|
|
8
8
|
let(:options) do
|
9
|
-
{ host
|
10
|
-
refresh_token
|
11
|
-
client_id
|
12
|
-
client_secret
|
9
|
+
{ :host => 'login.salesforce.com',
|
10
|
+
:refresh_token => 'refresh_token',
|
11
|
+
:client_id => 'client_id',
|
12
|
+
:client_secret => 'client_secret' }
|
13
13
|
end
|
14
14
|
|
15
15
|
it_behaves_like 'authentication middleware' do
|
16
16
|
let(:success_request) do
|
17
|
-
stub_login_request(body
|
18
|
-
"client_id=client_id&client_secret=client_secret")
|
19
|
-
|
17
|
+
stub_login_request(:body => "grant_type=refresh_token&refresh_token=refresh_token&" \
|
18
|
+
"client_id=client_id&client_secret=client_secret").
|
19
|
+
to_return(:status => 200, :body => fixture(:auth_success_response))
|
20
20
|
end
|
21
21
|
|
22
22
|
let(:fail_request) do
|
23
|
-
stub_login_request(body
|
24
|
-
"client_id=client_id&client_secret=client_secret")
|
25
|
-
|
23
|
+
stub_login_request(:body => "grant_type=refresh_token&refresh_token=refresh_token&" \
|
24
|
+
"client_id=client_id&client_secret=client_secret").
|
25
|
+
to_return(:status => 400, :body => fixture(:refresh_error_response))
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -4,7 +4,7 @@ describe Restforce::Middleware::Authentication do
|
|
4
4
|
let(:app) { double('app') }
|
5
5
|
let(:env) { { } }
|
6
6
|
let(:retries) { 3 }
|
7
|
-
let(:options) { { host
|
7
|
+
let(:options) { { :host => 'login.salesforce.com', :authentication_retries => retries } }
|
8
8
|
let(:middleware) { described_class.new app, nil, options }
|
9
9
|
|
10
10
|
describe '.authenticate!' do
|
@@ -29,7 +29,7 @@ describe Restforce::Middleware::Authentication do
|
|
29
29
|
context 'when an exception is thrown' do
|
30
30
|
before do
|
31
31
|
env[:body] = 'foo'
|
32
|
-
env[:request] = {proxy
|
32
|
+
env[:request] = {:proxy => nil}
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'attempts to authenticate' do
|
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Restforce::Middleware::Authorization do
|
4
4
|
let(:app) { double('app') }
|
5
|
-
let(:env) { { request_headers
|
6
|
-
let(:options) { { oauth_token
|
5
|
+
let(:env) { { :request_headers => {} } }
|
6
|
+
let(:options) { { :oauth_token => 'token' } }
|
7
7
|
let(:middleware) { described_class.new app, nil, options }
|
8
8
|
|
9
9
|
before do
|
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Restforce::Middleware::Gzip do
|
4
4
|
let(:app) { double('app') }
|
5
|
-
let(:env) { { request_headers
|
6
|
-
let(:options) { { oauth_token
|
5
|
+
let(:env) { { :request_headers => {}, :response_headers => {} } }
|
6
|
+
let(:options) { { :oauth_token => 'token' } }
|
7
7
|
let(:middleware) { described_class.new app, nil, options }
|
8
8
|
|
9
9
|
# Return a gzipped string.
|
@@ -4,7 +4,7 @@ describe Restforce::Middleware::Logger do
|
|
4
4
|
let(:app) { double('app') }
|
5
5
|
let(:env) { { } }
|
6
6
|
let(:logger) { double('logger') }
|
7
|
-
let(:options) { { host
|
7
|
+
let(:options) { { :host => 'login.salesforce.com', :client_secret => 'foo', :password => 'bar' } }
|
8
8
|
let(:middleware) { described_class.new app, logger, options }
|
9
9
|
|
10
10
|
describe 'logging' do
|
@@ -11,7 +11,7 @@ describe Restforce::Middleware::Mashify do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
context 'when the body contains a records key' do
|
14
|
-
let(:env) { { body
|
14
|
+
let(:env) { { :body => JSON.parse(fixture('sobject/query_success_response')) } }
|
15
15
|
|
16
16
|
it 'converts the response body into a restforce collection' do
|
17
17
|
env[:body].should be_a Restforce::Collection
|
@@ -19,7 +19,7 @@ describe Restforce::Middleware::Mashify do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
context 'when the body does not contain records' do
|
22
|
-
let(:env) { { body
|
22
|
+
let(:env) { { :body => { 'foo' => 'bar' } } }
|
23
23
|
|
24
24
|
it 'does not touch the body' do
|
25
25
|
env[:body].foo.should eq 'bar'
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Restforce::Middleware::RaiseError do
|
4
4
|
let(:app) { double('app') }
|
5
5
|
let(:body) { fixture('sobject/query_error_response') }
|
6
|
-
let(:env) { { status
|
6
|
+
let(:env) { { :status => status, :body => body } }
|
7
7
|
let(:middleware) { described_class.new app }
|
8
8
|
|
9
9
|
describe '.on_complete' do
|
data/spec/lib/sobject_spec.rb
CHANGED
@@ -58,8 +58,8 @@ describe Restforce::SObject do
|
|
58
58
|
|
59
59
|
context 'when an Id is present' do
|
60
60
|
before do
|
61
|
-
hash.merge!(Id
|
62
|
-
@request = stub_api_request 'sobjects/Whizbang/001D000000INjVe', method
|
61
|
+
hash.merge!(:Id => '001D000000INjVe')
|
62
|
+
@request = stub_api_request 'sobjects/Whizbang/001D000000INjVe', :method => :patch, :body => "{\"Checkbox_Label\":false,\"Text_Label\":\"Hi there!\",\"Date_Label\":\"2010-01-01\",\"DateTime_Label\":\"2011-07-07T00:37:00.000+0000\",\"Picklist_Multiselect_Label\":\"four;six\"}"
|
63
63
|
end
|
64
64
|
|
65
65
|
after do
|
@@ -79,8 +79,8 @@ describe Restforce::SObject do
|
|
79
79
|
|
80
80
|
context 'when an Id is present' do
|
81
81
|
before do
|
82
|
-
hash.merge!(Id
|
83
|
-
@request = stub_api_request 'sobjects/Whizbang/001D000000INjVe', method
|
82
|
+
hash.merge!(:Id => '001D000000INjVe')
|
83
|
+
@request = stub_api_request 'sobjects/Whizbang/001D000000INjVe', :method => :delete
|
84
84
|
end
|
85
85
|
|
86
86
|
after do
|
@@ -93,7 +93,7 @@ describe Restforce::SObject do
|
|
93
93
|
|
94
94
|
describe '.describe' do
|
95
95
|
before do
|
96
|
-
@request = stub_api_request 'sobjects/Whizbang/describe', with
|
96
|
+
@request = stub_api_request 'sobjects/Whizbang/describe', :with => 'sobject/sobject_describe_success_response'
|
97
97
|
end
|
98
98
|
|
99
99
|
after do
|
@@ -2,25 +2,25 @@ module FixtureHelpers
|
|
2
2
|
|
3
3
|
def stub_api_request(endpoint, options = {})
|
4
4
|
options = {
|
5
|
-
method
|
6
|
-
status
|
7
|
-
api_version
|
8
|
-
with
|
5
|
+
:method => :get,
|
6
|
+
:status => 200,
|
7
|
+
:api_version => '24.0',
|
8
|
+
:with => nil
|
9
9
|
}.merge(options)
|
10
10
|
|
11
11
|
stub = stub_request(options[:method], %r{/services/data/v#{options[:api_version]}/#{endpoint}})
|
12
|
-
stub = stub.with(body
|
13
|
-
stub = stub.to_return(status
|
12
|
+
stub = stub.with(:body => options[:body]) if options[:body] && !RUBY_VERSION.match(/^1.8/)
|
13
|
+
stub = stub.to_return(:status => options[:status], :body => fixture(options[:with])) if options[:with]
|
14
14
|
stub
|
15
15
|
end
|
16
16
|
|
17
17
|
def stub_login_request(options = {})
|
18
18
|
options = {
|
19
|
-
body
|
19
|
+
:body => nil
|
20
20
|
}.merge(options)
|
21
21
|
|
22
22
|
stub = stub_request(:post, "https://login.salesforce.com/services/oauth2/token")
|
23
|
-
stub = stub.with(body
|
23
|
+
stub = stub.with(:body => options[:body]) if options[:body] && !RUBY_VERSION.match(/^1.8/)
|
24
24
|
stub
|
25
25
|
end
|
26
26
|
|
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: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -96,17 +96,17 @@ dependencies:
|
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
97
97
|
none: false
|
98
98
|
requirements:
|
99
|
-
- -
|
99
|
+
- - '='
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version:
|
101
|
+
version: 0.8.3
|
102
102
|
type: :runtime
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
|
-
- -
|
107
|
+
- - '='
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
109
|
+
version: 0.8.3
|
110
110
|
- !ruby/object:Gem::Dependency
|
111
111
|
name: rspec
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|