require 'spec_helper' require 'rack' require 'rack/builder' require 'rack/mock' require 'rollbar' Rollbar.plugins.load! describe Rollbar::Middleware::Rack::Builder, :reconfigure_notifier => true do class RackMockError < Exception; end let(:action) do proc { fail(RackMockError, 'the-error') } end let(:app) do action_proc = action ::Rack::Builder.new { run action_proc } end let(:request) do ::Rack::MockRequest.new(app) end let(:exception) { kind_of(RackMockError) } let(:uncaught_level) { Rollbar.configuration.uncaught_exception_level } it 'reports the error to Rollbar' do expect(Rollbar).to receive(:log).with(uncaught_level, exception, :use_exception_level_filters => true) expect { request.get('/will_crash') }.to raise_error(exception) end context 'with GET parameters' do let(:params) do { 'key' => 'value' } end it 'sends them to Rollbar' do expect do request.get('/will_crash', :params => params) end.to raise_error(exception) expect(Rollbar.last_report[:request][:GET]).to be_eql(params) end end context 'with JSON body parameters' do let(:params) do { 'key' => 'value' } end it 'sends them to Rollbar' do expect do request.post('/will_crash', :input => params.to_json, 'CONTENT_TYPE' => 'application/json') end.to raise_error(exception) expect(Rollbar.last_report[:request][:body]).to be_eql(params.to_json) end end context 'with array POST parameters' do let(:params) do [{ :key => 'value'}, 'string', 10] end it 'sends a body.multi key in params' do expect do request.post('/will_crash', :input => params.to_json, 'CONTENT_TYPE' => 'application/json') end.to raise_error(exception) reported_body = Rollbar.last_report[:request][:body] expect(reported_body).to be_eql({ 'body.multi' => [{'key' => 'value'}, 'string', 10] }.to_json) end end context 'with not array or hash POST parameters' do let(:params) { 1000 } it 'sends a body.multi key in params' do expect do request.post('/will_crash', :input => params.to_json, 'CONTENT_TYPE' => 'application/json') end.to raise_error(exception) reported_body = Rollbar.last_report[:request][:body] expect(reported_body).to be_eql({ 'body.value' => params }.to_json) end end context 'with multiple HTTP_X_FORWARDED_PROTO values' do let(:headers) do { 'HTTP_X_FORWARDED_PROTO' => 'https,http' } end it 'uses the first scheme to generate the url' do expect do request.post('/will_crash', headers) end.to raise_error(exception) last_report = Rollbar.last_report expect(last_report[:request][:url]).to match(/https:/) end end context 'without HTTP_X_FORWARDED_PROTO' do it 'uses the the url_scheme set by Rack' do expect do request.post('/will_crash') end.to raise_error(exception) last_report = Rollbar.last_report expect(last_report[:request][:url]).to match(/http:/) end end context 'with single HTTP_X_FORWARDED_PROTO value' do let(:headers) do { 'HTTP_X_FORWARDED_PROTO' => 'https' } end it 'uses the scheme received in X-Forwarded-Proto header' do expect do request.post('/will_crash', headers) end.to raise_error(exception) last_report = Rollbar.last_report expect(last_report[:request][:url]).to match(/https:/) end end context 'with person data' do let(:person_data) do { 'email' => 'person@example.com' } end it 'includes person data from env' do expect do request.get('/will_crash', 'rollbar.person_data' => person_data) end.to raise_error(exception) expect(Rollbar.last_report[:person]).to be_eql(person_data) end it 'includes empty person data when not in env' do expect do request.get('/will_crash') end.to raise_error(exception) expect(Rollbar.last_report[:person]).to be_eql({}) end end end