restforce 5.0.6 → 6.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +4 -13
  3. data/.github/funding.yml +1 -0
  4. data/.github/workflows/build.yml +23 -0
  5. data/.github/workflows/faraday.yml +27 -0
  6. data/.rubocop.yml +2 -2
  7. data/CHANGELOG.md +68 -0
  8. data/Gemfile +15 -6
  9. data/README.md +61 -7
  10. data/UPGRADING.md +29 -0
  11. data/lib/restforce/abstract_client.rb +1 -0
  12. data/lib/restforce/collection.rb +20 -2
  13. data/lib/restforce/concerns/api.rb +2 -1
  14. data/lib/restforce/concerns/base.rb +2 -2
  15. data/lib/restforce/concerns/composite_api.rb +104 -0
  16. data/lib/restforce/concerns/connection.rb +1 -1
  17. data/lib/restforce/concerns/picklists.rb +1 -1
  18. data/lib/restforce/config.rb +12 -10
  19. data/lib/restforce/error_code.rb +30 -9
  20. data/lib/restforce/file_part.rb +12 -4
  21. data/lib/restforce/middleware/authentication.rb +1 -0
  22. data/lib/restforce/middleware/caching.rb +140 -15
  23. data/lib/restforce/middleware/gzip.rb +4 -0
  24. data/lib/restforce/middleware/json_request.rb +90 -0
  25. data/lib/restforce/middleware/json_response.rb +85 -0
  26. data/lib/restforce/middleware/logger.rb +6 -2
  27. data/lib/restforce/middleware/raise_error.rb +10 -1
  28. data/lib/restforce/version.rb +1 -1
  29. data/lib/restforce.rb +11 -7
  30. data/restforce.gemspec +8 -16
  31. data/spec/fixtures/sobject/list_view_results_success_response.json +151 -0
  32. data/spec/integration/abstract_client_spec.rb +42 -30
  33. data/spec/integration/data/client_spec.rb +6 -2
  34. data/spec/spec_helper.rb +10 -0
  35. data/spec/support/client_integration.rb +7 -7
  36. data/spec/support/concerns.rb +1 -1
  37. data/spec/support/middleware.rb +1 -2
  38. data/spec/unit/collection_spec.rb +22 -4
  39. data/spec/unit/concerns/api_spec.rb +22 -15
  40. data/spec/unit/concerns/authentication_spec.rb +6 -6
  41. data/spec/unit/concerns/base_spec.rb +1 -1
  42. data/spec/unit/concerns/composite_api_spec.rb +169 -0
  43. data/spec/unit/concerns/connection_spec.rb +1 -1
  44. data/spec/unit/concerns/streaming_spec.rb +4 -4
  45. data/spec/unit/config_spec.rb +2 -2
  46. data/spec/unit/middleware/authentication/jwt_bearer_spec.rb +24 -8
  47. data/spec/unit/middleware/authentication/password_spec.rb +12 -4
  48. data/spec/unit/middleware/authentication/token_spec.rb +12 -4
  49. data/spec/unit/middleware/authentication_spec.rb +8 -8
  50. data/spec/unit/middleware/authorization_spec.rb +5 -1
  51. data/spec/unit/middleware/custom_headers_spec.rb +6 -2
  52. data/spec/unit/middleware/gzip_spec.rb +60 -16
  53. data/spec/unit/middleware/instance_url_spec.rb +2 -2
  54. data/spec/unit/middleware/logger_spec.rb +1 -1
  55. data/spec/unit/middleware/raise_error_spec.rb +20 -10
  56. data/spec/unit/sobject_spec.rb +9 -5
  57. metadata +55 -172
  58. 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
- subject do
133
- lambda do
134
- client.update!('Account', Id: '001D000000INjVe', Name: 'Foobar')
135
- end
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
- it {
139
- should raise_error(
140
- Faraday::ResourceNotFound,
141
- "#{error.first['errorCode']}: #{error.first['message']}"
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 { should raise_error ArgumentError, 'ID field missing from provided attributes' }
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 be_false }
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 be_true }
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 be_true }
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 be_true }
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 { should raise_error Faraday::ResourceNotFound }
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 be_true }
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 be_true }
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 be_false }
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 be_true }
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
- "&client_secret=client_secret&username=foo" \
372
- "&password=barsecurity_token"
373
- ).to_return(status: 200, body: fixture(:auth_success_response))
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
- "&client_secret=client_secret&username=foo&" \
424
- "password=barsecurity_token"
425
- ).to_return(status: 200, body: fixture(:auth_success_response))
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 { should raise_error Restforce::UnauthorizedError }
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
- "client_secret&username=foo&password=barsecurity_token"
449
- ).to_return(status: 200, body: fixture(:auth_success_response))
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
- client.faye.should_receive(:subscribe).with(['/topic/PushTopic'])
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
- client.faye.should_receive(:subscribe).with(['/topic/PushTopic1',
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
- 'E3Ds1eQz3z8jr3W7_VbWmEu4Q8TVGSTHxs'
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
- example_group: {
44
- describes: lambda do |described|
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)
@@ -15,6 +15,6 @@ module ConcernsExampleGroup
15
15
  end
16
16
 
17
17
  RSpec.configure do |config|
18
- config.include self, example_group: { file_path: %r{spec/unit/concerns} }
18
+ config.include self, file_path: %r{spec/unit/concerns}
19
19
  end
20
20
  end
@@ -19,8 +19,7 @@ module MiddlewareExampleGroup
19
19
  end
20
20
 
21
21
  RSpec.configure do |config|
22
- config.include self,
23
- example_group: { file_path: %r{spec/unit/middleware} }
22
+ config.include self, file_path: %r{spec/unit/middleware}
24
23
  end
25
24
  end
26
25
 
@@ -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 be_false }
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 be_true }
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 be_false }
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 be_true }
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(*args).
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(*args).
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
- with('sobjects/Whizbang/1234', StageName: "Call Scheduled")
317
- expect(result).to be_true
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
- with('sobjects/Whizbang/1234%2F%3Fabc', StageName: "Call Scheduled")
327
- expect(result).to be_true
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 be_true
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 be_true
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 be_true
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 be_true
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 be_true
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 be_true
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 be_true }
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 be_true }
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 be_true }
106
+ it { should be_truthy }
107
107
  end
108
108
 
109
109
  context 'when oauth options are not provided' do
110
- it { should_not be_true }
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 be_true }
131
+ it { should be_truthy }
132
132
  end
133
133
 
134
134
  context 'when jwt options are not provided' do
135
- it { should_not be_true }
135
+ it { should_not be true }
136
136
  end
137
137
  end
138
138
  end
@@ -28,7 +28,7 @@ describe Restforce::Concerns::Base do
28
28
 
29
29
  describe '.options' do
30
30
  subject { lambda { client.options } }
31
- it { should_not raise_error }
31
+ it { expect { subject.call }.not_to raise_error }
32
32
  end
33
33
 
34
34
  describe '.instance_url' do