Lots going on
[lyrix.git] / vendor / rails / actionpack / test / controller / session / cookie_store_test.rb
blob0084f35deaa3dfb6d86e025465146efec516469c
1 require "#{File.dirname(__FILE__)}/../../abstract_unit"
2 require 'action_controller/cgi_process'
3 require 'action_controller/cgi_ext'
5 require 'stringio'
7 # Expose for tests.
8 class CGI
9   attr_reader :output_cookies, :output_hidden
11   class Session
12     attr_reader :dbman
14     class CookieStore
15       attr_reader :data, :original, :cookie_options
16     end
17   end
18 end
20 class CookieStoreTest < Test::Unit::TestCase
21   def self.default_session_options
22     { 'database_manager' => CGI::Session::CookieStore,
23       'session_key' => '_myapp_session',
24       'secret' => 'Keep it secret; keep it safe.',
25       'no_cookies' => true,
26       'no_hidden' => true }
27   end
29   def self.cookies
30     { :empty => ['BAgw--0686dcaccc01040f4bd4f35fe160afe9bc04c330', {}],
31       :a_one => ['BAh7BiIGYWkG--5689059497d7f122a7119f171aef81dcfd807fec', { 'a' => 1 }],
32       :typical => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7BiILbm90aWNlIgxIZXkgbm93--9d20154623b9eeea05c62ab819be0e2483238759', { 'user_id' => 123, 'flash' => { 'notice' => 'Hey now' }}],
33       :flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--bf9785a666d3c4ac09f7fe3353496b437546cfbf', { 'user_id' => 123, 'flash' => {} }] }
34   end
36   def setup
37     ENV.delete('HTTP_COOKIE')
38   end
40   def test_raises_argument_error_if_missing_session_key
41     [nil, ''].each do |blank|
42       assert_raise(ArgumentError, blank.inspect) { new_session 'session_key' => blank }
43     end
44   end
46   def test_raises_argument_error_if_missing_secret
47     [nil, ''].each do |blank|
48       assert_raise(ArgumentError, blank.inspect) { new_session 'secret' => blank }
49     end
50   end
52   def test_reconfigures_session_to_omit_id_cookie_and_hidden_field
53     new_session do |session|
54       assert_equal true, @options['no_hidden']
55       assert_equal true, @options['no_cookies']
56     end
57   end
59   def test_restore_unmarshals_missing_cookie_as_empty_hash
60     new_session do |session|
61       assert_nil session.dbman.data
62       assert_nil session['test']
63       assert_equal Hash.new, session.dbman.data
64     end
65   end
67   def test_restore_unmarshals_good_cookies
68     cookies(:empty, :a_one, :typical).each do |value, expected|
69       set_cookie! value
70       new_session do |session|
71         assert_nil session['lazy loads the data hash']
72         assert_equal expected, session.dbman.data
73       end
74     end
75   end
77   def test_restore_deletes_tampered_cookies
78     set_cookie! 'a--b'
79     new_session do |session|
80       assert_raise(CGI::Session::CookieStore::TamperedWithCookie) { session['fail'] }
81       assert_cookie_deleted session
82     end
83   end
85   def test_close_doesnt_write_cookie_if_data_is_blank
86     new_session do |session|
87       assert_no_cookies session
88       session.close
89       assert_no_cookies session
90     end
91   end
93   def test_close_doesnt_write_cookie_if_data_is_unchanged
94     set_cookie! cookie_value(:typical)
95     new_session do |session|
96       assert_no_cookies session
97       session['user_id'] = session['user_id']
98       session.close
99       assert_no_cookies session
100     end
101   end
103   def test_close_raises_when_data_overflows
104     set_cookie! cookie_value(:empty)
105     new_session do |session|
106       session['overflow'] = 'bye!' * 1024
107       assert_raise(CGI::Session::CookieStore::CookieOverflow) { session.close }
108       assert_no_cookies session
109     end
110   end
112   def test_close_marshals_and_writes_cookie
113     set_cookie! cookie_value(:typical)
114     new_session do |session|
115       assert_no_cookies session
116       session['flash'] = {}
117       assert_no_cookies session
118       session.close
119       assert_equal 1, session.cgi.output_cookies.size
120       cookie = session.cgi.output_cookies.first
121       assert_cookie cookie, cookie_value(:flashed)
122     end
123   end
125   def test_delete_writes_expired_empty_cookie_and_sets_data_to_nil
126     set_cookie! cookie_value(:typical)
127     new_session do |session|
128       assert_no_cookies session
129       session.delete
130       assert_cookie_deleted session
132       # @data is set to nil so #close doesn't send another cookie.
133       session.close
134       assert_cookie_deleted session
135     end
136   end
138   def test_new_session_doesnt_reuse_deleted_cookie_data
139     set_cookie! cookie_value(:typical)
141     new_session do |session|
142       assert_not_nil session['user_id']
143       session.delete
145       # Start a new session using the same CGI instance.
146       post_delete_session = CGI::Session.new(session.cgi, self.class.default_session_options)
147       assert_nil post_delete_session['user_id']
148     end
149   end
151   private
152     def assert_no_cookies(session)
153       assert_nil session.cgi.output_cookies, session.cgi.output_cookies.inspect
154     end
156     def assert_cookie_deleted(session, message = 'Expected session deletion cookie to be set')
157       assert_equal 1, session.cgi.output_cookies.size
158       cookie = session.cgi.output_cookies.first
159       assert_cookie cookie, nil, 1.year.ago.to_date, message
160     end
162     def assert_cookie(cookie, value = nil, expires = nil, message = nil)
163       assert_equal '_myapp_session', cookie.name, message
164       assert_equal [value].compact, cookie.value, message
165       assert_equal expires, cookie.expires ? cookie.expires.to_date : cookie.expires, message
166     end
169     def cookies(*which)
170       self.class.cookies.values_at(*which)
171     end
173     def cookie_value(which)
174       self.class.cookies[which].first
175     end
177     def set_cookie!(value)
178       ENV['HTTP_COOKIE'] = "_myapp_session=#{value}"
179     end
181     def new_session(options = {})
182       with_cgi do |cgi|
183         assert_nil cgi.output_hidden, "Output hidden params should be empty: #{cgi.output_hidden.inspect}"
184         assert_nil cgi.output_cookies, "Output cookies should be empty: #{cgi.output_cookies.inspect}"
186         @options = self.class.default_session_options.merge(options)
187         session = CGI::Session.new(cgi, @options)
189         assert_nil cgi.output_hidden, "Output hidden params should be empty: #{cgi.output_hidden.inspect}"
190         assert_nil cgi.output_cookies, "Output cookies should be empty: #{cgi.output_cookies.inspect}"
192         yield session if block_given?
193         session
194       end
195     end
197     def with_cgi
198       ENV['REQUEST_METHOD'] = 'GET'
199       ENV['HTTP_HOST'] = 'example.com'
200       ENV['QUERY_STRING'] = ''
202       cgi = CGI.new('query', StringIO.new(''))
203       yield cgi if block_given?
204       cgi
205     end
209 class CookieStoreWithBlockAsSecretTest < CookieStoreTest
210   def self.default_session_options
211     CookieStoreTest.default_session_options.merge 'secret' => Proc.new { 'Keep it secret; keep it safe.' }
212   end
216 class CookieStoreWithMD5DigestTest < CookieStoreTest
217   def self.default_session_options
218     CookieStoreTest.default_session_options.merge 'digest' => 'MD5'
219   end
221   def self.cookies
222     { :empty => ['BAgw--0415cc0be9579b14afc22ee2d341aa21', {}],
223       :a_one => ['BAh7BiIGYWkG--5a0ed962089cc6600ff44168a5d59bc8', { 'a' => 1 }],
224       :typical => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7BiILbm90aWNlIgxIZXkgbm93--f426763f6ef435b3738b493600db8d64', { 'user_id' => 123, 'flash' => { 'notice' => 'Hey now' }}],
225       :flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--0af9156650dab044a53a91a4ddec2c51', { 'user_id' => 123, 'flash' => {} }] }
226   end