require 'rack/cerberus'
RSpec.describe Rack::Cerberus do
let(:secret_app) {
lambda {|env|
[200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect]
}
}
let(:cerberus_app) {
Rack::Cerberus.new(secret_app, cerberus_options) do |login,pass|
[login,pass]==['mario@nintendo.com','bros']
end
}
let(:app) {
Rack::URLMap.new({
mount_path => Rack::Session::Cookie.new(cerberus_app, {secret: '42'})
})
}
let(:cerberus_options) { {} }
let(:mount_path) { '/' }
before :each do
clear_cookies
end
context 'No session is set' do
let(:app) { cerberus_app }
it 'Raises' do
expect{ get('/') }.to raise_error(Rack::Cerberus::NoSessionError)
end
end
context 'Not logged in' do
it 'Stops requests' do
get '/'
expect(last_response.status).to eq 401
body = last_response.body
expect(body.class).to eq String
expect(body).to match(/name="cerberus_login" value=""/)
expect(body).to match(/name="cerberus_pass" value=""/)
end
end
describe 'Logging in' do
context 'Login details are incorrect' do
it 'Stops requests' do
post('/', {'cerberus_login' => 'fake_login', 'cerberus_pass' => 'fake_pass'})
expect(last_response.status).to eq 401
expect(last_response.body).to match(/Wrong login or password/)
end
it 'Keeps what was entered in the fields' do
post('/', {'cerberus_login' => 'fake_login', 'cerberus_pass' => 'fake_pass'})
expect(last_response.body).to match(/name="cerberus_login" value="fake_login"/)
expect(last_response.body).to match(/name="cerberus_pass" value="fake_pass"/)
end
it 'Escapes HTML on submitted info' do
expect(Rack::Utils).to receive(:escape_html).with('').twice
post('/', {'cerberus_login' => '', 'cerberus_pass' => ''})
end
end
context 'Login details are correct' do
it 'Gives access' do
get('/', {'cerberus_login' => 'mario@nintendo.com', 'cerberus_pass' => 'bros'})
expect(last_response.status).to eq 200
end
end
end
describe 'Already logged in' do
it 'Uses session for persistent login' do
get('/', {'cerberus_login' => 'mario@nintendo.com', 'cerberus_pass' => 'bros'})
get('/')
expect(last_response.status).to eq 200
expect(last_response.body).to include('"cerberus_user"=>"mario@nintendo.com"}')
end
end
describe 'Logout' do
let(:mount_path) { '/admin' }
it 'Happens via /logout path' do
get('/admin/', {'cerberus_login' => 'mario@nintendo.com', 'cerberus_pass' => 'bros'})
expect(last_response.status).to eq 200
get('/admin/logout')
expect(last_response.status).to eq 401
end
it 'Never redirects to the logout path' do
get('/admin/logout', {'cerberus_login' => 'mario@nintendo.com', 'cerberus_pass' => 'bros'})
expect(last_response.status).to eq 302
expect(last_response['Location']).to eq '/admin'
end
end
describe 'Options' do
it 'Does not link CSS by default' do
get('/')
expect(last_response.body).not_to match(/'/main.css'} }
it 'Links the CSS file' do
get('/')
expect(last_response.body).to match(/ 'mario@nintendo.com', 'cerberus_pass' => 'bros'})
get('/')
expect(last_response.status).to eq 200
expect(last_response.body).to include('"different_user"=>"mario@nintendo.com"}')
end
end
end
end