restforce 4.2.1 → 5.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +14 -9
- data/.github/ISSUE_TEMPLATE/unhandled-salesforce-error.md +17 -0
- data/.github/dependabot.yml +19 -0
- data/.rubocop.yml +5 -4
- data/CHANGELOG.md +96 -0
- data/CONTRIBUTING.md +21 -1
- data/Dockerfile +31 -0
- data/Gemfile +10 -7
- data/README.md +94 -21
- data/UPGRADING.md +38 -0
- data/docker-compose.yml +7 -0
- data/lib/restforce/abstract_client.rb +1 -0
- data/lib/restforce/collection.rb +27 -4
- data/lib/restforce/concerns/api.rb +2 -2
- data/lib/restforce/concerns/base.rb +2 -2
- data/lib/restforce/concerns/caching.rb +7 -0
- data/lib/restforce/concerns/composite_api.rb +104 -0
- data/lib/restforce/concerns/picklists.rb +2 -2
- data/lib/restforce/concerns/streaming.rb +1 -3
- data/lib/restforce/config.rb +4 -1
- data/lib/restforce/error_code.rb +647 -0
- data/lib/restforce/file_part.rb +24 -0
- data/lib/restforce/mash.rb +8 -3
- data/lib/restforce/middleware/caching.rb +1 -1
- data/lib/restforce/middleware/logger.rb +8 -7
- data/lib/restforce/middleware/raise_error.rb +3 -4
- data/lib/restforce/middleware.rb +2 -0
- data/lib/restforce/version.rb +1 -1
- data/lib/restforce.rb +6 -7
- data/restforce.gemspec +11 -20
- data/spec/fixtures/sobject/list_view_results_success_response.json +151 -0
- data/spec/integration/abstract_client_spec.rb +41 -32
- data/spec/integration/data/client_spec.rb +6 -2
- data/spec/spec_helper.rb +24 -1
- data/spec/support/client_integration.rb +7 -7
- data/spec/support/concerns.rb +1 -1
- data/spec/support/fixture_helpers.rb +1 -3
- data/spec/support/middleware.rb +1 -2
- data/spec/unit/collection_spec.rb +38 -2
- data/spec/unit/concerns/api_spec.rb +11 -11
- data/spec/unit/concerns/authentication_spec.rb +6 -6
- data/spec/unit/concerns/caching_spec.rb +26 -0
- data/spec/unit/concerns/composite_api_spec.rb +143 -0
- data/spec/unit/concerns/connection_spec.rb +2 -2
- data/spec/unit/concerns/streaming_spec.rb +4 -4
- data/spec/unit/config_spec.rb +1 -1
- data/spec/unit/error_code_spec.rb +61 -0
- data/spec/unit/mash_spec.rb +5 -0
- data/spec/unit/middleware/authentication/jwt_bearer_spec.rb +4 -4
- data/spec/unit/middleware/authentication/password_spec.rb +2 -2
- data/spec/unit/middleware/authentication/token_spec.rb +2 -2
- data/spec/unit/middleware/authentication_spec.rb +11 -5
- data/spec/unit/middleware/gzip_spec.rb +2 -2
- data/spec/unit/middleware/raise_error_spec.rb +29 -10
- data/spec/unit/signed_request_spec.rb +1 -1
- metadata +41 -125
- data/lib/restforce/upload_io.rb +0 -9
@@ -13,7 +13,7 @@ describe Restforce::Collection do
|
|
13
13
|
|
14
14
|
it { should respond_to :each }
|
15
15
|
its(:size) { should eq 1 }
|
16
|
-
its(:has_next_page?) { should
|
16
|
+
its(:has_next_page?) { should be false }
|
17
17
|
it { should have_client client }
|
18
18
|
its(:page_size) { should eq 1 }
|
19
19
|
|
@@ -56,10 +56,46 @@ describe Restforce::Collection do
|
|
56
56
|
should(be_all { |page| expect(page).to be_a Restforce::Collection })
|
57
57
|
end
|
58
58
|
|
59
|
-
its(:has_next_page?) { should
|
59
|
+
its(:has_next_page?) { should be true }
|
60
60
|
it { should(be_all { |record| expect(record).to be_a Restforce::SObject }) }
|
61
61
|
its(:next_page) { should be_a Restforce::Collection }
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
65
|
+
|
66
|
+
describe '#size' do
|
67
|
+
subject(:size) do
|
68
|
+
described_class.new(JSON.parse(fixture(sobject_fixture)), client).size
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when the query response contains a totalSize field' do
|
72
|
+
let(:sobject_fixture) { 'sobject/query_success_response' }
|
73
|
+
|
74
|
+
it { should eq 1 }
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'when the query response contains a size field' do
|
78
|
+
let(:sobject_fixture) { 'sobject/list_view_results_success_response' }
|
79
|
+
|
80
|
+
it { should eq 1 }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#empty?' do
|
85
|
+
subject(:empty?) do
|
86
|
+
described_class.new(JSON.parse(fixture(sobject_fixture)), client).empty?
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'with size 1' do
|
90
|
+
let(:sobject_fixture) { 'sobject/query_success_response' }
|
91
|
+
|
92
|
+
it { should be false }
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'with size 0' do
|
96
|
+
let(:sobject_fixture) { 'sobject/query_empty_response' }
|
97
|
+
|
98
|
+
it { should be true }
|
99
|
+
end
|
100
|
+
end
|
65
101
|
end
|
@@ -11,7 +11,7 @@ describe Restforce::Concerns::API do
|
|
11
11
|
it 'returns the user info from identity url' do
|
12
12
|
identity_url = double('identity_url')
|
13
13
|
response.body.stub(:identity).and_return(identity_url)
|
14
|
-
client.should_receive(:api_get).with.and_return(response)
|
14
|
+
client.should_receive(:api_get).with(no_args).and_return(response)
|
15
15
|
|
16
16
|
identity = double('identity')
|
17
17
|
identity.stub(:body).and_return(identity)
|
@@ -268,7 +268,7 @@ describe Restforce::Concerns::API do
|
|
268
268
|
|
269
269
|
it "delegates to :#{method}!" do
|
270
270
|
client.should_receive(:"#{method}!").
|
271
|
-
with(
|
271
|
+
with(no_args).
|
272
272
|
and_return(response)
|
273
273
|
expect(result).to eq response
|
274
274
|
end
|
@@ -276,7 +276,7 @@ describe Restforce::Concerns::API do
|
|
276
276
|
it 'rescues exceptions' do
|
277
277
|
[Faraday::ClientError].each do |exception_klass|
|
278
278
|
client.should_receive(:"#{method}!").
|
279
|
-
with(
|
279
|
+
with(no_args).
|
280
280
|
and_raise(exception_klass.new(nil))
|
281
281
|
expect(result).to eq false
|
282
282
|
end
|
@@ -314,7 +314,7 @@ describe Restforce::Concerns::API do
|
|
314
314
|
it 'sends an HTTP PATCH, and returns true' do
|
315
315
|
client.should_receive(:api_patch).
|
316
316
|
with('sobjects/Whizbang/1234', StageName: "Call Scheduled")
|
317
|
-
expect(result).to
|
317
|
+
expect(result).to be true
|
318
318
|
end
|
319
319
|
end
|
320
320
|
|
@@ -324,7 +324,7 @@ describe Restforce::Concerns::API do
|
|
324
324
|
it 'sends an HTTP PATCH, and encodes the ID' do
|
325
325
|
client.should_receive(:api_patch).
|
326
326
|
with('sobjects/Whizbang/1234%2F%3Fabc', StageName: "Call Scheduled")
|
327
|
-
expect(result).to
|
327
|
+
expect(result).to be true
|
328
328
|
end
|
329
329
|
end
|
330
330
|
|
@@ -348,7 +348,7 @@ describe Restforce::Concerns::API do
|
|
348
348
|
client.should_receive(:api_patch).
|
349
349
|
with('sobjects/Whizbang/External_ID__c/1234', {}).
|
350
350
|
and_return(response)
|
351
|
-
expect(result).to
|
351
|
+
expect(result).to be true
|
352
352
|
end
|
353
353
|
|
354
354
|
context 'and the response body is a string' do
|
@@ -357,7 +357,7 @@ describe Restforce::Concerns::API do
|
|
357
357
|
client.should_receive(:api_patch).
|
358
358
|
with('sobjects/Whizbang/External_ID__c/1234', {}).
|
359
359
|
and_return(response)
|
360
|
-
expect(result).to
|
360
|
+
expect(result).to be true
|
361
361
|
end
|
362
362
|
end
|
363
363
|
end
|
@@ -431,7 +431,7 @@ describe Restforce::Concerns::API do
|
|
431
431
|
client.should_receive(:api_patch).
|
432
432
|
with('sobjects/Whizbang/External_ID__c/%E3%81%82', {}).
|
433
433
|
and_return(response)
|
434
|
-
expect(result).to
|
434
|
+
expect(result).to be true
|
435
435
|
end
|
436
436
|
end
|
437
437
|
end
|
@@ -448,7 +448,7 @@ describe Restforce::Concerns::API do
|
|
448
448
|
client.should_receive(:api_patch).
|
449
449
|
with('sobjects/Whizbang/External_ID__c/1234', {}).
|
450
450
|
and_return(response)
|
451
|
-
expect(result).to
|
451
|
+
expect(result).to be true
|
452
452
|
end
|
453
453
|
end
|
454
454
|
end
|
@@ -462,7 +462,7 @@ describe Restforce::Concerns::API do
|
|
462
462
|
it 'sends and HTTP delete, and returns true' do
|
463
463
|
client.should_receive(:api_delete).
|
464
464
|
with('sobjects/Whizbang/1234')
|
465
|
-
expect(result).to
|
465
|
+
expect(result).to be true
|
466
466
|
end
|
467
467
|
|
468
468
|
context 'when the id field contains special characters' do
|
@@ -471,7 +471,7 @@ describe Restforce::Concerns::API do
|
|
471
471
|
it 'sends an HTTP delete, and encodes the ID' do
|
472
472
|
client.should_receive(:api_delete).
|
473
473
|
with('sobjects/Whizbang/1234%2F%3Fabc')
|
474
|
-
expect(result).to
|
474
|
+
expect(result).to be true
|
475
475
|
end
|
476
476
|
end
|
477
477
|
end
|
@@ -80,11 +80,11 @@ describe Restforce::Concerns::Authentication do
|
|
80
80
|
client_secret: 'secret' }
|
81
81
|
end
|
82
82
|
|
83
|
-
it { should
|
83
|
+
it { should be_truthy }
|
84
84
|
end
|
85
85
|
|
86
86
|
context 'when username and password options are not provided' do
|
87
|
-
it { should_not
|
87
|
+
it { should_not be_truthy }
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
@@ -103,11 +103,11 @@ describe Restforce::Concerns::Authentication do
|
|
103
103
|
client_secret: 'secret' }
|
104
104
|
end
|
105
105
|
|
106
|
-
it { should
|
106
|
+
it { should be_truthy }
|
107
107
|
end
|
108
108
|
|
109
109
|
context 'when oauth options are not provided' do
|
110
|
-
it { should_not
|
110
|
+
it { should_not be true }
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
@@ -128,11 +128,11 @@ describe Restforce::Concerns::Authentication do
|
|
128
128
|
client_id: 'client' }
|
129
129
|
end
|
130
130
|
|
131
|
-
it { should
|
131
|
+
it { should be_truthy }
|
132
132
|
end
|
133
133
|
|
134
134
|
context 'when jwt options are not provided' do
|
135
|
-
it { should_not
|
135
|
+
it { should_not be true }
|
136
136
|
end
|
137
137
|
end
|
138
138
|
end
|
@@ -28,4 +28,30 @@ describe Restforce::Concerns::Caching do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
31
|
+
|
32
|
+
describe '.with_caching' do
|
33
|
+
let(:options) { double('Options') }
|
34
|
+
|
35
|
+
before do
|
36
|
+
client.stub options: options
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'runs the block with caching enabled' do
|
40
|
+
options.should_receive(:[]=).with(:use_cache, true)
|
41
|
+
options.should_receive(:[]=).with(:use_cache, false)
|
42
|
+
expect { |b| client.with_caching(&b) }.to yield_control
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when an exception is raised' do
|
46
|
+
it 'ensures the :use_cache is set to false' do
|
47
|
+
options.should_receive(:[]=).with(:use_cache, true)
|
48
|
+
options.should_receive(:[]=).with(:use_cache, false)
|
49
|
+
expect {
|
50
|
+
client.with_caching do
|
51
|
+
raise 'Foo'
|
52
|
+
end
|
53
|
+
}.to raise_error 'Foo'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
31
57
|
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Restforce::Concerns::CompositeAPI do
|
6
|
+
let(:endpoint) { 'composite' }
|
7
|
+
|
8
|
+
before do
|
9
|
+
client.should_receive(:options).and_return(api_version: 38.0)
|
10
|
+
end
|
11
|
+
|
12
|
+
shared_examples_for 'composite requests' do
|
13
|
+
it '#create' do
|
14
|
+
client.
|
15
|
+
should_receive(:api_post).
|
16
|
+
with(endpoint, { compositeRequest: [
|
17
|
+
{
|
18
|
+
method: 'POST',
|
19
|
+
url: '/services/data/v38.0/sobjects/Object',
|
20
|
+
body: { name: 'test' },
|
21
|
+
referenceId: 'create_ref'
|
22
|
+
}
|
23
|
+
], allOrNone: all_or_none, collateSubrequests: false }.to_json).
|
24
|
+
and_return(response)
|
25
|
+
|
26
|
+
client.send(method) do |subrequests|
|
27
|
+
subrequests.create('Object', 'create_ref', name: 'test')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it '#update' do
|
32
|
+
client.
|
33
|
+
should_receive(:api_post).
|
34
|
+
with(endpoint, { compositeRequest: [
|
35
|
+
{
|
36
|
+
method: 'PATCH',
|
37
|
+
url: '/services/data/v38.0/sobjects/Object/123',
|
38
|
+
body: { name: 'test' },
|
39
|
+
referenceId: 'update_ref'
|
40
|
+
}
|
41
|
+
], allOrNone: all_or_none, collateSubrequests: false }.to_json).
|
42
|
+
and_return(response)
|
43
|
+
|
44
|
+
client.send(method) do |subrequests|
|
45
|
+
subrequests.update('Object', 'update_ref', id: '123', name: 'test')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it '#destroy' do
|
50
|
+
client.
|
51
|
+
should_receive(:api_post).
|
52
|
+
with(endpoint, { compositeRequest: [
|
53
|
+
{
|
54
|
+
method: 'DELETE',
|
55
|
+
url: '/services/data/v38.0/sobjects/Object/123',
|
56
|
+
referenceId: 'destroy_ref'
|
57
|
+
}
|
58
|
+
], allOrNone: all_or_none, collateSubrequests: false }.to_json).
|
59
|
+
and_return(response)
|
60
|
+
|
61
|
+
client.send(method) do |subrequests|
|
62
|
+
subrequests.destroy('Object', 'destroy_ref', '123')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
it '#upsert' do
|
67
|
+
client.
|
68
|
+
should_receive(:api_post).
|
69
|
+
with(endpoint, { compositeRequest: [
|
70
|
+
{
|
71
|
+
method: 'PATCH',
|
72
|
+
url: '/services/data/v38.0/sobjects/Object/extIdField__c/456',
|
73
|
+
body: { name: 'test' },
|
74
|
+
referenceId: 'upsert_ref'
|
75
|
+
}
|
76
|
+
], allOrNone: all_or_none, collateSubrequests: false }.to_json).
|
77
|
+
and_return(response)
|
78
|
+
|
79
|
+
client.send(method) do |subrequests|
|
80
|
+
subrequests.upsert('Object', 'upsert_ref', 'extIdField__c',
|
81
|
+
extIdField__c: '456', name: 'test')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'multiple subrequests' do
|
86
|
+
client.
|
87
|
+
should_receive(:api_post).
|
88
|
+
with(endpoint, { compositeRequest: [
|
89
|
+
{
|
90
|
+
method: 'POST',
|
91
|
+
url: '/services/data/v38.0/sobjects/Object',
|
92
|
+
body: { name: 'test' },
|
93
|
+
referenceId: 'create_ref'
|
94
|
+
},
|
95
|
+
{
|
96
|
+
method: 'PATCH',
|
97
|
+
url: '/services/data/v38.0/sobjects/Object/123',
|
98
|
+
body: { name: 'test' },
|
99
|
+
referenceId: 'update_ref'
|
100
|
+
},
|
101
|
+
{
|
102
|
+
method: 'DELETE',
|
103
|
+
url: '/services/data/v38.0/sobjects/Object/123',
|
104
|
+
referenceId: 'destroy_ref'
|
105
|
+
}
|
106
|
+
], allOrNone: all_or_none, collateSubrequests: false }.to_json).
|
107
|
+
and_return(response)
|
108
|
+
|
109
|
+
client.send(method) do |subrequests|
|
110
|
+
subrequests.create('Object', 'create_ref', name: 'test')
|
111
|
+
subrequests.update('Object', 'update_ref', id: '123', name: 'test')
|
112
|
+
subrequests.destroy('Object', 'destroy_ref', '123')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'fails if more than 25 requests' do
|
117
|
+
expect do
|
118
|
+
client.send(method) do |subrequests|
|
119
|
+
26.times do |i|
|
120
|
+
subrequests.upsert('Object', "upsert_ref_#{i}", 'extIdField__c',
|
121
|
+
extIdField__c: '456', name: 'test')
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end.to raise_error(ArgumentError)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe '#composite' do
|
129
|
+
let(:method) { :composite }
|
130
|
+
let(:all_or_none) { false }
|
131
|
+
let(:response) { double('Faraday::Response', body: { 'compositeResponse' => [] }) }
|
132
|
+
it_behaves_like 'composite requests'
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '#composite!' do
|
136
|
+
let(:method) { :composite! }
|
137
|
+
let(:all_or_none) { true }
|
138
|
+
let(:response) do
|
139
|
+
double('Faraday::Response', body: { 'compositeResponse' => [] })
|
140
|
+
end
|
141
|
+
it_behaves_like 'composite requests'
|
142
|
+
end
|
143
|
+
end
|
@@ -73,9 +73,9 @@ describe Restforce::Concerns::Connection do
|
|
73
73
|
Restforce.stub(log?: true)
|
74
74
|
end
|
75
75
|
|
76
|
-
it "must always be used
|
76
|
+
it "must always be used as the last handler" do
|
77
77
|
client.middleware.handlers.reverse.index(Restforce::Middleware::Logger).
|
78
|
-
should eq
|
78
|
+
should eq 0
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
@@ -13,10 +13,10 @@ describe Restforce::Concerns::Streaming, event_machine: true do
|
|
13
13
|
it 'subscribes to the topics with faye' do
|
14
14
|
faye_double.
|
15
15
|
should_receive(:subscribe).
|
16
|
-
with(channels
|
16
|
+
with(channels)
|
17
17
|
client.stub faye: faye_double
|
18
18
|
|
19
|
-
client.subscription(channels
|
19
|
+
client.subscription(channels)
|
20
20
|
end
|
21
21
|
|
22
22
|
context "replay_handlers" do
|
@@ -87,7 +87,7 @@ describe Restforce::Concerns::Streaming, event_machine: true do
|
|
87
87
|
end
|
88
88
|
|
89
89
|
it 'connects to the streaming api' do
|
90
|
-
client.stub authenticate!:
|
90
|
+
client.stub authenticate!: double(access_token: 'secret2')
|
91
91
|
faye_double = double('Faye::Client')
|
92
92
|
Faye::Client.
|
93
93
|
should_receive(:new).
|
@@ -110,7 +110,7 @@ describe Restforce::Concerns::Streaming, event_machine: true do
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
113
|
-
describe
|
113
|
+
describe "ReplayExtension" do
|
114
114
|
let(:handlers) { {} }
|
115
115
|
let(:extension) { Restforce::Concerns::Streaming::ReplayExtension.new(handlers) }
|
116
116
|
|
data/spec/unit/config_spec.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Restforce::ErrorCode do
|
6
|
+
describe "mapping of error codes to classes" do
|
7
|
+
subject(:error_exception_classes) { described_class::ERROR_EXCEPTION_CLASSES }
|
8
|
+
|
9
|
+
let(:exception_classes) do
|
10
|
+
described_class.constants.
|
11
|
+
map { |constant_name| described_class.const_get(constant_name) }.
|
12
|
+
select { |constant| constant.is_a?(Class) }
|
13
|
+
end
|
14
|
+
|
15
|
+
it "maps all defined exception classes to an error code" do
|
16
|
+
exception_classes.each do |exception_class|
|
17
|
+
expect(error_exception_classes.values).to include(exception_class)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "maps all error codes to a defined exception class" do
|
22
|
+
error_exception_classes.each_value do |mapped_exception_class|
|
23
|
+
expect(exception_classes).to include(mapped_exception_class)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '.get_exception_class' do
|
29
|
+
context 'when a non-existent error code is looked up' do
|
30
|
+
let(:new_error_code) { 'ANOTHER_NEW_ERROR_CODE' }
|
31
|
+
subject { described_class.get_exception_class(new_error_code) }
|
32
|
+
|
33
|
+
it { should be Restforce::ResponseError }
|
34
|
+
|
35
|
+
it 'outputs a warning' do
|
36
|
+
expect(Warning).to receive(:warn)
|
37
|
+
subject
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when a known error code is looked up' do
|
42
|
+
let(:existing_error_code) { "ALL_OR_NONE_OPERATION_ROLLED_BACK" }
|
43
|
+
let(:existing_error) { described_class::AllOrNoneOperationRolledBack }
|
44
|
+
|
45
|
+
subject do
|
46
|
+
described_class.get_exception_class(existing_error_code)
|
47
|
+
end
|
48
|
+
|
49
|
+
it { should < Restforce::ResponseError }
|
50
|
+
|
51
|
+
it 'returns existing error' do
|
52
|
+
should be(existing_error)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'does not output a warning' do
|
56
|
+
expect(Warning).to_not receive(:warn)
|
57
|
+
subject
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/spec/unit/mash_spec.rb
CHANGED
@@ -33,6 +33,11 @@ describe Restforce::Mash do
|
|
33
33
|
let(:input) { { 'attributes' => { 'type' => 'Document' } } }
|
34
34
|
it { should eq Restforce::Document }
|
35
35
|
end
|
36
|
+
|
37
|
+
context 'when the attributes value is nil' do
|
38
|
+
let(:input) { { 'attributes' => nil } }
|
39
|
+
it { should eq Restforce::SObject }
|
40
|
+
end
|
36
41
|
end
|
37
42
|
|
38
43
|
context 'else' do
|
@@ -17,14 +17,14 @@ describe Restforce::Middleware::Authentication::JWTBearer do
|
|
17
17
|
let(:success_request) do
|
18
18
|
stub_login_request(
|
19
19
|
body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
|
20
|
-
|
20
|
+
"assertion=abc1234567890"
|
21
21
|
).to_return(status: 200, body: fixture(:auth_success_response))
|
22
22
|
end
|
23
23
|
|
24
24
|
let(:fail_request) do
|
25
25
|
stub_login_request(
|
26
26
|
body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
|
27
|
-
|
27
|
+
"assertion=abc1234567890"
|
28
28
|
).to_return(status: 400, body: fixture(:refresh_error_response))
|
29
29
|
end
|
30
30
|
end
|
@@ -47,14 +47,14 @@ describe Restforce::Middleware::Authentication::JWTBearer do
|
|
47
47
|
let(:success_request) do
|
48
48
|
stub_login_request(
|
49
49
|
body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
|
50
|
-
|
50
|
+
"assertion=abc1234567890"
|
51
51
|
).to_return(status: 200, body: fixture(:auth_success_response))
|
52
52
|
end
|
53
53
|
|
54
54
|
let(:fail_request) do
|
55
55
|
stub_login_request(
|
56
56
|
body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
|
57
|
-
|
57
|
+
"assertion=abc1234567890"
|
58
58
|
).to_return(status: 400, body: fixture(:refresh_error_response))
|
59
59
|
end
|
60
60
|
end
|
@@ -17,14 +17,14 @@ describe Restforce::Middleware::Authentication::Password do
|
|
17
17
|
let(:success_request) do
|
18
18
|
stub_login_request(
|
19
19
|
body: "grant_type=password&client_id=client_id&client_secret=client_secret" \
|
20
|
-
|
20
|
+
"&username=foo&password=barsecurity_token"
|
21
21
|
).to_return(status: 200, body: fixture(:auth_success_response))
|
22
22
|
end
|
23
23
|
|
24
24
|
let(:fail_request) do
|
25
25
|
stub_login_request(
|
26
26
|
body: "grant_type=password&client_id=client_id&client_secret=client_secret" \
|
27
|
-
|
27
|
+
"&username=foo&password=barsecurity_token"
|
28
28
|
).to_return(status: 400, body: fixture(:auth_error_response))
|
29
29
|
end
|
30
30
|
end
|
@@ -15,14 +15,14 @@ describe Restforce::Middleware::Authentication::Token do
|
|
15
15
|
let(:success_request) do
|
16
16
|
stub_login_request(
|
17
17
|
body: "grant_type=refresh_token&refresh_token=refresh_token&" \
|
18
|
-
|
18
|
+
"client_id=client_id&client_secret=client_secret"
|
19
19
|
).to_return(status: 200, body: fixture(:auth_success_response))
|
20
20
|
end
|
21
21
|
|
22
22
|
let(:fail_request) do
|
23
23
|
stub_login_request(
|
24
24
|
body: "grant_type=refresh_token&refresh_token=refresh_token&" \
|
25
|
-
|
25
|
+
"client_id=client_id&client_secret=client_secret"
|
26
26
|
).to_return(status: 400, body: fixture(:refresh_error_response))
|
27
27
|
end
|
28
28
|
end
|
@@ -8,7 +8,9 @@ describe Restforce::Middleware::Authentication do
|
|
8
8
|
proxy_uri: 'https://not-a-real-site.com',
|
9
9
|
authentication_retries: retries,
|
10
10
|
adapter: :net_http,
|
11
|
+
# rubocop:disable Naming/VariableNumber
|
11
12
|
ssl: { version: :TLSv1_2 } }
|
13
|
+
# rubocop:enable Naming/VariableNumber
|
12
14
|
end
|
13
15
|
|
14
16
|
describe '.authenticate!' do
|
@@ -57,10 +59,10 @@ describe Restforce::Middleware::Authentication do
|
|
57
59
|
end
|
58
60
|
|
59
61
|
its(:handlers) {
|
60
|
-
should include FaradayMiddleware::ParseJson
|
61
|
-
Faraday::Adapter::NetHttp
|
62
|
+
should include FaradayMiddleware::ParseJson
|
62
63
|
}
|
63
64
|
its(:handlers) { should_not include Restforce::Middleware::Logger }
|
65
|
+
its(:adapter) { should eq Faraday::Adapter::NetHttp }
|
64
66
|
end
|
65
67
|
|
66
68
|
context 'with logging enabled' do
|
@@ -70,8 +72,9 @@ describe Restforce::Middleware::Authentication do
|
|
70
72
|
|
71
73
|
its(:handlers) {
|
72
74
|
should include FaradayMiddleware::ParseJson,
|
73
|
-
Restforce::Middleware::Logger
|
75
|
+
Restforce::Middleware::Logger
|
74
76
|
}
|
77
|
+
its(:adapter) { should eq Faraday::Adapter::NetHttp }
|
75
78
|
end
|
76
79
|
|
77
80
|
context 'with specified adapter' do
|
@@ -80,13 +83,16 @@ describe Restforce::Middleware::Authentication do
|
|
80
83
|
end
|
81
84
|
|
82
85
|
its(:handlers) {
|
83
|
-
should include FaradayMiddleware::ParseJson
|
86
|
+
should include FaradayMiddleware::ParseJson
|
84
87
|
}
|
88
|
+
its(:adapter) { should eq Faraday::Adapter::Typhoeus }
|
85
89
|
end
|
86
90
|
end
|
87
91
|
|
88
92
|
it "should have SSL config set" do
|
93
|
+
# rubocop:disable Naming/VariableNumber
|
89
94
|
connection.ssl[:version].should eq(:TLSv1_2)
|
95
|
+
# rubocop:enable Naming/VariableNumber
|
90
96
|
end
|
91
97
|
end
|
92
98
|
|
@@ -94,7 +100,7 @@ describe Restforce::Middleware::Authentication do
|
|
94
100
|
context 'when response.body is present' do
|
95
101
|
let(:response) {
|
96
102
|
Faraday::Response.new(
|
97
|
-
|
103
|
+
response_body: { 'error' => 'error', 'error_description' => 'description' },
|
98
104
|
status: 401
|
99
105
|
)
|
100
106
|
}
|
@@ -58,11 +58,11 @@ describe Restforce::Middleware::Gzip do
|
|
58
58
|
env[:response_headers]['Content-Encoding'] = 'gzip'
|
59
59
|
end
|
60
60
|
|
61
|
-
it { should
|
61
|
+
it { should be true }
|
62
62
|
end
|
63
63
|
|
64
64
|
context 'when not gzipped' do
|
65
|
-
it { should
|
65
|
+
it { should be false }
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|