From f7ef778f33de7ae6f422bd23b2122d41bae248e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BCrk?= Date: Sat, 14 Dec 2024 23:03:29 +0100 Subject: [PATCH] [TASK] Add regression test for issue #395 Issue #395 has been recently fixed for 4.x and 5.x with following pull-requests: * https://github.com/web-vision/deepltranslate-core/pull/397 * https://github.com/web-vision/deepltranslate-core/pull/398 Adding regression test has been omited due to issues within the `typo3/testing-framework` already. The major missing part boils down to an incomplete frontend backend user authentication setup, reported by Daniel Siepmann [1] and provided a pull-request [2]. * [1] Issue: https://github.com/TYPO3/testing-framework/pull/535 * [2] Pull-request: https://github.com/TYPO3/testing-framework/pull/536 The pull-request has been adopted by providing a test-fixture extension replacing the BackendUserHandler with a fixed version. Sadly, this required an additional temporary workaround within the functional test bootstrap, enforce loading package infor for the testing-framework extensions. That needs to be fixed within `typo3/testing-framework`, enforce loading the package info in Testbase->linkFrameworkExtensionsToInstance` when linking the framework extension - or refactor the linking all together. For ongoing work to add TYPO3 v13 support we take the workarounds to continue the work having regression test in place and do not wait until resolved in the testing-framework which needs adoptions in the TYPO3 monorepo and therefore some coordination in fix, release and upgrade. SiteBasedTestTrait related reporting for new test case are added to the baseline for now, needs to be addressed in general with a dedcated change. Used command(s): ```bash Build/Scripts/runTests.sh -t 12 -p 8.1 -s phpstanGenerateBaseline ``` Related: https://github.com/web-vision/deepltranslate-core/issues/395 Related: https://github.com/web-vision/deepltranslate-core/pull/398 Related: https://github.com/web-vision/deepltranslate-core/pull/397 --- Build/phpstan/Core12/phpstan-baseline.neon | 50 +++++++ Build/phpstan/Core12/phpstan.neon | 3 + Build/phpunit/FunctionalTestsBootstrap.php | 24 ++++ .../Classes/Middleware/BackendUserHandler.php | 62 +++++++++ .../Configuration/RequestMiddlewares.php | 19 +++ .../Configuration/Services.yaml | 8 ++ .../composer.json | 20 +++ .../ext_emconf.php | 22 +++ .../PreviewTranslationInformation.csv | 10 ++ .../PreviewTranslationInformation.typoscript | 9 ++ .../PreviewTranslationInformationTest.php | 130 ++++++++++++++++++ composer.json | 3 +- 12 files changed, 359 insertions(+), 1 deletion(-) create mode 100644 Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/Classes/Middleware/BackendUserHandler.php create mode 100644 Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/Configuration/RequestMiddlewares.php create mode 100644 Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/Configuration/Services.yaml create mode 100644 Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/composer.json create mode 100644 Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/ext_emconf.php create mode 100644 Tests/Functional/Regression/Fixtures/PreviewTranslationInformation.csv create mode 100644 Tests/Functional/Regression/Fixtures/PreviewTranslationInformation.typoscript create mode 100644 Tests/Functional/Regression/PreviewTranslationInformationTest.php diff --git a/Build/phpstan/Core12/phpstan-baseline.neon b/Build/phpstan/Core12/phpstan-baseline.neon index 5e2a265a..f10b4578 100644 --- a/Build/phpstan/Core12/phpstan-baseline.neon +++ b/Build/phpstan/Core12/phpstan-baseline.neon @@ -335,6 +335,56 @@ parameters: count: 1 path: ../../../Tests/Functional/Regression/LocalizationInlineRegressionTest.php + - + message: "#^Method WebVision\\\\Deepltranslate\\\\Core\\\\Tests\\\\Functional\\\\Regression\\\\PreviewTranslationInformationTest\\:\\:buildDefaultLanguageConfiguration\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: ../../../Tests/Functional/Regression/PreviewTranslationInformationTest.php + + - + message: "#^Method WebVision\\\\Deepltranslate\\\\Core\\\\Tests\\\\Functional\\\\Regression\\\\PreviewTranslationInformationTest\\:\\:buildErrorHandlingConfiguration\\(\\) has parameter \\$codes with no value type specified in iterable type array\\.$#" + count: 1 + path: ../../../Tests/Functional/Regression/PreviewTranslationInformationTest.php + + - + message: "#^Method WebVision\\\\Deepltranslate\\\\Core\\\\Tests\\\\Functional\\\\Regression\\\\PreviewTranslationInformationTest\\:\\:buildErrorHandlingConfiguration\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: ../../../Tests/Functional/Regression/PreviewTranslationInformationTest.php + + - + message: "#^Method WebVision\\\\Deepltranslate\\\\Core\\\\Tests\\\\Functional\\\\Regression\\\\PreviewTranslationInformationTest\\:\\:buildLanguageConfiguration\\(\\) has parameter \\$fallbackIdentifiers with no value type specified in iterable type array\\.$#" + count: 1 + path: ../../../Tests/Functional/Regression/PreviewTranslationInformationTest.php + + - + message: "#^Method WebVision\\\\Deepltranslate\\\\Core\\\\Tests\\\\Functional\\\\Regression\\\\PreviewTranslationInformationTest\\:\\:buildLanguageConfiguration\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: ../../../Tests/Functional/Regression/PreviewTranslationInformationTest.php + + - + message: "#^Method WebVision\\\\Deepltranslate\\\\Core\\\\Tests\\\\Functional\\\\Regression\\\\PreviewTranslationInformationTest\\:\\:failIfArrayIsNotEmpty\\(\\) has parameter \\$items with no value type specified in iterable type array\\.$#" + count: 1 + path: ../../../Tests/Functional/Regression/PreviewTranslationInformationTest.php + + - + message: "#^Method WebVision\\\\Deepltranslate\\\\Core\\\\Tests\\\\Functional\\\\Regression\\\\PreviewTranslationInformationTest\\:\\:mergeSiteConfiguration\\(\\) has parameter \\$overrides with no value type specified in iterable type array\\.$#" + count: 1 + path: ../../../Tests/Functional/Regression/PreviewTranslationInformationTest.php + + - + message: "#^Method WebVision\\\\Deepltranslate\\\\Core\\\\Tests\\\\Functional\\\\Regression\\\\PreviewTranslationInformationTest\\:\\:writeSiteConfiguration\\(\\) has parameter \\$errorHandling with no value type specified in iterable type array\\.$#" + count: 1 + path: ../../../Tests/Functional/Regression/PreviewTranslationInformationTest.php + + - + message: "#^Method WebVision\\\\Deepltranslate\\\\Core\\\\Tests\\\\Functional\\\\Regression\\\\PreviewTranslationInformationTest\\:\\:writeSiteConfiguration\\(\\) has parameter \\$languages with no value type specified in iterable type array\\.$#" + count: 1 + path: ../../../Tests/Functional/Regression/PreviewTranslationInformationTest.php + + - + message: "#^Method WebVision\\\\Deepltranslate\\\\Core\\\\Tests\\\\Functional\\\\Regression\\\\PreviewTranslationInformationTest\\:\\:writeSiteConfiguration\\(\\) has parameter \\$site with no value type specified in iterable type array\\.$#" + count: 1 + path: ../../../Tests/Functional/Regression/PreviewTranslationInformationTest.php + - message: "#^Cannot access property \\$code on DeepL\\\\Language\\|null\\.$#" count: 7 diff --git a/Build/phpstan/Core12/phpstan.neon b/Build/phpstan/Core12/phpstan.neon index 85b91ad8..f85bac56 100644 --- a/Build/phpstan/Core12/phpstan.neon +++ b/Build/phpstan/Core12/phpstan.neon @@ -16,7 +16,10 @@ parameters: - ../../../.Build/* - ../../../Tests/Functional/Updates/Fixtures/Extension/test_extension/ext_emconf.php - ../../../Tests/Functional/Fixtures/Extensions/test_services_override/ext_emconf.php + - ../../../Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/ext_emconf.php typo3: contextApiGetAspectMapping: 'frontend.preview': TYPO3\CMS\Frontend\Aspect\PreviewAspect + requestGetAttributeMapping: + 'typo3.testing.context': TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext diff --git a/Build/phpunit/FunctionalTestsBootstrap.php b/Build/phpunit/FunctionalTestsBootstrap.php index a95bc520..5ee93da5 100644 --- a/Build/phpunit/FunctionalTestsBootstrap.php +++ b/Build/phpunit/FunctionalTestsBootstrap.php @@ -23,6 +23,30 @@ * before instantiating the test suites. */ (static function () { + /** + * @todo Fix testing-framework extension package information loading within the framework and remove workaround + * here after upgrade to testing-framework release containing the fix. + */ + $frameworkExtension = [ + 'Resources/Core/Functional/Extensions/json_response', + 'Resources/Core/Functional/Extensions/private_container', + ]; + $composerPackageManager = new \TYPO3\TestingFramework\Composer\ComposerPackageManager(); + $testingFrameworkPath = $composerPackageManager->getPackageInfo('typo3/testing-framework')->getRealPath(); + foreach ($frameworkExtension as $frameworkExtensionPath) { + $packageInfo = $composerPackageManager->getPackageInfoWithFallback(rtrim($testingFrameworkPath, '/') . '/' . $frameworkExtensionPath); + if ($packageInfo === null) { + throw new \RuntimeException( + sprintf( + 'Could not preload "typo3/testing-framework" extension "%s".', + basename($frameworkExtensionPath), + ), + 1734217315, + ); + } + } + + // Original typo3/testing-framework bootstrap $testbase = new \TYPO3\TestingFramework\Core\Testbase(); $testbase->defineOriginalRootPath(); $testbase->createDirectory(ORIGINAL_ROOT . 'typo3temp/var/tests'); diff --git a/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/Classes/Middleware/BackendUserHandler.php b/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/Classes/Middleware/BackendUserHandler.php new file mode 100644 index 00000000..1cc85a99 --- /dev/null +++ b/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/Classes/Middleware/BackendUserHandler.php @@ -0,0 +1,62 @@ +getAttribute('typo3.testing.context'); + $backendUserId = $internalRequestContext->getBackendUserId(); + $workspaceId = $internalRequestContext->getWorkspaceId() ?? 0; + + if ((int)$backendUserId === 0) { + // Skip if $backendUserId is invalid, typically null or 0 + return $handler->handle($request); + } + + $row = GeneralUtility::makeInstance(ConnectionPool::class) + ->getConnectionForTable('be_users') + ->select(['*'], 'be_users', ['uid' => $backendUserId]) + ->fetchAssociative(); + if ($row !== false) { + // Init backend user if found in database + $backendUser = GeneralUtility::makeInstance(FrontendBackendUserAuthentication::class); + $backendUser->user = $row; + $backendUser->uc = isset($row['uc']) ? unserialize($row['uc']) : []; + $backendUser->initializeUserSessionManager(); + $backendUser->setTemporaryWorkspace($workspaceId); + $GLOBALS['BE_USER'] = $backendUser; + $this->setBackendUserAspect(GeneralUtility::makeInstance(Context::class), $backendUser); + } + return $handler->handle($request); + } + + /** + * Register the backend user as aspect + */ + protected function setBackendUserAspect(Context $context, BackendUserAuthentication $user): void + { + $context->setAspect('backend.user', GeneralUtility::makeInstance(UserAspect::class, $user)); + $context->setAspect('workspace', GeneralUtility::makeInstance(WorkspaceAspect::class, $user->workspace)); + } +} diff --git a/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/Configuration/RequestMiddlewares.php b/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/Configuration/RequestMiddlewares.php new file mode 100644 index 00000000..7d023100 --- /dev/null +++ b/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/Configuration/RequestMiddlewares.php @@ -0,0 +1,19 @@ + [ + 'typo3/json-response/backend-user-authentication' => [ + /** + * Replace {@see \TYPO3\JsonResponse\Middleware\BackendUserHandler} as target here to incorporate + * `typo3/testing-framework` pull-request https://github.com/TYPO3/testing-framework/pull/536 as + * a workaround until resolved within testing-framework. + * + * @todo Remove test-fixture extension completely when fixed within typo3/testing-framework. Also requires + * temporary workaround in {@see Build/phpunit/FunctionalTestsBootstrap.php} to force framework + * extension loading to have have package information available - otherwise dependency ordering would + * not work. Needs to be resolved in the testing-framework. + */ + 'target' => \WebVision\TestingFrameworkBackendUserHandlerReplacement\Middleware\BackendUserHandler::class, + ], + ], +]; diff --git a/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/Configuration/Services.yaml b/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/Configuration/Services.yaml new file mode 100644 index 00000000..f0ea4711 --- /dev/null +++ b/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/Configuration/Services.yaml @@ -0,0 +1,8 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + WebVision\TestingFrameworkBackendUserHandlerReplacement\: + resource: '../Classes/*' diff --git a/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/composer.json b/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/composer.json new file mode 100644 index 00000000..9c7bcd07 --- /dev/null +++ b/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/composer.json @@ -0,0 +1,20 @@ +{ + "name": "web-vision/testing-framework-backenduserhandler-replacement", + "type": "typo3-cms-extension", + "description": "Change service registrations for testing purposes.", + "license": ["GPL-2.0-or-later"], + "extra": { + "typo3/cms": { + "extension-key": "testing_framework_backenduserhandler_replacement" + } + }, + "require": { + "typo3/cms-core": "12.*.*@dev || 13.*.*@dev", + "typo3/testing-json-response": "*" + }, + "autoload": { + "psr-4": { + "WebVision\\TestingFrameworkBackendUserHandlerReplacement\\": "Classes" + } + } +} diff --git a/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/ext_emconf.php b/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/ext_emconf.php new file mode 100644 index 00000000..73ccd10c --- /dev/null +++ b/Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/ext_emconf.php @@ -0,0 +1,22 @@ + 'TF BackendUserHandler replacement', + 'description' => 'TF BackendUserHandler replacement', + 'category' => 'example', + 'version' => '1.0.0', + 'state' => 'beta', + 'createDirs' => '', + 'clearCacheOnLoad' => 0, + 'author' => 'Stefan Bürk', + 'author_email' => 'stefan@buerk.tech', + 'author_company' => '', + 'constraints' => [ + 'depends' => [ + 'typo3' => '12.4.0-13.4.99', + 'json_response' => '*', + ], + 'conflicts' => [], + 'suggests' => [], + ], +]; diff --git a/Tests/Functional/Regression/Fixtures/PreviewTranslationInformation.csv b/Tests/Functional/Regression/Fixtures/PreviewTranslationInformation.csv new file mode 100644 index 00000000..cdc73348 --- /dev/null +++ b/Tests/Functional/Regression/Fixtures/PreviewTranslationInformation.csv @@ -0,0 +1,10 @@ +pages +,"uid","pid",doktype,"hidden","title",subtitle,"sys_language_uid","l10n_parent","slug","tx_wvdeepltranslate_content_not_checked","tx_wvdeepltranslate_translated_time" +,1,0,1,0,"Deepl-Functional-Test","",0,0,"/",0,0 +,2,0,1,0,"Artikel","",1,2,"//",0,0 +,3,1,1,0,"Articles","",0,0,"/articles/",0,0 +,4,1,1,1,"Artikel","",1,3,"/artikel/",1,1734104657 +"be_users" +,"uid","pid","tstamp","username","password","admin","disable","starttime","endtime","options","crdate","workspace_perms","deleted","TSconfig","lastlogin","workspace_id","db_mountpoints" +# The password is "password" +,1,0,1366642540,"admin","$1$tCrlLajZ$C0sikFQQ3SWaFAZ1Me0Z/1",1,0,0,0,0,1366642540,1,0,,1371033743,0,1 diff --git a/Tests/Functional/Regression/Fixtures/PreviewTranslationInformation.typoscript b/Tests/Functional/Regression/Fixtures/PreviewTranslationInformation.typoscript new file mode 100644 index 00000000..e184cfa0 --- /dev/null +++ b/Tests/Functional/Regression/Fixtures/PreviewTranslationInformation.typoscript @@ -0,0 +1,9 @@ +page = PAGE +page.100 = CONTENT +page.100 { + table = tt_content + select { + orderBy = sorting + where = {#colPos}=0 + } +} diff --git a/Tests/Functional/Regression/PreviewTranslationInformationTest.php b/Tests/Functional/Regression/PreviewTranslationInformationTest.php new file mode 100644 index 00000000..ca58e894 --- /dev/null +++ b/Tests/Functional/Regression/PreviewTranslationInformationTest.php @@ -0,0 +1,130 @@ + [ + 'id' => 0, + 'title' => 'English', + 'locale' => 'en_US.UTF-8', + 'iso' => 'en', + 'hrefLang' => 'en-US', + 'direction' => '', + 'custom' => [ + 'deeplTargetLanguage' => '', + 'deeplAllowedAutoTranslate' => false, + 'deeplAllowedReTranslate' => false, + ], + ], + 'DE' => [ + 'id' => 1, + 'title' => 'Deutsch', + 'locale' => 'de_DE', + 'iso' => 'de', + 'hrefLang' => 'de-DE', + 'direction' => '', + 'custom' => [ + 'deeplTargetLanguage' => 'DE', + 'deeplAllowedAutoTranslate' => true, + 'deeplAllowedReTranslate' => true, + ], + ], + ]; + + protected array $configurationToUseInTestInstance = [ + 'EXTENSIONS' => [ + 'wv_deepltranslate' => [ + 'apiKey' => 'mock_server', + ], + ], + ]; + + protected array $pathsToProvideInTestInstance = [ + 'typo3conf/ext/deepltranslate_core/Tests/Functional/Regression/Fixtures/Files' => 'fileadmin', + ]; + + protected function setUp(): void + { + $this->coreExtensionsToLoad[] = 'typo3/cms-fluid-styled-content'; + $this->testExtensionsToLoad[] = __DIR__ . '/../Fixtures/Extensions/testing_framework_backenduserhandler_replacement'; + parent::setUp(); + $this->importCSVDataSet(__DIR__ . '/Fixtures/PreviewTranslationInformation.csv'); + $this->writeSiteConfiguration( + 'acme', + $this->buildSiteConfiguration(1, 'https://acme.com/', 'Home', [ + 'deeplAllowedAutoTranslate' => true, + 'deeplAllowedReTranslate' => true, + ]), + [ + $this->buildDefaultLanguageConfiguration('EN', 'https://acme.com/'), + $this->buildLanguageConfiguration('DE', 'https://acme.com/de/', ['EN'], 'strict'), + ] + ); + $this->setUpFrontendRootPage( + 1, + [ + 'constants' => [ + 'EXT:fluid_styled_content/Configuration/TypoScript/constants.typoscript', + 'EXT:fluid_styled_content/Configuration/TypoScript/Styling/constants.typoscript', + ], + 'setup' => [ + 'EXT:fluid_styled_content/Configuration/TypoScript/setup.typoscript', + 'EXT:fluid_styled_content/Configuration/TypoScript/Styling/setup.typoscript', + 'EXT:deepltranslate_core/Tests/Functional/Regression/Fixtures/PreviewTranslationInformation.typoscript', + ], + ], + [ + 'title' => 'ACME Root', + ] + ); + $this->setUpBackendUser(1); + $GLOBALS['LANG'] = GeneralUtility::makeInstance(LanguageServiceFactory::class) + ->createFromUserPreferences($GLOBALS['BE_USER']); + } + + /** + * @test + */ + public function previewTranslationInformationIsRenderedForTranslatedPage(): void + { + $styles = []; + $styles[] = 'position: fixed'; + $styles[] = 'top: 65px'; + $styles[] = 'right: 15px'; + $styles[] = 'padding: 8px 18px'; + $styles[] = 'background: #006494'; + $styles[] = 'border: 1px solid #006494'; + $styles[] = 'font-family: sans-serif'; + $styles[] = 'font-size: 14px'; + $styles[] = 'font-weight: bold'; + $styles[] = 'color: #fff'; + $styles[] = 'z-index: 20000'; + $styles[] = 'user-select: none'; + $styles[] = 'pointer-events: none'; + $styles[] = 'text-align: center'; + $styles[] = 'border-radius: 2px'; + $expectedContent = '
' . htmlspecialchars('Translated with DeepL') . '
'; + + $requestContext = (new InternalRequestContext())->withBackendUserId(1); + $request = new InternalRequest('https://acme.com/de/artikel/'); + $response = $this->executeFrontendSubRequest($request, $requestContext); + static::assertSame(200, $response->getStatusCode()); + + $content = (string)$response->getBody(); + static::assertNotEmpty($content); + static::assertStringContainsString($expectedContent, $content, 'preview translation label is rendered in frontend preview'); + } +} diff --git a/composer.json b/composer.json index 55ab660c..7d4f1536 100644 --- a/composer.json +++ b/composer.json @@ -125,7 +125,8 @@ }, "autoload-dev": { "psr-4": { - "WebVision\\Deepltranslate\\Core\\Tests\\": "Tests" + "WebVision\\Deepltranslate\\Core\\Tests\\": "Tests", + "WebVision\\TestingFrameworkBackendUserHandlerReplacement\\": "Tests/Functional/Fixtures/Extensions/testing_framework_backenduserhandler_replacement/Classes" } }, "scripts": {