diff options
Diffstat (limited to 'tests/lib')
36 files changed, 1064 insertions, 439 deletions
diff --git a/tests/lib/AppFramework/Http/RequestIdTest.php b/tests/lib/AppFramework/Http/RequestIdTest.php index b3cfe2a8f4a..9cfd3b1785c 100644 --- a/tests/lib/AppFramework/Http/RequestIdTest.php +++ b/tests/lib/AppFramework/Http/RequestIdTest.php @@ -49,11 +49,7 @@ class RequestIdTest extends \Test\TestCase { $this->secureRandom->expects($this->once()) ->method('generate') ->with('20') - ->willReturnOnConsecutiveCalls( - 'GeneratedByNextcloudItself1', - 'GeneratedByNextcloudItself2', - 'GeneratedByNextcloudItself3' - ); + ->willReturn('GeneratedByNextcloudItself1'); $this->assertSame('GeneratedByNextcloudItself1', $requestId->getId()); $this->assertSame('GeneratedByNextcloudItself1', $requestId->getId()); diff --git a/tests/lib/AppFramework/Http/RequestTest.php b/tests/lib/AppFramework/Http/RequestTest.php index fe3614ab88e..781cca256ec 100644 --- a/tests/lib/AppFramework/Http/RequestTest.php +++ b/tests/lib/AppFramework/Http/RequestTest.php @@ -251,7 +251,7 @@ class RequestTest extends \Test\TestCase { $this->assertSame('someothertestvalue', $result['propertyB']); } - public function notJsonDataProvider() { + public static function dataNotJsonData(): array { return [ ['this is not valid json'], ['"just a string"'], @@ -260,9 +260,9 @@ class RequestTest extends \Test\TestCase { } /** - * @dataProvider notJsonDataProvider + * @dataProvider dataNotJsonData */ - public function testNotJsonPost($testData): void { + public function testNotJsonPost(string $testData): void { global $data; $data = $testData; $vars = [ @@ -544,7 +544,7 @@ class RequestTest extends \Test\TestCase { $this->assertEquals('3', $request->getParams()['id']); } - public function dataGetRemoteAddress(): array { + public static function dataGetRemoteAddress(): array { return [ 'IPv4 without trusted remote' => [ [ @@ -714,14 +714,10 @@ class RequestTest extends \Test\TestCase { public function testGetRemoteAddress(array $headers, array $trustedProxies, array $forwardedForHeaders, string $expected): void { $this->config ->method('getSystemValue') - ->withConsecutive( - ['trusted_proxies'], - ['forwarded_for_headers'], - ) - ->willReturnOnConsecutiveCalls( - $trustedProxies, - $forwardedForHeaders, - ); + ->willReturnMap([ + ['trusted_proxies', [], $trustedProxies], + ['forwarded_for_headers', ['HTTP_X_FORWARDED_FOR'], $forwardedForHeaders], + ]); $request = new Request( [ @@ -736,10 +732,7 @@ class RequestTest extends \Test\TestCase { $this->assertSame($expected, $request->getRemoteAddress()); } - /** - * @return array - */ - public function httpProtocolProvider() { + public static function dataHttpProtocol(): array { return [ // Valid HTTP 1.0 ['HTTP/1.0', 'HTTP/1.0'], @@ -766,7 +759,7 @@ class RequestTest extends \Test\TestCase { } /** - * @dataProvider httpProtocolProvider + * @dataProvider dataHttpProtocol * * @param mixed $input * @param string $expected @@ -956,7 +949,7 @@ class RequestTest extends \Test\TestCase { } /** - * @dataProvider userAgentProvider + * @dataProvider dataUserAgent * @param string $testAgent * @param array $userAgent * @param bool $matches @@ -978,7 +971,7 @@ class RequestTest extends \Test\TestCase { } /** - * @dataProvider userAgentProvider + * @dataProvider dataUserAgent * @param string $testAgent * @param array $userAgent * @param bool $matches @@ -995,10 +988,7 @@ class RequestTest extends \Test\TestCase { $this->assertFalse($request->isUserAgent($userAgent)); } - /** - * @return array - */ - public function userAgentProvider() { + public static function dataUserAgent(): array { return [ [ 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)', @@ -1117,7 +1107,7 @@ class RequestTest extends \Test\TestCase { ]; } - public function dataMatchClientVersion(): array { + public static function dataMatchClientVersion(): array { return [ [ 'Mozilla/5.0 (Android) Nextcloud-android/3.24.1', @@ -1373,10 +1363,7 @@ class RequestTest extends \Test\TestCase { $this->assertSame('', $request->getServerHost()); } - /** - * @return array - */ - public function dataGetServerHostTrustedDomain() { + public static function dataGetServerHostTrustedDomain(): array { return [ 'is array' => ['my.trusted.host', ['my.trusted.host']], 'is array but undefined index 0' => ['my.trusted.host', [2 => 'my.trusted.host']], @@ -1387,10 +1374,8 @@ class RequestTest extends \Test\TestCase { /** * @dataProvider dataGetServerHostTrustedDomain - * @param $expected - * @param $trustedDomain */ - public function testGetServerHostTrustedDomain($expected, $trustedDomain): void { + public function testGetServerHostTrustedDomain(string $expected, $trustedDomain): void { $this->config ->method('getSystemValue') ->willReturnCallback(function ($key, $default) use ($trustedDomain) { @@ -1499,7 +1484,7 @@ class RequestTest extends \Test\TestCase { } /** - * @dataProvider genericPathInfoProvider + * @dataProvider dataGenericPathInfo * @param string $requestUri * @param string $scriptName * @param string $expected @@ -1522,7 +1507,7 @@ class RequestTest extends \Test\TestCase { } /** - * @dataProvider genericPathInfoProvider + * @dataProvider dataGenericPathInfo * @param string $requestUri * @param string $scriptName * @param string $expected @@ -1545,7 +1530,7 @@ class RequestTest extends \Test\TestCase { } /** - * @dataProvider rawPathInfoProvider + * @dataProvider dataRawPathInfo * @param string $requestUri * @param string $scriptName * @param string $expected @@ -1568,7 +1553,7 @@ class RequestTest extends \Test\TestCase { } /** - * @dataProvider pathInfoProvider + * @dataProvider dataPathInfo * @param string $requestUri * @param string $scriptName * @param string $expected @@ -1590,10 +1575,7 @@ class RequestTest extends \Test\TestCase { $this->assertSame($expected, $request->getPathInfo()); } - /** - * @return array - */ - public function genericPathInfoProvider() { + public static function dataGenericPathInfo(): array { return [ ['/core/index.php?XDEBUG_SESSION_START=14600', '/core/index.php', ''], ['/index.php/apps/files/', 'index.php', '/apps/files/'], @@ -1605,19 +1587,13 @@ class RequestTest extends \Test\TestCase { ]; } - /** - * @return array - */ - public function rawPathInfoProvider() { + public static function dataRawPathInfo(): array { return [ ['/foo%2Fbar/subfolder', '', 'foo%2Fbar/subfolder'], ]; } - /** - * @return array - */ - public function pathInfoProvider() { + public static function dataPathInfo(): array { return [ ['/foo%2Fbar/subfolder', '', 'foo/bar/subfolder'], ]; @@ -1645,7 +1621,7 @@ class RequestTest extends \Test\TestCase { $this->assertSame('/test.php', $request->getRequestUri()); } - public function providesGetRequestUriWithOverwriteData() { + public static function dataGetRequestUriWithOverwrite(): array { return [ ['/scriptname.php/some/PathInfo', '/owncloud/', ''], ['/scriptname.php/some/PathInfo', '/owncloud/', '123', '123.123.123.123'], @@ -1653,7 +1629,7 @@ class RequestTest extends \Test\TestCase { } /** - * @dataProvider providesGetRequestUriWithOverwriteData + * @dataProvider dataGetRequestUriWithOverwrite */ public function testGetRequestUriWithOverwrite($expectedUri, $overwriteWebRoot, $overwriteCondAddr, $remoteAddr = ''): void { $this->config @@ -1665,7 +1641,7 @@ class RequestTest extends \Test\TestCase { ]); $request = $this->getMockBuilder(Request::class) - ->setMethods(['getScriptName']) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -1690,8 +1666,8 @@ class RequestTest extends \Test\TestCase { public function testPassesCSRFCheckWithGet(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'get' => [ @@ -1720,8 +1696,8 @@ class RequestTest extends \Test\TestCase { public function testPassesCSRFCheckWithPost(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'post' => [ @@ -1750,8 +1726,8 @@ class RequestTest extends \Test\TestCase { public function testPassesCSRFCheckWithHeader(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -1780,8 +1756,8 @@ class RequestTest extends \Test\TestCase { public function testPassesCSRFCheckWithGetAndWithoutCookies(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'get' => [ @@ -1804,8 +1780,8 @@ class RequestTest extends \Test\TestCase { public function testPassesCSRFCheckWithPostAndWithoutCookies(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'post' => [ @@ -1828,8 +1804,8 @@ class RequestTest extends \Test\TestCase { public function testPassesCSRFCheckWithHeaderAndWithoutCookies(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -1852,8 +1828,8 @@ class RequestTest extends \Test\TestCase { public function testFailsCSRFCheckWithHeaderAndNotAllChecksPassing(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -1879,8 +1855,8 @@ class RequestTest extends \Test\TestCase { public function testPassesStrictCookieCheckWithAllCookiesAndStrict(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName', 'getCookieParams']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName', 'getCookieParams']) ->setConstructorArgs([ [ 'server' => [ @@ -1911,8 +1887,8 @@ class RequestTest extends \Test\TestCase { public function testFailsStrictCookieCheckWithAllCookiesAndMissingStrict(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName', 'getCookieParams']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName', 'getCookieParams']) ->setConstructorArgs([ [ 'server' => [ @@ -1944,7 +1920,7 @@ class RequestTest extends \Test\TestCase { public function testGetCookieParams(): void { /** @var Request $request */ $request = $this->getMockBuilder(Request::class) - ->setMethods(['getScriptName']) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [], $this->requestId, @@ -1959,8 +1935,8 @@ class RequestTest extends \Test\TestCase { public function testPassesStrictCookieCheckWithAllCookies(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -1984,8 +1960,8 @@ class RequestTest extends \Test\TestCase { public function testPassesStrictCookieCheckWithRandomCookies(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -2007,8 +1983,8 @@ class RequestTest extends \Test\TestCase { public function testFailsStrictCookieCheckWithSessionCookie(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -2030,8 +2006,8 @@ class RequestTest extends \Test\TestCase { public function testFailsStrictCookieCheckWithRememberMeCookie(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -2053,8 +2029,8 @@ class RequestTest extends \Test\TestCase { public function testFailsCSRFCheckWithPostAndWithCookies(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'post' => [ @@ -2080,8 +2056,8 @@ class RequestTest extends \Test\TestCase { public function testFailStrictCookieCheckWithOnlyLaxCookie(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -2104,8 +2080,8 @@ class RequestTest extends \Test\TestCase { public function testFailStrictCookieCheckWithOnlyStrictCookie(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -2128,8 +2104,8 @@ class RequestTest extends \Test\TestCase { public function testPassesLaxCookieCheck(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -2152,8 +2128,8 @@ class RequestTest extends \Test\TestCase { public function testFailsLaxCookieCheckWithOnlyStrictCookie(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -2176,8 +2152,8 @@ class RequestTest extends \Test\TestCase { public function testSkipCookieCheckForOCSRequests(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -2199,10 +2175,7 @@ class RequestTest extends \Test\TestCase { $this->assertTrue($request->passesStrictCookieCheck()); } - /** - * @return array - */ - public function invalidTokenDataProvider() { + public static function dataInvalidToken(): array { return [ ['InvalidSentToken'], ['InvalidSentToken:InvalidSecret'], @@ -2211,13 +2184,12 @@ class RequestTest extends \Test\TestCase { } /** - * @dataProvider invalidTokenDataProvider - * @param string $invalidToken + * @dataProvider dataInvalidToken */ - public function testPassesCSRFCheckWithInvalidToken($invalidToken): void { + public function testPassesCSRFCheckWithInvalidToken(string $invalidToken): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ @@ -2243,8 +2215,8 @@ class RequestTest extends \Test\TestCase { public function testPassesCSRFCheckWithoutTokenFail(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [], $this->requestId, @@ -2259,8 +2231,8 @@ class RequestTest extends \Test\TestCase { public function testPassesCSRFCheckWithOCSAPIRequestHeader(): void { /** @var Request $request */ - $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') - ->setMethods(['getScriptName']) + $request = $this->getMockBuilder(Request::class) + ->onlyMethods(['getScriptName']) ->setConstructorArgs([ [ 'server' => [ diff --git a/tests/lib/BackgroundJob/JobListTest.php b/tests/lib/BackgroundJob/JobListTest.php index a9d7df0e6f4..bf21639d3aa 100644 --- a/tests/lib/BackgroundJob/JobListTest.php +++ b/tests/lib/BackgroundJob/JobListTest.php @@ -1,4 +1,7 @@ <?php + +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -153,7 +156,11 @@ class JobListTest extends TestCase { $this->assertFalse($this->instance->has($job, 10)); } - protected function createTempJob($class, $argument, $reservedTime = 0, $lastChecked = 0) { + protected function createTempJob($class, + $argument, + int $reservedTime = 0, + int $lastChecked = 0, + int $lastRun = 0): int { if ($lastChecked === 0) { $lastChecked = time(); } @@ -163,11 +170,12 @@ class JobListTest extends TestCase { ->values([ 'class' => $query->createNamedParameter($class), 'argument' => $query->createNamedParameter($argument), - 'last_run' => $query->createNamedParameter(0, IQueryBuilder::PARAM_INT), + 'last_run' => $query->createNamedParameter($lastRun, IQueryBuilder::PARAM_INT), 'last_checked' => $query->createNamedParameter($lastChecked, IQueryBuilder::PARAM_INT), 'reserved_at' => $query->createNamedParameter($reservedTime, IQueryBuilder::PARAM_INT), ]); - $query->execute(); + $query->executeStatement(); + return $query->getLastInsertId(); } public function testGetNext(): void { @@ -200,6 +208,21 @@ class JobListTest extends TestCase { $this->assertEquals(2, $nextJob->getArgument()); } + public function testGetNextSkipTimed(): void { + $job = new TestTimedJobNew($this->timeFactory); + $jobId = $this->createTempJob(get_class($job), 1, 123456789, 12345, 123456789 - 5); + $this->timeFactory->expects(self::atLeastOnce()) + ->method('getTime') + ->willReturn(123456789); + + $nextJob = $this->instance->getNext(); + + self::assertNull($nextJob); + $job = $this->instance->getById($jobId); + self::assertInstanceOf(TestTimedJobNew::class, $job); + self::assertEquals(123456789 - 5, $job->getLastRun()); + } + public function testGetNextSkipNonExisting(): void { $job = new TestJob(); $this->createTempJob('\OC\Non\Existing\Class', 1, 0, 12345); diff --git a/tests/lib/BackgroundJob/TestTimedJobNew.php b/tests/lib/BackgroundJob/TestTimedJobNew.php new file mode 100644 index 00000000000..a40c4033655 --- /dev/null +++ b/tests/lib/BackgroundJob/TestTimedJobNew.php @@ -0,0 +1,26 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +namespace Test\BackgroundJob; + +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\TimedJob; + +class TestTimedJobNew extends TimedJob { + public bool $ran = false; + + public function __construct(ITimeFactory $timeFactory) { + parent::__construct($timeFactory); + $this->setInterval(10); + } + + public function run($argument) { + $this->ran = true; + } +} diff --git a/tests/lib/BackgroundJob/TimedJobTest.php b/tests/lib/BackgroundJob/TimedJobTest.php index ad0f54ebe4a..6037365104f 100644 --- a/tests/lib/BackgroundJob/TimedJobTest.php +++ b/tests/lib/BackgroundJob/TimedJobTest.php @@ -8,20 +8,6 @@ namespace Test\BackgroundJob; use OCP\AppFramework\Utility\ITimeFactory; -use OCP\BackgroundJob\TimedJob; - -class TestTimedJobNew extends TimedJob { - public bool $ran = false; - - public function __construct(ITimeFactory $timeFactory) { - parent::__construct($timeFactory); - $this->setInterval(10); - } - - public function run($argument) { - $this->ran = true; - } -} class TimedJobTest extends \Test\TestCase { private DummyJobList $jobList; diff --git a/tests/lib/Calendar/CalendarEventBuilderTest.php b/tests/lib/Calendar/CalendarEventBuilderTest.php index 48684d56093..b01c209cd31 100644 --- a/tests/lib/Calendar/CalendarEventBuilderTest.php +++ b/tests/lib/Calendar/CalendarEventBuilderTest.php @@ -13,6 +13,7 @@ use DateTimeImmutable; use InvalidArgumentException; use OC\Calendar\CalendarEventBuilder; use OCP\AppFramework\Utility\ITimeFactory; +use OCP\Calendar\CalendarEventStatus; use OCP\Calendar\ICreateFromString; use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; @@ -37,6 +38,7 @@ class CalendarEventBuilderTest extends TestCase { public function testToIcs(): void { $this->calendarEventBuilder->setStartDate(new DateTimeImmutable('2025-01-05T17:09:58Z')); $this->calendarEventBuilder->setEndDate(new DateTimeImmutable('2025-01-05T17:19:58Z')); + $this->calendarEventBuilder->setStatus(CalendarEventStatus::CONFIRMED); $this->calendarEventBuilder->setSummary('My event'); $this->calendarEventBuilder->setDescription('Foo bar baz'); $this->calendarEventBuilder->setOrganizer('mailto:organizer@domain.tld'); @@ -51,6 +53,7 @@ class CalendarEventBuilderTest extends TestCase { public function testToIcsWithoutOrganizerAndAttendees(): void { $this->calendarEventBuilder->setStartDate(new DateTimeImmutable('2025-01-05T17:09:58Z')); $this->calendarEventBuilder->setEndDate(new DateTimeImmutable('2025-01-05T17:19:58Z')); + $this->calendarEventBuilder->setStatus(CalendarEventStatus::CONFIRMED); $this->calendarEventBuilder->setSummary('My event'); $this->calendarEventBuilder->setDescription('Foo bar baz'); @@ -62,6 +65,7 @@ class CalendarEventBuilderTest extends TestCase { public function testToIcsWithoutMailtoPrefix(): void { $this->calendarEventBuilder->setStartDate(new DateTimeImmutable('2025-01-05T17:09:58Z')); $this->calendarEventBuilder->setEndDate(new DateTimeImmutable('2025-01-05T17:19:58Z')); + $this->calendarEventBuilder->setStatus(CalendarEventStatus::CONFIRMED); $this->calendarEventBuilder->setSummary('My event'); $this->calendarEventBuilder->setDescription('Foo bar baz'); $this->calendarEventBuilder->setOrganizer('organizer@domain.tld'); @@ -76,6 +80,7 @@ class CalendarEventBuilderTest extends TestCase { public function testCreateInCalendar(): void { $this->calendarEventBuilder->setStartDate(new DateTimeImmutable('2025-01-05T17:09:58Z')); $this->calendarEventBuilder->setEndDate(new DateTimeImmutable('2025-01-05T17:19:58Z')); + $this->calendarEventBuilder->setStatus(CalendarEventStatus::CONFIRMED); $this->calendarEventBuilder->setSummary('My event'); $this->calendarEventBuilder->setDescription('Foo bar baz'); $this->calendarEventBuilder->setOrganizer('organizer@domain.tld'); diff --git a/tests/lib/Collaboration/Collaborators/LookupPluginTest.php b/tests/lib/Collaboration/Collaborators/LookupPluginTest.php index b54ca3ee4c3..7ff01831e18 100644 --- a/tests/lib/Collaboration/Collaborators/LookupPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/LookupPluginTest.php @@ -72,7 +72,7 @@ class LookupPluginTest extends TestCase { public function testSearchNoLookupServerURI(): void { $this->config->expects($this->once()) ->method('getAppValue') - ->with('files_sharing', 'lookupServerEnabled', 'yes') + ->with('files_sharing', 'lookupServerEnabled', 'no') ->willReturn('yes'); $this->config->expects($this->exactly(2)) ->method('getSystemValueBool') @@ -80,7 +80,7 @@ class LookupPluginTest extends TestCase { ['gs.enabled', false], ['has_internet_connection', true], )->willReturnOnConsecutiveCalls( - false, + true, true, ); @@ -101,7 +101,7 @@ class LookupPluginTest extends TestCase { public function testSearchNoInternet(): void { $this->config->expects($this->once()) ->method('getAppValue') - ->with('files_sharing', 'lookupServerEnabled', 'yes') + ->with('files_sharing', 'lookupServerEnabled', 'no') ->willReturn('yes'); $this->config->expects($this->exactly(2)) ->method('getSystemValueBool') @@ -137,7 +137,7 @@ class LookupPluginTest extends TestCase { $this->config->expects($this->once()) ->method('getAppValue') - ->with('files_sharing', 'lookupServerEnabled', 'yes') + ->with('files_sharing', 'lookupServerEnabled', 'no') ->willReturn('yes'); $this->config->expects($this->exactly(2)) ->method('getSystemValueBool') @@ -145,7 +145,7 @@ class LookupPluginTest extends TestCase { ['gs.enabled', false], ['has_internet_connection', true], )->willReturnOnConsecutiveCalls( - false, + true, true, ); @@ -197,9 +197,9 @@ class LookupPluginTest extends TestCase { $this->config->expects($this->once()) ->method('getAppValue') - ->with('files_sharing', 'lookupServerEnabled', 'yes') + ->with('files_sharing', 'lookupServerEnabled', 'no') ->willReturn($LookupEnabled ? 'yes' : 'no'); - if ($GSEnabled || $LookupEnabled) { + if ($GSEnabled) { $searchResult->expects($this->once()) ->method('addResultSet') ->with($type, $searchParams['expectedResult'], []); @@ -258,11 +258,13 @@ class LookupPluginTest extends TestCase { } - public function testSearchLookupServerDisabled(): void { - $this->config->expects($this->once()) - ->method('getAppValue') - ->with('files_sharing', 'lookupServerEnabled', 'yes') - ->willReturn('no'); + public function testSearchGSDisabled(): void { + $this->config->expects($this->atLeastOnce()) + ->method('getSystemValueBool') + ->willReturnMap([ + ['has_internet_connection', true, true], + ['gs.enabled', false, false], + ]); /** @var ISearchResult|MockObject $searchResult */ $searchResult = $this->createMock(ISearchResult::class); @@ -381,7 +383,6 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[0], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, - 'globalScale' => false, 'shareWith' => $fedIDs[0] ], 'extra' => ['federationId' => $fedIDs[0]], @@ -390,7 +391,6 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[1], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, - 'globalScale' => false, 'shareWith' => $fedIDs[1] ], 'extra' => ['federationId' => $fedIDs[1]], @@ -399,7 +399,6 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[2], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, - 'globalScale' => false, 'shareWith' => $fedIDs[2] ], 'extra' => ['federationId' => $fedIDs[2]], @@ -474,7 +473,7 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[0], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, - 'globalScale' => false, + 'globalScale' => true, 'shareWith' => $fedIDs[0] ], 'extra' => ['federationId' => $fedIDs[0]], @@ -483,7 +482,7 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[1], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, - 'globalScale' => false, + 'globalScale' => true, 'shareWith' => $fedIDs[1] ], 'extra' => ['federationId' => $fedIDs[1]], @@ -492,7 +491,7 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[2], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, - 'globalScale' => false, + 'globalScale' => true, 'shareWith' => $fedIDs[2] ], 'extra' => ['federationId' => $fedIDs[2]], diff --git a/tests/lib/Collaboration/Collaborators/MailPluginTest.php b/tests/lib/Collaboration/Collaborators/MailPluginTest.php index 568325fd30c..02b1034240f 100644 --- a/tests/lib/Collaboration/Collaborators/MailPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/MailPluginTest.php @@ -188,12 +188,12 @@ class MailPluginTest extends TestCase { 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'EMAIL' => [ - 'username@localhost', + 'username@example.com', ], ], ], true, - ['emails' => [['uuid' => 'uid1', 'name' => 'User @ Localhost', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => []]], + ['emails' => [['uuid' => 'uid1', 'name' => 'User @ Localhost', 'type' => '', 'label' => 'User @ Localhost (username@example.com)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@example.com']]], 'exact' => ['emails' => []]], false, false, false, @@ -233,24 +233,24 @@ class MailPluginTest extends TestCase { [ [ 'UID' => 'uid3', - 'FN' => 'User3 @ Localhost', + 'FN' => 'User3 @ example.com', ], [ 'UID' => 'uid2', - 'FN' => 'User2 @ Localhost', + 'FN' => 'User2 @ example.com', 'EMAIL' => [ ], ], [ 'UID' => 'uid1', - 'FN' => 'User @ Localhost', + 'FN' => 'User @ example.com', 'EMAIL' => [ - 'username@localhost', + 'username@example.com', ], ], ], true, - ['emails' => [['uuid' => 'uid1', 'name' => 'User @ Localhost', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => [['label' => 'test@remote.com', 'uuid' => 'test@remote.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], + ['emails' => [['uuid' => 'uid1', 'name' => 'User @ example.com', 'type' => '', 'label' => 'User @ example.com (username@example.com)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@example.com']]], 'exact' => ['emails' => [['label' => 'test@remote.com', 'uuid' => 'test@remote.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], false, false, true, @@ -286,56 +286,56 @@ class MailPluginTest extends TestCase { ], // data set 9 [ - 'username@localhost', + 'username@example.com', [ [ 'UID' => 'uid3', - 'FN' => 'User3 @ Localhost', + 'FN' => 'User3 @ example.com', ], [ 'UID' => 'uid2', - 'FN' => 'User2 @ Localhost', + 'FN' => 'User2 @ example.com', 'EMAIL' => [ ], ], [ 'UID' => 'uid1', - 'FN' => 'User @ Localhost', + 'FN' => 'User @ example.com', 'EMAIL' => [ - 'username@localhost', + 'username@example.com', ], ], ], true, - ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ Localhost', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]], + ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ example.com', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ example.com (username@example.com)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@example.com']]]]], true, false, false, ], // data set 10 [ - 'username@localhost', + 'username@example.com', [ [ 'UID' => 'uid1', - 'FN' => 'User3 @ Localhost', + 'FN' => 'User3 @ example.com', ], [ 'UID' => 'uid2', - 'FN' => 'User2 @ Localhost', + 'FN' => 'User2 @ example.com', 'EMAIL' => [ ], ], [ 'UID' => 'uid1', - 'FN' => 'User @ Localhost', + 'FN' => 'User @ example.com', 'EMAIL' => [ - 'username@localhost', + 'username@example.com', ], ], ], false, - ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ Localhost', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]], + ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ example.com', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ example.com (username@example.com)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@example.com']]]]], true, false, false, @@ -364,8 +364,8 @@ class MailPluginTest extends TestCase { ], ], false, - ['emails' => [], 'exact' => ['emails' => [['name' => 'User Name @ Localhost', 'uuid' => 'uid1', 'type' => '', 'label' => 'User Name @ Localhost (user name@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'user name@localhost']]]]], - true, + ['emails' => [], 'exact' => ['emails' => []]], + false, false, false, ], @@ -538,16 +538,16 @@ class MailPluginTest extends TestCase { 'UID' => 'uid1', 'FN' => 'User Name', 'EMAIL' => [ - ['type' => 'HOME', 'value' => 'username@localhost'], - ['type' => 'WORK', 'value' => 'username@other'], + ['type' => 'HOME', 'value' => 'username@example.com'], + ['type' => 'WORK', 'value' => 'other@example.com'], ], ], ], false, ['emails' => [ ], 'exact' => ['emails' => [ - ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'HOME', 'label' => 'User Name (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']], - ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'WORK', 'label' => 'User Name (username@other)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@other']] + ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'HOME', 'label' => 'User Name (username@example.com)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@example.com']], + ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'WORK', 'label' => 'User Name (other@example.com)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'other@example.com']] ]]], false, false, diff --git a/tests/lib/Comments/ManagerTest.php b/tests/lib/Comments/ManagerTest.php index 15961b029f5..02118125c24 100644 --- a/tests/lib/Comments/ManagerTest.php +++ b/tests/lib/Comments/ManagerTest.php @@ -507,14 +507,14 @@ class ManagerTest extends TestCase { } $saveSuccessful = $manager->save($comment); - $this->assertTrue($saveSuccessful); - $this->assertTrue($comment->getId() !== ''); - $this->assertTrue($comment->getId() !== '0'); - $this->assertTrue(!is_null($comment->getCreationDateTime())); + $this->assertTrue($saveSuccessful, 'Comment saving was not successful'); + $this->assertNotEquals('', $comment->getId(), 'Comment ID should not be empty'); + $this->assertNotEquals('0', $comment->getId(), 'Comment ID should not be string \'0\''); + $this->assertNotNull($comment->getCreationDateTime(), 'Comment creation date should not be null'); $loadedComment = $manager->get($comment->getId()); - $this->assertSame($comment->getMessage(), $loadedComment->getMessage()); - $this->assertEquals($comment->getCreationDateTime()->getTimestamp(), $loadedComment->getCreationDateTime()->getTimestamp()); + $this->assertSame($comment->getMessage(), $loadedComment->getMessage(), 'Comment message should match'); + $this->assertEquals($comment->getCreationDateTime()->getTimestamp(), $loadedComment->getCreationDateTime()->getTimestamp(), 'Comment creation date should match'); return $comment; } diff --git a/tests/lib/ContactsManagerTest.php b/tests/lib/ContactsManagerTest.php index 6a6cd5f421a..7586b063883 100644 --- a/tests/lib/ContactsManagerTest.php +++ b/tests/lib/ContactsManagerTest.php @@ -67,11 +67,15 @@ class ContactsManagerTest extends \Test\TestCase { */ public function testSearch($search1, $search2, $expectedResult): void { /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBook $addressbook */ - $addressbook1 = $this->getMockBuilder('\OCP\IAddressBook') + $addressbook1 = $this->getMockBuilder('\OCP\IAddressBookEnabled') ->disableOriginalConstructor() ->getMock(); $addressbook1->expects($this->once()) + ->method('isEnabled') + ->willReturn(true); + + $addressbook1->expects($this->once()) ->method('search') ->willReturn($search1); @@ -79,11 +83,15 @@ class ContactsManagerTest extends \Test\TestCase { ->method('getKey') ->willReturn('simple:1'); - $addressbook2 = $this->getMockBuilder('\OCP\IAddressBook') + $addressbook2 = $this->getMockBuilder('\OCP\IAddressBookEnabled') ->disableOriginalConstructor() ->getMock(); $addressbook2->expects($this->once()) + ->method('isEnabled') + ->willReturn(true); + + $addressbook2->expects($this->once()) ->method('search') ->willReturn($search2); @@ -98,10 +106,48 @@ class ContactsManagerTest extends \Test\TestCase { $this->assertEquals($expectedResult, $result); } + /** + * @dataProvider searchProvider + */ + public function testSearchDisabledAb($search1): void { + /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBookEnabled $addressbook */ + $addressbook1 = $this->getMockBuilder('\OCP\IAddressBookEnabled') + ->disableOriginalConstructor() + ->getMock(); + + $addressbook1->expects($this->once()) + ->method('isEnabled') + ->willReturn(true); + + $addressbook1->expects($this->once()) + ->method('search') + ->willReturn($search1); + + $addressbook1->expects($this->any()) + ->method('getKey') + ->willReturn('simple:1'); + + $addressbook2 = $this->getMockBuilder('\OCP\IAddressBookEnabled') + ->disableOriginalConstructor() + ->getMock(); + + $addressbook2->expects($this->once()) + ->method('isEnabled') + ->willReturn(false); + + $addressbook2->expects($this->never()) + ->method('search'); + + $this->cm->registerAddressBook($addressbook1); + $this->cm->registerAddressBook($addressbook2); + $result = $this->cm->search(''); + $this->assertEquals($search1, $result); + } + public function testDeleteHavePermission(): void { - /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBook $addressbook */ - $addressbook = $this->getMockBuilder('\OCP\IAddressBook') + /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBookEnabled $addressbook */ + $addressbook = $this->getMockBuilder('\OCP\IAddressBookEnabled') ->disableOriginalConstructor() ->getMock(); @@ -123,8 +169,8 @@ class ContactsManagerTest extends \Test\TestCase { } public function testDeleteNoPermission(): void { - /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBook $addressbook */ - $addressbook = $this->getMockBuilder('\OCP\IAddressBook') + /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBookEnabled $addressbook */ + $addressbook = $this->getMockBuilder('\OCP\IAddressBookEnabled') ->disableOriginalConstructor() ->getMock(); @@ -145,8 +191,8 @@ class ContactsManagerTest extends \Test\TestCase { } public function testDeleteNoAddressbook(): void { - /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBook $addressbook */ - $addressbook = $this->getMockBuilder('\OCP\IAddressBook') + /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBookEnabled $addressbook */ + $addressbook = $this->getMockBuilder('\OCP\IAddressBookEnabled') ->disableOriginalConstructor() ->getMock(); @@ -163,8 +209,8 @@ class ContactsManagerTest extends \Test\TestCase { } public function testCreateOrUpdateHavePermission(): void { - /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBook $addressbook */ - $addressbook = $this->getMockBuilder('\OCP\IAddressBook') + /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBookEnabled $addressbook */ + $addressbook = $this->getMockBuilder('\OCP\IAddressBookEnabled') ->disableOriginalConstructor() ->getMock(); @@ -186,8 +232,8 @@ class ContactsManagerTest extends \Test\TestCase { } public function testCreateOrUpdateNoPermission(): void { - /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBook $addressbook */ - $addressbook = $this->getMockBuilder('\OCP\IAddressBook') + /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBookEnabled $addressbook */ + $addressbook = $this->getMockBuilder('\OCP\IAddressBookEnabled') ->disableOriginalConstructor() ->getMock(); @@ -208,8 +254,8 @@ class ContactsManagerTest extends \Test\TestCase { } public function testCreateOrUpdateNOAdressbook(): void { - /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBook $addressbook */ - $addressbook = $this->getMockBuilder('\OCP\IAddressBook') + /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBookEnabled $addressbook */ + $addressbook = $this->getMockBuilder('\OCP\IAddressBookEnabled') ->disableOriginalConstructor() ->getMock(); @@ -231,8 +277,8 @@ class ContactsManagerTest extends \Test\TestCase { } public function testIsEnabledIfSo(): void { - /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBook $addressbook */ - $addressbook = $this->getMockBuilder('\OCP\IAddressBook') + /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBookEnabled $addressbook */ + $addressbook = $this->getMockBuilder('\OCP\IAddressBookEnabled') ->disableOriginalConstructor() ->getMock(); @@ -247,8 +293,8 @@ class ContactsManagerTest extends \Test\TestCase { public function testAddressBookEnumeration(): void { // create mock for the addressbook - /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBook $addressbook */ - $addressbook = $this->getMockBuilder('\OCP\IAddressBook') + /** @var \PHPUnit\Framework\MockObject\MockObject|IAddressBookEnabled $addressbook */ + $addressbook = $this->getMockBuilder('\OCP\IAddressBookEnabled') ->disableOriginalConstructor() ->getMock(); diff --git a/tests/lib/Federation/CloudIdManagerTest.php b/tests/lib/Federation/CloudIdManagerTest.php index 13e6b111864..7019cd202db 100644 --- a/tests/lib/Federation/CloudIdManagerTest.php +++ b/tests/lib/Federation/CloudIdManagerTest.php @@ -1,4 +1,7 @@ <?php + +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -10,11 +13,15 @@ use OC\Federation\CloudIdManager; use OC\Memcache\ArrayCache; use OCP\Contacts\IManager; use OCP\EventDispatcher\IEventDispatcher; +use OCP\Federation\ICloudIdManager; use OCP\ICacheFactory; use OCP\IURLGenerator; use OCP\IUserManager; use Test\TestCase; +/** + * @group DB + */ class CloudIdManagerTest extends TestCase { /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ protected $contactsManager; @@ -36,7 +43,7 @@ class CloudIdManagerTest extends TestCase { $this->userManager = $this->createMock(IUserManager::class); $this->cacheFactory = $this->createMock(ICacheFactory::class); - $this->cacheFactory->method('createLocal') + $this->cacheFactory->method('createDistributed') ->willReturn(new ArrayCache('')); $this->cloudIdManager = new CloudIdManager( @@ -46,6 +53,35 @@ class CloudIdManagerTest extends TestCase { $this->cacheFactory, $this->createMock(IEventDispatcher::class) ); + $this->overwriteService(ICloudIdManager::class, $this->cloudIdManager); + } + + public function dataGetDisplayNameFromContact(): array { + return [ + ['test1@example.tld', 'test', 'test'], + ['test2@example.tld', null, null], + ['test3@example.tld', 'test3@example', 'test3@example'], + ['test4@example.tld', 'test4@example.tld', null], + ]; + } + + /** + * @dataProvider dataGetDisplayNameFromContact + */ + public function testGetDisplayNameFromContact(string $cloudId, ?string $displayName, ?string $expected): void { + $returnedContact = [ + 'CLOUD' => [$cloudId], + 'FN' => $expected, + ]; + if ($displayName === null) { + unset($returnedContact['FN']); + } + $this->contactsManager->method('search') + ->with($cloudId, ['CLOUD']) + ->willReturn([$returnedContact]); + + $this->assertEquals($expected, $this->cloudIdManager->getDisplayNameFromContact($cloudId)); + $this->assertEquals($expected, $this->cloudIdManager->getDisplayNameFromContact($cloudId)); } public function cloudIdProvider(): array { @@ -55,6 +91,10 @@ class CloudIdManagerTest extends TestCase { ['test@example.com/cloud/', 'test', 'example.com/cloud', 'test@example.com/cloud'], ['test@example.com/cloud/index.php', 'test', 'example.com/cloud', 'test@example.com/cloud'], ['test@example.com@example.com', 'test@example.com', 'example.com', 'test@example.com@example.com'], + + // Equal signs are not valid on Nextcloud side, but can be used by other federated OCM compatible servers + ['test==@example.com', 'test==', 'example.com', 'test==@example.com'], + ['==@example.com', '==', 'example.com', '==@example.com'], ]; } @@ -70,7 +110,7 @@ class CloudIdManagerTest extends TestCase { ->willReturn([ [ 'CLOUD' => [$cleanId], - 'FN' => 'Ample Ex', + 'FN' => $displayName, ] ]); @@ -92,9 +132,6 @@ class CloudIdManagerTest extends TestCase { /** * @dataProvider invalidCloudIdProvider - * - * @param string $cloudId - * */ public function testInvalidCloudId(string $cloudId): void { $this->expectException(\InvalidArgumentException::class); diff --git a/tests/lib/Federation/CloudIdTest.php b/tests/lib/Federation/CloudIdTest.php index 4087f45622d..ca949d163c7 100644 --- a/tests/lib/Federation/CloudIdTest.php +++ b/tests/lib/Federation/CloudIdTest.php @@ -1,4 +1,7 @@ <?php + +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -7,25 +10,42 @@ namespace Test\Federation; use OC\Federation\CloudId; +use OC\Federation\CloudIdManager; +use OCP\Federation\ICloudIdManager; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; +/** + * @group DB + */ class CloudIdTest extends TestCase { - public function dataGetDisplayCloudId() { + protected CloudIdManager&MockObject $cloudIdManager; + + protected function setUp(): void { + parent::setUp(); + + $this->cloudIdManager = $this->createMock(CloudIdManager::class); + $this->overwriteService(ICloudIdManager::class, $this->cloudIdManager); + } + + public function dataGetDisplayCloudId(): array { return [ - ['test@example.com', 'test@example.com'], - ['test@http://example.com', 'test@example.com'], - ['test@https://example.com', 'test@example.com'], + ['test@example.com', 'test', 'example.com', 'test@example.com'], + ['test@http://example.com', 'test', 'http://example.com', 'test@example.com'], + ['test@https://example.com', 'test', 'https://example.com', 'test@example.com'], + ['test@https://example.com', 'test', 'https://example.com', 'Beloved Amy@example.com', 'Beloved Amy'], ]; } /** * @dataProvider dataGetDisplayCloudId - * - * @param string $id - * @param string $display */ - public function testGetDisplayCloudId($id, $display): void { - $cloudId = new CloudId($id, '', ''); + public function testGetDisplayCloudId(string $id, string $user, string $remote, string $display, ?string $addressbookName = null): void { + $this->cloudIdManager->expects($this->once()) + ->method('getDisplayNameFromContact') + ->willReturn($addressbookName); + + $cloudId = new CloudId($id, $user, $remote); $this->assertEquals($display, $cloudId->getDisplayId()); } } diff --git a/tests/lib/Files/EtagTest.php b/tests/lib/Files/EtagTest.php index dbf65eac439..b0cdff16f4d 100644 --- a/tests/lib/Files/EtagTest.php +++ b/tests/lib/Files/EtagTest.php @@ -10,6 +10,8 @@ namespace Test\Files; use OC\Files\Filesystem; use OCA\Files_Sharing\AppInfo\Application; use OCP\EventDispatcher\IEventDispatcher; +use OCP\IUserManager; +use OCP\Server; use Psr\Log\LoggerInterface; /** @@ -45,7 +47,7 @@ class EtagTest extends \Test\TestCase { $config->setSystemValue('datadirectory', $this->tmpDir); $this->userBackend = new \Test\Util\User\Dummy(); - \OC_User::useBackend($this->userBackend); + Server::get(IUserManager::class)->registerBackend($this->userBackend); } protected function tearDown(): void { diff --git a/tests/lib/Files/FilenameValidatorTest.php b/tests/lib/Files/FilenameValidatorTest.php index ac9ac032b64..45f681bd453 100644 --- a/tests/lib/Files/FilenameValidatorTest.php +++ b/tests/lib/Files/FilenameValidatorTest.php @@ -146,6 +146,10 @@ class FilenameValidatorTest extends TestCase { // needed for Windows namespaces 'com1.suffix', ['.htaccess'], ['com1'], [], [], ReservedWordException::class ], + 'forbidden basename case insensitive' => [ + // needed for Windows namespaces + 'COM1.suffix', ['.htaccess'], ['com1'], [], [], ReservedWordException::class + ], 'forbidden basename for hidden files' => [ // needed for Windows namespaces '.thumbs.db', ['.htaccess'], ['.thumbs'], [], [], ReservedWordException::class @@ -159,6 +163,9 @@ class FilenameValidatorTest extends TestCase { 'invalid extension' => [ 'a: b.txt', ['.htaccess'], [], ['.txt'], [], InvalidPathException::class ], + 'invalid extension case insensitive' => [ + 'a: b.TXT', ['.htaccess'], [], ['.txt'], [], InvalidPathException::class + ], 'empty filename' => [ '', [], [], [], [], EmptyFileNameException::class ], @@ -199,7 +206,6 @@ class FilenameValidatorTest extends TestCase { return [ ['plane 1 ๐ช
'], ['emoji ๐ถโ๐ซ๏ธ'], - ]; } @@ -284,4 +290,88 @@ class FilenameValidatorTest extends TestCase { ], ]; } + + /** + * @dataProvider dataGetForbiddenExtensions + */ + public function testGetForbiddenExtensions(array $configValue, array $expectedValue): void { + $validator = new FilenameValidator($this->l10n, $this->database, $this->config, $this->logger); + $this->config + // only once - then cached + ->expects(self::once()) + ->method('getSystemValue') + ->with('forbidden_filename_extensions', ['.filepart']) + ->willReturn($configValue); + + self::assertEqualsCanonicalizing($expectedValue, $validator->getForbiddenExtensions()); + } + + public static function dataGetForbiddenExtensions(): array { + return [ + // default + [['.filepart'], ['.filepart', '.part']], + // always include .part + [[], ['.part']], + // handle case insensitivity + [['.TXT'], ['.txt', '.part']], + ]; + } + + /** + * @dataProvider dataGetForbiddenFilenames + */ + public function testGetForbiddenFilenames(array $configValue, array $legacyValue, array $expectedValue): void { + $validator = new FilenameValidator($this->l10n, $this->database, $this->config, $this->logger); + $this->config + // only once - then cached + ->expects(self::exactly(2)) + ->method('getSystemValue') + ->willReturnMap([ + ['forbidden_filenames', ['.htaccess'], $configValue], + ['blacklisted_files', [], $legacyValue], + ]); + + $this->logger + ->expects(empty($legacyValue) ? self::never() : self::once()) + ->method('warning'); + + self::assertEqualsCanonicalizing($expectedValue, $validator->getForbiddenFilenames()); + } + + public static function dataGetForbiddenFilenames(): array { + return [ + // default + [['.htaccess'], [], ['.htaccess']], + // with legacy values + [['.htaccess'], ['legacy'], ['.htaccess', 'legacy']], + // handle case insensitivity + [['FileName', '.htaccess'], ['LegAcy'], ['.htaccess', 'filename', 'legacy']], + ]; + } + + /** + * @dataProvider dataGetForbiddenBasenames + */ + public function testGetForbiddenBasenames(array $configValue, array $expectedValue): void { + $validator = new FilenameValidator($this->l10n, $this->database, $this->config, $this->logger); + $this->config + // only once - then cached + ->expects(self::once()) + ->method('getSystemValue') + ->with('forbidden_filename_basenames', []) + ->willReturn($configValue); + + self::assertEqualsCanonicalizing($expectedValue, $validator->getForbiddenBasenames()); + } + + public static function dataGetForbiddenBasenames(): array { + return [ + // default + [[], []], + // with values + [['aux', 'com0'], ['aux', 'com0']], + // handle case insensitivity + [['AuX', 'COM1'], ['aux', 'com1']], + ]; + } } diff --git a/tests/lib/Files/FilesystemTest.php b/tests/lib/Files/FilesystemTest.php index 91f0bb9b01d..a920dc662da 100644 --- a/tests/lib/Files/FilesystemTest.php +++ b/tests/lib/Files/FilesystemTest.php @@ -13,6 +13,8 @@ use OC\User\NoUserException; use OCP\Files\Config\IMountProvider; use OCP\Files\Storage\IStorageFactory; use OCP\IUser; +use OCP\IUserManager; +use OCP\Server; class DummyMountProvider implements IMountProvider { private $mounts = []; @@ -295,7 +297,7 @@ class FilesystemTest extends \Test\TestCase { } else { $user = self::TEST_FILESYSTEM_USER1; $backend = new \Test\Util\User\Dummy(); - \OC_User::useBackend($backend); + Server::get(IUserManager::class)->registerBackend($backend); $backend->createUser($user, $user); $userObj = \OC::$server->getUserManager()->get($user); \OC::$server->getUserSession()->setUser($userObj); diff --git a/tests/lib/Files/Storage/StoragesTest.php b/tests/lib/Files/Storage/StoragesTest.php index e5a6469cdbe..3f8198d331d 100644 --- a/tests/lib/Files/Storage/StoragesTest.php +++ b/tests/lib/Files/Storage/StoragesTest.php @@ -42,6 +42,24 @@ abstract class StoragesTest extends TestCase { $this->assertEquals('foo', $this->storage1->file_get_contents($target)); } + public function testMoveFileFromStorageWithExistingTarget() { + $source = 'source.txt'; + $target = 'target.txt'; + $this->storage1->file_put_contents($target, 'bar'); + $this->storage2->file_put_contents($source, 'foo'); + + $targetURN = $this->storage1->getURN($this->storage1->getCache()->get($target)->getID()); + $sourceURN = $this->storage2->getURN($this->storage2->getCache()->get($source)->getID()); + + $this->storage1->moveFromStorage($this->storage2, $source, $target); + + $this->assertTrue($this->storage1->file_exists($target), $target . ' was not created in DB'); + $this->assertFalse($this->storage2->file_exists($source), $source . ' still exists in DB'); + $this->assertTrue($this->storage1->getObjectStore()->objectExists($sourceURN), $sourceURN . ' was not created in bucket'); + $this->assertFalse($this->storage1->getObjectStore()->objectExists($targetURN), $targetURN . ' still exists in bucket'); + $this->assertEquals('foo', $this->storage1->file_get_contents($target)); + } + public function testMoveDirectoryFromStorage() { $this->storage2->mkdir('source'); $this->storage2->file_put_contents('source/test1.txt', 'foo'); diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php index a6a7722f363..7cebfd01b03 100644 --- a/tests/lib/Files/ViewTest.php +++ b/tests/lib/Files/ViewTest.php @@ -26,6 +26,7 @@ use OCP\Files\GenericFileException; use OCP\Files\Mount\IMountManager; use OCP\Files\Storage\IStorage; use OCP\IDBConnection; +use OCP\IUserManager; use OCP\Lock\ILockingProvider; use OCP\Lock\LockedException; use OCP\Server; @@ -100,8 +101,8 @@ class ViewTest extends \Test\TestCase { parent::setUp(); \OC_Hook::clear(); - \OC_User::clearBackends(); - \OC_User::useBackend(new \Test\Util\User\Dummy()); + Server::get(IUserManager::class)->clearBackends(); + Server::get(IUserManager::class)->registerBackend(new \Test\Util\User\Dummy()); //login $userManager = \OC::$server->getUserManager(); diff --git a/tests/lib/Mail/EMailTemplateTest.php b/tests/lib/Mail/EMailTemplateTest.php index 76b37d48ff3..4943024043c 100644 --- a/tests/lib/Mail/EMailTemplateTest.php +++ b/tests/lib/Mail/EMailTemplateTest.php @@ -47,7 +47,7 @@ class EMailTemplateTest extends TestCase { public function testEMailTemplateCustomFooter(): void { $this->defaults - ->expects($this->any()) + ->expects($this->atLeastOnce()) ->method('getDefaultColorPrimary') ->willReturn('#0082c9'); $this->defaults @@ -59,8 +59,8 @@ class EMailTemplateTest extends TestCase { ->method('getName') ->willReturn('TestCloud'); $this->defaults - ->expects($this->any()) - ->method('getTextColorPrimary') + ->expects($this->atLeastOnce()) + ->method('getDefaultTextColorPrimary') ->willReturn('#ffffff'); $this->urlGenerator ->expects($this->once()) @@ -88,7 +88,7 @@ class EMailTemplateTest extends TestCase { public function testEMailTemplateDefaultFooter(): void { $this->defaults - ->expects($this->any()) + ->expects($this->atLeastOnce()) ->method('getDefaultColorPrimary') ->willReturn('#0082c9'); $this->defaults @@ -104,8 +104,8 @@ class EMailTemplateTest extends TestCase { ->method('getLogo') ->willReturn('/img/logo-mail-header.png'); $this->defaults - ->expects($this->any()) - ->method('getTextColorPrimary') + ->expects($this->atLeastOnce()) + ->method('getDefaultTextColorPrimary') ->willReturn('#ffffff'); $this->urlGenerator ->expects($this->once()) @@ -131,7 +131,7 @@ class EMailTemplateTest extends TestCase { public function testEMailTemplateSingleButton(): void { $this->defaults - ->expects($this->any()) + ->expects($this->atLeastOnce()) ->method('getDefaultColorPrimary') ->willReturn('#0082c9'); $this->defaults @@ -147,8 +147,8 @@ class EMailTemplateTest extends TestCase { ->method('getLogo') ->willReturn('/img/logo-mail-header.png'); $this->defaults - ->expects($this->any()) - ->method('getTextColorPrimary') + ->expects($this->atLeastOnce()) + ->method('getDefaultTextColorPrimary') ->willReturn('#ffffff'); $this->urlGenerator ->expects($this->once()) @@ -176,7 +176,7 @@ class EMailTemplateTest extends TestCase { public function testEMailTemplateAlternativePlainTexts(): void { $this->defaults - ->expects($this->any()) + ->expects($this->atLeastOnce()) ->method('getDefaultColorPrimary') ->willReturn('#0082c9'); $this->defaults @@ -192,8 +192,8 @@ class EMailTemplateTest extends TestCase { ->method('getLogo') ->willReturn('/img/logo-mail-header.png'); $this->defaults - ->expects($this->any()) - ->method('getTextColorPrimary') + ->expects($this->atLeastOnce()) + ->method('getDefaultTextColorPrimary') ->willReturn('#ffffff'); $this->urlGenerator ->expects($this->once()) diff --git a/tests/lib/NavigationManagerTest.php b/tests/lib/NavigationManagerTest.php index 91da970f3b9..48cfa972f2b 100644 --- a/tests/lib/NavigationManagerTest.php +++ b/tests/lib/NavigationManagerTest.php @@ -704,30 +704,64 @@ class NavigationManagerTest extends TestCase { true, 'settings', ], + // closure navigation entries are also resolved + [ + 'closure2', + '', + '', + true, + 'closure2', + ], + [ + '', + 'closure2', + '', + true, + 'closure2', + ], + [ + '', + '', + '{"closure2":{"order":1,"app":"closure2","href":"/closure2"}}', + true, + 'closure2', + ], ]; } /** * @dataProvider provideDefaultEntries */ - public function testGetDefaultEntryIdForUser($defaultApps, $userDefaultApps, $userApporder, $withFallbacks, $expectedApp): void { + public function testGetDefaultEntryIdForUser(string $defaultApps, string $userDefaultApps, string $userApporder, bool $withFallbacks, string $expectedApp): void { $this->navigationManager->add([ 'id' => 'files', ]); $this->navigationManager->add([ 'id' => 'settings', ]); + $this->navigationManager->add(static function (): array { + return [ + 'id' => 'closure1', + 'href' => '/closure1', + ]; + }); + $this->navigationManager->add(static function (): array { + return [ + 'id' => 'closure2', + 'href' => '/closure2', + ]; + }); $this->appManager->method('getEnabledApps')->willReturn([]); $user = $this->createMock(IUser::class); $user->method('getUID')->willReturn('user1'); - $this->userSession->expects($this->once()) + $this->userSession->expects($this->atLeastOnce()) ->method('getUser') ->willReturn($user); - $this->config->expects($this->once()) + $this->config->expects($this->atLeastOnce()) ->method('getSystemValueString') ->with('defaultapp', $this->anything()) ->willReturn($defaultApps); diff --git a/tests/lib/Preview/BackgroundCleanupJobTest.php b/tests/lib/Preview/BackgroundCleanupJobTest.php index 945366cde9f..cecb4a7a212 100644 --- a/tests/lib/Preview/BackgroundCleanupJobTest.php +++ b/tests/lib/Preview/BackgroundCleanupJobTest.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-only @@ -9,12 +10,15 @@ namespace Test\Preview; use OC\Preview\BackgroundCleanupJob; use OC\Preview\Storage\Root; use OC\PreviewManager; +use OCP\App\IAppManager; use OCP\AppFramework\Utility\ITimeFactory; use OCP\Files\File; use OCP\Files\IMimeTypeLoader; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\IDBConnection; +use OCP\IPreview; +use OCP\Server; use Test\Traits\MountProviderTrait; use Test\Traits\UserTrait; @@ -28,25 +32,12 @@ use Test\Traits\UserTrait; class BackgroundCleanupJobTest extends \Test\TestCase { use MountProviderTrait; use UserTrait; - - /** @var string */ - private $userId; - - /** @var bool */ - private $trashEnabled; - - /** @var IDBConnection */ - private $connection; - - /** @var PreviewManager */ - private $previewManager; - - /** @var IRootFolder */ - private $rootFolder; - - /** @var IMimeTypeLoader */ - private $mimeTypeLoader; - + private string $userId; + private bool $trashEnabled; + private IDBConnection $connection; + private PreviewManager $previewManager; + private IRootFolder $rootFolder; + private IMimeTypeLoader $mimeTypeLoader; private ITimeFactory $timeFactory; protected function setUp(): void { @@ -62,20 +53,20 @@ class BackgroundCleanupJobTest extends \Test\TestCase { $this->logout(); $this->loginAsUser($this->userId); - $appManager = \OC::$server->getAppManager(); + $appManager = Server::get(IAppManager::class); $this->trashEnabled = $appManager->isEnabledForUser('files_trashbin', $user); $appManager->disableApp('files_trashbin'); - $this->connection = \OC::$server->getDatabaseConnection(); - $this->previewManager = \OC::$server->getPreviewManager(); - $this->rootFolder = \OC::$server->get(IRootFolder::class); - $this->mimeTypeLoader = \OC::$server->getMimeTypeLoader(); - $this->timeFactory = \OCP\Server::get(ITimeFactory::class); + $this->connection = Server::get(IDBConnection::class); + $this->previewManager = Server::get(IPreview::class); + $this->rootFolder = Server::get(IRootFolder::class); + $this->mimeTypeLoader = Server::get(IMimeTypeLoader::class); + $this->timeFactory = Server::get(ITimeFactory::class); } protected function tearDown(): void { if ($this->trashEnabled) { - $appManager = \OC::$server->getAppManager(); + $appManager = Server::get(IAppManager::class); $appManager->enableApp('files_trashbin'); } diff --git a/tests/lib/Preview/GeneratorTest.php b/tests/lib/Preview/GeneratorTest.php index 7bd121250fb..8a08d741909 100644 --- a/tests/lib/Preview/GeneratorTest.php +++ b/tests/lib/Preview/GeneratorTest.php @@ -19,6 +19,7 @@ use OCP\IImage; use OCP\IPreview; use OCP\Preview\BeforePreviewFetchedEvent; use OCP\Preview\IProviderV2; +use Psr\Log\LoggerInterface; class GeneratorTest extends \Test\TestCase { /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ @@ -39,6 +40,8 @@ class GeneratorTest extends \Test\TestCase { /** @var Generator */ private $generator; + private LoggerInterface|\PHPUnit\Framework\MockObject\MockObject $logger; + protected function setUp(): void { parent::setUp(); @@ -47,13 +50,15 @@ class GeneratorTest extends \Test\TestCase { $this->appData = $this->createMock(IAppData::class); $this->helper = $this->createMock(GeneratorHelper::class); $this->eventDispatcher = $this->createMock(IEventDispatcher::class); + $this->logger = $this->createMock(LoggerInterface::class); $this->generator = new Generator( $this->config, $this->previewManager, $this->appData, $this->helper, - $this->eventDispatcher + $this->eventDispatcher, + $this->logger, ); } diff --git a/tests/lib/Preview/MovieTest.php b/tests/lib/Preview/MovieTest.php index d41b242945b..b8946ad4c5e 100644 --- a/tests/lib/Preview/MovieTest.php +++ b/tests/lib/Preview/MovieTest.php @@ -7,6 +7,9 @@ namespace Test\Preview; +use OCP\IBinaryFinder; +use OCP\Server; + /** * Class MovieTest * @@ -16,20 +19,20 @@ namespace Test\Preview; */ class MovieTest extends Provider { protected function setUp(): void { - $avconvBinary = \OC_Helper::findBinaryPath('avconv'); - $ffmpegBinary = ($avconvBinary) ? null : \OC_Helper::findBinaryPath('ffmpeg'); + $binaryFinder = Server::get(IBinaryFinder::class); + $movieBinary = $binaryFinder->findBinaryPath('avconv'); + if (!is_string($movieBinary)) { + $movieBinary = $binaryFinder->findBinaryPath('ffmpeg'); + } - if ($avconvBinary || $ffmpegBinary) { + if (is_string($movieBinary)) { parent::setUp(); - \OC\Preview\Movie::$avconvBinary = $avconvBinary; - \OC\Preview\Movie::$ffmpegBinary = $ffmpegBinary; - $fileName = 'testimage.mp4'; $this->imgPath = $this->prepareTestFile($fileName, \OC::$SERVERROOT . '/tests/data/' . $fileName); $this->width = 560; $this->height = 320; - $this->provider = new \OC\Preview\Movie; + $this->provider = new \OC\Preview\Movie(['movieBinary' => $movieBinary]); } else { $this->markTestSkipped('No Movie provider present'); } diff --git a/tests/lib/Preview/Provider.php b/tests/lib/Preview/Provider.php index 41a2a4ca3c4..a7f55151354 100644 --- a/tests/lib/Preview/Provider.php +++ b/tests/lib/Preview/Provider.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -9,33 +10,25 @@ namespace Test\Preview; use OC\Files\Node\File; use OCP\Files\IRootFolder; +use OCP\IUserManager; abstract class Provider extends \Test\TestCase { - /** @var string */ - protected $imgPath; - /** @var int */ - protected $width; - /** @var int */ - protected $height; - /** @var \OC\Preview\Provider */ + protected string $imgPath; + protected int $width; + protected int $height; + /** @var \OC\Preview\Provider|mixed $provider */ protected $provider; - /** @var int */ - protected $maxWidth = 1024; - /** @var int */ - protected $maxHeight = 1024; - /** @var bool */ - protected $scalingUp = false; - /** @var int */ - protected $userId; - /** @var \OC\Files\View */ - protected $rootView; - /** @var \OC\Files\Storage\Storage */ - protected $storage; + protected int $maxWidth = 1024; + protected int $maxHeight = 1024; + protected bool $scalingUp = false; + protected string $userId; + protected \OC\Files\View $rootView; + protected \OC\Files\Storage\Storage $storage; protected function setUp(): void { parent::setUp(); - $userManager = \OC::$server->getUserManager(); + $userManager = \OCP\Server::get(IUserManager::class); $userManager->clearBackends(); $backend = new \Test\Util\User\Dummy(); $userManager->registerBackend($backend); diff --git a/tests/lib/RichObjectStrings/ValidatorTest.php b/tests/lib/RichObjectStrings/ValidatorTest.php index c5ce1f04dad..c5f88394a33 100644 --- a/tests/lib/RichObjectStrings/ValidatorTest.php +++ b/tests/lib/RichObjectStrings/ValidatorTest.php @@ -39,7 +39,7 @@ class ValidatorTest extends TestCase { $this->expectException(InvalidObjectExeption::class); - $this->expectExceptionMessage('Object is invalid, value 123 is not a string'); + $this->expectExceptionMessage('Object for placeholder string1 is invalid, value 123 for key key is not a string'); $v->validate('test {string1} test.', [ 'string1' => [ 'type' => 'user', @@ -49,7 +49,7 @@ class ValidatorTest extends TestCase { ], ]); - $this->expectExceptionMessage('Object is invalid, key 456 is not a string'); + $this->expectExceptionMessage('Object for placeholder string1 is invalid, key 456 is not a string'); $v->validate('test {string1} test.', [ 'string1' => [ 'type' => 'user', diff --git a/tests/lib/Security/Normalizer/IpAddressTest.php b/tests/lib/Security/Normalizer/IpAddressTest.php index 55cb149309a..33a8b4d28f1 100644 --- a/tests/lib/Security/Normalizer/IpAddressTest.php +++ b/tests/lib/Security/Normalizer/IpAddressTest.php @@ -36,20 +36,20 @@ class IpAddressTest extends TestCase { '192.168.0.123/32', ], [ - '2001:0db8:85a3:0000:0000:8a2e:0370:7334', - '2001:db8:85a3::/64', + '2001:0db8:0000:0000:0000:8a2e:0370:7334', + '2001:db8::/56', ], [ '2001:db8:3333:4444:5555:6666:7777:8888', - '2001:db8:3333:4444::/64', + '2001:db8:3333:4400::/56', ], [ '::1234:5678', - '::/64', + '::/56', ], [ '[::1]', - '::/64', + '::/56', ], ]; } diff --git a/tests/lib/Share20/ManagerTest.php b/tests/lib/Share20/ManagerTest.php index 8b8d6ea4e65..03731a90754 100644 --- a/tests/lib/Share20/ManagerTest.php +++ b/tests/lib/Share20/ManagerTest.php @@ -2264,7 +2264,7 @@ class ManagerTest extends \Test\TestCase { public function testPathCreateChecksContainsSharedMount(): void { $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Path contains files shared with you'); + $this->expectExceptionMessage('You cannot share a folder that contains other shares'); $path = $this->createMock(Folder::class); $path->method('getPath')->willReturn('path'); diff --git a/tests/lib/TagsTest.php b/tests/lib/TagsTest.php index 7483ed15e6b..feb6bd2a1ad 100644 --- a/tests/lib/TagsTest.php +++ b/tests/lib/TagsTest.php @@ -10,7 +10,9 @@ namespace Test; use OCP\EventDispatcher\IEventDispatcher; use OCP\IDBConnection; use OCP\IUser; +use OCP\IUserManager; use OCP\IUserSession; +use OCP\Server; use Psr\Log\LoggerInterface; /** @@ -33,10 +35,10 @@ class TagsTest extends \Test\TestCase { protected function setUp(): void { parent::setUp(); - \OC_User::clearBackends(); - \OC_User::useBackend('dummy'); + Server::get(IUserManager::class)->clearBackends(); + Server::get(IUserManager::class)->registerBackend(new \Test\Util\User\Dummy()); $userId = $this->getUniqueID('user_'); - \OC::$server->getUserManager()->createUser($userId, 'pass'); + Server::get(IUserManager::class)->createUser($userId, 'pass'); \OC_User::setUserId($userId); $this->user = $this->createMock(IUser::class); $this->user->method('getUID') diff --git a/tests/lib/TaskProcessing/TaskProcessingTest.php b/tests/lib/TaskProcessing/TaskProcessingTest.php index 5dd38f83339..73f67b07266 100644 --- a/tests/lib/TaskProcessing/TaskProcessingTest.php +++ b/tests/lib/TaskProcessing/TaskProcessingTest.php @@ -28,6 +28,7 @@ use OCP\IServerContainer; use OCP\IUser; use OCP\IUserManager; use OCP\TaskProcessing\EShapeType; +use OCP\TaskProcessing\Events\GetTaskProcessingProvidersEvent; use OCP\TaskProcessing\Events\TaskFailedEvent; use OCP\TaskProcessing\Events\TaskSuccessfulEvent; use OCP\TaskProcessing\Exception\NotFoundException; @@ -131,8 +132,10 @@ class AsyncProvider implements IProvider { } class SuccessfulSyncProvider implements IProvider, ISynchronousProvider { + public const ID = 'test:sync:success'; + public function getId(): string { - return 'test:sync:success'; + return self::ID; } public function getName(): string { @@ -385,6 +388,132 @@ class FailingTextToImageProvider implements \OCP\TextToImage\IProvider { } } +class ExternalProvider implements IProvider { + public const ID = 'event:external:provider'; + public const TASK_TYPE_ID = 'event:external:tasktype'; + + public function getId(): string { + return self::ID; + } + public function getName(): string { + return 'External Provider via Event'; + } + public function getTaskTypeId(): string { + return self::TASK_TYPE_ID; + } + public function getExpectedRuntime(): int { + return 5; + } + public function getOptionalInputShape(): array { + return []; + } + public function getOptionalOutputShape(): array { + return []; + } + public function getInputShapeEnumValues(): array { + return []; + } + public function getInputShapeDefaults(): array { + return []; + } + public function getOptionalInputShapeEnumValues(): array { + return []; + } + public function getOptionalInputShapeDefaults(): array { + return []; + } + public function getOutputShapeEnumValues(): array { + return []; + } + public function getOptionalOutputShapeEnumValues(): array { + return []; + } +} + +class ConflictingExternalProvider implements IProvider { + // Same ID as SuccessfulSyncProvider + public const ID = 'test:sync:success'; + public const TASK_TYPE_ID = 'event:external:tasktype'; // Can be different task type + + public function getId(): string { + return self::ID; + } + public function getName(): string { + return 'Conflicting External Provider'; + } + public function getTaskTypeId(): string { + return self::TASK_TYPE_ID; + } + public function getExpectedRuntime(): int { + return 50; + } + public function getOptionalInputShape(): array { + return []; + } + public function getOptionalOutputShape(): array { + return []; + } + public function getInputShapeEnumValues(): array { + return []; + } + public function getInputShapeDefaults(): array { + return []; + } + public function getOptionalInputShapeEnumValues(): array { + return []; + } + public function getOptionalInputShapeDefaults(): array { + return []; + } + public function getOutputShapeEnumValues(): array { + return []; + } + public function getOptionalOutputShapeEnumValues(): array { + return []; + } +} + +class ExternalTaskType implements ITaskType { + public const ID = 'event:external:tasktype'; + + public function getId(): string { + return self::ID; + } + public function getName(): string { + return 'External Task Type via Event'; + } + public function getDescription(): string { + return 'A task type added via event'; + } + public function getInputShape(): array { + return ['external_input' => new ShapeDescriptor('Ext In', '', EShapeType::Text)]; + } + public function getOutputShape(): array { + return ['external_output' => new ShapeDescriptor('Ext Out', '', EShapeType::Text)]; + } +} + +class ConflictingExternalTaskType implements ITaskType { + // Same ID as built-in TextToText + public const ID = TextToText::ID; + + public function getId(): string { + return self::ID; + } + public function getName(): string { + return 'Conflicting External Task Type'; + } + public function getDescription(): string { + return 'Overrides built-in TextToText'; + } + public function getInputShape(): array { + return ['override_input' => new ShapeDescriptor('Override In', '', EShapeType::Number)]; + } + public function getOutputShape(): array { + return ['override_output' => new ShapeDescriptor('Override Out', '', EShapeType::Number)]; + } +} + /** * @group DB */ @@ -416,6 +545,10 @@ class TaskProcessingTest extends \Test\TestCase { FailingTextProcessingSummaryProvider::class => new FailingTextProcessingSummaryProvider(), SuccessfulTextToImageProvider::class => new SuccessfulTextToImageProvider(), FailingTextToImageProvider::class => new FailingTextToImageProvider(), + ExternalProvider::class => new ExternalProvider(), + ConflictingExternalProvider::class => new ConflictingExternalProvider(), + ExternalTaskType::class => new ExternalTaskType(), + ConflictingExternalTaskType::class => new ConflictingExternalTaskType(), ]; $userManager = \OCP\Server::get(IUserManager::class); @@ -447,6 +580,7 @@ class TaskProcessingTest extends \Test\TestCase { }); $this->eventDispatcher = $this->createMock(IEventDispatcher::class); + $this->configureEventDispatcherMock(); $text2imageManager = new \OC\TextToImage\Manager( $this->serverContainer, @@ -964,4 +1098,188 @@ class TaskProcessingTest extends \Test\TestCase { self::assertEquals('ERROR', $task->getErrorMessage()); self::assertTrue($this->providers[FailingTextToImageProvider::class]->ran); } + + public function testMergeProvidersLocalAndEvent() { + // Arrange: Local provider registered, DIFFERENT external provider via event + $this->registrationContext->expects($this->any())->method('getTaskProcessingProviders')->willReturn([ + new ServiceRegistration('test', SuccessfulSyncProvider::class) + ]); + $this->registrationContext->expects($this->any())->method('getTextProcessingProviders')->willReturn([]); + $this->registrationContext->expects($this->any())->method('getTextToImageProviders')->willReturn([]); + $this->registrationContext->expects($this->any())->method('getSpeechToTextProviders')->willReturn([]); + + $externalProvider = new ExternalProvider(); // ID = 'event:external:provider' + $this->configureEventDispatcherMock(providersToAdd: [$externalProvider]); + $this->manager = $this->createManagerInstance(); + + // Act + $providers = $this->manager->getProviders(); + + // Assert: Both providers should be present + self::assertArrayHasKey(SuccessfulSyncProvider::ID, $providers); + self::assertInstanceOf(SuccessfulSyncProvider::class, $providers[SuccessfulSyncProvider::ID]); + self::assertArrayHasKey(ExternalProvider::ID, $providers); + self::assertInstanceOf(ExternalProvider::class, $providers[ExternalProvider::ID]); + self::assertCount(2, $providers); + } + + public function testGetProvidersIncludesExternalViaEvent() { + // Arrange: No local providers, one external provider via event + $this->registrationContext->expects($this->any())->method('getTaskProcessingProviders')->willReturn([]); + $this->registrationContext->expects($this->any())->method('getTextProcessingProviders')->willReturn([]); + $this->registrationContext->expects($this->any())->method('getTextToImageProviders')->willReturn([]); + $this->registrationContext->expects($this->any())->method('getSpeechToTextProviders')->willReturn([]); + + + $externalProvider = new ExternalProvider(); + $this->configureEventDispatcherMock(providersToAdd: [$externalProvider]); + $this->manager = $this->createManagerInstance(); // Create manager with configured mocks + + // Act + $providers = $this->manager->getProviders(); // Returns ID-indexed array + + // Assert + self::assertArrayHasKey(ExternalProvider::ID, $providers); + self::assertInstanceOf(ExternalProvider::class, $providers[ExternalProvider::ID]); + self::assertCount(1, $providers); + self::assertTrue($this->manager->hasProviders()); + } + + public function testGetAvailableTaskTypesIncludesExternalViaEvent() { + // Arrange: No local types/providers, one external type and provider via event + $this->registrationContext->expects($this->any())->method('getTaskProcessingProviders')->willReturn([]); + $this->registrationContext->expects($this->any())->method('getTaskProcessingTaskTypes')->willReturn([]); + $this->registrationContext->expects($this->any())->method('getTextProcessingProviders')->willReturn([]); + $this->registrationContext->expects($this->any())->method('getTextToImageProviders')->willReturn([]); + $this->registrationContext->expects($this->any())->method('getSpeechToTextProviders')->willReturn([]); + + $externalProvider = new ExternalProvider(); // Provides ExternalTaskType + $externalTaskType = new ExternalTaskType(); + $this->configureEventDispatcherMock( + providersToAdd: [$externalProvider], + taskTypesToAdd: [$externalTaskType] + ); + $this->manager = $this->createManagerInstance(); + + // Act + $availableTypes = $this->manager->getAvailableTaskTypes(); + + // Assert + self::assertArrayHasKey(ExternalTaskType::ID, $availableTypes); + self::assertEquals(ExternalTaskType::ID, $externalProvider->getTaskTypeId(), 'Test Sanity: Provider must handle the Task Type'); + self::assertEquals('External Task Type via Event', $availableTypes[ExternalTaskType::ID]['name']); + // Check if shapes match the external type/provider + self::assertArrayHasKey('external_input', $availableTypes[ExternalTaskType::ID]['inputShape']); + self::assertArrayHasKey('external_output', $availableTypes[ExternalTaskType::ID]['outputShape']); + self::assertEmpty($availableTypes[ExternalTaskType::ID]['optionalInputShape']); // From ExternalProvider + } + + public function testLocalProviderWinsConflictWithEvent() { + // Arrange: Local provider registered, conflicting external provider via event + $this->registrationContext->expects($this->any())->method('getTaskProcessingProviders')->willReturn([ + new ServiceRegistration('test', SuccessfulSyncProvider::class) + ]); + $this->registrationContext->expects($this->any())->method('getTextProcessingProviders')->willReturn([]); + $this->registrationContext->expects($this->any())->method('getTextToImageProviders')->willReturn([]); + $this->registrationContext->expects($this->any())->method('getSpeechToTextProviders')->willReturn([]); + + $conflictingExternalProvider = new ConflictingExternalProvider(); // ID = 'test:sync:success' + $this->configureEventDispatcherMock(providersToAdd: [$conflictingExternalProvider]); + $this->manager = $this->createManagerInstance(); + + // Act + $providers = $this->manager->getProviders(); + + // Assert: Only the local provider should be present for the conflicting ID + self::assertArrayHasKey(SuccessfulSyncProvider::ID, $providers); + self::assertInstanceOf(SuccessfulSyncProvider::class, $providers[SuccessfulSyncProvider::ID]); + self::assertCount(1, $providers); // Ensure no extra provider was added + } + + public function testMergeTaskTypesLocalAndEvent() { + // Arrange: Local type registered, DIFFERENT external type via event + $this->registrationContext->expects($this->any())->method('getTaskProcessingProviders')->willReturn([ + new ServiceRegistration('test', AsyncProvider::class) + ]); + $this->registrationContext->expects($this->any())->method('getTaskProcessingTaskTypes')->willReturn([ + new ServiceRegistration('test', AudioToImage::class) + ]); + $this->registrationContext->expects($this->any())->method('getTextProcessingProviders')->willReturn([]); + $this->registrationContext->expects($this->any())->method('getTextToImageProviders')->willReturn([]); + $this->registrationContext->expects($this->any())->method('getSpeechToTextProviders')->willReturn([]); + + $externalTaskType = new ExternalTaskType(); // ID = 'event:external:tasktype' + $externalProvider = new ExternalProvider(); // Handles 'event:external:tasktype' + $this->configureEventDispatcherMock( + providersToAdd: [$externalProvider], + taskTypesToAdd: [$externalTaskType] + ); + $this->manager = $this->createManagerInstance(); + + // Act + $availableTypes = $this->manager->getAvailableTaskTypes(); + + // Assert: Both task types should be available + self::assertArrayHasKey(AudioToImage::ID, $availableTypes); + self::assertEquals(AudioToImage::class, $availableTypes[AudioToImage::ID]['name']); + + self::assertArrayHasKey(ExternalTaskType::ID, $availableTypes); + self::assertEquals('External Task Type via Event', $availableTypes[ExternalTaskType::ID]['name']); + + self::assertCount(2, $availableTypes); + } + + private function createManagerInstance(): Manager { + // Clear potentially cached config values if needed + $this->config->deleteAppValue('core', 'ai.taskprocessing_type_preferences'); + + // Re-create Text2ImageManager if its state matters or mocks change + $text2imageManager = new \OC\TextToImage\Manager( + $this->serverContainer, + $this->coordinator, + \OC::$server->get(LoggerInterface::class), + $this->jobList, + \OC::$server->get(\OC\TextToImage\Db\TaskMapper::class), + $this->config, // Use the shared config mock + \OC::$server->get(IAppDataFactory::class), + ); + + return new Manager( + $this->config, + $this->coordinator, + $this->serverContainer, + \OC::$server->get(LoggerInterface::class), + $this->taskMapper, + $this->jobList, + $this->eventDispatcher, // Use the potentially reconfigured mock + \OC::$server->get(IAppDataFactory::class), + $this->rootFolder, + $text2imageManager, + $this->userMountCache, + \OC::$server->get(IClientService::class), + \OC::$server->get(IAppManager::class), + \OC::$server->get(ICacheFactory::class), + ); + } + + private function configureEventDispatcherMock( + array $providersToAdd = [], + array $taskTypesToAdd = [], + ?int $expectedCalls = null, + ): void { + $dispatchExpectation = $expectedCalls === null ? $this->any() : $this->exactly($expectedCalls); + + $this->eventDispatcher->expects($dispatchExpectation) + ->method('dispatchTyped') + ->willReturnCallback(function (object $event) use ($providersToAdd, $taskTypesToAdd) { + if ($event instanceof GetTaskProcessingProvidersEvent) { + foreach ($providersToAdd as $providerInstance) { + $event->addProvider($providerInstance); + } + foreach ($taskTypesToAdd as $taskTypeInstance) { + $event->addTaskType($taskTypeInstance); + } + } + }); + } } diff --git a/tests/lib/Template/JSCombinerTest.php b/tests/lib/Template/JSCombinerTest.php index 63a52f34047..e4e6594c05c 100644 --- a/tests/lib/Template/JSCombinerTest.php +++ b/tests/lib/Template/JSCombinerTest.php @@ -70,14 +70,10 @@ class JSCombinerTest extends \Test\TestCase { $this->config ->expects($this->exactly(2)) ->method('getValue') - ->withConsecutive( - ['debug'], - ['installed'] - ) - ->willReturnOnConsecutiveCalls( - false, - false - ); + ->willReturnMap([ + ['debug', false], + ['installed', false] + ]); $actual = $this->jsCombiner->process(__DIR__, '/data/combine.json', 'awesomeapp'); $this->assertFalse($actual); @@ -87,14 +83,10 @@ class JSCombinerTest extends \Test\TestCase { $this->config ->expects($this->exactly(2)) ->method('getValue') - ->withConsecutive( - ['debug'], - ['installed'] - ) - ->willReturnOnConsecutiveCalls( - false, - true - ); + ->willReturnMap([ + ['debug', '', false], + ['installed', '', true], + ]); $folder = $this->createMock(ISimpleFolder::class); $this->appData->expects($this->once())->method('getFolder')->with('awesomeapp')->willThrowException(new NotFoundException()); $this->appData->expects($this->once())->method('newFolder')->with('awesomeapp')->willReturn($folder); @@ -127,14 +119,10 @@ class JSCombinerTest extends \Test\TestCase { $this->config ->expects($this->exactly(2)) ->method('getValue') - ->withConsecutive( - ['debug'], - ['installed'] - ) - ->willReturnOnConsecutiveCalls( - false, - true - ); + ->willReturnMap([ + ['debug', '', false], + ['installed', '', true], + ]); $folder = $this->createMock(ISimpleFolder::class); $this->appData->expects($this->once())->method('getFolder')->with('awesomeapp')->willReturn($folder); $file = $this->createMock(ISimpleFile::class); @@ -165,14 +153,10 @@ class JSCombinerTest extends \Test\TestCase { $this->config ->expects($this->exactly(2)) ->method('getValue') - ->withConsecutive( - ['debug'], - ['installed'] - ) - ->willReturnOnConsecutiveCalls( - false, - true - ); + ->willReturnMap([ + ['debug', '', false], + ['installed', '', true], + ]); $folder = $this->createMock(ISimpleFolder::class); $this->appData->expects($this->once())->method('getFolder')->with('awesomeapp')->willReturn($folder); $file = $this->createMock(ISimpleFile::class); @@ -206,14 +190,10 @@ class JSCombinerTest extends \Test\TestCase { $this->config ->expects($this->exactly(2)) ->method('getValue') - ->withConsecutive( - ['debug'], - ['installed'] - ) - ->willReturnOnConsecutiveCalls( - false, - true - ); + ->willReturnMap([ + ['debug', '', false], + ['installed', '', true], + ]); $folder = $this->createMock(ISimpleFolder::class); $this->appData->expects($this->once()) ->method('getFolder') @@ -395,15 +375,11 @@ class JSCombinerTest extends \Test\TestCase { $folder->expects($this->exactly(3)) ->method('getFile') - ->withConsecutive( - [$fileName], - [$fileName . '.deps'], - [$fileName . '.gzip'] - )->willReturnOnConsecutiveCalls( - $file, - $depsFile, - $gzFile - ); + ->willReturnMap([ + [$fileName, $file], + [$fileName . '.deps', $depsFile], + [$fileName . '.gzip', $gzFile] + ]); $file->expects($this->once()) ->method('putContent') @@ -484,7 +460,7 @@ var b = \'world\'; $this->assertTrue($actual); } - public function dataGetCachedSCSS() { + public static function dataGetCachedSCSS(): array { return [ ['awesomeapp', 'core/js/foo.json', '/js/core/foo.js'], ['files', 'apps/files/js/foo.json', '/js/files/foo.js'] diff --git a/tests/lib/TemplateFunctionsTest.php b/tests/lib/TemplateFunctionsTest.php index a693a39c580..5b23ef434c2 100644 --- a/tests/lib/TemplateFunctionsTest.php +++ b/tests/lib/TemplateFunctionsTest.php @@ -11,7 +11,7 @@ class TemplateFunctionsTest extends \Test\TestCase { protected function setUp(): void { parent::setUp(); - require_once \OC::$SERVERROOT . '/lib/private/legacy/OC_Template.php'; + require_once \OC::$SERVERROOT . '/lib/private/Template/functions.php'; } public function testPJavaScript(): void { diff --git a/tests/lib/TemplateLayoutTest.php b/tests/lib/TemplateLayoutTest.php index 405f1df7330..b3895525408 100644 --- a/tests/lib/TemplateLayoutTest.php +++ b/tests/lib/TemplateLayoutTest.php @@ -14,50 +14,73 @@ use OC\TemplateLayout; use OCP\App\IAppManager; use OCP\AppFramework\Http\TemplateResponse; use OCP\IConfig; +use OCP\INavigationManager; +use OCP\ServerVersion; +use OCP\Template\ITemplateManager; +use PHPUnit\Framework\MockObject\MockObject; class TemplateLayoutTest extends \Test\TestCase { - + private IConfig&MockObject $config; + private IAppManager&MockObject $appManager; + private InitialStateService&MockObject $initialState; + private INavigationManager&MockObject $navigationManager; + private ITemplateManager&MockObject $templateManager; + private ServerVersion&MockObject $serverVersion; + + private TemplateLayout $templateLayout; + + protected function setUp(): void { + parent::setUp(); + + $this->config = $this->createMock(IConfig::class); + $this->appManager = $this->createMock(IAppManager::class); + $this->initialState = $this->createMock(InitialStateService::class); + $this->navigationManager = $this->createMock(INavigationManager::class); + $this->templateManager = $this->createMock(ITemplateManager::class); + $this->serverVersion = $this->createMock(ServerVersion::class); + } /** @dataProvider dataVersionHash */ public function testVersionHash($path, $file, $installed, $debug, $expected): void { - $appManager = $this->createMock(IAppManager::class); - $appManager->expects(self::any()) + $this->appManager->expects(self::any()) ->method('getAppVersion') ->willReturnCallback(fn ($appId) => match ($appId) { 'shippedApp' => 'shipped_1', 'otherApp' => 'other_2', default => "$appId", }); - $appManager->expects(self::any()) + $this->appManager->expects(self::any()) ->method('isShipped') ->willReturnCallback(fn (string $app) => $app === 'shippedApp'); - $config = $this->createMock(IConfig::class); - $config->expects(self::atLeastOnce()) + $this->config->expects(self::atLeastOnce()) ->method('getSystemValueBool') ->willReturnMap([ ['installed', false, $installed], ['debug', false, $debug], ]); - $config->expects(self::any()) + $this->config->expects(self::any()) ->method('getAppValue') ->with('theming', 'cachebuster', '0') ->willReturn('42'); - $initialState = $this->createMock(InitialStateService::class); - - $this->overwriteService(IConfig::class, $config); - $this->overwriteService(IAppManager::class, $appManager); - $this->overwriteService(InitialStateService::class, $initialState); - - $layout = $this->getMockBuilder(TemplateLayout::class) + $this->templateLayout = $this->getMockBuilder(TemplateLayout::class) ->onlyMethods(['getAppNamefromPath']) - ->setConstructorArgs([TemplateResponse::RENDER_AS_ERROR]) + ->setConstructorArgs([ + $this->config, + $this->appManager, + $this->initialState, + $this->navigationManager, + $this->templateManager, + $this->serverVersion, + ]) ->getMock(); + $layout = $this->templateLayout->getPageTemplate(TemplateResponse::RENDER_AS_ERROR, ''); + self::invokePrivate(TemplateLayout::class, 'versionHash', ['version_hash']); - $layout->expects(self::any()) + $this->templateLayout->expects(self::any()) ->method('getAppNamefromPath') ->willReturnCallback(fn ($appName) => match($appName) { 'apps/shipped' => 'shippedApp', @@ -65,7 +88,7 @@ class TemplateLayoutTest extends \Test\TestCase { default => false, }); - $hash = self::invokePrivate($layout, 'getVersionHashSuffix', [$path, $file]); + $hash = self::invokePrivate($this->templateLayout, 'getVersionHashSuffix', [$path, $file]); self::assertEquals($expected, $hash); } diff --git a/tests/lib/TestCase.php b/tests/lib/TestCase.php index cfed2b06c61..918edf7150e 100644 --- a/tests/lib/TestCase.php +++ b/tests/lib/TestCase.php @@ -549,8 +549,6 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase { * @param array $vars */ protected function assertTemplate($expectedHtml, $template, $vars = []) { - require_once __DIR__ . '/../../lib/private/legacy/template/functions.php'; - $requestToken = 12345; /** @var Defaults|\PHPUnit\Framework\MockObject\MockObject $l10n */ $theme = $this->getMockBuilder('\OCP\Defaults') diff --git a/tests/lib/User/DatabaseTest.php b/tests/lib/User/DatabaseTest.php index bd74ab333fb..900f0ddd3fa 100644 --- a/tests/lib/User/DatabaseTest.php +++ b/tests/lib/User/DatabaseTest.php @@ -25,6 +25,9 @@ class DatabaseTest extends Backend { /** @var IEventDispatcher|MockObject */ private $eventDispatcher; + /** @var \OC\User\Database */ + protected $backend; + public function getUser() { $user = parent::getUser(); $this->users[] = $user; @@ -139,4 +142,14 @@ class DatabaseTest extends Backend { $result = $this->backend->getDisplayNames('@nextcloud.COM'); $this->assertCount(2, $result); } + + public function testUserCount(): void { + $base = $this->backend->countUsers() ?: 0; + $users = $this->backend->getUsers(); + self::assertEquals($base, count($users)); + + $user = $this->getUser(); + $this->backend->createUser($user, $user); + self::assertEquals($base + 1, $this->backend->countUsers()); + } } diff --git a/tests/lib/User/ManagerTest.php b/tests/lib/User/ManagerTest.php index 53f57eee086..5d3966cf4d8 100644 --- a/tests/lib/User/ManagerTest.php +++ b/tests/lib/User/ManagerTest.php @@ -79,6 +79,20 @@ class ManagerTest extends TestCase { $this->assertTrue($manager->userExists('foo')); } + public function testUserExistsTooLong(): void { + /** @var \Test\Util\User\Dummy|MockObject $backend */ + $backend = $this->createMock(\Test\Util\User\Dummy::class); + $backend->expects($this->never()) + ->method('userExists') + ->with($this->equalTo('foo')) + ->willReturn(true); + + $manager = new \OC\User\Manager($this->config, $this->cacheFactory, $this->eventDispatcher, $this->logger); + $manager->registerBackend($backend); + + $this->assertFalse($manager->userExists('foo' . str_repeat('a', 62))); + } + public function testUserExistsSingleBackendNotExists(): void { /** * @var \Test\Util\User\Dummy | \PHPUnit\Framework\MockObject\MockObject $backend @@ -230,6 +244,20 @@ class ManagerTest extends TestCase { $this->assertEquals(null, $manager->get('foo')); } + public function testGetTooLong(): void { + /** @var \Test\Util\User\Dummy|MockObject $backend */ + $backend = $this->createMock(\Test\Util\User\Dummy::class); + $backend->expects($this->never()) + ->method('userExists') + ->with($this->equalTo('foo')) + ->willReturn(false); + + $manager = new \OC\User\Manager($this->config, $this->cacheFactory, $this->eventDispatcher, $this->logger); + $manager->registerBackend($backend); + + $this->assertEquals(null, $manager->get('foo' . str_repeat('a', 62))); + } + public function testGetOneBackendDoNotTranslateLoginNames(): void { /** * @var \Test\Util\User\Dummy | \PHPUnit\Framework\MockObject\MockObject $backend @@ -305,7 +333,7 @@ class ManagerTest extends TestCase { $this->assertEquals('foo3', array_shift($result)->getUID()); } - public function dataCreateUserInvalid() { + public static function dataCreateUserInvalid(): array { return [ ['te?st', 'foo', 'Only the following characters are allowed in a username:' . ' "a-z", "A-Z", "0-9", spaces and "_.@-\'"'], @@ -333,6 +361,7 @@ class ManagerTest extends TestCase { ['..', 'foo', 'Username must not consist of dots only'], ['.test', '', 'A valid password must be provided'], ['test', '', 'A valid password must be provided'], + ['test' . str_repeat('a', 61), '', 'Login is too long'], ]; } @@ -760,16 +789,11 @@ class ManagerTest extends TestCase { $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->exactly(3)) ->method('userExists') - ->withConsecutive( - [$this->equalTo('uid1')], - [$this->equalTo('uid99')], - [$this->equalTo('uid2')] - ) - ->willReturnOnConsecutiveCalls( - true, - false, - true - ); + ->willReturnMap([ + ['uid1', true], + ['uid99', false], + ['uid2', true] + ]); $manager = new \OC\User\Manager($config, $this->cacheFactory, $this->eventDispatcher, $this->logger); $manager->registerBackend($backend); diff --git a/tests/lib/User/SessionTest.php b/tests/lib/User/SessionTest.php index b3f040d71ec..7ed02571460 100644 --- a/tests/lib/User/SessionTest.php +++ b/tests/lib/User/SessionTest.php @@ -34,6 +34,7 @@ use OCP\Lockdown\ILockdownManager; use OCP\Security\Bruteforce\IThrottler; use OCP\Security\ISecureRandom; use OCP\User\Events\PostLoginEvent; +use PHPUnit\Framework\ExpectationFailedException; use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use function array_diff; @@ -611,6 +612,45 @@ class SessionTest extends \Test\TestCase { self::assertFalse($loginResult); } + public function testTryTokenLoginNotAnAppPassword(): void { + $request = $this->createMock(IRequest::class); + $this->config->expects(self::once()) + ->method('getSystemValueString') + ->with('instanceid') + ->willReturn('abc123'); + $request->method('getHeader')->with('Authorization')->willReturn(''); + $request->method('getCookie')->with('abc123')->willReturn('abcde12345'); + $this->session->expects(self::once()) + ->method('getId') + ->willReturn('abcde12345'); + $dbToken = new PublicKeyToken(); + $dbToken->setId(42); + $dbToken->setUid('johnny'); + $dbToken->setLoginName('johnny'); + $dbToken->setLastCheck(0); + $dbToken->setType(IToken::TEMPORARY_TOKEN); + $dbToken->setRemember(IToken::REMEMBER); + $this->tokenProvider->expects(self::any()) + ->method('getToken') + ->with('abcde12345') + ->willReturn($dbToken); + $this->session->method('set') + ->willReturnCallback(function ($key, $value) { + if ($key === 'app_password') { + throw new ExpectationFailedException('app_password should not be set in session'); + } + }); + $user = $this->createMock(IUser::class); + $user->method('isEnabled')->willReturn(true); + $this->manager->method('get') + ->with('johnny') + ->willReturn($user); + + $loginResult = $this->userSession->tryTokenLogin($request); + + self::assertTrue($loginResult); + } + public function testRememberLoginValidToken(): void { $session = $this->createMock(Memory::class); $managerMethods = get_class_methods(Manager::class); diff --git a/tests/lib/UtilTest.php b/tests/lib/UtilTest.php index c1dea8d5423..0063a991e48 100644 --- a/tests/lib/UtilTest.php +++ b/tests/lib/UtilTest.php @@ -8,6 +8,7 @@ namespace Test; use OC_Util; +use OCP\Util; /** * Class UtilTest @@ -17,7 +18,7 @@ use OC_Util; */ class UtilTest extends \Test\TestCase { public function testGetVersion(): void { - $version = \OCP\Util::getVersion(); + $version = Util::getVersion(); $this->assertTrue(is_array($version)); foreach ($version as $num) { $this->assertTrue(is_int($num)); @@ -41,25 +42,25 @@ class UtilTest extends \Test\TestCase { 'And It Even May <strong>Nest</strong>' ], ]; - $result = OC_Util::sanitizeHTML($badArray); + $result = Util::sanitizeHTML($badArray); $this->assertEquals($goodArray, $result); $badString = '<img onload="alert(1)" />'; - $result = OC_Util::sanitizeHTML($badString); + $result = Util::sanitizeHTML($badString); $this->assertEquals('<img onload="alert(1)" />', $result); $badString = "<script>alert('Hacked!');</script>"; - $result = OC_Util::sanitizeHTML($badString); + $result = Util::sanitizeHTML($badString); $this->assertEquals('<script>alert('Hacked!');</script>', $result); $goodString = 'This is a good string without HTML.'; - $result = OC_Util::sanitizeHTML($goodString); + $result = Util::sanitizeHTML($goodString); $this->assertEquals('This is a good string without HTML.', $result); } public function testEncodePath(): void { $component = '/ยง#@test%&^รค/-child'; - $result = OC_Util::encodePath($component); + $result = Util::encodePath($component); $this->assertEquals('/%C2%A7%23%40test%25%26%5E%C3%A4/-child', $result); } @@ -86,7 +87,7 @@ class UtilTest extends \Test\TestCase { * So we check that with strict email verification we fallback to the default */ public function testGetDefaultEmailAddressStrict(): void { - $email = \OCP\Util::getDefaultEmailAddress('no-reply'); + $email = Util::getDefaultEmailAddress('no-reply'); $this->assertEquals('no-reply@localhost.localdomain', $email); } @@ -96,7 +97,7 @@ class UtilTest extends \Test\TestCase { public function testGetDefaultEmailAddress(): void { $config = \OC::$server->getConfig(); $config->setAppValue('core', 'enforce_strict_email_check', 'no'); - $email = \OCP\Util::getDefaultEmailAddress('no-reply'); + $email = Util::getDefaultEmailAddress('no-reply'); $this->assertEquals('no-reply@localhost', $email); $config->deleteAppValue('core', 'enforce_strict_email_check'); } @@ -104,7 +105,7 @@ class UtilTest extends \Test\TestCase { public function testGetDefaultEmailAddressFromConfig(): void { $config = \OC::$server->getConfig(); $config->setSystemValue('mail_domain', 'example.com'); - $email = \OCP\Util::getDefaultEmailAddress('no-reply'); + $email = Util::getDefaultEmailAddress('no-reply'); $this->assertEquals('no-reply@example.com', $email); $config->deleteSystemValue('mail_domain'); } @@ -113,7 +114,7 @@ class UtilTest extends \Test\TestCase { $config = \OC::$server->getConfig(); $config->setSystemValue('mail_domain', 'example.com'); $config->setSystemValue('mail_from_address', 'owncloud'); - $email = \OCP\Util::getDefaultEmailAddress('no-reply'); + $email = Util::getDefaultEmailAddress('no-reply'); $this->assertEquals('owncloud@example.com', $email); $config->deleteSystemValue('mail_domain'); $config->deleteSystemValue('mail_from_address'); @@ -135,19 +136,19 @@ class UtilTest extends \Test\TestCase { $oldConfigVersion = $config->getSystemValue('version', '0.0.0'); $oldSessionVersion = \OC::$server->getSession()->get('OC_Version'); - $this->assertFalse(\OCP\Util::needUpgrade()); + $this->assertFalse(Util::needUpgrade()); $config->setSystemValue('version', '7.0.0.0'); \OC::$server->getSession()->set('OC_Version', [7, 0, 0, 1]); - self::invokePrivate(new \OCP\Util, 'needUpgradeCache', [null]); + self::invokePrivate(new Util, 'needUpgradeCache', [null]); - $this->assertTrue(\OCP\Util::needUpgrade()); + $this->assertTrue(Util::needUpgrade()); $config->setSystemValue('version', $oldConfigVersion); \OC::$server->getSession()->set('OC_Version', $oldSessionVersion); - self::invokePrivate(new \OCP\Util, 'needUpgradeCache', [null]); + self::invokePrivate(new Util, 'needUpgradeCache', [null]); - $this->assertFalse(\OCP\Util::needUpgrade()); + $this->assertFalse(Util::needUpgrade()); } public function testCheckDataDirectoryValidity(): void { @@ -170,39 +171,37 @@ class UtilTest extends \Test\TestCase { protected function setUp(): void { parent::setUp(); - \OC_Util::$scripts = []; \OC_Util::$styles = []; - self::invokePrivate(\OCP\Util::class, 'scripts', [[]]); - self::invokePrivate(\OCP\Util::class, 'scriptDeps', [[]]); + self::invokePrivate(Util::class, 'scripts', [[]]); + self::invokePrivate(Util::class, 'scriptDeps', [[]]); } protected function tearDown(): void { parent::tearDown(); - \OC_Util::$scripts = []; \OC_Util::$styles = []; - self::invokePrivate(\OCP\Util::class, 'scripts', [[]]); - self::invokePrivate(\OCP\Util::class, 'scriptDeps', [[]]); + self::invokePrivate(Util::class, 'scripts', [[]]); + self::invokePrivate(Util::class, 'scriptDeps', [[]]); } public function testAddScript(): void { - \OCP\Util::addScript('first', 'myFirstJSFile'); - \OCP\Util::addScript('core', 'myFancyJSFile1'); - \OCP\Util::addScript('files', 'myFancyJSFile2', 'core'); - \OCP\Util::addScript('myApp5', 'myApp5JSFile', 'myApp2'); - \OCP\Util::addScript('myApp', 'myFancyJSFile3'); - \OCP\Util::addScript('core', 'myFancyJSFile4'); + Util::addScript('first', 'myFirstJSFile'); + Util::addScript('core', 'myFancyJSFile1'); + Util::addScript('files', 'myFancyJSFile2', 'core'); + Util::addScript('myApp5', 'myApp5JSFile', 'myApp2'); + Util::addScript('myApp', 'myFancyJSFile3'); + Util::addScript('core', 'myFancyJSFile4'); // after itself - \OCP\Util::addScript('core', 'myFancyJSFile5', 'core'); + Util::addScript('core', 'myFancyJSFile5', 'core'); // add duplicate - \OCP\Util::addScript('core', 'myFancyJSFile1'); + Util::addScript('core', 'myFancyJSFile1'); // dependency chain - \OCP\Util::addScript('myApp4', 'myApp4JSFile', 'myApp3'); - \OCP\Util::addScript('myApp3', 'myApp3JSFile', 'myApp2'); - \OCP\Util::addScript('myApp2', 'myApp2JSFile', 'myApp'); - \OCP\Util::addScript('core', 'common'); - \OCP\Util::addScript('core', 'main'); + Util::addScript('myApp4', 'myApp4JSFile', 'myApp3'); + Util::addScript('myApp3', 'myApp3JSFile', 'myApp2'); + Util::addScript('myApp2', 'myApp2JSFile', 'myApp'); + Util::addScript('core', 'common'); + Util::addScript('core', 'main'); - $scripts = \OCP\Util::getScripts(); + $scripts = Util::getScripts(); // Core should appear first $this->assertEquals( @@ -278,49 +277,32 @@ class UtilTest extends \Test\TestCase { } public function testAddScriptCircularDependency(): void { - \OCP\Util::addScript('circular', 'file1', 'dependency'); - \OCP\Util::addScript('dependency', 'file2', 'circular'); + Util::addScript('circular', 'file1', 'dependency'); + Util::addScript('dependency', 'file2', 'circular'); - $scripts = \OCP\Util::getScripts(); + $scripts = Util::getScripts(); $this->assertContains('circular/js/file1', $scripts); $this->assertContains('dependency/js/file2', $scripts); } - public function testAddVendorScript(): void { - \OC_Util::addVendorScript('core', 'myFancyJSFile1'); - \OC_Util::addVendorScript('myApp', 'myFancyJSFile2'); - \OC_Util::addVendorScript('core', 'myFancyJSFile0', true); - \OC_Util::addVendorScript('core', 'myFancyJSFile10', true); - // add duplicate - \OC_Util::addVendorScript('core', 'myFancyJSFile1'); - - $this->assertEquals([ - 'core/vendor/myFancyJSFile10', - 'core/vendor/myFancyJSFile0', - 'core/vendor/myFancyJSFile1', - 'myApp/vendor/myFancyJSFile2', - ], \OC_Util::$scripts); - $this->assertEquals([], \OC_Util::$styles); - } - public function testAddTranslations(): void { - \OC_Util::addTranslations('appId', 'de'); + Util::addTranslations('appId', 'de'); $this->assertEquals([ 'appId/l10n/de' - ], \OC_Util::$scripts); + ], Util::getScripts()); $this->assertEquals([], \OC_Util::$styles); } public function testAddStyle(): void { - \OC_Util::addStyle('core', 'myFancyCSSFile1'); - \OC_Util::addStyle('myApp', 'myFancyCSSFile2'); - \OC_Util::addStyle('core', 'myFancyCSSFile0', true); - \OC_Util::addStyle('core', 'myFancyCSSFile10', true); + Util::addStyle('core', 'myFancyCSSFile1'); + Util::addStyle('myApp', 'myFancyCSSFile2'); + Util::addStyle('core', 'myFancyCSSFile0', true); + Util::addStyle('core', 'myFancyCSSFile10', true); // add duplicate - \OC_Util::addStyle('core', 'myFancyCSSFile1'); + Util::addStyle('core', 'myFancyCSSFile1'); - $this->assertEquals([], \OC_Util::$scripts); + $this->assertEquals([], Util::getScripts()); $this->assertEquals([ 'core/css/myFancyCSSFile10', 'core/css/myFancyCSSFile0', @@ -337,7 +319,7 @@ class UtilTest extends \Test\TestCase { // add duplicate \OC_Util::addVendorStyle('core', 'myFancyCSSFile1'); - $this->assertEquals([], \OC_Util::$scripts); + $this->assertEquals([], Util::getScripts()); $this->assertEquals([ 'core/vendor/myFancyCSSFile10', 'core/vendor/myFancyCSSFile0', @@ -347,9 +329,9 @@ class UtilTest extends \Test\TestCase { } public function testShortenMultibyteString(): void { - $this->assertEquals('Short nuff', \OCP\Util::shortenMultibyteString('Short nuff', 255)); - $this->assertEquals('ABC', \OCP\Util::shortenMultibyteString('ABCDEF', 3)); + $this->assertEquals('Short nuff', Util::shortenMultibyteString('Short nuff', 255)); + $this->assertEquals('ABC', Util::shortenMultibyteString('ABCDEF', 3)); // each of the characters is 12 bytes - $this->assertEquals('๐', \OCP\Util::shortenMultibyteString('๐๐๐', 16, 2)); + $this->assertEquals('๐', Util::shortenMultibyteString('๐๐๐', 16, 2)); } } |