Skip to content

Commit aaa1a4c

Browse files
committed
Add tests
1 parent 08ddd5b commit aaa1a4c

File tree

3 files changed

+175
-2
lines changed

3 files changed

+175
-2
lines changed

packages/http/src/Session/Config/RedisSessionConfig.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,4 @@ public function createManager(Container $container): RedisSessionManager
2323
{
2424
return $container->get(RedisSessionManager::class);
2525
}
26-
2726
}

packages/http/src/Session/Managers/RedisSessionManager.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
use Tempest\Http\Session\SessionId;
1212
use Tempest\Http\Session\SessionManager;
1313
use Tempest\KeyValue\Redis\Redis;
14-
use Tempest\Support\Filesystem;
1514
use Throwable;
15+
1616
use function Tempest\event;
1717

1818
final readonly class RedisSessionManager implements SessionManager
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Integration\Http;
6+
7+
use PHPUnit\Framework\Attributes\Test;
8+
use Tempest\Clock\Clock;
9+
use Tempest\DateTime\Duration;
10+
use Tempest\EventBus\EventBus;
11+
use Tempest\Http\Session\Config\RedisSessionConfig;
12+
use Tempest\Http\Session\Managers\RedisSessionManager;
13+
use Tempest\Http\Session\Session;
14+
use Tempest\Http\Session\SessionConfig;
15+
use Tempest\Http\Session\SessionDestroyed;
16+
use Tempest\Http\Session\SessionId;
17+
use Tempest\Http\Session\SessionManager;
18+
use Tempest\KeyValue\Redis\Redis;
19+
use Tests\Tempest\Integration\FrameworkIntegrationTestCase;
20+
21+
/**
22+
* @internal
23+
*/
24+
final class RedisSessionTest extends FrameworkIntegrationTestCase
25+
{
26+
protected function setUp(): void
27+
{
28+
parent::setUp();
29+
30+
$this->container->config(new RedisSessionConfig(expiration: Duration::hours(2)));
31+
$this->container->singleton(
32+
SessionManager::class,
33+
fn () => new RedisSessionManager(
34+
$this->container->get(Clock::class),
35+
$this->container->get(Redis::class),
36+
$this->container->get(SessionConfig::class),
37+
),
38+
);
39+
}
40+
41+
#[Test]
42+
public function create_session_from_container(): void
43+
{
44+
$session = $this->container->get(Session::class);
45+
46+
$this->assertInstanceOf(Session::class, $session);
47+
}
48+
49+
#[Test]
50+
public function put_get(): void
51+
{
52+
$session = $this->container->get(Session::class);
53+
54+
$session->set('test', 'value');
55+
56+
$value = $session->get('test');
57+
$this->assertEquals('value', $value);
58+
}
59+
60+
#[Test]
61+
public function remove(): void
62+
{
63+
$session = $this->container->get(Session::class);
64+
65+
$session->set('test', 'value');
66+
$session->remove('test');
67+
68+
$value = $session->get('test');
69+
$this->assertNull($value);
70+
}
71+
72+
#[Test]
73+
public function destroy(): void
74+
{
75+
$manager = $this->container->get(SessionManager::class);
76+
$sessionId = new SessionId('test_session_destroy');
77+
78+
$session = $manager->create($sessionId);
79+
$session->set('magic_type', 'offensive');
80+
81+
$this->assertTrue($manager->isValid($sessionId));
82+
83+
$events = [];
84+
$eventBus = $this->container->get(EventBus::class);
85+
$eventBus->listen(function (SessionDestroyed $event) use (&$events): void {
86+
$events[] = $event;
87+
});
88+
89+
$session->destroy();
90+
91+
$this->assertFalse($manager->isValid($sessionId));
92+
$this->assertCount(1, $events);
93+
$this->assertEquals((string) $sessionId, (string) $events[0]->id);
94+
}
95+
96+
#[Test]
97+
public function set_previous_url(): void
98+
{
99+
$session = $this->container->get(Session::class);
100+
$session->setPreviousUrl('http://localhost/previous');
101+
102+
$this->assertEquals('http://localhost/previous', $session->getPreviousUrl());
103+
}
104+
105+
#[Test]
106+
public function is_valid(): void
107+
{
108+
$clock = $this->clock('2023-01-01 00:00:00');
109+
110+
$this->container->config(new RedisSessionConfig(
111+
expiration: Duration::second(),
112+
));
113+
114+
$sessionManager = $this->container->get(SessionManager::class);
115+
116+
$this->assertFalse($sessionManager->isValid(new SessionId('unknown')));
117+
118+
$session = $sessionManager->create(new SessionId('new'));
119+
120+
$this->assertTrue($session->isValid());
121+
122+
$clock->plus(1);
123+
124+
$this->assertFalse($session->isValid());
125+
}
126+
127+
#[Test]
128+
public function session_reflash(): void
129+
{
130+
$session = $this->container->get(Session::class);
131+
132+
$session->flash('test', 'value');
133+
$session->flash('test2', ['key' => 'value']);
134+
135+
$this->assertEquals('value', $session->get('test'));
136+
137+
$session->reflash();
138+
$session->cleanup();
139+
140+
$this->assertEquals('value', $session->get('test'));
141+
$this->assertEquals(['key' => 'value'], $session->get('test2'));
142+
}
143+
144+
#[Test]
145+
public function session_expires_based_on_last_activity(): void
146+
{
147+
$clock = $this->clock('2023-01-01 00:00:00');
148+
149+
$this->container->config(new RedisSessionConfig(
150+
expiration: Duration::minutes(30),
151+
));
152+
153+
$manager = $this->container->get(SessionManager::class);
154+
$sessionId = new SessionId('last_activity_test');
155+
156+
// Create session
157+
$session = $manager->create($sessionId);
158+
$this->assertTrue($session->isValid());
159+
160+
$clock->plus(Duration::minutes(25));
161+
$this->assertTrue($session->isValid());
162+
163+
// Perform activity
164+
$session->set('activity', 'user_action');
165+
$clock->plus(Duration::minutes(25));
166+
$this->assertTrue($session->isValid());
167+
$this->assertTrue($manager->isValid($sessionId));
168+
169+
// Move forward another 10 minutes, now 35 minutes from last activity
170+
$clock->plus(Duration::minutes(10));
171+
$this->assertFalse($session->isValid());
172+
$this->assertFalse($manager->isValid($sessionId));
173+
}
174+
}

0 commit comments

Comments
 (0)