Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions tests/bootstrap-stubs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

/**
* Loads the stubs for server-only classes the unit tests touch.
*
* Each stub loads only when the real class is absent. The stubs sit two directories
* below tests/Stubs so the early glob in tests/bootstrap.php cannot reach them:
* loaded before Nextcloud boots, the ExpressionBuilder stub shadows Doctrine's
* and the server cannot finish booting.
*
* @category Test
* @package OCA\Stackiq\Tests
* @author Conduction b.v. <[email protected]>
* @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. <[email protected]>
* 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';
}
21 changes: 2 additions & 19 deletions tests/bootstrap-unit.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
4 changes: 4 additions & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Loading