socialforge/lib/rack-mini-profiler/spec/integration/mini_profiler_spec.rb

262 lines
7.4 KiB
Ruby

require 'spec_helper'
require 'rack-mini-profiler'
require 'rack/test'
describe Rack::MiniProfiler do
include Rack::Test::Methods
def app
@app ||= Rack::Builder.new {
use Rack::MiniProfiler
map '/path2/a' do
run lambda { |env| [200, {'Content-Type' => 'text/html'}, '<h1>path1</h1>'] }
end
map '/path1/a' do
run lambda { |env| [200, {'Content-Type' => 'text/html'}, '<h1>path2</h1>'] }
end
map '/post' do
run lambda { |env| [302, {'Content-Type' => 'text/html'}, '<h1>POST</h1>'] }
end
map '/html' do
run lambda { |env| [200, {'Content-Type' => 'text/html'}, "<html><BODY><h1>Hi</h1></BODY>\n \t</html>"] }
end
map '/implicitbody' do
run lambda { |env| [200, {'Content-Type' => 'text/html'}, "<html><h1>Hi</h1></html>"] }
end
map '/implicitbodyhtml' do
run lambda { |env| [200, {'Content-Type' => 'text/html'}, "<h1>Hi</h1>"] }
end
map '/db' do
run lambda { |env|
::Rack::MiniProfiler.record_sql("I want to be, in a db", 10)
[200, {'Content-Type' => 'text/html'}, '<h1>Hi+db</h1>']
}
end
map '/3ms' do
run lambda { |env|
sleep(0.003)
[200, {'Content-Type' => 'text/html'}, '<h1>Hi</h1>']
}
end
map '/whitelisted' do
run lambda { |env|
Rack::MiniProfiler.authorize_request
[200, {'Content-Type' => 'text/html'}, '<h1>path1</h1>']
}
end
}.to_app
end
before do
Rack::MiniProfiler.reset_config
end
describe 'with a valid request' do
before do
get '/html'
end
it 'returns 200' do
last_response.should be_ok
end
it 'has the X-MiniProfiler-Ids header' do
last_response.headers.has_key?('X-MiniProfiler-Ids').should be_true
end
it 'has only one X-MiniProfiler-Ids header' do
h = last_response.headers['X-MiniProfiler-Ids']
ids = ::JSON.parse(h)
ids.count.should == 1
end
it 'has the JS in the body' do
last_response.body.include?('/mini-profiler-resources/includes.js').should be_true
end
it 'has a functioning share link' do
h = last_response.headers['X-MiniProfiler-Ids']
id = ::JSON.parse(h)[0]
get "/mini-profiler-resources/results?id=#{id}"
last_response.should be_ok
end
it 'avoids xss attacks' do
h = last_response.headers['X-MiniProfiler-Ids']
id = ::JSON.parse(h)[0]
get "/mini-profiler-resources/results?id=%22%3E%3Cqss%3E"
last_response.should_not be_ok
last_response.body.should_not =~ /<qss>/
last_response.body.should =~ /&lt;qss&gt;/
end
end
describe 'with an implicit body tag' do
before do
get '/implicitbody'
end
it 'has the JS in the body' do
last_response.body.include?('/mini-profiler-resources/includes.js').should be_true
end
end
describe 'with implicit body and html tags' do
before do
get '/implicitbodyhtml'
end
it 'does not include the JS in the body' do
last_response.body.include?('/mini-profiler-resources/includes.js').should be_false
end
end
describe 'with a SCRIPT_NAME' do
before do
get '/html', nil, 'SCRIPT_NAME' => '/test'
end
it 'has the JS in the body with the correct path' do
last_response.body.include?('/test/mini-profiler-resources/includes.js').should be_true
end
end
describe 'configuration' do
it "doesn't add MiniProfiler if the callback fails" do
Rack::MiniProfiler.config.pre_authorize_cb = lambda {|env| false }
get '/html'
last_response.headers.has_key?('X-MiniProfiler-Ids').should be_false
end
it "skips paths listed" do
Rack::MiniProfiler.config.skip_paths = ['/path/', '/path2/']
get '/path2/a'
last_response.headers.has_key?('X-MiniProfiler-Ids').should be_false
get '/path1/a'
last_response.headers.has_key?('X-MiniProfiler-Ids').should be_true
end
it 'disables default functionality' do
Rack::MiniProfiler.config.enabled = false
get '/html'
last_response.headers.has_key?('X-MiniProfiler-Ids').should be_false
end
end
def load_prof(response)
id = response.headers['X-MiniProfiler-Ids']
id = ::JSON.parse(id)[0]
Rack::MiniProfiler.config.storage_instance.load(id)
end
describe 'special options' do
it "omits db backtrace if requested" do
get '/db?pp=no-backtrace'
prof = load_prof(last_response)
stack = prof["Root"]["SqlTimings"][0]["StackTraceSnippet"]
stack.should be_nil
end
it 'disables functionality if requested' do
get '/html?pp=disable'
last_response.body.should_not include('/mini-profiler-resources/includes.js')
end
context 'when disabled' do
before(:each) do
get '/html?pp=disable'
get '/html'
last_response.body.should_not include('/mini-profiler-resources/includes.js')
end
it 're-enables functionality if requested' do
get '/html?pp=enable'
last_response.body.should include('/mini-profiler-resources/includes.js')
end
it "does not re-enable functionality if not whitelisted" do
Rack::MiniProfiler.config.authorization_mode = :whitelist
get '/html?pp=enable'
last_response.body.should_not include('/mini-profiler-resources/includes.js')
end
it "re-enabled functionality if whitelisted" do
Rack::MiniProfiler.config.authorization_mode = :whitelist
expect(Rack::MiniProfiler).to receive(:request_authorized?) { true }.twice
get '/html?pp=enable'
last_response.body.should include('/mini-profiler-resources/includes.js')
end
end
end
describe 'POST followed by GET' do
it "should end up with 2 ids" do
post '/post'
get '/html'
ids = last_response.headers['X-MiniProfiler-Ids']
::JSON.parse(ids).length.should == 2
end
end
describe 'authorization mode whitelist' do
before do
Rack::MiniProfiler.config.authorization_mode = :whitelist
end
it "should ban requests that are not whitelisted" do
get '/html'
last_response.headers['X-MiniProfiler-Ids'].should be_nil
end
it "should allow requests that are whitelisted" do
set_cookie("__profilin=stylin")
get '/whitelisted'
last_response.headers['X-MiniProfiler-Ids'].should_not be_nil
end
end
describe 'gc profiler' do
it "should return a report" do
get '/html?pp=profile-gc'
last_response.header['Content-Type'].should == 'text/plain'
end
end
describe 'error handling when storage_instance fails to save' do
it "should recover gracefully" do
Rack::MiniProfiler.config.pre_authorize_cb = lambda {|env| true }
Rack::MiniProfiler::MemoryStore.any_instance.stub(:save) { raise "This error" }
Rack::MiniProfiler.config.storage_failure.should_receive(:call)
get '/html'
end
end
describe 'when profiler is disabled by default' do
before(:each) do
Rack::MiniProfiler.config.enabled = false
get '/html'
last_response.headers.has_key?('X-MiniProfiler-Ids').should be_false
end
it 'functionality can be re-enabled' do
get '/html?pp=enable'
last_response.headers.has_key?('X-MiniProfiler-Ids').should be_true
get '/html'
last_response.headers.has_key?('X-MiniProfiler-Ids').should be_true
end
end
end