diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 6d3c2bc..05de7a8 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -25,4 +25,26 @@ // OCP/Guzzle dev dependencies are enough for the pure unit tests. require_once __DIR__ . '/../vendor/autoload.php'; require_once __DIR__ . '/../vendor-bin/nextcloud-ocp/vendor/autoload.php'; + + // The nextcloud/ocp package is a stub collection without an autoload + // section (psalm scans it as extra files), so OCP\… must be mapped by + // hand for tests that mock OCP interfaces. + spl_autoload_register(function (string $class): void { + if (str_starts_with($class, 'OCP\\')) { + $file = __DIR__ . '/../vendor-bin/nextcloud-ocp/vendor/nextcloud/ocp/' + . str_replace('\\', '/', $class) . '.php'; + if (file_exists($file)) { + require_once $file; + } + } + }); + + // \OC::$SERVERROOT appears as a default argument in resolveLogDir(); PHP + // evaluates default arguments on every call, so the class must exist even + // when the mocked config never lets that default win. + if (!class_exists('OC')) { + class OC { + public static string $SERVERROOT = '/srv/nextcloud'; + } + } } diff --git a/tests/unit/Http/Client/LoggingClientServiceTest.php b/tests/unit/Http/Client/LoggingClientServiceTest.php new file mode 100644 index 0000000..697ffd2 --- /dev/null +++ b/tests/unit/Http/Client/LoggingClientServiceTest.php @@ -0,0 +1,92 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCA\AdminAuditHttpClient\Tests\Unit\Http\Client; + +use OCA\AdminAuditHttpClient\Http\Client\LoggingClientService; +use OCP\Http\Client\IClientService; +use OCP\IConfig; +use OCP\IRequest; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; + +class LoggingClientServiceTest extends TestCase { + private function service(array $stringValues, array $values = []): LoggingClientService { + $config = $this->createMock(IConfig::class); + $config->method('getSystemValueString')->willReturnCallback( + fn (string $key, string $default = ''): string => $stringValues[$key] ?? $default, + ); + $config->method('getSystemValue')->willReturnCallback( + fn (string $key, $default = '') => $values[$key] ?? $default, + ); + + return new LoggingClientService( + $this->createMock(IClientService::class), + new NullLogger(), + $config, + $this->createMock(IRequest::class), + ); + } + + private function resolveLogDir(LoggingClientService $service): string { + $ref = new \ReflectionMethod($service, 'resolveLogDir'); + return $ref->invoke($service); + } + + public function testExplicitLogdirWinsAndTrailingSlashIsTrimmed(): void { + $service = $this->service( + ['audit_http_client_logdir' => '/var/log/nextcloud/http_client/'], + ['datadirectory' => '/srv/nc/data'], + ); + $this->assertSame('/var/log/nextcloud/http_client', $this->resolveLogDir($service)); + } + + public function testAuditLogSiblingOutsideTheDataDirectory(): void { + $service = $this->service( + ['logfile_audit' => '/var/log/nextcloud/audit.log'], + ['datadirectory' => '/srv/nc/data'], + ); + $this->assertSame('/var/log/nextcloud/client', $this->resolveLogDir($service)); + } + + public function testAuditLogInsideTheDataDirectoryUsesTheDataDirSubfolder(): void { + $service = $this->service( + ['logfile_audit' => '/srv/nc/data/audit.log'], + ['datadirectory' => '/srv/nc/data'], + ); + $this->assertSame('/srv/nc/data/admin_audit_http_client_logs', $this->resolveLogDir($service)); + } + + public function testLogfileSiblingWhenNoAuditLogIsConfigured(): void { + $service = $this->service( + ['logfile' => '/var/log/nextcloud/nextcloud.log'], + ['datadirectory' => '/srv/nc/data'], + ); + $this->assertSame('/var/log/nextcloud/client', $this->resolveLogDir($service)); + } + + public function testDefaultsToTheDataDirSubfolder(): void { + $service = $this->service( + [], + ['datadirectory' => '/srv/nc/data'], + ); + $this->assertSame('/srv/nc/data/admin_audit_http_client_logs', $this->resolveLogDir($service)); + } + + public function testAuditLogWinsOverLogfile(): void { + $service = $this->service( + [ + 'logfile_audit' => '/var/log/nextcloud-audit/audit.log', + 'logfile' => '/var/log/nextcloud/nextcloud.log', + ], + ['datadirectory' => '/srv/nc/data'], + ); + $this->assertSame('/var/log/nextcloud-audit/client', $this->resolveLogDir($service)); + } +}