Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
# A simple app that implements a naive session-based login, to demonstrate the problems with testing sessions in Sinatra.
require 'rubygems'
require 'sinatra/base'
class LoginApp < Sinatra::Base
enable :sessions
get '/' do
if session[:current_user]
"Hi, #{session[:current_user]}" +
"<form action='/logout' method='post'><input type='submit' value='log out'></form>"
else
"Please log in." +
"<form action='/login' method='post'><input name='username'><input type='submit' value='log in'></form>"
end
end
post '/login' do
session[:current_user] = params[:username]
redirect '/'
end
post '/logout' do
session[:current_user] = nil
redirect '/'
end
end
LoginApp.run! if __FILE__ == $0
require "app"
require "spec"
require "rack/test"
require 'cgi'
describe LoginApp do
include Rack::Test::Methods
def app
LoginApp
end
class SessionData
def initialize(cookies)
@cookies = cookies
@data = cookies['rack.session']
if @data
@data = @data.unpack("m*").first
@data = Marshal.load(@data)
else
@data = {}
end
end
def [](key)
@data[key]
end
def []=(key, value)
@data[key] = value
session_data = Marshal.dump(@data)
session_data = [session_data].pack("m*")
@cookies.merge("rack.session=#{Rack::Utils.escape(session_data)}", URI.parse("//example.org//"))
raise "session variable not set" unless @cookies['rack.session'] == session_data
end
end
def session
SessionData.new(rack_test_session.instance_variable_get(:@rack_mock_session).cookie_jar)
end
it "renders the login form" do
get "/"
last_response.body.should include("Please log in")
end
it "redirects afer a login" do
post "/login", :username => "brad"
last_response.should be_redirect
end
it "displays the logged in user after a login" do
post "/login", :username => "brad"
get "/"
last_response.body.should include("Hi, brad")
end
it "logs out" do
post "/login", :username => "brad"
post "/logout"
get "/"
last_response.body.should include("Please log in")
end
it "can fake a login" do
session[:current_user] = "chad"
get "/"
last_response.body.should include("Hi, chad")
end
it "can fake a logout" do
post "/login", :username => "brad"
session[:current_user] = nil
session[:current_user].should == nil
get "/"
last_response.body.should include("Please log in")
end
it "can fake a user switch" do
post "/login", :username => "brad"
session[:current_user] = "chad"
get "/"
last_response.body.should include("Hi, chad")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.