From f9381041121ecaefabe744efa9b3014d2446277b Mon Sep 17 00:00:00 2001 From: Konrad Michalik Date: Mon, 27 Jul 2026 20:34:51 +0200 Subject: [PATCH 1/3] test: integrate ttt for PHPUnit test sandboxing Install konradmichalik/ttt and register its PHPUnit extension in the unit config. Replace hand-rolled $GLOBALS['TYPO3_CONF_VARS'] setUp/tearDown juggling with declarative #[WithTypo3ConfVars] attributes, giving a guaranteed restore regardless of test outcome and fixing several leaks that had no cleanup at all. --- .../DetectorConfigurationBuilderTest.php | 14 ++-- Tests/Unit/ConfigurationTest.php | 18 ++--- Tests/Unit/Detector/AbstractDetectorTest.php | 5 +- .../Detector/LongTimeNoSeeDetectorTest.php | 11 +-- Tests/Unit/Detector/NewIpDetectorTest.php | 15 ++-- .../Notification/EmailNotificationTest.php | 10 +-- Tests/Unit/Security/LoginNotificationTest.php | 26 +++---- Tests/Unit/Utility/DeviceInfoParserTest.php | 5 +- composer.json | 1 + composer.lock | 69 ++++++++++++++++++- phpunit.xml | 3 + 11 files changed, 107 insertions(+), 70 deletions(-) diff --git a/Tests/Unit/Configuration/DetectorConfigurationBuilderTest.php b/Tests/Unit/Configuration/DetectorConfigurationBuilderTest.php index af1cc3e..7add267 100644 --- a/Tests/Unit/Configuration/DetectorConfigurationBuilderTest.php +++ b/Tests/Unit/Configuration/DetectorConfigurationBuilderTest.php @@ -14,6 +14,7 @@ namespace MoveElevator\Typo3LoginWarning\Tests\Unit\Configuration; use Exception; +use KonradMichalik\Ttt\Attribute\WithTypo3ConfVars; use MoveElevator\Typo3LoginWarning\Configuration; use MoveElevator\Typo3LoginWarning\Configuration\DetectorConfigurationBuilder; use MoveElevator\Typo3LoginWarning\Detector\{LongTimeNoSeeDetector, NewIpDetector, OutOfOfficeDetector}; @@ -29,6 +30,7 @@ * @author Konrad Michalik * @license GPL-2.0-or-later */ +#[WithTypo3ConfVars(['EXTENSIONS' => [Configuration::EXT_KEY => []]])] final class DetectorConfigurationBuilderTest extends TestCase { private ExtensionConfiguration&MockObject $extensionConfiguration; @@ -44,12 +46,6 @@ protected function setUp(): void $this->extensionConfiguration = $this->createMock(ExtensionConfiguration::class); $this->subject = new DetectorConfigurationBuilder($this->extensionConfiguration); - $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][Configuration::EXT_KEY] = []; - } - - protected function tearDown(): void - { - unset($GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][Configuration::EXT_KEY]); } public function testIsActiveReturnsTrueWhenDetectorIsActive(): void @@ -189,6 +185,7 @@ public function testBuildLongTimeNoSeeConfigWithCustomValues(): void ], $result); } + #[WithTypo3ConfVars(['SYS' => ['phpTimeZone' => 'Europe/Berlin']])] public function testBuildOutOfOfficeConfigWithDefaults(): void { $this->extensionConfiguration @@ -196,8 +193,6 @@ public function testBuildOutOfOfficeConfigWithDefaults(): void ->with(Configuration::EXT_KEY) ->willReturn(['outOfOffice' => ['active' => true]]); - $GLOBALS['TYPO3_CONF_VARS']['SYS']['phpTimeZone'] = 'Europe/Berlin'; - $result = $this->subject->build(OutOfOfficeDetector::class); self::assertSame('Europe/Berlin', $result['timezone']); @@ -256,6 +251,7 @@ public function testBuildOutOfOfficeConfigWithBlockedPeriods(): void ], $result['blockedPeriods']); } + #[WithTypo3ConfVars(['BE' => ['warning_email_addr' => 'admin@example.com']])] public function testBuildNotificationConfigWithDefaults(): void { $this->extensionConfiguration @@ -263,8 +259,6 @@ public function testBuildNotificationConfigWithDefaults(): void ->with(Configuration::EXT_KEY) ->willReturn([]); - $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'] = 'admin@example.com'; - $result = $this->subject->buildNotificationConfig(); self::assertSame('admin@example.com', $result['recipient']); diff --git a/Tests/Unit/ConfigurationTest.php b/Tests/Unit/ConfigurationTest.php index 37cb989..1731b09 100644 --- a/Tests/Unit/ConfigurationTest.php +++ b/Tests/Unit/ConfigurationTest.php @@ -13,6 +13,7 @@ namespace MoveElevator\Typo3LoginWarning\Tests\Unit; +use KonradMichalik\Ttt\Attribute\WithTypo3ConfVars; use MoveElevator\Typo3LoginWarning\Configuration; use PHPUnit\Framework\TestCase; @@ -22,15 +23,9 @@ * @author Konrad Michalik * @license GPL-2.0-or-later */ +#[WithTypo3ConfVars([])] final class ConfigurationTest extends TestCase { - protected function tearDown(): void - { - // Clean up global state - unset($GLOBALS['TYPO3_CONF_VARS']['MAIL']['templateRootPaths'][500]); - unset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][Configuration::EXT_KEY]); - } - public function testExtKeyConstant(): void { self::assertSame('typo3_login_warning', Configuration::EXT_KEY); @@ -58,9 +53,9 @@ public function testRegisterMailTemplateAddsTemplateRootPath(): void ); } + #[WithTypo3ConfVars(['SYS' => ['encryptionKey' => 'test-encryption-key-12345']])] public function testRegisterHmacKeyUsesEncryptionKeyWhenNotSet(): void { - $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = 'test-encryption-key-12345'; unset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][Configuration::EXT_KEY]['hmacKey']); Configuration::registerHmacKey(); @@ -71,11 +66,12 @@ public function testRegisterHmacKeyUsesEncryptionKeyWhenNotSet(): void ); } + #[WithTypo3ConfVars([ + 'SYS' => ['encryptionKey' => 'test-encryption-key-12345'], + 'EXTCONF' => [Configuration::EXT_KEY => ['hmacKey' => 'existing-hmac-key']], + ])] public function testRegisterHmacKeyDoesNotOverwriteExistingKey(): void { - $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][Configuration::EXT_KEY]['hmacKey'] = 'existing-hmac-key'; - $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = 'test-encryption-key-12345'; - Configuration::registerHmacKey(); self::assertSame( diff --git a/Tests/Unit/Detector/AbstractDetectorTest.php b/Tests/Unit/Detector/AbstractDetectorTest.php index c690a46..3aaa0d1 100644 --- a/Tests/Unit/Detector/AbstractDetectorTest.php +++ b/Tests/Unit/Detector/AbstractDetectorTest.php @@ -13,6 +13,7 @@ namespace MoveElevator\Typo3LoginWarning\Tests\Unit\Detector; +use KonradMichalik\Ttt\Attribute\WithTypo3ConfVars; use MoveElevator\Typo3LoginWarning\Detector\AbstractDetector; use PHPUnit\Framework\TestCase; @@ -52,17 +53,17 @@ public function testShouldDetectForUserReturnsFalseForNonAdminWhenAffectedUsersI self::assertFalse($this->subject->exposeShouldDetectForUser($userArray, ['affectedUsers' => 'admins'])); } + #[WithTypo3ConfVars(['SYS' => ['systemMaintainers' => [1, 2]]])] public function testShouldDetectForUserReturnsTrueForSystemMaintainerWhenAffectedUsersIsMaintainers(): void { - $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers'] = [1, 2]; $userArray = $this->createUserArray(uid: 1); self::assertTrue($this->subject->exposeShouldDetectForUser($userArray, ['affectedUsers' => 'maintainers'])); } + #[WithTypo3ConfVars(['SYS' => ['systemMaintainers' => [2, 3]]])] public function testShouldDetectForUserReturnsFalseForNonSystemMaintainerWhenAffectedUsersIsMaintainers(): void { - $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers'] = [2, 3]; $userArray = $this->createUserArray(uid: 1); self::assertFalse($this->subject->exposeShouldDetectForUser($userArray, ['affectedUsers' => 'maintainers'])); diff --git a/Tests/Unit/Detector/LongTimeNoSeeDetectorTest.php b/Tests/Unit/Detector/LongTimeNoSeeDetectorTest.php index 37fb08e..4466126 100644 --- a/Tests/Unit/Detector/LongTimeNoSeeDetectorTest.php +++ b/Tests/Unit/Detector/LongTimeNoSeeDetectorTest.php @@ -14,6 +14,7 @@ namespace MoveElevator\Typo3LoginWarning\Tests\Unit\Detector; use DateTime; +use KonradMichalik\Ttt\Attribute\WithTypo3ConfVars; use MoveElevator\Typo3LoginWarning\Configuration; use MoveElevator\Typo3LoginWarning\Detector\{DetectorInterface, LongTimeNoSeeDetector}; use PHPUnit\Framework\TestCase; @@ -384,10 +385,9 @@ public function testShouldDetectForUserReturnsTrueForAdmin(): void self::assertTrue($result); } + #[WithTypo3ConfVars(['SYS' => ['systemMaintainers' => [2, 3]]])] public function testShouldDetectForUserReturnsFalseForNonMaintainer(): void { - $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers'] = [2, 3]; - $user = $this->createMockUser(['uid' => 123]); $configuration = ['affectedUsers' => 'maintainers']; @@ -396,14 +396,11 @@ public function testShouldDetectForUserReturnsFalseForNonMaintainer(): void $result = $subject->shouldDetectForUser($user, $configuration); self::assertFalse($result); - - unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers']); } + #[WithTypo3ConfVars(['SYS' => ['systemMaintainers' => [123, 456]]])] public function testShouldDetectForUserReturnsTrueForMaintainer(): void { - $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers'] = [123, 456]; - $user = $this->createMockUser(['uid' => 123]); $configuration = ['affectedUsers' => 'maintainers']; @@ -412,8 +409,6 @@ public function testShouldDetectForUserReturnsTrueForMaintainer(): void $result = $subject->shouldDetectForUser($user, $configuration); self::assertTrue($result); - - unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers']); } /** diff --git a/Tests/Unit/Detector/NewIpDetectorTest.php b/Tests/Unit/Detector/NewIpDetectorTest.php index 312adcb..32cfb00 100644 --- a/Tests/Unit/Detector/NewIpDetectorTest.php +++ b/Tests/Unit/Detector/NewIpDetectorTest.php @@ -13,6 +13,7 @@ namespace MoveElevator\Typo3LoginWarning\Tests\Unit\Detector; +use KonradMichalik\Ttt\Attribute\WithTypo3ConfVars; use MoveElevator\Typo3LoginWarning\Detector\{DetectorInterface, NewIpDetector}; use MoveElevator\Typo3LoginWarning\Domain\Repository\IpLogRepository; use MoveElevator\Typo3LoginWarning\Service\GeolocationServiceInterface; @@ -26,20 +27,18 @@ * @author Konrad Michalik * @license GPL-2.0-or-later */ +#[WithTypo3ConfVars(['SYS' => ['encryptionKey' => 'test-encryption-key-for-phpunit']])] final class NewIpDetectorTest extends TestCase { protected function setUp(): void { // Clean slate for each test - set default to avoid issues $GLOBALS['_SERVER']['REMOTE_ADDR'] = '127.0.0.1'; - // Set HMAC key for tests - $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = 'test-encryption-key-for-phpunit'; } protected function tearDown(): void { unset($GLOBALS['_SERVER']['REMOTE_ADDR']); - unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']); } public function testImplementsDetectorInterface(): void @@ -288,10 +287,9 @@ public function testShouldDetectForUserReturnsTrueForAdmin(): void self::assertTrue($result); } + #[WithTypo3ConfVars(['SYS' => ['systemMaintainers' => [2, 3]]])] public function testShouldDetectForUserReturnsFalseForNonMaintainer(): void { - $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers'] = [2, 3]; - $user = $this->createMockUser(['uid' => 123]); $configuration = ['affectedUsers' => 'maintainers']; @@ -300,14 +298,11 @@ public function testShouldDetectForUserReturnsFalseForNonMaintainer(): void $result = $subject->shouldDetectForUser($user, $configuration); self::assertFalse($result); - - unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers']); } + #[WithTypo3ConfVars(['SYS' => ['systemMaintainers' => [123, 456]]])] public function testShouldDetectForUserReturnsTrueForMaintainer(): void { - $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers'] = [123, 456]; - $user = $this->createMockUser(['uid' => 123]); $configuration = ['affectedUsers' => 'maintainers']; @@ -316,8 +311,6 @@ public function testShouldDetectForUserReturnsTrueForMaintainer(): void $result = $subject->shouldDetectForUser($user, $configuration); self::assertTrue($result); - - unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers']); } public function testDetectAddsDeviceInfoWhenEnabled(): void diff --git a/Tests/Unit/Notification/EmailNotificationTest.php b/Tests/Unit/Notification/EmailNotificationTest.php index 85796f3..34112d4 100644 --- a/Tests/Unit/Notification/EmailNotificationTest.php +++ b/Tests/Unit/Notification/EmailNotificationTest.php @@ -13,6 +13,7 @@ namespace MoveElevator\Typo3LoginWarning\Tests\Unit\Notification; +use KonradMichalik\Ttt\Attribute\WithTypo3ConfVars; use MoveElevator\Typo3LoginWarning\Notification\{EmailNotification, NotifierInterface}; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -29,6 +30,7 @@ * @author Konrad Michalik * @license GPL-2.0-or-later */ +#[WithTypo3ConfVars(['BE' => ['warning_email_addr' => '']])] final class EmailNotificationTest extends TestCase { private MailerInterface&MockObject $mailer; @@ -44,9 +46,6 @@ protected function setUp(): void $this->subject = new EmailNotification($this->mailer); $this->subject->setLogger($this->logger); - - // Initialize TYPO3_CONF_VARS to prevent warnings - $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'] = ''; } public function testImplementsNotifierInterface(): void @@ -71,8 +70,6 @@ public function testNotifyLogsInfoWhenNoRecipientConfigured(): void $user = $this->createMockBackendUser(['uid' => 123]); $configuration = []; - $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'] = ''; - $this->logger ->expects(self::once()) ->method('info') @@ -101,13 +98,12 @@ public function testNotifyUsesConfiguredRecipient(): void $this->subject->notify($user, $this->request, 'TestTrigger', $configuration); } + #[WithTypo3ConfVars(['BE' => ['warning_email_addr' => 'global@example.com']])] public function testNotifyFallsBackToGlobalConfiguration(): void { $user = $this->createMockBackendUser(['uid' => 123]); $configuration = []; - $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'] = 'global@example.com'; - $fluidEmail = $this->createMock(FluidEmail::class); $fluidEmail->expects(self::once())->method('to')->with('global@example.com')->willReturnSelf(); $fluidEmail->expects(self::once())->method('setRequest')->willReturnSelf(); diff --git a/Tests/Unit/Security/LoginNotificationTest.php b/Tests/Unit/Security/LoginNotificationTest.php index 133e84e..bb46247 100644 --- a/Tests/Unit/Security/LoginNotificationTest.php +++ b/Tests/Unit/Security/LoginNotificationTest.php @@ -13,6 +13,7 @@ namespace MoveElevator\Typo3LoginWarning\Tests\Unit\Security; +use KonradMichalik\Ttt\Attribute\WithTypo3ConfVars; use MoveElevator\Typo3LoginWarning\Configuration; use MoveElevator\Typo3LoginWarning\Configuration\DetectorConfigurationBuilder; use MoveElevator\Typo3LoginWarning\Event\ModifyLoginNotificationEvent; @@ -32,6 +33,10 @@ * @author Konrad Michalik * @license GPL-2.0-or-later */ +#[WithTypo3ConfVars([ + 'EXTCONF' => [Configuration::EXT_KEY => ['_notification' => [], '_detector' => []]], + 'EXTENSIONS' => [Configuration::EXT_KEY => []], +])] final class LoginNotificationTest extends TestCase { private LoggerInterface&MockObject $logger; @@ -62,16 +67,6 @@ protected function setUp(): void $this->eventDispatcher, ); $this->subject->setLogger($this->logger); - - $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][Configuration::EXT_KEY]['_notification'] = []; - $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][Configuration::EXT_KEY]['_detector'] = []; - $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][Configuration::EXT_KEY] = []; - } - - protected function tearDown(): void - { - unset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][Configuration::EXT_KEY]); - unset($GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][Configuration::EXT_KEY]); } public function testWarningAtLoginDoesNothingForNonBackendUsers(): void @@ -98,6 +93,11 @@ public function testWarningAtLoginDoesNothingWhenUserArrayIsNotArray(): void $this->addToAssertionCount(1); } + #[WithTypo3ConfVars(['EXTENSIONS' => [Configuration::EXT_KEY => [ + 'newIp' => ['active' => false], + 'longTimeNoSee' => ['active' => false], + 'outOfOffice' => ['active' => false], + ]]])] public function testWarningAtLoginHandlesNoActiveDetectors(): void { $user = $this->createMock(BackendUserAuthentication::class); @@ -105,12 +105,6 @@ public function testWarningAtLoginHandlesNoActiveDetectors(): void $request = $this->createMock(ServerRequestInterface::class); $event = new AfterUserLoggedInEvent($user, $request); - $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][Configuration::EXT_KEY] = [ - 'newIp' => ['active' => false], - 'longTimeNoSee' => ['active' => false], - 'outOfOffice' => ['active' => false], - ]; - ($this->subject)($event); // Should complete without errors when no detectors are active diff --git a/Tests/Unit/Utility/DeviceInfoParserTest.php b/Tests/Unit/Utility/DeviceInfoParserTest.php index d8af44b..463ac11 100644 --- a/Tests/Unit/Utility/DeviceInfoParserTest.php +++ b/Tests/Unit/Utility/DeviceInfoParserTest.php @@ -13,6 +13,7 @@ namespace MoveElevator\Typo3LoginWarning\Tests\Unit\Utility; +use KonradMichalik\Ttt\Attribute\WithTypo3ConfVars; use MoveElevator\Typo3LoginWarning\Utility\DeviceInfoParser; use PHPUnit\Framework\Attributes\{DataProvider, Test}; use PHPUnit\Framework\TestCase; @@ -258,11 +259,9 @@ public function parseOperatingSystemHandlesIosVersionFormat(): void } #[Test] + #[WithTypo3ConfVars(['SYS' => ['ddmmyy' => 'Y-m-d', 'hhmm' => 'H:i']])] public function parseFromRequestIncludesFormattedDate(): void { - $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] = 'Y-m-d'; - $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'] = 'H:i'; - $userAgent = 'Mozilla/5.0 (Test) AppleWebKit/537.36'; $request = $this->createMock(ServerRequestInterface::class); $request->method('getHeaderLine')->with('User-Agent')->willReturn($userAgent); diff --git a/composer.json b/composer.json index d51dbda..1a996bf 100644 --- a/composer.json +++ b/composer.json @@ -30,6 +30,7 @@ }, "require-dev": { "eliashaeussler/version-bumper": "^2.4 || ^3.0 || ^4.0", + "konradmichalik/ttt": "^0.2.0", "mobiledetect/mobiledetectlib": "^4.11.0", "phpunit/phpcov": "^9.0 || ^10.0 || ^11.0 || ^13.0", "phpunit/phpunit": "^10.2 || ^11.0 || ^12.0 || ^13.0", diff --git a/composer.lock b/composer.lock index f047912..ca2b8b0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "964cb9447ce57bb9cb8339db93f672ee", + "content-hash": "b815856c93e8a402647869bed4307c3e", "packages": [ { "name": "bacon/bacon-qr-code", @@ -5568,6 +5568,71 @@ }, "time": "2026-06-04T05:37:13+00:00" }, + { + "name": "konradmichalik/ttt", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/konradmichalik/ttt.git", + "reference": "7924d932009d8a20b9b4e12e67bf4baf28dd0057" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/konradmichalik/ttt/zipball/7924d932009d8a20b9b4e12e67bf4baf28dd0057", + "reference": "7924d932009d8a20b9b4e12e67bf4baf28dd0057", + "shasum": "" + }, + "require": { + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", + "phpunit/phpunit": "^10.5 || ^11.0 || ^12.0 || ^13.0" + }, + "require-dev": { + "armin/editorconfig-cli": "^2.0", + "ergebnis/composer-normalize": "^2.44", + "konradmichalik/php-cs-fixer-preset": "^0.2.0", + "konradmichalik/php-doc-block-header-fixer": "^0.3.4", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "rector/rector": "^2.2", + "typo3/cms-core": "^13.4 || ^14.0" + }, + "suggest": { + "typo3/cms-core": "Required for TYPO3-specific attributes like InApplicationContext and WithEnvironment (^13.4 || ^14.0)" + }, + "type": "library", + "autoload": { + "psr-4": { + "KonradMichalik\\Ttt\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "authors": [ + { + "name": "Konrad Michalik", + "email": "hej@konradmichalik.dev", + "role": "Maintainer" + } + ], + "description": "ttt - TYPO3 Testing Terrarium. Declarative test sandboxing via PHP attributes: TYPO3_CONF_VARS, application context, environment and more - applied before the test, guaranteed to be restored afterwards.", + "keywords": [ + "Toolbox", + "attributes", + "php", + "phpunit", + "sandbox", + "testing", + "ttt", + "typo3" + ], + "support": { + "issues": "https://github.com/konradmichalik/ttt/issues", + "source": "https://github.com/konradmichalik/ttt/tree/0.2.0" + }, + "time": "2026-07-27T11:34:34+00:00" + }, { "name": "mobiledetect/mobiledetectlib", "version": "4.11.0", @@ -9800,5 +9865,5 @@ "platform-overrides": { "php": "8.2" }, - "plugin-api-version": "2.9.0" + "plugin-api-version": "2.6.0" } diff --git a/phpunit.xml b/phpunit.xml index 82776b6..8c22281 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -7,6 +7,9 @@ bootstrap="vendor/autoload.php" colors="true" > + + + From d802d6e6d6e0ffb3599aba554160eb04d10569ce Mon Sep 17 00:00:00 2001 From: Konrad Michalik Date: Mon, 27 Jul 2026 20:49:20 +0200 Subject: [PATCH 2/3] test: mark test encryption key literals as gitleaks-allowed false positives --- Tests/Unit/ConfigurationTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/Unit/ConfigurationTest.php b/Tests/Unit/ConfigurationTest.php index 1731b09..2a4d26f 100644 --- a/Tests/Unit/ConfigurationTest.php +++ b/Tests/Unit/ConfigurationTest.php @@ -53,7 +53,7 @@ public function testRegisterMailTemplateAddsTemplateRootPath(): void ); } - #[WithTypo3ConfVars(['SYS' => ['encryptionKey' => 'test-encryption-key-12345']])] + #[WithTypo3ConfVars(['SYS' => ['encryptionKey' => 'test-encryption-key-12345']])] // gitleaks:allow public function testRegisterHmacKeyUsesEncryptionKeyWhenNotSet(): void { unset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][Configuration::EXT_KEY]['hmacKey']); @@ -67,7 +67,7 @@ public function testRegisterHmacKeyUsesEncryptionKeyWhenNotSet(): void } #[WithTypo3ConfVars([ - 'SYS' => ['encryptionKey' => 'test-encryption-key-12345'], + 'SYS' => ['encryptionKey' => 'test-encryption-key-12345'], // gitleaks:allow 'EXTCONF' => [Configuration::EXT_KEY => ['hmacKey' => 'existing-hmac-key']], ])] public function testRegisterHmacKeyDoesNotOverwriteExistingKey(): void From 5b69809b70affdfc4445b239bf5e4bccec2ee2cd Mon Sep 17 00:00:00 2001 From: Konrad Michalik Date: Mon, 27 Jul 2026 21:03:50 +0200 Subject: [PATCH 3/3] chore(ci): ignore test-fixture encryption keys in gitleaks history scan --- .gitleaksignore | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .gitleaksignore diff --git a/.gitleaksignore b/.gitleaksignore new file mode 100644 index 0000000..5467af4 --- /dev/null +++ b/.gitleaksignore @@ -0,0 +1,8 @@ +# Test fixtures, not real secrets: TYPO3 SYS.encryptionKey values used only in unit tests. +# Migrating ConfigurationTest to ttt's #[WithTypo3ConfVars] turned the previous +# $GLOBALS[...]['encryptionKey'] = '...' assignment into an array-arrow literal, which trips +# gitleaks' generic-api-key rule where the bracket assignment did not. The literals are the +# obviously-fake string "test-encryption-key-12345"; the HEAD occurrences also carry an inline +# `gitleaks:allow`, these fingerprints cover the same lines in the historical integration commit. +f9381041121ecaefabe744efa9b3014d2446277b:Tests/Unit/ConfigurationTest.php:generic-api-key:56 +f9381041121ecaefabe744efa9b3014d2446277b:Tests/Unit/ConfigurationTest.php:generic-api-key:70