Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
158 / 158
100.00% covered (success)
100.00%
1 / 1
CRAP
n/a
0 / 0
resetSession
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3// ╔════════════════════════════════════════════════════════════╗
4// ║ MIT Licence (#Expat) - https://opensource.org/licenses/MIT ║
5// ║ Copyright 2026 Frederic Poeydomenge <dyno@phexium.com>     ║
6// ╚════════════════════════════════════════════════════════════╝
7
8declare(strict_types=1);
9
10use Phexium\Plugin\Session\Adapter\NativeSession;
11use Phexium\Plugin\Session\Port\FlashInterface;
12
13function resetSession(): void
14{
15    if (session_status() === PHP_SESSION_ACTIVE) {
16        session_destroy();
17    } else {
18        ini_set('session.use_cookies', '0');
19        ini_set('session.cache_limiter', '');
20    }
21
22    $_SESSION = [];
23
24    session_id(bin2hex(random_bytes(16)));
25}
26beforeEach(function (): void {
27    resetSession();
28});
29
30afterEach(function (): void {
31    resetSession();
32});
33
34test('Set and get a value from session', function (): void {
35    $session = new NativeSession();
36    $session->start();
37
38    $session->set('foo', 'bar');
39
40    expect($session->get('foo'))->toBe('bar');
41});
42
43test('Return null when key does not exist', function (): void {
44    $session = new NativeSession();
45    $session->start();
46
47    expect($session->get('non_existent_key'))->toBeNull();
48});
49
50test('Return default value when key does not exist', function (): void {
51    $session = new NativeSession();
52    $session->start();
53
54    expect($session->get('non_existent_key', 'default'))->toBe('default');
55});
56
57test('Check if a value exists in session', function (): void {
58    $session = new NativeSession();
59    $session->start();
60
61    expect($session->has('foo'))->toBeFalse();
62
63    $session->set('foo', 'bar');
64
65    expect($session->has('foo'))->toBeTrue();
66});
67
68test('Clear all session data', function (): void {
69    $session = new NativeSession();
70    $session->start();
71    $session->set('foo', 'bar');
72
73    $session->clear();
74
75    expect($session->has('foo'))->toBeFalse();
76});
77
78test('Restart the session after clear', function (): void {
79    $session = new NativeSession();
80    $session->start();
81    $session->set('foo', 'bar');
82
83    $session->clear();
84    $session->start();
85
86    expect($session->isStarted())->toBeTrue();
87    expect($session->all())->toBeEmpty();
88});
89
90test('Delete a value from session', function (): void {
91    $session = new NativeSession();
92    $session->start();
93    $session->set('foo', 'bar');
94
95    expect($session->has('foo'))->toBeTrue();
96
97    $session->delete('foo');
98
99    expect($session->has('foo'))->toBeFalse();
100});
101
102test('Add flash message and retrieve via getFlash', function (): void {
103    $session = new NativeSession();
104    $session->start();
105
106    $session->addFlashMessage('success', 'Success message #1');
107    $session->addFlashMessage('error', 'Error message');
108    $session->addFlashMessage('success', 'Success message #2');
109
110    $flash = $session->getFlash();
111
112    expect($flash)->toBeInstanceOf(FlashInterface::class);
113
114    $successMessages = $flash->get('success');
115    expect($successMessages)->toHaveCount(2);
116    expect($successMessages)->toContain('Success message #1');
117    expect($successMessages)->toContain('Success message #2');
118
119    $errorMessages = $flash->get('error');
120    expect($errorMessages)->toHaveCount(1);
121    expect($errorMessages)->toContain('Error message');
122});
123
124test('Regenerate session id', function (): void {
125    $session = new NativeSession();
126    $session->start();
127
128    $oldId = $session->getId();
129    $session->regenerateId();
130    $newId = $session->getId();
131
132    expect($oldId)->not->toBeEmpty();
133    expect($newId)->not->toBeEmpty();
134    expect($oldId)->not->toBe($newId);
135});
136
137test('Get session id and name', function (): void {
138    $session = new NativeSession('myapp');
139    $session->start();
140
141    expect($session->getId())->not->toBeEmpty();
142    expect($session->getName())->toBe('myapp');
143});
144
145test('Replace all session data', function (): void {
146    $session = new NativeSession();
147    $session->start();
148    $session->set('foo', 'bar');
149
150    $session->replace(['qix' => 'baz']);
151
152    expect($session->has('foo'))->toBeFalse();
153    expect($session->has('qix'))->toBeTrue();
154    expect($session->get('qix'))->toBe('baz');
155});
156
157test('Count session data keys', function (): void {
158    $session = new NativeSession();
159    $session->start();
160
161    expect($session->count())->toBe(0);
162
163    $session->set('key1', 'value1');
164    expect($session->count())->toBe(1);
165
166    $session->set('key2', 'value2');
167    $session->set('key3', 'value3');
168    expect($session->count())->toBe(3);
169
170    $session->delete('key2');
171    expect($session->count())->toBe(2);
172});
173
174test('Destroy session', function (): void {
175    $session = new NativeSession();
176    $session->start();
177    $session->set('foo', 'bar');
178
179    $oldId = $session->getId();
180
181    $session->destroy();
182
183    $newId = $session->getId();
184
185    expect($oldId)->not->toBe($newId);
186    expect($session->has('foo'))->toBeFalse();
187    expect($session->count())->toBe(0);
188});
189
190test('Destroy session with cookies enabled clears cookie', function (): void {
191    ini_set('session.use_cookies', '1');
192
193    $session = new NativeSession();
194    $session->start();
195    $session->set('foo', 'bar');
196
197    $oldId = $session->getId();
198
199    @$session->destroy();
200
201    $newId = $session->getId();
202
203    expect($oldId)->not->toBe($newId);
204    expect($session->has('foo'))->toBeFalse();
205    expect($session->count())->toBe(0);
206
207    $session->save();
208    ini_set('session.use_cookies', '0');
209});
210
211test('Start session multiple times does not restart already started session', function (): void {
212    $session = new NativeSession();
213    $session->start();
214    $id1 = $session->getId();
215
216    $session->start();
217    $id2 = $session->getId();
218
219    expect($id1)->toBe($id2);
220});
221
222test('Save session closes the session for writing', function (): void {
223    $session = new NativeSession();
224    $session->start();
225    $session->set('foo', 'bar');
226
227    $session->save();
228
229    expect(session_status())->toBe(PHP_SESSION_NONE);
230});
231
232test('isStarted returns false before start and true after', function (): void {
233    $session = new NativeSession();
234
235    expect($session->isStarted())->toBeFalse();
236
237    $session->start();
238
239    expect($session->isStarted())->toBeTrue();
240});