* * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ namespace Polymorphine\Session\Tests\SessionContext; use PHPUnit\Framework\TestCase; use Polymorphine\Session\SessionContext; use Polymorphine\Session\SessionStorageProvider; use Polymorphine\Session\Tests\Fixtures\SessionGlobalState; use Psr\Http\Server\MiddlewareInterface; use Polymorphine\Session\Tests\Doubles; use RuntimeException; require_once dirname(__DIR__) . '/Fixtures/session-functions.php'; class NativeSessionContextTest extends TestCase { protected function tearDown(): void { SessionGlobalState::reset(); } public function test_Instantiation() { $context = $this->context(); $this->assertInstanceOf(MiddlewareInterface::class, $context); $this->assertInstanceOf(SessionContext::class, $context); $this->assertInstanceOf(SessionStorageProvider::class, $context); } public function test_SessionName_IsSynchronizedWithCookieName() { $cookie = new Doubles\MockedCookie('MySESSION'); $this->context($cookie)->process($this->request(), $this->handler()); $this->assertSame('MySESSION', SessionGlobalState::$name); } public function test_SessionInitialization() { $context = $this->context($cookie); $handler = $this->handler(function () use ($context) { $context->storage()->set('foo', 'bar'); }); $context->process($this->request(), $handler); $this->assertSame(['foo' => 'bar'], SessionGlobalState::$data); $this->assertSame('DefaultSessionId', $cookie->value); } public function test_SessionResume() { SessionGlobalState::$data = ['foo' => 'bar']; $context = $this->context($cookie); $handler = $this->handler(function () use ($context) { $session = $context->storage(); $session->set('foo', $session->get('foo') . '-baz'); }); $context->process($this->request(true), $handler); $this->assertSame(['foo' => 'bar-baz'], SessionGlobalState::$data); $this->assertNull($cookie->value); } public function test_SessionRegenerateId() { SessionGlobalState::$data = ['foo' => 'bar']; $context = $this->context($cookie); $handler = $this->handler(function () use ($context) { $context->reset(); }); $context->process($this->request(true), $handler); $this->assertSame(['foo' => 'bar'], SessionGlobalState::$data); $this->assertSame('RegeneratedSessionId', $cookie->value); } public function test_SessionDestroy() { SessionGlobalState::$data = ['foo' => 'bar']; $context = $this->context($cookie); $handler = $this->handler(function () use ($context) { $context->storage()->clear(); }); $context->process($this->request(true), $handler); $this->assertSame([], SessionGlobalState::$data); $this->assertTrue($cookie->deleted); } public function test_ClearedSession_WithNewData_RegeneratesId() { SessionGlobalState::$data = ['foo' => 'bar']; $context = $this->context($cookie); $handler = $this->handler(function () use ($context) { $storage = $context->storage(); $storage->clear(); $storage->set('baz', 'qux'); }); $context->process($this->request(true), $handler); $this->assertSame('RegeneratedSessionId', SessionGlobalState::$id); $this->assertSame('RegeneratedSessionId', $cookie->value); } public function test_ProcessingWhileSessionStarted_ThrowsException() { SessionGlobalState::$status = PHP_SESSION_ACTIVE; $context = $this->context(); $this->expectException(RuntimeException::class); $context->process($this->request(true), $this->handler()); } public function test_CallingSessionWithoutContextProcessing_ThrowsException() { $context = $this->context(); $this->expectException(RuntimeException::class); $context->storage(); } private function request($cookie = false): Doubles\FakeServerRequest { return $cookie ? Doubles\FakeServerRequest::withSessionCookie(SessionGlobalState::$name, SessionGlobalState::$id) : new Doubles\FakeServerRequest(); } private function handler(?callable $process = null): Doubles\FakeRequestHandler { return new Doubles\FakeRequestHandler($process); } private function context(?Doubles\MockedCookie &$cookie = null): SessionContext\NativeSessionContext { $cookie ??= new Doubles\MockedCookie(SessionGlobalState::$name); return new SessionContext\NativeSessionContext($cookie); } }