Updated README.rdoc again
[feedcatcher.git] / vendor / rails / actionpack / test / controller / session / cookie_store_test.rb
1 require 'abstract_unit'
2 require 'stringio'
3
4 class CookieStoreTest < ActionController::IntegrationTest
5 SessionKey = '_myapp_session'
6 SessionSecret = 'b3c631c314c0bbca50c1b2843150fe33'
7
8 DispatcherApp = ActionController::Dispatcher.new
9 CookieStoreApp = ActionController::Session::CookieStore.new(DispatcherApp, :key => SessionKey, :secret => SessionSecret)
10
11 Verifier = ActiveSupport::MessageVerifier.new(SessionSecret, 'SHA1')
12
13 SignedBar = "BAh7BjoIZm9vIghiYXI%3D--fef868465920f415f2c0652d6910d3af288a0367"
14
15 class TestController < ActionController::Base
16 def no_session_access
17 head :ok
18 end
19
20 def persistent_session_id
21 render :text => session[:session_id]
22 end
23
24 def set_session_value
25 session[:foo] = "bar"
26 render :text => Rack::Utils.escape(Verifier.generate(session.to_hash))
27 end
28
29 def get_session_value
30 render :text => "foo: #{session[:foo].inspect}"
31 end
32
33 def get_session_id
34 render :text => "foo: #{session[:foo].inspect}; id: #{request.session_options[:id]}"
35 end
36
37 def call_reset_session
38 reset_session
39 head :ok
40 end
41
42 def raise_data_overflow
43 session[:foo] = 'bye!' * 1024
44 head :ok
45 end
46
47 def rescue_action(e) raise end
48 end
49
50 def setup
51 @integration_session = open_session(CookieStoreApp)
52 end
53
54 def test_raises_argument_error_if_missing_session_key
55 assert_raise(ArgumentError, nil.inspect) {
56 ActionController::Session::CookieStore.new(nil,
57 :key => nil, :secret => SessionSecret)
58 }
59
60 assert_raise(ArgumentError, ''.inspect) {
61 ActionController::Session::CookieStore.new(nil,
62 :key => '', :secret => SessionSecret)
63 }
64 end
65
66 def test_raises_argument_error_if_missing_secret
67 assert_raise(ArgumentError, nil.inspect) {
68 ActionController::Session::CookieStore.new(nil,
69 :key => SessionKey, :secret => nil)
70 }
71
72 assert_raise(ArgumentError, ''.inspect) {
73 ActionController::Session::CookieStore.new(nil,
74 :key => SessionKey, :secret => '')
75 }
76 end
77
78 def test_raises_argument_error_if_secret_is_probably_insecure
79 assert_raise(ArgumentError, "password".inspect) {
80 ActionController::Session::CookieStore.new(nil,
81 :key => SessionKey, :secret => "password")
82 }
83
84 assert_raise(ArgumentError, "secret".inspect) {
85 ActionController::Session::CookieStore.new(nil,
86 :key => SessionKey, :secret => "secret")
87 }
88
89 assert_raise(ArgumentError, "12345678901234567890123456789".inspect) {
90 ActionController::Session::CookieStore.new(nil,
91 :key => SessionKey, :secret => "12345678901234567890123456789")
92 }
93 end
94
95 def test_setting_session_value
96 with_test_route_set do
97 get '/set_session_value'
98 assert_response :success
99 assert_equal "_myapp_session=#{response.body}; path=/; HttpOnly",
100 headers['Set-Cookie']
101 end
102 end
103
104 def test_getting_session_value
105 with_test_route_set do
106 cookies[SessionKey] = SignedBar
107 get '/get_session_value'
108 assert_response :success
109 assert_equal 'foo: "bar"', response.body
110 end
111 end
112
113 def test_getting_session_id
114 with_test_route_set do
115 cookies[SessionKey] = SignedBar
116 get '/persistent_session_id'
117 assert_response :success
118 assert_equal response.body.size, 32
119 session_id = response.body
120
121 get '/get_session_id'
122 assert_response :success
123 assert_equal "foo: \"bar\"; id: #{session_id}", response.body
124 end
125 end
126
127 def test_disregards_tampered_sessions
128 with_test_route_set do
129 cookies[SessionKey] = "BAh7BjoIZm9vIghiYXI%3D--123456780"
130 get '/get_session_value'
131 assert_response :success
132 assert_equal 'foo: nil', response.body
133 end
134 end
135
136 def test_close_raises_when_data_overflows
137 with_test_route_set do
138 assert_raise(ActionController::Session::CookieStore::CookieOverflow) {
139 get '/raise_data_overflow'
140 }
141 end
142 end
143
144 def test_doesnt_write_session_cookie_if_session_is_not_accessed
145 with_test_route_set do
146 get '/no_session_access'
147 assert_response :success
148 assert_equal "", headers['Set-Cookie']
149 end
150 end
151
152 def test_doesnt_write_session_cookie_if_session_is_unchanged
153 with_test_route_set do
154 cookies[SessionKey] = "BAh7BjoIZm9vIghiYXI%3D--" +
155 "fef868465920f415f2c0652d6910d3af288a0367"
156 get '/no_session_access'
157 assert_response :success
158 assert_equal "", headers['Set-Cookie']
159 end
160 end
161
162 def test_setting_session_value_after_session_reset
163 with_test_route_set do
164 get '/set_session_value'
165 assert_response :success
166 session_payload = response.body
167 assert_equal "_myapp_session=#{response.body}; path=/; HttpOnly",
168 headers['Set-Cookie']
169
170 get '/call_reset_session'
171 assert_response :success
172 assert_not_equal [], headers['Set-Cookie']
173 assert_not_equal session_payload, cookies[SessionKey]
174
175 get '/get_session_value'
176 assert_response :success
177 assert_equal 'foo: nil', response.body
178 end
179 end
180
181 def test_persistent_session_id
182 with_test_route_set do
183 cookies[SessionKey] = SignedBar
184 get '/persistent_session_id'
185 assert_response :success
186 assert_equal response.body.size, 32
187 session_id = response.body
188 get '/persistent_session_id'
189 assert_equal session_id, response.body
190 reset!
191 get '/persistent_session_id'
192 assert_not_equal session_id, response.body
193 end
194 end
195
196 def test_session_store_with_expire_after
197 app = ActionController::Session::CookieStore.new(DispatcherApp, :key => SessionKey, :secret => SessionSecret, :expire_after => 5.hours)
198 @integration_session = open_session(app)
199
200 with_test_route_set do
201 # First request accesses the session
202 time = Time.local(2008, 4, 24)
203 Time.stubs(:now).returns(time)
204 expected_expiry = (time + 5.hours).gmtime.strftime("%a, %d-%b-%Y %H:%M:%S GMT")
205
206 cookies[SessionKey] = SignedBar
207
208 get '/set_session_value'
209 assert_response :success
210
211 cookie_body = response.body
212 assert_equal "_myapp_session=#{cookie_body}; path=/; expires=#{expected_expiry}; HttpOnly",
213 headers['Set-Cookie']
214
215 # Second request does not access the session
216 time = Time.local(2008, 4, 25)
217 Time.stubs(:now).returns(time)
218 expected_expiry = (time + 5.hours).gmtime.strftime("%a, %d-%b-%Y %H:%M:%S GMT")
219
220 get '/no_session_access'
221 assert_response :success
222
223 assert_equal "_myapp_session=#{cookie_body}; path=/; expires=#{expected_expiry}; HttpOnly",
224 headers['Set-Cookie']
225 end
226 end
227
228 private
229 def with_test_route_set
230 with_routing do |set|
231 set.draw do |map|
232 map.with_options :controller => "cookie_store_test/test" do |c|
233 c.connect "/:action"
234 end
235 end
236 yield
237 end
238 end
239 end