From 2281bb034956dbc5609dfd6d1873b7187c4a2f83 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 10 Sep 2026 04:56:23 +0000 Subject: [PATCH] Add standalone PHP unit test suite (no Nextcloud checkout needed) Adds a second way to run tests/Unit/ that only needs `composer install`, using the existing nextcloud/ocp dependency for OCP/NCU symbols instead of a full Nextcloud checkout: - tests/bootstrap.standalone.php + phpunit.standalone.xml: new bootstrap and phpunit config, `make php-unittest-standalone`. - Six test files that only used Test\TestCase out of habit now extend plain PHPUnit\Framework\TestCase. - tests/Unit/TestUtils/: an invokePrivate replacement trait, plus small polyfills for classes nextcloud/ocp doesn't ship (OC\User\NoUserException, OC\Notification\Notification, OCA\Files_Versions\Versions\*, OCA\AppAPI\PublicFunctions), loaded only when not already autoloadable. - composer.json: nextcloud/ocp ships no autoload section, so autoload-dev adds a classmap for it plus a PSR-4 mapping for tests/Unit/. - Seven files that touch a real, non-trivial Nextcloud implementation (not just an interface) are excluded via #[Group('nextcloud-full')] and keep running only under phpunit.xml inside a full Nextcloud checkout: AppInfo/ApplicationTest, OcrProcessors/OcrProcessorFactoryTest, composer/AutoloadTest (real OCP\AppFramework\App), Wrapper/ViewFactoryTest (real OC\Files\View), BackgroundJobs/ProcessFileJobTest and Listener/RegisterFlowOperationsListenerTest (real OCP\Server::get() call chains), Notification/NotifierTest (real OC\Notification\Notification). CI: .github/workflows/phpunit.yml's sqlite/mysql/pgsql jobs now run `make php-integrationtest` instead of `make php-test`, since the unit suite doesn't vary by DB backend; a new `standalone` job covers the unit suite instead. The coverage workflow (sonarqube.yml) is untouched and is now the only pipeline still running the full, NC-bootstrapped unit suite. phpunit-integration.yml needed no change. CLAUDE.md and .github/copilot-instructions.md updated accordingly. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01Kaif5z7SuTvEMonu4eTHjw --- .github/copilot-instructions.md | 22 ++- .github/workflows/phpunit.yml | 39 +++- CLAUDE.md | 42 +++- Makefile | 4 + composer.json | 9 + phpunit.standalone.xml | 44 +++++ tests/Unit/AppInfo/ApplicationTest.php | 5 + .../BackgroundJobs/ProcessFileJobTest.php | 5 + .../GlobalSettingsControllerTest.php | 2 +- .../RegisterFlowOperationsListenerTest.php | 5 + tests/Unit/Model/WorkflowSettingsTest.php | 2 +- tests/Unit/Notification/NotifierTest.php | 6 + .../Local/ImageOcrProcessorTest.php | 2 +- .../OcrProcessors/OcrProcessorFactoryTest.php | 6 + .../Service/GlobalSettingsServiceTest.php | 2 +- tests/Unit/Service/OcrServiceTest.php | 5 +- tests/Unit/Settings/GlobalSettingsTest.php | 2 +- .../AppApiPublicFunctionsPolyfill.php | 38 ++++ .../Unit/TestUtils/FilesVersionsPolyfill.php | 47 +++++ .../Unit/TestUtils/InvokesPrivateMethods.php | 23 +++ .../TestUtils/NoUserExceptionPolyfill.php | 18 ++ tests/Unit/TestUtils/NotificationPolyfill.php | 180 ++++++++++++++++++ tests/Unit/Wrapper/ViewFactoryTest.php | 5 + tests/Unit/composer/AutoloadTest.php | 5 + tests/bootstrap.standalone.php | 59 ++++++ 25 files changed, 558 insertions(+), 19 deletions(-) create mode 100644 phpunit.standalone.xml create mode 100644 tests/Unit/TestUtils/AppApiPublicFunctionsPolyfill.php create mode 100644 tests/Unit/TestUtils/FilesVersionsPolyfill.php create mode 100644 tests/Unit/TestUtils/InvokesPrivateMethods.php create mode 100644 tests/Unit/TestUtils/NoUserExceptionPolyfill.php create mode 100644 tests/Unit/TestUtils/NotificationPolyfill.php create mode 100644 tests/bootstrap.standalone.php diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 6b99de5c..c9158e69 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -35,11 +35,20 @@ The app supports two OCR processing modes: ### Critical Context -**IMPORTANT**: This app cannot run standalone. For development, you MUST: +**IMPORTANT**: This app cannot *run* standalone, and most of its tests still need a real +Nextcloud instance. For development, you MUST: 1. Set up a full [Nextcloud Server](https://github.com/nextcloud/server) instance 2. Install this app into the Nextcloud installation -3. Tests must run within a working Nextcloud environment (see CI/CD workflows for examples) +3. `tests/Integration/` and the full `tests/Unit/` suite (`phpunit.xml`) must run within a + working Nextcloud environment (see CI/CD workflows for examples) + +**Exception**: most of `tests/Unit/` (all but seven files that touch a real, non-trivial +Nextcloud implementation rather than just an interface) can run standalone — clone, +`composer install`, then `make php-unittest-standalone` — with no Nextcloud checkout, +using the `nextcloud/ocp` composer package for `OCP\*`/`NCU\*` symbols. See CLAUDE.md's +"Critical constraints" for +the excluded files and the `dev-master` dependency risk. ### Target Version Compatibility @@ -244,11 +253,16 @@ Set Nextcloud log level to 0 for detailed debugging: ### General Guidelines -1. **Never assume standalone operation** - All development and testing requires a Nextcloud instance +1. **Never assume standalone operation for the app itself or for `tests/Integration/`** - + Running the app and its integration tests requires a Nextcloud instance. Most of + `tests/Unit/` is the one exception and runs standalone via + `make php-unittest-standalone` (see CLAUDE.md) 2. **Check Nextcloud Server code** - Always verify implementations against the target Nextcloud version 3. **Respect branching strategy** - Ensure changes are compatible with the target Nextcloud version 4. **Follow existing patterns** - The codebase has established patterns for controllers, services, and processors -5. **Test within Nextcloud** - Tests cannot run in isolation; they need the Nextcloud environment +5. **Integration tests need Nextcloud** - `tests/Integration/` and the full `tests/Unit/` + suite need the Nextcloud environment; most of `tests/Unit/` runs standalone via + `make php-unittest-standalone` 6. **Consider both backends** - Changes may affect both local CLI and external backend processing modes ### Before Committing Changes diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index bb90c02b..9a13ccdf 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -65,7 +65,40 @@ jobs: php -S localhost:8080 & - name: PHPUnit working-directory: apps/${{ env.APP_NAME }} - run: make php-test + run: make php-integrationtest + + # Runs tests/Unit without a Nextcloud checkout (see phpunit.standalone.xml). The + # sqlite/mysql/pgsql jobs above only run the integration suite now, since the unit + # suite is fully mocked and produces identical results regardless of DB backend. The + # full, NC-bootstrapped unit suite (phpunit.xml, including the files excluded here via + # the nextcloud-full group) still runs once, in the PHPUnit-Coverage workflow. + standalone: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php-versions: ['8.4', '8.5'] + + name: standalone-php${{ matrix.php-versions }} + + steps: + - name: Checkout app + uses: actions/checkout@v5 + + - name: Set up php ${{ matrix.php-versions }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + tools: phpunit + extensions: mbstring, iconv, fileinfo, intl, gd, zip, imagick + coverage: none + + - name: Install dependencies + run: composer i + + - name: PHPUnit (standalone) + run: make php-unittest-standalone mysql: runs-on: ubuntu-22.04 @@ -131,7 +164,7 @@ jobs: php -S localhost:8080 & - name: PHPUnit working-directory: apps/${{ env.APP_NAME }} - run: make php-test + run: make php-integrationtest pgsql: runs-on: ubuntu-22.04 @@ -199,4 +232,4 @@ jobs: php -S localhost:8080 & - name: PHPUnit working-directory: apps/${{ env.APP_NAME }} - run: make php-test + run: make php-integrationtest diff --git a/CLAUDE.md b/CLAUDE.md index 28a09c3e..76977d63 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,11 +7,30 @@ ExApp). Both repos are versioned in lock-step and share a REST contract — see ## Critical constraints -- **The app cannot run or be tested standalone.** PHP unit *and* integration tests boot - Nextcloud via `tests/bootstrap.php` and need a Nextcloud checkout with this app - installed under `apps/workflow_ocr` and enabled (`php occ app:enable workflow_ocr`). - Use the devcontainer (`.devcontainer/`) or mirror `.github/workflows/phpunit*.yml`. - JS tests (`vitest`) are the only suite that runs without Nextcloud. +- **Most of `tests/Unit/` runs standalone.** `make php-unittest-standalone` + (bootstrap `tests/bootstrap.standalone.php`, config `phpunit.standalone.xml`) needs + only `composer install` — no Nextcloud checkout — because it resolves `OCP\*`/`NCU\*` + via the `nextcloud/ocp` composer dependency instead of a real NC core, with a handful + of small polyfills in `tests/Unit/TestUtils/` for legacy/other-app classes + `nextcloud/ocp` doesn't ship (`OC\User\NoUserException`, `OC\Notification\Notification`, + `OCA\Files_Versions\Versions\*`, `OCA\AppAPI\PublicFunctions`). Seven files that touch a + real, non-trivial Nextcloud implementation (not just an interface) are excluded via + `#[Group('nextcloud-full')]` and still run only under `phpunit.xml`: + `AppInfo/ApplicationTest.php`, `OcrProcessors/OcrProcessorFactoryTest.php`, + `composer/AutoloadTest.php` (all construct a real `OCP\AppFramework\App`, needing + `\OC::$server` and Nextcloud's internal DI container), `Wrapper/ViewFactoryTest.php` + (real `OC\Files\View`), `BackgroundJobs/ProcessFileJobTest.php` and + `Listener/RegisterFlowOperationsListenerTest.php` (call real OCP methods that + internally use `OCP\Server::get()`/`\OC::$server`), and `Notification/NotifierTest.php` + (real `OC\Notification\Notification`, whose validation logic is too much to safely + polyfill). In CI, only the coverage workflow (`.github/workflows/sonarqube.yml`) still + runs the full, NC-bootstrapped unit suite; `phpunit.yml`'s other jobs use the + standalone suite instead. +- **`tests/Integration/` and the full `tests/Unit/` suite (`phpunit.xml`) still need a + full Nextcloud checkout.** Both boot Nextcloud via `tests/bootstrap.php` and need a + Nextcloud checkout with this app installed under `apps/workflow_ocr` and enabled + (`php occ app:enable workflow_ocr`). Use the devcontainer (`.devcontainer/`) or mirror + `.github/workflows/phpunit*.yml`. JS tests (`vitest`) also run without Nextcloud. - **Every change must be considered against both backend modes** (local CLI and remote ExApp). A change to settings, CLI arguments, or processors usually touches both paths. - **Target Nextcloud version comes from `appinfo/info.xml`** (``), @@ -25,7 +44,9 @@ ExApp). Both repos are versioned in lock-step and share a REST contract — see PHP 8.2–8.5 (composer platform pin 8.4, psalm `phpVersion` 8.2) · Vue 3 · Node ^24 / npm ^11.6 · rsbuild + vitest · phpunit 12 · psalm 6.4 · php-cs-fixer via -`nextcloud/coding-standard` · `nextcloud/ocp` for OCP stubs. +`nextcloud/coding-standard` · `nextcloud/ocp` for OCP stubs and (as of the standalone +unit suite) real `OCP\*`/`NCU\*` symbols at test-run time — an unpinned `dev-master` +dependency, see "Critical constraints". Namespace `OCA\WorkflowOcr\`, PSR-4 from `lib/`. Frontend sources in `src/`, built into `js/` by rsbuild (`make npm-build`). @@ -124,6 +145,7 @@ Run from the repo root. The Makefile is authoritative — there is no `make unit ```bash make build # composer (no-dev) + npm install + rsbuild build make php-unittest # phpunit -c phpunit.xml (tests/Unit) +make php-unittest-standalone # phpunit -c phpunit.standalone.xml (tests/Unit, no NC checkout) make php-integrationtest # phpunit -c phpunit.integration.xml (tests/Integration) make php-test # both PHP suites make js-test # vitest unit + integration @@ -152,6 +174,14 @@ clean. Never add to the psalm baseline to silence a new error you introduced. matrix value names are load-bearing, do not rename them. - Test PDFs/images live in `tests/Integration/testdata/`. - JS tests are `src/test/**/*.spec.js` with `@nextcloud/*` mocks in `src/test/__mocks__/`. +- `tests/Unit/TestUtils/` holds standalone-suite-only scaffolding (an `invokePrivate` + replacement trait, plus polyfills for classes `nextcloud/ocp` doesn't ship) needed + only because `phpunit.standalone.xml` doesn't have a full Nextcloud core to draw on. + Mirrors the `tests/Integration/TestUtils/` convention. `nextcloud/ocp` itself ships no + composer `autoload` section, so `composer.json`'s `autoload-dev` adds a `classmap` over + `vendor/nextcloud/ocp/{OCP,NCU}/` to make its classes loadable at all, plus a PSR-4 + mapping for `tests/Unit/` (so test-only support classes like + `tests/Unit/Service/IMetadataVersionWithBackend.php` autoload without a manual require). ## Conventions diff --git a/Makefile b/Makefile index 7e6a5c41..5920745f 100644 --- a/Makefile +++ b/Makefile @@ -192,6 +192,10 @@ php-test: composer php-unittest: composer $(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.xml +.PHONY: php-unittest-standalone +php-unittest-standalone: composer + $(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.standalone.xml + .PHONY: php-integrationtest php-integrationtest: composer $(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.integration.xml diff --git a/composer.json b/composer.json index 873b994e..fe5793d7 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,15 @@ "OCA\\WorkflowOcr\\": "lib/" } }, + "autoload-dev": { + "psr-4": { + "OCA\\WorkflowOcr\\Tests\\Unit\\": "tests/Unit/" + }, + "classmap": [ + "vendor/nextcloud/ocp/OCP/", + "vendor/nextcloud/ocp/NCU/" + ] + }, "scripts": { "lint": "find . -name \\*.php -not -path './vendor/*' -not -path './node_modules/*' -exec php -l \"{}\" \\;", "cs:check": "php-cs-fixer fix --dry-run --diff", diff --git a/phpunit.standalone.xml b/phpunit.standalone.xml new file mode 100644 index 00000000..481b419c --- /dev/null +++ b/phpunit.standalone.xml @@ -0,0 +1,44 @@ + + + + + ./tests/Unit + + ./tests/Unit/OcrProcessors/OcrProcessorFactoryTest.php + + + + + nextcloud-full + + + + + ./ + + + ./appinfo + ./l10n + ./templates + ./tests + ./vendor + ./node_modules + ./lib/Migration + ./lib/OcrProcessors/Remote/Client/Model + ./lib/OcrProcessors/Remote/Client/Configuration.php + ./lib/OcrProcessors/Remote/Client/ObjectSerializer.php + ./.php-cs-fixer.dist.php + + + diff --git a/tests/Unit/AppInfo/ApplicationTest.php b/tests/Unit/AppInfo/ApplicationTest.php index ed453aea..3df882e6 100644 --- a/tests/Unit/AppInfo/ApplicationTest.php +++ b/tests/Unit/AppInfo/ApplicationTest.php @@ -25,9 +25,14 @@ use OCA\WorkflowOcr\AppInfo\Application; use OCP\AppFramework\Bootstrap\IBootContext; +use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +// Constructs a real OCP\AppFramework\App (via Application), which needs \OC::$server +// and Nextcloud's internal DI container — requires a full Nextcloud checkout. Excluded +// from the standalone suite (see phpunit.standalone.xml). +#[Group('nextcloud-full')] class ApplicationTest extends TestCase { public function testBootDoesNothingOnBootContext() { /** @var IBootContext|MockObject */ diff --git a/tests/Unit/BackgroundJobs/ProcessFileJobTest.php b/tests/Unit/BackgroundJobs/ProcessFileJobTest.php index a7412196..dbe729ba 100644 --- a/tests/Unit/BackgroundJobs/ProcessFileJobTest.php +++ b/tests/Unit/BackgroundJobs/ProcessFileJobTest.php @@ -27,10 +27,15 @@ use OCA\WorkflowOcr\Service\IOcrService; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\IJobList; +use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; +// Calling the real inherited start() (via QueuedJob/Job) internally calls +// OCP\Server::get(), which needs \OC::$server -- requires a full Nextcloud checkout. +// Excluded from the standalone suite (see phpunit.standalone.xml). +#[Group('nextcloud-full')] class ProcessFileJobTest extends TestCase { /** @var LoggerInterface|MockObject */ private $logger; diff --git a/tests/Unit/Controller/GlobalSettingsControllerTest.php b/tests/Unit/Controller/GlobalSettingsControllerTest.php index 4a1fe628..aa3d1e8a 100644 --- a/tests/Unit/Controller/GlobalSettingsControllerTest.php +++ b/tests/Unit/Controller/GlobalSettingsControllerTest.php @@ -31,8 +31,8 @@ use OCP\IRequest; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; -use Test\TestCase; class GlobalSettingsControllerTest extends TestCase { /** @var IGlobalSettingsService|MockObject */ diff --git a/tests/Unit/Listener/RegisterFlowOperationsListenerTest.php b/tests/Unit/Listener/RegisterFlowOperationsListenerTest.php index 63c7ddfd..4a0fe213 100644 --- a/tests/Unit/Listener/RegisterFlowOperationsListenerTest.php +++ b/tests/Unit/Listener/RegisterFlowOperationsListenerTest.php @@ -34,10 +34,15 @@ use OCP\WorkflowEngine\Events\RegisterOperationsEvent; use OCP\WorkflowEngine\IManager; use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Container\ContainerInterface; +// Real OCP\Util::addScript() internally calls OCP\Server::get(), which needs +// \OC::$server -- requires a full Nextcloud checkout. Excluded from the standalone +// suite (see phpunit.standalone.xml). +#[Group('nextcloud-full')] class RegisterFlowOperationsListenerTest extends TestCase { /** @var ContainerInterface|MockObject */ private $container; diff --git a/tests/Unit/Model/WorkflowSettingsTest.php b/tests/Unit/Model/WorkflowSettingsTest.php index 78e42bac..f32e2055 100644 --- a/tests/Unit/Model/WorkflowSettingsTest.php +++ b/tests/Unit/Model/WorkflowSettingsTest.php @@ -26,7 +26,7 @@ use InvalidArgumentException; use OCA\WorkflowOcr\Model\WorkflowSettings; use PHPUnit\Framework\Attributes\DataProvider; -use Test\TestCase; +use PHPUnit\Framework\TestCase; class WorkflowSettingsTest extends TestCase { #[DataProvider('dataProvider_testConstruction')] diff --git a/tests/Unit/Notification/NotifierTest.php b/tests/Unit/Notification/NotifierTest.php index 89c0632e..ece1e26b 100644 --- a/tests/Unit/Notification/NotifierTest.php +++ b/tests/Unit/Notification/NotifierTest.php @@ -38,10 +38,16 @@ use OCP\Notification\INotification; use OCP\RichObjectStrings\IRichTextFormatter; use OCP\RichObjectStrings\IValidator; +use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; +// Instantiates the real Nextcloud\OC\Notification\Notification for its actual fluent +// setter/getter/validation behavior (not just as a mock target), which is too much +// internal logic to safely reproduce in a polyfill. Excluded from the standalone suite +// (see phpunit.standalone.xml). +#[Group('nextcloud-full')] class NotifierTest extends TestCase { /** @var IFactory|MockObject */ private $l10nFactory; diff --git a/tests/Unit/OcrProcessors/Local/ImageOcrProcessorTest.php b/tests/Unit/OcrProcessors/Local/ImageOcrProcessorTest.php index 37cb6de5..055daea9 100644 --- a/tests/Unit/OcrProcessors/Local/ImageOcrProcessorTest.php +++ b/tests/Unit/OcrProcessors/Local/ImageOcrProcessorTest.php @@ -31,8 +31,8 @@ use OCA\WorkflowOcr\Wrapper\ICommand; use OCP\Files\File; use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; -use Test\TestCase; class ImageOcrProcessorTest extends TestCase { /** @var \OCA\WorkflowOcr\Wrapper\IPhpNativeFunctions|MockObject */ diff --git a/tests/Unit/OcrProcessors/OcrProcessorFactoryTest.php b/tests/Unit/OcrProcessors/OcrProcessorFactoryTest.php index 25ef87e0..0aad30f4 100644 --- a/tests/Unit/OcrProcessors/OcrProcessorFactoryTest.php +++ b/tests/Unit/OcrProcessors/OcrProcessorFactoryTest.php @@ -31,10 +31,16 @@ use OCA\WorkflowOcr\OcrProcessors\Remote\WorkflowOcrRemoteProcessor; use OCA\WorkflowOcr\Service\IOcrBackendInfoService; use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\MockObject\MockObject; use Psr\Container\ContainerInterface; use Test\TestCase; +// Constructs a real OCP\AppFramework\App (via Application) and resolves services from +// its DI container, which needs \OC::$server and Nextcloud's internal DI container — +// requires a full Nextcloud checkout. Excluded from the standalone suite (see +// phpunit.standalone.xml). +#[Group('nextcloud-full')] class OcrProcessorFactoryTest extends TestCase { /** @var ContainerInterface */ private $appContainer; diff --git a/tests/Unit/Service/GlobalSettingsServiceTest.php b/tests/Unit/Service/GlobalSettingsServiceTest.php index e63d5f60..f322f2a3 100644 --- a/tests/Unit/Service/GlobalSettingsServiceTest.php +++ b/tests/Unit/Service/GlobalSettingsServiceTest.php @@ -28,7 +28,7 @@ use OCA\WorkflowOcr\Service\GlobalSettingsService; use OCP\IAppConfig; use PHPUnit\Framework\MockObject\MockObject; -use Test\TestCase; +use PHPUnit\Framework\TestCase; class GlobalSettingsServiceTest extends TestCase { /** @var IAppConfig|MockObject */ diff --git a/tests/Unit/Service/OcrServiceTest.php b/tests/Unit/Service/OcrServiceTest.php index d1368ac3..91456fcb 100644 --- a/tests/Unit/Service/OcrServiceTest.php +++ b/tests/Unit/Service/OcrServiceTest.php @@ -43,6 +43,7 @@ use OCA\WorkflowOcr\Service\IGlobalSettingsService; use OCA\WorkflowOcr\Service\INotificationService; use OCA\WorkflowOcr\Service\OcrService; +use OCA\WorkflowOcr\Tests\Unit\TestUtils\InvokesPrivateMethods; use OCA\WorkflowOcr\Wrapper\IFilesystem; use OCA\WorkflowOcr\Wrapper\IView; use OCA\WorkflowOcr\Wrapper\IViewFactory; @@ -57,10 +58,12 @@ use OCP\SystemTag\ISystemTagObjectMapper; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; -use Test\TestCase; class OcrServiceTest extends TestCase { + use InvokesPrivateMethods; + /** @var IOcrProcessorFactory|MockObject */ private $ocrProcessorFactory; /** @var IOcrProcessor|MockObject */ diff --git a/tests/Unit/Settings/GlobalSettingsTest.php b/tests/Unit/Settings/GlobalSettingsTest.php index 827ab43e..f55dae67 100644 --- a/tests/Unit/Settings/GlobalSettingsTest.php +++ b/tests/Unit/Settings/GlobalSettingsTest.php @@ -24,7 +24,7 @@ namespace OCA\WorkflowOcr\Tests\Unit\Settings; use OCA\WorkflowOcr\Settings\GlobalSettings; -use Test\TestCase; +use PHPUnit\Framework\TestCase; class GlobalSettingsTest extends TestCase { /** @var GlobalSettings */ diff --git a/tests/Unit/TestUtils/AppApiPublicFunctionsPolyfill.php b/tests/Unit/TestUtils/AppApiPublicFunctionsPolyfill.php new file mode 100644 index 00000000..1feea576 --- /dev/null +++ b/tests/Unit/TestUtils/AppApiPublicFunctionsPolyfill.php @@ -0,0 +1,38 @@ + $args + * @return mixed + */ + protected function invokePrivate(object $object, string $methodName, array $args = []) { + $reflectionMethod = new \ReflectionMethod($object, $methodName); + $reflectionMethod->setAccessible(true); + return $reflectionMethod->invokeArgs($object, $args); + } +} diff --git a/tests/Unit/TestUtils/NoUserExceptionPolyfill.php b/tests/Unit/TestUtils/NoUserExceptionPolyfill.php new file mode 100644 index 00000000..1c159555 --- /dev/null +++ b/tests/Unit/TestUtils/NoUserExceptionPolyfill.php @@ -0,0 +1,18 @@ +