diff --git a/Classes/Caching/CacheManager.php b/Classes/Caching/CacheManager.php new file mode 100644 index 0000000..0856ed3 --- /dev/null +++ b/Classes/Caching/CacheManager.php @@ -0,0 +1,64 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +namespace Wrm\Events\Caching; + +use TYPO3\CMS\Core\Cache\CacheManager as Typo3CacheManager; +use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; + +class CacheManager +{ + /** + * @var Typo3CacheManager + */ + private $cacheManager; + + /** + * @var array + */ + private $tags = [ + 'tx_events_domain_model_date', + 'tx_events_domain_model_event', + 'tx_events_domain_model_organizer', + 'tx_events_domain_model_partner', + 'tx_events_domain_model_region', + ]; + + public function __construct( + Typo3CacheManager $cacheManager + ) { + $this->cacheManager = $cacheManager; + } + + public function addAllCacheTagsToPage(ContentObjectRenderer $cObject): void + { + $cObject->stdWrap_addPageCacheTags('', [ + 'addPageCacheTags' => implode(',', $this->tags), + ]); + } + + public function clearAllCacheTags(): void + { + $this->cacheManager->flushCachesByTags($this->tags); + } +} diff --git a/Classes/Controller/AbstractController.php b/Classes/Controller/AbstractController.php index 55e27d2..52c44dd 100644 --- a/Classes/Controller/AbstractController.php +++ b/Classes/Controller/AbstractController.php @@ -23,9 +23,34 @@ namespace Wrm\Events\Controller; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; +use Wrm\Events\Caching\CacheManager; class AbstractController extends ActionController { + /** + * @var CacheManager + */ + protected $cacheManager; + + public function injectCacheManager(CacheManager $cacheManager): void + { + $this->cacheManager = $cacheManager; + } + + /** + * Extend to add cache tag to page. + * This allows to clear pages on modifications. + */ + protected function initializeAction(): void + { + parent::initializeAction(); + + $cObject = $this->configurationManager->getContentObject(); + if ($cObject instanceof ContentObjectRenderer) { + $this->cacheManager->addAllCacheTagsToPage($cObject); + } + } + /** * Extend original to also add data from current cobject if available. */ diff --git a/Classes/Controller/DateController.php b/Classes/Controller/DateController.php index c470026..7e3d8be 100644 --- a/Classes/Controller/DateController.php +++ b/Classes/Controller/DateController.php @@ -79,6 +79,8 @@ class DateController extends AbstractController protected function initializeAction(): void { + parent::initializeAction(); + $contentObject = $this->configurationManager->getContentObject(); if ($contentObject !== null) { $this->demandFactory->setContentObjectRenderer($contentObject); diff --git a/Classes/Controller/EventController.php b/Classes/Controller/EventController.php index 6df13c3..d0a6412 100644 --- a/Classes/Controller/EventController.php +++ b/Classes/Controller/EventController.php @@ -37,6 +37,8 @@ class EventController extends AbstractController protected function initializeAction(): void { + parent::initializeAction(); + $this->dataProcessing->setConfigurationManager($this->configurationManager); } diff --git a/Classes/Service/DestinationDataImportService.php b/Classes/Service/DestinationDataImportService.php index 6b5b5a2..63549d2 100644 --- a/Classes/Service/DestinationDataImportService.php +++ b/Classes/Service/DestinationDataImportService.php @@ -10,6 +10,7 @@ use TYPO3\CMS\Extbase\Configuration\ConfigurationManager; use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; use TYPO3\CMS\Extbase\Object\ObjectManager; use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager; +use Wrm\Events\Caching\CacheManager; use Wrm\Events\Domain\Model\Event; use Wrm\Events\Domain\Model\Import; use Wrm\Events\Domain\Model\Organizer; @@ -102,6 +103,11 @@ class DestinationDataImportService */ private $slugger; + /** + * @var CacheManager + */ + private $cacheManager; + /** * ImportService constructor. * @param EventRepository $eventRepository @@ -115,6 +121,7 @@ class DestinationDataImportService * @param CategoriesAssignment $categoriesAssignment * @param LocationAssignment $locationAssignment * @param Slugger $slugger + * @param CacheManager $cacheManager */ public function __construct( EventRepository $eventRepository, @@ -128,7 +135,8 @@ class DestinationDataImportService FilesAssignment $filesAssignment, CategoriesAssignment $categoriesAssignment, LocationAssignment $locationAssignment, - Slugger $slugger + Slugger $slugger, + CacheManager $cacheManager ) { $this->eventRepository = $eventRepository; $this->organizerRepository = $organizerRepository; @@ -142,6 +150,7 @@ class DestinationDataImportService $this->categoriesAssignment = $categoriesAssignment; $this->locationAssignment = $locationAssignment; $this->slugger = $slugger; + $this->cacheManager = $cacheManager; } public function import( @@ -265,6 +274,9 @@ class DestinationDataImportService $this->slugger->update('tx_events_domain_model_date'); } + $this->logger->info('Flushing cache'); + $this->cacheManager->clearAllCacheTags(); + $this->logger->info('Finished import'); return 0; } diff --git a/Tests/Functional/Frontend/AbstractTestCase.php b/Classes/Testing/TypoScriptInstructionModifier.php similarity index 50% rename from Tests/Functional/Frontend/AbstractTestCase.php rename to Classes/Testing/TypoScriptInstructionModifier.php index dc0fb6f..198e1ca 100644 --- a/Tests/Functional/Frontend/AbstractTestCase.php +++ b/Classes/Testing/TypoScriptInstructionModifier.php @@ -21,33 +21,34 @@ declare(strict_types=1); * 02110-1301, USA. */ -namespace Wrm\Events\Tests\Functional\Frontend; +namespace Wrm\Events\Testing; +use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\TypoScript\TemplateService; -use TYPO3\CMS\Core\Utility\ArrayUtility; -use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\Hook\TypoScriptInstructionModifier; -use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\Internal\TypoScriptInstruction; -use Wrm\Events\Tests\Functional\AbstractFunctionalTestCase; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\Hook\TypoScriptInstructionModifier as Typo3TypoScriptInstructionModifier; +use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\RequestBootstrap; -abstract class AbstractTestCase extends AbstractFunctionalTestCase +/** + * Wrap original code to check whether internal request exists. + * It does not exist during import. + * + * No PR upstream as this is probably an unusual use case. + * But we call frontend, import, frontend so have a mix. + */ +class TypoScriptInstructionModifier implements SingletonInterface { - protected function setUp(): void + public function apply(array $parameters, TemplateService $service): void { - ArrayUtility::mergeRecursiveWithOverrule($this->configurationToUseInTestInstance, [ - 'SC_OPTIONS' => [ - 'Core/TypoScript/TemplateService' => [ - 'runThroughTemplatesPostProcessing' => [ - 'FunctionalTest' => TypoScriptInstructionModifier::class . '->apply', - ], - ], - ], - ]); + $request = RequestBootstrap::getInternalRequest(); + if ($request === null) { + return; + } - parent::setUp(); - } - - protected function getTypoScriptInstruction(): TypoScriptInstruction - { - return new TypoScriptInstruction(TemplateService::class); + GeneralUtility::callUserFunction( + Typo3TypoScriptInstructionModifier::class . '->apply', + $parameters, + $service + ); } } diff --git a/Documentation/Changelog/3.4.0.rst b/Documentation/Changelog/3.4.0.rst index b5e4bfe..fdd47a0 100644 --- a/Documentation/Changelog/3.4.0.rst +++ b/Documentation/Changelog/3.4.0.rst @@ -36,6 +36,11 @@ Features This was now improved. The import now will update, remove and re-sort images as well. Existing image files won't be downloaded again, only information and position are updated. +* Flushes page caches during import and edits. + Proper cache tags are now added to the pages whenever the controller is used. + That ensures that modifications during import or while editing records are flushing + corresponding pages. + Fixes ----- diff --git a/Documentation/Maintenance/TYPO3/V10.rst b/Documentation/Maintenance/TYPO3/V10.rst new file mode 100644 index 0000000..e4f8619 --- /dev/null +++ b/Documentation/Maintenance/TYPO3/V10.rst @@ -0,0 +1,11 @@ +TYPO3 V10 +========= + +Changes that should happen once we drop TYPO3 v10. + + +Remove fetching cached page stage from body from tests +------------------------------------------------------ + +We have different assertions based on TYPO3 version, due to how TYPO3 exposes the info. +We can remove the condition with its content once we drop v10. diff --git a/Tests/Functional/AbstractFunctionalTestCase.php b/Tests/Functional/AbstractFunctionalTestCase.php index 992b736..d67b785 100644 --- a/Tests/Functional/AbstractFunctionalTestCase.php +++ b/Tests/Functional/AbstractFunctionalTestCase.php @@ -24,15 +24,50 @@ declare(strict_types=1); namespace Wrm\Events\Tests\Functional; use Codappix\Typo3PhpDatasets\TestingFramework; +use DateTimeImmutable; +use GuzzleHttp\ClientInterface as GuzzleClientInterface; +use Psr\Http\Client\ClientInterface; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Component\DependencyInjection\Container; +use TYPO3\CMS\Core\Context\Context; +use TYPO3\CMS\Core\Context\DateTimeAspect; +use TYPO3\CMS\Core\Localization\LanguageServiceFactory; +use TYPO3\CMS\Core\TypoScript\TemplateService; use TYPO3\CMS\Core\Utility\ArrayUtility; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\Internal\TypoScriptInstruction; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; +use Wrm\Events\Command\ImportDestinationDataViaConfigruationCommand; +use Wrm\Events\Testing\TypoScriptInstructionModifier; +use Wrm\Events\Tests\ClientFactory; abstract class AbstractFunctionalTestCase extends FunctionalTestCase { use TestingFramework; + /** + * The folder path in file system used to store the imported images. + * + * @var string + */ + protected $fileImportPath = ''; + protected function setUp(): void { + $this->coreExtensionsToLoad = array_merge($this->coreExtensionsToLoad, [ + 'filelist', + 'fluid_styled_content', + ]); + + $this->testExtensionsToLoad = array_merge($this->testExtensionsToLoad, [ + 'typo3conf/ext/events', + ]); + + $this->pathsToProvideInTestInstance = array_merge($this->pathsToProvideInTestInstance, [ + 'typo3conf/ext/events/Tests/Functional/Frontend/Fixtures/Sites/' => 'typo3conf/sites', + ]); + ArrayUtility::mergeRecursiveWithOverrule($this->configurationToUseInTestInstance, [ 'GFX' => [ 'processor_enabled' => true, @@ -40,8 +75,122 @@ abstract class AbstractFunctionalTestCase extends FunctionalTestCase 'processor_path_lzw' => '/usr/bin/', 'processor' => 'ImageMagick', ], + 'SC_OPTIONS' => [ + 'Core/TypoScript/TemplateService' => [ + 'runThroughTemplatesPostProcessing' => [ + 'FunctionalTest' => TypoScriptInstructionModifier::class . '->apply', + ], + ], + ], ]); parent::setUp(); + + $this->setUpBackendUserFromFixture(1); + + $languageServiceFactory = $this->getContainer()->get(LanguageServiceFactory::class); + if (!$languageServiceFactory instanceof LanguageServiceFactory) { + throw new \UnexpectedValueException('Did not retrieve LanguageServiceFactory.', 1637847250); + } + $GLOBALS['LANG'] = $languageServiceFactory->create('default'); + + $fileImportPathConfiguration = 'staedte/beispielstadt/events/'; + $this->fileImportPath = $this->getInstancePath() . '/fileadmin/' . $fileImportPathConfiguration; + GeneralUtility::mkdir_deep($this->fileImportPath); + } + + protected function tearDown(): void + { + unset($GLOBALS['LANG']); + GeneralUtility::rmdir($this->fileImportPath, true); + + parent::tearDown(); + } + + protected function getTypoScriptInstruction(): TypoScriptInstruction + { + return new TypoScriptInstruction(TemplateService::class); + } + + protected function setUpConfiguration( + array $destinationDataSettings, + array $importSettings = [] + ): void { + $this->setUpFrontendRootPage(1, [], [ + 'config' => implode(PHP_EOL, [ + 'module.tx_events_pi1.settings.destinationData {', + implode(PHP_EOL, $destinationDataSettings), + '}', + 'module.tx_events_import.settings {', + implode(PHP_EOL, $importSettings), + '}', + ]), + ]); + } + + protected function &setUpResponses(array $responses): array + { + $requests = []; + + $client = ClientFactory::createClientWithHistory($responses, $requests); + $container = $this->getContainer(); + if ($container instanceof Container) { + $container->set(ClientInterface::class, $client); + // For TYPO3 10 support + $container->set(GuzzleClientInterface::class, $client); + } + + return $requests; + } + + protected function executeCommand( + array $argumentsAndOptions = ['configurationUid' => '1'], + string $command = ImportDestinationDataViaConfigruationCommand::class + ): CommandTester { + $subject = $this->getContainer()->get($command); + self::assertInstanceOf(Command::class, $subject); + + $tester = new CommandTester($subject); + $tester->execute( + $argumentsAndOptions, + [ + 'capture_stderr_separately' => true, + ] + ); + + return $tester; + } + + protected function setUpFrontendRendering(): void + { + $this->setUpFrontendRootPage(1, $this->getTypoScriptFiles()); + } + + protected function getTypoScriptFiles(): array + { + return [ + 'constants' => [ + 'EXT:events/Configuration/TypoScript/constants.typoscript', + ], + 'setup' => [ + 'EXT:fluid_styled_content/Configuration/TypoScript/setup.typoscript', + 'EXT:events/Configuration/TypoScript/setup.typoscript', + 'EXT:events/Tests/Functional/Frontend/Fixtures/TypoScript/Rendering.typoscript', + ], + ]; + } + + /** + * @api Actual tests can use this method to define the actual date of "now". + */ + protected function setDateAspect(DateTimeImmutable $dateTime): void + { + $context = $this->getContainer()->get(Context::class); + if (!$context instanceof Context) { + throw new \TypeError('Retrieved context was of unexpected type.', 1638182021); + } + + $aspect = new DateTimeAspect($dateTime); + $context->setAspect('date', $aspect); } } diff --git a/Tests/Functional/Cleanup/RemoveAllTest.php b/Tests/Functional/Cleanup/RemoveAllTest.php index c4d1493..a985932 100644 --- a/Tests/Functional/Cleanup/RemoveAllTest.php +++ b/Tests/Functional/Cleanup/RemoveAllTest.php @@ -13,19 +13,13 @@ use Wrm\Events\Tests\Functional\AbstractFunctionalTestCase; */ class RemoveAllTest extends AbstractFunctionalTestCase { - protected $testExtensionsToLoad = [ - 'typo3conf/ext/events', - ]; - - protected $pathsToProvideInTestInstance = [ - 'typo3conf/ext/events/Tests/Functional/Cleanup/Fixtures/RemoveAllTestFileadmin/' => 'fileadmin/', - ]; - protected function setUp(): void { - parent::setUp(); + $this->pathsToProvideInTestInstance = [ + 'typo3conf/ext/events/Tests/Functional/Cleanup/Fixtures/RemoveAllTestFileadmin/' => 'fileadmin/', + ]; - $this->setUpBackendUserFromFixture(1); + parent::setUp(); } /** diff --git a/Tests/Functional/Cleanup/RemovePastTest.php b/Tests/Functional/Cleanup/RemovePastTest.php index 8e2498b..bf71b68 100644 --- a/Tests/Functional/Cleanup/RemovePastTest.php +++ b/Tests/Functional/Cleanup/RemovePastTest.php @@ -13,19 +13,13 @@ use Wrm\Events\Tests\Functional\AbstractFunctionalTestCase; */ class RemovePastTest extends AbstractFunctionalTestCase { - protected $testExtensionsToLoad = [ - 'typo3conf/ext/events', - ]; - - protected $pathsToProvideInTestInstance = [ - 'typo3conf/ext/events/Tests/Functional/Cleanup/Fixtures/RemovePastTestFileadmin/' => 'fileadmin/', - ]; - protected function setUp(): void { - parent::setUp(); + $this->pathsToProvideInTestInstance = [ + 'typo3conf/ext/events/Tests/Functional/Cleanup/Fixtures/RemovePastTestFileadmin/' => 'fileadmin/', + ]; - $this->setUpBackendUserFromFixture(1); + parent::setUp(); } /** diff --git a/Tests/Functional/Frontend/CacheTest.php b/Tests/Functional/Frontend/CacheTest.php index b0a981d..dd0d89c 100644 --- a/Tests/Functional/Frontend/CacheTest.php +++ b/Tests/Functional/Frontend/CacheTest.php @@ -26,29 +26,23 @@ namespace Wrm\Events\Tests\Functional\Frontend; use Codappix\Typo3PhpDatasets\PhpDataSet; use DateTimeImmutable; use DateTimeZone; +use GuzzleHttp\Psr7\Response; use Psr\Http\Message\ResponseInterface; +use TYPO3\CMS\Core\Information\Typo3Version; use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; +use Wrm\Events\Tests\Functional\AbstractFunctionalTestCase; /** * @covers \Wrm\Events\Caching\PageCacheTimeout */ -class CacheTest extends AbstractTestCase +class CacheTest extends AbstractFunctionalTestCase { - protected $testExtensionsToLoad = [ - 'typo3conf/ext/events', - 'typo3conf/ext/events/Tests/Functional/Frontend/Fixtures/Extensions/example', - ]; - - protected $coreExtensionsToLoad = [ - 'fluid_styled_content', - ]; - - protected $pathsToProvideInTestInstance = [ - 'typo3conf/ext/events/Tests/Functional/Frontend/Fixtures/Sites/' => 'typo3conf/sites', - ]; - protected function setUp(): void { + $this->testExtensionsToLoad = [ + 'typo3conf/ext/events/Tests/Functional/Frontend/Fixtures/Extensions/example', + ]; + parent::setUp(); $this->importPHPDataSet(__DIR__ . '/Fixtures/Database/SiteStructure.php'); @@ -59,7 +53,7 @@ class CacheTest extends AbstractTestCase 'list_type' => 'events_datelisttest', 'header' => 'All Dates', ]]]); - $this->setUpFrontendRootPage(1, $this->getTypoScriptFiles()); + $this->setUpFrontendRendering(); } /** @@ -260,6 +254,37 @@ class CacheTest extends AbstractTestCase self::assertSame('public', $response->getHeaderLine('Pragma')); } + /** + * @test + */ + public function cachesAreClearedByImport(): void + { + // Assert frontend is cached + $this->assertResponseIsNotCached($this->executeFrontendRequest($this->getRequestWithSleep())); + $this->assertResponseIsCached($this->executeFrontendRequest($this->getRequestWithSleep())); + + // Import + $this->importPHPDataSet(__DIR__ . '/../Import/DestinationDataTest/Fixtures/Database/DefaultImportConfiguration.php'); + $this->setUpConfiguration([ + 'restUrl = https://example.com/some-path/', + 'license = example-license', + 'restType = Event', + 'restLimit = 3', + 'restMode = next_months,12', + 'restTemplate = ET2014A.json', + ]); + $this->setUpResponses([ + new Response(200, [], file_get_contents(__DIR__ . '/../Import/DestinationDataTest/Fixtures/ResponseWithSingleImageForSingleEvent.json') ?: ''), + new Response(200, [], file_get_contents(__DIR__ . '/../Import/DestinationDataTest/Fixtures/ExampleImage.jpg') ?: ''), + ]); + $this->executeCommand(); + + // Assert frontend is not cached on first hit + $this->setUpFrontendRendering(); + $this->assertResponseIsNotCached($this->executeFrontendRequest($this->getRequestWithSleep())); + $this->assertResponseIsCached($this->executeFrontendRequest($this->getRequestWithSleep())); + } + private static function assertCacheHeaders(DateTimeImmutable $end, ResponseInterface $response): void { self::assertSame('public', $response->getHeaderLine('Pragma')); @@ -280,18 +305,22 @@ class CacheTest extends AbstractTestCase self::assertGreaterThanOrEqual($age - 3, $value, 'Max age of cached response is less than expected.'); } - private function getTypoScriptFiles(): array + private function assertResponseIsNotCached(ResponseInterface $response): void { - return [ - 'constants' => [ - 'EXT:events/Configuration/TypoScript/constants.typoscript', - ], - 'setup' => [ - 'EXT:fluid_styled_content/Configuration/TypoScript/setup.typoscript', - 'EXT:events/Configuration/TypoScript/setup.typoscript', - 'EXT:events/Tests/Functional/Frontend/Fixtures/TypoScript/Rendering.typoscript', - ], - ]; + if ((new Typo3Version())->getMajorVersion() < 11) { + self::assertStringNotContainsString('Cached page', $response->getBody()->__toString()); + return; + } + self::assertStringStartsNotWith('Cached page', $response->getHeaderLine('X-TYPO3-Debug-Cache')); + } + + private function assertResponseIsCached(ResponseInterface $response): void + { + if ((new Typo3Version())->getMajorVersion() < 11) { + self::assertStringContainsString('Cached page', $response->getBody()->__toString()); + return; + } + self::assertStringStartsWith('Cached page', $response->getHeaderLine('X-TYPO3-Debug-Cache')); } private function getRequestWithSleep(array $typoScript = []): InternalRequest diff --git a/Tests/Functional/Frontend/DatesTest.php b/Tests/Functional/Frontend/DatesTest.php index e31fb97..65eb57a 100644 --- a/Tests/Functional/Frontend/DatesTest.php +++ b/Tests/Functional/Frontend/DatesTest.php @@ -25,39 +25,19 @@ namespace Wrm\Events\Tests\Functional\Frontend; use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; use Wrm\Events\Frontend\Dates; +use Wrm\Events\Tests\Functional\AbstractFunctionalTestCase; /** * @covers \Wrm\Events\Frontend\Dates */ -class DatesTest extends AbstractTestCase +class DatesTest extends AbstractFunctionalTestCase { - protected $testExtensionsToLoad = [ - 'typo3conf/ext/events', - ]; - - protected $coreExtensionsToLoad = [ - 'fluid_styled_content', - ]; - - protected $pathsToProvideInTestInstance = [ - 'typo3conf/ext/events/Tests/Functional/Frontend/Fixtures/Sites/' => 'typo3conf/sites', - ]; - protected function setUp(): void { parent::setUp(); $this->importPHPDataSet(__DIR__ . '/Fixtures/Database/SiteStructure.php'); - $this->setUpFrontendRootPage(1, [ - 'constants' => [ - 'EXT:events/Configuration/TypoScript/constants.typoscript', - ], - 'setup' => [ - 'EXT:fluid_styled_content/Configuration/TypoScript/setup.typoscript', - 'EXT:events/Configuration/TypoScript/setup.typoscript', - 'EXT:events/Tests/Functional/Frontend/Fixtures/TypoScript/Rendering.typoscript', - ], - ]); + $this->setUpFrontendRendering(); } /** diff --git a/Tests/Functional/Frontend/FilterTest.php b/Tests/Functional/Frontend/FilterTest.php index 7491b5d..d919d58 100644 --- a/Tests/Functional/Frontend/FilterTest.php +++ b/Tests/Functional/Frontend/FilterTest.php @@ -5,40 +5,20 @@ declare(strict_types=1); namespace Wrm\Events\Tests\Functional\Frontend; use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; +use Wrm\Events\Tests\Functional\AbstractFunctionalTestCase; /** * @covers \Wrm\Events\Controller\DateController * @covers \Wrm\Events\Domain\Repository\DateRepository */ -class FilterTest extends AbstractTestCase +class FilterTest extends AbstractFunctionalTestCase { - protected $testExtensionsToLoad = [ - 'typo3conf/ext/events', - ]; - - protected $coreExtensionsToLoad = [ - 'fluid_styled_content', - ]; - - protected $pathsToProvideInTestInstance = [ - 'typo3conf/ext/events/Tests/Functional/Frontend/Fixtures/Sites/' => 'typo3conf/sites', - ]; - protected function setUp(): void { parent::setUp(); $this->importPHPDataSet(__DIR__ . '/Fixtures/Database/SiteStructure.php'); - $this->setUpFrontendRootPage(1, [ - 'constants' => [ - 'EXT:events/Configuration/TypoScript/constants.typoscript', - ], - 'setup' => [ - 'EXT:fluid_styled_content/Configuration/TypoScript/setup.typoscript', - 'EXT:events/Configuration/TypoScript/setup.typoscript', - 'EXT:events/Tests/Functional/Frontend/Fixtures/TypoScript/Rendering.typoscript', - ], - ]); + $this->setUpFrontendRendering(); } /** diff --git a/Tests/Functional/Frontend/Fixtures/TypoScript/Rendering.typoscript b/Tests/Functional/Frontend/Fixtures/TypoScript/Rendering.typoscript index a01ba2f..716ed1d 100644 --- a/Tests/Functional/Frontend/Fixtures/TypoScript/Rendering.typoscript +++ b/Tests/Functional/Frontend/Fixtures/TypoScript/Rendering.typoscript @@ -2,6 +2,7 @@ config { cache_period = 86400 no_cache = 0 sendCacheHeaders = 1 + debug = 1 } page = PAGE diff --git a/Tests/Functional/Import/DestinationDataTest/AbstractTest.php b/Tests/Functional/Import/DestinationDataTest/AbstractTest.php index fe2dadc..949be73 100644 --- a/Tests/Functional/Import/DestinationDataTest/AbstractTest.php +++ b/Tests/Functional/Import/DestinationDataTest/AbstractTest.php @@ -2,109 +2,14 @@ namespace Wrm\Events\Tests\Functional\Import\DestinationDataTest; -use GuzzleHttp\ClientInterface as GuzzleClientInterface; -use Psr\Http\Client\ClientInterface; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Tester\CommandTester; -use Symfony\Component\DependencyInjection\Container; -use TYPO3\CMS\Core\Context\Context; -use TYPO3\CMS\Core\Context\DateTimeAspect; -use TYPO3\CMS\Core\Localization\LanguageServiceFactory; -use Wrm\Events\Command\ImportDestinationDataViaConfigruationCommand; -use Wrm\Events\Tests\ClientFactory; use Wrm\Events\Tests\Functional\AbstractFunctionalTestCase; abstract class AbstractTest extends AbstractFunctionalTestCase { - protected $coreExtensionsToLoad = [ - 'filelist', - ]; - - protected $testExtensionsToLoad = [ - 'typo3conf/ext/events', - ]; - protected function setUp(): void { parent::setUp(); $this->importPHPDataSet(__DIR__ . '/Fixtures/Database/Structure.php'); - $this->setUpBackendUserFromFixture(1); - - $languageServiceFactory = $this->getContainer()->get(LanguageServiceFactory::class); - if (!$languageServiceFactory instanceof LanguageServiceFactory) { - throw new \UnexpectedValueException('Did not retrieve LanguageServiceFactory.', 1637847250); - } - $GLOBALS['LANG'] = $languageServiceFactory->create('default'); - } - - protected function tearDown(): void - { - unset($GLOBALS['LANG']); - - parent::tearDown(); - } - - protected function setUpConfiguration( - array $destinationDataSettings, - array $importSettings = [] - ): void { - $this->setUpFrontendRootPage(1, [], [ - 'config' => implode(PHP_EOL, [ - 'module.tx_events_pi1.settings.destinationData {', - implode(PHP_EOL, $destinationDataSettings), - '}', - 'module.tx_events_import.settings {', - implode(PHP_EOL, $importSettings), - '}', - ]), - ]); - } - - protected function &setUpResponses(array $responses): array - { - $requests = []; - - $client = ClientFactory::createClientWithHistory($responses, $requests); - $container = $this->getContainer(); - if ($container instanceof Container) { - $container->set(ClientInterface::class, $client); - // For TYPO3 10 support - $container->set(GuzzleClientInterface::class, $client); - } - - return $requests; - } - - protected function executeCommand( - array $argumentsAndOptions = ['configurationUid' => '1'], - string $command = ImportDestinationDataViaConfigruationCommand::class - ): CommandTester { - $subject = $this->getContainer()->get($command); - self::assertInstanceOf(Command::class, $subject); - - $tester = new CommandTester($subject); - $tester->execute( - $argumentsAndOptions, - [ - 'capture_stderr_separately' => true, - ] - ); - - return $tester; - } - - /** - * @api Actual tests can use this method to define the actual date of "now". - */ - protected function setDateAspect(\DateTimeImmutable $dateTime): void - { - $context = $this->getContainer()->get(Context::class); - if (!$context instanceof Context) { - throw new \TypeError('Retrieved context was of unexpected type.', 1638182021); - } - - $aspect = new DateTimeAspect($dateTime); - $context->setAspect('date', $aspect); } } diff --git a/Tests/Functional/Import/DestinationDataTest/ImportCleansTransientFilesTest.php b/Tests/Functional/Import/DestinationDataTest/ImportCleansTransientFilesTest.php index 563f6bc..b2ef113 100644 --- a/Tests/Functional/Import/DestinationDataTest/ImportCleansTransientFilesTest.php +++ b/Tests/Functional/Import/DestinationDataTest/ImportCleansTransientFilesTest.php @@ -16,10 +16,6 @@ class ImportCleansTransientFilesTest extends AbstractTest */ public function cleansTransientFiles(): void { - $fileImportPathConfiguration = 'staedte/beispielstadt/events/'; - $fileImportPath = $this->getInstancePath() . '/fileadmin/' . $fileImportPathConfiguration; - GeneralUtility::mkdir_deep($fileImportPath); - $this->importPHPDataSet(__DIR__ . '/Fixtures/Database/DefaultImportConfiguration.php'); $this->setUpConfiguration([ 'restUrl = https://example.com/some-path/', @@ -47,7 +43,7 @@ class ImportCleansTransientFilesTest extends AbstractTest self::assertSame('https://dam.destination.one/828118/f13bbf5602ffc406ebae2faa3527654dea84194666bce4925a1ca8bd3f50c5e9/tueftlerzeit-sfz-rudolstadt-jpg.jpg', (string)$requests[2]['request']->getUri()); self::assertSame('https://dam.destination.one/853436/109ac1cf87913e21b5e2b0ef0cc63d223a14374364952a855746a8e7c3fcfc36/lutherkirche-jpg.jpg', (string)$requests[3]['request']->getUri()); - $importedFiles = GeneralUtility::getFilesInDir($fileImportPath); + $importedFiles = GeneralUtility::getFilesInDir($this->fileImportPath); self::assertIsArray($importedFiles, 'Failed to retrieve imported files from filesystem.'); self::assertSame( [ diff --git a/Tests/Functional/Import/DestinationDataTest/ImportHandlesImagesTest.php b/Tests/Functional/Import/DestinationDataTest/ImportHandlesImagesTest.php index 6d3e95d..d7930c4 100644 --- a/Tests/Functional/Import/DestinationDataTest/ImportHandlesImagesTest.php +++ b/Tests/Functional/Import/DestinationDataTest/ImportHandlesImagesTest.php @@ -10,11 +10,6 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; */ class ImportHandlesImagesTest extends AbstractTest { - /** - * @var string - */ - private $fileImportPath = ''; - protected function setUp(): void { // Ensure proper type mapping within tests. @@ -23,12 +18,7 @@ class ImportHandlesImagesTest extends AbstractTest parent::setUp(); - $fileImportPathConfiguration = 'staedte/beispielstadt/events/'; - $this->fileImportPath = $this->getInstancePath() . '/fileadmin/' . $fileImportPathConfiguration; - GeneralUtility::mkdir_deep($this->fileImportPath); - $this->importPHPDataSet(__DIR__ . '/Fixtures/Database/DefaultImportConfiguration.php'); - $this->setUpConfiguration([ 'restUrl = https://example.com/some-path/', 'license = example-license', @@ -39,13 +29,6 @@ class ImportHandlesImagesTest extends AbstractTest ]); } - protected function tearDown(): void - { - parent::tearDown(); - - GeneralUtility::rmdir($this->fileImportPath, true); - } - /** * @test */