diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 06285280..ecdb20b3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -63,14 +63,69 @@ jobs: - "php:cs-fixer" php-version: - 8.2 - tests: + testV12: runs-on: ubuntu-latest strategy: max-parallel: 2 matrix: - php-versions: [8.1] + php-versions: [ 8.1, 8.2 ] typo3-versions: - - {typo3: 12, testing: ^7.0@dev} + - { typo3: 12, testing: ^8.0, phpunit: ^10, phpcov: ^9, yaml: ^6 } + + name: "Run tests with PHP ${{ matrix.php-versions }} + using TYPO3 ${{ matrix.typo3-versions.typo3 }} + with testing framework version ${{ matrix.typo3-versions.testing }}" + steps: + - uses: actions/checkout@v4 + + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: intl, mbstring, pdo_sqlite + + - name: "Cache composer dependencies" + uses: actions/cache@v4 + with: + path: ~/.composer/cache + key: php-${{ matrix.php-versions }} + -typo3-${{ matrix.typo3-versions.typo3 }} + -phpunit-${{ matrix.typo3-versions.phpunit }} + -phpcov-${{ matrix.typo3-versions.phpcov }} + -yaml-${{ matrix.typo3-versions.yaml }} + -testing-${{ matrix.typo3-versions.testing }} + -composer-${{ hashFiles('composer.json') }} + restore-keys: | + php-${{ matrix.php-versions }} + -typo3-${{ matrix.typo3-versions.typo3 }} + -phpunit-${{ matrix.typo3-versions.phpunit }} + -phpcov-${{ matrix.typo3-versions.phpcov }} + -yaml-${{ matrix.typo3-versions.yaml }} + -testing-${{ matrix.typo3-versions.testing }}composer- + php-${{ matrix.php-versions }}-typo3- + + - name: "Install composer dependencies" + run: composer require typo3/minimal + "^${{ matrix.typo3-versions.typo3 }}" + typo3/testing-framework "${{ matrix.typo3-versions.testing }}" + phpunit/phpunit "${{ matrix.typo3-versions.phpunit }}" + phpunit/phpcov "${{ matrix.typo3-versions.phpcov }}" + symfony/yaml "${{ matrix.typo3-versions.yaml }}" + --prefer-dist --no-progress + + - name: "Run Unit tests" + run: composer ci:test:unit + + - name: "Functional tests" + run: composer ci:test:functional + + testsV13: + runs-on: ubuntu-latest + strategy: + max-parallel: 2 + matrix: + php-versions: [8.2, 8.3] + typo3-versions: + - {typo3: 13, testing: ^9.0, phpunit: ^11, phpcov: ^10, yaml: ^7 } name: "Run tests with PHP ${{ matrix.php-versions }} using TYPO3 ${{ matrix.typo3-versions.typo3 }} @@ -89,19 +144,28 @@ jobs: path: ~/.composer/cache key: php-${{ matrix.php-versions }} -typo3-${{ matrix.typo3-versions.typo3 }} + -phpunit-${{ matrix.typo3-versions.phpunit }} + -phpcov-${{ matrix.typo3-versions.phpcov }} + -yaml-${{ matrix.typo3-versions.yaml }} -testing-${{ matrix.typo3-versions.testing }} -composer-${{ hashFiles('composer.json') }} restore-keys: | php-${{ matrix.php-versions }} -typo3-${{ matrix.typo3-versions.typo3 }} + -phpunit-${{ matrix.typo3-versions.phpunit }} + -phpcov-${{ matrix.typo3-versions.phpcov }} + -yaml-${{ matrix.typo3-versions.yaml }} -testing-${{ matrix.typo3-versions.testing }}composer- php-${{ matrix.php-versions }}-typo3- - name: "Install composer dependencies" - run: composer require typo3/minimal + run: composer remove php-coveralls/php-coveralls --dev --no-progress && composer require typo3/minimal "^${{ matrix.typo3-versions.typo3 }}" typo3/testing-framework "${{ matrix.typo3-versions.testing }}" - --prefer-dist --no-progress --no-suggest + phpunit/phpunit "${{ matrix.typo3-versions.phpunit }}" + phpunit/phpcov "${{ matrix.typo3-versions.phpcov }}" + symfony/yaml "${{ matrix.typo3-versions.yaml }}" + --prefer-dist --no-progress - name: "Run Unit tests" run: composer ci:test:unit diff --git a/Classes/ContentObject/JsonContentContentObject.php b/Classes/ContentObject/JsonContentContentObject.php index 3f717984..a6ffee69 100755 --- a/Classes/ContentObject/JsonContentContentObject.php +++ b/Classes/ContentObject/JsonContentContentObject.php @@ -14,7 +14,10 @@ use FriendsOfTYPO3\Headless\Json\JsonEncoder; use FriendsOfTYPO3\Headless\Json\JsonEncoderInterface; use FriendsOfTYPO3\Headless\Utility\HeadlessUserInt; +use Psr\EventDispatcher\EventDispatcherInterface; use TYPO3\CMS\Backend\View\BackendLayoutView; +use TYPO3\CMS\Core\Information\Typo3Version; +use TYPO3\CMS\Core\TimeTracker\TimeTracker; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\ContentObject\ContentContentObject; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; @@ -23,6 +26,7 @@ use function count; use function is_array; use function json_decode; +use function json_encode; use function str_contains; use function trim; @@ -97,16 +101,25 @@ * } * returnSingleRow = 1 * } + * + * @codeCoverageIgnore */ class JsonContentContentObject extends ContentContentObject { private HeadlessUserInt $headlessUserInt; private JsonEncoderInterface $jsonEncoder; + /** + * @var mixed|object|\Psr\Log\LoggerAwareInterface|\TYPO3\CMS\Core\SingletonInterface|TimeTracker|(TimeTracker&\Psr\Log\LoggerAwareInterface)|(TimeTracker&\TYPO3\CMS\Core\SingletonInterface)|null + */ + private TimeTracker $timeTracker; + private EventDispatcherInterface $eventDispatcher; public function __construct() { $this->headlessUserInt = GeneralUtility::makeInstance(HeadlessUserInt::class); $this->jsonEncoder = GeneralUtility::makeInstance(JsonEncoder::class); + $this->timeTracker = GeneralUtility::makeInstance(TimeTracker::class); + $this->eventDispatcher = GeneralUtility::makeInstance(EventDispatcherInterface::class); } /** @@ -199,6 +212,8 @@ protected function groupContentElementsByColPos(array $contentElements, array $c */ private function prepareValue(array $conf): array { + $t3v13andAbove = (new Typo3Version())->getMajorVersion() >= 13; + $frontendController = $this->getTypoScriptFrontendController(); $theValue = []; $originalRec = $frontendController->currentRecord; @@ -233,20 +248,44 @@ private function prepareValue(array $conf): array $tmpValue = ''; do { - $records = $this->cObj->getRecords($conf['table'], $conf['select.']); + if ($t3v13andAbove) { + $modifyRecordsEvent = $this->eventDispatcher->dispatch( + new \TYPO3\CMS\Frontend\ContentObject\Event\ModifyRecordsAfterFetchingContentEvent( + $this->cObj->getRecords($conf['table'], $conf['select.']), + json_encode($theValue, JSON_THROW_ON_ERROR), + $slide, + $slideCollect, + $slideCollectReverse, + $slideCollectFuzzy, + $conf + ) + ); + + $records = $modifyRecordsEvent->getRecords(); + $theValue = json_decode($modifyRecordsEvent->getFinalContent(), true, 512, JSON_THROW_ON_ERROR); + $slide = $modifyRecordsEvent->getSlide(); + $slideCollect = $modifyRecordsEvent->getSlideCollect(); + $slideCollectReverse = $modifyRecordsEvent->getSlideCollectReverse(); + $slideCollectFuzzy = $modifyRecordsEvent->getSlideCollectFuzzy(); + $conf = $modifyRecordsEvent->getConfiguration(); + } else { + $records = $this->cObj->getRecords($conf['table'], $conf['select.']); + } $cobjValue = []; if (!empty($records)) { - $this->getTimeTracker()->setTSlogMessage('NUMROWS: ' . count($records)); + $this->timeTracker->setTSlogMessage('NUMROWS: ' . count($records)); $cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class, $frontendController); $cObj->setParent($this->cObj->data, $this->cObj->currentRecord); $this->cObj->currentRecordNumber = 0; foreach ($records as $row) { - // Call hook for possible manipulation of database row for cObj->data - foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content_content.php']['modifyDBRow'] ?? [] as $className) { - $_procObj = GeneralUtility::makeInstance($className); - $_procObj->modifyDBRow($row, $conf['table']); + if (!$t3v13andAbove) { + // Call hook for possible manipulation of database row for cObj->data + foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content_content.php']['modifyDBRow'] ?? [] as $className) { + $_procObj = GeneralUtility::makeInstance($className); + $_procObj->modifyDBRow($row, $conf['table']); + } } $registerField = $conf['table'] . ':' . ($row['uid'] ?? 0); if (!($frontendController->recordRegister[$registerField] ?? false)) { @@ -282,7 +321,7 @@ private function prepareValue(array $conf): array } $again = (string)$conf['select.']['pidInList'] !== ''; } - } while ($again && $slide && ((string)$tmpValue === '' && $slideCollectFuzzy || $slideCollect)); + } while ($again && $slide && (((string)$tmpValue === '' && $slideCollectFuzzy) || $slideCollect)); $theValue = $this->groupContentElementsByColPos($theValue, $conf); // Restore diff --git a/Classes/DataProcessing/FlexFormProcessor.php b/Classes/DataProcessing/FlexFormProcessor.php index 1f74834e..8fb89653 100644 --- a/Classes/DataProcessing/FlexFormProcessor.php +++ b/Classes/DataProcessing/FlexFormProcessor.php @@ -108,7 +108,11 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu } // processing the flexform data - $originalValue = $processedData['data'][$fieldName] ?? $processedData[$fieldName]; + $originalValue = $processedData['data'][$fieldName] ?? $processedData[$fieldName] ?? null; + + if ($originalValue === null || $originalValue === '' || $originalValue === []) { + return $processedData; + } if (is_array($originalValue)) { $flexformData = $originalValue; diff --git a/Classes/Event/Listener/HeadlessHreflangGeneratorListener.php b/Classes/Event/Listener/HeadlessHreflangGeneratorListener.php new file mode 100644 index 00000000..6177a1d6 --- /dev/null +++ b/Classes/Event/Listener/HeadlessHreflangGeneratorListener.php @@ -0,0 +1,34 @@ +withRequest($event->getRequest()); + + foreach ($event->getHrefLangs() as $lang => $hrefLang) { + $hrefLangs[$lang] = $urlUtility->getFrontendUrlWithSite($hrefLang, $event->getRequest()->getAttribute('site')); + } + + $event->setHrefLangs($hrefLangs); + } +} diff --git a/Classes/Middleware/ShortcutAndMountPointRedirect.php b/Classes/Middleware/ShortcutAndMountPointRedirect.php index 8c644bfa..145a4791 100644 --- a/Classes/Middleware/ShortcutAndMountPointRedirect.php +++ b/Classes/Middleware/ShortcutAndMountPointRedirect.php @@ -12,29 +12,19 @@ namespace FriendsOfTYPO3\Headless\Middleware; use FriendsOfTYPO3\Headless\Utility\HeadlessMode; +use FriendsOfTYPO3\Headless\Utility\UrlUtility; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; -use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; -use Psr\Log\LoggerAwareInterface; -use Psr\Log\LoggerAwareTrait; -use TYPO3\CMS\Core\Domain\Repository\PageRepository; -use TYPO3\CMS\Core\Http\ImmediateResponseException; use TYPO3\CMS\Core\Http\JsonResponse; use TYPO3\CMS\Core\Http\RedirectResponse; -use TYPO3\CMS\Core\Routing\PageArguments; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Frontend\Controller\ErrorController; -use TYPO3\CMS\Frontend\Page\PageAccessFailureReasons; - -use function is_array; -use function parse_url; - -class ShortcutAndMountPointRedirect implements MiddlewareInterface, LoggerAwareInterface +/** + * @codeCoverageIgnore + */ +class ShortcutAndMountPointRedirect extends \TYPO3\CMS\Frontend\Middleware\ShortcutAndMountPointRedirect { - use LoggerAwareTrait; - public function __construct(private readonly HeadlessMode $headlessMode) {} public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface @@ -46,96 +36,18 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface return $handler->handle($request); } - $exposeInformation = $GLOBALS['TYPO3_CONF_VARS']['FE']['exposeRedirectInformation'] ?? false; + $coreResponse = parent::process($request, $handler); - // Check for shortcut page and mount point redirect - try { - $redirectToUri = $this->getRedirectUri($request); - } catch (ImmediateResponseException $e) { - return $e->getResponse(); + if ($coreResponse instanceof RedirectResponse && $this->isHeadlessEnabled($request)) { + return new JsonResponse([ + 'redirectUrl' => GeneralUtility::makeInstance(UrlUtility::class) + ->withRequest($request) + ->prepareRelativeUrlIfPossible($coreResponse->getHeader('location')[0] ?? ''), + 'statusCode' => $coreResponse->getStatusCode(), + ]); } - if ($redirectToUri !== null && $redirectToUri !== (string)$request->getUri()) { - /** @var PageArguments $pageArguments */ - $pageArguments = $request->getAttribute('routing', null); - $message = 'TYPO3 Shortcut/Mountpoint' . ($exposeInformation ? ' at page with ID ' . $pageArguments->getPageId() : ''); - - if ($this->isHeadlessEnabled($request)) { - $parsed = parse_url($redirectToUri); - if (is_array($parsed)) { - $path = $parsed['path'] ?? '/'; - return new JsonResponse(['redirectUrl' => $path, 'statusCode' => 307]); - } - } - return new RedirectResponse( - $redirectToUri, - 307, - ['X-Redirect-By' => $message] - ); - } - - // See if the current page is of doktype "External URL", if so, do a redirect as well. - $controller = $request->getAttribute('frontend.controller'); - if ((int)$controller->page['doktype'] === PageRepository::DOKTYPE_LINK) { - $externalUrl = $this->prefixExternalPageUrl( - $controller->page['url'], - $request->getAttribute('normalizedParams')->getSiteUrl() - ); - $message = 'TYPO3 External URL' . ($exposeInformation ? ' at page with ID ' . $controller->page['uid'] : ''); - if (!empty($externalUrl)) { - if ($this->isHeadlessEnabled($request)) { - return new JsonResponse(['redirectUrl' => $externalUrl, 'statusCode' => 303]); - } - - return new RedirectResponse( - $externalUrl, - 303, - ['X-Redirect-By' => $message] - ); - } - $this->logger->error( - 'Page of type "External URL" could not be resolved properly', - [ - 'page' => $controller->page, - ] - ); - return GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction( - $request, - 'Page of type "External URL" could not be resolved properly', - $controller->getPageAccessFailureReasons(PageAccessFailureReasons::INVALID_EXTERNAL_URL) - ); - } - - return $handler->handle($request); - } - - protected function getRedirectUri(ServerRequestInterface $request): ?string - { - $controller = $request->getAttribute('frontend.controller'); - $redirectToUri = $controller->getRedirectUriForShortcut($request); - return $redirectToUri ?? $controller->getRedirectUriForMountPoint($request); - } - - /** - * Returns the redirect URL for the input page row IF the doktype is set to 3. - * - * @param string $redirectTo The page row to return URL type for - * @param string $sitePrefix if no protocol or relative path given, the site prefix is added - * @return string The URL from based on the external page URL given with a prefix. - */ - protected function prefixExternalPageUrl(string $redirectTo, string $sitePrefix): string - { - $uI = parse_url($redirectTo); - // If relative path, prefix Site URL - // If it's a valid email without protocol, add "mailto:" - if (!($uI['scheme'] ?? false)) { - if (GeneralUtility::validEmail($redirectTo)) { - $redirectTo = 'mailto:' . $redirectTo; - } elseif (!str_starts_with($redirectTo, '/')) { - $redirectTo = $sitePrefix . $redirectTo; - } - } - return $redirectTo; + return $coreResponse; } private function isHeadlessEnabled(ServerRequestInterface $request): bool diff --git a/Classes/Seo/CanonicalGenerator.php b/Classes/Seo/CanonicalGenerator.php index fafb93cc..e24f9cf6 100644 --- a/Classes/Seo/CanonicalGenerator.php +++ b/Classes/Seo/CanonicalGenerator.php @@ -12,73 +12,42 @@ namespace FriendsOfTYPO3\Headless\Seo; use FriendsOfTYPO3\Headless\Utility\HeadlessMode; -use Psr\EventDispatcher\EventDispatcherInterface; -use TYPO3\CMS\Core\Domain\Page; -use TYPO3\CMS\Core\Domain\Repository\PageRepository; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; -use TYPO3\CMS\Seo\Event\ModifyUrlForCanonicalTagEvent; +use TYPO3\CMS\Seo\Canonical\CanonicalGenerator as CoreCanonicalGenerator; use function htmlspecialchars; use function json_encode; /** - * Overridden core version with headless implementation + * Decorate Core version with headless flavor * * @codeCoverageIgnore */ -class CanonicalGenerator extends \TYPO3\CMS\Seo\Canonical\CanonicalGenerator +class CanonicalGenerator { - protected TypoScriptFrontendController $typoScriptFrontendController; - protected PageRepository $pageRepository; - protected EventDispatcherInterface $eventDispatcher; - public function handle(array &$params): string { - if ($this->typoScriptFrontendController->config['config']['disableCanonical'] ?? false) { - return ''; - } + $canonical = GeneralUtility::makeInstance(CoreCanonicalGenerator::class)->generate($params); - $event = new ModifyUrlForCanonicalTagEvent('', $params['request'], new Page($params['page'])); - $event = $this->eventDispatcher->dispatch($event); - $href = $event->getUrl(); - - if (empty($href) && (int)$this->typoScriptFrontendController->page['no_index'] === 1) { + if ($canonical === '') { return ''; } - if (empty($href)) { - // 1) Check if page has canonical URL set - $href = $this->checkForCanonicalLink(); - } - if (empty($href)) { - // 2) Check if page show content from other page - $href = $this->checkContentFromPid(); - } - if (empty($href)) { - // 3) Fallback, create canonical URL - $href = $this->checkDefaultCanonical(); - } + if (GeneralUtility::makeInstance(HeadlessMode::class)->withRequest($params['request'])->isEnabled()) { + $canonical = [ + 'href' => $this->processCanonical($canonical), + 'rel' => 'canonical', + ]; - if (!empty($href)) { - if (GeneralUtility::makeInstance(HeadlessMode::class)->withRequest($params['request'])->isEnabled()) { - $canonical = [ - 'href' => htmlspecialchars($href), - 'rel' => 'canonical', - ]; + $params['_seoLinks'][] = $canonical; + $canonical = json_encode($canonical); + } - $params['_seoLinks'][] = $canonical; - $canonical = json_encode($canonical); - } else { - $canonical = ' 'canonical', - 'href' => $href, - ], true) . '/>' . LF; - $this->typoScriptFrontendController->additionalHeaderData[] = $canonical; - } + return $canonical; + } - return $canonical; - } - return ''; + protected function processCanonical(string $canonical): string + { + return htmlspecialchars(GeneralUtility::get_tag_attributes($canonical)['href'] ?? ''); } } diff --git a/Classes/Seo/MetaHandler.php b/Classes/Seo/MetaHandler.php index d8b7f799..1f1aa2b3 100644 --- a/Classes/Seo/MetaHandler.php +++ b/Classes/Seo/MetaHandler.php @@ -36,7 +36,7 @@ public function process(ServerRequestInterface $request, TypoScriptFrontendContr GeneralUtility::callUserFunction($_funcRef, $_params, $_ref); } - $content['seo']['title'] = $controller->generatePageTitle(); + $content['seo']['title'] = $controller->generatePageTitle($request); $this->generateMetaTagsFromTyposcript( $controller->pSetup['meta.'] ?? [], diff --git a/Classes/Utility/HeadlessVersion.php b/Classes/Utility/HeadlessVersion.php new file mode 100644 index 00000000..e2d20fac --- /dev/null +++ b/Classes/Utility/HeadlessVersion.php @@ -0,0 +1,36 @@ +getVersion(); + } +} diff --git a/Classes/XClass/Controller/FormFrontendController.php b/Classes/XClass/Controller/FormFrontendController.php index bc62fb04..64c13a8e 100644 --- a/Classes/XClass/Controller/FormFrontendController.php +++ b/Classes/XClass/Controller/FormFrontendController.php @@ -18,39 +18,34 @@ use FriendsOfTYPO3\Headless\Utility\HeadlessMode; use FriendsOfTYPO3\Headless\XClass\FormRuntime; use Psr\Http\Message\ResponseInterface; +use TYPO3\CMS\Core\Information\Typo3Version; use TYPO3\CMS\Core\Utility\ArrayUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface as ExtbaseConfigurationManagerInterface; use TYPO3\CMS\Extbase\Error\Error; -use TYPO3\CMS\Extbase\Security\Cryptography\HashService; +use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters; use TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory; use TYPO3\CMS\Form\Domain\Model\FormDefinition; use function array_merge; use function array_pop; use function base64_encode; +use function class_exists; use function count; use function in_array; +use function is_array; use function json_decode; use function serialize; use function str_replace; /** - * The frontend controller + * Overridden form implementation with headless flavor * - * Scope: frontend * @internal * @codeCoverageIgnore */ class FormFrontendController extends \TYPO3\CMS\Form\Controller\FormFrontendController { - private Translator $jsonFormTranslator; - - public function __construct() - { - $this->hashService = GeneralUtility::makeInstance(HashService::class); - $this->jsonFormTranslator = GeneralUtility::makeInstance(Translator::class); - } - /** * Take the form which should be rendered from the plugin settings * and overlay the formDefinition with additional data from @@ -64,13 +59,28 @@ public function renderAction(): ResponseInterface { $headlessMode = GeneralUtility::makeInstance(HeadlessMode::class); - if (!$headlessMode->withRequest($GLOBALS['TYPO3_REQUEST'])->isEnabled()) { + if (!$headlessMode->withRequest($this->request)->isEnabled()) { return parent::renderAction(); } $formDefinition = []; if (!empty($this->settings['persistenceIdentifier'])) { - $formDefinition = $this->formPersistenceManager->load($this->settings['persistenceIdentifier']); + $formSettings = []; + $typoScriptSettings = []; + + if ((new Typo3Version())->getMajorVersion() >= 13) { + $typoScriptSettings = $this->configurationManager->getConfiguration( + ExtbaseConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS, + 'form' + ); + $formSettings = $this->extFormConfigurationManager->getYamlConfiguration($typoScriptSettings, true); + } + + $formDefinition = $this->formPersistenceManager->load( + $this->settings['persistenceIdentifier'], + $formSettings, + $typoScriptSettings + ); $formDefinition['persistenceIdentifier'] = $this->settings['persistenceIdentifier']; $formDefinition = $this->overrideByFlexFormSettings($formDefinition); $formDefinition = ArrayUtility::setValueByPath( @@ -80,10 +90,7 @@ public function renderAction(): ResponseInterface '.' ); - $formId = ($this->configurationManager->getContentObject() !== null ? - ($this->configurationManager->getContentObject()->data['uid'] ?? 0) : 0); - - $formDefinition['identifier'] .= '-' . $formId; + $formDefinition['identifier'] .= '-' . ($this->request->getAttribute('currentContentObject')?->data['uid'] ?? ''); } $i18n = []; @@ -128,14 +135,21 @@ public function renderAction(): ResponseInterface $honeyPot = array_pop($elements); } - $stateHash = $this->hashService->appendHmac(base64_encode(serialize($formState))); + $stateHash = $this->getHashService()->appendHmac( + base64_encode(serialize($formState)), + class_exists(\TYPO3\CMS\Form\Security\HashScope::class) ? \TYPO3\CMS\Form\Security\HashScope::FormState->prefix() : '' + ); $currentPageIndex = $formRuntime->getCurrentPage() ? $formRuntime->getCurrentPage()->getIndex() : 0; $currentPageId = $currentPageIndex + 1; $formFields = $formDefinition['renderables'][$currentPageIndex]['renderables'] ?? []; // provides support for custom options providers (dynamic selects/radio/checkboxes) - $formFieldsNames = $this->generateFieldNamesAndReplaceCustomOptions($formFields, $formDefinition['identifier'], $formRuntime); + $formFieldsNames = $this->generateFieldNamesAndReplaceCustomOptions( + $formFields, + $formDefinition['identifier'], + $formRuntime + ); if ($honeyPot) { $formFields[] = [ @@ -188,7 +202,7 @@ public function renderAction(): ResponseInterface $formDefinition['renderables'][$currentPageIndex]['renderables'] = $formFields; $formDefinition['i18n'] = count($i18n) ? $i18n : null; - $formDefinition = $this->jsonFormTranslator->translate( + $formDefinition = $this->getFormTranslator()->translate( $formDefinition, $formRuntime->getFormDefinition()->getRenderingOptions(), $formRuntime->getFormState() ? $formRuntime->getFormState()->getFormValues() : [] @@ -260,8 +274,11 @@ private function getNextPage(\TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRun * @param array $formFields * @return array */ - private function generateFieldNamesAndReplaceCustomOptions(array &$formFields, string $identifier, FormRuntime $formRuntime): array - { + private function generateFieldNamesAndReplaceCustomOptions( + array &$formFields, + string $identifier, + FormRuntime $formRuntime + ): array { $formFieldsNames = []; foreach ($formFields as &$field) { @@ -274,7 +291,13 @@ private function generateFieldNamesAndReplaceCustomOptions(array &$formFields, s ); } else { if (!empty($field['properties']['customOptions'])) { - $customOptions = GeneralUtility::makeInstance($field['properties']['customOptions'], $field, $formFields, $identifier, $formRuntime); + $customOptions = GeneralUtility::makeInstance( + $field['properties']['customOptions'], + $field, + $formFields, + $identifier, + $formRuntime + ); if ($customOptions instanceof CustomOptionsInterface) { $field['properties']['options'] = $customOptions->get(); @@ -295,4 +318,18 @@ private function generateFieldNamesAndReplaceCustomOptions(array &$formFields, s return $formFieldsNames; } + + private function getHashService(): \TYPO3\CMS\Extbase\Security\Cryptography\HashService|\TYPO3\CMS\Core\Crypto\HashService + { + if ((new Typo3Version())->getMajorVersion() >= 13) { + return GeneralUtility::makeInstance(\TYPO3\CMS\Core\Crypto\HashService::class); + } + + return GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Security\Cryptography\HashService::class); + } + + private function getFormTranslator(): Translator + { + return GeneralUtility::makeInstance(Translator::class); + } } diff --git a/Classes/XClass/ResourceLocalDriver.php b/Classes/XClass/ResourceLocalDriver.php index 285479af..18b4ace1 100644 --- a/Classes/XClass/ResourceLocalDriver.php +++ b/Classes/XClass/ResourceLocalDriver.php @@ -16,6 +16,7 @@ use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Core\Http\ApplicationType; use TYPO3\CMS\Core\Http\Uri; +use TYPO3\CMS\Core\Information\Typo3Version; use TYPO3\CMS\Core\Resource\Driver\LocalDriver; use TYPO3\CMS\Core\Resource\ResourceStorage; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -30,6 +31,7 @@ protected function determineBaseUrl(): void $request = $GLOBALS['TYPO3_REQUEST'] ?? null; if (!$request instanceof ServerRequestInterface) { + parent::determineBaseUrl(); return; } @@ -41,7 +43,7 @@ protected function determineBaseUrl(): void return; } - if ($this->hasCapability(ResourceStorage::CAPABILITY_PUBLIC)) { + if ($this->hasCapability(((new Typo3Version())->getMajorVersion() < 13) ? ResourceStorage::CAPABILITY_PUBLIC : \TYPO3\CMS\Core\Resource\Capabilities::CAPABILITY_PUBLIC)) { $urlUtility = GeneralUtility::makeInstance(UrlUtility::class)->withRequest($request); $basePath = match (true) { diff --git a/Configuration/Services.php b/Configuration/Services.php index d6dddabb..c847d1e7 100644 --- a/Configuration/Services.php +++ b/Configuration/Services.php @@ -23,6 +23,7 @@ use FriendsOfTYPO3\Headless\Event\Listener\AfterCacheableContentIsGeneratedListener; use FriendsOfTYPO3\Headless\Event\Listener\AfterLinkIsGeneratedListener; use FriendsOfTYPO3\Headless\Event\Listener\AfterPagePreviewUriGeneratedListener; +use FriendsOfTYPO3\Headless\Event\Listener\HeadlessHreflangGeneratorListener; use FriendsOfTYPO3\Headless\Event\Listener\LoginConfirmedEventListener; use FriendsOfTYPO3\Headless\Form\Service\FormTranslationService; use FriendsOfTYPO3\Headless\Utility\FileUtility; @@ -96,6 +97,16 @@ ['identifier' => 'headless/AfterPagePreviewUriGenerated'] ); + if (class_exists(\TYPO3\CMS\Seo\HrefLang\HrefLangGenerator::class)) { + $services->set(HeadlessHreflangGeneratorListener::class)->tag( + 'event.listener', + [ + 'identifier' => 'headless/hreflangGenerator', + 'after' => 'typo3-seo/hreflangGenerator', + ] + ); + } + if ($cmsFormsInstalled) { $services->set(FormTranslationService::class)->arg('$runtimeCache', service('cache.runtime'))->public(); } @@ -116,7 +127,11 @@ RootSitesProcessor::class => ['identifier' => 'headless-root-sites', 'share' => true, 'public' => false], MenuProcessor::class => ['identifier' => 'headless-menu', 'share' => false, 'public' => true], GalleryProcessor::class => ['identifier' => 'headless-gallery', 'share' => false, 'public' => false], - DatabaseQueryProcessor::class => ['identifier' => 'headless-database-query', 'share' => false, 'public' => true], + DatabaseQueryProcessor::class => [ + 'identifier' => 'headless-database-query', + 'share' => false, + 'public' => true, + ], FlexFormProcessor::class => ['identifier' => 'headless-flex-form', 'share' => false, 'public' => false], ] as $class => $processorConfig ) { diff --git a/Configuration/SiteConfiguration/Overrides/site.php b/Configuration/SiteConfiguration/Overrides/site.php index e3f14f98..03bfb80e 100644 --- a/Configuration/SiteConfiguration/Overrides/site.php +++ b/Configuration/SiteConfiguration/Overrides/site.php @@ -7,7 +7,6 @@ * LICENSE.md file that was distributed with this source code. */ -use FriendsOfTYPO3\Headless\Utility\Headless; use FriendsOfTYPO3\Headless\Utility\HeadlessMode; use TYPO3\CMS\Core\Configuration\Features; use TYPO3\CMS\Core\Utility\GeneralUtility; diff --git a/README.md b/README.md index c75f03f0..d1738a28 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # TYPO3 Extension `headless` - JSON Content API for TYPO3 Headless solution +[![TYPO3 13](https://img.shields.io/badge/TYPO3-13-orange.svg)](https://get.typo3.org/version/13) [![TYPO3 12](https://img.shields.io/badge/TYPO3-12-orange.svg)](https://get.typo3.org/version/12) [![TYPO3 11](https://img.shields.io/badge/TYPO3-11-orange.svg)](https://get.typo3.org/version/11) -[![TYPO3 10](https://img.shields.io/badge/TYPO3-10-orange.svg)](https://get.typo3.org/version/10) [![CI Status](https://github.com/TYPO3-Initiatives/headless/workflows/CI/badge.svg)](https://github.com/TYPO3-Initiatives/headless/actions) [![Latest Stable Version](https://poser.pugx.org/friendsoftypo3/headless/v)](//packagist.org/packages/friendsoftypo3/headless) [![Total Downloads](https://poser.pugx.org/friendsoftypo3/headless/downloads)](//packagist.org/packages/friendsoftypo3/headless) @@ -37,7 +37,6 @@ If you have any questions just drop a line in #initiative-headless-pwa Slack cha - support for EXT:felogin - support for EXT:redirects - support for EXT:seo -- [BETA] backend module for simulating page preview (with specific page type, lang, usergroup) see [headless_dev_tools](https://github.com/TYPO3-Headless/headless_dev_tools) ### Additional extensions and integrations @@ -50,11 +49,11 @@ If you have any questions just drop a line in #initiative-headless-pwa Slack cha ## Requirements and compatibility -| EXT:headless version | TYPO3 support | PHP support | Status | -|-----------------------|--------------|-------------------|------------------------| -| `>= 4.0` | `12` | `>= 8.1` | Active development & support | -| `>= 3.0` | `11` | `>= 7.4, <= 8.2` | Active support | -| `>= 2.0` | `9`, `10` | `>= 7.2, <=7.4` | Critical bugfixes only | +| EXT:headless version | TYPO3 support | PHP support | Status | +|-------------------------|---------------|-------------------|-------------------------------| +| `>= 4.0` | `12`, `13` | `>= 8.1` | Active development & support | +| `>= 3.0` | `11` | `>= 7.4, <= 8.2` | Critical bugfixes only | +| `>= 2.0` | `9`, `10` | `>= 7.2, <=7.4` | Critical bugfixes only | ## Quickstart / Demo diff --git a/Tests/Functional/BaseTest.php b/Tests/Functional/BaseHeadlessTesting.php similarity index 95% rename from Tests/Functional/BaseTest.php rename to Tests/Functional/BaseHeadlessTesting.php index b07fbcb1..08e49125 100644 --- a/Tests/Functional/BaseTest.php +++ b/Tests/Functional/BaseHeadlessTesting.php @@ -18,7 +18,7 @@ use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; -abstract class BaseTest extends FunctionalTestCase +abstract class BaseHeadlessTesting extends FunctionalTestCase { protected array $coreExtensionsToLoad = [ 'install', @@ -34,7 +34,7 @@ public function setUp(): void { parent::setUp(); - $this->importDataSet(__DIR__ . '/Fixtures/pages.xml'); + $this->importCSVDataSet(__DIR__ . '/Fixtures/pages.csv'); $this->setUpFrontendRootPage( 1, @@ -129,4 +129,9 @@ protected function checkHeaderFieldsLink($contentElement, $link, $urlPrefix, $ta self::assertStringStartsWith($urlPrefix, $contentElementHeaderFieldsLink['href'], 'url mismatch'); self::assertEquals($target, $contentElementHeaderFieldsLink['target'], 'target mismatch'); } + + protected function importDataSet(string $string): void + { + // @TODO move data into CSV + } } diff --git a/Tests/Functional/ContentTypes/BaseContentTypeTest.php b/Tests/Functional/ContentTypes/BaseContentTypeTesting.php similarity index 95% rename from Tests/Functional/ContentTypes/BaseContentTypeTest.php rename to Tests/Functional/ContentTypes/BaseContentTypeTesting.php index ae4caa90..ee2df378 100644 --- a/Tests/Functional/ContentTypes/BaseContentTypeTest.php +++ b/Tests/Functional/ContentTypes/BaseContentTypeTesting.php @@ -11,9 +11,9 @@ namespace FriendsOfTYPO3\Headless\Tests\Functional\ContentTypes; -use FriendsOfTYPO3\Headless\Tests\Functional\BaseTest; +use FriendsOfTYPO3\Headless\Tests\Functional\BaseHeadlessTesting; -abstract class BaseContentTypeTest extends BaseTest +abstract class BaseContentTypeTesting extends BaseHeadlessTesting { /** * set up objects @@ -22,7 +22,7 @@ public function setUp(): void { parent::setUp(); - $this->importDataSet(__DIR__ . '/../Fixtures/content.xml'); + $this->importCSVDataSet(__DIR__ . '/../Fixtures/content.csv'); } protected function checkDefaultContentFields($contentElement, $id, $pid, $type, $colPos = 0, $categories = '') @@ -54,12 +54,12 @@ protected function checkHeaderFields($contentElement, $header = '', $subheader = self::assertTrue(isset($contentElementContent['headerLink']), 'headerLink not set'); } - protected function checkHeaderFieldsLink($contentElement, $linkText, $urlPrefix, $target) + protected function checkHeaderFieldsLink($contentElement, $link, $urlPrefix, $target) { $contentElementHeaderFieldsLink = $contentElement['content']['headerLink']; self::assertIsArray($contentElementHeaderFieldsLink, 'headerLink not an array'); - self::assertEquals($linkText, $contentElementHeaderFieldsLink['linkText'], 'linkText mismatch'); + self::assertEquals($link, $contentElementHeaderFieldsLink['linkText'], 'linkText mismatch'); self::assertStringStartsWith($urlPrefix, $contentElementHeaderFieldsLink['href'], 'url mismatch'); self::assertEquals($target, $contentElementHeaderFieldsLink['target'], 'target mismatch'); } diff --git a/Tests/Functional/ContentTypes/BasicListElementTest.php b/Tests/Functional/ContentTypes/BasicListElementTest.php index 162f0b4f..535ddfe1 100644 --- a/Tests/Functional/ContentTypes/BasicListElementTest.php +++ b/Tests/Functional/ContentTypes/BasicListElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class BasicListElementTest extends BaseContentTypeTest +class BasicListElementTest extends BaseContentTypeTesting { public function testBasicListContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/BulletsElementTest.php b/Tests/Functional/ContentTypes/BulletsElementTest.php index 98342110..ed3af242 100644 --- a/Tests/Functional/ContentTypes/BulletsElementTest.php +++ b/Tests/Functional/ContentTypes/BulletsElementTest.php @@ -13,13 +13,13 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class BulletsElementTest extends BaseContentTypeTest +class BulletsElementTest extends BaseContentTypeTesting { public function testBulletsContentElement() { $testBulletsContent = ['Top1', 'Top2', 'Top3']; - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/DefaultContentsTest.php b/Tests/Functional/ContentTypes/DefaultContentsTest.php index c4a8201a..c10a281e 100644 --- a/Tests/Functional/ContentTypes/DefaultContentsTest.php +++ b/Tests/Functional/ContentTypes/DefaultContentsTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class DefaultContentsTest extends BaseContentTypeTest +class DefaultContentsTest extends BaseContentTypeTesting { public function testContentStructure() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/DivElementTest.php b/Tests/Functional/ContentTypes/DivElementTest.php index 06b1094c..124355a5 100644 --- a/Tests/Functional/ContentTypes/DivElementTest.php +++ b/Tests/Functional/ContentTypes/DivElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class DivElementTest extends BaseContentTypeTest +class DivElementTest extends BaseContentTypeTesting { public function testDivContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/HeaderElementTest.php b/Tests/Functional/ContentTypes/HeaderElementTest.php index cf2bc75b..97ad857b 100644 --- a/Tests/Functional/ContentTypes/HeaderElementTest.php +++ b/Tests/Functional/ContentTypes/HeaderElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class HeaderElementTest extends BaseContentTypeTest +class HeaderElementTest extends BaseContentTypeTesting { public function testHeaderContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/HtmlElementTest.php b/Tests/Functional/ContentTypes/HtmlElementTest.php index 09c39b27..a6ca5be8 100644 --- a/Tests/Functional/ContentTypes/HtmlElementTest.php +++ b/Tests/Functional/ContentTypes/HtmlElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class HtmlElementTest extends BaseContentTypeTest +class HtmlElementTest extends BaseContentTypeTesting { public function testHtmlContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/ImageElementTest.php b/Tests/Functional/ContentTypes/ImageElementTest.php index bb2bcd7e..a799ac1a 100644 --- a/Tests/Functional/ContentTypes/ImageElementTest.php +++ b/Tests/Functional/ContentTypes/ImageElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class ImageElementTest extends BaseContentTypeTest +class ImageElementTest extends BaseContentTypeTesting { public function testImageContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/MenuAbstractPagesElementTest.php b/Tests/Functional/ContentTypes/MenuAbstractPagesElementTest.php index d2108350..797dfd4e 100644 --- a/Tests/Functional/ContentTypes/MenuAbstractPagesElementTest.php +++ b/Tests/Functional/ContentTypes/MenuAbstractPagesElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class MenuAbstractPagesElementTest extends BaseContentTypeTest +class MenuAbstractPagesElementTest extends BaseContentTypeTesting { public function testMenuContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/MenuCategorizedContentElementTest.php b/Tests/Functional/ContentTypes/MenuCategorizedContentElementTest.php index cac77ff5..1aac8129 100644 --- a/Tests/Functional/ContentTypes/MenuCategorizedContentElementTest.php +++ b/Tests/Functional/ContentTypes/MenuCategorizedContentElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class MenuCategorizedContentElementTest extends BaseContentTypeTest +class MenuCategorizedContentElementTest extends BaseContentTypeTesting { public function testMenuContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/MenuCategorizedPagesElementTest.php b/Tests/Functional/ContentTypes/MenuCategorizedPagesElementTest.php index d596983e..22c3c7d6 100644 --- a/Tests/Functional/ContentTypes/MenuCategorizedPagesElementTest.php +++ b/Tests/Functional/ContentTypes/MenuCategorizedPagesElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class MenuCategorizedPagesElementTest extends BaseContentTypeTest +class MenuCategorizedPagesElementTest extends BaseContentTypeTesting { public function testMenuContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/page1') ); diff --git a/Tests/Functional/ContentTypes/MenuPagesElementTest.php b/Tests/Functional/ContentTypes/MenuPagesElementTest.php index 463d6a78..5fcb33a0 100644 --- a/Tests/Functional/ContentTypes/MenuPagesElementTest.php +++ b/Tests/Functional/ContentTypes/MenuPagesElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class MenuPagesElementTest extends BaseContentTypeTest +class MenuPagesElementTest extends BaseContentTypeTesting { public function testMenuContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/MenuRecentlyUpdatedPagesElementTest.php b/Tests/Functional/ContentTypes/MenuRecentlyUpdatedPagesElementTest.php index 96d2d064..dad36e9b 100644 --- a/Tests/Functional/ContentTypes/MenuRecentlyUpdatedPagesElementTest.php +++ b/Tests/Functional/ContentTypes/MenuRecentlyUpdatedPagesElementTest.php @@ -16,7 +16,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class MenuRecentlyUpdatedPagesElementTest extends BaseContentTypeTest +class MenuRecentlyUpdatedPagesElementTest extends BaseContentTypeTesting { public function setUp(): void { @@ -26,14 +26,22 @@ public function setUp(): void $modifiedSevenDayAgo = (clone $currentDate)->modify('-7 day'); $modifiedEightDayAgo = (clone $currentDate)->modify('-8 day'); $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('pages'); - $connection->prepare('update pages set SYS_LASTCHANGED = ? WHERE uid = 2')->execute([$modifiedOneDayAgo->getTimestamp()]); - $connection->prepare('update pages set SYS_LASTCHANGED = ? WHERE uid = 3')->execute([$modifiedSevenDayAgo->getTimestamp()]); - $connection->prepare('update pages set SYS_LASTCHANGED = ? WHERE uid = 4')->execute([$modifiedEightDayAgo->getTimestamp()]); + $sql = $connection->prepare('update pages set SYS_LASTCHANGED = :change WHERE uid = 2'); + $sql->bindValue(':change', $modifiedOneDayAgo->getTimestamp()); + $sql->executeStatement(); + + $sql = $connection->prepare('update pages set SYS_LASTCHANGED = :change WHERE uid = 3'); + $sql->bindValue(':change', $modifiedSevenDayAgo->getTimestamp()); + $sql->executeStatement(); + + $sql = $connection->prepare('update pages set SYS_LASTCHANGED = :change WHERE uid = 4'); + $sql->bindValue(':change', $modifiedEightDayAgo->getTimestamp()); + $sql->executeStatement(); } public function testMenuContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/MenuRelatedPagesElementTest.php b/Tests/Functional/ContentTypes/MenuRelatedPagesElementTest.php index 8a68c30a..1b07c95d 100644 --- a/Tests/Functional/ContentTypes/MenuRelatedPagesElementTest.php +++ b/Tests/Functional/ContentTypes/MenuRelatedPagesElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class MenuRelatedPagesElementTest extends BaseContentTypeTest +class MenuRelatedPagesElementTest extends BaseContentTypeTesting { public function testMenuContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/MenuSectionElementTest.php b/Tests/Functional/ContentTypes/MenuSectionElementTest.php index d16fee55..569d1aec 100644 --- a/Tests/Functional/ContentTypes/MenuSectionElementTest.php +++ b/Tests/Functional/ContentTypes/MenuSectionElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class MenuSectionElementTest extends BaseContentTypeTest +class MenuSectionElementTest extends BaseContentTypeTesting { public function testMenuContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/MenuSitemapElementTest.php b/Tests/Functional/ContentTypes/MenuSitemapElementTest.php index dc791a86..54fe8d34 100644 --- a/Tests/Functional/ContentTypes/MenuSitemapElementTest.php +++ b/Tests/Functional/ContentTypes/MenuSitemapElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class MenuSitemapElementTest extends BaseContentTypeTest +class MenuSitemapElementTest extends BaseContentTypeTesting { public function testMenuContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/MenuSitemapSelectedPagesElementTest.php b/Tests/Functional/ContentTypes/MenuSitemapSelectedPagesElementTest.php index 965a3b5b..96800b47 100644 --- a/Tests/Functional/ContentTypes/MenuSitemapSelectedPagesElementTest.php +++ b/Tests/Functional/ContentTypes/MenuSitemapSelectedPagesElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class MenuSitemapSelectedPagesElementTest extends BaseContentTypeTest +class MenuSitemapSelectedPagesElementTest extends BaseContentTypeTesting { public function testMenuContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/page3') ); diff --git a/Tests/Functional/ContentTypes/MenuSubpagesElementTest.php b/Tests/Functional/ContentTypes/MenuSubpagesElementTest.php index bfd0993b..a0b2205e 100644 --- a/Tests/Functional/ContentTypes/MenuSubpagesElementTest.php +++ b/Tests/Functional/ContentTypes/MenuSubpagesElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class MenuSubpagesElementTest extends BaseContentTypeTest +class MenuSubpagesElementTest extends BaseContentTypeTesting { public function testMenuSubpagesContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/ShortcutElementTest.php b/Tests/Functional/ContentTypes/ShortcutElementTest.php index 1197f237..5331c14e 100644 --- a/Tests/Functional/ContentTypes/ShortcutElementTest.php +++ b/Tests/Functional/ContentTypes/ShortcutElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class ShortcutElementTest extends BaseContentTypeTest +class ShortcutElementTest extends BaseContentTypeTesting { public function testShortcutContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/TableElementTest.php b/Tests/Functional/ContentTypes/TableElementTest.php index dc527aa6..bc839dfb 100644 --- a/Tests/Functional/ContentTypes/TableElementTest.php +++ b/Tests/Functional/ContentTypes/TableElementTest.php @@ -13,13 +13,13 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class TableElementTest extends BaseContentTypeTest +class TableElementTest extends BaseContentTypeTesting { public function testTableContentElement() { $testTableContent = json_decode('[["Cell1.1","Cell1.2","Cell1.3","Cell1.4","",""],["Cell2.1","","","","",""],["Cell3.1","","","","",""],["\"","","","","",""]]', true); - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/TextElementTest.php b/Tests/Functional/ContentTypes/TextElementTest.php index 654072b2..9cfa3c34 100644 --- a/Tests/Functional/ContentTypes/TextElementTest.php +++ b/Tests/Functional/ContentTypes/TextElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class TextElementTest extends BaseContentTypeTest +class TextElementTest extends BaseContentTypeTesting { public function testTextContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/TextMediaElementTest.php b/Tests/Functional/ContentTypes/TextMediaElementTest.php index 8115c5d8..3ebdc69d 100644 --- a/Tests/Functional/ContentTypes/TextMediaElementTest.php +++ b/Tests/Functional/ContentTypes/TextMediaElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class TextMediaElementTest extends BaseContentTypeTest +class TextMediaElementTest extends BaseContentTypeTesting { public function testTextMediaContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/ContentTypes/TextpicElementTest.php b/Tests/Functional/ContentTypes/TextpicElementTest.php index 1e5010e5..2d807660 100644 --- a/Tests/Functional/ContentTypes/TextpicElementTest.php +++ b/Tests/Functional/ContentTypes/TextpicElementTest.php @@ -13,11 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class TextpicElementTest extends BaseContentTypeTest +class TextpicElementTest extends BaseContentTypeTesting { public function testTextpicContentElement() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/Fixtures/content.csv b/Tests/Functional/Fixtures/content.csv new file mode 100644 index 00000000..3013b371 --- /dev/null +++ b/Tests/Functional/Fixtures/content.csv @@ -0,0 +1,55 @@ +tt_content,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,uid,pid,sorting,colPos,CType,space_before_class,space_after_class,frame_class,layout,categories,header,subheader,header_layout,header_position,header_link,bodytext,list_type,table_caption,table_delimiter,table_enclosure,table_class,table_tfoot,table_header_position,cols,bullets_type,records,image,assets,pages,selected_categories,category_field +,1,1,1,0,text,SpaceBefore,SpaceAfter,Frame,1,1,Header,SubHeader,1,2,"t3://page?uid=2 _blank LinkClass LinkTitle parameter=999"," +

Link

+ ",,,,,,,,,,,,,,, +,3,1,2,0,header,SpaceBefore,SpaceAfter,Frame,1,1,Header,SubHeader,1,2,"t3://page?uid=2 _blank LinkClass LinkTitle parameter=999",,,,,,,,,,,,,,,, +,4,1,3,0,html,SpaceBefore,SpaceAfter,Frame,1,1,Header,SubHeader,1,2,"t3://page?uid=2 _blank LinkClass LinkTitle parameter=999","Link",,,,,,,,,,,,,,, +,5,1,4,0,div,SpaceBefore,SpaceAfter,Frame,1,1,Header,SubHeader,1,2,"t3://page?uid=2 _blank LinkClass LinkTitle parameter=999","Link",,,,,,,,,,,,,,, +,6,1,5,0,list,SpaceBefore,SpaceAfter,Frame,1,1,Header,SubHeader,1,2,"t3://page?uid=2 _blank LinkClass LinkTitle parameter=999","Link",BasicList,,,,,,,,,,,,,, +,7,1,6,0,table,SpaceBefore,SpaceAfter,Frame,1,1,Header,SubHeader,1,2,"t3://page?uid=2 _blank LinkClass LinkTitle parameter=999","""Cell1.1"";""Cell1.2"";""Cell1.3"";""Cell1.4"" +""Cell2.1"";"""";"""";"""" +""Cell3.1"";"""";"""";"""" +"""""""";"""";"""";""""",,TableCaption,59,34,striped,1,1,6,,,,,,, +,8,1,7,0,bullets,SpaceBefore,SpaceAfter,Frame,1,1,Header,SubHeader,1,2,"t3://page?uid=2 _blank LinkClass LinkTitle parameter=999","Top1 +Top2 +Top3",,,,,,,,,1,,,,,, +,9,1,8,0,shortcut,SpaceBefore,SpaceAfter,Frame,1,1,Header,SubHeader,1,2,"t3://page?uid=2 _blank LinkClass LinkTitle parameter=999",,,,,,,,,,,"pages_1,tt_content_2,tt_content_1",,,,, +,2,1,1,1,textmedia,,,default,,,,,,,,"Link",,,,,,,,,,,1,,,, +,10,1,1,1,image,,,default,,,,,,,,,,,,,,,,,,,,1,,, +,11,1,1,1,textpic,,,default,,,,,,,,"Link",,,,,,,,,,,1,,,, +,12,1,1,1,menu_subpages,SpaceBefore,SpaceAfter,default,,1,Header,SubHeader,0,2,,,,,,,,,,,,,,,,, +,13,1,1,1,menu_sitemap,SpaceBefore,SpaceAfter,default,,1,Header,SubHeader,0,2,,,,,,,,,,,,,,,"1,2,3",, +,14,1,1,1,menu_pages,SpaceBefore,SpaceAfter,default,,1,Header,SubHeader,0,2,,,,,,,,,,,,,,,"1,2,3,4",, +,15,1,1,1,menu_section,SpaceBefore,SpaceAfter,default,,1,Header,SubHeader,0,2,,,,,,,,,,,,,,,"1,4",, +,16,1,1,1,menu_recently_updated,SpaceBefore,SpaceAfter,default,,1,Header,SubHeader,0,2,,,,,,,,,,,,,,,1,, +,17,1,1,1,header,,,default,,3,,,,,,,,,,,,,,,,,,,,, +,18,1,1,1,textpic,,,default,,3,,,,,,,,,,,,,,,,,,,,, +,19,1,1,1,menu_categorized_content,SpaceBefore,SpaceAfter,default,,3,Header,SubHeader,0,2,,,,,,,,,,,,,,,,3,categories +,20,2,1,1,menu_categorized_pages,SpaceBefore,SpaceAfter,default,,1,Header,SubHeader,0,2,,,,,,,,,,,,,,,,3,categories +,21,5,1,1,menu_sitemap_pages,SpaceBefore,SpaceAfter,default,,1,Header,SubHeader,0,2,,,,,,,,,,,,,,,5,, +,22,1,1,1,menu_related_pages,SpaceBefore,SpaceAfter,default,,1,Header,SubHeader,0,2,,,,,,,,,,,,,,,,, +,23,1,1,1,menu_abstract,SpaceBefore,SpaceAfter,default,,1,Header,SubHeader,0,2,,,,,,,,,,,,,,,5,, +sys_category,,, +,uid,pid,title +,1,0,SysCategory1Title +,2,0,SysCategory2Title +,3,0,SysCategory3Title +sys_category_record_mm,,,,,, +,tablenames,uid_foreign,uid_local,fieldname,sorting,sorting_foreign +,tt_content,1,1,categories,, +,tt_content,1,2,categories,, +,pages,5,3,categories,, +,tt_content,17,3,categories,1,0 +,tt_content,18,3,categories,1,0 +sys_file,,,,,,,,,,,,,, +,uid,pid,storage,type,identifier,identifier_hash,folder_hash,extension,mime_type,name,sha1,size,creation_date,modification_date +,1,0,0,1,/typo3conf/ext/headless/ext_icon.gif,ae03df120da87352822f4aae6d476086cb8c0cf8,85051482e1ba204348a9b9f6c1a37069e77de027,gif,image/gif,ext_icon.gif,4a53ba5b5a156b82e3efd443f9a402f8c6e6dd08,177,1400176659,1400176659 +sys_file_metadata,,,,,, +,uid,pid,file,title,width,height +,1,0,1,MetadataTitle,18,16 +sys_file_reference,,,,,,, +,uid,pid,uid_local,uid_foreign,tablenames,fieldname,autoplay +,1,1,1,2,tt_content,assets,1 +,2,1,1,10,tt_content,image,1 +,3,1,1,11,tt_content,image,1 diff --git a/Tests/Functional/Fixtures/content.xml b/Tests/Functional/Fixtures/content.xml deleted file mode 100644 index 3ada8520..00000000 --- a/Tests/Functional/Fixtures/content.xml +++ /dev/null @@ -1,455 +0,0 @@ - - - - 1 - 1 - 1 - 0 - text - SpaceBefore - SpaceAfter - Frame - 1 - 1 -
Header
- SubHeader - 1 - 2 - t3://page?uid=2 _blank LinkClass LinkTitle parameter=999 - Link

- ]]>
-
- - 3 - 1 - 2 - 0 - header - SpaceBefore - SpaceAfter - Frame - 1 - 1 -
Header
- SubHeader - 1 - 2 - t3://page?uid=2 _blank LinkClass LinkTitle parameter=999 -
- - 4 - 1 - 3 - 0 - html - SpaceBefore - SpaceAfter - Frame - 1 - 1 -
Header
- SubHeader - 1 - 2 - t3://page?uid=2 _blank LinkClass LinkTitle parameter=999 - Link]]> -
- - 5 - 1 - 4 - 0 - div - SpaceBefore - SpaceAfter - Frame - 1 - 1 -
Header
- SubHeader - 1 - 2 - t3://page?uid=2 _blank LinkClass LinkTitle parameter=999 - Link]]> -
- - 6 - 1 - 5 - 0 - list - BasicList - SpaceBefore - SpaceAfter - Frame - 1 - 1 -
Header
- SubHeader - 1 - 2 - t3://page?uid=2 _blank LinkClass LinkTitle parameter=999 - Link]]> -
- - 7 - 1 - 6 - 0 - table - SpaceBefore - SpaceAfter - Frame - 1 - 1 -
Header
- SubHeader - 1 - 2 - t3://page?uid=2 _blank LinkClass LinkTitle parameter=999 - TableCaption - 59 - 34 - striped - 1 - 1 - 6 - -
- - 8 - 1 - 7 - 0 - bullets - SpaceBefore - SpaceAfter - Frame - 1 - 1 -
Header
- SubHeader - 1 - 2 - t3://page?uid=2 _blank LinkClass LinkTitle parameter=999 - 1 - -
- - 9 - 1 - 8 - 0 - shortcut - SpaceBefore - SpaceAfter - Frame - 1 - 1 -
Header
- SubHeader - 1 - 2 - t3://page?uid=2 _blank LinkClass LinkTitle parameter=999 - pages_1,tt_content_2,tt_content_1 -
- - 2 - 1 - 1 - 1 - textmedia - 1 - Link]]> - - - 10 - 1 - 1 - 1 - image - 1 - - - 11 - 1 - 1 - 1 - textpic - 1 - Link]]> - - - 12 - 1 - 1 - 1 - menu_subpages - SpaceBefore - SpaceAfter - 1 -
Header
- SubHeader - 0 - 2 -
- - 13 - 1 - 1 - 1 - menu_sitemap - SpaceBefore - SpaceAfter - 1 -
Header
- SubHeader - 0 - 2 - 1,2,3 -
- - 14 - 1 - 1 - 1 - menu_pages - SpaceBefore - SpaceAfter - 1 -
Header
- SubHeader - 0 - 2 - 1,2,3,4 -
- - 15 - 1 - 1 - 1 - menu_section - SpaceBefore - SpaceAfter - 1 -
Header
- SubHeader - 0 - 2 - 1,4 -
- - 16 - 1 - 1 - 1 - menu_recently_updated - SpaceBefore - SpaceAfter - 1 -
Header
- SubHeader - 0 - 2 - 1 -
- - 17 - 1 - 1 - 1 - header - 3 - - - 18 - 1 - 1 - 1 - textpic - 3 - - - 19 - 1 - 1 - 1 - menu_categorized_content - 3 - 3 - categories - SpaceBefore - SpaceAfter -
Header
- SubHeader - 0 - 2 -
- - 20 - 2 - 1 - 1 - menu_categorized_pages - SpaceBefore - SpaceAfter - 1 - 3 - categories -
Header
- SubHeader - 0 - 2 -
- - 21 - 5 - 1 - 1 - menu_sitemap_pages - SpaceBefore - SpaceAfter - 1 -
Header
- SubHeader - 0 - 2 - 5 -
- - 22 - 1 - 1 - 1 - menu_related_pages - SpaceBefore - SpaceAfter - 1 -
Header
- SubHeader - 0 - 2 -
- - 23 - 1 - 1 - 1 - menu_abstract - SpaceBefore - SpaceAfter - 1 -
Header
- SubHeader - 0 - 2 - 5 -
- - 1 - 0 - SysCategory1Title - - - 2 - 0 - SysCategory2Title - - - 3 - 0 - SysCategory3Title - - - tt_content - 1 - 1 - categories - - - tt_content - 1 - 2 - categories - - - pages - 5 - 3 - categories - - - tt_content - 17 - 3 - categories - 1 - 0 - - - tt_content - 18 - 3 - categories - 1 - 0 - - - 1 - 0 - 0 - 1 - /typo3conf/ext/headless/ext_icon.gif - ae03df120da87352822f4aae6d476086cb8c0cf8 - 85051482e1ba204348a9b9f6c1a37069e77de027 - gif - image/gif - ext_icon.gif - 4a53ba5b5a156b82e3efd443f9a402f8c6e6dd08 - 177 - 1400176659 - 1400176659 - - - 1 - 0 - 1 - MetadataTitle - 18 - 16 - - - 1 - 1 - 1 - 2 - tt_content - assets - 1 - - - 2 - 1 - 1 - 10 - tt_content - image - 1 - - - 3 - 1 - 1 - 11 - tt_content - image - 1 - - -
\ No newline at end of file diff --git a/Tests/Functional/Fixtures/pages.csv b/Tests/Functional/Fixtures/pages.csv new file mode 100644 index 00000000..3eaa70e2 --- /dev/null +++ b/Tests/Functional/Fixtures/pages.csv @@ -0,0 +1,12 @@ +"pages",,,,,,,, +,uid,pid,title,slug,deleted,perms_everybody,keywords,abstract +,1,0,"Root","/",0,15,"test", +,2,1,"Page 1","/page1",0,15,, +,3,2,"Page 1.1","/page1/page1_1",0,15,, +,4,1,"Page 2","/page2",0,15,, +,5,1,"Page 3","/page3",0,15,,"Test" +,6,5,"Page 4","/page4",0,15,,"Test" +,7,6,"Page 5","/page5",0,15,,, +,8,1,"Page 8","/page8",0,15,"test",, +,9,1,"Page 9","/page9",0,15,"test",, +,10,9,"Page 10","/page10",0,15,"test",, diff --git a/Tests/Functional/Fixtures/pages.xml b/Tests/Functional/Fixtures/pages.xml deleted file mode 100644 index 92d914b3..00000000 --- a/Tests/Functional/Fixtures/pages.xml +++ /dev/null @@ -1,89 +0,0 @@ - - - - 1 - 0 - Root - / - 0 - 15 - test - - - 2 - 1 - Page 1 - /page1 - 0 - 15 - - - 3 - 2 - Page 1.1 - /page1/page1_1 - 0 - 15 - - - 4 - 1 - Page 2 - /page2 - 0 - 15 - - - 5 - 1 - Page 3 - /page3 - 0 - Test - 15 - - - 6 - 5 - Page 4 - /page4 - 0 - Test - 15 - - - 7 - 6 - Page 5 - /page5 - 0 - 15 - - - 8 - 1 - Page 8 - /page8 - 0 - 15 - test - - - 9 - 1 - Page 9 - /page9 - 0 - 15 - test - - - 10 - 9 - Page 10 - /page10 - 0 - 15 - test - - \ No newline at end of file diff --git a/Tests/Functional/PageTypes/BasePageTypesTest.php b/Tests/Functional/PageTypes/BasePageTypesHeadlessTesting.php similarity index 92% rename from Tests/Functional/PageTypes/BasePageTypesTest.php rename to Tests/Functional/PageTypes/BasePageTypesHeadlessTesting.php index fb426ba2..21a0608a 100644 --- a/Tests/Functional/PageTypes/BasePageTypesTest.php +++ b/Tests/Functional/PageTypes/BasePageTypesHeadlessTesting.php @@ -11,13 +11,13 @@ namespace FriendsOfTYPO3\Headless\Tests\Functional\PageTypes; -use FriendsOfTYPO3\Headless\Tests\Functional\BaseTest; +use FriendsOfTYPO3\Headless\Tests\Functional\BaseHeadlessTesting; use JsonSchema\SchemaStorage; use JsonSchema\Uri\UriRetriever; use JsonSchema\Validator; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; -abstract class BasePageTypesTest extends BaseTest +abstract class BasePageTypesHeadlessTesting extends BaseHeadlessTesting { /** * @param string $jsonString diff --git a/Tests/Functional/PageTypes/SchemaPageTypesTest.php b/Tests/Functional/PageTypes/SchemaPageTypesTest.php index 8ec042fa..ddb003db 100644 --- a/Tests/Functional/PageTypes/SchemaPageTypesTest.php +++ b/Tests/Functional/PageTypes/SchemaPageTypesTest.php @@ -13,26 +13,20 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class SchemaPageTypesTest extends BasePageTypesTest +class SchemaPageTypesTest extends BasePageTypesHeadlessTesting { - /** - * @test - */ - public function getMenu() + public function testGetMenu() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/?type=834') ); self::assertEquals(200, $response->getStatusCode()); } - /** - * @test - */ - public function getPage() + public function testGetPage() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/') ); diff --git a/Tests/Functional/PageTypes/StructurePageTypesTest.php b/Tests/Functional/PageTypes/StructurePageTypesTest.php index aee84608..c33eeb8f 100644 --- a/Tests/Functional/PageTypes/StructurePageTypesTest.php +++ b/Tests/Functional/PageTypes/StructurePageTypesTest.php @@ -13,14 +13,11 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; -class StructurePageTypesTest extends BasePageTypesTest +class StructurePageTypesTest extends BasePageTypesHeadlessTesting { - /** - * @test - */ - public function getMenuStructure() + public function testGetMenuStructure() { - $response = $this->executeFrontendRequest( + $response = $this->executeFrontendSubRequest( new InternalRequest('https://website.local/?type=834') ); diff --git a/Tests/Functional/phpunit.xml b/Tests/Functional/phpunit.xml index 71c525ec..5502063c 100644 --- a/Tests/Functional/phpunit.xml +++ b/Tests/Functional/phpunit.xml @@ -1,24 +1,18 @@ - - - - ../../Classes - - ./ @@ -29,4 +23,9 @@ + + + ../../Classes + + diff --git a/Tests/Unit/ContentObject/BooleanContentObjectTest.php b/Tests/Unit/ContentObject/BooleanContentObjectTest.php index 76f1e289..5bd49414 100644 --- a/Tests/Unit/ContentObject/BooleanContentObjectTest.php +++ b/Tests/Unit/ContentObject/BooleanContentObjectTest.php @@ -12,6 +12,7 @@ namespace FriendsOfTYPO3\Headless\Tests\Unit\ContentObject; use FriendsOfTYPO3\Headless\ContentObject\BooleanContentObject; +use PHPUnit\Framework\Attributes\DataProvider; use Prophecy\PhpUnit\ProphecyTrait; use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; @@ -21,10 +22,7 @@ class BooleanContentObjectTest extends UnitTestCase { use ProphecyTrait; - /** - * @test - */ - public function renderTest() + public function testRender() { $cObj = $this->createMock(ContentObjectRenderer::class); $cObj->setRequest(new ServerRequest()); @@ -36,11 +34,8 @@ public function renderTest() self::assertFalse($contentObject->render()); } - /** - * @test - * @dataProvider dataProvider - */ - public function renderWithProviderTest($argument, bool $result) + #[DataProvider('dataProvider')] + public function testRenderWithProvider($argument, bool $result): void { $cObj = $this->createMock(ContentObjectRenderer::class); $cObj->setRequest(new ServerRequest()); @@ -50,7 +45,7 @@ public function renderWithProviderTest($argument, bool $result) self::assertEquals($result, $contentObject->render($argument)); } - public function dataProvider(): array + public static function dataProvider(): array { return [ ['test', false], diff --git a/Tests/Unit/ContentObject/FloatContentObjectTest.php b/Tests/Unit/ContentObject/FloatContentObjectTest.php index 9ffb9891..52b30af2 100644 --- a/Tests/Unit/ContentObject/FloatContentObjectTest.php +++ b/Tests/Unit/ContentObject/FloatContentObjectTest.php @@ -12,16 +12,16 @@ namespace FriendsOfTYPO3\Headless\Tests\Unit\ContentObject; use FriendsOfTYPO3\Headless\ContentObject\FloatContentObject; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; class FloatContentObjectTest extends UnitTestCase { - /** - * @test - */ - public function renderTest() + #[Test] + public function render(): void { $cObj = $this->createMock(ContentObjectRenderer::class); $cObj->setRequest(new ServerRequest()); @@ -32,11 +32,8 @@ public function renderTest() self::assertEquals(0.0, $contentObject->render()); } - /** - * @test - * @dataProvider dataProvider - */ - public function renderWithProviderTest($argument, float $result) + #[Test,DataProvider('dataProvider')] + public function renderWithProvider($argument, float $result): void { $cObj = $this->createMock(ContentObjectRenderer::class); $cObj->setRequest(new ServerRequest()); @@ -47,7 +44,7 @@ public function renderWithProviderTest($argument, float $result) self::assertEquals($result, $contentObject->render($argument)); } - public function dataProvider(): array + public static function dataProvider(): array { return [ ['test', 0.0], diff --git a/Tests/Unit/ContentObject/IntegerContentObjectTest.php b/Tests/Unit/ContentObject/IntegerContentObjectTest.php index 4abbbee8..f84e2d5e 100644 --- a/Tests/Unit/ContentObject/IntegerContentObjectTest.php +++ b/Tests/Unit/ContentObject/IntegerContentObjectTest.php @@ -12,6 +12,8 @@ namespace FriendsOfTYPO3\Headless\Tests\Unit\ContentObject; use FriendsOfTYPO3\Headless\ContentObject\IntegerContentObject; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use Prophecy\PhpUnit\ProphecyTrait; use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; @@ -21,10 +23,8 @@ class IntegerContentObjectTest extends UnitTestCase { use ProphecyTrait; - /** - * @test - */ - public function renderTest() + #[Test] + public function render(): void { $cObj = $this->createMock(ContentObjectRenderer::class); $cObj->setRequest(new ServerRequest()); @@ -35,11 +35,8 @@ public function renderTest() self::assertEquals(0, $contentObject->render()); } - /** - * @test - * @dataProvider dataProvider - */ - public function renderWithProviderTest($argument, int $result) + #[Test, DataProvider('dataProvider')] + public function renderWithProvider($argument, int $result): void { $cObj = $this->createMock(ContentObjectRenderer::class); $cObj->setRequest(new ServerRequest()); @@ -50,7 +47,7 @@ public function renderWithProviderTest($argument, int $result) self::assertEquals($result, $contentObject->render($argument)); } - public function dataProvider(): array + public static function dataProvider(): array { return [ ['test', 0], diff --git a/Tests/Unit/ContentObject/JsonContentObjectTest.php b/Tests/Unit/ContentObject/JsonContentObjectTest.php index 0d8addb9..dd041fc7 100644 --- a/Tests/Unit/ContentObject/JsonContentObjectTest.php +++ b/Tests/Unit/ContentObject/JsonContentObjectTest.php @@ -16,10 +16,14 @@ use FriendsOfTYPO3\Headless\ContentObject\IntegerContentObject; use FriendsOfTYPO3\Headless\ContentObject\JsonContentContentObject; use FriendsOfTYPO3\Headless\ContentObject\JsonContentObject; +use PHPUnit\Framework\Attributes\DataProvider; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; +use Psr\EventDispatcher\EventDispatcherInterface; use stdClass; use Symfony\Component\DependencyInjection\Container; +use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface; +use TYPO3\CMS\Core\EventDispatcher\EventDispatcher; use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Core\Service\MarkerBasedTemplateService; use TYPO3\CMS\Core\TimeTracker\TimeTracker; @@ -86,6 +90,18 @@ protected function setUp(): void 'BOOL' => BooleanContentObject::class, ]; + $container = new Container(); + + $eventDispatcher = $this->prophesize(EventDispatcher::class); + $eventDispatcher->dispatch(Argument::any())->willReturnArgument(); + + $container->set(MarkerBasedTemplateService::class, new MarkerBasedTemplateService($this->prophesize(FrontendInterface::class)->reveal(), $this->prophesize(FrontendInterface::class)->reveal())); + $container->set(TimeTracker::class, new TimeTracker(false)); + $container->set(EventDispatcherInterface::class, $eventDispatcher->reveal()); + $container->set(RecordsContentObject::class, new RecordsContentObject($container->get(TimeTracker::class))); + $container->set(ContentContentObject::class, new ContentContentObject($container->get(TimeTracker::class), $container->get(EventDispatcherInterface::class))); + GeneralUtility::setContainer($container); + $request = new ServerRequest(); $contentObjectRenderer = GeneralUtility::makeInstance(ContentObjectRenderer::class); $contentObjectRenderer->setRequest($request); @@ -101,7 +117,7 @@ protected function setUp(): void return $obj; }); - $container = new Container(); + $container = GeneralUtility::getContainer(); $container->set(ContentObjectFactory::class, $factory->reveal()); GeneralUtility::setContainer($container); @@ -113,9 +129,7 @@ protected function setUp(): void } GeneralUtility::makeInstance(JsonContentObject::class, $contentDataProcessor); - GeneralUtility::makeInstance(ImageContentObject::class, $this->prophesize(MarkerBasedTemplateService::class)->reveal()); - - GeneralUtility::makeInstance(TimeTracker::class, false); + // GeneralUtility::makeInstance(ImageContentObject::class, $this->prophesize(MarkerBasedTemplateService::class)->reveal()); $tsfe = $this->prophesize(TypoScriptFrontendController::class); $tsfe->uniqueHash()->willReturn(md5('123')); @@ -127,24 +141,18 @@ protected function setUp(): void $this->contentObject->setContentObjectRenderer($contentObjectRenderer); } - /** - * @test - */ - public function renderTest() + public function testRender() { self::assertEquals('[]', $this->contentObject->render()); } - /** - * @test - * @dataProvider dataProvider - */ - public function renderWithProviderTest($argument, $result) + #[DataProvider('dataProvider')] + public function testRenderWithProvider($argument, $result) { self::assertEquals($result, $this->contentObject->render($argument)); } - public function dataProvider(): array + public static function dataProvider(): array { return [ [[], '[]'], diff --git a/Tests/Unit/DataProcessing/DataProcessingTraitTest.php b/Tests/Unit/DataProcessing/DataProcessingTraitTest.php index c41b0750..e703f63a 100644 --- a/Tests/Unit/DataProcessing/DataProcessingTraitTest.php +++ b/Tests/Unit/DataProcessing/DataProcessingTraitTest.php @@ -12,15 +12,13 @@ namespace FriendsOfTYPO3\Headless\Tests\Unit\DataProcessing; use FriendsOfTYPO3\Headless\DataProcessing\DataProcessingTrait; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; class DataProcessingTraitTest extends TestCase { - /** - * @test - * @dataProvider dataProvider - */ - public function removeDataIfnotAppendInConfigurationTest( + #[DataProvider('dataProvider')] + public function testRemoveDataIfnotAppendInConfiguration( $expected, array $processorConfiguration, array $processedData @@ -37,10 +35,7 @@ public function removeDataIfnotAppendInConfigurationTest( ); } - /** - * @test - */ - public function removeDataIfnotAppendInConfigurationAsMenuProcessorTest() + public function testRemoveDataIfnotAppendInConfigurationAsMenuProcessor() { $trait = new class () { use DataProcessingTrait { @@ -96,7 +91,7 @@ public function isMenuProcessor() )); } - public function dataProvider(): array + public static function dataProvider(): array { return [ [ diff --git a/Tests/Unit/DataProcessing/DatabaseQueryProcessorTest.php b/Tests/Unit/DataProcessing/DatabaseQueryProcessorTest.php index ef93d28e..65d1a8bb 100644 --- a/Tests/Unit/DataProcessing/DatabaseQueryProcessorTest.php +++ b/Tests/Unit/DataProcessing/DatabaseQueryProcessorTest.php @@ -61,10 +61,7 @@ protected function setUp(): void parent::setUp(); } - /** - * @test - */ - public function returnEarlyDueToIfStatementReturnsFalse(): void + public function testReturnEarlyDueToIfStatementReturnsFalse(): void { $processorConfiguration = [ 'if.' => [ @@ -77,10 +74,7 @@ public function returnEarlyDueToIfStatementReturnsFalse(): void self::assertEquals($processedData, $this->subject->process($this->contentObjectRenderer->reveal(), [], $processorConfiguration, $processedData)); } - /** - * @test - */ - public function returnEarlyNoTableIsGiven(): void + public function testReturnEarlyNoTableIsGiven(): void { $processorConfiguration = [ 'if.' => [ @@ -93,10 +87,7 @@ public function returnEarlyNoTableIsGiven(): void self::assertEquals($processedData, $this->subject->process($this->contentObjectRenderer->reveal(), [], $processorConfiguration, $processedData)); } - /** - * @test - */ - public function processWithoutAdditionalFields(): void + public function testProcessWithoutAdditionalFields(): void { $processorConfiguration = [ 'table' => 'tt_content', @@ -131,10 +122,7 @@ public function processWithoutAdditionalFields(): void self::assertEquals($processedData, $this->subject->process($this->contentObjectRenderer->reveal(), [], $processorConfiguration, $processedData)); } - /** - * @test - */ - public function processWithAdditionalFields(): void + public function testProcessWithAdditionalFields(): void { $processorConfiguration = [ 'table' => 'tt_content', diff --git a/Tests/Unit/DataProcessing/RootSiteProcessing/DomainSchemaTest.php b/Tests/Unit/DataProcessing/RootSiteProcessing/DomainSchemaTest.php index c9cd1751..f7db61da 100644 --- a/Tests/Unit/DataProcessing/RootSiteProcessing/DomainSchemaTest.php +++ b/Tests/Unit/DataProcessing/RootSiteProcessing/DomainSchemaTest.php @@ -33,10 +33,7 @@ class DomainSchemaTest extends UnitTestCase { use ProphecyTrait; - /** - * @test - */ - public function processTest() + public function testProcess(): void { $testUri = new Uri('https://test.domain.tld'); $cObj = $this->prophesize(ContentObjectRenderer::class); @@ -133,17 +130,20 @@ protected function getUrlUtility($site = null): UrlUtility $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::any())->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); + $mock = $this->createPartialMock(SiteFinder::class, ['getSiteByPageId']); + $mock->method('getSiteByPageId')->willReturn($site); if ($site === null) { $site = $this->getSiteWithBase($uri); } - $siteFinder->getSiteByPageId(Argument::is(1))->willReturn($site); + $mock->method('getSiteByPageId')->willReturn($site); + + //$siteFinder->getSiteByPageId(Argument::is(1))->willReturn($site); $dummyRequest = (new ServerRequest())->withAttribute('site', $site); $dummyRequest = $dummyRequest->withAttribute('headless', new Headless()); - return new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), $dummyRequest, (new HeadlessMode())->withRequest($dummyRequest)); + return new UrlUtility(null, $resolver->reveal(), $mock, $dummyRequest, (new HeadlessMode())->withRequest($dummyRequest)); } protected function getSiteWithBase(UriInterface $uri, $withLanguage = null) diff --git a/Tests/Unit/DataProcessing/RootSitesProcessorTest.php b/Tests/Unit/DataProcessing/RootSitesProcessorTest.php index 8e488dd1..dd657c33 100644 --- a/Tests/Unit/DataProcessing/RootSitesProcessorTest.php +++ b/Tests/Unit/DataProcessing/RootSitesProcessorTest.php @@ -33,10 +33,7 @@ protected function setUp(): void parent::setUp(); } - /** - * @test - */ - public function customImplementation(): void + public function testCustomImplementation(): void { $processor = new RootSitesProcessor(); @@ -72,10 +69,7 @@ public function customImplementation(): void ], $processor->process($contentObjectRenderer, [], $conf, [])); } - /** - * @test - */ - public function objectNotSet() + public function testObjectNotSet() { $processor = new RootSitesProcessor(); @@ -87,10 +81,7 @@ public function objectNotSet() self::assertEquals([], $processor->process($contentObjectRenderer, [], $conf, [])); } - /** - * @test - */ - public function featureEnabledButWrongSiteProvider(): void + public function testFeatureEnabledButWrongSiteProvider(): void { $processor = new RootSitesProcessor(); @@ -104,10 +95,7 @@ public function featureEnabledButWrongSiteProvider(): void self::assertEquals([], $processor->process($contentObjectRenderer, [], $conf, [])); } - /** - * @test - */ - public function featureEnabledButWrongSiteSchema(): void + public function testFeatureEnabledButWrongSiteSchema(): void { $processor = new RootSitesProcessor(); diff --git a/Tests/Unit/Event/Listener/AfterCacheableContentIsGeneratedListenerTest.php b/Tests/Unit/Event/Listener/AfterCacheableContentIsGeneratedListenerTest.php index 55cb0f80..3c8579d4 100644 --- a/Tests/Unit/Event/Listener/AfterCacheableContentIsGeneratedListenerTest.php +++ b/Tests/Unit/Event/Listener/AfterCacheableContentIsGeneratedListenerTest.php @@ -84,7 +84,7 @@ public function testNotModifiedWhileValidJson(): void $controller = $this->prophesize(TypoScriptFrontendController::class); $controller->content = $content; - $controller->generatePageTitle()->willReturn('Modified title via PageTitleManager'); + $controller->generatePageTitle($request)->willReturn('Modified title via PageTitleManager'); $event = new AfterCacheableContentIsGeneratedEvent($request->reveal(), $controller->reveal(), 'abc', false); @@ -106,7 +106,7 @@ public function testNotModifiedWhenUserIntContent(): void $controller = $this->prophesize(TypoScriptFrontendController::class); $controller->content = $content; - $controller->generatePageTitle()->willReturn('Modified title via PageTitleManager'); + $controller->generatePageTitle($request)->willReturn('Modified title via PageTitleManager'); $event = new AfterCacheableContentIsGeneratedEvent($request->reveal(), $controller->reveal(), 'abc', false); @@ -131,7 +131,7 @@ public function testModifiedPageTitle(): void $controller = $this->prophesize(TypoScriptFrontendController::class); $controller->content = json_encode(['meta' => ['title' => 'test before event'], 'seo' => ['title' => 'test before event']]); $controller->cObj = $this->prophesize(ContentObjectRenderer::class)->reveal(); - $controller->generatePageTitle()->willReturn('Modified title via PageTitleProviderManager'); + $controller->generatePageTitle($request)->willReturn('Modified title via PageTitleProviderManager'); $event = new AfterCacheableContentIsGeneratedEvent($request->reveal(), $controller->reveal(), 'abc', false); @@ -162,7 +162,7 @@ public function testHreflangs(): void $controller = $this->prophesize(TypoScriptFrontendController::class); $controller->content = json_encode(['meta' => ['title' => 'test before event'], 'seo' => ['title' => 'test before event']]); $controller->cObj = $this->prophesize(ContentObjectRenderer::class)->reveal(); - $controller->generatePageTitle()->willReturn('Modified title via PageTitleProviderManager'); + $controller->generatePageTitle($request)->willReturn('Modified title via PageTitleProviderManager'); $registry = GeneralUtility::makeInstance(MetaTagManagerRegistry::class); $registry->registerManager('html5', Html5MetaTagManager::class); diff --git a/Tests/Unit/Event/Listener/AfterLinkIsGeneratedListenerTest.php b/Tests/Unit/Event/Listener/AfterLinkIsGeneratedListenerTest.php index f5397f48..5f7b4d51 100644 --- a/Tests/Unit/Event/Listener/AfterLinkIsGeneratedListenerTest.php +++ b/Tests/Unit/Event/Listener/AfterLinkIsGeneratedListenerTest.php @@ -13,6 +13,7 @@ use FriendsOfTYPO3\Headless\Utility\UrlUtility; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; +use Psr\EventDispatcher\EventDispatcherInterface; use TYPO3\CMS\Core\ExpressionLanguage\Resolver; use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Core\LinkHandling\LinkService; @@ -33,14 +34,14 @@ public function test__construct() { $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::any())->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createPartialMock(SiteFinder::class, []); $listener = new AfterLinkIsGeneratedListener( $this->prophesize(Logger::class)->reveal(), - new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal()), + new UrlUtility(null, $resolver->reveal(), $siteFinder), $this->prophesize(LinkService::class)->reveal(), - new TypoLinkCodecService(), - $this->prophesize(SiteFinder::class)->reveal() + new TypoLinkCodecService($this->prophesize(EventDispatcherInterface::class)->reveal()), + $siteFinder ); self::assertInstanceOf(AfterLinkIsGeneratedListener::class, $listener); @@ -50,14 +51,14 @@ public function test__invokeNotModifingAnything() { $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::any())->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createMock(SiteFinder::class); $listener = new AfterLinkIsGeneratedListener( $this->prophesize(Logger::class)->reveal(), - new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal()), + new UrlUtility(null, $resolver->reveal(), $siteFinder), $this->prophesize(LinkService::class)->reveal(), - new TypoLinkCodecService(), - $this->prophesize(SiteFinder::class)->reveal() + new TypoLinkCodecService($this->prophesize(EventDispatcherInterface::class)->reveal()), + $siteFinder ); $site = new Site('test', 1, []); @@ -109,8 +110,8 @@ public function test__invokeModifingFromPageUid() $this->prophesize(Logger::class)->reveal(), $urlUtility->reveal(), $this->prophesize(LinkService::class)->reveal(), - new TypoLinkCodecService(), - $this->prophesize(SiteFinder::class)->reveal() + new TypoLinkCodecService($this->prophesize(EventDispatcherInterface::class)->reveal()), + $this->createMock(SiteFinder::class) ); $linkResult = new LinkResult('page', '/'); @@ -146,8 +147,8 @@ public function test__invokeModifingExternalSite() $this->prophesize(Logger::class)->reveal(), $urlUtility->reveal(), $linkService->reveal(), - new TypoLinkCodecService(), - $this->prophesize(SiteFinder::class)->reveal() + new TypoLinkCodecService($this->prophesize(EventDispatcherInterface::class)->reveal()), + $this->createMock(SiteFinder::class) ); $linkResult = new LinkResult('page', '/'); $linkResult = $linkResult->withLinkConfiguration(['parameter.' => ['data' => 'parameters:href']]); @@ -181,17 +182,20 @@ public function test__SitemapLink() $request = (new ServerRequest())->withAttribute('site', $site); $cObj->getRequest()->willReturn($request); - $siteFinder = $this->prophesize(SiteFinder::class); - $siteFinder->getSiteByPageId(Argument::any())->willReturn($site); + $siteFinder = $this->createPartialMock(SiteFinder::class, ['getSiteByPageId']); + $siteFinder->method('getSiteByPageId')->willReturn($site); $urlUtility->withRequest($request)->willReturn($urlUtility->reveal()); + $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); + $eventDispatcher->dispatch(Argument::any())->willReturnArgument(); + $listener = new AfterLinkIsGeneratedListener( $this->prophesize(Logger::class)->reveal(), $urlUtility->reveal(), $linkService->reveal(), - new TypoLinkCodecService(), - $siteFinder->reveal() + new TypoLinkCodecService($eventDispatcher->reveal()), + $siteFinder ); $linkResult = new LinkResult('page', 'https://typo3.tld/sitemap-type/pages/sitemap.xml'); diff --git a/Tests/Unit/Event/Listener/AfterPagePreviewUriGeneratedListenerTest.php b/Tests/Unit/Event/Listener/AfterPagePreviewUriGeneratedListenerTest.php index a32090a3..a78bd93c 100644 --- a/Tests/Unit/Event/Listener/AfterPagePreviewUriGeneratedListenerTest.php +++ b/Tests/Unit/Event/Listener/AfterPagePreviewUriGeneratedListenerTest.php @@ -33,13 +33,13 @@ public function test__construct() { $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::any())->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createMock(SiteFinder::class); $listener = new AfterPagePreviewUriGeneratedListener(new UrlUtility( null, $resolver->reveal(), - $siteFinder->reveal() - ), $siteFinder->reveal()); + $siteFinder + ), $siteFinder); self::assertInstanceOf(AfterPagePreviewUriGeneratedListener::class, $listener); } @@ -48,14 +48,14 @@ public function testLink() { $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::any())->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); - $siteFinder->getSiteByPageId(Argument::any())->willReturn($site = new Site('test', 1, ['headless' => HeadlessMode::MIXED, 'frontendBase' => 'https://front.test.tld', 'base' => 'https://test.tld'])); + $siteFinder = $this->createPartialMock(SiteFinder::class, ['getSiteByPageId']); + $siteFinder->method('getSiteByPageId')->willReturn($site = new Site('test', 1, ['headless' => HeadlessMode::MIXED, 'frontendBase' => 'https://front.test.tld', 'base' => 'https://test.tld'])); $listener = new AfterPagePreviewUriGeneratedListener(new UrlUtility( null, $resolver->reveal(), - $siteFinder->reveal() - ), $siteFinder->reveal()); + $siteFinder + ), $siteFinder); $event = new AfterPagePreviewUriGeneratedEvent( new Uri('https://test.tld/page'), @@ -82,14 +82,14 @@ public function testSiteNotFound() { $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::any())->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); - $siteFinder->getSiteByPageId(Argument::any())->willThrow(new SiteNotFoundException()); + $siteFinder = $this->createPartialMock(SiteFinder::class, ['getSiteByPageId']); + $siteFinder->method('getSiteByPageId')->willThrowException(new SiteNotFoundException()); $listener = new AfterPagePreviewUriGeneratedListener(new UrlUtility( null, $resolver->reveal(), - $siteFinder->reveal() - ), $siteFinder->reveal()); + $siteFinder + ), $siteFinder); $event = new AfterPagePreviewUriGeneratedEvent( new Uri('https://test.tld/page'), diff --git a/Tests/Unit/Event/Listener/RedirectUrlAdditionalParamsListenerTest.php b/Tests/Unit/Event/Listener/RedirectUrlAdditionalParamsListenerTest.php index 92df106e..33b320a8 100644 --- a/Tests/Unit/Event/Listener/RedirectUrlAdditionalParamsListenerTest.php +++ b/Tests/Unit/Event/Listener/RedirectUrlAdditionalParamsListenerTest.php @@ -19,6 +19,7 @@ use InvalidArgumentException; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; +use Psr\EventDispatcher\EventDispatcherInterface; use Psr\Http\Message\UriInterface; use TYPO3\CMS\Core\ExpressionLanguage\Resolver; use TYPO3\CMS\Core\Http\ServerRequest; @@ -35,13 +36,13 @@ class RedirectUrlAdditionalParamsListenerTest extends UnitTestCase { use ProphecyTrait; - /** - * @test - */ - public function invokeTest() + public function testInvoke(): void { + $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); + $eventDispatcher->dispatch(Argument::any())->willReturnArgument(); + $listener = new RedirectUrlAdditionalParamsListener( - new TypoLinkCodecService(), + new TypoLinkCodecService($eventDispatcher->reveal()), new LinkService(), $this->getUrlUtility() ); @@ -119,7 +120,7 @@ public function invokeTest() $mockListener->method('getPageRouterForSite') ->willReturn($pageRouter->reveal()); $mockListener->__construct( - new TypoLinkCodecService(), + new TypoLinkCodecService($eventDispatcher->reveal()), new LinkService(), $this->getUrlUtility() ); @@ -128,11 +129,11 @@ public function invokeTest() self::assertSame((string)$expectedUri, $newRedirectEvent->getTargetUrl()); } - /** - * @test - */ - public function invokeWithLanguageTest() + public function testInvokeWithLanguaget(): void { + $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); + $eventDispatcher->dispatch(Argument::any())->willReturnArgument(); + $targetUrl = 'https://test.domain2.tld/123'; $additionalParams = 'tx_test[action]=test&tx_test[controller]=Test&tx_test[test]=123'; $expectedUri = new Uri($targetUrl . '&' . $additionalParams); @@ -180,7 +181,7 @@ public function invokeWithLanguageTest() ->willReturn($pageRouter->reveal()); $mockListener->__construct( - new TypoLinkCodecService(), + new TypoLinkCodecService($eventDispatcher->reveal()), new LinkService(), $this->getUrlUtility($site) ); @@ -239,14 +240,14 @@ protected function getUrlUtility($site = null): UrlUtility $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::any())->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createPartialMock(SiteFinder::class, ['getSiteByPageId']); if ($site === null) { $site = $this->getSiteWithBase($uri); } - $siteFinder->getSiteByPageId(Argument::is(1))->willReturn($site); + $siteFinder->method('getSiteByPageId')->willReturn($site); - return new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, (new HeadlessMode())->withRequest((new ServerRequest())->withAttribute('headless', new Headless()))); + return new UrlUtility(null, $resolver->reveal(), $siteFinder, null, (new HeadlessMode())->withRequest((new ServerRequest())->withAttribute('headless', new Headless()))); } } diff --git a/Tests/Unit/Event/RedirectUrlEventTest.php b/Tests/Unit/Event/RedirectUrlEventTest.php index ca44a2f1..d89e47a1 100644 --- a/Tests/Unit/Event/RedirectUrlEventTest.php +++ b/Tests/Unit/Event/RedirectUrlEventTest.php @@ -12,6 +12,7 @@ namespace FriendsOfTYPO3\Headless\Tests\Unit\Event; use FriendsOfTYPO3\Headless\Event\RedirectUrlEvent; +use PHPUnit\Framework\Attributes\Test; use Prophecy\PhpUnit\ProphecyTrait; use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Core\Http\Uri; @@ -21,9 +22,7 @@ class RedirectUrlEventTest extends UnitTestCase { use ProphecyTrait; - /** - * @test - */ + #[Test] public function eventTest() { $request = (new ServerRequest())->withAttribute('test', 1); diff --git a/Tests/Unit/Form/Decorator/AbstractFormDefinitionDecoratorTest.php b/Tests/Unit/Form/Decorator/AbstractFormDefinitionDecoratorTest.php index ff874cbf..68d9ecd1 100644 --- a/Tests/Unit/Form/Decorator/AbstractFormDefinitionDecoratorTest.php +++ b/Tests/Unit/Form/Decorator/AbstractFormDefinitionDecoratorTest.php @@ -16,28 +16,24 @@ class AbstractFormDefinitionDecoratorTest extends UnitTestCase { - /** - * @test - */ - public function basicOutput(): void + public function testBasicOutput(): void { - $stub = $this->getMockForAbstractClass(AbstractFormDefinitionDecorator::class, [['api' => 'test']]); + $class = new class () extends AbstractFormDefinitionDecorator {}; + $classUnderTest = new $class(['api' => 'test']); $definition = [ 'identifier' => 'test-123', 'renderables' => [0 => ['renderables' => []]], 'i18n' => ['properties' => []], ]; - $test = $stub($definition, 1); + $test = $classUnderTest($definition, 1); self::assertSame(['id' => 'test-123', 'api' => ['api' => 'test'], 'i18n' => [], 'elements' => []], $test); } - /** - * @test - */ - public function renderElements(): void + public function testRenderElements(): void { - $stub = $this->getMockForAbstractClass(AbstractFormDefinitionDecorator::class, [['api' => 'test']]); + $class = new class () extends AbstractFormDefinitionDecorator {}; + $classUnderTest = new $class(['api' => 'test']); $definition = [ 'identifier' => 'test-123', @@ -91,7 +87,7 @@ public function renderElements(): void ], 'i18n' => ['properties' => []], ]; - $test = $stub($definition, 0); + $test = $classUnderTest($definition, 0); self::assertSame([ 'id' => 'test-123', diff --git a/Tests/Unit/Hooks/HeadlessUserIntTest.php b/Tests/Unit/Hooks/HeadlessUserIntTest.php index 5b121945..2b1fa47a 100644 --- a/Tests/Unit/Hooks/HeadlessUserIntTest.php +++ b/Tests/Unit/Hooks/HeadlessUserIntTest.php @@ -13,7 +13,6 @@ use FriendsOfTYPO3\Headless\Utility\HeadlessUserInt; use Prophecy\PhpUnit\ProphecyTrait; -use TYPO3\CMS\Core\TypoScript\TemplateService; use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; @@ -23,23 +22,12 @@ class HeadlessUserIntTest extends UnitTestCase { use ProphecyTrait; - /** - * @test - */ - public function processingOnPlainTextWithNewline() + public function testProcessingOnPlainTextWithNewline() { $testProcessed = 'PlainText' . PHP_EOL . 'NextLine'; $testContent = 'HEADLESS_INT_START<<' . $testProcessed . '>>HEADLESS_INT_END'; - $setup = []; - $setup['plugin.']['tx_headless.']['staticTemplate'] = '1'; - - $tmpl = $this->prophesize(TemplateService::class); - $tmpl->setup = $setup; - $tsfe = $this->prophesize(TypoScriptFrontendController::class); - $tsfe->tmpl = $tmpl->reveal(); - $tsfe->content = $testContent; $classUnderTest = new HeadlessUserInt(); @@ -49,23 +37,12 @@ public function processingOnPlainTextWithNewline() self::assertEquals(json_encode($testProcessed), '"' . $tsfe->content . '"'); } - /** - * @test - */ - public function processingOnQuotedText() + public function testProcessingOnQuotedText() { $testProcessed = '"PlainText' . PHP_EOL . 'NextLine"'; $testContent = 'HEADLESS_INT_START<<' . $testProcessed . '>>HEADLESS_INT_END'; - $setup = []; - $setup['plugin.']['tx_headless.']['staticTemplate'] = '1'; - - $tmpl = $this->prophesize(TemplateService::class); - $tmpl->setup = $setup; - $tsfe = $this->prophesize(TypoScriptFrontendController::class); - $tsfe->tmpl = $tmpl->reveal(); - $tsfe->content = $testContent; $classUnderTest = new HeadlessUserInt(); @@ -75,23 +52,14 @@ public function processingOnQuotedText() self::assertEquals(json_encode($testProcessed), '"' . $tsfe->content . '"'); } - /** - * @test - */ - public function processingOnQuotedContent() + public function testProcessingOnQuotedContent() { $testProcessed = '"PlainText' . PHP_EOL . 'NextLine"'; $testContent = '"HEADLESS_INT_START<<' . $testProcessed . '>>HEADLESS_INT_END"'; $setup = []; - $setup['plugin.']['tx_headless.']['staticTemplate'] = '1'; - - $tmpl = $this->prophesize(TemplateService::class); - $tmpl->setup = $setup; $tsfe = $this->prophesize(TypoScriptFrontendController::class); - $tsfe->tmpl = $tmpl->reveal(); - $tsfe->content = $testContent; $classUnderTest = new HeadlessUserInt(); @@ -101,10 +69,7 @@ public function processingOnQuotedContent() self::assertEquals(json_encode($testProcessed), $tsfe->content); } - /** - * @test - */ - public function processingOnQuotedJsonContent() + public function testProcessingOnQuotedJsonContent() { $testProcessed = json_encode( [ @@ -113,15 +78,7 @@ public function processingOnQuotedJsonContent() ); $testContent = '"HEADLESS_INT_START<<' . $testProcessed . '>>HEADLESS_INT_END"'; - $setup = []; - $setup['plugin.']['tx_headless.']['staticTemplate'] = '1'; - - $tmpl = $this->prophesize(TemplateService::class); - $tmpl->setup = $setup; - $tsfe = $this->prophesize(TypoScriptFrontendController::class); - $tsfe->tmpl = $tmpl->reveal(); - $tsfe->content = $testContent; $classUnderTest = new HeadlessUserInt(); @@ -131,25 +88,14 @@ public function processingOnQuotedJsonContent() self::assertEquals($testProcessed, $tsfe->content); } - /** - * @test - */ - public function processingEmptyPluginResponse() + public function testProcessingEmptyPluginResponse() { $testProcessed = json_encode( '' ); $testContent = '"HEADLESS_INT_NULL_START<<' . $testProcessed . '>>HEADLESS_INT_NULL_END"'; - $setup = []; - $setup['plugin.']['tx_headless.']['staticTemplate'] = '1'; - - $tmpl = $this->prophesize(TemplateService::class); - $tmpl->setup = $setup; - $tsfe = $this->prophesize(TypoScriptFrontendController::class); - $tsfe->tmpl = $tmpl->reveal(); - $tsfe->content = $testContent; $classUnderTest = new HeadlessUserInt(); @@ -163,15 +109,7 @@ public function processingEmptyPluginResponse() ); $testContent = '"NESTED_HEADLESS_INT_NULL_START<<' . $testProcessed . '>>NESTED_HEADLESS_INT_NULL_END"'; - $setup = []; - $setup['plugin.']['tx_headless.']['staticTemplate'] = '1'; - - $tmpl = $this->prophesize(TemplateService::class); - $tmpl->setup = $setup; - $tsfe = $this->prophesize(TypoScriptFrontendController::class); - $tsfe->tmpl = $tmpl->reveal(); - $tsfe->content = $testContent; $classUnderTest = new HeadlessUserInt(); @@ -181,10 +119,7 @@ public function processingEmptyPluginResponse() self::assertEquals(json_encode(null), $tsfe->content); } - /** - * @test - */ - public function processingOnNestedJsonContent() + public function testProcessingOnNestedJsonContent() { $nestedProcessed = json_encode( [ @@ -217,12 +152,7 @@ public function processingOnNestedJsonContent() $setup = []; $setup['plugin.']['tx_headless.']['staticTemplate'] = '1'; - $tmpl = $this->prophesize(TemplateService::class); - $tmpl->setup = $setup; - $tsfe = $this->prophesize(TypoScriptFrontendController::class); - $tsfe->tmpl = $tmpl->reveal(); - $tsfe->content = $testContent; $classUnderTest = new HeadlessUserInt(); @@ -232,10 +162,7 @@ public function processingOnNestedJsonContent() self::assertEquals($finalOutput, $tsfe->content); } - /** - * @test - */ - public function processingOnMultipleUserIntOnPageJsonContent() + public function testProcessingOnMultipleUserIntOnPageJsonContent() { $nestedProcessed = json_encode( [ @@ -276,15 +203,7 @@ public function processingOnMultipleUserIntOnPageJsonContent() $testContent = '["HEADLESS_INT_START<<' . $testProcessed . '>>HEADLESS_INT_END","HEADLESS_INT_START<<' . $testProcessed2 . '>>HEADLESS_INT_END"]'; - $setup = []; - $setup['plugin.']['tx_headless.']['staticTemplate'] = '1'; - - $tmpl = $this->prophesize(TemplateService::class); - $tmpl->setup = $setup; - $tsfe = $this->prophesize(TypoScriptFrontendController::class); - $tsfe->tmpl = $tmpl->reveal(); - $tsfe->content = $testContent; $classUnderTest = new HeadlessUserInt(); @@ -294,10 +213,7 @@ public function processingOnMultipleUserIntOnPageJsonContent() self::assertEquals($finalOutput, $tsfe->content); } - /** - * @test - */ - public function wrapTest() + public function testWrapTest() { $headlessUserInt = new HeadlessUserInt(); diff --git a/Tests/Unit/Json/JsonDecoderTest.php b/Tests/Unit/Json/JsonDecoderTest.php index 090adce2..1d297f7b 100644 --- a/Tests/Unit/Json/JsonDecoderTest.php +++ b/Tests/Unit/Json/JsonDecoderTest.php @@ -9,9 +9,11 @@ declare(strict_types=1); -namespace FriendsOfTYPO3\Headless\Tests\Unit\ContentObject; +namespace FriendsOfTYPO3\Headless\Tests\Unit\Json; use FriendsOfTYPO3\Headless\Json\JsonDecoder; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use stdClass; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -29,13 +31,7 @@ protected function setUp(): void parent::setUp(); } - /** - * @param $testValue - * @param $expectedValue - * - * @test - * @dataProvider possibleJsonProvider - */ + #[Test, DataProvider('possibleJsonProvider')] public function possibleFalsePositives($testValue, $expectedValue): void { $jsonDecoder = GeneralUtility::makeInstance(JsonDecoder::class); @@ -43,7 +39,8 @@ public function possibleFalsePositives($testValue, $expectedValue): void self::assertSame($expectedValue, $jsonDecoder->isJson($testValue)); } - public function testDecoding(): void + #[Test] + public function decoding(): void { $jsonDecoder = GeneralUtility::makeInstance(JsonDecoder::class); @@ -71,7 +68,7 @@ public function testDecoding(): void self::assertEquals(json_decode($encoded), $jsonDecoder->decode(['teststring'])); } - public function possibleJsonProvider(): array + public static function possibleJsonProvider(): array { return [ [' "12"', false], diff --git a/Tests/Unit/Json/JsonEncoderTest.php b/Tests/Unit/Json/JsonEncoderTest.php index e911970c..d9fd1cf3 100644 --- a/Tests/Unit/Json/JsonEncoderTest.php +++ b/Tests/Unit/Json/JsonEncoderTest.php @@ -12,6 +12,8 @@ namespace FriendsOfTYPO3\Headless\Tests\Unit\ContentObject; use FriendsOfTYPO3\Headless\Json\JsonEncoder; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use stdClass; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -27,12 +29,7 @@ protected function setUp(): void parent::setUp(); } - /** - * @param $testValue - * @param $expectedValue - * - * @dataProvider jsonProvider - */ + #[Test, DataProvider('jsonProvider')] public function testEncoding($testValue, $expectedValue): void { $encoder = GeneralUtility::makeInstance(JsonEncoder::class); @@ -40,7 +37,8 @@ public function testEncoding($testValue, $expectedValue): void self::assertSame($expectedValue, $encoder->encode($testValue)); } - public function testPrettyEncoding(): void + #[Test] + public function prettyEncoding(): void { $GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['headless.prettyPrint'] = true; $encoder = GeneralUtility::makeInstance(JsonEncoder::class); @@ -50,7 +48,7 @@ public function testPrettyEncoding(): void self::assertSame(json_encode($encodeValue, JSON_PRETTY_PRINT), $encoder->encode($encodeValue)); } - public function jsonProvider(): array + public static function jsonProvider(): array { return [ [[], '[]'], diff --git a/Tests/Unit/Middleware/CookieDomainPerSiteTest.php b/Tests/Unit/Middleware/CookieDomainPerSiteTest.php index 816e0896..19c73df2 100644 --- a/Tests/Unit/Middleware/CookieDomainPerSiteTest.php +++ b/Tests/Unit/Middleware/CookieDomainPerSiteTest.php @@ -13,6 +13,7 @@ use FriendsOfTYPO3\Headless\Middleware\CookieDomainPerSite; use FriendsOfTYPO3\Headless\Utility\UrlUtility; +use PHPUnit\Framework\Attributes\Test; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; use Psr\Log\LoggerInterface; @@ -29,9 +30,7 @@ class CookieDomainPerSiteTest extends UnitTestCase { use ProphecyTrait; - /** - * @test - */ + #[Test] public function emptyCookieDomain() { $site = $this->prophesize(Site::class); @@ -61,16 +60,16 @@ public function emptyCookieDomain() $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::containingString('Development'))->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createPartialMock(SiteFinder::class, ['getAllSites']); - $siteFinder->getAllSites()->willReturn([ - $site, + $siteFinder->method('getAllSites')->willReturn([ + $site->reveal(), ]); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal()); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder); $urlUtility = $urlUtility->withSite($site->reveal()); - $middleware = new CookieDomainPerSite($urlUtility, $siteFinder->reveal(), $this->prophesize(LoggerInterface::class)->reveal()); + $middleware = new CookieDomainPerSite($urlUtility, $siteFinder, $this->prophesize(LoggerInterface::class)->reveal()); $request = new ServerRequest('https://test-backend-api.tld'); $request = $request->withAttribute('normalizedParams', NormalizedParams::createFromRequest($request)); @@ -88,9 +87,7 @@ public function emptyCookieDomain() ); } - /** - * @test - */ + #[Test] public function cookieDomainIsSet() { $site = $this->prophesize(Site::class); @@ -121,16 +118,16 @@ public function cookieDomainIsSet() $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::containingString('Development'))->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createPartialMock(SiteFinder::class, ['getAllSites']); - $siteFinder->getAllSites()->willReturn([ - $site, + $siteFinder->method('getAllSites')->willReturn([ + $site->reveal(), ]); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal()); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder); $urlUtility = $urlUtility->withSite($site->reveal()); - $middleware = new CookieDomainPerSite($urlUtility, $siteFinder->reveal(), $this->prophesize(LoggerInterface::class)->reveal()); + $middleware = new CookieDomainPerSite($urlUtility, $siteFinder, $this->prophesize(LoggerInterface::class)->reveal()); $request = new ServerRequest('https://test-backend-api.tld'); $request = $request->withAttribute('normalizedParams', NormalizedParams::createFromRequest($request)); diff --git a/Tests/Unit/Middleware/ElementBodyResponseMiddlewareTest.php b/Tests/Unit/Middleware/ElementBodyResponseMiddlewareTest.php index bd763c8d..2f89de98 100644 --- a/Tests/Unit/Middleware/ElementBodyResponseMiddlewareTest.php +++ b/Tests/Unit/Middleware/ElementBodyResponseMiddlewareTest.php @@ -26,10 +26,7 @@ class ElementBodyResponseMiddlewareTest extends UnitTestCase { use ProphecyTrait; - /** - * @test - */ - public function processTest() + public function testProcess(): void { $middleware = new ElementBodyResponseMiddleware(new JsonEncoder(), new HeadlessMode()); diff --git a/Tests/Unit/Middleware/ShortcutAndMountPointRedirectTest.php b/Tests/Unit/Middleware/ShortcutAndMountPointRedirectTest.php deleted file mode 100644 index 687cb7d1..00000000 --- a/Tests/Unit/Middleware/ShortcutAndMountPointRedirectTest.php +++ /dev/null @@ -1,273 +0,0 @@ -test'; - $linkRedirect = 'https://test.domain2.tld'; - $genericResponse = new HtmlResponse($genericHtml); - $middleware = new ShortcutAndMountPointRedirect((new HeadlessMode())->withRequest((new ServerRequest())->withAttribute( - 'headless', - ['mode' => HeadlessMode::FULL] - ))); - - $correctRedirect = [ - 'redirectUrl' => $linkRedirect, - 'statusCode' => 303, - ]; - - $linkRedirectResponse = $middleware->process( - $this->getTestRequest( - ['type' => 0], - 'https://test.domain.tld', - $this->getTsfeProphecy( - '1', - ['id' => 1, 'doktype' => PageRepository::DOKTYPE_LINK, 'url' => $linkRedirect] - )->reveal() - ), - $this->getMockHandlerWithResponse($genericResponse), - ); - $linkRedirectJson = json_decode($linkRedirectResponse->getBody()->__toString(), true); - self::assertEquals($correctRedirect, $linkRedirectJson); - - $initialDataResponse = $middleware->process( - $this->getTestRequest(['type' => 834], 'https://test.domain.tld'), - $this->getMockHandlerWithResponse($genericResponse) - ); - - self::assertEquals($genericHtml, $initialDataResponse->getBody()->__toString()); - - $middleware = new ShortcutAndMountPointRedirect((new HeadlessMode())->withRequest((new ServerRequest())->withAttribute( - 'headless', - ['mode' => HeadlessMode::FULL] - ))); - $shortcutJsonDecoded = [ - 'redirectUrl' => '/shortcut-target', - 'statusCode' => 307, - ]; - - $middlewareResponse = $middleware->process( - $this->getTestRequest( - ['type' => 0], - 'https://test.domain.tld', - $this->getTsfeProphecy( - '1', - ['id' => 1, 'doktype' => PageRepository::DOKTYPE_SHORTCUT, 'shortcut' => '5'] - )->reveal() - ), - $this->getMockHandlerWithResponse($genericResponse) - ); - self::assertEquals($shortcutJsonDecoded, json_decode($middlewareResponse->getBody()->__toString(), true)); - - $middleware = new ShortcutAndMountPointRedirect((new HeadlessMode())); - - $testRedirectResponse = new RedirectResponse('https://test.domain.tld/shortcut-target', 307); - - $middlewareResponse = $middleware->process( - $this->getTestRequest( - ['type' => 0], - 'https://test.domain.tld', - $this->getTsfeProphecy( - '0', - ['id' => 1, 'doktype' => PageRepository::DOKTYPE_SHORTCUT, 'shortcut' => '5'] - )->reveal(), - false - ), - $this->getMockHandlerWithResponse($genericResponse) - ); - - self::assertEquals( - $testRedirectResponse->getHeader('location')[0], - $middlewareResponse->getHeader('location')[0] - ); - self::assertEquals($testRedirectResponse->getStatusCode(), $middlewareResponse->getStatusCode()); - - $middleware = new ShortcutAndMountPointRedirect(new HeadlessMode()); - - $linkRedirectResponse = $middleware->process( - $this->getTestRequest( - ['type' => 0], - 'https://test.domain.tld', - $this->getTsfeProphecy( - '0', - ['id' => 1, 'doktype' => PageRepository::DOKTYPE_LINK, 'url' => $linkRedirect] - )->reveal(), - false - ), - $this->getMockHandlerWithResponse($genericResponse) - ); - - self::assertEquals($linkRedirect, $linkRedirectResponse->getHeader('location')[0]); - self::assertEquals(303, $linkRedirectResponse->getStatusCode()); - - $middleware = new ShortcutAndMountPointRedirect((new HeadlessMode())->withRequest((new ServerRequest())->withAttribute( - 'headless', - ['mode' => HeadlessMode::FULL] - ))); - $tsfe = $this->getTsfeProphecy( - '0', - ['id' => 1, 'doktype' => PageRepository::DOKTYPE_DEFAULT, 'url' => $linkRedirect] - ); - $tsfe->getRedirectUriForShortcut(Argument::any())->willReturn(null); - $tsfe->getRedirectUriForMountPoint(Argument::any())->willReturn(null); - - $GLOBALS['TSFE'] = $tsfe->reveal(); - - $normalResponse = $middleware->process( - $this->getTestRequest( - ['type' => 0], - 'https://test.domain.tld', - $GLOBALS['TSFE'] - ), - $this->getMockHandlerWithResponse($genericResponse) - ); - - self::assertEquals($genericHtml, $normalResponse->getBody()->__toString()); - } - - public function redirectProvider(): array - { - $domain = 'https://test.redirect.domain.tld'; - return [ - ['user@tes@t', $domain . 'user@tes@t'], - ['user@test.com', 'mailto:user@test.com'], - ['/false/url:1', '/false/url:1'], - ['/relative-url', '/relative-url'], - ]; - } - - /** - * @param $url - * @param $expectedValue - * - * @test - * @dataProvider redirectProvider - */ - public function linkRedirectTest($url, $expectedValue): void - { - $domain = 'https://test.redirect.domain.tld'; - $genericHtml = 'test'; - $genericResponse = new HtmlResponse($genericHtml); - - $middleware = new ShortcutAndMountPointRedirect((new HeadlessMode())->withRequest((new ServerRequest())->withAttribute( - 'headless', - ['mode' => HeadlessMode::FULL] - ))); - - $linkRedirectResponse = $middleware->process( - $this->getTestRequest( - ['type' => 0], - $domain, - $this->getTsfeProphecy( - '1', - ['id' => 1, 'doktype' => PageRepository::DOKTYPE_LINK, 'url' => $url] - )->reveal() - ), - $this->getMockHandlerWithResponse($genericResponse) - ); - - $correctRedirect = [ - 'redirectUrl' => $expectedValue, - 'statusCode' => 303, - ]; - - $linkRedirectJson = json_decode($linkRedirectResponse->getBody()->__toString(), true); - self::assertEquals($correctRedirect, $linkRedirectJson); - } - - protected function getMockHandlerWithResponse($response) - { - $handler = $this->createPartialMock(RequestHandler::class, ['handle']); - $handler->method('handle')->willReturn($response); - return $handler; - } - - protected function getTestRequest( - array $withQueryParams = [], - string $withNormalizedParamsUrl = '', - $withTsfe = null, - bool $withEnabledHeadless = true - ) { - $request = new ServerRequest(); - $request = $request->withUri(new Uri('/')); - - if ($withQueryParams !== []) { - $request = $request->withQueryParams($withQueryParams); - } - - if ($withNormalizedParamsUrl !== '') { - $normalizedParams = $this->prophesize(NormalizedParams::class); - $normalizedParams->getSiteUrl()->willReturn($withNormalizedParamsUrl); - $request = $request->withAttribute('normalizedParams', $normalizedParams->reveal()); - } - - if ($withTsfe) { - $request = $request->withAttribute('frontend.controller', $withTsfe); - } - - $request = $request->withAttribute('headless', new Headless()); - - if ($withEnabledHeadless) { - $request = $request->withAttribute('site', new Site('test_site', 1, ['headless' => true])); - return $request->withAttribute('headless', new Headless(HeadlessMode::FULL)); - } - - return $request; - } - - protected function getTsfeProphecy(string $staticTemplate = '1', array $pageData = []) - { - $setup = []; - $setup['plugin.']['tx_headless.']['staticTemplate'] = $staticTemplate; - - $tmpl = $this->prophesize(TemplateService::class); - $tmpl->setup = $setup; - - $tsfe = $this->prophesize(TypoScriptFrontendController::class); - $tsfe->tmpl = $tmpl->reveal(); - - if ($pageData === []) { - $pageData = ['id' => 1, 'doktype' => PageRepository::DOKTYPE_LINK, 'url' => 'https://test.domain2.tld']; - } elseif ($pageData['doktype'] === PageRepository::DOKTYPE_SHORTCUT) { - $tsfe->getRedirectUriForShortcut(Argument::any())->willReturn('https://test.domain.tld/shortcut-target'); - } - - $tsfe->page = $pageData; - - return $tsfe; - } -} diff --git a/Tests/Unit/Middleware/SiteBaseRedirectResolverTest.php b/Tests/Unit/Middleware/SiteBaseRedirectResolverTest.php index 4353a0f2..0013fae7 100644 --- a/Tests/Unit/Middleware/SiteBaseRedirectResolverTest.php +++ b/Tests/Unit/Middleware/SiteBaseRedirectResolverTest.php @@ -60,11 +60,11 @@ public function testJsonRedirect() ], ]]); - $siteFinder = $this->prophesize(SiteFinder::class); - $siteFinder->getSiteByPageId(1)->willReturn($site); + $siteFinder = $this->createPartialMock(SiteFinder::class, ['getSiteByPageId']); + $siteFinder->method('getSiteByPageId')->willReturn($site); $container = new Container(); - $urlUtility = GeneralUtility::makeInstance(UrlUtility::class, null, $this->prophesize(Resolver::class)->reveal(), $siteFinder->reveal()); + $urlUtility = GeneralUtility::makeInstance(UrlUtility::class, null, $this->prophesize(Resolver::class)->reveal(), $siteFinder); $container->set(UrlUtility::class, $urlUtility); GeneralUtility::setContainer($container); @@ -131,11 +131,11 @@ public function testJsonRedirect() ], ]]); - $siteFinder = $this->prophesize(SiteFinder::class); - $siteFinder->getSiteByPageId(1)->willReturn($site); + $siteFinder = $this->createPartialMock(SiteFinder::class, ['getSiteByPageId']); + $siteFinder->method('getSiteByPageId')->willReturn($site); $container = new Container(); - $urlUtility = GeneralUtility::makeInstance(UrlUtility::class, null, $this->prophesize(Resolver::class)->reveal(), $siteFinder->reveal()); + $urlUtility = GeneralUtility::makeInstance(UrlUtility::class, null, $this->prophesize(Resolver::class)->reveal(), $siteFinder); $container->set(UrlUtility::class, $urlUtility); $errorController = $this->prophesize(ErrorController::class); $errorController->pageNotFoundAction(Argument::any(), Argument::any(), Argument::any())->willReturn(new JsonResponse(['ErrorController' => true])); diff --git a/Tests/Unit/Middleware/UserIntMiddlewareTest.php b/Tests/Unit/Middleware/UserIntMiddlewareTest.php index 1f679d54..5caac21d 100644 --- a/Tests/Unit/Middleware/UserIntMiddlewareTest.php +++ b/Tests/Unit/Middleware/UserIntMiddlewareTest.php @@ -16,6 +16,7 @@ use FriendsOfTYPO3\Headless\Utility\Headless; use FriendsOfTYPO3\Headless\Utility\HeadlessMode; use FriendsOfTYPO3\Headless\Utility\HeadlessUserInt; +use PHPUnit\Framework\Attributes\Test; use Prophecy\PhpUnit\ProphecyTrait; use TYPO3\CMS\Core\Http\HtmlResponse; use TYPO3\CMS\Core\Http\ServerRequest; @@ -29,10 +30,8 @@ class UserIntMiddlewareTest extends UnitTestCase { use ProphecyTrait; - /** - * @test - */ - public function processTest() + #[Test] + public function process(): void { $middleware = new UserIntMiddleware(new HeadlessUserInt(), new HeadlessMode(), $this->createMock(MetaHandler::class)); @@ -113,7 +112,7 @@ public function processTest() protected function getMockHandlerWithResponse($response) { - $handler = $this->createPartialMock(RequestHandler::class, ['handle']); + $handler = $this->createMock(RequestHandler::class, ['handle']); $handler->method('handle')->willReturn($response); return $handler; } diff --git a/Tests/Unit/Utility/UrlUtilityTest.php b/Tests/Unit/Utility/UrlUtilityTest.php index 8c8d185b..a49dcd76 100644 --- a/Tests/Unit/Utility/UrlUtilityTest.php +++ b/Tests/Unit/Utility/UrlUtilityTest.php @@ -70,9 +70,9 @@ public function testFrontendUrls(): void $resolver->evaluate(Argument::containingString('Development'))->willReturn(true); $resolver->evaluate(Argument::containingString('Testing'))->willReturn(false); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createMock(SiteFinder::class); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); self::assertSame('https://test-frontend.tld', $urlUtility->getFrontendUrl()); @@ -84,9 +84,9 @@ public function testFrontendUrls(): void $resolver->evaluate(Argument::containingString('Development'))->willReturn(false); $resolver->evaluate(Argument::containingString('Testing'))->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createMock(SiteFinder::class); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); self::assertSame('https://test-frontend2.tld', $urlUtility->getFrontendUrl()); @@ -99,11 +99,11 @@ public function testFrontendUrls(): void $resolver->evaluate(Argument::containingString('Testing'))->willReturn(false); $resolver->evaluate(Argument::containingString('Misconfigured'))->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createMock(SiteFinder::class); $site->getBase()->shouldBeCalled(2)->willReturn(new Uri('https://test-backend3-api.tld/')); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); self::assertSame('https://test-frontend3.tld', $urlUtility->getFrontendUrl()); @@ -135,9 +135,9 @@ public function testFrontendUrlsWithDifferentPaths(): void $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::containingString('Development'))->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createMock(SiteFinder::class); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); self::assertSame('https://test-frontend.tld/frontend/content-page', $urlUtility->getFrontendUrlWithSite('https://test-backend-api.tld/dev-path/content-page', $site->reveal())); @@ -165,7 +165,7 @@ public function testFrontendUrlsWithBaseProductionAndLocalOverride(): void ], ]); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createMock(SiteFinder::class); // local override $resolver = $this->prophesize(Resolver::class); @@ -173,7 +173,7 @@ public function testFrontendUrlsWithBaseProductionAndLocalOverride(): void $headlessMode = $this->createHeadlessMode(); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); self::assertSame('https://test-frontend.tld', $urlUtility->getFrontendUrl()); @@ -185,7 +185,7 @@ public function testFrontendUrlsWithBaseProductionAndLocalOverride(): void $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::containingString('Development'))->willReturn(false); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); self::assertSame('https://www.typo3.org', $urlUtility->getFrontendUrl()); @@ -224,9 +224,9 @@ public function testOptimizedUrlsForFrontendApp(): void $resolver->evaluate(Argument::containingString('Development'))->willReturn(true); $resolver->evaluate(Argument::containingString('Testing'))->willReturn(false); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createMock(SiteFinder::class); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); // same page, so we make it relative @@ -253,9 +253,9 @@ public function testOptimizedUrlsForFrontendApp(): void $resolver->evaluate(Argument::containingString('Development'))->willReturn(false); $resolver->evaluate(Argument::containingString('Testing'))->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createMock(SiteFinder::class); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); // same page, so we make it relative @@ -320,9 +320,9 @@ public function testLanguageResolver(): void $resolver->evaluate(Argument::containingString('Development'))->willReturn(true); $resolver->evaluate(Argument::containingString('Testing'))->willReturn(false); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createMock(SiteFinder::class); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); $urlUtility = $urlUtility->withLanguage(new SiteLanguage(0, 'en', new Uri('/'), [ 'title' => 'English', @@ -371,7 +371,7 @@ public function testLanguageResolver(): void self::assertSame('https://test-frontend-from-lang.tld/headless/fileadmin', $urlUtility->getStorageProxyUrl()); // not overlay site variants if language has not defined variants - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal()); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder); $urlUtility = $urlUtility->withSite($site->reveal()); $urlUtility = $urlUtility->withLanguage(new SiteLanguage(0, 'en', new Uri('/'), [ 'title' => 'English', @@ -394,9 +394,9 @@ public function testLanguageResolver(): void $resolver->evaluate(Argument::containingString('Development'))->willReturn(false); $resolver->evaluate(Argument::containingString('Testing'))->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder = $this->createMock(SiteFinder::class); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); $urlUtility = $urlUtility->withLanguage(new SiteLanguage(0, 'en', new Uri('/'), [ 'title' => 'English', @@ -453,11 +453,11 @@ public function testFrontendUrlForPage(): void $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::any())->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); - $siteFinder->getSiteByPageId(Argument::is(1))->shouldBeCalled(2)->willReturn($site->reveal()); + $siteFinder = $this->createPartialMock(SiteFinder::class, ['getSiteByPageId']); + $siteFinder->method('getSiteByPageId')->willReturn($site->reveal()); $headlessMode = $this->createHeadlessMode(HeadlessMode::NONE); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); // flag is not existing/disabled @@ -468,7 +468,7 @@ public function testFrontendUrlForPage(): void $headlessMode = $this->createHeadlessMode(HeadlessMode::FULL); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); self::assertSame( 'https://test-frontend.tld/test-page', @@ -499,12 +499,12 @@ public function testFrontendUrlForPageWithAlreadyFrontendUrlResolved(): void $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::any())->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); - $siteFinder->getSiteByPageId(Argument::is(1))->shouldBeCalledOnce()->willReturn($site->reveal()); + $siteFinder = $this->createPartialMock(SiteFinder::class, ['getSiteByPageId']); + $siteFinder->method('getSiteByPageId')->willReturn($site->reveal()); $headlessMode = $this->createHeadlessMode(); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); self::assertSame( @@ -535,11 +535,11 @@ public function testFrontendUrlForPageWithPortsOnFrontendSide(): void $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::any())->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); - $siteFinder->getSiteByPageId(Argument::is(1))->shouldBeCalled(2)->willReturn($site->reveal()); + $siteFinder = $this->createPartialMock(SiteFinder::class, ['getSiteByPageId']); + $siteFinder->method('getSiteByPageId')->willReturn($site->reveal()); $headlessMode = $this->createHeadlessMode(HeadlessMode::NONE); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); // flag is not existing/disabled @@ -550,7 +550,7 @@ public function testFrontendUrlForPageWithPortsOnFrontendSide(): void // flag is enabled $headlessMode = $this->createHeadlessMode(); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); self::assertSame( 'https://test-frontend.tld:3000/test-page', @@ -581,10 +581,10 @@ public function testFrontendUrlForPageWithPortsOnBothSides(): void $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::any())->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); - $siteFinder->getSiteByPageId(Argument::is(1))->shouldBeCalled(2)->willReturn($site->reveal()); + $siteFinder = $this->createPartialMock(SiteFinder::class, ['getSiteByPageId']); + $siteFinder->method('getSiteByPageId')->willReturn($site->reveal()); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); // flag is not existing/disabled @@ -595,7 +595,7 @@ public function testFrontendUrlForPageWithPortsOnBothSides(): void // flag is enabled $headlessMode = $this->createHeadlessMode(); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), null, $headlessMode); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, null, $headlessMode); $urlUtility = $urlUtility->withSite($site->reveal()); self::assertSame( 'https://test-frontend.tld:3000/test-page', @@ -617,9 +617,9 @@ public function testEdgeCases() $resolver = $this->prophesize(Resolver::class); $resolver->evaluate(Argument::any())->willReturn(true); - $siteFinder = $this->prophesize(SiteFinder::class); - $siteFinder->getSiteByPageId(Argument::is(1))->shouldBeCalledOnce()->willReturn($site); - $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder->reveal(), $request->reveal(), null, $headlessMode); + $siteFinder = $this->createPartialMock(SiteFinder::class, ['getSiteByPageId']); + $siteFinder->method('getSiteByPageId')->willReturn($site); + $urlUtility = new UrlUtility(null, $resolver->reveal(), $siteFinder, $request->reveal(), null, $headlessMode); self::assertSame( 'https://test-backend-api.tld:8000/test-page', diff --git a/Tests/Unit/XClass/TemplateViewTest.php b/Tests/Unit/XClass/TemplateViewTest.php index a3197b49..e8a94c76 100644 --- a/Tests/Unit/XClass/TemplateViewTest.php +++ b/Tests/Unit/XClass/TemplateViewTest.php @@ -14,6 +14,7 @@ use FriendsOfTYPO3\Headless\Utility\Headless; use FriendsOfTYPO3\Headless\Utility\HeadlessMode; use FriendsOfTYPO3\Headless\XClass\TemplateView; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; use RuntimeException; use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Fluid\Core\Rendering\RenderingContext; @@ -27,6 +28,7 @@ use function json_encode; +#[IgnoreDeprecations] class TemplateViewTest extends UnitTestCase { public function testTemplateNotFoundRender(): void diff --git a/Tests/Unit/phpunit.xml b/Tests/Unit/phpunit.xml index 71bf1ca2..b66cdc5c 100644 --- a/Tests/Unit/phpunit.xml +++ b/Tests/Unit/phpunit.xml @@ -1,27 +1,19 @@ - - - ../../Classes - - ./ @@ -29,7 +21,12 @@ - - + + + + + ../../Classes + + diff --git a/composer.json b/composer.json index ffd26bd3..8fa1ce01 100644 --- a/composer.json +++ b/composer.json @@ -28,24 +28,24 @@ ], "require": { "ext-json": "*", - "typo3/cms-core": "^12.4", - "typo3/cms-install": "^12.4" + "typo3/cms-core": "^12.4 || ^13.4", + "typo3/cms-install": "^12.4 || ^13.4" }, "require-dev": { - "ergebnis/composer-normalize": "^2.15.0", - "friendsofphp/php-cs-fixer": "^3.1", + "ergebnis/composer-normalize": "^2.43", + "friendsofphp/php-cs-fixer": "^v3", "helmich/typo3-typoscript-lint": "^v3", - "justinrainbow/json-schema": "^5.2", - "php-coveralls/php-coveralls": "^2.5.2", - "phpspec/prophecy-phpunit": "^2.0", + "justinrainbow/json-schema": "^5", + "php-coveralls/php-coveralls": "^2", + "phpspec/prophecy-phpunit": "^2", "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.9", - "phpunit/phpcov": "^8.2", + "phpstan/phpstan": "^1.12", + "phpunit/phpcov": "^8 || ^9 || ^10", "saschaegerer/phpstan-typo3": "^1.1", - "seld/jsonlint": "^1.8", - "symfony/yaml": "^6.1", - "typo3/cms-form": "^12.4", - "typo3/testing-framework": "^7.0", + "seld/jsonlint": "^1.11", + "symfony/yaml": "^6.1 || ^7.1", + "typo3/cms-form": "^12.4 || ^13.3", + "typo3/testing-framework": "^8.0", "typo3/coding-standards": "^0.8" }, "conflict": { @@ -91,7 +91,7 @@ ], "ci:coverage:functional": [ "@coverage:create-directories", - ".Build/vendor/bin/phpunit -c Tests/Functional/phpunit.xml --whitelist Classes --coverage-php=.Build/coverage/functional.cov Tests/Functional" + ".Build/vendor/bin/phpunit -c Tests/Functional/phpunit.xml Classes --coverage-php=.Build/coverage/functional.cov Tests/Functional" ], "ci:coverage:merge": [ "@coverage:create-directories", @@ -99,7 +99,7 @@ ], "ci:coverage:unit": [ "@coverage:create-directories", - ".Build/vendor/bin/phpunit -c Tests/Unit/phpunit.xml --whitelist Classes --coverage-php=.Build/coverage/unit.cov Tests/Unit" + ".Build/vendor/bin/phpunit -c Tests/Unit/phpunit.xml Classes --coverage-php=.Build/coverage/unit.cov Tests/Unit" ], "coverage:create-directories": "mkdir -p build/logs .Build/coverage", "ci:json:lint": [ diff --git a/ext_emconf.php b/ext_emconf.php index 3263a2f1..bc311997 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -15,11 +15,11 @@ 'author_email' => 'extensions@macopedia.pl', 'author_company' => 'Macopedia Sp. z o.o.', 'category' => 'fe', - 'version' => '4.4.1', + 'version' => '4.5.0', 'constraints' => [ 'depends' => [ - 'frontend' => '12.4.3-12.5.99', - 'typo3' => '12.4.3-12.5.99' + 'frontend' => '12.4.21-13.4.99', + 'typo3' => '12.4.21-13.4.99' ], 'conflicts' => [], 'suggests' => [],