diff --git a/composer.json b/composer.json index 1cf3959f53175d2ab1d608dd62df5e07be0e532d..20f6b6f6a5f292d3840148efcdb63b2693776297 100644 --- a/composer.json +++ b/composer.json @@ -92,6 +92,7 @@ "codeception/codeception": "^4.1.22", "codeception/lib-asserts": "^1.13.2", "codeception/module-asserts": "^1.3.1", + "codeception/module-cli": "^1.1", "codeception/module-filesystem": "^1.0.3", "codeception/module-webdriver": "^1.2.1", "composer/package-versions-deprecated": "^1.11.99.2", diff --git a/composer.lock b/composer.lock index e3dfdf304e40844c3af22a546fc71c136817398a..b7e5ab19f553e2fcecbfbaad0dc7521e8325fd73 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5f735b56f523e7891b4c7a42c483dcdb", + "content-hash": "18ef972ae8ceffb3b4f8e1a1aef18269", "packages": [ { "name": "bacon/bacon-qr-code", @@ -5445,6 +5445,53 @@ }, "time": "2020-10-21T16:48:15+00:00" }, + { + "name": "codeception/module-cli", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/Codeception/module-cli.git", + "reference": "1f841ad4a1d43e5d9e60a43c4cc9e5af8008024f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/module-cli/zipball/1f841ad4a1d43e5d9e60a43c4cc9e5af8008024f", + "reference": "1f841ad4a1d43e5d9e60a43c4cc9e5af8008024f", + "shasum": "" + }, + "require": { + "codeception/codeception": "*@dev", + "php": ">=5.6.0 <9.0" + }, + "conflict": { + "codeception/codeception": "<4.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk" + } + ], + "description": "Codeception module for testing basic shell commands and shell output", + "homepage": "http://codeception.com/", + "keywords": [ + "codeception" + ], + "support": { + "issues": "https://github.com/Codeception/module-cli/issues", + "source": "https://github.com/Codeception/module-cli/tree/1.1.1" + }, + "time": "2020-12-26T16:56:19+00:00" + }, { "name": "codeception/module-filesystem", "version": "1.0.3", diff --git a/typo3/sysext/core/Tests/Acceptance/Application.suite.yml b/typo3/sysext/core/Tests/Acceptance/Application.suite.yml index fada464757823ed0f3cdee38f9cd0d48e2b59ffd..a9a73cf344fad3706a8a55ba93d70a207a6a26c8 100644 --- a/typo3/sysext/core/Tests/Acceptance/Application.suite.yml +++ b/typo3/sysext/core/Tests/Acceptance/Application.suite.yml @@ -13,6 +13,7 @@ modules: editor: ff83dfd81e20b34c27d3e97771a4525a admin: 886526ce72b86870739cc41991144ec1 - Asserts + - Codeception\Module\Cli extensions: enabled: diff --git a/typo3/sysext/core/Tests/Acceptance/Application/Cli/CommandCest.php b/typo3/sysext/core/Tests/Acceptance/Application/Cli/CommandCest.php new file mode 100644 index 0000000000000000000000000000000000000000..7ddaac9926b13623a1df736963716a511a2e5476 --- /dev/null +++ b/typo3/sysext/core/Tests/Acceptance/Application/Cli/CommandCest.php @@ -0,0 +1,74 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Core\Tests\Acceptance\Application\Cli; + +use TYPO3\CMS\Core\Tests\Acceptance\Support\ApplicationTester; + +/** + * Tests the styleguide backend module can be loaded + */ +class CommandCest +{ + protected string $typo3Cli = '../../../../bin/typo3 '; + + /** + * @param ApplicationTester $I + */ + public function runCommand(ApplicationTester $I): void + { + foreach ($this->commandTestDataProvider() as $command => $expectedCode) { + $I->runShellCommand($this->typo3Cli . $command, false); + $I->seeResultCodeIs($expectedCode); + } + } + + /** + * Test cli commands for their exit status + * + * 'site:show' and 'mailer:spool:send' fail + * due to missing configuration or unpredictable + * params. + */ + protected function commandTestDataProvider(): array + { + return [ + 'cleanup:flexforms' => 0, + 'cleanup:deletedrecords' => 0, + 'cleanup:multiplereferencedfiles --dry-run --update-refindex' => 0, + 'cleanup:lostfiles --dry-run --update-refindex' => 0, + 'cleanup:missingfiles --dry-run --update-refindex' => 0, + 'cleanup:missingrelations --dry-run --update-refindex' => 0, + 'cleanup:orphanrecords' => 0, + 'cleanup:previewlinks' => 0, + 'cleanup:versions' => 0, + 'extension:list' => 0, + 'extension:deactivate workspaces' => 0, + 'extension:activate workspaces' => 0, + 'language:update' => 0, + 'mailer:spool:send' => 1, + 'redirects:checkintegrity' => 0, + 'redirects:cleanup' => 0, + 'referenceindex:update --check' => 0, + 'scheduler:run' => 0, + 'site:list' => 0, + 'site:show' => 1, + 'syslog:list' => 0, + 'upgrade:list' => 0, + ]; + } +} diff --git a/typo3/sysext/core/Tests/Acceptance/Application/DbCheck/DbCheckModuleCest.php b/typo3/sysext/core/Tests/Acceptance/Application/DbCheck/DbCheckModuleCest.php index c70e1975ebb9c71bb0ba15d22f607682bf149070..3c7aa211603bfcf8fac7a154feb80e7e7eb3ad86 100644 --- a/typo3/sysext/core/Tests/Acceptance/Application/DbCheck/DbCheckModuleCest.php +++ b/typo3/sysext/core/Tests/Acceptance/Application/DbCheck/DbCheckModuleCest.php @@ -105,10 +105,10 @@ class DbCheckModuleCest $this->goToPageAndSeeHeadline($I, 'Manage Reference Index', 'Manage Reference Index'); $I->click('Check reference index'); - $I->waitForElement('.alert-danger'); + $I->waitForElement('.alert'); $I->click('Update reference index'); - $I->waitForElement('.alert-danger'); + $I->waitForElement('.alert'); $I->click('Check reference index'); $I->waitForElement('.alert-success'); diff --git a/typo3/sysext/install/Classes/Command/LanguagePackCommand.php b/typo3/sysext/install/Classes/Command/LanguagePackCommand.php index 70ea56423cdc9baacaa9438343b169906126c7a2..2ee1d110af23b5adf2346e6f2a2c13fdf7873218 100644 --- a/typo3/sysext/install/Classes/Command/LanguagePackCommand.php +++ b/typo3/sysext/install/Classes/Command/LanguagePackCommand.php @@ -126,7 +126,7 @@ class LanguagePackCommand extends Command } $languagePackService->setLastUpdatedIsoCode($isos); $progressBar->finish(); - + $output->writeln(''); // Flush language cache GeneralUtility::makeInstance(CacheManager::class)->getCache('l10n')->flush(); diff --git a/typo3/sysext/lowlevel/Classes/Command/ListSysLogCommand.php b/typo3/sysext/lowlevel/Classes/Command/ListSysLogCommand.php index b5a9e8c5c8146c85d5095394e33d2bdcefb85854..e8d62e242c966f042c0dd9459cfb00066e54794c 100644 --- a/typo3/sysext/lowlevel/Classes/Command/ListSysLogCommand.php +++ b/typo3/sysext/lowlevel/Classes/Command/ListSysLogCommand.php @@ -89,7 +89,7 @@ class ListSysLogCommand extends Command $row['uid'], BackendUtility::datetime($row['tstamp']), $userInformation, - sprintf($row['details'], $logData[0], $logData[1], $logData[2], $logData[3], $logData[4], $logData[5]) + sprintf($row['details'], ($logData[0] ?? ''), ($logData[1] ?? ''), ($logData[2] ?? ''), ($logData[3] ?? ''), ($logData[4] ?? ''), ($logData[5] ?? '')) ]; if ($showDetails) { diff --git a/typo3/sysext/lowlevel/Classes/Command/MissingRelationsCommand.php b/typo3/sysext/lowlevel/Classes/Command/MissingRelationsCommand.php index db1ec7aed5984eb9031f7abae7052062ae497362..a91680560cbf87c5a9847961ef679a0b14667d5c 100644 --- a/typo3/sysext/lowlevel/Classes/Command/MissingRelationsCommand.php +++ b/typo3/sysext/lowlevel/Classes/Command/MissingRelationsCommand.php @@ -278,7 +278,7 @@ If you want to get more detailed information, use the --verbose option.') // Compile info string for location of reference: $infoString = $this->formatReferenceIndexEntryToString($rec); // Handle missing file: - if ($existingRecords[$idx]['uid']) { + if ($existingRecords[$idx]['uid'] ?? false) { // Record exists, but is a reference to an offline version if ((int)($existingRecords[$idx]['t3ver_oid'] ?? 0) > 0) { if ($isSoftReference) { diff --git a/typo3/sysext/lowlevel/Classes/Command/OrphanRecordsCommand.php b/typo3/sysext/lowlevel/Classes/Command/OrphanRecordsCommand.php index 32e964ab197178f130f759c0c271a39e8ce4cc8f..1aed3ab91c796e1d4416949ee6be4751e35ab7a2 100644 --- a/typo3/sysext/lowlevel/Classes/Command/OrphanRecordsCommand.php +++ b/typo3/sysext/lowlevel/Classes/Command/OrphanRecordsCommand.php @@ -99,7 +99,7 @@ Manual repair suggestions: $orphans = []; foreach (array_keys($GLOBALS['TCA']) as $tableName) { $idList = [0]; - if (is_array($allRecords[$tableName]) && !empty($allRecords[$tableName])) { + if (is_array($allRecords[$tableName] ?? false) && !empty($allRecords[$tableName])) { $idList = $allRecords[$tableName]; } // Select all records that are NOT connected diff --git a/typo3/sysext/redirects/Classes/Service/IntegrityService.php b/typo3/sysext/redirects/Classes/Service/IntegrityService.php index af7fdb301582cb4231268504407d368d47a57778..2627430cb154d964b7886ee83398b9ee2b338fe1 100644 --- a/typo3/sysext/redirects/Classes/Service/IntegrityService.php +++ b/typo3/sysext/redirects/Classes/Service/IntegrityService.php @@ -126,7 +126,7 @@ class IntegrityService $row = $queryBuilder->execute()->fetchAssociative(); $subPages = $this->getSlugsOfSubPages($site->getRootPageId()); - $pages = array_merge([$site->getBase()->getPath() . '/', $row['slug']], $subPages); + $pages = array_merge([$site->getBase()->getPath() . '/', ($row['slug'] ?? '')], $subPages); return array_unique($pages); } diff --git a/typo3/sysext/workspaces/Classes/Command/WorkspaceVersionRecordsCommand.php b/typo3/sysext/workspaces/Classes/Command/WorkspaceVersionRecordsCommand.php index 7a47e7d65bf8d84670b4652b15e56a83701de666..36ee89f7e5c98b8fd4416beb7d4f4194628e4e9b 100644 --- a/typo3/sysext/workspaces/Classes/Command/WorkspaceVersionRecordsCommand.php +++ b/typo3/sysext/workspaces/Classes/Command/WorkspaceVersionRecordsCommand.php @@ -298,7 +298,7 @@ class WorkspaceVersionRecordsCommand extends Command ->execute(); while ($rowSub = $result->fetchAssociative()) { // Add any versions of those records - $versions = BackendUtility::selectVersionsOfRecord($tableName, $rowSub['uid'], 'uid,t3ver_wsid' . ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] ? ',' . $GLOBALS['TCA'][$tableName]['ctrl']['delete'] : ''), null, true); + $versions = BackendUtility::selectVersionsOfRecord($tableName, $rowSub['uid'], 'uid,t3ver_wsid' . (($GLOBALS['TCA'][$tableName]['ctrl']['delete'] ?? false) ? ',' . $GLOBALS['TCA'][$tableName]['ctrl']['delete'] : ''), null, true); if (is_array($versions)) { foreach ($versions as $verRec) { if (!$verRec['_CURRENT_VERSION']) {