From bf4a818e0105731c4117368a11706b645e95af1b Mon Sep 17 00:00:00 2001 From: Igor Scheller Date: Sat, 8 Apr 2023 14:14:57 +0200 Subject: [PATCH] Make session cleanup more robust and tests explicit --- src/Http/SessionHandlers/DatabaseHandler.php | 17 ++---- .../SessionHandlers/DatabaseHandlerTest.php | 59 +++++++++++-------- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/Http/SessionHandlers/DatabaseHandler.php b/src/Http/SessionHandlers/DatabaseHandler.php index 9e8f4665..277765c9 100644 --- a/src/Http/SessionHandlers/DatabaseHandler.php +++ b/src/Http/SessionHandlers/DatabaseHandler.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Engelsystem\Http\SessionHandlers; use Engelsystem\Database\Database; +use Engelsystem\Helpers\Carbon; use Illuminate\Database\Query\Builder as QueryBuilder; class DatabaseHandler extends AbstractHandler @@ -32,7 +33,7 @@ class DatabaseHandler extends AbstractHandler { $values = [ 'payload' => $data, - 'last_activity' => $this->getCurrentTimestamp(), + 'last_activity' => Carbon::now(), ]; $session = $this->getQuery() @@ -71,11 +72,11 @@ class DatabaseHandler extends AbstractHandler */ public function gc(int $max_lifetime): int|false { - $max_lifetime = config('session.lifetime') * 24 * 60 * 60; - $timestamp = $this->getCurrentTimestamp(-$max_lifetime); + $sessionDays = config('session')['lifetime']; + $deleteBefore = Carbon::now()->subDays($sessionDays); return $this->getQuery() - ->where('last_activity', '<', $timestamp) + ->where('last_activity', '<', $deleteBefore) ->delete(); } @@ -85,12 +86,4 @@ class DatabaseHandler extends AbstractHandler ->getConnection() ->table('sessions'); } - - /** - * Format the SQL timestamp - */ - protected function getCurrentTimestamp(int $diff = 0): string - { - return date('Y-m-d H:i:s', strtotime(sprintf('%+d seconds', $diff))); - } } diff --git a/tests/Unit/Http/SessionHandlers/DatabaseHandlerTest.php b/tests/Unit/Http/SessionHandlers/DatabaseHandlerTest.php index 180f01b9..13af667d 100644 --- a/tests/Unit/Http/SessionHandlers/DatabaseHandlerTest.php +++ b/tests/Unit/Http/SessionHandlers/DatabaseHandlerTest.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Engelsystem\Test\Unit\Http\SessionHandlers; use Engelsystem\Config\Config; +use Engelsystem\Helpers\Carbon; use Engelsystem\Http\SessionHandlers\DatabaseHandler; use Engelsystem\Test\Unit\HasDatabase; use Engelsystem\Test\Unit\TestCase; @@ -23,12 +24,15 @@ class DatabaseHandlerTest extends TestCase $handler = new DatabaseHandler($this->database); $this->assertEquals('', $handler->read('foo')); - $this->database->insert("INSERT INTO sessions VALUES ('foo', 'Lorem Ipsum', CURRENT_TIMESTAMP)"); - $this->assertEquals('Lorem Ipsum', $handler->read('foo')); + $this->database->getConnection() + ->table('sessions') + ->insert([ + ['id' => 'id-foo', 'payload' => 'Lorem Ipsum', 'last_activity' => Carbon::now()], + ]); + $this->assertEquals('Lorem Ipsum', $handler->read('id-foo')); } /** - * @covers \Engelsystem\Http\SessionHandlers\DatabaseHandler::getCurrentTimestamp * @covers \Engelsystem\Http\SessionHandlers\DatabaseHandler::write */ public function testWrite(): void @@ -36,12 +40,14 @@ class DatabaseHandlerTest extends TestCase $handler = new DatabaseHandler($this->database); foreach (['Lorem Ipsum', 'Dolor Sit!'] as $data) { - $this->assertTrue($handler->write('foo', $data)); + $this->assertTrue($handler->write('id-foo', $data)); - $return = $this->database->select('SELECT * FROM sessions WHERE id = :id', ['id' => 'foo']); + $return = $this->database->getConnection()->table('sessions') + ->where('id', 'id-foo') + ->get(); $this->assertCount(1, $return); - $return = array_shift($return); + $return = $return->first(); $this->assertEquals($data, $return->payload); } } @@ -51,22 +57,26 @@ class DatabaseHandlerTest extends TestCase */ public function testDestroy(): void { - $this->database->insert("INSERT INTO sessions VALUES ('foo', 'Lorem Ipsum', CURRENT_TIMESTAMP)"); - $this->database->insert("INSERT INTO sessions VALUES ('bar', 'Dolor Sit', CURRENT_TIMESTAMP)"); + $table = $this->database->getConnection()->table('sessions'); + $table + ->insert([ + ['id' => 'id-foo', 'payload' => 'Lorem Ipsum', 'last_activity' => Carbon::now()->subHours(25)], + ['id' => 'id-bar', 'payload' => 'Dolor Sit', 'last_activity' => Carbon::now()], + ]); $handler = new DatabaseHandler($this->database); - $this->assertTrue($handler->destroy('batz')); + $this->assertTrue($handler->destroy('id-baz')); - $return = $this->database->select('SELECT * FROM sessions'); + $return = $table->get(); $this->assertCount(2, $return); - $this->assertTrue($handler->destroy('bar')); + $this->assertTrue($handler->destroy('id-bar')); - $return = $this->database->select('SELECT * FROM sessions'); + $return = $table->get(); $this->assertCount(1, $return); - $return = array_shift($return); - $this->assertEquals('foo', $return->id); + $return = $return->first(); + $this->assertEquals('id-foo', $return->id); } /** @@ -74,22 +84,25 @@ class DatabaseHandlerTest extends TestCase */ public function testGc(): void { - $this->app->instance('config', new Config()); + $this->app->instance('config', new Config(['session' => ['lifetime' => 2]])); // 2 days - $this->database->insert("INSERT INTO sessions VALUES ('foo', 'Lorem Ipsum', '2000-01-01 01:00')"); - $this->database->insert("INSERT INTO sessions VALUES ('bar', 'Dolor Sit', '3000-01-01 01:00')"); - config(['session.lifetime' => 1]); // 1 day + $table = $this->database->getConnection()->table('sessions'); + $table + ->insert([ + ['id' => 'id-foo', 'payload' => 'Lorem Ipsum', 'last_activity' => Carbon::now()->subHours(48 + 1)], + ['id' => 'id-bar', 'payload' => 'Dolor Sit', 'last_activity' => Carbon::now()], + ]); $handler = new DatabaseHandler($this->database); - // Max lifetime gets overwritten by settings - $this->assertEquals(1, $handler->gc(0)); + // Max lifetime gets overwritten by settings anyway + $this->assertEquals(1, $handler->gc(42)); - $return = $this->database->select('SELECT * FROM sessions'); + $return = $table->get(); $this->assertCount(1, $return); - $return = array_shift($return); - $this->assertEquals('bar', $return->id); + $return = $return->first(); + $this->assertEquals('id-bar', $return->id); } /**