restforce 2.5.2 → 2.5.3
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 +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile +1 -0
- data/Gemfile.travis +1 -0
- data/README.md +1 -1
- data/lib/restforce/concerns/api.rb +6 -1
- data/lib/restforce/middleware/authentication.rb +2 -1
- data/lib/restforce/version.rb +1 -1
- data/spec/integration/abstract_client_spec.rb +1 -1
- data/spec/unit/concerns/api_spec.rb +101 -82
- data/spec/unit/middleware/authentication_spec.rb +6 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37d2535283740f9a089e2a1fa91dd856b3047180
|
4
|
+
data.tar.gz: 68d9358e56b9c9150ac504549ad0baa031f1fa25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6968dd3d8edd7559f36225b85325f9b2712836b30cde5e26393e676266013a7267f4e4b36e4273610cb33dda9dea95f8ebff862a021fd817e46528c29e34b04d
|
7
|
+
data.tar.gz: d7049225f2af6b649103a7b86b4d4487c0e4af5a4759db4345473d79562e74889384bee64a96c81980a8c9187ceaa6c78843d233413bf5ce291ea7bb714552d0
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 2.5.3 (April 25, 2017)
|
2
|
+
|
3
|
+
* Raise an error where a custom external ID field name is supplied to `upsert` and `upsert!`, but it is missing from the provided attributes (@velveret)
|
4
|
+
* Use the Restforce client's configured SSL options for authentication requests (@jvdp)
|
5
|
+
* Fix bug where `upsert` and `upsert!` mutate the provided attributes, previously fixed in [v1.5.3](https://github.com/ejholmes/restforce/blob/master/CHANGELOG.md#153-jun-26-2015) (@velveret)
|
6
|
+
|
7
|
+
|
1
8
|
## 2.5.2 (Apr 3, 2017)
|
2
9
|
|
3
10
|
* Ensure `Restforce::Middleware::Logger` is the last Faraday middleware to be called so everything is properly logged (including the effects of the `Gzip` and `CustomHeaders` middlewares which were previously running after it) (@jonnymacs)
|
data/Gemfile
CHANGED
data/Gemfile.travis
CHANGED
data/README.md
CHANGED
@@ -317,7 +317,7 @@ module Restforce
|
|
317
317
|
# Raises an exception if an error is returned from Salesforce.
|
318
318
|
def update!(sobject, attrs)
|
319
319
|
id = attrs.fetch(attrs.keys.find { |k, v| k.to_s.downcase == 'id' }, nil)
|
320
|
-
raise ArgumentError, '
|
320
|
+
raise ArgumentError, 'ID field missing from provided attributes' unless id
|
321
321
|
attrs_without_id = attrs.reject { |k, v| k.to_s.downcase == "id" }
|
322
322
|
api_patch "sobjects/#{sobject}/#{id}", attrs_without_id
|
323
323
|
true
|
@@ -361,8 +361,13 @@ module Restforce
|
|
361
361
|
# error returned if the external ID provided matches multiple records (in which
|
362
362
|
# case the conflicting IDs can be found by looking at the response on the error)
|
363
363
|
def upsert!(sobject, field, attrs)
|
364
|
+
attrs = attrs.dup
|
364
365
|
external_id =
|
365
366
|
extract_case_insensitive_string_or_symbol_key_from_hash!(attrs, field)
|
367
|
+
if field.to_s != "Id" && (external_id.nil? || external_id.strip.empty?)
|
368
|
+
raise ArgumentError, 'Specified external ID field missing from provided ' \
|
369
|
+
'attributes'
|
370
|
+
end
|
366
371
|
|
367
372
|
response =
|
368
373
|
if field.to_s == "Id" && (external_id.nil? || external_id.strip.empty?)
|
data/lib/restforce/version.rb
CHANGED
@@ -133,7 +133,7 @@ shared_examples_for Restforce::AbstractClient do
|
|
133
133
|
describe '.update' do
|
134
134
|
context 'with missing Id' do
|
135
135
|
subject { lambda { client.update('Account', Name: 'Foobar') } }
|
136
|
-
it { should raise_error ArgumentError, '
|
136
|
+
it { should raise_error ArgumentError, 'ID field missing from provided attributes' }
|
137
137
|
end
|
138
138
|
|
139
139
|
context 'with invalid Id' do
|
@@ -282,116 +282,135 @@ describe Restforce::Concerns::API do
|
|
282
282
|
end
|
283
283
|
end
|
284
284
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
subject(:result) { client.create!(sobject, attrs) }
|
289
|
-
|
290
|
-
it 'send an HTTP POST, and returns the id of the record' do
|
291
|
-
response.body.stub(:[]).with('id').and_return('1234')
|
292
|
-
client.should_receive(:api_post).
|
293
|
-
with('sobjects/Whizbang', attrs).
|
294
|
-
and_return(response)
|
295
|
-
expect(result).to eq '1234'
|
285
|
+
context 'methods with attrs' do
|
286
|
+
before do
|
287
|
+
attrs.freeze
|
296
288
|
end
|
297
|
-
end
|
298
289
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
context 'when the id field is present' do
|
305
|
-
let(:attrs) { { id: '1234', StageName: "Call Scheduled" } }
|
290
|
+
describe '.create!' do
|
291
|
+
let(:sobject) { 'Whizbang' }
|
292
|
+
let(:attrs) { Hash.new }
|
293
|
+
subject(:result) { client.create!(sobject, attrs) }
|
306
294
|
|
307
|
-
it '
|
308
|
-
|
309
|
-
|
310
|
-
|
295
|
+
it 'send an HTTP POST, and returns the id of the record' do
|
296
|
+
response.body.stub(:[]).with('id').and_return('1234')
|
297
|
+
client.should_receive(:api_post).
|
298
|
+
with('sobjects/Whizbang', attrs).
|
299
|
+
and_return(response)
|
300
|
+
expect(result).to eq '1234'
|
311
301
|
end
|
312
302
|
end
|
313
303
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
end
|
304
|
+
describe '.update!' do
|
305
|
+
let(:sobject) { 'Whizbang' }
|
306
|
+
let(:attrs) { Hash.new }
|
307
|
+
subject(:result) { client.update!(sobject, attrs) }
|
319
308
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
response.body.stub :[]
|
329
|
-
client.should_receive(:api_patch).
|
330
|
-
with('sobjects/Whizbang/External_ID__c/1234', {}).
|
331
|
-
and_return(response)
|
332
|
-
expect(result).to be_true
|
309
|
+
context 'when the id field is present' do
|
310
|
+
let(:attrs) { { id: '1234', StageName: "Call Scheduled" } }
|
311
|
+
|
312
|
+
it 'sends an HTTP PATCH, and returns true' do
|
313
|
+
client.should_receive(:api_patch).
|
314
|
+
with('sobjects/Whizbang/1234', StageName: "Call Scheduled")
|
315
|
+
expect(result).to be_true
|
316
|
+
end
|
333
317
|
end
|
334
|
-
end
|
335
318
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
and_return(response)
|
342
|
-
expect(result).to eq '4321'
|
319
|
+
context 'when the id field is missing from the attrs' do
|
320
|
+
it "raises an error" do
|
321
|
+
expect { client.update!(sobject, attrs) }.
|
322
|
+
to raise_error(ArgumentError, 'ID field missing from provided attributes')
|
323
|
+
end
|
343
324
|
end
|
344
325
|
end
|
345
326
|
|
346
|
-
|
347
|
-
let(:
|
348
|
-
let(:
|
327
|
+
describe '.upsert!' do
|
328
|
+
let(:sobject) { 'Whizbang' }
|
329
|
+
let(:field) { :External_ID__c }
|
330
|
+
let(:attrs) { { 'External_ID__c' => '1234' } }
|
331
|
+
subject(:result) { client.upsert!(sobject, field, attrs) }
|
349
332
|
|
350
|
-
context '
|
333
|
+
context 'when the record is found and updated' do
|
334
|
+
it 'returns true' do
|
335
|
+
response.body.stub :[]
|
336
|
+
client.should_receive(:api_patch).
|
337
|
+
with('sobjects/Whizbang/External_ID__c/1234', {}).
|
338
|
+
and_return(response)
|
339
|
+
expect(result).to be_true
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
context 'when the record is found and created' do
|
351
344
|
it 'returns the id of the record' do
|
352
345
|
response.body.stub(:[]).with('id').and_return('4321')
|
353
346
|
client.should_receive(:api_patch).
|
354
|
-
with('sobjects/Whizbang/
|
347
|
+
with('sobjects/Whizbang/External_ID__c/1234', {}).
|
355
348
|
and_return(response)
|
356
349
|
expect(result).to eq '4321'
|
357
350
|
end
|
358
351
|
end
|
359
352
|
|
360
|
-
context '
|
361
|
-
let(:attrs) {
|
353
|
+
context 'when the external id field is missing from the attrs' do
|
354
|
+
let(:attrs) { Hash.new }
|
362
355
|
|
363
|
-
it '
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
356
|
+
it 'raises an argument error' do
|
357
|
+
expect { client.upsert!(sobject, field, attrs) }.
|
358
|
+
to raise_error ArgumentError, 'Specified external ID field missing from ' \
|
359
|
+
'provided attributes'
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
context 'when using Id as the attribute' do
|
364
|
+
let(:field) { :Id }
|
365
|
+
let(:attrs) { { 'Id' => '4321' } }
|
366
|
+
|
367
|
+
context 'and the value for Id is provided' do
|
368
|
+
it 'returns the id of the record, and original record still contains id' do
|
369
|
+
response.body.stub(:[]).with('id').and_return('4321')
|
370
|
+
client.should_receive(:api_patch).
|
371
|
+
with('sobjects/Whizbang/Id/4321', {}).
|
372
|
+
and_return(response)
|
373
|
+
expect(result).to eq '4321'
|
374
|
+
expect(attrs).to include('Id' => '4321')
|
375
|
+
end
|
370
376
|
end
|
371
377
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
378
|
+
context 'and no value for Id is provided' do
|
379
|
+
let(:attrs) { { 'External_ID__c' => '1234' } }
|
380
|
+
|
381
|
+
it 'uses POST to create the record' do
|
382
|
+
response.body.stub(:[]).with('id').and_return('4321')
|
383
|
+
client.should_receive(:options).and_return(api_version: 38.0)
|
384
|
+
client.should_receive(:api_post).
|
385
|
+
with('sobjects/Whizbang/Id', attrs).
|
386
|
+
and_return(response)
|
387
|
+
expect(result).to eq '4321'
|
388
|
+
end
|
389
|
+
|
390
|
+
it 'guards functionality for unsupported API versions' do
|
391
|
+
client.should_receive(:options).and_return(api_version: 35.0)
|
392
|
+
expect do
|
393
|
+
client.upsert!(sobject, field, attrs)
|
394
|
+
end.to raise_error Restforce::APIVersionError
|
395
|
+
end
|
377
396
|
end
|
378
397
|
end
|
379
398
|
end
|
380
|
-
end
|
381
399
|
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
400
|
+
describe '.upsert! with multi bytes character' do
|
401
|
+
let(:sobject) { 'Whizbang' }
|
402
|
+
let(:field) { :External_ID__c }
|
403
|
+
let(:attrs) { { 'External_ID__c' => "\u{3042}" } }
|
404
|
+
subject(:result) { client.upsert!(sobject, field, attrs) }
|
405
|
+
|
406
|
+
context 'when the record is found and updated' do
|
407
|
+
it 'returns true' do
|
408
|
+
response.body.stub :[]
|
409
|
+
client.should_receive(:api_patch).
|
410
|
+
with('sobjects/Whizbang/External_ID__c/%E3%81%82', {}).
|
411
|
+
and_return(response)
|
412
|
+
expect(result).to be_true
|
413
|
+
end
|
395
414
|
end
|
396
415
|
end
|
397
416
|
end
|
@@ -5,7 +5,8 @@ describe Restforce::Middleware::Authentication do
|
|
5
5
|
{ host: 'login.salesforce.com',
|
6
6
|
proxy_uri: 'https://not-a-real-site.com',
|
7
7
|
authentication_retries: retries,
|
8
|
-
adapter: :net_http
|
8
|
+
adapter: :net_http,
|
9
|
+
ssl: { version: :TLSv1_2 } }
|
9
10
|
end
|
10
11
|
|
11
12
|
describe '.authenticate!' do
|
@@ -81,5 +82,9 @@ describe Restforce::Middleware::Authentication do
|
|
81
82
|
}
|
82
83
|
end
|
83
84
|
end
|
85
|
+
|
86
|
+
it "should have SSL config set" do
|
87
|
+
connection.ssl[:version].should eq(:TLSv1_2)
|
88
|
+
end
|
84
89
|
end
|
85
90
|
end
|
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.5.
|
4
|
+
version: 2.5.3
|
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: 2017-04-
|
12
|
+
date: 2017-04-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faraday
|