restforce 5.0.6 → 6.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +4 -13
- data/.github/funding.yml +1 -0
- data/.github/workflows/build.yml +23 -0
- data/.github/workflows/faraday.yml +27 -0
- data/.rubocop.yml +2 -2
- data/CHANGELOG.md +68 -0
- data/Gemfile +15 -6
- data/README.md +61 -7
- data/UPGRADING.md +29 -0
- data/lib/restforce/abstract_client.rb +1 -0
- data/lib/restforce/collection.rb +20 -2
- data/lib/restforce/concerns/api.rb +2 -1
- data/lib/restforce/concerns/base.rb +2 -2
- data/lib/restforce/concerns/composite_api.rb +104 -0
- data/lib/restforce/concerns/connection.rb +1 -1
- data/lib/restforce/concerns/picklists.rb +1 -1
- data/lib/restforce/config.rb +12 -10
- data/lib/restforce/error_code.rb +30 -9
- data/lib/restforce/file_part.rb +12 -4
- data/lib/restforce/middleware/authentication.rb +1 -0
- data/lib/restforce/middleware/caching.rb +140 -15
- data/lib/restforce/middleware/gzip.rb +4 -0
- data/lib/restforce/middleware/json_request.rb +90 -0
- data/lib/restforce/middleware/json_response.rb +85 -0
- data/lib/restforce/middleware/logger.rb +6 -2
- data/lib/restforce/middleware/raise_error.rb +10 -1
- data/lib/restforce/version.rb +1 -1
- data/lib/restforce.rb +11 -7
- data/restforce.gemspec +8 -16
- data/spec/fixtures/sobject/list_view_results_success_response.json +151 -0
- data/spec/integration/abstract_client_spec.rb +42 -30
- data/spec/integration/data/client_spec.rb +6 -2
- data/spec/spec_helper.rb +10 -0
- data/spec/support/client_integration.rb +7 -7
- data/spec/support/concerns.rb +1 -1
- data/spec/support/middleware.rb +1 -2
- data/spec/unit/collection_spec.rb +22 -4
- data/spec/unit/concerns/api_spec.rb +22 -15
- data/spec/unit/concerns/authentication_spec.rb +6 -6
- data/spec/unit/concerns/base_spec.rb +1 -1
- data/spec/unit/concerns/composite_api_spec.rb +169 -0
- data/spec/unit/concerns/connection_spec.rb +1 -1
- data/spec/unit/concerns/streaming_spec.rb +4 -4
- data/spec/unit/config_spec.rb +2 -2
- data/spec/unit/middleware/authentication/jwt_bearer_spec.rb +24 -8
- data/spec/unit/middleware/authentication/password_spec.rb +12 -4
- data/spec/unit/middleware/authentication/token_spec.rb +12 -4
- data/spec/unit/middleware/authentication_spec.rb +8 -8
- data/spec/unit/middleware/authorization_spec.rb +5 -1
- data/spec/unit/middleware/custom_headers_spec.rb +6 -2
- data/spec/unit/middleware/gzip_spec.rb +60 -16
- data/spec/unit/middleware/instance_url_spec.rb +2 -2
- data/spec/unit/middleware/logger_spec.rb +1 -1
- data/spec/unit/middleware/raise_error_spec.rb +20 -10
- data/spec/unit/sobject_spec.rb +9 -5
- metadata +55 -172
- data/.circleci/config.yml +0 -56
@@ -0,0 +1,151 @@
|
|
1
|
+
{
|
2
|
+
"columns" : [ {
|
3
|
+
"ascendingLabel" : "Z-A",
|
4
|
+
"descendingLabel" : "A-Z",
|
5
|
+
"fieldNameOrPath" : "Name",
|
6
|
+
"hidden" : false,
|
7
|
+
"label" : "Account Name",
|
8
|
+
"selectListItem" : "Name",
|
9
|
+
"sortDirection" : "ascending",
|
10
|
+
"sortIndex" : 0,
|
11
|
+
"sortable" : true,
|
12
|
+
"type" : "string"
|
13
|
+
}, {
|
14
|
+
"ascendingLabel" : "Z-A",
|
15
|
+
"descendingLabel" : "A-Z",
|
16
|
+
"fieldNameOrPath" : "Site",
|
17
|
+
"hidden" : false,
|
18
|
+
"label" : "Account Site",
|
19
|
+
"selectListItem" : "Site",
|
20
|
+
"sortDirection" : null,
|
21
|
+
"sortIndex" : null,
|
22
|
+
"sortable" : true,
|
23
|
+
"type" : "string"
|
24
|
+
}, {
|
25
|
+
"ascendingLabel" : "Z-A",
|
26
|
+
"descendingLabel" : "A-Z",
|
27
|
+
"fieldNameOrPath" : "BillingState",
|
28
|
+
"hidden" : false,
|
29
|
+
"label" : "Billing State/Province",
|
30
|
+
"selectListItem" : "BillingState",
|
31
|
+
"sortDirection" : null,
|
32
|
+
"sortIndex" : null,
|
33
|
+
"sortable" : true,
|
34
|
+
"type" : "string"
|
35
|
+
}, {
|
36
|
+
"ascendingLabel" : "9-0",
|
37
|
+
"descendingLabel" : "0-9",
|
38
|
+
"fieldNameOrPath" : "Phone",
|
39
|
+
"hidden" : false,
|
40
|
+
"label" : "Phone",
|
41
|
+
"selectListItem" : "Phone",
|
42
|
+
"sortDirection" : null,
|
43
|
+
"sortIndex" : null,
|
44
|
+
"sortable" : true,
|
45
|
+
"type" : "phone"
|
46
|
+
}, {
|
47
|
+
"ascendingLabel" : "Low to High",
|
48
|
+
"descendingLabel" : "High to Low",
|
49
|
+
"fieldNameOrPath" : "Type",
|
50
|
+
"hidden" : false,
|
51
|
+
"label" : "Type",
|
52
|
+
"selectListItem" : "toLabel(Type)",
|
53
|
+
"sortDirection" : null,
|
54
|
+
"sortIndex" : null,
|
55
|
+
"sortable" : true,
|
56
|
+
"type" : "picklist"
|
57
|
+
}, {
|
58
|
+
"ascendingLabel" : "Z-A",
|
59
|
+
"descendingLabel" : "A-Z",
|
60
|
+
"fieldNameOrPath" : "Owner.Alias",
|
61
|
+
"hidden" : false,
|
62
|
+
"label" : "Account Owner Alias",
|
63
|
+
"selectListItem" : "Owner.Alias",
|
64
|
+
"sortDirection" : null,
|
65
|
+
"sortIndex" : null,
|
66
|
+
"sortable" : true,
|
67
|
+
"type" : "string"
|
68
|
+
}, {
|
69
|
+
"ascendingLabel" : null,
|
70
|
+
"descendingLabel" : null,
|
71
|
+
"fieldNameOrPath" : "Id",
|
72
|
+
"hidden" : true,
|
73
|
+
"label" : "Account ID",
|
74
|
+
"selectListItem" : "Id",
|
75
|
+
"sortDirection" : null,
|
76
|
+
"sortIndex" : null,
|
77
|
+
"sortable" : false,
|
78
|
+
"type" : "id"
|
79
|
+
}, {
|
80
|
+
"ascendingLabel" : null,
|
81
|
+
"descendingLabel" : null,
|
82
|
+
"fieldNameOrPath" : "CreatedDate",
|
83
|
+
"hidden" : true,
|
84
|
+
"label" : "Created Date",
|
85
|
+
"selectListItem" : "CreatedDate",
|
86
|
+
"sortDirection" : null,
|
87
|
+
"sortIndex" : null,
|
88
|
+
"sortable" : false,
|
89
|
+
"type" : "datetime"
|
90
|
+
}, {
|
91
|
+
"ascendingLabel" : null,
|
92
|
+
"descendingLabel" : null,
|
93
|
+
"fieldNameOrPath" : "LastModifiedDate",
|
94
|
+
"hidden" : true,
|
95
|
+
"label" : "Last Modified Date",
|
96
|
+
"selectListItem" : "LastModifiedDate",
|
97
|
+
"sortDirection" : null,
|
98
|
+
"sortIndex" : null,
|
99
|
+
"sortable" : false,
|
100
|
+
"type" : "datetime"
|
101
|
+
}, {
|
102
|
+
"ascendingLabel" : null,
|
103
|
+
"descendingLabel" : null,
|
104
|
+
"fieldNameOrPath" : "SystemModstamp",
|
105
|
+
"hidden" : true,
|
106
|
+
"label" : "System Modstamp",
|
107
|
+
"selectListItem" : "SystemModstamp",
|
108
|
+
"sortDirection" : null,
|
109
|
+
"sortIndex" : null,
|
110
|
+
"sortable" : false,
|
111
|
+
"type" : "datetime"
|
112
|
+
} ],
|
113
|
+
"developerName" : "MyAccounts",
|
114
|
+
"done" : true,
|
115
|
+
"id" : "00BD0000005WcCN",
|
116
|
+
"label" : "My Accounts",
|
117
|
+
"records" : [ {
|
118
|
+
"columns" : [ {
|
119
|
+
"fieldNameOrPath" : "Name",
|
120
|
+
"value" : "Burlington Textiles Corp of America"
|
121
|
+
}, {
|
122
|
+
"fieldNameOrPath" : "Site",
|
123
|
+
"value" : null
|
124
|
+
}, {
|
125
|
+
"fieldNameOrPath" : "BillingState",
|
126
|
+
"value" : "NC"
|
127
|
+
}, {
|
128
|
+
"fieldNameOrPath" : "Phone",
|
129
|
+
"value" : "(336) 222-7000"
|
130
|
+
}, {
|
131
|
+
"fieldNameOrPath" : "Type",
|
132
|
+
"value" : "Customer - Direct"
|
133
|
+
}, {
|
134
|
+
"fieldNameOrPath" : "Owner.Alias",
|
135
|
+
"value" : "TUser"
|
136
|
+
}, {
|
137
|
+
"fieldNameOrPath" : "Id",
|
138
|
+
"value" : "001D000000JliSTIAZ"
|
139
|
+
}, {
|
140
|
+
"fieldNameOrPath" : "CreatedDate",
|
141
|
+
"value" : "Fri Aug 01 21:15:46 GMT 2014"
|
142
|
+
}, {
|
143
|
+
"fieldNameOrPath" : "LastModifiedDate",
|
144
|
+
"value" : "Fri Aug 01 21:15:46 GMT 2014"
|
145
|
+
}, {
|
146
|
+
"fieldNameOrPath" : "SystemModstamp",
|
147
|
+
"value" : "Fri Aug 01 21:15:46 GMT 2014"
|
148
|
+
} ]
|
149
|
+
} ],
|
150
|
+
"size" : 1
|
151
|
+
}
|
@@ -129,25 +129,25 @@ shared_examples_for Restforce::AbstractClient do
|
|
129
129
|
JSON.parse(fixture('sobject/delete_error_response'))
|
130
130
|
end
|
131
131
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
end
|
132
|
+
it "raises Faraday::ResourceNotFound" do
|
133
|
+
expect { client.update!('Account', Id: '001D000000INjVe', Name: 'Foobar') }.
|
134
|
+
to raise_error do |exception|
|
135
|
+
expect(exception).to be_a(Faraday::ResourceNotFound)
|
137
136
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
)
|
143
|
-
}
|
137
|
+
expect(exception.message).
|
138
|
+
to start_with("#{error.first['errorCode']}: #{error.first['message']}")
|
139
|
+
end
|
140
|
+
end
|
144
141
|
end
|
145
142
|
end
|
146
143
|
|
147
144
|
describe '.update' do
|
148
145
|
context 'with missing Id' do
|
149
146
|
subject { lambda { client.update('Account', Name: 'Foobar') } }
|
150
|
-
it {
|
147
|
+
it {
|
148
|
+
expect { subject.call }.
|
149
|
+
to raise_error ArgumentError, 'ID field missing from provided attributes'
|
150
|
+
}
|
151
151
|
end
|
152
152
|
|
153
153
|
context 'with invalid Id' do
|
@@ -158,7 +158,7 @@ shared_examples_for Restforce::AbstractClient do
|
|
158
158
|
fixture: 'sobject/delete_error_response'
|
159
159
|
|
160
160
|
subject { client.update('Account', Id: '001D000000INjVe', Name: 'Foobar') }
|
161
|
-
it { should
|
161
|
+
it { should be false }
|
162
162
|
end
|
163
163
|
|
164
164
|
context 'with success' do
|
@@ -172,7 +172,7 @@ shared_examples_for Restforce::AbstractClient do
|
|
172
172
|
client.update('Account', key => '001D000000INjVe', :Name => 'Foobar')
|
173
173
|
end
|
174
174
|
|
175
|
-
it { should
|
175
|
+
it { should be true }
|
176
176
|
end
|
177
177
|
end
|
178
178
|
end
|
@@ -191,7 +191,7 @@ shared_examples_for Restforce::AbstractClient do
|
|
191
191
|
Name: 'Foobar')
|
192
192
|
end
|
193
193
|
|
194
|
-
it { should
|
194
|
+
it { should be true }
|
195
195
|
end
|
196
196
|
|
197
197
|
context 'with string external Id key' do
|
@@ -200,7 +200,7 @@ shared_examples_for Restforce::AbstractClient do
|
|
200
200
|
'Name' => 'Foobar')
|
201
201
|
end
|
202
202
|
|
203
|
-
it { should
|
203
|
+
it { should be true }
|
204
204
|
end
|
205
205
|
end
|
206
206
|
|
@@ -251,20 +251,20 @@ shared_examples_for Restforce::AbstractClient do
|
|
251
251
|
status: 404
|
252
252
|
|
253
253
|
subject { lambda { destroy! } }
|
254
|
-
it {
|
254
|
+
it { expect { subject.call }.to raise_error Faraday::ResourceNotFound }
|
255
255
|
end
|
256
256
|
|
257
257
|
context 'with success' do
|
258
258
|
requests 'sobjects/Account/001D000000INjVe', method: :delete
|
259
259
|
|
260
|
-
it { should
|
260
|
+
it { should be true }
|
261
261
|
end
|
262
262
|
|
263
263
|
context 'with a space in the id' do
|
264
264
|
subject(:destroy!) { client.destroy!('Account', '001D000000 INjVe') }
|
265
265
|
requests 'sobjects/Account/001D000000%20INjVe', method: :delete
|
266
266
|
|
267
|
-
it { should
|
267
|
+
it { should be true }
|
268
268
|
end
|
269
269
|
end
|
270
270
|
|
@@ -277,13 +277,13 @@ shared_examples_for Restforce::AbstractClient do
|
|
277
277
|
method: :delete,
|
278
278
|
status: 404
|
279
279
|
|
280
|
-
it { should
|
280
|
+
it { should be false }
|
281
281
|
end
|
282
282
|
|
283
283
|
context 'with success' do
|
284
284
|
requests 'sobjects/Account/001D000000INjVe', method: :delete
|
285
285
|
|
286
|
-
it { should
|
286
|
+
it { should be true }
|
287
287
|
end
|
288
288
|
end
|
289
289
|
|
@@ -368,9 +368,13 @@ shared_examples_for Restforce::AbstractClient do
|
|
368
368
|
before do
|
369
369
|
@request = stub_login_request(
|
370
370
|
with_body: "grant_type=password&client_id=client_id" \
|
371
|
-
|
372
|
-
|
373
|
-
).to_return(
|
371
|
+
"&client_secret=client_secret&username=foo" \
|
372
|
+
"&password=barsecurity_token"
|
373
|
+
).to_return(
|
374
|
+
status: 200,
|
375
|
+
body: fixture(:auth_success_response),
|
376
|
+
headers: { "Content-Type" => "application/json" }
|
377
|
+
)
|
374
378
|
end
|
375
379
|
|
376
380
|
after do
|
@@ -420,13 +424,17 @@ shared_examples_for Restforce::AbstractClient do
|
|
420
424
|
|
421
425
|
@query_request = stub_login_request(
|
422
426
|
with_body: "grant_type=password&client_id=client_id" \
|
423
|
-
|
424
|
-
|
425
|
-
).to_return(
|
427
|
+
"&client_secret=client_secret&username=foo&" \
|
428
|
+
"password=barsecurity_token"
|
429
|
+
).to_return(
|
430
|
+
status: 200,
|
431
|
+
body: fixture(:auth_success_response),
|
432
|
+
headers: { "Content-Type" => "application/json" }
|
433
|
+
)
|
426
434
|
end
|
427
435
|
|
428
436
|
subject { lambda { client.query('SELECT some, fields FROM object') } }
|
429
|
-
it {
|
437
|
+
it { expect { subject.call }.to raise_error Restforce::UnauthorizedError }
|
430
438
|
end
|
431
439
|
end
|
432
440
|
|
@@ -445,8 +453,12 @@ shared_examples_for Restforce::AbstractClient do
|
|
445
453
|
|
446
454
|
@login = stub_login_request(
|
447
455
|
with_body: "grant_type=password&client_id=client_id&client_secret=" \
|
448
|
-
|
449
|
-
).to_return(
|
456
|
+
"client_secret&username=foo&password=barsecurity_token"
|
457
|
+
).to_return(
|
458
|
+
status: 200,
|
459
|
+
body: fixture(:auth_success_response),
|
460
|
+
headers: { "Content-Type" => "application/json" }
|
461
|
+
)
|
450
462
|
end
|
451
463
|
|
452
464
|
after do
|
@@ -98,17 +98,21 @@ shared_examples_for Restforce::Data::Client do
|
|
98
98
|
end
|
99
99
|
|
100
100
|
describe '.subscribe', event_machine: true do
|
101
|
+
let(:faye_double) { double('Faye') }
|
102
|
+
|
101
103
|
context 'when given a single pushtopic' do
|
102
104
|
it 'subscribes to the pushtopic' do
|
103
|
-
|
105
|
+
faye_double.should_receive(:subscribe).with(['/topic/PushTopic'])
|
106
|
+
client.stub faye: faye_double
|
104
107
|
client.subscribe('PushTopic')
|
105
108
|
end
|
106
109
|
end
|
107
110
|
|
108
111
|
context 'when given an array of pushtopics' do
|
109
112
|
it 'subscribes to each pushtopic' do
|
110
|
-
|
113
|
+
faye_double.should_receive(:subscribe).with(['/topic/PushTopic1',
|
111
114
|
'/topic/PushTopic2'])
|
115
|
+
client.stub faye: faye_double
|
112
116
|
client.subscribe(%w[PushTopic1 PushTopic2])
|
113
117
|
end
|
114
118
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -8,6 +8,8 @@ Bundler.require :default, :test
|
|
8
8
|
require 'faye' unless RUBY_PLATFORM == 'java'
|
9
9
|
|
10
10
|
require 'webmock/rspec'
|
11
|
+
require 'rspec/collection_matchers'
|
12
|
+
require 'rspec/its'
|
11
13
|
|
12
14
|
WebMock.disable_net_connect!
|
13
15
|
|
@@ -27,6 +29,14 @@ RSpec.configure do |config|
|
|
27
29
|
$stderr = original_stderr
|
28
30
|
$stdout = original_stdout
|
29
31
|
end
|
32
|
+
|
33
|
+
config.expect_with :rspec do |expectations|
|
34
|
+
expectations.syntax = %i[expect should]
|
35
|
+
end
|
36
|
+
|
37
|
+
config.mock_with :rspec do |mocks|
|
38
|
+
mocks.syntax = %i[expect should]
|
39
|
+
end
|
30
40
|
end
|
31
41
|
|
32
42
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
@@ -5,7 +5,7 @@ module ClientIntegrationExampleGroup
|
|
5
5
|
base.class_eval do
|
6
6
|
let(:oauth_token) do
|
7
7
|
'00Dx0000000BV7z!AR8AQAxo9UfVkh8AlV0Gomt9Czx9LjHnSSpwBMmbRcgKFmxOtvxjTrKW19ye6P' \
|
8
|
-
|
8
|
+
'E3Ds1eQz3z8jr3W7_VbWmEu4Q8TVGSTHxs'
|
9
9
|
end
|
10
10
|
|
11
11
|
let(:refresh_token) { 'refresh' }
|
@@ -39,13 +39,13 @@ module ClientIntegrationExampleGroup
|
|
39
39
|
end
|
40
40
|
|
41
41
|
RSpec.configure do |config|
|
42
|
+
describes = lambda do |described|
|
43
|
+
described <= Restforce::AbstractClient
|
44
|
+
end
|
45
|
+
|
42
46
|
config.include self,
|
43
|
-
|
44
|
-
|
45
|
-
described <= Restforce::AbstractClient
|
46
|
-
end,
|
47
|
-
file_path: %r{spec/integration}
|
48
|
-
}
|
47
|
+
file_path: %r{spec/integration},
|
48
|
+
describes: describes
|
49
49
|
|
50
50
|
config.before mashify: false do
|
51
51
|
base_options.merge!(mashify: false)
|
data/spec/support/concerns.rb
CHANGED
data/spec/support/middleware.rb
CHANGED
@@ -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,13 +56,31 @@ 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
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
|
+
|
66
84
|
describe '#empty?' do
|
67
85
|
subject(:empty?) do
|
68
86
|
described_class.new(JSON.parse(fixture(sobject_fixture)), client).empty?
|
@@ -71,13 +89,13 @@ describe Restforce::Collection do
|
|
71
89
|
context 'with size 1' do
|
72
90
|
let(:sobject_fixture) { 'sobject/query_success_response' }
|
73
91
|
|
74
|
-
it { should
|
92
|
+
it { should be false }
|
75
93
|
end
|
76
94
|
|
77
95
|
context 'with size 0' do
|
78
96
|
let(:sobject_fixture) { 'sobject/query_empty_response' }
|
79
97
|
|
80
|
-
it { should
|
98
|
+
it { should be true }
|
81
99
|
end
|
82
100
|
end
|
83
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
|
@@ -312,9 +312,12 @@ describe Restforce::Concerns::API do
|
|
312
312
|
let(:attrs) { { id: '1234', StageName: "Call Scheduled" } }
|
313
313
|
|
314
314
|
it 'sends an HTTP PATCH, and returns true' do
|
315
|
-
client.should_receive(:api_patch)
|
316
|
-
|
317
|
-
|
315
|
+
client.should_receive(:api_patch) do |*args|
|
316
|
+
expect(args).to eq(["sobjects/Whizbang/1234",
|
317
|
+
{ StageName: "Call Scheduled" }])
|
318
|
+
end
|
319
|
+
|
320
|
+
expect(result).to be true
|
318
321
|
end
|
319
322
|
end
|
320
323
|
|
@@ -322,9 +325,13 @@ describe Restforce::Concerns::API do
|
|
322
325
|
let(:attrs) { { id: '1234/?abc', StageName: "Call Scheduled" } }
|
323
326
|
|
324
327
|
it 'sends an HTTP PATCH, and encodes the ID' do
|
325
|
-
client.should_receive(:api_patch)
|
326
|
-
|
327
|
-
|
328
|
+
client.should_receive(:api_patch) do |*args|
|
329
|
+
expect(args).to eq(['sobjects/Whizbang/1234%2F%3Fabc', {
|
330
|
+
StageName: "Call Scheduled"
|
331
|
+
}])
|
332
|
+
end
|
333
|
+
|
334
|
+
expect(result).to be true
|
328
335
|
end
|
329
336
|
end
|
330
337
|
|
@@ -348,7 +355,7 @@ describe Restforce::Concerns::API do
|
|
348
355
|
client.should_receive(:api_patch).
|
349
356
|
with('sobjects/Whizbang/External_ID__c/1234', {}).
|
350
357
|
and_return(response)
|
351
|
-
expect(result).to
|
358
|
+
expect(result).to be true
|
352
359
|
end
|
353
360
|
|
354
361
|
context 'and the response body is a string' do
|
@@ -357,7 +364,7 @@ describe Restforce::Concerns::API do
|
|
357
364
|
client.should_receive(:api_patch).
|
358
365
|
with('sobjects/Whizbang/External_ID__c/1234', {}).
|
359
366
|
and_return(response)
|
360
|
-
expect(result).to
|
367
|
+
expect(result).to be true
|
361
368
|
end
|
362
369
|
end
|
363
370
|
end
|
@@ -431,7 +438,7 @@ describe Restforce::Concerns::API do
|
|
431
438
|
client.should_receive(:api_patch).
|
432
439
|
with('sobjects/Whizbang/External_ID__c/%E3%81%82', {}).
|
433
440
|
and_return(response)
|
434
|
-
expect(result).to
|
441
|
+
expect(result).to be true
|
435
442
|
end
|
436
443
|
end
|
437
444
|
end
|
@@ -448,7 +455,7 @@ describe Restforce::Concerns::API do
|
|
448
455
|
client.should_receive(:api_patch).
|
449
456
|
with('sobjects/Whizbang/External_ID__c/1234', {}).
|
450
457
|
and_return(response)
|
451
|
-
expect(result).to
|
458
|
+
expect(result).to be true
|
452
459
|
end
|
453
460
|
end
|
454
461
|
end
|
@@ -462,7 +469,7 @@ describe Restforce::Concerns::API do
|
|
462
469
|
it 'sends and HTTP delete, and returns true' do
|
463
470
|
client.should_receive(:api_delete).
|
464
471
|
with('sobjects/Whizbang/1234')
|
465
|
-
expect(result).to
|
472
|
+
expect(result).to be true
|
466
473
|
end
|
467
474
|
|
468
475
|
context 'when the id field contains special characters' do
|
@@ -471,7 +478,7 @@ describe Restforce::Concerns::API do
|
|
471
478
|
it 'sends an HTTP delete, and encodes the ID' do
|
472
479
|
client.should_receive(:api_delete).
|
473
480
|
with('sobjects/Whizbang/1234%2F%3Fabc')
|
474
|
-
expect(result).to
|
481
|
+
expect(result).to be true
|
475
482
|
end
|
476
483
|
end
|
477
484
|
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
|