restforce 6.1.0 → 6.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00cd20b461c775bcec8084de1916659fbf3d6f9328624daa79dbfad47f48efbe
4
- data.tar.gz: 6de0e7734bd1a53d088107effd4ed737f8eb20d1e3c51292f098f05195f9b0b9
3
+ metadata.gz: 5b88661434383f16571c2b240a9c2482035058a34adadfe39a86b4fecb7382ca
4
+ data.tar.gz: bb4ac026f9b7fbd43f7b5237760e341d9d351c5433ca19009daa24794be251f0
5
5
  SHA512:
6
- metadata.gz: d26f78e108cd25d6358720652bcd09d125e1a91caef34c85ab2a4e033763a7a2aa4a7dada91ff393c43dc433c9c1cd68d58c6b918c88c103c2f45cd50030f1b1
7
- data.tar.gz: 930d88396329214bcf344c0fbb11210b716c3db66a645c6c4369598095d36f66a0cc6486c597fd4ebe8f225a9bd5fac0150b76a4b3f95922b9f7f14ed2ef6df3
6
+ metadata.gz: da66afd00a69c078e3883f76ae0039d2742911de7b0ca8cb6b14b15801695973a25deec7e71fede838d9193a60224510eee625b72b06c827d6f0467111757023
7
+ data.tar.gz: 86cad2e9fecc5610dae221bdec91a8a1868b9333d7aa552b5fb21af928352c73cad50ea64f63f26cd61ea50048784f5c3dad20b04d798c70aee2f0295c1721bd
@@ -6,7 +6,7 @@ jobs:
6
6
  strategy:
7
7
  fail-fast: false
8
8
  matrix:
9
- ruby_version: ['2.7', '3.0', '3.1', '3.2.0-preview1']
9
+ ruby_version: ['2.7', '3.0', '3.1', '3.2']
10
10
  steps:
11
11
  - name: Checkout code
12
12
  uses: actions/checkout@v3
@@ -10,7 +10,7 @@ jobs:
10
10
  # For v2.0.x, we test v2.0.0 and v2.0.1 because v2.0.0 has a special behaviour where
11
11
  # the Net::HTTP adapter is not included. See
12
12
  # https://github.com/lostisland/faraday/blob/main/UPGRADING.md#faraday-20.
13
- faraday_version: ['1.1.0', '1.2.0', '1.3.1', '1.4.1', '1.5.1', '1.6.0', '1.7.2', '1.8.0', '1.9.3', '1.10.0', '2.0.0', '2.0.1', '2.1.0', '2.2.0', '2.3.0', '2.4.0', '2.5.0', '2.6.0']
13
+ faraday_version: ['1.1.0', '1.2.0', '1.3.1', '1.4.1', '1.5.1', '1.6.0', '1.7.2', '1.8.0', '1.9.3', '1.10.0', '2.0.0', '2.0.1', '2.1.0', '2.2.0', '2.3.0', '2.4.0', '2.5.0', '2.6.0', '2.7.0']
14
14
  env:
15
15
  FARADAY_VERSION: ~> ${{ matrix.faraday_version }}
16
16
  steps:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ # 6.2.1 (Jan 18 2023)
2
+
3
+ * When a response claims to be gzipped but isn't, return the body as it is and don't explode (@timrogers)
4
+
5
+ # 6.2.0 (Jan 18 2023)
6
+
7
+ * Add support for `faraday` v2.7.x (@timrogers)
8
+ * Expose the Faraday `Response` on `CompositeAPIError`s (@shravan097)
9
+
1
10
  # 6.1.0 (Nov 18 2022)
2
11
 
3
12
  * Add support for `faraday` v2.5.x and v2.6.x (@marcrohloff, @timrogers)
data/Gemfile CHANGED
@@ -3,7 +3,7 @@
3
3
  source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
- faraday_version = ENV.fetch('FARADAY_VERSION', '~> 1.8.0')
6
+ faraday_version = ENV.fetch('FARADAY_VERSION', '~> 2.7.3')
7
7
 
8
8
  # Enable us to explicitly pick a Faraday version when running tests
9
9
  gem 'faraday', faraday_version
@@ -17,6 +17,6 @@ gem 'rspec', '~> 3.12.0'
17
17
  gem 'rspec-collection_matchers', '~> 1.2.0'
18
18
  gem 'rspec-its', '~> 1.3.0'
19
19
  gem 'rspec_junit_formatter', '~> 0.6.0'
20
- gem 'rubocop', '~> 1.39.0'
21
- gem 'simplecov', '~> 0.21.2'
20
+ gem 'rubocop', '~> 1.43.0'
21
+ gem 'simplecov', '~> 0.22.0'
22
22
  gem 'webmock', '~> 3.18.1'
data/README.md CHANGED
@@ -27,7 +27,7 @@ Features include:
27
27
 
28
28
  Add this line to your application's Gemfile:
29
29
 
30
- gem 'restforce', '~> 6.1.0'
30
+ gem 'restforce', '~> 6.2.1'
31
31
 
32
32
  And then execute:
33
33
 
@@ -29,7 +29,7 @@ module Restforce
29
29
  if all_or_none && has_errors
30
30
  last_error_index = results.rindex { |result| result['httpStatusCode'] != 412 }
31
31
  last_error = results[last_error_index]
32
- raise CompositeAPIError, last_error['body'][0]['errorCode']
32
+ raise CompositeAPIError.new(last_error['body'][0]['errorCode'], response)
33
33
  end
34
34
 
35
35
  results
@@ -28,6 +28,10 @@ module Restforce
28
28
  # Internal: Decompresses a gzipped string.
29
29
  def decompress(body)
30
30
  Zlib::GzipReader.new(StringIO.new(body)).read
31
+ rescue Zlib::GzipFile::Error
32
+ # We thought the response was gzipped, but it wasn't. Return the original
33
+ # body back to the caller. See https://github.com/restforce/restforce/issues/761.
34
+ body
31
35
  end
32
36
  end
33
37
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Restforce
4
- VERSION = '6.1.0'
4
+ VERSION = '6.2.1'
5
5
  end
data/lib/restforce.rb CHANGED
@@ -49,7 +49,6 @@ module Restforce
49
49
  UnauthorizedError = Class.new(Faraday::ClientError)
50
50
  APIVersionError = Class.new(Error)
51
51
  BatchAPIError = Class.new(Error)
52
- CompositeAPIError = Class.new(Error)
53
52
 
54
53
  # Inherit from Faraday::ResourceNotFound for backwards-compatibility
55
54
  # Consumers of this library that rescue and handle Faraday::ResourceNotFound
@@ -60,6 +59,7 @@ module Restforce
60
59
  # Consumers of this library that rescue and handle Faraday::ClientError
61
60
  # can continue to do so.
62
61
  ResponseError = Class.new(Faraday::ClientError)
62
+ CompositeAPIError = Class.new(ResponseError)
63
63
  MatchesMultipleError= Class.new(ResponseError)
64
64
  EntityTooLargeError = Class.new(ResponseError)
65
65
 
data/restforce.gemspec CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |gem|
24
24
 
25
25
  gem.required_ruby_version = '>= 2.7'
26
26
 
27
- gem.add_dependency 'faraday', '< 2.7.0', '>= 1.1.0'
27
+ gem.add_dependency 'faraday', '< 2.8.0', '>= 1.1.0'
28
28
  gem.add_dependency 'faraday-follow_redirects', '<= 0.3.0', '< 1.0.0'
29
29
  gem.add_dependency 'faraday-multipart', '>= 1.0.0', '< 2.0.0'
30
30
  gem.add_dependency 'faraday-net_http', '< 4.0.0'
@@ -144,7 +144,10 @@ shared_examples_for Restforce::AbstractClient do
144
144
  describe '.update' do
145
145
  context 'with missing Id' do
146
146
  subject { lambda { client.update('Account', Name: 'Foobar') } }
147
- 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
+ }
148
151
  end
149
152
 
150
153
  context 'with invalid Id' do
@@ -248,7 +251,7 @@ shared_examples_for Restforce::AbstractClient do
248
251
  status: 404
249
252
 
250
253
  subject { lambda { destroy! } }
251
- it { should raise_error Faraday::ResourceNotFound }
254
+ it { expect { subject.call }.to raise_error Faraday::ResourceNotFound }
252
255
  end
253
256
 
254
257
  context 'with success' do
@@ -431,7 +434,7 @@ shared_examples_for Restforce::AbstractClient do
431
434
  end
432
435
 
433
436
  subject { lambda { client.query('SELECT some, fields FROM object') } }
434
- it { should raise_error Restforce::UnauthorizedError }
437
+ it { expect { subject.call }.to raise_error Restforce::UnauthorizedError }
435
438
  end
436
439
  end
437
440
 
@@ -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
@@ -123,6 +123,32 @@ describe Restforce::Concerns::CompositeAPI do
123
123
  end
124
124
  end.to raise_error(ArgumentError)
125
125
  end
126
+
127
+ it 'has response in CompositeAPIError' do
128
+ response = double('Faraday::Response',
129
+ body: { 'compositeResponse' =>
130
+ [{ 'httpStatusCode' => 400,
131
+ 'body' => [{ 'errorCode' =>
132
+ 'DUPLICATE_VALUE' }] }] })
133
+ client.
134
+ should_receive(:api_post).
135
+ with(endpoint, { compositeRequest: [
136
+ {
137
+ method: 'POST',
138
+ url: '/services/data/v38.0/sobjects/Object',
139
+ body: { name: 'test' },
140
+ referenceId: 'create_ref'
141
+ }
142
+ ], allOrNone: true, collateSubrequests: false }.to_json).
143
+ and_return(response)
144
+ arg = method == :composite ? { all_or_none: true } : {}
145
+ expect do
146
+ client.send(method, **arg) do |subrequests|
147
+ subrequests.create('Object', 'create_ref', name: 'test')
148
+ end
149
+ end.to raise_error(an_instance_of(Restforce::CompositeAPIError).
150
+ and(having_attributes(response: response)))
151
+ end
126
152
  end
127
153
 
128
154
  describe '#composite' do
@@ -15,7 +15,7 @@ describe Restforce::Middleware::Authentication do
15
15
 
16
16
  describe '.authenticate!' do
17
17
  subject { lambda { middleware.authenticate! } }
18
- it { should raise_error NotImplementedError }
18
+ it { expect { subject.call }.to raise_error NotImplementedError }
19
19
  end
20
20
 
21
21
  describe '.call' do
@@ -26,7 +26,7 @@ describe Restforce::Middleware::Authentication do
26
26
  app.should_receive(:call).once
27
27
  end
28
28
 
29
- it { should_not raise_error }
29
+ it { expect { subject.call }.not_to raise_error }
30
30
  end
31
31
 
32
32
  context 'when an exception is thrown' do
@@ -37,7 +37,7 @@ describe Restforce::Middleware::Authentication do
37
37
  and_raise(Restforce::UnauthorizedError.new('something bad'))
38
38
  end
39
39
 
40
- it { should raise_error Restforce::UnauthorizedError }
40
+ it { expect { subject.call }.to raise_error Restforce::UnauthorizedError }
41
41
  end
42
42
  end
43
43
 
@@ -8,6 +8,10 @@ describe Restforce::Middleware::Authorization do
8
8
  describe '.call' do
9
9
  subject { lambda { middleware.call(env) } }
10
10
 
11
- it { should change { env[:request_headers]['Authorization'] }.to eq 'OAuth token' }
11
+ it {
12
+ expect { subject.call }.to change {
13
+ env[:request_headers]['Authorization']
14
+ }.to eq 'OAuth token'
15
+ }
12
16
  end
13
17
  end
@@ -9,13 +9,17 @@ describe Restforce::Middleware::CustomHeaders do
9
9
  context 'when :request_headers are a Hash' do
10
10
  let(:options) { { request_headers: { 'x-test-header' => 'Test Value' } } }
11
11
 
12
- it { should change { env[:request_headers]['x-test-header'] }.to eq 'Test Value' }
12
+ it {
13
+ expect { subject.call }.to change {
14
+ env[:request_headers]['x-test-header']
15
+ }.to eq 'Test Value'
16
+ }
13
17
  end
14
18
 
15
19
  context 'when :request_headers are not a Hash' do
16
20
  let(:options) { { request_headers: 'bad header' } }
17
21
 
18
- it { should_not(change { env[:request_headers] }) }
22
+ it { expect { subject.call }.not_to(change { env[:request_headers] }) }
19
23
  end
20
24
  end
21
25
  end
@@ -17,29 +17,73 @@ describe Restforce::Middleware::Gzip do
17
17
  describe '.call' do
18
18
  subject { lambda { middleware.call(env) } }
19
19
 
20
- before do
21
- app.should_receive(:on_complete) { middleware.on_complete(env) }
22
- app.should_receive(:call) do
23
- env[:body] = gzip fixture('sobject/query_success_response')
24
- env[:response_headers]['Content-Encoding'] = 'gzip'
25
- app
20
+ context 'when the response is gzipped' do
21
+ before do
22
+ app.should_receive(:on_complete) { middleware.on_complete(env) }
23
+ app.should_receive(:call) do
24
+ env[:body] = gzip fixture('sobject/query_success_response')
25
+ env[:response_headers]['Content-Encoding'] = 'gzip'
26
+ app
27
+ end
28
+ end
29
+
30
+ it 'decompresses the body' do
31
+ expect { subject.call }.to change {
32
+ env[:body]
33
+ }.to(fixture('sobject/query_success_response'))
34
+ end
35
+
36
+ context 'when :compress is false' do
37
+ it 'does not set request headers to ask the response to be compressed' do
38
+ expect { subject.call }.
39
+ not_to(change { env[:request_headers]['Accept-Encoding'] })
40
+ end
26
41
  end
27
- end
28
42
 
29
- it 'decompresses the body' do
30
- should change { env[:body] }.to(fixture('sobject/query_success_response'))
43
+ context 'when :compress is true' do
44
+ before do
45
+ options[:compress] = true
46
+ end
47
+
48
+ it 'sets request headers to ask the response to be compressed' do
49
+ expect { subject.call }.to change {
50
+ env[:request_headers]['Accept-Encoding']
51
+ }.to('gzip')
52
+ end
53
+ end
31
54
  end
32
55
 
33
- context 'when :compress is false' do
34
- it { should_not(change { env[:request_headers]['Accept-Encoding'] }) }
56
+ context 'when the response claims to be gzipped, but is not' do
57
+ before do
58
+ app.should_receive(:on_complete) { middleware.on_complete(env) }
59
+ app.should_receive(:call) do
60
+ env[:body] = fixture('sobject/query_success_response')
61
+ env[:response_headers]['Content-Encoding'] = 'gzip'
62
+ app
63
+ end
64
+ end
65
+
66
+ it 'does not decompress the body' do
67
+ expect { subject.call }.to change {
68
+ env[:body]
69
+ }.to(fixture('sobject/query_success_response'))
70
+ end
35
71
  end
36
72
 
37
- context 'when :compress is true' do
73
+ context 'when the response does not even claim to be gzipped' do
38
74
  before do
39
- options[:compress] = true
75
+ app.should_receive(:on_complete) { middleware.on_complete(env) }
76
+ app.should_receive(:call) do
77
+ env[:body] = fixture('sobject/query_success_response')
78
+ app
79
+ end
40
80
  end
41
81
 
42
- it { should(change { env[:request_headers]['Accept-Encoding'] }.to('gzip')) }
82
+ it 'does not decompress the body' do
83
+ expect { subject.call }.to change {
84
+ env[:body]
85
+ }.to(fixture('sobject/query_success_response'))
86
+ end
43
87
  end
44
88
  end
45
89
 
@@ -11,7 +11,7 @@ describe Restforce::Middleware::InstanceURL do
11
11
  client.stub_chain :connection, url_prefix: URI.parse('http:/')
12
12
  end
13
13
 
14
- it { should raise_error Restforce::UnauthorizedError }
14
+ it { expect { subject.call }.to raise_error Restforce::UnauthorizedError }
15
15
  end
16
16
 
17
17
  context 'when the instance url is set' do
@@ -20,7 +20,7 @@ describe Restforce::Middleware::InstanceURL do
20
20
  app.should_receive(:call).once
21
21
  end
22
22
 
23
- it { should_not raise_error }
23
+ it { expect { subject.call }.not_to raise_error }
24
24
  end
25
25
  end
26
26
  end
@@ -16,6 +16,6 @@ describe Restforce::Middleware::Logger do
16
16
  logger.should_receive(:debug).with('response')
17
17
  end
18
18
 
19
- it { should_not raise_error }
19
+ it { expect { subject.call }.not_to raise_error }
20
20
  end
21
21
  end
@@ -48,7 +48,11 @@ describe Restforce::SObject do
48
48
  subject(:send_method) { lambda { sobject.send(method) } }
49
49
 
50
50
  context 'when an Id was not queried' do
51
- it { should raise_error ArgumentError, /need to query the Id for the record/ }
51
+ it {
52
+ expect do
53
+ subject.call
54
+ end.to raise_error ArgumentError, /need to query the Id for the record/
55
+ }
52
56
  end
53
57
 
54
58
  context 'when an Id is present' do
@@ -57,7 +61,7 @@ describe Restforce::SObject do
57
61
  client.should_receive(receiver)
58
62
  end
59
63
 
60
- it { should_not raise_error }
64
+ it { expect { subject.call }.not_to raise_error }
61
65
  end
62
66
  end
63
67
  end
@@ -69,7 +73,7 @@ describe Restforce::SObject do
69
73
  client.should_receive(:describe).with('Whizbang')
70
74
  end
71
75
 
72
- it { should_not raise_error }
76
+ it { expect { subject.call }.not_to raise_error }
73
77
  end
74
78
 
75
79
  describe '.describe_layouts' do
@@ -80,13 +84,13 @@ describe Restforce::SObject do
80
84
  client.should_receive(:describe_layouts).with('Whizbang', layout_id)
81
85
  end
82
86
 
83
- it { should_not raise_error }
87
+ it { expect { subject.call }.not_to raise_error }
84
88
 
85
89
  context 'when a layout Id is specified' do
86
90
  let(:layout_id) { '012E0000000RHEp' }
87
91
  subject { lambda { sobject.describe_layouts(layout_id) } }
88
92
 
89
- it { should_not raise_error }
93
+ it { expect { subject.call }.not_to raise_error }
90
94
  end
91
95
  end
92
96
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restforce
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.0
4
+ version: 6.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Rogers
8
8
  - Eric J. Holmes
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-11-18 00:00:00.000000000 Z
12
+ date: 2023-01-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -17,7 +17,7 @@ dependencies:
17
17
  requirements:
18
18
  - - "<"
19
19
  - !ruby/object:Gem::Version
20
- version: 2.7.0
20
+ version: 2.8.0
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
23
  version: 1.1.0
@@ -27,7 +27,7 @@ dependencies:
27
27
  requirements:
28
28
  - - "<"
29
29
  - !ruby/object:Gem::Version
30
- version: 2.7.0
30
+ version: 2.8.0
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: 1.1.0
@@ -278,7 +278,7 @@ metadata:
278
278
  source_code_uri: https://github.com/restforce/restforce
279
279
  changelog_uri: https://github.com/restforce/restforce/blob/master/CHANGELOG.md
280
280
  rubygems_mfa_required: 'true'
281
- post_install_message:
281
+ post_install_message:
282
282
  rdoc_options: []
283
283
  require_paths:
284
284
  - lib
@@ -293,8 +293,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
293
293
  - !ruby/object:Gem::Version
294
294
  version: '0'
295
295
  requirements: []
296
- rubygems_version: 3.1.6
297
- signing_key:
296
+ rubygems_version: 3.4.1
297
+ signing_key:
298
298
  specification_version: 4
299
299
  summary: A lightweight Ruby client for the Salesforce REST API
300
300
  test_files: []