Browse files

Move integration test from Rails

  • Loading branch information...
1 parent fdaf532 commit 71678a85c56902b3865dbae93a2b09a85f60e89c @sikachu committed Aug 23, 2012
Showing with 336 additions and 1 deletion.
  1. +288 −0 test/action_controller_test.rb
  2. +44 −0 test/helper.rb
  3. +4 −1 test/session_test.rb
View
288 test/action_controller_test.rb
@@ -0,0 +1,288 @@
+require 'helper'
+
+class ActionControllerTest < ActionDispatch::IntegrationTest
+ class TestController < ActionController::Base
+ def no_session_access
+ head :ok
+ end
+
+ def set_session_value
+ raise "missing session!" unless session
+ session[:foo] = params[:foo] || "bar"
+ head :ok
+ end
+
+ def get_session_value
+ render :text => "foo: #{session[:foo].inspect}"
+ end
+
+ def get_session_id
+ render :text => "#{request.session_options[:id]}"
+ end
+
+ def call_reset_session
+ session[:foo]
+ reset_session
+ reset_session if params[:twice]
+ session[:foo] = "baz"
+ head :ok
+ end
+
+ def renew
+ env["rack.session.options"][:renew] = true
+ session[:foo] = "baz"
+ head :ok
+ end
+ end
+
+ def setup
+ ActionDispatch::Session::ActiveRecordStore.session_class.create_table!
+ end
+
+ def teardown
+ ActionDispatch::Session::ActiveRecordStore.session_class.drop_table!
+ end
+
+ %w{ session sql_bypass }.each do |class_name|
+ define_method("test_setting_and_getting_session_value_with_#{class_name}_store") do
+ with_store class_name do
+ with_test_route_set do
+ get '/set_session_value'
+ assert_response :success
+ assert cookies['_session_id']
+
+ get '/get_session_value'
+ assert_response :success
+ assert_equal 'foo: "bar"', response.body
+
+ get '/set_session_value', :foo => "baz"
+ assert_response :success
+ assert cookies['_session_id']
+
+ get '/get_session_value'
+ assert_response :success
+ assert_equal 'foo: "baz"', response.body
+
+ get '/call_reset_session'
+ assert_response :success
+ assert_not_equal [], headers['Set-Cookie']
+ end
+ end
+ end
+
+ define_method("test_renewing_with_#{class_name}_store") do
+ with_store class_name do
+ with_test_route_set do
+ get '/set_session_value'
+ assert_response :success
+ assert cookies['_session_id']
+
+ get '/renew'
+ assert_response :success
+ assert_not_equal [], headers['Set-Cookie']
+ end
+ end
+ end
+ end
+
+ def test_getting_nil_session_value
+ with_test_route_set do
+ get '/get_session_value'
+ assert_response :success
+ assert_equal 'foo: nil', response.body
+ end
+ end
+
+ def test_calling_reset_session_twice_does_not_raise_errors
+ with_test_route_set do
+ get '/call_reset_session', :twice => "true"
+ assert_response :success
+
+ get '/get_session_value'
+ assert_response :success
+ assert_equal 'foo: "baz"', response.body
+ end
+ end
+
+ def test_setting_session_value_after_session_reset
+ with_test_route_set do
+ get '/set_session_value'
+ assert_response :success
+ assert cookies['_session_id']
+ session_id = cookies['_session_id']
+
+ get '/call_reset_session'
+ assert_response :success
+ assert_not_equal [], headers['Set-Cookie']
+
+ get '/get_session_value'
+ assert_response :success
+ assert_equal 'foo: "baz"', response.body
+
+ get '/get_session_id'
+ assert_response :success
+ assert_not_equal session_id, response.body
+ end
+ end
+
+ def test_getting_session_value_after_session_reset
+ with_test_route_set do
+ get '/set_session_value'
+ assert_response :success
+ assert cookies['_session_id']
+ session_cookie = cookies.send(:hash_for)['_session_id']
+
+ get '/call_reset_session'
+ assert_response :success
+ assert_not_equal [], headers['Set-Cookie']
+
+ cookies << session_cookie # replace our new session_id with our old, pre-reset session_id
+
+ get '/get_session_value'
+ assert_response :success
+ assert_equal 'foo: nil', response.body, "data for this session should have been obliterated from the database"
+ end
+ end
+
+ def test_getting_from_nonexistent_session
+ with_test_route_set do
+ get '/get_session_value'
+ assert_response :success
+ assert_equal 'foo: nil', response.body
+ assert_nil cookies['_session_id'], "should only create session on write, not read"
+ end
+ end
+
+ def test_getting_session_id
+ with_test_route_set do
+ get '/set_session_value'
+ assert_response :success
+ assert cookies['_session_id']
+ session_id = cookies['_session_id']
+
+ get '/get_session_id'
+ assert_response :success
+ assert_equal session_id, response.body, "should be able to read session id without accessing the session hash"
+ end
+ end
+
+ def test_doesnt_write_session_cookie_if_session_id_is_already_exists
+ with_test_route_set do
+ get '/set_session_value'
+ assert_response :success
+ assert cookies['_session_id']
+
+ get '/get_session_value'
+ assert_response :success
+ assert_equal nil, headers['Set-Cookie'], "should not resend the cookie again if session_id cookie is already exists"
+ end
+ end
+
+ def test_prevents_session_fixation
+ with_test_route_set do
+ get '/set_session_value'
+ assert_response :success
+ assert cookies['_session_id']
+
+ get '/get_session_value'
+ assert_response :success
+ assert_equal 'foo: "bar"', response.body
+ session_id = cookies['_session_id']
+ assert session_id
+
+ reset!
+
+ get '/get_session_value', :_session_id => session_id
+ assert_response :success
+ assert_equal 'foo: nil', response.body
+ assert_not_equal session_id, cookies['_session_id']
+ end
+ end
+
+ def test_allows_session_fixation
+ with_test_route_set(:cookie_only => false) do
+ get '/set_session_value'
+ assert_response :success
+ assert cookies['_session_id']
+
+ get '/get_session_value'
+ assert_response :success
+ assert_equal 'foo: "bar"', response.body
+ session_id = cookies['_session_id']
+ assert session_id
+
+ reset!
+
+ get '/set_session_value', :_session_id => session_id, :foo => "baz"
+ assert_response :success
+ assert_equal session_id, cookies['_session_id']
+
+ get '/get_session_value', :_session_id => session_id
+ assert_response :success
+ assert_equal 'foo: "baz"', response.body
+ assert_equal session_id, cookies['_session_id']
+ end
+ end
+
+ def test_incoming_invalid_session_id_via_cookie_should_be_ignored
+ with_test_route_set do
+ open_session do |sess|
+ sess.cookies['_session_id'] = 'INVALID'
+
+ sess.get '/set_session_value'
+ new_session_id = sess.cookies['_session_id']
+ assert_not_equal 'INVALID', new_session_id
+
+ sess.get '/get_session_value'
+ new_session_id_2 = sess.cookies['_session_id']
+ assert_equal new_session_id, new_session_id_2
+ end
+ end
+ end
+
+ def test_incoming_invalid_session_id_via_parameter_should_be_ignored
+ with_test_route_set(:cookie_only => false) do
+ open_session do |sess|
+ sess.get '/set_session_value', :_session_id => 'INVALID'
+ new_session_id = sess.cookies['_session_id']
+ assert_not_equal 'INVALID', new_session_id
+
+ sess.get '/get_session_value'
+ new_session_id_2 = sess.cookies['_session_id']
+ assert_equal new_session_id, new_session_id_2
+ end
+ end
+ end
+
+ def test_session_store_with_all_domains
+ with_test_route_set(:domain => :all) do
+ get '/set_session_value'
+ assert_response :success
+ end
+ end
+
+ private
+
+ def with_test_route_set(options = {})
+ with_routing do |set|
+ set.draw do
+ get ':action', :to => 'action_controller_test/test'
+ end
+
+ @app = self.class.build_app(set) do |middleware|
+ middleware.use ActionDispatch::Session::ActiveRecordStore, options.reverse_merge(:key => '_session_id')
+ middleware.delete "ActionDispatch::ShowExceptions"
+ end
+
+ yield
+ end
+ end
+
+ def with_store(class_name)
+ session_class, ActionDispatch::Session::ActiveRecordStore.session_class =
+ ActionDispatch::Session::ActiveRecordStore.session_class, "ActiveRecord::SessionStore::#{class_name.camelize}".constantize
+ yield
+ ensure
+ ActionDispatch::Session::ActiveRecordStore.session_class = session_class
+ end
+end
View
44 test/helper.rb
@@ -1,6 +1,50 @@
require 'bundler/setup'
require 'active_record'
+require 'action_controller'
+require 'action_dispatch'
require 'minitest/autorun'
+require 'active_record/session_store'
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
+
+SharedTestRoutes = ActionDispatch::Routing::RouteSet.new
+
+module ActionDispatch
+ module SharedRoutes
+ def before_setup
+ @routes = SharedTestRoutes
+ super
+ end
+ end
+end
+
+class ActionDispatch::IntegrationTest < ActiveSupport::TestCase
+ include ActionDispatch::SharedRoutes
+
+ def self.build_app(routes = nil)
+ RoutedRackApp.new(routes || ActionDispatch::Routing::RouteSet.new) do |middleware|
+ middleware.use "ActionDispatch::DebugExceptions"
+ middleware.use "ActionDispatch::Callbacks"
+ middleware.use "ActionDispatch::ParamsParser"
+ middleware.use "ActionDispatch::Cookies"
+ middleware.use "ActionDispatch::Flash"
+ middleware.use "Rack::Head"
+ yield(middleware) if block_given?
+ end
+ end
+end
+
+class RoutedRackApp
+ attr_reader :routes
+
+ def initialize(routes, &blk)
+ @routes = routes
+ @stack = ActionDispatch::MiddlewareStack.new(&blk).build(@routes)
+ end
+
+ def call(env)
+ @stack.call(env)
+ end
+end
View
5 test/session_test.rb
@@ -1,5 +1,4 @@
require 'helper'
-require 'action_dispatch'
require 'active_record/session_store'
module ActiveRecord
@@ -39,6 +38,10 @@ def test_create_table!
end
def test_find_by_sess_id_compat
+ # Force class reload, as we need to redo the meta-programming
+ ActiveRecord::SessionStore.send(:remove_const, :Session)
+ load 'active_record/session_store/session.rb'
+
Session.reset_column_information
klass = Class.new(Session) do
def self.session_id_column

0 comments on commit 71678a8

Please sign in to comment.