aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/test/dispatch/session/cache_store_test.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/test/dispatch/session/cache_store_test.rb')
-rw-r--r--actionpack/test/dispatch/session/cache_store_test.rb183
1 files changed, 183 insertions, 0 deletions
diff --git a/actionpack/test/dispatch/session/cache_store_test.rb b/actionpack/test/dispatch/session/cache_store_test.rb
new file mode 100644
index 0000000000..06e67fac9f
--- /dev/null
+++ b/actionpack/test/dispatch/session/cache_store_test.rb
@@ -0,0 +1,183 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "fixtures/session_autoload_test/session_autoload_test/foo"
+
+class CacheStoreTest < ActionDispatch::IntegrationTest
+ class TestController < ActionController::Base
+ def no_session_access
+ head :ok
+ end
+
+ def set_session_value
+ session[:foo] = "bar"
+ head :ok
+ end
+
+ def set_serialized_session_value
+ session[:foo] = SessionAutoloadTest::Foo.new
+ head :ok
+ end
+
+ def get_session_value
+ render plain: "foo: #{session[:foo].inspect}"
+ end
+
+ def get_session_id
+ render plain: "#{request.session.id}"
+ end
+
+ def call_reset_session
+ session[:bar]
+ reset_session
+ session[:bar] = "baz"
+ head :ok
+ end
+ end
+
+ def test_setting_and_getting_session_value
+ 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
+ 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_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 cache"
+ 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_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: nil", response.body
+
+ get "/get_session_id"
+ assert_response :success
+ assert_not_equal session_id, response.body
+ 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_deserializes_unloaded_class
+ with_test_route_set do
+ with_autoload_path "session_autoload_test" do
+ get "/set_serialized_session_value"
+ assert_response :success
+ assert cookies["_session_id"]
+ end
+ with_autoload_path "session_autoload_test" do
+ get "/get_session_id"
+ assert_response :success
+ end
+ with_autoload_path "session_autoload_test" do
+ get "/get_session_value"
+ assert_response :success
+ assert_equal 'foo: #<SessionAutoloadTest::Foo bar:"baz">', response.body, "should auto-load unloaded class"
+ end
+ 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_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
+ assert_nil @cache.read("_session_id:0xhax")
+
+ cookies["_session_id"] = "0xhax"
+ get "/set_session_value"
+
+ assert_response :success
+ assert_not_equal "0xhax", cookies["_session_id"]
+ assert_nil @cache.read("_session_id:0xhax")
+ assert_equal({ "foo" => "bar" }, @cache.read("_session_id:#{cookies['_session_id']}"))
+ end
+ end
+
+ private
+ def with_test_route_set
+ with_routing do |set|
+ set.draw do
+ ActiveSupport::Deprecation.silence do
+ get ":action", to: ::CacheStoreTest::TestController
+ end
+ end
+
+ @app = self.class.build_app(set) do |middleware|
+ @cache = ActiveSupport::Cache::MemoryStore.new
+ middleware.use ActionDispatch::Session::CacheStore, key: "_session_id", cache: @cache
+ middleware.delete ActionDispatch::ShowExceptions
+ end
+
+ yield
+ end
+ end
+end