From b5a728e6693e96ce235e819421fc3f12f3d1832e Mon Sep 17 00:00:00 2001 From: julien Date: Mon, 16 Mar 2026 08:50:42 +0100 Subject: [PATCH] Working state --- ...MediaControllerUploadCompatibilityTest.php | 26 +++++++++++++++++++ tests/Post/PostExtensionTest.php | 15 +++++++++++ tests/Shared/ClientIpResolverTest.php | 24 ++++++++++++++++- tests/Shared/ConfigTest.php | 20 +++++++++++++- tests/Shared/FlashServiceTest.php | 21 ++++++++++++++- tests/Shared/NotFoundExceptionTest.php | 17 ++++++++++++ tests/Shared/SessionManagerEdgeCasesTest.php | 9 ++++++- 7 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 tests/Shared/NotFoundExceptionTest.php diff --git a/tests/Media/MediaControllerUploadCompatibilityTest.php b/tests/Media/MediaControllerUploadCompatibilityTest.php index 43d0349..daa9e6d 100644 --- a/tests/Media/MediaControllerUploadCompatibilityTest.php +++ b/tests/Media/MediaControllerUploadCompatibilityTest.php @@ -63,6 +63,32 @@ final class MediaControllerUploadCompatibilityTest extends ControllerTestCase ]); } + + public function testUploadPrefersFileFieldWhenBothFileAndImageArePresent(): void + { + $fileField = $this->makeValidUploadedFile(); + $imageField = $this->makeValidUploadedFile(); + + $this->sessionManager->method('getUserId')->willReturn(11); + $this->mediaService->expects($this->once()) + ->method('store') + ->with($fileField, 11) + ->willReturn('/media/preferred-file-field.webp'); + + $req = $this->makePost('/admin/media/upload')->withUploadedFiles([ + 'file' => $fileField, + 'image' => $imageField, + ]); + $res = $this->controller->upload($req, $this->makeResponse()); + + $this->assertStatus($res, 200); + $this->assertJsonContains($res, [ + 'success' => true, + 'url' => '/media/preferred-file-field.webp', + 'file' => '/media/preferred-file-field.webp', + ]); + } + public function testUploadSuccessResponseContainsBothUrlAndFileKeys(): void { $file = $this->makeValidUploadedFile(); diff --git a/tests/Post/PostExtensionTest.php b/tests/Post/PostExtensionTest.php index 15b087e..0f2a685 100644 --- a/tests/Post/PostExtensionTest.php +++ b/tests/Post/PostExtensionTest.php @@ -59,6 +59,21 @@ final class PostExtensionTest extends TestCase self::assertNull($this->call('post_thumbnail', $post)); } + + public function testPostExcerptReturnsHtmlUnchangedWhenContentIsShortEnough(): void + { + $post = new Post(4, 'Titre', '

Bonjour monde

', 'titre-4'); + + self::assertSame('Bonjour monde', $this->call('post_excerpt', $post, 50)); + } + + public function testPostInitialsFallsBackToFirstRawCharacterWhenOnlyStopWordsRemain(): void + { + $post = new Post(5, 'de la', '

Contenu

', 'slug-5'); + + self::assertSame('D', $this->call('post_initials', $post)); + } + public function testPostInitialsUseMeaningfulWordsAndFallback(): void { $post = new Post(1, 'Article de Blog', '

Contenu

', 'slug'); diff --git a/tests/Shared/ClientIpResolverTest.php b/tests/Shared/ClientIpResolverTest.php index 4706ec0..54b49a7 100644 --- a/tests/Shared/ClientIpResolverTest.php +++ b/tests/Shared/ClientIpResolverTest.php @@ -8,7 +8,6 @@ use PHPUnit\Framework\TestCase; use Slim\Psr7\Factory\ServerRequestFactory; #[\PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations] - final class ClientIpResolverTest extends TestCase { public function testResolveReturnsDefaultWhenRemoteAddrMissing(): void @@ -54,4 +53,27 @@ final class ClientIpResolverTest extends TestCase self::assertSame('127.0.0.1', $resolver->resolve($request)); } + + public function testResolveReturnsRemoteAddrWhenTrustedProxyHasNoForwardedHeader(): void + { + $request = (new ServerRequestFactory())->createServerRequest('GET', '/', [ + 'REMOTE_ADDR' => '127.0.0.1', + ]); + + $resolver = new ClientIpResolver(['127.0.0.1']); + + self::assertSame('127.0.0.1', $resolver->resolve($request)); + } + + public function testResolveTrimsWhitespaceAroundRemoteAndForwardedAddresses(): void + { + $request = (new ServerRequestFactory())->createServerRequest('GET', '/', [ + 'REMOTE_ADDR' => ' 127.0.0.1 ', + 'HTTP_X_FORWARDED_FOR' => ' 203.0.113.10 , 198.51.100.12', + ]); + + $resolver = new ClientIpResolver(['*']); + + self::assertSame('203.0.113.10', $resolver->resolve($request)); + } } diff --git a/tests/Shared/ConfigTest.php b/tests/Shared/ConfigTest.php index 189bc69..c56f140 100644 --- a/tests/Shared/ConfigTest.php +++ b/tests/Shared/ConfigTest.php @@ -7,7 +7,6 @@ use App\Shared\Config; use PHPUnit\Framework\TestCase; #[\PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations] - final class ConfigTest extends TestCase { public function testGetTwigCacheReturnsFalseInDev(): void @@ -23,6 +22,25 @@ final class ConfigTest extends TestCase self::assertStringEndsWith('/var/cache/twig', $cachePath); } + public function testGetDatabasePathReturnsExistingFilePathUnchanged(): void + { + $dbFile = dirname(__DIR__, 2).'/database/app.sqlite'; + $dbDir = dirname($dbFile); + + if (!is_dir($dbDir)) { + mkdir($dbDir, 0755, true); + } + + if (!file_exists($dbFile)) { + touch($dbFile); + } + + $path = Config::getDatabasePath(); + + self::assertSame($dbFile, $path); + self::assertFileExists($dbFile); + } + public function testGetDatabasePathCreatesDatabaseFileWhenMissing(): void { $dbFile = dirname(__DIR__, 2).'/database/app.sqlite'; diff --git a/tests/Shared/FlashServiceTest.php b/tests/Shared/FlashServiceTest.php index 921c5af..0770eea 100644 --- a/tests/Shared/FlashServiceTest.php +++ b/tests/Shared/FlashServiceTest.php @@ -7,7 +7,6 @@ use App\Shared\Http\FlashService; use PHPUnit\Framework\TestCase; #[\PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations] - final class FlashServiceTest extends TestCase { protected function setUp(): void @@ -35,6 +34,26 @@ final class FlashServiceTest extends TestCase self::assertArrayNotHasKey('count', $_SESSION['flash']); } + public function testGetCastsBooleanFalseToEmptyStringAndRemovesIt(): void + { + $_SESSION['flash']['flag'] = false; + + $flash = new FlashService(); + + self::assertSame('', $flash->get('flag')); + self::assertArrayNotHasKey('flag', $_SESSION['flash']); + } + + public function testSetOverridesPreviousMessageForSameKey(): void + { + $flash = new FlashService(); + + $flash->set('notice', 'Premier'); + $flash->set('notice', 'Second'); + + self::assertSame('Second', $flash->get('notice')); + } + public function testGetReturnsNullWhenMissing(): void { $flash = new FlashService(); diff --git a/tests/Shared/NotFoundExceptionTest.php b/tests/Shared/NotFoundExceptionTest.php new file mode 100644 index 0000000..75d7bb2 --- /dev/null +++ b/tests/Shared/NotFoundExceptionTest.php @@ -0,0 +1,17 @@ +getMessage()); + } +} diff --git a/tests/Shared/SessionManagerEdgeCasesTest.php b/tests/Shared/SessionManagerEdgeCasesTest.php index 7e7c65c..d5c0a44 100644 --- a/tests/Shared/SessionManagerEdgeCasesTest.php +++ b/tests/Shared/SessionManagerEdgeCasesTest.php @@ -7,7 +7,6 @@ use App\Shared\Http\SessionManager; use PHPUnit\Framework\TestCase; #[\PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations] - final class SessionManagerEdgeCasesTest extends TestCase { private SessionManager $manager; @@ -31,6 +30,14 @@ final class SessionManagerEdgeCasesTest extends TestCase self::assertFalse($this->manager->isAuthenticated()); } + public function testGetUserIdCastsNumericStringToInteger(): void + { + $_SESSION['user_id'] = '42'; + + self::assertSame(42, $this->manager->getUserId()); + self::assertTrue($this->manager->isAuthenticated()); + } + public function testSetUserUsesDefaultRoleUser(): void { $this->manager->setUser(12, 'julien');