Permalink
Browse files

added session_timeout tests for sinatra, and improved test helpers

  • Loading branch information...
1 parent 0a3c779 commit f8646b77ca5eee9f7dad47d67047f4119f4f262b @NoamB committed Mar 19, 2011
@@ -2,17 +2,46 @@ module Sorcery
module Controller
module Adapters
module Sinatra
- def reset_session
- session.clear
+ def self.included(base)
+ base.class_eval do
+ class << self
+ # prepend a filter
+ def prepend_filter(type, path = nil, options = {}, &block)
+ return filters[type].unshift block unless path
+ path, options = //, path if path.respond_to?(:each_pair)
+ block, *arguments = compile!(type, path, block, options)
+ prepend_filter(type) do
+ process_route(*arguments) { instance_eval(&block) }
+ end
+ end
+ end
+ end
+ base.send(:include, InstanceMethods)
+ base.extend(ClassMethods)
end
- def redirect_to(*args)
- args.pop if args.last.is_a?(Hash)
- redirect(*args)
+ module InstanceMethods
+ def reset_session
+ session.clear
+ end
+
+ def redirect_to(*args)
+ args.pop if args.last.is_a?(Hash)
+ redirect(*args)
+ end
+
+ def root_path
+ '/'
+ end
end
- def root_path
- '/'
+ module ClassMethods
+ def prepend_before_filter(filter)
+ puts "called!"
+ prepend_filter(:before) do
+ send(filter)
+ end
+ end
end
end
end
@@ -34,11 +34,18 @@ def register_login_time(user, credentials)
# Checks if session timeout was reached and expires the current session if so.
# To be used as a before_filter, before require_login
def validate_session
+ puts "vallll"
session_to_use = Config.session_timeout_from_last_action ? session[:last_action_time] : session[:login_time]
+ p Time.now.utc - session_to_use if session_to_use
+ p Time.now.utc
+ p session_to_use
+ p session[:last_action_time]
if session_to_use && (Time.now.utc - session_to_use > Config.session_timeout)
+ puts "expired"
reset_session
@current_user = false
else
+ puts "good"
session[:last_action_time] = Time.now.utc
end
end
@@ -1,5 +1,13 @@
module Sorcery
module TestHelpers
+ # a patch to fix a bug in testing that happens when you 'destroy' a session twice.
+ # After the first destroy, the session is an ordinary hash, and then when destroy is called again there's an exception.
+ class ::Hash
+ def destroy
+ clear
+ end
+ end
+
def create_new_user(attributes_hash = nil)
user_attributes_hash = attributes_hash || {:username => 'gizmo', :email => "bla@bla.com", :password => 'secret'}
@user = User.new(user_attributes_hash)
@@ -14,20 +22,6 @@ def create_new_external_user(provider, attributes_hash = nil)
@user
end
- def login_user(user = nil)
- user ||= @user
- subject.send(:login_user,user)
- subject.send(:after_login!,user,[user.username,'secret'])
- end
-
- def logout_user
- subject.send(:logout)
- end
-
- def clear_user_without_logout
- subject.instance_variable_set(:@current_user,nil)
- end
-
def sorcery_model_property_set(property, *values)
User.class_eval do
sorcery_config.send(:"#{property}=", *values)
@@ -38,6 +38,20 @@ def sorcery_controller_oauth_property_set(provider, property, value)
config.send(provider).send(:"#{property}=", value)
end
end
+
+ def login_user(user = nil)
+ user ||= @user
+ subject.send(:login_user,user)
+ subject.send(:after_login!,user,[user.username,'secret'])
+ end
+
+ def logout_user
+ subject.send(:logout)
+ end
+
+ def clear_user_without_logout
+ subject.instance_variable_set(:@current_user,nil)
+ end
end
end
end
@@ -12,29 +12,25 @@ def new
class ::Sinatra::Application
class << self
- attr_accessor :sorcery_vars, :sorcery_cookies, :sorcery_instance
+ attr_accessor :sorcery_vars
end
@sorcery_vars = {}
- @sorcery_cookies = {}
before do
self.class.sorcery_vars = {}
- self.class.sorcery_cookies = {}
- self.class.sorcery_instance = self
end
after do
save_instance_vars
- self.class.sorcery_cookies = response.cookies
end
- end
-
- def save_instance_vars
- instance_variables.each do |var|
- self.class.sorcery_vars[:"#{var.to_s.delete("@")}"] = instance_variable_get(var)
+
+ def save_instance_vars
+ instance_variables.each do |var|
+ self.class.sorcery_vars[:"#{var.to_s.delete("@")}"] = instance_variable_get(var)
+ end
end
end
-
+
::RSpec::Matchers.define :redirect_to do |expected|
match do |actual|
actual.status == 302 && actual.location == expected
@@ -47,17 +43,51 @@ def get_sinatra_app(app)
end
app
end
-
- def this
- ::Sinatra::Application.sorcery_instance
+
+ def logout_user
+ get_sinatra_app(subject).send(:logout)
end
-
+
+ def clear_user_without_logout
+ get_sinatra_app(subject).instance_variable_set(:@current_user,nil)
+ end
+
def assigns
::Sinatra::Application.sorcery_vars
end
- def cookies
- ::Sinatra::Application.sorcery_cookies
+ 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
+
+ def login_user(user=nil)
+ user ||= @user
+ session[:user_id] = user.id
end
def sorcery_reload!(submodules = [], options = {})
@@ -70,7 +100,8 @@ def sorcery_reload!(submodules = [], options = {})
# configure
::Sorcery::Controller::Config.submodules = submodules
::Sorcery::Controller::Config.user_class = nil
- Sinatra::Application.send(:include, Sorcery::Controller)
+ ::Sinatra::Application.send(:include, Sorcery::Controller::Adapters::Sinatra)
+ ::Sinatra::Application.send(:include, Sorcery::Controller)
User.activate_sorcery! do |config|
options.each do |property,value|
@@ -27,7 +27,7 @@
it "with 'session_timeout_from_last_action' should not logout if there was activity" do
sorcery_controller_property_set(:session_timeout_from_last_action, true)
- login_user
+ get :test_login, :username => 'gizmo', :password => 'secret'
sleep 0.3
get :test_should_be_logged_in
session[:user_id].should_not be_nil
@@ -39,7 +39,7 @@
it "with 'session_timeout_from_last_action' should logout if there was no activity" do
sorcery_controller_property_set(:session_timeout_from_last_action, true)
- login_user
+ get :test_login, :username => 'gizmo', :password => 'secret'
sleep 0.6
get :test_should_be_logged_in
session[:user_id].should be_nil
View
@@ -19,12 +19,10 @@
APP_ROOT = File.dirname(__FILE__)
-before '/test_logout|test_should_be_logged_in/' do
- require_login
-end
-
-before '/some_action' do
- require_login
+['/test_logout','/some_action','/test_should_be_logged_in'].each do |patt|
+ before patt do
+ require_login
+ end
end
get '/' do
@@ -60,6 +58,10 @@
return_or_redirect_to(:some_action)
end
+get '/test_should_be_logged_in' do
+ erb ''
+end
+
def test_not_authenticated_action
halt "test_not_authenticated_action"
end
@@ -1,49 +1,51 @@
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
-describe 'MyApp' do
+describe Sinatra::Application do
# ----------------- SESSION TIMEOUT -----------------------
- describe 'MyApp', "with session timeout features" do
+ describe Sinatra::Application, "with session timeout features" do
before(:all) do
sorcery_reload!([:session_timeout])
sorcery_controller_property_set(:session_timeout,0.5)
create_new_user
end
it "should not reset session before session timeout" do
- login_user
- get :test_should_be_logged_in
- session[:user_id].should_not be_nil
- response.should be_a_success
+ session[:user_id] = User.first.id
+ get "/test_should_be_logged_in"
+ last_response.should be_ok
end
it "should reset session after session timeout" do
- login_user
+ get "/test_login", :username => 'gizmo', :password => 'secret'
+ session[:user_id].should_not be_nil
sleep 0.6
- get :test_should_be_logged_in
- session[:user_id].should be_nil
- response.should be_a_redirect
+ get "/test_should_be_logged_in"
+ last_response.should be_a_redirect
end
it "with 'session_timeout_from_last_action' should not logout if there was activity" do
+ session[:user_id] = nil
+ sorcery_controller_property_set(:session_timeout,2)
sorcery_controller_property_set(:session_timeout_from_last_action, true)
- login_user
- sleep 0.3
- get :test_should_be_logged_in
+ get "/test_login", :username => 'gizmo', :password => 'secret'
+ sleep 1
+ get "/test_should_be_logged_in"
session[:user_id].should_not be_nil
- sleep 0.3
- get :test_should_be_logged_in
+ sleep 1
+ get "/test_should_be_logged_in"
session[:user_id].should_not be_nil
- response.should be_a_success
+ last_response.should be_ok
end
it "with 'session_timeout_from_last_action' should logout if there was no activity" do
+ sorcery_controller_property_set(:session_timeout,0.5)
sorcery_controller_property_set(:session_timeout_from_last_action, true)
- login_user
+ get "/test_login", :username => 'gizmo', :password => 'secret'
sleep 0.6
- get :test_should_be_logged_in
+ get "/test_should_be_logged_in"
session[:user_id].should be_nil
- response.should be_a_redirect
+ last_response.should be_a_redirect
end
end
Oops, something went wrong.

0 comments on commit f8646b7

Please sign in to comment.