Skip to content

Commit

Permalink
[TASK] Add regression test for issue #395
Browse files Browse the repository at this point in the history
Issue #395 has been recently fixed for 4.x and 5.x
with following pull-requests:

* #397
* #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: TYPO3/testing-framework#535
* [2] Pull-request: TYPO3/testing-framework#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: #395
Related: #398
Related: #397
  • Loading branch information
sbuerk committed Dec 14, 2024
1 parent 98af8ca commit f7ef778
Show file tree
Hide file tree
Showing 12 changed files with 359 additions and 1 deletion.
50 changes: 50 additions & 0 deletions Build/phpstan/Core12/phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions Build/phpstan/Core12/phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -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
24 changes: 24 additions & 0 deletions Build/phpunit/FunctionalTestsBootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace WebVision\TestingFrameworkBackendUserHandlerReplacement\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Context\UserAspect;
use TYPO3\CMS\Core\Context\WorkspaceAspect;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;

/**
* Handler for backend user
*/
class BackendUserHandler implements \TYPO3\CMS\Core\SingletonInterface, MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
/** @var InternalRequestContext $internalRequestContext */
$internalRequestContext = $request->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));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

return [
'frontend' => [
'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,
],
],
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: false

WebVision\TestingFrameworkBackendUserHandlerReplacement\:
resource: '../Classes/*'
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

$EM_CONF[$_EXTKEY] = [
'title' => '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' => [],
],
];
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
page = PAGE
page.100 = CONTENT
page.100 {
table = tt_content
select {
orderBy = sorting
where = {#colPos}=0
}
}
130 changes: 130 additions & 0 deletions Tests/Functional/Regression/PreviewTranslationInformationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php

declare(strict_types=1);

namespace WebVision\Deepltranslate\Core\Tests\Functional\Regression;

use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
use WebVision\Deepltranslate\Core\Tests\Functional\AbstractDeepLTestCase;
use WebVision\Deepltranslate\Core\Tests\Functional\Fixtures\Traits\SiteBasedTestTrait;

final class PreviewTranslationInformationTest extends AbstractDeepLTestCase
{
use SiteBasedTestTrait;

protected const LANGUAGE_PRESETS = [
'EN' => [
'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 = '<div id="deepl-preview-info" style="' . implode(';', $styles) . '">' . htmlspecialchars('Translated with DeepL') . '</div>';

$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');
}
}
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down

0 comments on commit f7ef778

Please sign in to comment.