airbrake 9.2.1 → 9.2.2
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 +4 -4
- data/lib/airbrake/rack/middleware.rb +21 -13
- data/lib/airbrake/rails/action_controller_performance_breakdown_subscriber.rb +20 -2
- data/lib/airbrake/version.rb +1 -1
- metadata +5 -81
- data/spec/apps/rack/dummy_app.rb +0 -17
- data/spec/apps/rails/dummy_app.rb +0 -258
- data/spec/apps/rails/dummy_task.rake +0 -15
- data/spec/apps/rails/logs/32.log +0 -34094
- data/spec/apps/rails/logs/42.log +0 -1488
- data/spec/apps/rails/logs/52.log +0 -6321
- data/spec/apps/sinatra/sinatra_test_app.rb +0 -12
- data/spec/integration/rack/rack_spec.rb +0 -19
- data/spec/integration/rails/rails_spec.rb +0 -430
- data/spec/integration/rails/rake_spec.rb +0 -97
- data/spec/integration/shared_examples/rack_examples.rb +0 -110
- data/spec/integration/sinatra/sinatra_spec.rb +0 -30
- data/spec/spec_helper.rb +0 -105
- data/spec/support/matchers/a_notice_with.rb +0 -29
- data/spec/unit/logger_spec.rb +0 -125
- data/spec/unit/rack/context_filter_spec.rb +0 -90
- data/spec/unit/rack/http_headers_filter_spec.rb +0 -44
- data/spec/unit/rack/http_params_filter_spec.rb +0 -58
- data/spec/unit/rack/instrumentable_spec.rb +0 -105
- data/spec/unit/rack/middleware_spec.rb +0 -98
- data/spec/unit/rack/rack_spec.rb +0 -46
- data/spec/unit/rack/request_body_filter_spec.rb +0 -44
- data/spec/unit/rack/request_store_spec.rb +0 -36
- data/spec/unit/rack/route_filter_spec.rb +0 -52
- data/spec/unit/rack/session_filter_spec.rb +0 -44
- data/spec/unit/rack/user_filter_spec.rb +0 -30
- data/spec/unit/rack/user_spec.rb +0 -218
- data/spec/unit/rails/action_cable/notify_callback_spec.rb +0 -26
- data/spec/unit/rails/action_controller_notify_subscriber_spec.rb +0 -43
- data/spec/unit/rails/action_controller_performance_breakdown_subscriber_spec.rb +0 -63
- data/spec/unit/rails/action_controller_route_subscriber_spec.rb +0 -84
- data/spec/unit/rails/active_record_subscriber_spec.rb +0 -70
- data/spec/unit/rails/excon_spec.rb +0 -46
- data/spec/unit/rake/tasks_spec.rb +0 -70
- data/spec/unit/shoryuken_spec.rb +0 -55
- data/spec/unit/sidekiq/retryable_jobs_filter_spec.rb +0 -36
- data/spec/unit/sidekiq_spec.rb +0 -33
- data/spec/unit/sneakers_spec.rb +0 -83
@@ -1,90 +0,0 @@
|
|
1
|
-
RSpec.describe Airbrake::Rack::ContextFilter do
|
2
|
-
def env_for(url, opts = {})
|
3
|
-
Rack::MockRequest.env_for(url, opts)
|
4
|
-
end
|
5
|
-
|
6
|
-
let(:notice) do
|
7
|
-
Airbrake.build_notice('oops').tap do |notice|
|
8
|
-
notice.stash[:rack_request] = Rack::Request.new(env_for(uri, opts))
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
let(:uri) { '/' }
|
13
|
-
let(:opts) { {} }
|
14
|
-
|
15
|
-
it "adds framework version to the context" do
|
16
|
-
subject.call(notice)
|
17
|
-
expect(notice[:context][:versions]).to include(
|
18
|
-
'rack_version' => a_string_matching(/\d.\d/),
|
19
|
-
'rack_release' => a_string_matching(/\d.\d\.\d/)
|
20
|
-
)
|
21
|
-
end
|
22
|
-
|
23
|
-
context "when URL is present" do
|
24
|
-
let(:uri) { '/bingo' }
|
25
|
-
let(:opts) { {} }
|
26
|
-
|
27
|
-
it "adds URL to the context" do
|
28
|
-
subject.call(notice)
|
29
|
-
expect(notice[:context][:url]).to eq('http://example.org/bingo')
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
context "when User-Agent is present" do
|
34
|
-
let(:uri) { '/' }
|
35
|
-
let(:opts) do
|
36
|
-
{ 'HTTP_USER_AGENT' => 'Bingo Agent' }
|
37
|
-
end
|
38
|
-
|
39
|
-
it "adds User-Agent to the context" do
|
40
|
-
subject.call(notice)
|
41
|
-
expect(notice[:context][:userAgent]).to eq('Bingo Agent')
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context "when visitor address is present" do
|
46
|
-
let(:opts) do
|
47
|
-
{ 'REMOTE_ADDR' => '1.2.3.4' }
|
48
|
-
end
|
49
|
-
|
50
|
-
it "adds userAddr to the context" do
|
51
|
-
subject.call(notice)
|
52
|
-
expect(notice[:context][:userAddr]).to eq('1.2.3.4')
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
context "when visitor is behind a proxy or load balancer" do
|
57
|
-
let(:opts) do
|
58
|
-
{ 'HTTP_X_FORWARDED_FOR' => '8.8.8.8, 9.9.9.9' }
|
59
|
-
end
|
60
|
-
|
61
|
-
it "adds userAddr to the context" do
|
62
|
-
subject.call(notice)
|
63
|
-
expect(notice[:context][:userAddr]).to eq('9.9.9.9')
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context "when controller is present" do
|
68
|
-
let(:controller) do
|
69
|
-
double.tap do |ctrl|
|
70
|
-
allow(ctrl).to receive(:controller_name).and_return('BingoController')
|
71
|
-
allow(ctrl).to receive(:action_name).and_return('bango_name')
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
let(:uri) { '/' }
|
76
|
-
let(:opts) do
|
77
|
-
{ 'action_controller.instance' => controller }
|
78
|
-
end
|
79
|
-
|
80
|
-
it "adds controller name as component" do
|
81
|
-
subject.call(notice)
|
82
|
-
expect(notice[:context][:component]).to eq('BingoController')
|
83
|
-
end
|
84
|
-
|
85
|
-
it "adds action name as action" do
|
86
|
-
subject.call(notice)
|
87
|
-
expect(notice[:context][:action]).to eq('bango_name')
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
RSpec.describe Airbrake::Rack::HttpHeadersFilter do
|
2
|
-
def env_for(url, opts = {})
|
3
|
-
Rack::MockRequest.env_for(url, opts)
|
4
|
-
end
|
5
|
-
|
6
|
-
let(:notice) do
|
7
|
-
Airbrake.build_notice('oops').tap do |notice|
|
8
|
-
notice.stash[:rack_request] = Rack::Request.new(env_for(uri, opts))
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
let(:headers) do
|
13
|
-
{
|
14
|
-
'HTTP_HOST' => 'example.com',
|
15
|
-
'CONTENT_TYPE' => 'text/html',
|
16
|
-
'CONTENT_LENGTH' => 100500
|
17
|
-
}
|
18
|
-
end
|
19
|
-
|
20
|
-
let(:uri) { '/' }
|
21
|
-
let(:opts) { headers.dup }
|
22
|
-
|
23
|
-
it "preserves data that already has been added to the context" do
|
24
|
-
notice[:context]['SOME_KEY'] = 'SOME_VALUE'
|
25
|
-
subject.call(notice)
|
26
|
-
expect(notice[:context]['SOME_KEY']).to eq('SOME_VALUE')
|
27
|
-
end
|
28
|
-
|
29
|
-
context "when CONTENT_TYPE, CONTENT_LENGTH and HTTP_* headers are present" do
|
30
|
-
it "adds them to the context hash" do
|
31
|
-
subject.call(notice)
|
32
|
-
expect(notice[:context][:headers]).to eq(headers)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
context "when unexpected headers are present" do
|
37
|
-
let(:opts) { headers.dup.merge('X-SOME-HEADER' => 'value') }
|
38
|
-
|
39
|
-
it "adds them to the context hash" do
|
40
|
-
subject.call(notice)
|
41
|
-
expect(notice[:context][:headers]).to eq(headers)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
RSpec.describe Airbrake::Rack::HttpParamsFilter do
|
2
|
-
def env_for(url, opts = {})
|
3
|
-
Rack::MockRequest.env_for(url, opts)
|
4
|
-
end
|
5
|
-
|
6
|
-
let(:notice) do
|
7
|
-
Airbrake.build_notice('oops').tap do |notice|
|
8
|
-
notice.stash[:rack_request] = Rack::Request.new(env_for(uri, opts))
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
context "when rack params is nil" do
|
13
|
-
let(:uri) { '/' }
|
14
|
-
let(:opts) { {} }
|
15
|
-
|
16
|
-
it "doesn't overwrite the params key with nil" do
|
17
|
-
subject.call(notice)
|
18
|
-
expect(notice[:params]).to eq({})
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
context "when form params are present" do
|
23
|
-
let(:params) do
|
24
|
-
{ a: 1, b: 2 }
|
25
|
-
end
|
26
|
-
|
27
|
-
let(:input) { StringIO.new }
|
28
|
-
let(:uri) { '/' }
|
29
|
-
let(:opts) do
|
30
|
-
{
|
31
|
-
'rack.request.form_hash' => params,
|
32
|
-
'rack.request.form_input' => input,
|
33
|
-
'rack.input' => input
|
34
|
-
}
|
35
|
-
end
|
36
|
-
|
37
|
-
it "sets the params hash" do
|
38
|
-
subject.call(notice)
|
39
|
-
expect(notice[:params]).to eq(params)
|
40
|
-
end
|
41
|
-
|
42
|
-
it "merges given params with existing params" do
|
43
|
-
notice[:params] = { bingo: :bango }
|
44
|
-
subject.call(notice)
|
45
|
-
expect(notice[:params]).to eq(bingo: :bango, a: 1, b: 2)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context "when query string params are present" do
|
50
|
-
let(:uri) { '/?bingo=bango&bongo=bish' }
|
51
|
-
let(:opts) { {} }
|
52
|
-
|
53
|
-
it "sets the params hash" do
|
54
|
-
subject.call(notice)
|
55
|
-
expect(notice[:params]).to eq('bingo' => 'bango', 'bongo' => 'bish')
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,105 +0,0 @@
|
|
1
|
-
RSpec.describe Airbrake::Rack::Instrumentable do
|
2
|
-
after { Airbrake::Rack::RequestStore.clear }
|
3
|
-
|
4
|
-
describe ".airbrake_capture_timing" do
|
5
|
-
let(:routes) { Airbrake::Rack::RequestStore[:routes] }
|
6
|
-
|
7
|
-
let(:klass) do
|
8
|
-
Class.new do
|
9
|
-
extend Airbrake::Rack::Instrumentable
|
10
|
-
|
11
|
-
def method; end
|
12
|
-
airbrake_capture_timing :method
|
13
|
-
|
14
|
-
def method_with_arg(a); end
|
15
|
-
airbrake_capture_timing :method_with_arg
|
16
|
-
|
17
|
-
def method_with_args(a, b); end
|
18
|
-
airbrake_capture_timing :method_with_args
|
19
|
-
|
20
|
-
def method_with_vla(*args); end
|
21
|
-
airbrake_capture_timing :method_with_vla
|
22
|
-
|
23
|
-
def method_with_args_and_vla(*args); end
|
24
|
-
airbrake_capture_timing :method_with_args_and_vla
|
25
|
-
|
26
|
-
def method_with_kwargs(foo:, bar:); end
|
27
|
-
airbrake_capture_timing :method_with_kwargs
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
context "when request store doesn't have any routes" do
|
32
|
-
before { Airbrake::Rack::RequestStore.clear }
|
33
|
-
|
34
|
-
it "doesn't store timing of the tracked method" do
|
35
|
-
klass.new.method
|
36
|
-
expect(Airbrake::Rack::RequestStore.store).to be_empty
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
context "when request store has a route" do
|
41
|
-
let(:groups) { routes['/about'][:groups] }
|
42
|
-
|
43
|
-
before do
|
44
|
-
Airbrake::Rack::RequestStore[:routes] = {
|
45
|
-
'/about' => {
|
46
|
-
method: 'GET',
|
47
|
-
response_type: :html,
|
48
|
-
groups: {}
|
49
|
-
}
|
50
|
-
}
|
51
|
-
end
|
52
|
-
|
53
|
-
it "attaches timing for a method without an argument" do
|
54
|
-
klass.new.method
|
55
|
-
expect(groups).to match('method' => be > 0)
|
56
|
-
end
|
57
|
-
|
58
|
-
it "attaches timing for a method with an argument" do
|
59
|
-
klass.new.method_with_arg(1)
|
60
|
-
expect(groups).to match('method_with_arg' => be > 0)
|
61
|
-
end
|
62
|
-
|
63
|
-
it "attaches timing for a variable-length argument method" do
|
64
|
-
klass.new.method_with_vla(1, 2, 3)
|
65
|
-
expect(groups).to match('method_with_vla' => be > 0)
|
66
|
-
end
|
67
|
-
|
68
|
-
it "attaches timing for a method with args and a variable-length array" do
|
69
|
-
klass.new.method_with_args_and_vla(1, 2, 3)
|
70
|
-
expect(groups).to match('method_with_args_and_vla' => be > 0)
|
71
|
-
end
|
72
|
-
|
73
|
-
it "attaches timing for a method with kwargs" do
|
74
|
-
klass.new.method_with_kwargs(foo: 1, bar: 2)
|
75
|
-
expect(groups).to match('method_with_kwargs' => be > 0)
|
76
|
-
end
|
77
|
-
|
78
|
-
it "attaches all timings for multiple methods to the request store" do
|
79
|
-
klass.new.method
|
80
|
-
klass.new.method_with_arg(1)
|
81
|
-
|
82
|
-
expect(groups).to match(
|
83
|
-
'method' => be > 0,
|
84
|
-
'method_with_arg' => be > 0
|
85
|
-
)
|
86
|
-
end
|
87
|
-
|
88
|
-
context "and when a custom label was provided" do
|
89
|
-
let(:klass) do
|
90
|
-
Class.new do
|
91
|
-
extend Airbrake::Rack::Instrumentable
|
92
|
-
|
93
|
-
def method; end
|
94
|
-
airbrake_capture_timing :method, label: 'custom label'
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
it "attaches timing under the provided label" do
|
99
|
-
klass.new.method
|
100
|
-
expect(groups).to match('custom label' => be > 0)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
@@ -1,98 +0,0 @@
|
|
1
|
-
RSpec.describe Airbrake::Rack::Middleware do
|
2
|
-
# The list of Rack filters that read Rack request information and append it to
|
3
|
-
# notices.
|
4
|
-
[
|
5
|
-
Airbrake::Rack::ContextFilter,
|
6
|
-
Airbrake::Rack::UserFilter,
|
7
|
-
Airbrake::Rack::SessionFilter,
|
8
|
-
Airbrake::Rack::HttpParamsFilter,
|
9
|
-
Airbrake::Rack::HttpHeadersFilter,
|
10
|
-
Airbrake::Rack::RouteFilter,
|
11
|
-
|
12
|
-
# Optional filters (must be included by users):
|
13
|
-
# Airbrake::Rack::RequestBodyFilter
|
14
|
-
].each do |filter|
|
15
|
-
Airbrake.add_filter(filter.new)
|
16
|
-
end
|
17
|
-
|
18
|
-
let(:app) { proc { |env| [200, env, 'Bingo bango content'] } }
|
19
|
-
let(:faulty_app) { proc { raise AirbrakeTestError } }
|
20
|
-
let(:endpoint) { 'https://api.airbrake.io/api/v3/projects/113743/notices' }
|
21
|
-
let(:middleware) { described_class.new(app) }
|
22
|
-
|
23
|
-
def env_for(url, opts = {})
|
24
|
-
Rack::MockRequest.env_for(url, opts)
|
25
|
-
end
|
26
|
-
|
27
|
-
def wait_for_a_request_with_body(body)
|
28
|
-
wait_for(a_request(:post, endpoint).with(body: body)).to have_been_made.once
|
29
|
-
end
|
30
|
-
|
31
|
-
before do
|
32
|
-
stub_request(:post, endpoint).to_return(status: 201, body: '{}')
|
33
|
-
end
|
34
|
-
|
35
|
-
describe "#call" do
|
36
|
-
context "when app raises an exception" do
|
37
|
-
it "rescues the exception, notifies Airbrake & re-raises it" do
|
38
|
-
expect { described_class.new(faulty_app).call(env_for('/')) }
|
39
|
-
.to raise_error(AirbrakeTestError)
|
40
|
-
|
41
|
-
wait_for_a_request_with_body(/"errors":\[{"type":"AirbrakeTestError"/)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "sends framework version and name" do
|
45
|
-
expect { described_class.new(faulty_app).call(env_for('/bingo/bango')) }
|
46
|
-
.to raise_error(AirbrakeTestError)
|
47
|
-
|
48
|
-
wait_for_a_request_with_body(
|
49
|
-
/"context":{.*"versions":{"(rails|sinatra|rack_version)"/
|
50
|
-
)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
context "when app doesn't raise" do
|
55
|
-
context "and previous middleware stored an exception in env" do
|
56
|
-
shared_examples 'stored exception' do |type|
|
57
|
-
it "notifies on #{type}, but doesn't raise" do
|
58
|
-
env = env_for('/').merge(type => AirbrakeTestError.new)
|
59
|
-
described_class.new(app).call(env)
|
60
|
-
|
61
|
-
wait_for_a_request_with_body(/"errors":\[{"type":"AirbrakeTestError"/)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
['rack.exception', 'action_dispatch.exception', 'sinatra.error'].each do |type|
|
66
|
-
include_examples 'stored exception', type
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
it "doesn't notify Airbrake" do
|
71
|
-
described_class.new(app).call(env_for('/'))
|
72
|
-
sleep 1
|
73
|
-
expect(a_request(:post, endpoint)).not_to have_been_made
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
it "returns a response" do
|
78
|
-
response = described_class.new(app).call(env_for('/'))
|
79
|
-
|
80
|
-
expect(response[0]).to eq(200)
|
81
|
-
expect(response[1]).to be_a(Hash)
|
82
|
-
expect(response[2]).to eq('Bingo bango content')
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
context "when Airbrake is not configured" do
|
87
|
-
it "returns nil" do
|
88
|
-
allow(Airbrake).to receive(:build_notice).and_return(nil)
|
89
|
-
allow(Airbrake).to receive(:notify)
|
90
|
-
|
91
|
-
expect { described_class.new(faulty_app).call(env_for('/')) }
|
92
|
-
.to raise_error(AirbrakeTestError)
|
93
|
-
|
94
|
-
expect(Airbrake).to have_received(:build_notice)
|
95
|
-
expect(Airbrake).not_to have_received(:notify)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
data/spec/unit/rack/rack_spec.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
RSpec.describe Airbrake::Rack do
|
2
|
-
after { Airbrake::Rack::RequestStore.clear }
|
3
|
-
|
4
|
-
describe ".timing" do
|
5
|
-
let(:routes) { Airbrake::Rack::RequestStore[:routes] }
|
6
|
-
|
7
|
-
context "when request store doesn't have any routes" do
|
8
|
-
it "doesn't store timing" do
|
9
|
-
described_class.capture_timing('operation') {}
|
10
|
-
expect(Airbrake::Rack::RequestStore.store).to be_empty
|
11
|
-
end
|
12
|
-
|
13
|
-
it "returns the value of the block" do
|
14
|
-
expect(described_class.capture_timing('operation') { 1 }).to eq(1)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
context "when request store has a route" do
|
19
|
-
before do
|
20
|
-
Airbrake::Rack::RequestStore[:routes] = {
|
21
|
-
'/about' => {
|
22
|
-
method: 'GET',
|
23
|
-
response_type: :html,
|
24
|
-
groups: {}
|
25
|
-
}
|
26
|
-
}
|
27
|
-
end
|
28
|
-
|
29
|
-
it "attaches all timings for different operations to the request store" do
|
30
|
-
described_class.capture_timing('operation 1') {}
|
31
|
-
described_class.capture_timing('operation 2') {}
|
32
|
-
described_class.capture_timing('operation 3') {}
|
33
|
-
|
34
|
-
expect(routes['/about'][:groups]).to match(
|
35
|
-
'operation 1' => be > 0,
|
36
|
-
'operation 2' => be > 0,
|
37
|
-
'operation 3' => be > 0
|
38
|
-
)
|
39
|
-
end
|
40
|
-
|
41
|
-
it "returns the value of the block" do
|
42
|
-
expect(described_class.capture_timing('operation') { 1 }).to eq(1)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
RSpec.describe Airbrake::Rack::RequestBodyFilter do
|
2
|
-
def env_for(url, opts = {})
|
3
|
-
Rack::MockRequest.env_for(url, opts)
|
4
|
-
end
|
5
|
-
|
6
|
-
let(:notice) do
|
7
|
-
Airbrake.build_notice('oops').tap do |notice|
|
8
|
-
notice.stash[:rack_request] = Rack::Request.new(env_for(uri, opts))
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
let(:uri) { '/' }
|
13
|
-
let(:opts) do
|
14
|
-
{ 'rack.input' => body }
|
15
|
-
end
|
16
|
-
|
17
|
-
context "when a request has a body" do
|
18
|
-
let(:body) { StringIO.new('<bingo>bongo</bango>') }
|
19
|
-
|
20
|
-
it "reads the body" do
|
21
|
-
subject.call(notice)
|
22
|
-
expect(notice[:environment][:body]).to eq(body.string)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
context "when body was read" do
|
27
|
-
let(:body) { StringIO.new('<bingo>bongo</bango>' * 512) }
|
28
|
-
|
29
|
-
it "rewinds rack.input" do
|
30
|
-
subject.call(notice)
|
31
|
-
expect(body.pos).to be_zero
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context "when body is bigger than the limit" do
|
36
|
-
let(:len) { 4097 }
|
37
|
-
let(:body) { StringIO.new('a' * len) }
|
38
|
-
|
39
|
-
it "reads only first 4096 bytes" do
|
40
|
-
subject.call(notice)
|
41
|
-
expect(notice[:environment][:body]).to eq(body.string[0...len - 1])
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|