Skip to content
Draft
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
4 changes: 4 additions & 0 deletions apps/dav/appinfo/v1/caldav.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin;
use OCA\DAV\Connector\Sabre\MaintenancePlugin;
use OCA\DAV\Connector\Sabre\Principal;
use OCA\DAV\Events\SabrePluginAddEvent;
use OCP\Accounts\IAccountManager;
use OCP\App\IAppManager;
use OCP\EventDispatcher\IEventDispatcher;
Expand Down Expand Up @@ -128,5 +129,8 @@
$server->addPlugin(Server::get(RateLimitingPlugin::class));
$server->addPlugin(Server::get(CalDavValidatePlugin::class));

// allow setup of additional plugins
$dispatcher->dispatchTyped(new SabrePluginAddEvent($server));

// And off we go!
$server->start();
4 changes: 4 additions & 0 deletions apps/dav/appinfo/v1/carddav.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin;
use OCA\DAV\Connector\Sabre\MaintenancePlugin;
use OCA\DAV\Connector\Sabre\Principal;
use OCA\DAV\Events\SabrePluginAddEvent;
use OCP\Accounts\IAccountManager;
use OCP\App\IAppManager;
use OCP\EventDispatcher\IEventDispatcher;
Expand Down Expand Up @@ -106,5 +107,8 @@
$server->addPlugin(Server::get(CardDavRateLimitingPlugin::class));
$server->addPlugin(Server::get(CardDavValidatePlugin::class));

// allow setup of additional plugins
Server::get(IEventDispatcher::class)->dispatchTyped(new SabrePluginAddEvent($server));

// And off we go!
$server->start();
76 changes: 76 additions & 0 deletions apps/dav/tests/unit/AppInfo/LegacyEndpointsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\DAV\Tests\unit\AppInfo;

use OCA\DAV\Events\SabrePluginAddEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IRequest;
use OCP\Server;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use Sabre\DAV\Server as SabreServer;
use Test\TestCase;

/**
* The legacy endpoints (remote.php/webdav, caldav and carddav) let apps add
* their plugins, like remote.php/dav does.
*/
#[Group(name: 'DB')]
class LegacyEndpointsTest extends TestCase {
public static function endpoints(): array {
return [
'webdav' => ['v1/webdav.php', '/remote.php/webdav', null],
'caldav' => ['v1/caldav.php', '/remote.php/caldav', 'caldav'],
'carddav' => ['v1/carddav.php', '/remote.php/carddav', 'carddav'],
];
}

#[DataProvider(methodName: 'endpoints')]
public function testTheEndpointDispatchesSabrePluginAddEvent(string $file, string $baseuri, ?string $plugin): void {
$server = $this->serverOf(__DIR__ . '/../../../appinfo/' . $file, $baseuri);

$this->assertInstanceOf(SabreServer::class, $server, 'The event was dispatched before the server started');
if ($plugin !== null) {
$this->assertNotNull($server->getPlugin($plugin));
}
}

/**
* Runs an endpoint up to the event and returns the server it carries.
*/
private function serverOf(string $endpoint, string $baseuri): ?SabreServer {
$request = $this->createMock(IRequest::class);
$request->method('getRequestUri')->willReturn($baseuri . '/');
$this->overwriteService(IRequest::class, $request);
$captured = null;
$listener = static function (SabrePluginAddEvent $event) use (&$captured): void {
$captured = $event->getServer();
throw new \RuntimeException('stop before the server starts');
};
$dispatcher = Server::get(IEventDispatcher::class);
$dispatcher->addListener(SabrePluginAddEvent::class, $listener, -1000);
// The endpoints close every output buffer; PHPUnit expects its own back.
$level = ob_get_level();
try {
(static function (string $endpoint, string $baseuri): void {
require $endpoint;
})($endpoint, $baseuri);
} catch (\RuntimeException $e) {
$this->assertSame('stop before the server starts', $e->getMessage());
} finally {
while (ob_get_level() < $level) {
ob_start();
}
$dispatcher->removeListener(SabrePluginAddEvent::class, $listener);
$this->restoreService(IRequest::class);
}
return $captured;
}
}
Loading