Skip to content

Commit

Permalink
Ensure session destruction handled by OpenSession middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
cspray committed Feb 17, 2024
1 parent 7838174 commit 68ed2d6
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 6 deletions.
4 changes: 3 additions & 1 deletion src/Web/Middleware/OpenSession.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ public function handleRequest(Request $request, RequestHandler $requestHandler)

$response = $requestHandler->handleRequest($request);

$session->commit();
if ($session->isLocked()) {
$session->commit();
}

return $response;
}
Expand Down
28 changes: 23 additions & 5 deletions test/Unit/Web/Middleware/OpenSessionMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Amp\Http\Server\Session\SessionStorage;
use Amp\Sync\LocalKeyedMutex;
use Labrador\Test\Unit\Web\Stub\ResponseControllerStub;
use Labrador\Test\Unit\Web\Stub\SessionDestroyingController;
use Labrador\Web\Exception\SessionNotEnabled;
use Labrador\Web\Middleware\OpenSession;
use League\Uri\Http;
Expand Down Expand Up @@ -44,7 +45,7 @@ public function testRequestDoesNotHaveSessionThrowsException() : void {
$this->expectExceptionMessage('The ' . OpenSession::class . ' was added to a route but no session was found on the request.');

$this->subject->handleRequest(
new Request($this->client, 'GET', Http::createFromString('https://example.com')),
new Request($this->client, 'GET', Http::new('https://example.com')),
$handler
);
}
Expand All @@ -57,7 +58,7 @@ public function testRequestDoesHaveSessionOpensItBeforeRequestHandler() : void {
$this->sessionId = $generator->generate()
);

$request = new Request($this->client, 'GET', Http::createFromString('https://example.com'));
$request = new Request($this->client, 'GET', Http::new('https://example.com'));
$request->setAttribute(Session::class, $this->session);

$handler = $this->getMockBuilder(RequestHandler::class)->getMock();
Expand All @@ -79,7 +80,7 @@ public function testRequestDoesHaveSessionSavesToStorageIfControllerWritesData()
$this->sessionId = $generator->generate()
);

$request = new Request($this->client, 'GET', Http::createFromString('https://example.com'));
$request = new Request($this->client, 'GET', Http::new('https://example.com'));
$request->setAttribute(Session::class, $this->session);

self::assertEmpty($this->storage->read($this->sessionId));
Expand All @@ -104,12 +105,29 @@ public function testRequestSessionIsUnlockedAfterControllerInvoked() : void {
$this->sessionId = $generator->generate()
);

$request = new Request($this->client, 'GET', Http::createFromString('https://example.com'));
$request = new Request($this->client, 'GET', Http::new('https://example.com'));
$request->setAttribute(Session::class, $this->session);

$this->subject->handleRequest($request, new ResponseControllerStub(new Response()));

self::assertFalse($this->session->isLocked());
}

}
public function testHandleSessionBeingDestroyedDoesNotThrowError() : void {
$this->session = new Session(
new LocalKeyedMutex(),
$this->storage = new LocalSessionStorage(),
$generator = new Base64UrlSessionIdGenerator(),
$this->sessionId = $generator->generate()
);

$request = new Request($this->client, 'GET', Http::new('https://example.com'));
$request->setAttribute(Session::class, $this->session);

$response = $this->subject->handleRequest($request, new SessionDestroyingController());

self::assertFalse($this->session->isLocked());
self::assertSame('Session destroyed', $response->getBody()->read());
}

}
24 changes: 24 additions & 0 deletions test/Unit/Web/Stub/SessionDestroyingController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php declare(strict_types=1);

namespace Labrador\Test\Unit\Web\Stub;

use Amp\Http\Server\Request;
use Amp\Http\Server\Response;
use Amp\Http\Server\Session\Session;
use Labrador\Web\Controller\Controller;
use Labrador\Web\Controller\SelfDescribingController;
use PHPUnit\Framework\Assert;

class SessionDestroyingController extends SelfDescribingController {

public function handleRequest(Request $request) : Response {
$session = $request->getAttribute(Session::class);

Assert::assertInstanceOf(Session::class, $session);

$session->destroy();

return new Response(body: 'Session destroyed');
}

}

0 comments on commit 68ed2d6

Please sign in to comment.