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,169 @@
|
|
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
|
+
|
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
|
152
|
+
end
|
153
|
+
|
154
|
+
describe '#composite' do
|
155
|
+
let(:method) { :composite }
|
156
|
+
let(:all_or_none) { false }
|
157
|
+
let(:response) { double('Faraday::Response', body: { 'compositeResponse' => [] }) }
|
158
|
+
it_behaves_like 'composite requests'
|
159
|
+
end
|
160
|
+
|
161
|
+
describe '#composite!' do
|
162
|
+
let(:method) { :composite! }
|
163
|
+
let(:all_or_none) { true }
|
164
|
+
let(:response) do
|
165
|
+
double('Faraday::Response', body: { 'compositeResponse' => [] })
|
166
|
+
end
|
167
|
+
it_behaves_like 'composite requests'
|
168
|
+
end
|
169
|
+
end
|
@@ -73,7 +73,7 @@ describe Restforce::Concerns::Connection do
|
|
73
73
|
Restforce.stub(log?: true)
|
74
74
|
end
|
75
75
|
|
76
|
-
it "must always be used as the last handler" do
|
76
|
+
it "must always be used as the last handler before the adapter" do
|
77
77
|
client.middleware.handlers.reverse.index(Restforce::Middleware::Logger).
|
78
78
|
should eq 0
|
79
79
|
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
@@ -44,7 +44,7 @@ describe Restforce do
|
|
44
44
|
'SALESFORCE_PROXY_URI' => 'proxy',
|
45
45
|
'SALESFORCE_HOST' => 'test.host.com',
|
46
46
|
'SALESFORCE_API_VERSION' => '37.0' }.
|
47
|
-
each { |var, value| ENV.stub(:
|
47
|
+
each { |var, value| ENV.stub(:fetch).with(var, anything).and_return(value) }
|
48
48
|
end
|
49
49
|
|
50
50
|
its(:username) { should eq 'foo' }
|
@@ -76,7 +76,7 @@ describe Restforce do
|
|
76
76
|
subject { Restforce.log? }
|
77
77
|
|
78
78
|
context 'by default' do
|
79
|
-
it { should
|
79
|
+
it { should be false }
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -17,15 +17,23 @@ 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
|
-
|
21
|
-
).to_return(
|
20
|
+
"assertion=abc1234567890"
|
21
|
+
).to_return(
|
22
|
+
status: 200,
|
23
|
+
body: fixture(:auth_success_response),
|
24
|
+
headers: { "Content-Type" => "application/json" }
|
25
|
+
)
|
22
26
|
end
|
23
27
|
|
24
28
|
let(:fail_request) do
|
25
29
|
stub_login_request(
|
26
30
|
body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
|
27
|
-
|
28
|
-
).to_return(
|
31
|
+
"assertion=abc1234567890"
|
32
|
+
).to_return(
|
33
|
+
status: 400,
|
34
|
+
body: fixture(:refresh_error_response),
|
35
|
+
headers: { "Content-Type" => "application/json" }
|
36
|
+
)
|
29
37
|
end
|
30
38
|
end
|
31
39
|
|
@@ -47,15 +55,23 @@ describe Restforce::Middleware::Authentication::JWTBearer do
|
|
47
55
|
let(:success_request) do
|
48
56
|
stub_login_request(
|
49
57
|
body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
|
50
|
-
|
51
|
-
).to_return(
|
58
|
+
"assertion=abc1234567890"
|
59
|
+
).to_return(
|
60
|
+
status: 200,
|
61
|
+
body: fixture(:auth_success_response),
|
62
|
+
headers: { "Content-Type" => "application/json" }
|
63
|
+
)
|
52
64
|
end
|
53
65
|
|
54
66
|
let(:fail_request) do
|
55
67
|
stub_login_request(
|
56
68
|
body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
|
57
|
-
|
58
|
-
).to_return(
|
69
|
+
"assertion=abc1234567890"
|
70
|
+
).to_return(
|
71
|
+
status: 400,
|
72
|
+
body: fixture(:refresh_error_response),
|
73
|
+
headers: { "Content-Type" => "application/json" }
|
74
|
+
)
|
59
75
|
end
|
60
76
|
end
|
61
77
|
end
|
@@ -17,15 +17,23 @@ 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
|
-
|
21
|
-
).to_return(
|
20
|
+
"&username=foo&password=barsecurity_token"
|
21
|
+
).to_return(
|
22
|
+
status: 200,
|
23
|
+
body: fixture(:auth_success_response),
|
24
|
+
headers: { "Content-Type" => "application/json" }
|
25
|
+
)
|
22
26
|
end
|
23
27
|
|
24
28
|
let(:fail_request) do
|
25
29
|
stub_login_request(
|
26
30
|
body: "grant_type=password&client_id=client_id&client_secret=client_secret" \
|
27
|
-
|
28
|
-
).to_return(
|
31
|
+
"&username=foo&password=barsecurity_token"
|
32
|
+
).to_return(
|
33
|
+
status: 400,
|
34
|
+
body: fixture(:auth_error_response),
|
35
|
+
headers: { "Content-Type" => "application/json" }
|
36
|
+
)
|
29
37
|
end
|
30
38
|
end
|
31
39
|
|
@@ -15,15 +15,23 @@ 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
|
-
|
19
|
-
).to_return(
|
18
|
+
"client_id=client_id&client_secret=client_secret"
|
19
|
+
).to_return(
|
20
|
+
status: 200,
|
21
|
+
body: fixture(:auth_success_response),
|
22
|
+
headers: { "Content-Type" => "application/json" }
|
23
|
+
)
|
20
24
|
end
|
21
25
|
|
22
26
|
let(:fail_request) do
|
23
27
|
stub_login_request(
|
24
28
|
body: "grant_type=refresh_token&refresh_token=refresh_token&" \
|
25
|
-
|
26
|
-
).to_return(
|
29
|
+
"client_id=client_id&client_secret=client_secret"
|
30
|
+
).to_return(
|
31
|
+
status: 400,
|
32
|
+
body: fixture(:refresh_error_response),
|
33
|
+
headers: { "Content-Type" => "application/json" }
|
34
|
+
)
|
27
35
|
end
|
28
36
|
end
|
29
37
|
end
|
@@ -15,7 +15,7 @@ describe Restforce::Middleware::Authentication do
|
|
15
15
|
|
16
16
|
describe '.authenticate!' do
|
17
17
|
subject { lambda { middleware.authenticate! } }
|
18
|
-
it {
|
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 {
|
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 {
|
40
|
+
it { expect { subject.call }.to raise_error Restforce::UnauthorizedError }
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -59,7 +59,7 @@ describe Restforce::Middleware::Authentication do
|
|
59
59
|
end
|
60
60
|
|
61
61
|
its(:handlers) {
|
62
|
-
should include
|
62
|
+
should include Restforce::Middleware::JsonResponse
|
63
63
|
}
|
64
64
|
its(:handlers) { should_not include Restforce::Middleware::Logger }
|
65
65
|
its(:adapter) { should eq Faraday::Adapter::NetHttp }
|
@@ -71,7 +71,7 @@ describe Restforce::Middleware::Authentication do
|
|
71
71
|
end
|
72
72
|
|
73
73
|
its(:handlers) {
|
74
|
-
should include
|
74
|
+
should include Restforce::Middleware::JsonResponse,
|
75
75
|
Restforce::Middleware::Logger
|
76
76
|
}
|
77
77
|
its(:adapter) { should eq Faraday::Adapter::NetHttp }
|
@@ -83,7 +83,7 @@ describe Restforce::Middleware::Authentication do
|
|
83
83
|
end
|
84
84
|
|
85
85
|
its(:handlers) {
|
86
|
-
should include
|
86
|
+
should include Restforce::Middleware::JsonResponse
|
87
87
|
}
|
88
88
|
its(:adapter) { should eq Faraday::Adapter::Typhoeus }
|
89
89
|
end
|
@@ -97,7 +97,7 @@ describe Restforce::Middleware::Authentication do
|
|
97
97
|
end
|
98
98
|
|
99
99
|
describe '.error_message' do
|
100
|
-
context 'when
|
100
|
+
context 'when response_body is present' do
|
101
101
|
let(:response) {
|
102
102
|
Faraday::Response.new(
|
103
103
|
response_body: { 'error' => 'error', 'error_description' => 'description' },
|
@@ -109,7 +109,7 @@ describe Restforce::Middleware::Authentication do
|
|
109
109
|
it { should eq "error: description (401)" }
|
110
110
|
end
|
111
111
|
|
112
|
-
context 'when
|
112
|
+
context 'when response_body is nil' do
|
113
113
|
let(:response) { Faraday::Response.new(status: 401) }
|
114
114
|
|
115
115
|
subject { middleware.error_message(response) }
|
@@ -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 {
|
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 {
|
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 {
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
30
|
-
|
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
|
34
|
-
|
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
|
73
|
+
context 'when the response does not even claim to be gzipped' do
|
38
74
|
before do
|
39
|
-
|
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
|
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
|
|
@@ -58,11 +102,11 @@ describe Restforce::Middleware::Gzip do
|
|
58
102
|
env[:response_headers]['Content-Encoding'] = 'gzip'
|
59
103
|
end
|
60
104
|
|
61
|
-
it { should
|
105
|
+
it { should be true }
|
62
106
|
end
|
63
107
|
|
64
108
|
context 'when not gzipped' do
|
65
|
-
it { should
|
109
|
+
it { should be false }
|
66
110
|
end
|
67
111
|
end
|
68
112
|
end
|
@@ -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 {
|
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 {
|
23
|
+
it { expect { subject.call }.not_to raise_error }
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -14,8 +14,10 @@ describe Restforce::Middleware::RaiseError do
|
|
14
14
|
let(:status) { 404 }
|
15
15
|
|
16
16
|
it 'raises Restforce::NotFoundError' do
|
17
|
-
expect { on_complete }.to raise_error
|
18
|
-
|
17
|
+
expect { on_complete }.to raise_error do |error|
|
18
|
+
expect(error).to be_a Restforce::NotFoundError
|
19
|
+
expect(error.message).to start_with("INVALID_FIELD: error_message")
|
20
|
+
end
|
19
21
|
end
|
20
22
|
|
21
23
|
it 'raises an error that inherits from Faraday::ResourceNotFound' do
|
@@ -40,8 +42,10 @@ describe Restforce::Middleware::RaiseError do
|
|
40
42
|
let(:status) { 400 }
|
41
43
|
|
42
44
|
it "raises an error derived from the response's errorCode" do
|
43
|
-
expect { on_complete }.to raise_error
|
44
|
-
|
45
|
+
expect { on_complete }.to raise_error do |error|
|
46
|
+
expect(error).to be_a Restforce::ErrorCode::InvalidField
|
47
|
+
expect(error.message).to start_with("INVALID_FIELD: error_message")
|
48
|
+
end
|
45
49
|
end
|
46
50
|
|
47
51
|
it 'raises an error that inherits from Faraday::ClientError' do
|
@@ -53,8 +57,10 @@ describe Restforce::Middleware::RaiseError do
|
|
53
57
|
let(:status) { 401 }
|
54
58
|
|
55
59
|
it 'raises Restforce::UnauthorizedError' do
|
56
|
-
expect { on_complete }.to raise_error
|
57
|
-
|
60
|
+
expect { on_complete }.to raise_error do |error|
|
61
|
+
expect(error).to be_a Restforce::UnauthorizedError
|
62
|
+
expect(error.message).to start_with("INVALID_FIELD: error_message")
|
63
|
+
end
|
58
64
|
end
|
59
65
|
end
|
60
66
|
|
@@ -76,13 +82,17 @@ describe Restforce::Middleware::RaiseError do
|
|
76
82
|
let(:status) { 400 }
|
77
83
|
|
78
84
|
it 'raises a generic Restforce::ResponseError' do
|
79
|
-
expect { on_complete }.to raise_error
|
80
|
-
|
85
|
+
expect { on_complete }.to raise_error do |error|
|
86
|
+
expect(error).to be_a Restforce::ResponseError
|
87
|
+
expect(error.message).to start_with("(error code missing): An error occured")
|
88
|
+
end
|
81
89
|
end
|
82
90
|
|
83
91
|
it 'raises an error that inherits from Faraday::ClientError' do
|
84
|
-
expect { on_complete }.to raise_error
|
85
|
-
|
92
|
+
expect { on_complete }.to raise_error do |error|
|
93
|
+
expect(error).to be_a Faraday::ClientError
|
94
|
+
expect(error.message).to start_with("(error code missing): An error occured")
|
95
|
+
end
|
86
96
|
end
|
87
97
|
end
|
88
98
|
|