Skip to content

Add standalone PHP unit test suite (no Nextcloud checkout needed) - #399

Open
R0Wi wants to merge 1 commit into
masterfrom
claude/nextcloud-independent-php-tests-q4vgwo
Open

Add standalone PHP unit test suite (no Nextcloud checkout needed)#399
R0Wi wants to merge 1 commit into
masterfrom
claude/nextcloud-independent-php-tests-q4vgwo

Conversation

@R0Wi

@R0Wi R0Wi commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

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 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01Kaif5z7SuTvEMonu4eTHjw

@R0Wi
R0Wi force-pushed the claude/nextcloud-independent-php-tests-q4vgwo branch 2 times, most recently from bfd9cde to 1f95468 Compare September 11, 2026 09:46

R0Wi commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

php8.5-sqlite-COVERAGE is failing on this PR's head, but it's not this PR's failure — it's already red on master itself, at both commits this branch has since rebased onto (5379ad2 and 58c3125), and was still green at bca032a before them. This PR never touches NotifierTest.php's test logic (only added a #[Group('nextcloud-full')] attribute + its import for the new standalone suite).

Root cause: OCP\Files\IUserFolder (@since 36.0.0) was just added to nextcloud/server:masterIRootFolder::getUserFolder()'s return type narrowed from Folder to this new interface. tests/Unit/Notification/NotifierTest.php still mocks Folder::class for that return value in 3 places (lines ~163, ~262, ~315), which no longer satisfies the declared return type:

PHPUnit\Framework\MockObject\IncompatibleReturnValueException: Method getUserFolder may not return
value of type MockObject_Folder_da846c50, its declared return type is "OCP\Files\IUserFolder"

No fix exists yet anywhere in the repo for this (checked open/closed PRs — #353 fixed a similar-shaped NC-version-bump break in this same file back in February, but not this one). Proposed patch, to be applied on master directly (out of scope for this PR):

- use OCP\Files\Folder;
+ use OCP\Files\IUserFolder;

and, at each of the 3 call sites:

- /** @var Folder|MockObject */
- $userFolder = $this->createMock(Folder::class);
+ /** @var IUserFolder|MockObject */
+ $userFolder = $this->createMock(IUserFolder::class);

I'm not pushing this into this PR since it's unrelated to its purpose (would be widening scope) — happy to open a dedicated fix PR if you'd like.


Generated by Claude Code

@R0Wi
R0Wi force-pushed the claude/nextcloud-independent-php-tests-q4vgwo branch from 1f95468 to 8ddb7f2 Compare September 11, 2026 10:14
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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kaif5z7SuTvEMonu4eTHjw
@R0Wi
R0Wi force-pushed the claude/nextcloud-independent-php-tests-q4vgwo branch from 8ddb7f2 to 756816d Compare September 12, 2026 04:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants