Upgraded Rails and RSpec
[monkeycharger.git] / vendor / rails / actionpack / test / controller / session / cookie_store_test.rb
blobb2655c72d91b649ed4002a8f5e7d4173b7a4f6a0
1 require "#{File.dirname(__FILE__)}/../../abstract_unit"
2 require 'action_controller/cgi_process'
3 require 'action_controller/cgi_ext'
5 require 'stringio'
8 class CGI::Session::CookieStore
9   def ensure_secret_secure_with_test_hax(secret)
10     if secret == CookieStoreTest.default_session_options['secret']
11       return true
12     else
13       ensure_secret_secure_without_test_hax(secret)
14     end
15   end
16   alias_method_chain :ensure_secret_secure, :test_hax
17 end
20 # Expose for tests.
21 class CGI
22   attr_reader :output_cookies, :output_hidden
24   class Session
25     attr_reader :dbman
27     class CookieStore
28       attr_reader :data, :original, :cookie_options
29     end
30   end
31 end
33 class CookieStoreTest < Test::Unit::TestCase
34   def self.default_session_options
35     { 'database_manager' => CGI::Session::CookieStore,
36       'session_key' => '_myapp_session',
37       'secret' => 'Keep it secret; keep it safe.',
38       'no_cookies' => true,
39       'no_hidden' => true }
40   end
42   def self.cookies
43     { :empty => ['BAgw--0686dcaccc01040f4bd4f35fe160afe9bc04c330', {}],
44       :a_one => ['BAh7BiIGYWkG--5689059497d7f122a7119f171aef81dcfd807fec', { 'a' => 1 }],
45       :typical => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7BiILbm90aWNlIgxIZXkgbm93--9d20154623b9eeea05c62ab819be0e2483238759', { 'user_id' => 123, 'flash' => { 'notice' => 'Hey now' }}],
46       :flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--bf9785a666d3c4ac09f7fe3353496b437546cfbf', { 'user_id' => 123, 'flash' => {} }] }
47   end
49   def setup
50     ENV.delete('HTTP_COOKIE')
51   end
53   def test_raises_argument_error_if_missing_session_key
54     [nil, ''].each do |blank|
55       assert_raise(ArgumentError, blank.inspect) { new_session 'session_key' => blank }
56     end
57   end
59   def test_raises_argument_error_if_missing_secret
60     [nil, ''].each do |blank|
61       assert_raise(ArgumentError, blank.inspect) { new_session 'secret' => blank }
62     end
63   end
65   def test_raises_argument_error_if_secret_is_probably_insecure
66     ["password", "secret", "12345678901234567890123456789"].each do |blank|
67       assert_raise(ArgumentError, blank.inspect) { new_session 'secret' => blank }
68     end
69   end
71   def test_reconfigures_session_to_omit_id_cookie_and_hidden_field
72     new_session do |session|
73       assert_equal true, @options['no_hidden']
74       assert_equal true, @options['no_cookies']
75     end
76   end
78   def test_restore_unmarshals_missing_cookie_as_empty_hash
79     new_session do |session|
80       assert_nil session.dbman.data
81       assert_nil session['test']
82       assert_equal Hash.new, session.dbman.data
83     end
84   end
86   def test_restore_unmarshals_good_cookies
87     cookies(:empty, :a_one, :typical).each do |value, expected|
88       set_cookie! value
89       new_session do |session|
90         assert_nil session['lazy loads the data hash']
91         assert_equal expected, session.dbman.data
92       end
93     end
94   end
96   def test_restore_deletes_tampered_cookies
97     set_cookie! 'a--b'
98     new_session do |session|
99       assert_raise(CGI::Session::CookieStore::TamperedWithCookie) { session['fail'] }
100       assert_cookie_deleted session
101     end
102   end
104   def test_close_doesnt_write_cookie_if_data_is_blank
105     new_session do |session|
106       assert_no_cookies session
107       session.close
108       assert_no_cookies session
109     end
110   end
112   def test_close_doesnt_write_cookie_if_data_is_unchanged
113     set_cookie! cookie_value(:typical)
114     new_session do |session|
115       assert_no_cookies session
116       session['user_id'] = session['user_id']
117       session.close
118       assert_no_cookies session
119     end
120   end
122   def test_close_raises_when_data_overflows
123     set_cookie! cookie_value(:empty)
124     new_session do |session|
125       session['overflow'] = 'bye!' * 1024
126       assert_raise(CGI::Session::CookieStore::CookieOverflow) { session.close }
127       assert_no_cookies session
128     end
129   end
131   def test_close_marshals_and_writes_cookie
132     set_cookie! cookie_value(:typical)
133     new_session do |session|
134       assert_no_cookies session
135       session['flash'] = {}
136       assert_no_cookies session
137       session.close
138       assert_equal 1, session.cgi.output_cookies.size
139       cookie = session.cgi.output_cookies.first
140       assert_cookie cookie, cookie_value(:flashed)
141     end
142   end
144   def test_delete_writes_expired_empty_cookie_and_sets_data_to_nil
145     set_cookie! cookie_value(:typical)
146     new_session do |session|
147       assert_no_cookies session
148       session.delete
149       assert_cookie_deleted session
151       # @data is set to nil so #close doesn't send another cookie.
152       session.close
153       assert_cookie_deleted session
154     end
155   end
157   def test_new_session_doesnt_reuse_deleted_cookie_data
158     set_cookie! cookie_value(:typical)
160     new_session do |session|
161       assert_not_nil session['user_id']
162       session.delete
164       # Start a new session using the same CGI instance.
165       post_delete_session = CGI::Session.new(session.cgi, self.class.default_session_options)
166       assert_nil post_delete_session['user_id']
167     end
168   end
170   private
171     def assert_no_cookies(session)
172       assert_nil session.cgi.output_cookies, session.cgi.output_cookies.inspect
173     end
175     def assert_cookie_deleted(session, message = 'Expected session deletion cookie to be set')
176       assert_equal 1, session.cgi.output_cookies.size
177       cookie = session.cgi.output_cookies.first
178       assert_cookie cookie, nil, 1.year.ago.to_date, message
179     end
181     def assert_cookie(cookie, value = nil, expires = nil, message = nil)
182       assert_equal '_myapp_session', cookie.name, message
183       assert_equal [value].compact, cookie.value, message
184       assert_equal expires, cookie.expires ? cookie.expires.to_date : cookie.expires, message
185     end
188     def cookies(*which)
189       self.class.cookies.values_at(*which)
190     end
192     def cookie_value(which)
193       self.class.cookies[which].first
194     end
196     def set_cookie!(value)
197       ENV['HTTP_COOKIE'] = "_myapp_session=#{value}"
198     end
200     def new_session(options = {})
201       with_cgi do |cgi|
202         assert_nil cgi.output_hidden, "Output hidden params should be empty: #{cgi.output_hidden.inspect}"
203         assert_nil cgi.output_cookies, "Output cookies should be empty: #{cgi.output_cookies.inspect}"
205         @options = self.class.default_session_options.merge(options)
206         session = CGI::Session.new(cgi, @options)
208         assert_nil cgi.output_hidden, "Output hidden params should be empty: #{cgi.output_hidden.inspect}"
209         assert_nil cgi.output_cookies, "Output cookies should be empty: #{cgi.output_cookies.inspect}"
211         yield session if block_given?
212         session
213       end
214     end
216     def with_cgi
217       ENV['REQUEST_METHOD'] = 'GET'
218       ENV['HTTP_HOST'] = 'example.com'
219       ENV['QUERY_STRING'] = ''
221       cgi = CGI.new('query', StringIO.new(''))
222       yield cgi if block_given?
223       cgi
224     end
228 class CookieStoreWithBlockAsSecretTest < CookieStoreTest
229   def self.default_session_options
230     CookieStoreTest.default_session_options.merge 'secret' => Proc.new { 'Keep it secret; keep it safe.' }
231   end
235 class CookieStoreWithMD5DigestTest < CookieStoreTest
236   def self.default_session_options
237     CookieStoreTest.default_session_options.merge 'digest' => 'MD5'
238   end
240   def self.cookies
241     { :empty => ['BAgw--0415cc0be9579b14afc22ee2d341aa21', {}],
242       :a_one => ['BAh7BiIGYWkG--5a0ed962089cc6600ff44168a5d59bc8', { 'a' => 1 }],
243       :typical => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7BiILbm90aWNlIgxIZXkgbm93--f426763f6ef435b3738b493600db8d64', { 'user_id' => 123, 'flash' => { 'notice' => 'Hey now' }}],
244       :flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--0af9156650dab044a53a91a4ddec2c51', { 'user_id' => 123, 'flash' => {} }] }
245   end