From 9d86d8a673695b348b68e96034e07046ace2987c Mon Sep 17 00:00:00 2001 From: Christian Kuhn Date: Tue, 6 Aug 2024 08:56:45 +0200 Subject: [PATCH] [TASK] Cli tests with phpunit .phpt files, ditch codeception (#123) Let's see if this works better than codeception. Only enabled with v12 since it uses bin/typo3 setup command. https://qa.php.net/phpt_details.php --- .github/workflows/testscorev11.yml | 21 - .github/workflows/testscorev12.yml | 24 +- .gitignore | 3 +- Build/FunctionalTests.xml | 5 +- Build/Scripts/runTests.sh | 81 +-- Tests/Acceptance/Cli.suite.yml | 13 - Tests/Acceptance/Cli/DbdoctorCommandCest.php | 35 -- Tests/Acceptance/Support/CliTester.php | 26 - .../Extension/BackendDbdoctorEnvironment.php | 44 -- Tests/Cli/InvalidArgumentTest.phpt | 570 ++++++++++++++++++ Tests/codeception.yml | 18 - composer.json | 3 - 12 files changed, 629 insertions(+), 214 deletions(-) delete mode 100644 Tests/Acceptance/Cli.suite.yml delete mode 100644 Tests/Acceptance/Cli/DbdoctorCommandCest.php delete mode 100644 Tests/Acceptance/Support/CliTester.php delete mode 100644 Tests/Acceptance/Support/Extension/BackendDbdoctorEnvironment.php create mode 100644 Tests/Cli/InvalidArgumentTest.phpt delete mode 100644 Tests/codeception.yml diff --git a/.github/workflows/testscorev11.yml b/.github/workflows/testscorev11.yml index f796ba6..07f5ab7 100644 --- a/.github/workflows/testscorev11.yml +++ b/.github/workflows/testscorev11.yml @@ -48,24 +48,3 @@ jobs: # is not fixed in doctrine core v11 doctrine 2.13.9 if: ${{ matrix.php <= '8.1' }} run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -d postgres -i 10 -s functional - - - name: Functional Tests with sqlite - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -d sqlite -s functional - - - name: Acceptance Tests mariadb and mysqli - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s acceptance -i 10.5 -d mariadb -a mysqli - - - name: Acceptance Tests mariadb and pdo_mysql - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s acceptance -i 10.5 -d mariadb -a pdo_mysql - - - name: Acceptance Tests mysql and mysqli - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s acceptance -i 8.0 -d mysql -a mysqli - - - name: Acceptance Tests mysql and pdo_mysql - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s acceptance -i 8.0 -d mysql -a pdo_mysql - - - name: Acceptance Tests postgres - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s acceptance -i 10 -d postgres - - - name: Acceptance Tests sqlite - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s acceptance -d sqlite diff --git a/.github/workflows/testscorev12.yml b/.github/workflows/testscorev12.yml index 65bf91c..25d5f83 100644 --- a/.github/workflows/testscorev12.yml +++ b/.github/workflows/testscorev12.yml @@ -52,20 +52,20 @@ jobs: - name: Functional Tests with sqlite run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -d sqlite -s functional - - name: Acceptance Tests mariadb and mysqli - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s acceptance -d mariadb -i 10.5 -a mysqli + - name: Cli Tests mariadb and mysqli + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s cli -d mariadb -i 10.5 -a mysqli - - name: Acceptance Tests mariadb and pdo_mysql - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s acceptance -d mariadb -i 10.5 -a pdo_mysql + - name: Cli Tests mariadb and pdo_mysql + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s cli -d mariadb -i 10.5 -a pdo_mysql - - name: Acceptance Tests mysql and mysqli - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s acceptance -d mysql -i 8.0 -a mysqli + - name: Cli Tests mysql and mysqli + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s cli -d mysql -i 8.0 -a mysqli - - name: Acceptance Tests mysql and pdo_mysql - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s acceptance -d mysql -i 8.0 -a pdo_mysql + - name: Cli Tests mysql and pdo_mysql + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s cli -d mysql -i 8.0 -a pdo_mysql - - name: Acceptance Tests postgres - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s acceptance -d postgres -i 10 + - name: Cli Tests postgres + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s cli -d postgres -i 10 - - name: Acceptance Tests sqlite - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s acceptance -d sqlite + - name: Cli Tests sqlite + run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s cli -d sqlite diff --git a/.gitignore b/.gitignore index 5d152ad..5fc8282 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ .idea/ composer.json.testing composer.lock -Tests/Acceptance/Support/_generated/ +config/ +var/ diff --git a/Build/FunctionalTests.xml b/Build/FunctionalTests.xml index 4a1def7..b7cc0a1 100644 --- a/Build/FunctionalTests.xml +++ b/Build/FunctionalTests.xml @@ -19,9 +19,12 @@ failOnWarning="true" > - + ../Tests/Functional/ + + ../Tests/Cli/ + diff --git a/Build/Scripts/runTests.sh b/Build/Scripts/runTests.sh index 19433d9..c1c4018 100755 --- a/Build/Scripts/runTests.sh +++ b/Build/Scripts/runTests.sh @@ -160,9 +160,9 @@ No arguments: Run all unit tests with PHP 8.1 Options: -s <...> Specifies which test suite to run - - acceptance: backend acceptance tests - cgl: cgl test and fix all php files - clean: clean up build and testing related files + - cli: cli end-to-end tests - composerUpdate: "composer update", handy if host has no PHP - functional: functional tests - lint: PHP linting @@ -171,7 +171,7 @@ Options: - unit (default): PHP unit tests -a - Only with -s acceptance,functional + Only with -s cli,functional Specifies to use another driver, following combinations are available: - mysql - mysqli (default) @@ -186,7 +186,7 @@ Options: - docker -d - Only with -s acceptance,functional + Only with -s cli,functional Specifies on which DBMS tests are performed - sqlite: (default) use sqlite - mariadb: use mariadb @@ -246,7 +246,7 @@ Options: - 12: Use TYPO3 core v12 -x - Only with -s functional|unit|acceptance + Only with -s functional|unit|cli Send information to host instance for test or system under test break points. This is especially useful if a local PhpStorm instance is listening on default xdebug port 9003. A different port can be selected with -y @@ -432,54 +432,57 @@ fi # Suite execution case ${TEST_SUITE} in - acceptance) - mkdir -p "${ROOT_DIR}/.Build/Web/typo3temp/var/tests/" - COMMAND=(./.Build/bin/codecept run Cli -d -c ./Tests/codeception.yml "$@" --html reports.html) - rm -rf "${ROOT_DIR}/.Build/Web/typo3temp/var/tests/acceptance" "${ROOT_DIR}/.Build/Web/typo3temp/var/tests/AcceptanceReports" - mkdir -p "${ROOT_DIR}/.Build/Web/typo3temp/var/tests/acceptance" + cgl) + # Active dry-run for cgl needs not "-n" but specific options + if [ -n "${CGLCHECK_DRY_RUN}" ]; then + CGLCHECK_DRY_RUN="--dry-run --diff" + fi + COMMAND="php -dxdebug.mode=off ./.Build/bin/php-cs-fixer fix -v ${CGLCHECK_DRY_RUN} --show-progress none --config=Build/php-cs-fixer/config.php" + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name cgl-${SUFFIX} ${IMAGE_PHP} ${COMMAND} + SUITE_EXIT_CODE=$? + ;; + clean) + rm -rf ./composer.lock ./.Build/ ./composer.json.testing ./config ./var + ;; + cli) + COMMAND=(./.Build/bin/phpunit -c Build/FunctionalTests.xml --testsuite Cli "$@") case ${DBMS} in mariadb) - ${CONTAINER_BIN} run --rm ${CI_PARAMS} --name mariadb-ac-${SUFFIX} --network ${NETWORK} -d -e MYSQL_ROOT_PASSWORD=funcp --tmpfs /var/lib/mysql/:rw,noexec,nosuid ${IMAGE_MARIADB} >/dev/null - waitFor mariadb-ac-${SUFFIX} 3306 - CONTAINERPARAMS="-e typo3DatabaseName=func_test -e typo3DatabaseUsername=root -e typo3DatabasePassword=funcp -e typo3DatabaseHost=mariadb-ac-${SUFFIX}" - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name ac-mariadb ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${CONTAINERPARAMS} ${IMAGE_PHP} "${COMMAND[@]}" + ${CONTAINER_BIN} run --rm ${CI_PARAMS} --name mariadb-func-${SUFFIX} --network ${NETWORK} -d -e MYSQL_DATABASE=func -e MYSQL_ROOT_PASSWORD=funcp --tmpfs /var/lib/mysql/:rw,noexec,nosuid ${IMAGE_MARIADB} >/dev/null + waitFor mariadb-func-${SUFFIX} 3306 + SETUPCOMMAND=(./.Build/bin/typo3 setup -n --force --admin-user-password=Admin123! --server-type=other --driver=mysqli --dbname=func --username=root --password=funcp --host=mariadb-func-${SUFFIX}) + ${CONTAINER_BIN} run --rm ${CONTAINER_COMMON_PARAMS} --name functional-setup-${SUFFIX} ${IMAGE_PHP} "${SETUPCOMMAND[@]}" + CONTAINERPARAMS="-e typo3DatabaseDriver=${DATABASE_DRIVER} -e typo3DatabaseName=func_test -e typo3DatabaseUsername=root -e typo3DatabaseHost=mariadb-func-${SUFFIX} -e typo3DatabasePassword=funcp" + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name functional-${SUFFIX} ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${CONTAINERPARAMS} ${IMAGE_PHP} "${COMMAND[@]}" SUITE_EXIT_CODE=$? ;; mysql) - ${CONTAINER_BIN} run --rm ${CI_PARAMS} --name mysql-ac-${SUFFIX} --network ${NETWORK} -d -e MYSQL_ROOT_PASSWORD=funcp --tmpfs /var/lib/mysql/:rw,noexec,nosuid ${IMAGE_MYSQL} >/dev/null - waitFor mysql-ac-${SUFFIX} 3306 - CONTAINERPARAMS="-e typo3DatabaseName=func_test -e typo3DatabaseUsername=root -e typo3DatabasePassword=funcp -e typo3DatabaseHost=mysql-ac-${SUFFIX}" - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name ac-mysql ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${CONTAINERPARAMS} ${IMAGE_PHP} "${COMMAND[@]}" + ${CONTAINER_BIN} run --rm ${CI_PARAMS} --name mysql-func-${SUFFIX} --network ${NETWORK} -d -e MYSQL_DATABASE=func -e MYSQL_ROOT_PASSWORD=funcp --tmpfs /var/lib/mysql/:rw,noexec,nosuid ${IMAGE_MYSQL} >/dev/null + waitFor mysql-func-${SUFFIX} 3306 + SETUPCOMMAND=(./.Build/bin/typo3 setup -n --force --admin-user-password=Admin123! --server-type=other --driver=mysqli --dbname=func --username=root --password=funcp --host=mysql-func-${SUFFIX}) + ${CONTAINER_BIN} run --rm ${CONTAINER_COMMON_PARAMS} --name functional-setup-${SUFFIX} ${IMAGE_PHP} "${SETUPCOMMAND[@]}" + CONTAINERPARAMS="-e typo3DatabaseDriver=${DATABASE_DRIVER} -e typo3DatabaseName=func_test -e typo3DatabaseUsername=root -e typo3DatabaseHost=mysql-func-${SUFFIX} -e typo3DatabasePassword=funcp" + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name functional-${SUFFIX} ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${CONTAINERPARAMS} ${IMAGE_PHP} "${COMMAND[@]}" SUITE_EXIT_CODE=$? ;; postgres) - ${CONTAINER_BIN} run --rm ${CI_PARAMS} --name postgres-ac-${SUFFIX} --network ${NETWORK} -d -e POSTGRES_PASSWORD=funcp -e POSTGRES_USER=funcu --tmpfs /var/lib/postgresql/data:rw,noexec,nosuid ${IMAGE_POSTGRES} >/dev/null - waitFor postgres-ac-${SUFFIX} 5432 - CONTAINERPARAMS="-e typo3DatabaseDriver=pdo_pgsql -e typo3DatabaseName=func_test -e typo3DatabaseUsername=funcu -e typo3DatabasePassword=funcp -e typo3DatabaseHost=postgres-ac-${SUFFIX}" - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name ac-postgres ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${CONTAINERPARAMS} ${IMAGE_PHP} "${COMMAND[@]}" + ${CONTAINER_BIN} run --rm ${CI_PARAMS} --name postgres-func-${SUFFIX} --network ${NETWORK} -d -e POSTGRES_PASSWORD=funcp -e POSTGRES_USER=funcu --tmpfs /var/lib/postgresql/data:rw,noexec,nosuid ${IMAGE_POSTGRES} >/dev/null + waitFor postgres-func-${SUFFIX} 5432 + SETUPCOMMAND=(./.Build/bin/typo3 setup -n --force --admin-user-password=Admin123! --server-type=other --driver=postgres --dbname=funcu --username=funcu --password=funcp --host=postgres-func-${SUFFIX} --port=5432) + ${CONTAINER_BIN} run --rm ${CONTAINER_COMMON_PARAMS} --name functional-setup-${SUFFIX} ${IMAGE_PHP} "${SETUPCOMMAND[@]}" + CONTAINERPARAMS="-e typo3DatabaseDriver=pdo_pgsql -e typo3DatabaseName=bamboo -e typo3DatabaseUsername=funcu -e typo3DatabaseHost=postgres-func-${SUFFIX} -e typo3DatabasePassword=funcp" + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name functional-${SUFFIX} ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${CONTAINERPARAMS} ${IMAGE_PHP} "${COMMAND[@]}" SUITE_EXIT_CODE=$? ;; sqlite) - rm -rf "${ROOT_DIR}/.Build/Web/typo3temp/var/tests/acceptance-sqlite-dbs/" - mkdir -p "${ROOT_DIR}/.Build/Web/typo3temp/var/tests/acceptance-sqlite-dbs/" + SETUPCOMMAND=(./.Build/bin/typo3 setup -n --force --admin-user-password=Admin123! --server-type=other --driver=sqlite) + ${CONTAINER_BIN} run --rm ${CONTAINER_COMMON_PARAMS} --name functional-setup-${SUFFIX} ${IMAGE_PHP} "${SETUPCOMMAND[@]}" CONTAINERPARAMS="-e typo3DatabaseDriver=pdo_sqlite" - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name ac-sqlite ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${CONTAINERPARAMS} ${IMAGE_PHP} "${COMMAND[@]}" + ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name functional-${SUFFIX} ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${CONTAINERPARAMS} ${IMAGE_PHP} "${COMMAND[@]}" SUITE_EXIT_CODE=$? ;; esac ;; - cgl) - # Active dry-run for cgl needs not "-n" but specific options - if [ -n "${CGLCHECK_DRY_RUN}" ]; then - CGLCHECK_DRY_RUN="--dry-run --diff" - fi - COMMAND="php -dxdebug.mode=off ./.Build/bin/php-cs-fixer fix -v ${CGLCHECK_DRY_RUN} --show-progress none --config=Build/php-cs-fixer/config.php" - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name cgl-${SUFFIX} ${IMAGE_PHP} ${COMMAND} - SUITE_EXIT_CODE=$? - ;; - clean) - rm -rf ./composer.lock ./.Build/ ./Tests/Acceptance/Support/_generated/ ./composer.json.testing - ;; composerUpdate) cp composer.json composer.json.orig if [ ${TYPO3_VERSION} -eq 11 ]; then @@ -500,10 +503,9 @@ case ${TEST_SUITE} in mv composer.json.orig composer.json ;; functional) - COMMAND=(./.Build/bin/phpunit -c Build/FunctionalTests.xml --exclude-group not-${DBMS} "$@") + COMMAND=(./.Build/bin/phpunit -c Build/FunctionalTests.xml --testsuite Functional --exclude-group not-${DBMS} "$@") case ${DBMS} in mariadb) - echo "Using driver: ${DATABASE_DRIVER}" ${CONTAINER_BIN} run --rm ${CI_PARAMS} --name mariadb-func-${SUFFIX} --network ${NETWORK} -d -e MYSQL_ROOT_PASSWORD=funcp --tmpfs /var/lib/mysql/:rw,noexec,nosuid ${IMAGE_MARIADB} >/dev/null waitFor mariadb-func-${SUFFIX} 3306 CONTAINERPARAMS="-e typo3DatabaseDriver=${DATABASE_DRIVER} -e typo3DatabaseName=func_test -e typo3DatabaseUsername=root -e typo3DatabaseHost=mariadb-func-${SUFFIX} -e typo3DatabasePassword=funcp" @@ -511,7 +513,6 @@ case ${TEST_SUITE} in SUITE_EXIT_CODE=$? ;; mysql) - echo "Using driver: ${DATABASE_DRIVER}" ${CONTAINER_BIN} run --rm ${CI_PARAMS} --name mysql-func-${SUFFIX} --network ${NETWORK} -d -e MYSQL_ROOT_PASSWORD=funcp --tmpfs /var/lib/mysql/:rw,noexec,nosuid ${IMAGE_MYSQL} >/dev/null waitFor mysql-func-${SUFFIX} 3306 CONTAINERPARAMS="-e typo3DatabaseDriver=${DATABASE_DRIVER} -e typo3DatabaseName=func_test -e typo3DatabaseUsername=root -e typo3DatabaseHost=mysql-func-${SUFFIX} -e typo3DatabasePassword=funcp" @@ -580,7 +581,7 @@ echo "########################################################################## echo "Result of ${TEST_SUITE}" >&2 echo "Container runtime: ${CONTAINER_BIN}" >&2 echo "PHP: ${PHP_VERSION}" >&2 -if [[ ${TEST_SUITE} =~ ^(functional|acceptance)$ ]]; then +if [[ ${TEST_SUITE} =~ ^(functional|cli)$ ]]; then case "${DBMS}" in mariadb|mysql|postgres) echo "DBMS: ${DBMS} version ${DBMS_VERSION} driver ${DATABASE_DRIVER}" >&2 diff --git a/Tests/Acceptance/Cli.suite.yml b/Tests/Acceptance/Cli.suite.yml deleted file mode 100644 index e3ed775..0000000 --- a/Tests/Acceptance/Cli.suite.yml +++ /dev/null @@ -1,13 +0,0 @@ -actor: CliTester -# @todo: Next one is obsolete when codeception 4 is dropped -class_name: CliTester -modules: - enabled: - - Asserts - -extensions: - enabled: - - Lolli\Dbdoctor\Tests\Acceptance\Support\Extension\BackendDbdoctorEnvironment - -groups: - AcceptanceTests-Job-*: AcceptanceTests-Job-* diff --git a/Tests/Acceptance/Cli/DbdoctorCommandCest.php b/Tests/Acceptance/Cli/DbdoctorCommandCest.php deleted file mode 100644 index 552eee8..0000000 --- a/Tests/Acceptance/Cli/DbdoctorCommandCest.php +++ /dev/null @@ -1,35 +0,0 @@ -amGoingTo('Call bin/typo3 dbdoctor:health'); - $I->runShellCommand($this->command); - $I->seeInShellOutput('Find and fix database inconsistencies'); - } -} diff --git a/Tests/Acceptance/Support/CliTester.php b/Tests/Acceptance/Support/CliTester.php deleted file mode 100644 index 47e15fb..0000000 --- a/Tests/Acceptance/Support/CliTester.php +++ /dev/null @@ -1,26 +0,0 @@ - [ - 'core', - 'extbase', - 'fluid', - 'backend', - 'install', - 'frontend', - 'recordlist', - 'impexp', - 'workspaces', - 'redirects', - ], - 'testExtensionsToLoad' => [ - 'typo3conf/ext/dbdoctor', - ], - ]; -} diff --git a/Tests/Cli/InvalidArgumentTest.phpt b/Tests/Cli/InvalidArgumentTest.phpt new file mode 100644 index 0000000..9a81b2b --- /dev/null +++ b/Tests/Cli/InvalidArgumentTest.phpt @@ -0,0 +1,570 @@ +--TEST-- +dbdoctor:health +--ARGS-- +dbdoctor:health +--FILE-- + 0) with + their default language record (l10n_parent field) not existing in the database. + Those translated pages are never shown in backend and frontend and removed. + + [OK] No affected records found%w + +Check pages with deleted language parent +---------------------------------------- + + Class: PagesTranslatedLanguageParentDeleted + Actions: soft-delete, workspace-remove + This health check finds not deleted but translated (sys_language_uid > 0) "pages" records, + with their default language record (l10n_parent field) being soft-deleted. + Those translated pages are never shown in backend and frontend. They are soft-deleted in + live and removed if they are workspace overlay records. + + [OK] No affected records found%w + +Check pages with different pid than their language parent +--------------------------------------------------------- + + Class: PagesTranslatedLanguageParentDifferentPid + Actions: remove + This health check finds translated "pages" records (sys_language_uid > 0) with + their default language record (l10n_parent field) on a different pid. + Those translated pages are shown in backend at a wrong place. They are removed. + + [OK] No affected records found%w + +Scan for record translations pointing to non default language parent +-------------------------------------------------------------------- + + Class: TcaTablesTranslatedParentInvalidPointer + Actions: update-fields + Record translations ("translate" / "connected" mode, as opposed to "free" mode) use the + database field "transOrigPointerField" (field name usually "l10n_parent" or "l18n_parent"). + This field points to the default language record. This health check verifies that target + actually has sys_language_uid = 0. Violating localizations are set to the transOrigPointerField + of the current target record. + + [OK] No affected records found%w + +Scan for tt_content on not existing pages +----------------------------------------- + + Class: TtContentPidMissing + Actions: remove + tt_content must have a "pid" page record that exists. Otherwise, they are most likely not editable + and can be removed. There are potential exceptions for tt_content records that are inline children + for example using "news" extension that may create such scenarios, but even then, those records + are most likely not shown in FE. You may want to look at some cases manually if this instance + has some weird scenarios where tt_content is used as inline child. Otherwise, it is usually ok + to let dbdoctor just REMOVE tt_content records that are located at a page that does not exist. + + [OK] No affected records found%w + +Scan for tt_content on soft-deleted pages +----------------------------------------- + + Class: TtContentPidDeleted + Actions: remove + tt_content must have a "pid" page record that is not soft-deleted. Otherwise, they are most likely + not editable. This is similar to the previous check, affected records will be soft-deleted if in + live, and removed if in workspaces. + + [OK] No affected records found%w + +Scan for soft-deleted localized tt_content records without parent +----------------------------------------------------------------- + + Class: TtContentDeletedLocalizedParentExists + Actions: remove + Soft deleted localized records in "tt_content" (sys_language_uid > 0) having + l18n_parent > 0 must point to a sys_language_uid = 0 existing language parent record. + Records violating this are removed. + + [OK] No affected records found%w + +Localized tt_content records without parent +------------------------------------------- + + Class: TtContentLocalizedParentExists + Actions: remove + Localized records in "tt_content" (sys_language_uid > 0) having + l18n_parent > 0 must point to a sys_language_uid = 0 existing language parent record. + Violating records are removed since they are typically never rendered in FE, + even though the BE renders them in page module. + + [OK] No affected records found%w + +Localized tt_content records with soft-deleted parent +----------------------------------------------------- + + Class: TtContentLocalizedParentSoftDeleted + Actions: soft-delete, workspace-remove + Not soft-deleted localized records in "tt_content" (sys_language_uid > 0) having + l18n_parent > 0 must point to a sys_language_uid = 0 language parent record that + is not soft-deleted as well. Violating records are set to soft-deleted as well (or + removed if in workspaces), since they are typically never rendered in FE, even + though the BE renders them in page module. + + [OK] No affected records found%w + +Scan for soft-deleted localized tt_content records with parent on different pid +------------------------------------------------------------------------------- + + Class: TtContentDeletedLocalizedParentDifferentPid + Actions: remove + Soft deleted localized records in "tt_content" (sys_language_uid > 0) having + l18n_parent > 0 must point to a sys_language_uid = 0 language parent record + on the same pid. Records violating this are removed. + + [OK] No affected records found%w + +Scan for localized tt_content records with parent on different pid +------------------------------------------------------------------ + + Class: TtContentLocalizedParentDifferentPid + Actions: update-fields, workspace-remove + Localized records in "tt_content" (sys_language_uid > 0) having + l18n_parent > 0 must point to a sys_language_uid = 0 language parent record + on the same pid. Records violating this are typically still shown in FE at + the correct page the l18n_parent lives on, but are shown in the BE at the + wrong page. Affected records are moved to the pid of the l18n_parent record + when possible, or removed in some workspace scenarios. + + [OK] No affected records found%w + +Duplicate localized tt_content records +-------------------------------------- + + Class: TtContentLocalizedDuplicates + Actions: remove + There must be only one localized record in "tt_content" per target language. + Having more than one leads to various issues in FE and BE. This check finds + duplicates, keeps the one with the lowest uid and soft-deletes others. + + [OK] No affected records found%w + +Localized tt_content records must point to existing localization source +----------------------------------------------------------------------- + + Class: TtContentLocalizationSourceExists + Actions: update-fields + When l10n_source is not zero, the target record must exist. + A broken l10n_source especially confuses the "Translate" button in page module. + Affected records l10n_source is set to l18n_parent if set, to zero otherwise. + + [OK] No affected records found%w + +Localized tt_content records must have localization source when parent is set +----------------------------------------------------------------------------- + + Class: TtContentLocalizationSourceSetWithParent + Actions: update-fields + When l18n_parent is not zero ("Connected mode"), l10n_source must not be zero. + A broken l10n_source especially confuses the "Translate" button in page module. + Affected records l10n_source is set to l18n_parent. + + [OK] No affected records found%w + +Localized tt_content records must have logically correct localization source +---------------------------------------------------------------------------- + + Class: TtContentLocalizationSourceLogicWithParent + Actions: update-fields + When tt_content l18n_parent and l10n_source are not zero but point to different uids, + it indicates this record "source" has been derived from a different language record + and not from the default language record. That different language record should have the + same l18n_parent. If this is not the case, set the tt_content l10n_source to the + value of l18n_parent to fix the inheritance chain. + + [OK] No affected records found%w + +Scan for sys_file_reference_records with broken table_local field +----------------------------------------------------------------- + + Class: SysFileReferenceInvalidTableLocal + Actions: disabled + This check is obsolete with TYPO3 core v12. + + [OK] No affected records found%w + +Scan for orphan sys_file_reference records +------------------------------------------ + + Class: SysFileReferenceDangling + Actions: remove + Basic check of sys_file_reference: Records referenced in uid_local and uid_foreign + must exist, otherwise that sys_file_reference row is obsolete and removed. + + [OK] No affected records found%w + +Scan for deleted localized sys_file_reference records without parent +-------------------------------------------------------------------- + + Class: SysFileReferenceDeletedLocalizedParentExists + Actions: remove + Soft deleted localized records in "sys_file_reference" (sys_language_uid > 0) having + l10n_parent > 0 must point to a sys_language_uid = 0 existing language parent record. + Records violating this are removed. + + [OK] No affected records found%w + +Scan for localized sys_file_reference records without parent +------------------------------------------------------------ + + Class: SysFileReferenceLocalizedParentExists + Actions: risky, remove + Localized records in "sys_file_reference" (sys_language_uid > 0) having + l10n_parent > 0 must point to a sys_language_uid = 0 existing language parent record. + Records violating this are REMOVED. + This change is risky. Records with an invalid l10n_parent pointer typically throw + an exception in the BE when edited. However, the FE often still shows such an image. + As such, when this check REMOVES records, you may want to check them manually by looking + at the referencing inline parent record indicated by fields "tablenames" and "uid_foreign" + to eventually find a better solution manually, for instance by setting l10n_parent=0 or + connecting it to the correct l10n_parent if in "connected mode", or by creating a new + image relation and then letting dbdoctor remove this one after reloading the check. + + [OK] No affected records found%w + +Scan for localized sys_file_reference records with deleted parent +----------------------------------------------------------------- + + Class: SysFileReferenceLocalizedParentDeleted + Actions: risky, soft-delete, workspace-remove + Localized, not deleted records in "sys_file_reference" (sys_language_uid > 0) having + l10n_parent > 0 must point to a sys_language_uid = 0, not soft-deleted, language parent record. + Records violating this are soft-deleted in live and removed if in workspaces. + This change is risky. Records with a deleted=1 l10n_parent typically throw + an exception in the BE when edited. However, the FE often still shows such an image. + As such, when this check soft-deletes or removes records, you may want to check them manually by + looking at the referencing inline parent record indicated by fields "tablenames" and "uid_foreign" + to eventually find a better solution manually, for instance by setting l10n_parent=0 or + connecting it to the correct l10n_parent if in "connected mode", or by creating a new + image relation and then letting dbdoctor remove this one after reloading the check. + + [OK] No affected records found%w + +Scan for localized sys_file_reference records with parent not in sync +--------------------------------------------------------------------- + + Class: SysFileReferenceLocalizedFieldSync + Actions: risky, soft-delete, workspace-remove + Localized records in "sys_file_reference" (sys_language_uid > 0) must have fields "tablenames" + and "fieldname" set to the same values as its language parent record. + Records violating this indicate something is wrong with this localized record. + This may happen for instance, when the tt_content ctype of a default language record is changed and + relations are adapted after the record has been localized. + This check is risky: It sets affected localized records to deleted=1 in live and removes + them if they are workspace overlay records. Depending on what is wrong, this may change FE output. + Look at "tablenames" and "uid_foreign" to see which inline parent record this relation is connected to, + and eventually take care of affected records yourself by creating new localizations if needed. + + [OK] No affected records found%w + +Scan for sys_file_reference records with invalid pid +---------------------------------------------------- + + Class: SysFileReferenceInvalidPid + Actions: update-fields + Records in "sys_file_reference" must have "pid" set to the same pid as the + parent record: If for instance a tt_content record on pid 5 references a sys_file, the + sys_file_reference record should be on pid 5, too. This updates the pid of affected records. + + [OK] No affected records found%w + +Scan for records on not existing pages +-------------------------------------- + + Class: TcaTablesPidMissing + Actions: remove + TCA records have a pid field set to a single page. This page must exist. + Records on pages that do not exist anymore are deleted. + + [OK] No affected records found%w + +Scan for not-deleted records on pages set to deleted +---------------------------------------------------- + + Class: TcaTablesPidDeleted + Actions: soft-delete, remove, workspace-remove + TCA records have a pid field set to a single page. This page must exist. + This scan finds deleted=0 records pointing to pages having deleted=1. + Affected records are soft deleted if possible, or removed. + + [OK] No affected records found%w + +Scan for record translations with missing parent +------------------------------------------------ + + Class: TcaTablesTranslatedLanguageParentMissing + Actions: remove + Record translations use the TCA ctrl field "transOrigPointerField" + (DB field name usually "l10n_parent" or "l18n_parent"). This field points to a + default language record. This health check verifies if that target exists. + Affected records without language parent are removed. + + [OK] No affected records found%w + +Scan for orphan sys_file_reference records +------------------------------------------ + + Class: SysFileReferenceDangling + Actions: remove + Basic check of sys_file_reference: Records referenced in uid_local and uid_foreign + must exist, otherwise that sys_file_reference row is obsolete and removed. + + [OK] No affected records found%w + +Scan for not-deleted record translations with deleted parent +------------------------------------------------------------ + + Class: TcaTablesTranslatedLanguageParentDeleted + Actions: soft-delete, workspace-remove + Record translations use the TCA ctrl field "transOrigPointerField" + (DB field name usually "l10n_parent" or "l18n_parent"). This field points to a + default language record. This health check verifies the target is not deleted=1. + Affected records are set to deleted=1 if in live, or removed if in workspaces. + + [OK] No affected records found%w + +Scan for record translations on wrong pid +----------------------------------------- + + Class: TcaTablesTranslatedLanguageParentDifferentPid + Actions: update-fields, soft-delete, remove, workspace-remove + Record translations use the TCA ctrl field "transOrigPointerField" + (DB field name usually "l10n_parent" or "l18n_parent"). This field points to a + default language record. This health check verifies translated records are on + the same pid as the default language record. It will move, hide or remove affected + records, which depends on potentially existing localizations on the target page. + + [OK] No affected records found%w + +Scan for inline foreign field records with missing parent +--------------------------------------------------------- + + Class: InlineForeignFieldChildrenParentMissing + Actions: remove + TCA inline foreign field records point to a parent record. This parent must exist. + This check is for inline children defined *with* foreign_table_field in TCA. + Inline children with missing parent are deleted. + + [OK] No affected records found%w + +Scan for inline foreign field records with missing parent +--------------------------------------------------------- + + Class: InlineForeignFieldNoForeignTableFieldChildrenParentMissing + Actions: remove + TCA inline foreign field records point to a parent record. This parent must exist. + This check is for inline children defined *without* foreign_table_field in TCA. + Inline children with missing parent are deleted. + + [OK] No affected records found%w + +Scan for inline foreign field records with deleted=1 parent +----------------------------------------------------------- + + Class: InlineForeignFieldChildrenParentDeleted + Actions: soft-delete, remove, workspace-remove + TCA inline foreign field records point to a parent record. When this parent is + soft-deleted, all children must be soft-deleted, too. + This check finds not soft-deleted children and sets soft-deleted for for live records, + or removes them when dealing with workspace records. + + [OK] No affected records found%w + +Scan for inline foreign field records with deleted=1 parent +----------------------------------------------------------- + + Class: InlineForeignFieldNoForeignTableFieldChildrenParentDeleted + Actions: soft-delete, remove, workspace-remove + TCA inline foreign field records point to a parent record. When this parent is + soft-deleted, all children must be soft-deleted, too. + This check is for inline children defined *without* foreign_table_field in TCA. + This check finds not soft-deleted children and sets soft-deleted for for live records, + or removes them when dealing with workspace records. + + [OK] No affected records found%w + +Scan for inline foreign field records with different language than their parent +------------------------------------------------------------------------------- + + Class: InlineForeignFieldChildrenParentLanguageDifferent + Actions: update-fields, risky + TCA inline foreign field child records point to a parent record. This check finds + child records that have a different language than the parent record. + Affected children are soft-deleted if the table is soft-delete aware, and + hard deleted if not. + + [OK] No affected records found%w + +Scan for inline foreign field records with different language than their parent +------------------------------------------------------------------------------- + + Class: InlineForeignFieldNoForeignTableFieldChildrenParentLanguageDifferent + Actions: update-fields, risky + TCA inline foreign field child records point to a parent record. This check finds + child records that have a different language than the parent record. + This check is for inline children defined *without* foreign_table_field in TCA. + Affected children are soft-deleted if the table is soft-delete aware, and + hard deleted if not. + + [OK] No affected records found%w diff --git a/Tests/codeception.yml b/Tests/codeception.yml deleted file mode 100644 index dd16f42..0000000 --- a/Tests/codeception.yml +++ /dev/null @@ -1,18 +0,0 @@ -namespace: Lolli\Dbdoctor\Tests\Acceptance\Support -paths: - tests: Acceptance - data: . - # @todo: Next one is obsolete when codeception 4 is dropped - log: ../.Build/Web/typo3temp/var/tests/AcceptanceReports - output: ../.Build/Web/typo3temp/var/tests/AcceptanceReports - support: Acceptance/Support -settings: - colors: true - memory_limit: 1024M -modules: - enabled: - - Codeception\Module\Cli -extensions: - enabled: - - Codeception\Extension\RunFailed - - Codeception\Extension\Recorder diff --git a/composer.json b/composer.json index d62020a..2dbc07a 100644 --- a/composer.json +++ b/composer.json @@ -27,9 +27,6 @@ }, "require-dev": { "bnf/phpstan-psr-container": "^1.0", - "codeception/codeception": "^4.1 || ^5.0.0", - "codeception/module-asserts": "^2.0 || ^3.0.0", - "codeception/module-cli": "^1.1 || ^2.0.0", "friendsofphp/php-cs-fixer": "^3.52.0", "friendsoftypo3/phpstan-typo3": "^0.9.0", "phpstan/phpstan": "^1.4.6",