forked from rails/activerecord-session_store
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsession_test.rb
186 lines (151 loc) · 6.3 KB
/
session_test.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
require 'helper'
require 'active_record/session_store'
require 'active_support/core_ext/hash/keys'
module ActiveRecord
module SessionStore
class SessionTest < ActiveSupport::TestCase
attr_reader :session_klass
def setup
super
ActiveRecord::Base.connection.schema_cache.clear!
Session.drop_table! if Session.table_exists?
@session_klass = Class.new(Session)
ActiveRecord::SessionStore::Session.serializer = :json
end
def test_data_column_name
# default column name is 'data'
assert_equal 'data', Session.data_column_name
end
def test_table_name
assert_equal 'sessions', Session.table_name
end
def test_create_table!
assert !Session.table_exists?
Session.create_table!
assert Session.table_exists?
Session.drop_table!
assert !Session.table_exists?
end
def test_json_serialization
Session.create_table!
ActiveRecord::SessionStore::Session.serializer = :json
s = session_klass.create!(:data => 'world', :session_id => '7')
sessions = ActiveRecord::Base.connection.execute("SELECT * FROM #{Session.table_name}")
data = Session.deserialize(sessions[0][Session.data_column_name])
assert_equal s.data, data
end
def test_hybrid_serialization
Session.create_table!
# Star with marshal, which will serialize with Marshal
ActiveRecord::SessionStore::Session.serializer = :marshal
s1 = session_klass.create!(:data => 'world', :session_id => '1')
# Switch to hybrid, which will serialize as JSON
ActiveRecord::SessionStore::Session.serializer = :hybrid
s2 = session_klass.create!(:data => 'world', :session_id => '2')
# Check that first was serialized with Marshal and second as JSON
sessions = ActiveRecord::Base.connection.execute("SELECT * FROM #{Session.table_name}")
assert_equal ::Base64.encode64(Marshal.dump(s1.data)), sessions[0][Session.data_column_name]
assert_equal s2.data, Session.deserialize(sessions[1][Session.data_column_name])
end
def test_hybrid_deserialization
Session.create_table!
# Star with marshal, which will serialize with Marshal
ActiveRecord::SessionStore::Session.serializer = :marshal
s = session_klass.create!(:data => 'world', :session_id => '1')
# Switch to hybrid, which will deserialize with Marshal if needed
ActiveRecord::SessionStore::Session.serializer = :hybrid
# Check that it was serialized with Marshal,
sessions = ActiveRecord::Base.connection.execute("SELECT * FROM #{Session.table_name}")
assert_equal sessions[0][Session.data_column_name], ::Base64.encode64(Marshal.dump(s.data))
# deserializes properly,
session = Session.find_by_session_id(s.id)
assert_equal s.data, session.data
# and reserializes as JSON
session.save
sessions = ActiveRecord::Base.connection.execute("SELECT * FROM #{Session.table_name}")
assert_equal s.data,Session.deserialize(sessions[0][Session.data_column_name])
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
'sessid'
end
end
klass.create_table!
assert klass.columns_hash['sessid'], 'sessid column exists'
session = klass.new(:data => 'hello')
session.sessid = "100"
session.save!
found = klass.find_by_session_id("100")
assert_equal session, found
assert_equal session.sessid, found.session_id
ensure
klass.drop_table!
Session.reset_column_information
end
def test_find_by_session_id
Session.create_table!
session_id = "10"
s = session_klass.create!(:data => 'world', :session_id => session_id)
t = session_klass.find_by_session_id(session_id)
assert_equal s, t
assert_equal s.data, t.data
Session.drop_table!
end
def test_loaded?
Session.create_table!
s = Session.new
assert !s.loaded?, 'session is not loaded'
end
def test_session_can_be_secured
Session.create_table!
session_id = 'unsecure'
session = session_klass.create!(:data => 'world', :session_id => 'foo')
session.update_column(:session_id, session_id)
assert_equal 'unsecure', session.read_attribute(:session_id)
session.secure!
secured = Rack::Session::SessionId.new(session_id).private_id
assert_equal secured, session.reload.read_attribute(:session_id)
end
def test_session_can_be_secured_with_sessid_compatibility
# 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
'sessid'
end
end
klass.create_table!
session_id = 'unsecure'
session = klass.create!(:data => 'world', :sessid => 'foo')
session.update_column(:sessid, session_id)
assert_equal 'unsecure', session.read_attribute(:sessid)
session.secure!
secured = Rack::Session::SessionId.new(session_id).private_id
assert_equal secured, session.reload.read_attribute(:sessid)
ensure
klass.drop_table!
Session.reset_column_information
end
def test_secure_is_idempotent
Session.create_table!
session_id = 'unsecure'
session = session_klass.create!(:data => 'world', :session_id => 'foo')
session.update_column(:session_id, session_id)
assert_equal 'unsecure', session.read_attribute(:session_id)
session.secure!
private_id = session.read_attribute(:session_id)
session.secure!
session.reload
session.secure!
assert_equal private_id, session.reload.read_attribute(:session_id)
end
end
end
end