From d436dda8db640f8227269d8883b0b2cf639422c4 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 3 Nov 2026 17:55:42 +0100 Subject: [PATCH] fix(tests): keep the standalone Doctrine and Symfony stubs out of the CI bootstrap #1400 put the Doctrine and HeaderUtils stubs one directory below tests/Stubs. tests/bootstrap.php, the bootstrap CI runs, loads every file that deep before Nextcloud boots, so the stub ExpressionBuilder (without eq()) replaced Doctrine's. The server then could not finish booting, OpenRegister never loaded, and every PHPUnit cell failed on its missing event classes. The stubs move to tests/Stubs/Standalone/, out of that glob's reach, and tests/bootstrap-stubs.php loads each one only when the real class is absent. bootstrap-unit.php requires it as before; bootstrap.php requires it after the boot, so a run without a server still finds them. Assisted-by: ClaudeCode:claude-opus-5-5 --- .../Doctrine/ArrayParameterType.php | 0 .../Doctrine/ExpressionBuilder.php | 0 .../Doctrine/ParameterType.php | 0 .../Stubs/{ => Standalone}/Doctrine/Types.php | 0 .../{ => Standalone}/Symfony/HeaderUtils.php | 0 tests/bootstrap-stubs.php | 42 +++++++++++++++++++ tests/bootstrap-unit.php | 21 +--------- tests/bootstrap.php | 4 ++ 8 files changed, 48 insertions(+), 19 deletions(-) rename tests/Stubs/{ => Standalone}/Doctrine/ArrayParameterType.php (100%) rename tests/Stubs/{ => Standalone}/Doctrine/ExpressionBuilder.php (100%) rename tests/Stubs/{ => Standalone}/Doctrine/ParameterType.php (100%) rename tests/Stubs/{ => Standalone}/Doctrine/Types.php (100%) rename tests/Stubs/{ => Standalone}/Symfony/HeaderUtils.php (100%) create mode 100644 tests/bootstrap-stubs.php diff --git a/tests/Stubs/Doctrine/ArrayParameterType.php b/tests/Stubs/Standalone/Doctrine/ArrayParameterType.php similarity index 100% rename from tests/Stubs/Doctrine/ArrayParameterType.php rename to tests/Stubs/Standalone/Doctrine/ArrayParameterType.php diff --git a/tests/Stubs/Doctrine/ExpressionBuilder.php b/tests/Stubs/Standalone/Doctrine/ExpressionBuilder.php similarity index 100% rename from tests/Stubs/Doctrine/ExpressionBuilder.php rename to tests/Stubs/Standalone/Doctrine/ExpressionBuilder.php diff --git a/tests/Stubs/Doctrine/ParameterType.php b/tests/Stubs/Standalone/Doctrine/ParameterType.php similarity index 100% rename from tests/Stubs/Doctrine/ParameterType.php rename to tests/Stubs/Standalone/Doctrine/ParameterType.php diff --git a/tests/Stubs/Doctrine/Types.php b/tests/Stubs/Standalone/Doctrine/Types.php similarity index 100% rename from tests/Stubs/Doctrine/Types.php rename to tests/Stubs/Standalone/Doctrine/Types.php diff --git a/tests/Stubs/Symfony/HeaderUtils.php b/tests/Stubs/Standalone/Symfony/HeaderUtils.php similarity index 100% rename from tests/Stubs/Symfony/HeaderUtils.php rename to tests/Stubs/Standalone/Symfony/HeaderUtils.php diff --git a/tests/bootstrap-stubs.php b/tests/bootstrap-stubs.php new file mode 100644 index 000000000..d651ef506 --- /dev/null +++ b/tests/bootstrap-stubs.php @@ -0,0 +1,42 @@ + + * @copyright 2026 Conduction B.V. + * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * @link https://github.com/ConductionNL/stackiq + * + * SPDX-FileCopyrightText: 2026 Conduction B.V. + * SPDX-License-Identifier: EUPL-1.2 + */ + +declare(strict_types=1); + +// OCP\DB\QueryBuilder\IQueryBuilder initialises its PARAM_* class constants +// from Doctrine constants at class-load, and IExpressionBuilder reads +// Doctrine's ExpressionBuilder, so mocking OCP\IDBConnection fatals without +// them. The real classes ship with the Nextcloud server at runtime. +if (class_exists(\Doctrine\DBAL\ParameterType::class) === false) { + require_once __DIR__ . '/Stubs/Standalone/Doctrine/ParameterType.php'; + require_once __DIR__ . '/Stubs/Standalone/Doctrine/ArrayParameterType.php'; + require_once __DIR__ . '/Stubs/Standalone/Doctrine/Types.php'; +} + +if (class_exists(\Doctrine\DBAL\Query\Expression\ExpressionBuilder::class) === false) { + require_once __DIR__ . '/Stubs/Standalone/Doctrine/ExpressionBuilder.php'; +} + +// OCP's DownloadResponse builds its Content-Disposition with Symfony's +// HeaderUtils, which only the server ships. +if (class_exists(\Symfony\Component\HttpFoundation\HeaderUtils::class) === false) { + require_once __DIR__ . '/Stubs/Standalone/Symfony/HeaderUtils.php'; +} diff --git a/tests/bootstrap-unit.php b/tests/bootstrap-unit.php index b41ab1d44..49ad039a1 100644 --- a/tests/bootstrap-unit.php +++ b/tests/bootstrap-unit.php @@ -91,22 +91,5 @@ unset($integriqStubEvent); -// OCP\DB\QueryBuilder\IQueryBuilder initialises its PARAM_* class constants -// from Doctrine constants at class-load, and IExpressionBuilder reads -// Doctrine's ExpressionBuilder, so mocking OCP\IDBConnection fatals without -// them. The real classes ship with the Nextcloud server at runtime. -if (class_exists(\Doctrine\DBAL\ParameterType::class) === false) { - require_once __DIR__ . '/Stubs/Doctrine/ParameterType.php'; - require_once __DIR__ . '/Stubs/Doctrine/ArrayParameterType.php'; - require_once __DIR__ . '/Stubs/Doctrine/Types.php'; -} - -if (class_exists(\Doctrine\DBAL\Query\Expression\ExpressionBuilder::class) === false) { - require_once __DIR__ . '/Stubs/Doctrine/ExpressionBuilder.php'; -} - -// OCP's DownloadResponse builds its Content-Disposition with Symfony's -// HeaderUtils, which only the server ships. -if (class_exists(\Symfony\Component\HttpFoundation\HeaderUtils::class) === false) { - require_once __DIR__ . '/Stubs/Symfony/HeaderUtils.php'; -} +// Doctrine and Symfony classes only the server ships; see bootstrap-stubs.php. +require_once __DIR__ . '/bootstrap-stubs.php'; diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 9d39d07ed..22ee73a38 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -203,3 +203,7 @@ function stackiq_nc_root_is_installed(string $ncRoot): bool ) { require_once __DIR__ . '/Stubs/OpenRegister/Event/ObjectCreatedEvent.php'; } + +// Doctrine and Symfony classes only the server ships, for a run without a +// booted server. After a boot class_exists() finds the real ones. +require_once __DIR__ . '/bootstrap-stubs.php';