spec/unit/rack/notice_builder_spec.rb in airbrake-5.6.0 vs spec/unit/rack/notice_builder_spec.rb in airbrake-5.6.1
- old
+ new
@@ -1,58 +1,78 @@
require 'spec_helper'
RSpec.describe Airbrake::Rack::NoticeBuilder do
+ def env_for(url, opts = {})
+ Rack::MockRequest.env_for(url, opts)
+ end
+
describe "#build_notice" do
- it "doesn't overwrite session with nil" do
- notice_builder = described_class.new('rack.session' => nil)
+ it "doesn't overwrite the session key with nil" do
+ notice_builder = described_class.new(env_for('/', 'rack.session' => nil))
notice = notice_builder.build_notice(AirbrakeTestError.new)
expect(notice[:session]).to eq({})
end
it "sets session if it is present" do
session = { a: 1, b: 2 }
- notice_builder = described_class.new('rack.session' => session)
+ notice_builder = described_class.new(env_for('/', 'rack.session' => session))
notice = notice_builder.build_notice(AirbrakeTestError.new)
expect(notice[:session]).to eq(session)
end
- it "doesn't overwrite params with nil" do
- notice_builder = described_class.new('action_dispatch.request.parameters' => nil)
+ it "doesn't overwrite the params key with nil" do
+ notice_builder = described_class.new(env_for('/'))
notice = notice_builder.build_notice(AirbrakeTestError.new)
expect(notice[:session]).to eq({})
end
- it "sets params if they're present" do
+ it "sets form params if they're present" do
params = { a: 1, b: 2 }
- notice_builder = described_class.new('action_dispatch.request.parameters' => params)
+ input = StringIO.new
+
+ notice_builder = described_class.new(
+ 'rack.request.form_hash' => params,
+ 'rack.request.form_input' => input,
+ 'rack.input' => input
+ )
notice = notice_builder.build_notice(AirbrakeTestError.new)
expect(notice[:params]).to eq(params)
end
+ it "sets query string params if they're present" do
+ notice_builder = described_class.new(env_for('/?bingo=bango&bongo=bish'))
+ notice = notice_builder.build_notice(AirbrakeTestError.new)
+
+ expect(notice[:params]).to eq('bingo' => 'bango', 'bongo' => 'bish')
+ end
+
it "adds CONTENT_TYPE, CONTENT_LENGTH and HTTP_* headers in the environment" do
headers = {
"HTTP_HOST" => "example.com",
"CONTENT_TYPE" => "text/html",
"CONTENT_LENGTH" => 100500
}
- notice_builder = described_class.new(headers.dup)
+ notice_builder = described_class.new(env_for('/', headers.dup))
notice = notice_builder.build_notice(AirbrakeTestError.new)
expect(notice[:environment][:headers]).to eq(headers)
end
it "skips headers that were not selected to be stored in the environment" do
headers = {
"HTTP_HOST" => "example.com",
"CONTENT_TYPE" => "text/html",
"CONTENT_LENGTH" => 100500
}
- notice_builder = described_class.new(headers.merge("X-SOME-HEADER" => "value"))
+ notice_builder = described_class.new(
+ env_for('/', headers.merge("X-SOME-HEADER" => "value"))
+ )
notice = notice_builder.build_notice(AirbrakeTestError.new)
+
expect(notice[:environment][:headers]).to eq(headers)
end
it "preserves data that already has been added to the environment" do
headers = {
@@ -63,31 +83,75 @@
allow(Airbrake).to receive(:build_notice).and_wrap_original do |method, *args|
notice = method.call(*args)
notice[:environment]["SOME_KEY"] = "SOME_VALUE"
notice
end
- notice_builder = described_class.new(headers)
+ notice_builder = described_class.new(env_for('/', headers))
notice = notice_builder.build_notice(AirbrakeTestError.new)
+
expect(notice[:environment]["SOME_KEY"]).to eq("SOME_VALUE")
end
- it "runs user defined builders against notices" do
- extended_class = described_class.dup
- extended_class.add_builder do |notice, request|
- notice[:params][:remoteIp] = request.env['REMOTE_IP']
+ context "when a custom builder is defined" do
+ before do
+ described_class.add_builder do |notice, request|
+ notice[:params][:remoteIp] = request.env['REMOTE_IP']
+ end
end
- notice_builder = extended_class.new('REMOTE_IP' => '127.0.0.1')
- notice = notice_builder.build_notice(AirbrakeTestError.new)
- expect(notice[:params][:remoteIp]).to eq("127.0.0.1")
+
+ after do
+ described_class.instance_variable_get(:@builders).pop
+ end
+
+ it "runs the builder against notices" do
+ notice_builder = described_class.new(env_for('/', 'REMOTE_IP' => '127.0.0.1'))
+ notice = notice_builder.build_notice(AirbrakeTestError.new)
+
+ expect(notice[:params][:remoteIp]).to eq("127.0.0.1")
+ end
end
context "when Airbrake is not configured" do
it "returns nil" do
allow(Airbrake).to receive(:build_notice).and_return(nil)
- notice_builder = described_class.new('bingo' => 'bango')
+ notice_builder = described_class.new(env_for('/', 'bingo' => 'bango'))
expect(notice_builder.build_notice('bongo')).to be_nil
expect(Airbrake).to have_received(:build_notice)
+ end
+ end
+
+ context "when a request has a body" do
+ it "reads the body" do
+ body = StringIO.new('<bingo>bongo</bango>')
+ notice_builder = described_class.new(
+ env_for('/', 'rack.input' => body)
+ )
+ notice = notice_builder.build_notice(AirbrakeTestError.new)
+
+ expect(notice[:environment][:body]).to eq(body.string)
+ end
+
+ it "rewinds rack.input" do
+ body = StringIO.new('<bingo>bongo</bango>' * 512)
+ notice_builder = described_class.new(
+ env_for('/', 'rack.input' => body)
+ )
+
+ notice_builder.build_notice(AirbrakeTestError.new)
+
+ expect(body.pos).to be_zero
+ end
+
+ it "reads only first 512 bytes" do
+ len = 513
+ body = StringIO.new('a' * len)
+ notice_builder = described_class.new(
+ env_for('/', 'rack.input' => body)
+ )
+ notice = notice_builder.build_notice(AirbrakeTestError.new)
+
+ expect(notice[:environment][:body]).to eq(body.string[0...len - 1])
end
end
end
end