unbreak backwards compatibility
[catagits/Catalyst-Plugin-Session.git] / t / 02_session_data.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Test::More tests => 25;
7 use Test::MockObject;
8 use Test::Deep;
9 use Test::Exception;
10
11 my $m;
12 BEGIN { use_ok( $m = "Catalyst::Plugin::Session" ) }
13
14 my %config;
15 my $log      = Test::MockObject->new;
16 my $req      = Test::MockObject->new;
17 my @mock_isa = ();
18 my %session;
19
20 $log->set_true(qw/fatal warn error/);
21
22 $req->set_always( address => "127.0.0.1" );
23
24 {
25
26     package MockCxt;
27     use base $m;
28     sub new { bless {}, $_[0] }
29     sub config  { \%config }
30     sub log     { $log }
31     sub request { $req }
32     sub debug   { 0 }
33     sub isa     { 1 }          # subvert the plugin tests, we're faking them
34     sub get_session_data    { \%session }
35     sub store_session_data  { }
36     sub delete_session_data { }
37 }
38
39 {
40     my $c = MockCxt->new;
41     $c->setup;
42
43     $c->_load_session;
44     ok( !$c->_session, "without a session ID prepare doesn't load a session" );
45 }
46
47 {
48     %config = ( session => { expires => 100 } );
49
50     %session = (
51         __expires => time() + 1000,
52         __created => time(),
53         __updated => time(),
54         __address => "127.0.0.1",
55     );
56
57     my $c = MockCxt->new;
58     $c->setup;
59
60     $c->sessionid("decafbad");
61     $c->_load_session;
62
63     ok( $c->_session, 'session "restored" with session id' );
64 }
65
66 {
67     %session = (
68         __expires => time() - 100,    # a while ago
69         __created => time() - 1000,
70         __udpated => time() - 1000,
71         __address => "127.0.0.1",
72     );
73
74     my $c = MockCxt->new;
75     $c->setup;
76
77     $c->sessionid("decafbad");
78     $c->_load_session;
79
80     ok( !$c->_session, "expired sessions are deleted" );
81     like( $c->session_delete_reason, qr/expire/i, "with appropriate reason" );
82     ok( !$c->sessionid, "sessionid is also cleared" );
83 }
84
85 {
86     %session = (
87         __expires => time() + 1000,
88         __created => time(),
89         __updated => time(),
90         __address => "unlocalhost",
91     );
92
93     my $c = MockCxt->new;
94     $c->setup;
95
96     $c->sessionid("decafbad");
97     $c->_load_session;
98
99     ok( !$c->_session, "hijacked sessions are deleted" );
100     like( $c->session_delete_reason, qr/mismatch/, "with appropriate reason" );
101     ok( !$c->sessionid, "sessionid is also cleared" );
102 }
103
104 {
105     %session = (
106         __expires => time() + 1000,
107         __created => time(),
108         __updated => time(),
109         __address => "unlocalhost",
110     );
111
112     $config{session}{verify_address} = 0;
113
114     my $c = MockCxt->new;
115     $c->setup;
116
117     $c->sessionid("decafbad");
118     $c->_load_session;
119
120     ok( $c->_session, "address mismatch is OK if verify_address is disabled" );
121 }
122
123 {
124     %session = ();
125     %config  = ();
126
127     my $now = time;
128
129     my $c = MockCxt->new;
130     $c->setup;
131     $c->_load_session;
132
133     ok( $c->session,   "creating a session works" );
134     ok( $c->sessionid, "session id generated" );
135
136     cmp_ok( $c->session->{__created}, ">=", $now, "__created time is logical" );
137     cmp_ok( $c->session->{__updated}, ">=", $now, "__updated time is logical" );
138     cmp_ok(
139         $c->session->{__expires},
140         ">=",
141         ( $now + $config{session}{expires} ),
142         "__expires time is logical"
143     );
144     is( $c->session->{__address},
145         $c->request->address, "address is also correct" );
146
147     cmp_deeply(
148         [ keys %{ $c->_session } ],
149         bag(qw/__expires __created __updated __address/),
150         "initial keys in session are all there",
151     );
152 }
153
154 {
155     %session = (
156         __expires => time() + 1000,
157         __created => time(),
158         __updated => time(),
159         __address => "127.0.0.1",
160     );
161
162     $config{session}{expires} = 2000;
163
164     my $c = MockCxt->new;
165     $c->setup;
166
167     my $now = time();
168
169     $c->sessionid("decafbad");
170     $c->_load_session;
171     $c->finalize;
172
173     ok( $c->_session,
174         "session is still alive after 1/2 expired and finalized" );
175
176     cmp_ok(
177         $c->session->{__expires},
178         ">=",
179         $now + 2000,
180         "session expires time extended"
181     );
182 }
183
184 {
185     my $c = MockCxt->new;
186     $c->setup;
187
188         dies_ok {
189                 $c->sessionid("user:foo");
190         } "can't set invalid sessionid string";
191 }
192
193 {
194     %session = (
195         %session,
196         __expire_keys => {
197             foo => time - 1000,
198             bar => time + 1000,
199         },
200         foo => 1,
201         bar => 2,
202         gorch => 3,
203     );
204
205     my $c = MockCxt->new;
206     $c->setup;
207
208     $c->sessionid("decafbad");
209     $c->_load_session;
210     $c->finalize;
211
212     ok( !$c->session->{foo}, "foo was deleted, expired");
213     ok( $c->session->{bar}, "bar not deleted - still valid");
214     ok( $c->session->{gorch}, "gorch not deleted - no expiry");
215
216     is_deeply( [ sort keys %{ $c->session->{__expire_keys} } ], [qw/bar/], "expiry entry only for bar");
217
218     $c->session_expire_key( gorch => 10 );
219
220     is_deeply( [ sort keys %{ $c->session->{__expire_keys} } ], [qw/bar gorch/], "expiry entries for bar and gorch");
221 }