diff options
Diffstat (limited to 'tests/lib')
62 files changed, 2559 insertions, 750 deletions
diff --git a/tests/lib/App/AppManagerTest.php b/tests/lib/App/AppManagerTest.php index de515837406..3518ada3314 100644 --- a/tests/lib/App/AppManagerTest.php +++ b/tests/lib/App/AppManagerTest.php @@ -14,7 +14,10 @@ namespace Test\App; use OC\App\AppManager; use OC\AppConfig; use OCP\App\AppPathNotFoundException; +use OCP\App\Events\AppDisableEvent; +use OCP\App\Events\AppEnableEvent; use OCP\App\IAppManager; +use OCP\EventDispatcher\IEventDispatcher; use OCP\ICache; use OCP\ICacheFactory; use OCP\IConfig; @@ -91,6 +94,9 @@ class AppManagerTest extends TestCase { protected $cacheFactory; /** @var EventDispatcherInterface|MockObject */ + protected $legacyEventDispatcher; + + /** @var IEventDispatcher|MockObject */ protected $eventDispatcher; /** @var LoggerInterface|MockObject */ @@ -108,7 +114,8 @@ class AppManagerTest extends TestCase { $this->appConfig = $this->getAppConfig(); $this->cacheFactory = $this->createMock(ICacheFactory::class); $this->cache = $this->createMock(ICache::class); - $this->eventDispatcher = $this->createMock(EventDispatcherInterface::class); + $this->legacyEventDispatcher = $this->createMock(EventDispatcherInterface::class); + $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->logger = $this->createMock(LoggerInterface::class); $this->cacheFactory->expects($this->any()) ->method('createDistributed') @@ -120,6 +127,7 @@ class AppManagerTest extends TestCase { $this->appConfig, $this->groupManager, $this->cacheFactory, + $this->legacyEventDispatcher, $this->eventDispatcher, $this->logger ); @@ -137,12 +145,14 @@ class AppManagerTest extends TestCase { if ($this->manager->isEnabledForUser('files_trashbin')) { $this->manager->disableApp('files_trashbin'); } + $this->eventDispatcher->expects($this->once())->method('dispatchTyped')->with(new AppEnableEvent('files_trashbin')); $this->manager->enableApp('files_trashbin'); $this->assertEquals('yes', $this->appConfig->getValue('files_trashbin', 'enabled', 'no')); } public function testDisableApp() { $this->expectClearCache(); + $this->eventDispatcher->expects($this->once())->method('dispatchTyped')->with(new AppDisableEvent('files_trashbin')); $this->manager->disableApp('files_trashbin'); $this->assertEquals('no', $this->appConfig->getValue('files_trashbin', 'enabled', 'no')); } @@ -175,7 +185,7 @@ class AppManagerTest extends TestCase { /** @var AppManager|MockObject $manager */ $manager = $this->getMockBuilder(AppManager::class) ->setConstructorArgs([ - $this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger + $this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->legacyEventDispatcher, $this->eventDispatcher, $this->logger ]) ->setMethods([ 'getAppPath', @@ -187,6 +197,8 @@ class AppManagerTest extends TestCase { ->with('test') ->willReturn('apps/test'); + $this->eventDispatcher->expects($this->once())->method('dispatchTyped')->with(new AppEnableEvent('test', ['group1', 'group2'])); + $manager->enableAppForGroups('test', $groups); $this->assertEquals('["group1","group2"]', $this->appConfig->getValue('test', 'enabled', 'no')); } @@ -222,7 +234,7 @@ class AppManagerTest extends TestCase { /** @var AppManager|MockObject $manager */ $manager = $this->getMockBuilder(AppManager::class) ->setConstructorArgs([ - $this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger + $this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->legacyEventDispatcher, $this->eventDispatcher, $this->logger ]) ->setMethods([ 'getAppPath', @@ -240,6 +252,8 @@ class AppManagerTest extends TestCase { ->with('test') ->willReturn($appInfo); + $this->eventDispatcher->expects($this->once())->method('dispatchTyped')->with(new AppEnableEvent('test', ['group1', 'group2'])); + $manager->enableAppForGroups('test', $groups); $this->assertEquals('["group1","group2"]', $this->appConfig->getValue('test', 'enabled', 'no')); } @@ -276,7 +290,7 @@ class AppManagerTest extends TestCase { /** @var AppManager|MockObject $manager */ $manager = $this->getMockBuilder(AppManager::class) ->setConstructorArgs([ - $this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger + $this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->legacyEventDispatcher, $this->eventDispatcher, $this->logger ]) ->setMethods([ 'getAppPath', @@ -296,6 +310,8 @@ class AppManagerTest extends TestCase { 'types' => [$type], ]); + $this->eventDispatcher->expects($this->never())->method('dispatchTyped')->with(new AppEnableEvent('test', ['group1', 'group2'])); + $manager->enableAppForGroups('test', $groups); } @@ -470,7 +486,7 @@ class AppManagerTest extends TestCase { public function testGetAppsNeedingUpgrade() { /** @var AppManager|MockObject $manager */ $manager = $this->getMockBuilder(AppManager::class) - ->setConstructorArgs([$this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger]) + ->setConstructorArgs([$this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->legacyEventDispatcher, $this->eventDispatcher, $this->logger]) ->setMethods(['getAppInfo']) ->getMock(); @@ -521,7 +537,7 @@ class AppManagerTest extends TestCase { public function testGetIncompatibleApps() { /** @var AppManager|MockObject $manager */ $manager = $this->getMockBuilder(AppManager::class) - ->setConstructorArgs([$this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger]) + ->setConstructorArgs([$this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->legacyEventDispatcher, $this->eventDispatcher, $this->logger]) ->setMethods(['getAppInfo']) ->getMock(); @@ -601,4 +617,47 @@ class AppManagerTest extends TestCase { $this->assertEquals([], $this->manager->getAppRestriction('test2')); $this->assertEquals(['foo'], $this->manager->getAppRestriction('test3')); } + + public function provideDefaultApps(): array { + return [ + // none specified, default to files + [ + '', + 'files', + ], + // unexisting or inaccessible app specified, default to files + [ + 'unexist', + 'files', + ], + // non-standard app + [ + 'settings', + 'settings', + ], + // non-standard app with fallback + [ + 'unexist,settings', + 'settings', + ], + ]; + } + + /** + * @dataProvider provideDefaultApps + */ + public function testGetDefaultAppForUser($defaultApps, $expectedApp) { + $user = $this->newUser('user1'); + + $this->userSession->expects($this->once()) + ->method('getUser') + ->willReturn($user); + + $this->config->expects($this->once()) + ->method('getSystemValueString') + ->with('defaultapp', $this->anything()) + ->willReturn($defaultApps); + + $this->assertEquals($expectedApp, $this->manager->getDefaultAppForUser()); + } } diff --git a/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php b/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php index a2d56838b07..39b0a699092 100644 --- a/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php +++ b/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php @@ -1872,7 +1872,7 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== } public function testGetWithFilter() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->willReturnCallback(function ($key, $default) { if ($key === 'version') { return '11.0.0.2'; @@ -1884,8 +1884,7 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== }); $this->config ->method('getSystemValueBool') - ->with('appstoreenabled', true) - ->willReturn(true); + ->willReturnArgument(1); $file = $this->createMock(ISimpleFile::class); $folder = $this->createMock(ISimpleFolder::class); @@ -1957,7 +1956,7 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== public function testAppstoreDisabled() { $this->config - ->method('getSystemValue') + ->method('getSystemValueString') ->willReturnCallback(function ($var, $default) { if ($var === 'version') { return '11.0.0.2'; @@ -1966,8 +1965,14 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== }); $this->config ->method('getSystemValueBool') - ->with('appstoreenabled', true) - ->willReturn(false); + ->willReturnCallback(function ($var, $default) { + if ($var === 'has_internet_connection') { + return true; + } elseif ($var === 'appstoreenabled') { + return false; + } + return $default; + }); $this->appData ->expects($this->never()) ->method('getFolder'); @@ -1978,7 +1983,7 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== public function testNoInternet() { $this->config - ->method('getSystemValue') + ->method('getSystemValueString') ->willReturnCallback(function ($var, $default) { if ($var === 'has_internet_connection') { return false; @@ -1989,8 +1994,14 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== }); $this->config ->method('getSystemValueBool') - ->with('appstoreenabled', true) - ->willReturn(true); + ->willReturnCallback(function ($var, $default) { + if ($var === 'has_internet_connection') { + return false; + } elseif ($var === 'appstoreenabled') { + return true; + } + return $default; + }); $this->appData ->expects($this->never()) ->method('getFolder'); @@ -1999,7 +2010,7 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== } public function testSetVersion() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->willReturnCallback(function ($key, $default) { if ($key === 'version') { return '10.0.7.2'; @@ -2011,8 +2022,7 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== }); $this->config ->method('getSystemValueBool') - ->with('appstoreenabled', true) - ->willReturn(true); + ->willReturnArgument(1); $file = $this->createMock(ISimpleFile::class); $folder = $this->createMock(ISimpleFolder::class); @@ -2084,13 +2094,19 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== } public function testGetAppsAllowlist() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->willReturnCallback(function ($key, $default) { if ($key === 'version') { return '11.0.0.2'; } elseif ($key === 'appstoreurl' && $default === 'https://apps.nextcloud.com/api/v1') { return 'https://custom.appsstore.endpoint/api/v1'; - } elseif ($key === 'appsallowlist') { + } else { + return $default; + } + }); + $this->config->method('getSystemValue') + ->willReturnCallback(function ($key, $default) { + if ($key === 'appsallowlist') { return ['contacts']; } else { return $default; @@ -2098,8 +2114,7 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== }); $this->config ->method('getSystemValueBool') - ->with('appstoreenabled', true) - ->willReturn(true); + ->willReturnArgument(1); $file = $this->createMock(ISimpleFile::class); $folder = $this->createMock(ISimpleFolder::class); diff --git a/tests/lib/App/AppStore/Fetcher/CategoryFetcherTest.php b/tests/lib/App/AppStore/Fetcher/CategoryFetcherTest.php index b83e405db61..874a58fc6ba 100644 --- a/tests/lib/App/AppStore/Fetcher/CategoryFetcherTest.php +++ b/tests/lib/App/AppStore/Fetcher/CategoryFetcherTest.php @@ -41,7 +41,7 @@ class CategoryFetcherTest extends FetcherBase { public function testAppstoreDisabled() { $this->config - ->method('getSystemValue') + ->method('getSystemValueBool') ->willReturnCallback(function ($var, $default) { if ($var === 'appstoreenabled') { return false; @@ -57,7 +57,7 @@ class CategoryFetcherTest extends FetcherBase { public function testNoInternet() { $this->config - ->method('getSystemValue') + ->method('getSystemValueBool') ->willReturnCallback(function ($var, $default) { if ($var === 'has_internet_connection') { return false; diff --git a/tests/lib/App/AppStore/Fetcher/FetcherBase.php b/tests/lib/App/AppStore/Fetcher/FetcherBase.php index 42ad02ce6d8..dbc3f2a687c 100644 --- a/tests/lib/App/AppStore/Fetcher/FetcherBase.php +++ b/tests/lib/App/AppStore/Fetcher/FetcherBase.php @@ -76,20 +76,12 @@ abstract class FetcherBase extends TestCase { public function testGetWithAlreadyExistingFileAndUpToDateTimestampAndVersion() { $this->config - ->expects($this->once()) - ->method('getSystemValueBool') - ->with('appstoreenabled', true) - ->willReturn(true); - $this->config - ->expects($this->exactly(2)) - ->method('getSystemValue') - ->withConsecutive( - ['has_internet_connection', true], - [$this->equalTo('version'), $this->anything()], - )->willReturnOnConsecutiveCalls( - true, - '11.0.0.2', - ); + ->expects($this->exactly(1)) + ->method('getSystemValueString') + ->with($this->equalTo('version'), $this->anything()) + ->willReturn('11.0.0.2'); + $this->config->method('getSystemValueBool') + ->willReturnArgument(1); $folder = $this->createMock(ISimpleFolder::class); $file = $this->createMock(ISimpleFile::class); @@ -122,21 +114,17 @@ abstract class FetcherBase extends TestCase { public function testGetWithNotExistingFileAndUpToDateTimestampAndVersion() { $this->config - ->method('getSystemValue') + ->method('getSystemValueString') ->willReturnCallback(function ($var, $default) { - if ($var === 'has_internet_connection') { - return true; - } elseif ($var === 'appstoreurl') { + if ($var === 'appstoreurl') { return 'https://apps.nextcloud.com/api/v1'; } elseif ($var === 'version') { return '11.0.0.2'; } return $default; }); - $this->config - ->method('getSystemValueBool') - ->with('appstoreenabled', $this->anything()) - ->willReturn(true); + $this->config->method('getSystemValueBool') + ->willReturnArgument(1); $folder = $this->createMock(ISimpleFolder::class); $file = $this->createMock(ISimpleFile::class); @@ -200,7 +188,7 @@ abstract class FetcherBase extends TestCase { } public function testGetWithAlreadyExistingFileAndOutdatedTimestamp() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->willReturnCallback(function ($key, $default) { if ($key === 'version') { return '11.0.0.2'; @@ -208,10 +196,8 @@ abstract class FetcherBase extends TestCase { return $default; } }); - $this->config - ->method('getSystemValueBool') - ->with('appstoreenabled', true) - ->willReturn(true); + $this->config->method('getSystemValueBool') + ->willReturnArgument(1); $folder = $this->createMock(ISimpleFolder::class); $file = $this->createMock(ISimpleFile::class); @@ -277,21 +263,17 @@ abstract class FetcherBase extends TestCase { public function testGetWithAlreadyExistingFileAndNoVersion() { $this->config - ->method('getSystemValue') + ->method('getSystemValueString') ->willReturnCallback(function ($var, $default) { - if ($var === 'has_internet_connection') { - return true; - } elseif ($var === 'appstoreurl') { + if ($var === 'appstoreurl') { return 'https://apps.nextcloud.com/api/v1'; } elseif ($var === 'version') { return '11.0.0.2'; } return $default; }); - $this->config - ->method('getSystemValueBool') - ->with('appstoreenabled', true) - ->willReturn(true); + $this->config->method('getSystemValueBool') + ->willReturnArgument(1); $folder = $this->createMock(ISimpleFolder::class); $file = $this->createMock(ISimpleFile::class); @@ -354,21 +336,17 @@ abstract class FetcherBase extends TestCase { public function testGetWithAlreadyExistingFileAndOutdatedVersion() { $this->config - ->method('getSystemValue') + ->method('getSystemValueString') ->willReturnCallback(function ($var, $default) { - if ($var === 'has_internet_connection') { - return true; - } elseif ($var === 'appstoreurl') { + if ($var === 'appstoreurl') { return 'https://apps.nextcloud.com/api/v1'; } elseif ($var === 'version') { return '11.0.0.2'; } return $default; }); - $this->config - ->method('getSystemValueBool') - ->with('appstoreenabled', true) - ->willReturn(true); + $this->config->method('getSystemValueBool') + ->willReturnArgument(1); $folder = $this->createMock(ISimpleFolder::class); $file = $this->createMock(ISimpleFile::class); @@ -429,14 +407,10 @@ abstract class FetcherBase extends TestCase { } public function testGetWithExceptionInClient() { - $this->config->method('getSystemValue') - ->willReturnCallback(function ($key, $default) { - return $default; - }); - $this->config - ->method('getSystemValueBool') - ->with('appstoreenabled', true) - ->willReturn(true); + $this->config->method('getSystemValueString') + ->willReturnArgument(1); + $this->config->method('getSystemValueBool') + ->willReturnArgument(1); $folder = $this->createMock(ISimpleFolder::class); $file = $this->createMock(ISimpleFile::class); @@ -469,7 +443,7 @@ abstract class FetcherBase extends TestCase { } public function testGetMatchingETag() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->willReturnCallback(function ($key, $default) { if ($key === 'version') { return '11.0.0.2'; @@ -477,10 +451,8 @@ abstract class FetcherBase extends TestCase { return $default; } }); - $this->config - ->method('getSystemValueBool') - ->with('appstoreenabled', true) - ->willReturn(true); + $this->config->method('getSystemValueBool') + ->willReturnArgument(1); $folder = $this->createMock(ISimpleFolder::class); $file = $this->createMock(ISimpleFile::class); @@ -550,7 +522,7 @@ abstract class FetcherBase extends TestCase { } public function testGetNoMatchingETag() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->willReturnCallback(function ($key, $default) { if ($key === 'version') { return '11.0.0.2'; @@ -558,10 +530,8 @@ abstract class FetcherBase extends TestCase { return $default; } }); - $this->config - ->method('getSystemValueBool') - ->with('appstoreenabled', true) - ->willReturn(true); + $this->config->method('getSystemValueBool') + ->willReturnArgument(1); $folder = $this->createMock(ISimpleFolder::class); $file = $this->createMock(ISimpleFile::class); @@ -637,7 +607,7 @@ abstract class FetcherBase extends TestCase { public function testFetchAfterUpgradeNoETag() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->willReturnCallback(function ($key, $default) { if ($key === 'version') { return '11.0.0.3'; @@ -645,10 +615,8 @@ abstract class FetcherBase extends TestCase { return $default; } }); - $this->config - ->method('getSystemValueBool') - ->with('appstoreenabled', true) - ->willReturn(true); + $this->config->method('getSystemValueBool') + ->willReturnArgument(1); $folder = $this->createMock(ISimpleFolder::class); $file = $this->createMock(ISimpleFile::class); diff --git a/tests/lib/AppFramework/Http/RequestTest.php b/tests/lib/AppFramework/Http/RequestTest.php index 78e656f5fc3..839c7ad4338 100644 --- a/tests/lib/AppFramework/Http/RequestTest.php +++ b/tests/lib/AppFramework/Http/RequestTest.php @@ -938,7 +938,7 @@ class RequestTest extends \Test\TestCase { public function testGetServerProtocolWithOverride() { $this->config ->expects($this->exactly(3)) - ->method('getSystemValue') + ->method('getSystemValueString') ->willReturnMap([ ['overwriteprotocol', '', 'customProtocol'], ['overwritecondaddr', '', ''], @@ -1358,7 +1358,7 @@ class RequestTest extends \Test\TestCase { public function testGetServerHostWithOverwriteHost() { $this->config - ->method('getSystemValue') + ->method('getSystemValueString') ->willReturnCallback(function ($key, $default) { if ($key === 'overwritecondaddr') { return ''; @@ -1513,7 +1513,7 @@ class RequestTest extends \Test\TestCase { public function testGetOverwriteHostDefaultNull() { $this->config ->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('overwritehost') ->willReturn(''); $request = new Request( @@ -1530,7 +1530,7 @@ class RequestTest extends \Test\TestCase { public function testGetOverwriteHostWithOverwrite() { $this->config ->expects($this->exactly(3)) - ->method('getSystemValue') + ->method('getSystemValueString') ->willReturnMap([ ['overwritehost', '', 'www.owncloud.org'], ['overwritecondaddr', '', ''], @@ -1717,7 +1717,7 @@ class RequestTest extends \Test\TestCase { public function testGetRequestUriWithoutOverwrite() { $this->config ->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('overwritewebroot') ->willReturn(''); @@ -1749,7 +1749,7 @@ class RequestTest extends \Test\TestCase { public function testGetRequestUriWithOverwrite($expectedUri, $overwriteWebRoot, $overwriteCondAddr) { $this->config ->expects($this->exactly(2)) - ->method('getSystemValue') + ->method('getSystemValueString') ->willReturnMap([ ['overwritewebroot', '', $overwriteWebRoot], ['overwritecondaddr', '', $overwriteCondAddr], diff --git a/tests/lib/AppFramework/Middleware/MiddlewareTest.php b/tests/lib/AppFramework/Middleware/MiddlewareTest.php index f9d8926db7e..f9e775269d4 100644 --- a/tests/lib/AppFramework/Middleware/MiddlewareTest.php +++ b/tests/lib/AppFramework/Middleware/MiddlewareTest.php @@ -70,27 +70,27 @@ class MiddlewareTest extends \Test\TestCase { } - public function testBeforeController() { - $this->middleware->beforeController($this->controller, null); + public function testBeforeController(): void { + $this->middleware->beforeController($this->controller, ''); $this->assertNull(null); } - public function testAfterExceptionRaiseAgainWhenUnhandled() { + public function testAfterExceptionRaiseAgainWhenUnhandled(): void { $this->expectException(\Exception::class); - $this->middleware->afterException($this->controller, null, $this->exception); + $this->middleware->afterException($this->controller, '', $this->exception); } - public function testAfterControllerReturnResponseWhenUnhandled() { - $response = $this->middleware->afterController($this->controller, null, $this->response); + public function testAfterControllerReturnResponseWhenUnhandled(): void { + $response = $this->middleware->afterController($this->controller, '', $this->response); $this->assertEquals($this->response, $response); } - public function testBeforeOutputReturnOutputhenUnhandled() { - $output = $this->middleware->beforeOutput($this->controller, null, 'test'); + public function testBeforeOutputReturnOutputhenUnhandled(): void { + $output = $this->middleware->beforeOutput($this->controller, '', 'test'); $this->assertEquals('test', $output); } diff --git a/tests/lib/AppFramework/Middleware/Security/BruteForceMiddlewareTest.php b/tests/lib/AppFramework/Middleware/Security/BruteForceMiddlewareTest.php index 7dfcfe22261..388b2fbf534 100644 --- a/tests/lib/AppFramework/Middleware/Security/BruteForceMiddlewareTest.php +++ b/tests/lib/AppFramework/Middleware/Security/BruteForceMiddlewareTest.php @@ -1,5 +1,6 @@ <?php /** + * @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com> * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch> * * @license GNU AGPL version 3 or any later version @@ -25,44 +26,60 @@ use OC\AppFramework\Middleware\Security\BruteForceMiddleware; use OC\AppFramework\Utility\ControllerMethodReflector; use OC\Security\Bruteforce\Throttler; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\Attribute\BruteForceProtection; use OCP\AppFramework\Http\Response; use OCP\IRequest; +use Psr\Log\LoggerInterface; use Test\TestCase; +class TestController extends Controller { + /** + * @BruteForceProtection(action=login) + */ + public function testMethodWithAnnotation() { + } + + public function testMethodWithoutAnnotation() { + } + + #[BruteForceProtection(action: 'single')] + public function singleAttribute(): void { + } + + #[BruteForceProtection(action: 'first')] + #[BruteForceProtection(action: 'second')] + public function multipleAttributes(): void { + } +} + class BruteForceMiddlewareTest extends TestCase { - /** @var ControllerMethodReflector|\PHPUnit\Framework\MockObject\MockObject */ + /** @var ControllerMethodReflector */ private $reflector; /** @var Throttler|\PHPUnit\Framework\MockObject\MockObject */ private $throttler; /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ private $request; + /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ + private $logger; private BruteForceMiddleware $bruteForceMiddleware; protected function setUp(): void { parent::setUp(); - $this->reflector = $this->createMock(ControllerMethodReflector::class); + $this->reflector = new ControllerMethodReflector(); $this->throttler = $this->createMock(Throttler::class); $this->request = $this->createMock(IRequest::class); + $this->logger = $this->createMock(LoggerInterface::class); $this->bruteForceMiddleware = new BruteForceMiddleware( $this->reflector, $this->throttler, - $this->request + $this->request, + $this->logger, ); } - public function testBeforeControllerWithAnnotation() { - $this->reflector - ->expects($this->once()) - ->method('hasAnnotation') - ->with('BruteForceProtection') - ->willReturn(true); - $this->reflector - ->expects($this->once()) - ->method('getAnnotationParameter') - ->with('BruteForceProtection', 'action') - ->willReturn('login'); + public function testBeforeControllerWithAnnotation(): void { $this->request ->expects($this->once()) ->method('getRemoteAddress') @@ -72,20 +89,45 @@ class BruteForceMiddlewareTest extends TestCase { ->method('sleepDelayOrThrowOnMax') ->with('127.0.0.1', 'login'); - /** @var Controller|\PHPUnit\Framework\MockObject\MockObject $controller */ - $controller = $this->createMock(Controller::class); - $this->bruteForceMiddleware->beforeController($controller, 'testMethod'); + $controller = new TestController('test', $this->request); + $this->reflector->reflect($controller, 'testMethodWithAnnotation'); + $this->bruteForceMiddleware->beforeController($controller, 'testMethodWithAnnotation'); } - public function testBeforeControllerWithoutAnnotation() { - $this->reflector + public function testBeforeControllerWithSingleAttribute(): void { + $this->request ->expects($this->once()) - ->method('hasAnnotation') - ->with('BruteForceProtection') - ->willReturn(false); - $this->reflector - ->expects($this->never()) - ->method('getAnnotationParameter'); + ->method('getRemoteAddress') + ->willReturn('::1'); + $this->throttler + ->expects($this->once()) + ->method('sleepDelayOrThrowOnMax') + ->with('::1', 'single'); + + $controller = new TestController('test', $this->request); + $this->reflector->reflect($controller, 'singleAttribute'); + $this->bruteForceMiddleware->beforeController($controller, 'singleAttribute'); + } + + public function testBeforeControllerWithMultipleAttributes(): void { + $this->request + ->expects($this->once()) + ->method('getRemoteAddress') + ->willReturn('::1'); + $this->throttler + ->expects($this->exactly(2)) + ->method('sleepDelayOrThrowOnMax') + ->withConsecutive( + ['::1', 'first'], + ['::1', 'second'], + ); + + $controller = new TestController('test', $this->request); + $this->reflector->reflect($controller, 'multipleAttributes'); + $this->bruteForceMiddleware->beforeController($controller, 'multipleAttributes'); + } + + public function testBeforeControllerWithoutAnnotation(): void { $this->request ->expects($this->never()) ->method('getRemoteAddress'); @@ -93,19 +135,14 @@ class BruteForceMiddlewareTest extends TestCase { ->expects($this->never()) ->method('sleepDelayOrThrowOnMax'); - /** @var Controller|\PHPUnit\Framework\MockObject\MockObject $controller */ - $controller = $this->createMock(Controller::class); - $this->bruteForceMiddleware->beforeController($controller, 'testMethod'); + $controller = new TestController('test', $this->request); + $this->reflector->reflect($controller, 'testMethodWithoutAnnotation'); + $this->bruteForceMiddleware->beforeController($controller, 'testMethodWithoutAnnotation'); } - public function testAfterControllerWithAnnotationAndThrottledRequest() { + public function testAfterControllerWithAnnotationAndThrottledRequest(): void { /** @var Response|\PHPUnit\Framework\MockObject\MockObject $response */ $response = $this->createMock(Response::class); - $this->reflector - ->expects($this->once()) - ->method('hasAnnotation') - ->with('BruteForceProtection') - ->willReturn(true); $response ->expects($this->once()) ->method('isThrottled') @@ -114,11 +151,6 @@ class BruteForceMiddlewareTest extends TestCase { ->expects($this->once()) ->method('getThrottleMetadata') ->willReturn([]); - $this->reflector - ->expects($this->once()) - ->method('getAnnotationParameter') - ->with('BruteForceProtection', 'action') - ->willReturn('login'); $this->request ->expects($this->once()) ->method('getRemoteAddress') @@ -132,26 +164,18 @@ class BruteForceMiddlewareTest extends TestCase { ->method('registerAttempt') ->with('login', '127.0.0.1'); - /** @var Controller|\PHPUnit\Framework\MockObject\MockObject $controller */ - $controller = $this->createMock(Controller::class); - $this->bruteForceMiddleware->afterController($controller, 'testMethod', $response); + $controller = new TestController('test', $this->request); + $this->reflector->reflect($controller, 'testMethodWithAnnotation'); + $this->bruteForceMiddleware->afterController($controller, 'testMethodWithAnnotation', $response); } - public function testAfterControllerWithAnnotationAndNotThrottledRequest() { + public function testAfterControllerWithAnnotationAndNotThrottledRequest(): void { /** @var Response|\PHPUnit\Framework\MockObject\MockObject $response */ $response = $this->createMock(Response::class); - $this->reflector - ->expects($this->once()) - ->method('hasAnnotation') - ->with('BruteForceProtection') - ->willReturn(true); $response ->expects($this->once()) ->method('isThrottled') ->willReturn(false); - $this->reflector - ->expects($this->never()) - ->method('getAnnotationParameter'); $this->request ->expects($this->never()) ->method('getRemoteAddress'); @@ -162,20 +186,123 @@ class BruteForceMiddlewareTest extends TestCase { ->expects($this->never()) ->method('registerAttempt'); - /** @var Controller|\PHPUnit\Framework\MockObject\MockObject $controller */ - $controller = $this->createMock(Controller::class); - $this->bruteForceMiddleware->afterController($controller, 'testMethod', $response); + $controller = new TestController('test', $this->request); + $this->reflector->reflect($controller, 'testMethodWithAnnotation'); + $this->bruteForceMiddleware->afterController($controller, 'testMethodWithAnnotation', $response); } - public function testAfterControllerWithoutAnnotation() { - $this->reflector + public function testAfterControllerWithSingleAttribute(): void { + /** @var Response|\PHPUnit\Framework\MockObject\MockObject $response */ + $response = $this->createMock(Response::class); + $response ->expects($this->once()) - ->method('hasAnnotation') - ->with('BruteForceProtection') - ->willReturn(false); - $this->reflector + ->method('isThrottled') + ->willReturn(true); + $response + ->expects($this->once()) + ->method('getThrottleMetadata') + ->willReturn([]); + + $this->request + ->expects($this->once()) + ->method('getRemoteAddress') + ->willReturn('::1'); + $this->throttler + ->expects($this->once()) + ->method('sleepDelay') + ->with('::1', 'single'); + $this->throttler + ->expects($this->once()) + ->method('registerAttempt') + ->with('single', '::1'); + + $controller = new TestController('test', $this->request); + $this->reflector->reflect($controller, 'singleAttribute'); + $this->bruteForceMiddleware->afterController($controller, 'singleAttribute', $response); + } + + public function testAfterControllerWithMultipleAttributesGeneralMatch(): void { + /** @var Response|\PHPUnit\Framework\MockObject\MockObject $response */ + $response = $this->createMock(Response::class); + $response + ->expects($this->once()) + ->method('isThrottled') + ->willReturn(true); + $response + ->expects($this->once()) + ->method('getThrottleMetadata') + ->willReturn([]); + + $this->request + ->expects($this->once()) + ->method('getRemoteAddress') + ->willReturn('::1'); + $this->throttler + ->expects($this->exactly(2)) + ->method('sleepDelay') + ->withConsecutive( + ['::1', 'first'], + ['::1', 'second'], + ); + $this->throttler + ->expects($this->exactly(2)) + ->method('registerAttempt') + ->withConsecutive( + ['first', '::1'], + ['second', '::1'], + ); + + $controller = new TestController('test', $this->request); + $this->reflector->reflect($controller, 'multipleAttributes'); + $this->bruteForceMiddleware->afterController($controller, 'multipleAttributes', $response); + } + + public function testAfterControllerWithMultipleAttributesSpecificMatch(): void { + /** @var Response|\PHPUnit\Framework\MockObject\MockObject $response */ + $response = $this->createMock(Response::class); + $response + ->expects($this->once()) + ->method('isThrottled') + ->willReturn(true); + $response + ->expects($this->once()) + ->method('getThrottleMetadata') + ->willReturn(['action' => 'second']); + + $this->request + ->expects($this->once()) + ->method('getRemoteAddress') + ->willReturn('::1'); + $this->throttler + ->expects($this->once()) + ->method('sleepDelay') + ->with('::1', 'second'); + $this->throttler + ->expects($this->once()) + ->method('registerAttempt') + ->with('second', '::1'); + + $controller = new TestController('test', $this->request); + $this->reflector->reflect($controller, 'multipleAttributes'); + $this->bruteForceMiddleware->afterController($controller, 'multipleAttributes', $response); + } + + public function testAfterControllerWithoutAnnotation(): void { + $this->request ->expects($this->never()) - ->method('getAnnotationParameter'); + ->method('getRemoteAddress'); + $this->throttler + ->expects($this->never()) + ->method('sleepDelay'); + + $controller = new TestController('test', $this->request); + $this->reflector->reflect($controller, 'testMethodWithoutAnnotation'); + /** @var Response|\PHPUnit\Framework\MockObject\MockObject $response */ + $response = $this->createMock(Response::class); + $this->bruteForceMiddleware->afterController($controller, 'testMethodWithoutAnnotation', $response); + } + + public function testAfterControllerWithThrottledResponseButUnhandled(): void { $this->request ->expects($this->never()) ->method('getRemoteAddress'); @@ -183,10 +310,17 @@ class BruteForceMiddlewareTest extends TestCase { ->expects($this->never()) ->method('sleepDelay'); - /** @var Controller|\PHPUnit\Framework\MockObject\MockObject $controller */ - $controller = $this->createMock(Controller::class); + $controller = new TestController('test', $this->request); + $this->reflector->reflect($controller, 'testMethodWithoutAnnotation'); /** @var Response|\PHPUnit\Framework\MockObject\MockObject $response */ $response = $this->createMock(Response::class); - $this->bruteForceMiddleware->afterController($controller, 'testMethod', $response); + $response->method('isThrottled') + ->willReturn(true); + + $this->logger->expects($this->once()) + ->method('debug') + ->with('Response for Test\AppFramework\Middleware\Security\TestController::testMethodWithoutAnnotation got bruteforce throttled but has no annotation nor attribute defined.'); + + $this->bruteForceMiddleware->afterController($controller, 'testMethodWithoutAnnotation', $response); } } diff --git a/tests/lib/AppFramework/Middleware/Security/RateLimitingMiddlewareTest.php b/tests/lib/AppFramework/Middleware/Security/RateLimitingMiddlewareTest.php index 38d01950f6a..47d479b18a1 100644 --- a/tests/lib/AppFramework/Middleware/Security/RateLimitingMiddlewareTest.php +++ b/tests/lib/AppFramework/Middleware/Security/RateLimitingMiddlewareTest.php @@ -1,7 +1,13 @@ <?php + +declare(strict_types=1); + /** + * @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com> * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch> * + * @author Joas Schilling <coding@schilljs.com> + * * @license GNU AGPL version 3 or any later version * * This program is free software: you can redistribute it and/or modify @@ -26,34 +32,59 @@ use OC\AppFramework\Utility\ControllerMethodReflector; use OC\Security\RateLimiting\Exception\RateLimitExceededException; use OC\Security\RateLimiting\Limiter; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\Attribute\AnonRateLimit; +use OCP\AppFramework\Http\Attribute\UserRateLimit; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\IRequest; use OCP\IUser; use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; +class TestRateLimitController extends Controller { + /** + * @UserRateThrottle(limit=20, period=200) + * @AnonRateThrottle(limit=10, period=100) + */ + public function testMethodWithAnnotation() { + } + + /** + * @AnonRateThrottle(limit=10, period=100) + */ + public function testMethodWithAnnotationFallback() { + } + + public function testMethodWithoutAnnotation() { + } + + #[UserRateLimit(limit: 20, period: 200)] + #[AnonRateLimit(limit: 10, period: 100)] + public function testMethodWithAttributes() { + } + + #[AnonRateLimit(limit: 10, period: 100)] + public function testMethodWithAttributesFallback() { + } +} + /** * @group DB */ class RateLimitingMiddlewareTest extends TestCase { - /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ - private $request; - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - private $userSession; - /** @var ControllerMethodReflector|\PHPUnit\Framework\MockObject\MockObject */ - private $reflector; - /** @var Limiter|\PHPUnit\Framework\MockObject\MockObject */ - private $limiter; - /** @var RateLimitingMiddleware */ - private $rateLimitingMiddleware; + private IRequest|MockObject $request; + private IUserSession|MockObject $userSession; + private ControllerMethodReflector $reflector; + private Limiter|MockObject $limiter; + private RateLimitingMiddleware $rateLimitingMiddleware; protected function setUp(): void { parent::setUp(); $this->request = $this->createMock(IRequest::class); $this->userSession = $this->createMock(IUserSession::class); - $this->reflector = $this->createMock(ControllerMethodReflector::class); + $this->reflector = new ControllerMethodReflector(); $this->limiter = $this->createMock(Limiter::class); $this->rateLimitingMiddleware = new RateLimitingMiddleware( @@ -64,23 +95,25 @@ class RateLimitingMiddlewareTest extends TestCase { ); } - public function testBeforeControllerWithoutAnnotation() { - $this->reflector - ->expects($this->exactly(4)) - ->method('getAnnotationParameter') - ->withConsecutive( - ['AnonRateThrottle', 'limit'], - ['AnonRateThrottle', 'period'], - ['UserRateThrottle', 'limit'], - ['UserRateThrottle', 'period'] - ) - ->willReturnMap([ - ['AnonRateThrottle', 'limit', ''], - ['AnonRateThrottle', 'period', ''], - ['UserRateThrottle', 'limit', ''], - ['UserRateThrottle', 'period', ''], - ]); + public function testBeforeControllerWithoutAnnotationForAnon(): void { + $this->limiter + ->expects($this->never()) + ->method('registerUserRequest'); + $this->limiter + ->expects($this->never()) + ->method('registerAnonRequest'); + + $this->userSession->expects($this->once()) + ->method('isLoggedIn') + ->willReturn(false); + + /** @var TestRateLimitController|MockObject $controller */ + $controller = $this->createMock(TestRateLimitController::class); + $this->reflector->reflect($controller, 'testMethodWithoutAnnotation'); + $this->rateLimitingMiddleware->beforeController($controller, 'testMethodWithoutAnnotation'); + } + public function testBeforeControllerWithoutAnnotationForLoggedIn(): void { $this->limiter ->expects($this->never()) ->method('registerUserRequest'); @@ -88,34 +121,79 @@ class RateLimitingMiddlewareTest extends TestCase { ->expects($this->never()) ->method('registerAnonRequest'); - /** @var Controller|\PHPUnit\Framework\MockObject\MockObject $controller */ - $controller = $this->createMock(Controller::class); - $this->rateLimitingMiddleware->beforeController($controller, 'testMethod'); + $this->userSession->expects($this->once()) + ->method('isLoggedIn') + ->willReturn(true); + + /** @var TestRateLimitController|MockObject $controller */ + $controller = $this->createMock(TestRateLimitController::class); + $this->reflector->reflect($controller, 'testMethodWithoutAnnotation'); + $this->rateLimitingMiddleware->beforeController($controller, 'testMethodWithoutAnnotation'); } - public function testBeforeControllerForAnon() { - /** @var Controller|\PHPUnit\Framework\MockObject\MockObject $controller */ - $controller = $this->createMock(Controller::class); + public function testBeforeControllerForAnon(): void { + $controller = new TestRateLimitController('test', $this->request); + + $this->request + ->method('getRemoteAddress') + ->willReturn('127.0.0.1'); + + $this->userSession + ->expects($this->once()) + ->method('isLoggedIn') + ->willReturn(false); + + $this->limiter + ->expects($this->never()) + ->method('registerUserRequest'); + $this->limiter + ->expects($this->once()) + ->method('registerAnonRequest') + ->with(get_class($controller) . '::testMethodWithAnnotation', '10', '100', '127.0.0.1'); + + $this->reflector->reflect($controller, 'testMethodWithAnnotation'); + $this->rateLimitingMiddleware->beforeController($controller, 'testMethodWithAnnotation'); + } + + public function testBeforeControllerForLoggedIn(): void { + $controller = new TestRateLimitController('test', $this->request); + /** @var IUser|MockObject $user */ + $user = $this->createMock(IUser::class); + + $this->userSession + ->expects($this->once()) + ->method('isLoggedIn') + ->willReturn(true); + $this->userSession + ->expects($this->once()) + ->method('getUser') + ->willReturn($user); + + $this->limiter + ->expects($this->never()) + ->method('registerAnonRequest'); + $this->limiter + ->expects($this->once()) + ->method('registerUserRequest') + ->with(get_class($controller) . '::testMethodWithAnnotation', '20', '200', $user); + + + $this->reflector->reflect($controller, 'testMethodWithAnnotation'); + $this->rateLimitingMiddleware->beforeController($controller, 'testMethodWithAnnotation'); + } + + public function testBeforeControllerAnonWithFallback(): void { + $controller = new TestRateLimitController('test', $this->request); $this->request ->expects($this->once()) ->method('getRemoteAddress') ->willReturn('127.0.0.1'); - $this->reflector - ->expects($this->exactly(4)) - ->method('getAnnotationParameter') - ->withConsecutive( - ['AnonRateThrottle', 'limit'], - ['AnonRateThrottle', 'period'], - ['UserRateThrottle', 'limit'], - ['UserRateThrottle', 'period'] - ) - ->willReturnMap([ - ['AnonRateThrottle', 'limit', '100'], - ['AnonRateThrottle', 'period', '10'], - ['UserRateThrottle', 'limit', ''], - ['UserRateThrottle', 'period', ''], - ]); + $this->userSession + ->expects($this->once()) + ->method('isLoggedIn') + ->willReturn(true); + $this->limiter ->expects($this->never()) @@ -123,16 +201,39 @@ class RateLimitingMiddlewareTest extends TestCase { $this->limiter ->expects($this->once()) ->method('registerAnonRequest') - ->with(get_class($controller) . '::testMethod', '100', '10', '127.0.0.1'); + ->with(get_class($controller) . '::testMethodWithAnnotationFallback', '10', '100', '127.0.0.1'); + + $this->reflector->reflect($controller, 'testMethodWithAnnotationFallback'); + $this->rateLimitingMiddleware->beforeController($controller, 'testMethodWithAnnotationFallback'); + } + + public function testBeforeControllerAttributesForAnon(): void { + $controller = new TestRateLimitController('test', $this->request); + + $this->request + ->method('getRemoteAddress') + ->willReturn('127.0.0.1'); + $this->userSession + ->expects($this->once()) + ->method('isLoggedIn') + ->willReturn(false); - $this->rateLimitingMiddleware->beforeController($controller, 'testMethod'); + $this->limiter + ->expects($this->never()) + ->method('registerUserRequest'); + $this->limiter + ->expects($this->once()) + ->method('registerAnonRequest') + ->with(get_class($controller) . '::testMethodWithAttributes', '10', '100', '127.0.0.1'); + + $this->reflector->reflect($controller, 'testMethodWithAttributes'); + $this->rateLimitingMiddleware->beforeController($controller, 'testMethodWithAttributes'); } - public function testBeforeControllerForLoggedIn() { - /** @var Controller|\PHPUnit\Framework\MockObject\MockObject $controller */ - $controller = $this->createMock(Controller::class); - /** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */ + public function testBeforeControllerAttributesForLoggedIn(): void { + $controller = new TestRateLimitController('test', $this->request); + /** @var IUser|MockObject $user */ $user = $this->createMock(IUser::class); $this->userSession @@ -144,37 +245,21 @@ class RateLimitingMiddlewareTest extends TestCase { ->method('getUser') ->willReturn($user); - $this->reflector - ->expects($this->exactly(4)) - ->method('getAnnotationParameter') - ->withConsecutive( - ['AnonRateThrottle', 'limit'], - ['AnonRateThrottle', 'period'], - ['UserRateThrottle', 'limit'], - ['UserRateThrottle', 'period'] - ) - ->willReturnMap([ - ['AnonRateThrottle', 'limit', ''], - ['AnonRateThrottle', 'period', ''], - ['UserRateThrottle', 'limit', '100'], - ['UserRateThrottle', 'period', '10'], - ]); - $this->limiter ->expects($this->never()) ->method('registerAnonRequest'); $this->limiter ->expects($this->once()) ->method('registerUserRequest') - ->with(get_class($controller) . '::testMethod', '100', '10', $user); + ->with(get_class($controller) . '::testMethodWithAttributes', '20', '200', $user); - $this->rateLimitingMiddleware->beforeController($controller, 'testMethod'); + $this->reflector->reflect($controller, 'testMethodWithAttributes'); + $this->rateLimitingMiddleware->beforeController($controller, 'testMethodWithAttributes'); } - public function testBeforeControllerAnonWithFallback() { - /** @var Controller|\PHPUnit\Framework\MockObject\MockObject $controller */ - $controller = $this->createMock(Controller::class); + public function testBeforeControllerAttributesAnonWithFallback(): void { + $controller = new TestRateLimitController('test', $this->request); $this->request ->expects($this->once()) ->method('getRemoteAddress') @@ -183,23 +268,8 @@ class RateLimitingMiddlewareTest extends TestCase { $this->userSession ->expects($this->once()) ->method('isLoggedIn') - ->willReturn(false); + ->willReturn(true); - $this->reflector - ->expects($this->exactly(4)) - ->method('getAnnotationParameter') - ->withConsecutive( - ['AnonRateThrottle', 'limit'], - ['AnonRateThrottle', 'period'], - ['UserRateThrottle', 'limit'], - ['UserRateThrottle', 'period'] - ) - ->willReturnMap([ - ['AnonRateThrottle', 'limit', '200'], - ['AnonRateThrottle', 'period', '20'], - ['UserRateThrottle', 'limit', '100'], - ['UserRateThrottle', 'period', '10'], - ]); $this->limiter ->expects($this->never()) @@ -207,25 +277,23 @@ class RateLimitingMiddlewareTest extends TestCase { $this->limiter ->expects($this->once()) ->method('registerAnonRequest') - ->with(get_class($controller) . '::testMethod', '200', '20', '127.0.0.1'); + ->with(get_class($controller) . '::testMethodWithAttributesFallback', '10', '100', '127.0.0.1'); - $this->rateLimitingMiddleware->beforeController($controller, 'testMethod'); + $this->reflector->reflect($controller, 'testMethodWithAttributesFallback'); + $this->rateLimitingMiddleware->beforeController($controller, 'testMethodWithAttributesFallback'); } - - public function testAfterExceptionWithOtherException() { + public function testAfterExceptionWithOtherException(): void { $this->expectException(\Exception::class); $this->expectExceptionMessage('My test exception'); - /** @var Controller|\PHPUnit\Framework\MockObject\MockObject $controller */ - $controller = $this->createMock(Controller::class); + $controller = new TestRateLimitController('test', $this->request); $this->rateLimitingMiddleware->afterException($controller, 'testMethod', new \Exception('My test exception')); } - public function testAfterExceptionWithJsonBody() { - /** @var Controller|\PHPUnit\Framework\MockObject\MockObject $controller */ - $controller = $this->createMock(Controller::class); + public function testAfterExceptionWithJsonBody(): void { + $controller = new TestRateLimitController('test', $this->request); $this->request ->expects($this->once()) ->method('getHeader') @@ -238,9 +306,8 @@ class RateLimitingMiddlewareTest extends TestCase { $this->assertEquals($expected, $result); } - public function testAfterExceptionWithHtmlBody() { - /** @var Controller|\PHPUnit\Framework\MockObject\MockObject $controller */ - $controller = $this->createMock(Controller::class); + public function testAfterExceptionWithHtmlBody(): void { + $controller = new TestRateLimitController('test', $this->request); $this->request ->expects($this->once()) ->method('getHeader') diff --git a/tests/lib/AppFramework/Utility/TimeFactoryTest.php b/tests/lib/AppFramework/Utility/TimeFactoryTest.php new file mode 100644 index 00000000000..5811a2cf86a --- /dev/null +++ b/tests/lib/AppFramework/Utility/TimeFactoryTest.php @@ -0,0 +1,49 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2022, Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace Test\AppFramework\Utility; + +use OC\AppFramework\Utility\TimeFactory; + +class TimeFactoryTest extends \Test\TestCase { + protected TimeFactory $timeFactory; + + protected function setUp(): void { + $this->timeFactory = new TimeFactory(); + } + + public function testNow(): void { + $now = $this->timeFactory->now(); + self::assertSame('UTC', $now->getTimezone()->getName()); + } + + public function testNowWithTimeZone(): void { + $timezone = new \DateTimeZone('Europe/Berlin'); + $withTimeZone = $this->timeFactory->withTimeZone($timezone); + + $now = $withTimeZone->now(); + self::assertSame('Europe/Berlin', $now->getTimezone()->getName()); + } +} diff --git a/tests/lib/AppTest.php b/tests/lib/AppTest.php index 4b2619a3761..5cdee5e1200 100644 --- a/tests/lib/AppTest.php +++ b/tests/lib/AppTest.php @@ -12,6 +12,7 @@ namespace Test; use OC\App\AppManager; use OC\App\InfoParser; use OC\AppConfig; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IAppConfig; use Psr\Log\LoggerInterface; @@ -553,13 +554,14 @@ class AppTest extends \Test\TestCase { */ private function registerAppConfig(AppConfig $appConfig) { $this->overwriteService(AppConfig::class, $appConfig); - $this->overwriteService(AppManager::class, new \OC\App\AppManager( + $this->overwriteService(AppManager::class, new AppManager( \OC::$server->getUserSession(), \OC::$server->getConfig(), $appConfig, \OC::$server->getGroupManager(), \OC::$server->getMemCacheFactory(), \OC::$server->getEventDispatcher(), + \OC::$server->get(IEventDispatcher::class), \OC::$server->get(LoggerInterface::class) )); } diff --git a/tests/lib/Authentication/Login/FinishRememberedLoginCommandTest.php b/tests/lib/Authentication/Login/FinishRememberedLoginCommandTest.php index d6f18ad9eff..890dd63892a 100644 --- a/tests/lib/Authentication/Login/FinishRememberedLoginCommandTest.php +++ b/tests/lib/Authentication/Login/FinishRememberedLoginCommandTest.php @@ -62,7 +62,7 @@ class FinishRememberedLoginCommandTest extends ALoginCommandTest { public function testProcess() { $data = $this->getLoggedInLoginData(); $this->config->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('auto_logout', false) ->willReturn(false); $this->userSession->expects($this->once()) @@ -77,7 +77,7 @@ class FinishRememberedLoginCommandTest extends ALoginCommandTest { public function testProcessNotRemeberedLoginWithAutologout() { $data = $this->getLoggedInLoginData(); $this->config->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('auto_logout', false) ->willReturn(true); $this->userSession->expects($this->never()) diff --git a/tests/lib/Authentication/Token/ManagerTest.php b/tests/lib/Authentication/Token/ManagerTest.php index 5f024bb1d43..de3e5e1c362 100644 --- a/tests/lib/Authentication/Token/ManagerTest.php +++ b/tests/lib/Authentication/Token/ManagerTest.php @@ -355,4 +355,48 @@ class ManagerTest extends TestCase { $this->manager->updatePasswords('uid', 'pass'); } + + public function testInvalidateTokensOfUserNoClientName() { + $t1 = new PublicKeyToken(); + $t2 = new PublicKeyToken(); + $t1->setId(123); + $t2->setId(456); + + $this->publicKeyTokenProvider + ->expects($this->once()) + ->method('getTokenByUser') + ->with('theUser') + ->willReturn([$t1, $t2]); + $this->publicKeyTokenProvider + ->expects($this->exactly(2)) + ->method('invalidateTokenById') + ->withConsecutive( + ['theUser', 123], + ['theUser', 456], + ); + $this->manager->invalidateTokensOfUser('theUser', null); + } + + public function testInvalidateTokensOfUserClientNameGiven() { + $t1 = new PublicKeyToken(); + $t2 = new PublicKeyToken(); + $t3 = new PublicKeyToken(); + $t1->setId(123); + $t1->setName('Firefox session'); + $t2->setId(456); + $t2->setName('My Client Name'); + $t3->setId(789); + $t3->setName('mobile client'); + + $this->publicKeyTokenProvider + ->expects($this->once()) + ->method('getTokenByUser') + ->with('theUser') + ->willReturn([$t1, $t2, $t3]); + $this->publicKeyTokenProvider + ->expects($this->once()) + ->method('invalidateTokenById') + ->with('theUser', 456); + $this->manager->invalidateTokensOfUser('theUser', 'My Client Name'); + } } diff --git a/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php b/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php index d19f98eeda9..a614780a908 100644 --- a/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php +++ b/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php @@ -67,13 +67,20 @@ class PublicKeyTokenProviderTest extends TestCase { $this->hasher = \OC::$server->getHasher(); $this->crypto = \OC::$server->getCrypto(); $this->config = $this->createMock(IConfig::class); - $this->config->method('getSystemValue') + $this->config->method('getSystemValueInt') ->willReturnMap([ ['session_lifetime', 60 * 60 * 24, 150], ['remember_login_cookie_lifetime', 60 * 60 * 24 * 15, 300], - ['secret', '', '1f4h9s'], + ['token_auth_activity_update', 60, 60], + ]); + $this->config->method('getSystemValue') + ->willReturnMap([ ['openssl', [], []], ]); + $this->config->method('getSystemValueString') + ->willReturnMap([ + ['secret', '', '1f4h9s'], + ]); $this->db = $this->createMock(IDBConnection::class); $this->logger = $this->createMock(LoggerInterface::class); $this->timeFactory = $this->createMock(ITimeFactory::class); @@ -336,7 +343,7 @@ class PublicKeyTokenProviderTest extends TestCase { $defaultSessionLifetime = 60 * 60 * 24; $defaultRememberMeLifetime = 60 * 60 * 24 * 15; $this->config->expects($this->exactly(2)) - ->method('getSystemValue') + ->method('getSystemValueInt') ->willReturnMap([ ['session_lifetime', $defaultSessionLifetime, 150], ['remember_login_cookie_lifetime', $defaultRememberMeLifetime, 300], diff --git a/tests/lib/Collaboration/Collaborators/LookupPluginTest.php b/tests/lib/Collaboration/Collaborators/LookupPluginTest.php index 462497c637b..3eb28a861a5 100644 --- a/tests/lib/Collaboration/Collaborators/LookupPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/LookupPluginTest.php @@ -92,19 +92,19 @@ class LookupPluginTest extends TestCase { ->with('files_sharing', 'lookupServerEnabled', 'yes') ->willReturn('yes'); $this->config->expects($this->exactly(2)) - ->method('getSystemValue') + ->method('getSystemValueBool') ->withConsecutive( ['gs.enabled', false], - ['lookup_server', 'https://lookup.nextcloud.com'], + ['has_internet_connection', true], )->willReturnOnConsecutiveCalls( false, - '', + true, ); $this->config->expects($this->once()) - ->method('getSystemValueBool') - ->with('has_internet_connection', true) - ->willReturn(true); + ->method('getSystemValueString') + ->with('lookup_server', 'https://lookup.nextcloud.com') + ->willReturn(''); $this->clientService->expects($this->never()) ->method('newClient'); @@ -120,15 +120,15 @@ class LookupPluginTest extends TestCase { ->method('getAppValue') ->with('files_sharing', 'lookupServerEnabled', 'yes') ->willReturn('yes'); - $this->config->expects($this->once()) - ->method('getSystemValue') - ->with('gs.enabled', false) - ->willReturn(false); - - $this->config->expects($this->once()) + $this->config->expects($this->exactly(2)) ->method('getSystemValueBool') - ->with('has_internet_connection', true) - ->willReturn(false); + ->withConsecutive( + ['gs.enabled', false], + ['has_internet_connection', true], + )->willReturnOnConsecutiveCalls( + false, + false, + ); $this->clientService->expects($this->never()) ->method('newClient'); @@ -157,19 +157,19 @@ class LookupPluginTest extends TestCase { ->with('files_sharing', 'lookupServerEnabled', 'yes') ->willReturn('yes'); $this->config->expects($this->exactly(2)) - ->method('getSystemValue') + ->method('getSystemValueBool') ->withConsecutive( ['gs.enabled', false], - ['lookup_server', 'https://lookup.nextcloud.com'], + ['has_internet_connection', true], )->willReturnOnConsecutiveCalls( false, - $searchParams['server'], + true, ); $this->config->expects($this->once()) - ->method('getSystemValueBool') - ->with('has_internet_connection', true) - ->willReturn(true); + ->method('getSystemValueString') + ->with('lookup_server', 'https://lookup.nextcloud.com') + ->willReturn($searchParams['server']); $response = $this->createMock(IResponse::class); $response->expects($this->once()) @@ -221,19 +221,19 @@ class LookupPluginTest extends TestCase { ->method('addResultSet') ->with($type, $searchParams['expectedResult'], []); - $this->config->expects($this->once()) - ->method('getSystemValueBool') - ->with('has_internet_connection', true) - ->willReturn(true); $this->config->expects($this->exactly(2)) - ->method('getSystemValue') + ->method('getSystemValueBool') ->withConsecutive( ['gs.enabled', false], - ['lookup_server', 'https://lookup.nextcloud.com'], + ['has_internet_connection', true], )->willReturnOnConsecutiveCalls( $GSEnabled, - $searchParams['server'], + true, ); + $this->config->expects($this->once()) + ->method('getSystemValueString') + ->with('lookup_server', 'https://lookup.nextcloud.com') + ->willReturn($searchParams['server']); $response = $this->createMock(IResponse::class); $response->expects($this->once()) @@ -254,10 +254,15 @@ class LookupPluginTest extends TestCase { ->willReturn($client); } else { $searchResult->expects($this->never())->method('addResultSet'); - $this->config->expects($this->once()) - ->method('getSystemValue') - ->with('gs.enabled', false) - ->willReturn($GSEnabled); + $this->config->expects($this->exactly(2)) + ->method('getSystemValueBool') + ->withConsecutive( + ['gs.enabled', false], + ['has_internet_connection', true], + )->willReturnOnConsecutiveCalls( + $GSEnabled, + true, + ); } $moreResults = $this->plugin->search( $searchParams['search'], diff --git a/tests/lib/Comments/ManagerTest.php b/tests/lib/Comments/ManagerTest.php index 1af460e6f1b..bc1692a5958 100644 --- a/tests/lib/Comments/ManagerTest.php +++ b/tests/lib/Comments/ManagerTest.php @@ -1122,6 +1122,1213 @@ class ManagerTest extends TestCase { ['👍', 'frank'], ], ], + [# 600 reactions to cover chunk size when retrieve comments of reactions. + [ + ['message', 'alice', 'comment', null], + ['😀', 'alice', 'reaction', 'message#alice'], + ['😃', 'alice', 'reaction', 'message#alice'], + ['😄', 'alice', 'reaction', 'message#alice'], + ['😁', 'alice', 'reaction', 'message#alice'], + ['😆', 'alice', 'reaction', 'message#alice'], + ['😅', 'alice', 'reaction', 'message#alice'], + ['😂', 'alice', 'reaction', 'message#alice'], + ['🤣', 'alice', 'reaction', 'message#alice'], + ['🥲', 'alice', 'reaction', 'message#alice'], + ['🥹', 'alice', 'reaction', 'message#alice'], + ['☺️', 'alice', 'reaction', 'message#alice'], + ['😊', 'alice', 'reaction', 'message#alice'], + ['😇', 'alice', 'reaction', 'message#alice'], + ['🙂', 'alice', 'reaction', 'message#alice'], + ['🙃', 'alice', 'reaction', 'message#alice'], + ['😉', 'alice', 'reaction', 'message#alice'], + ['😌', 'alice', 'reaction', 'message#alice'], + ['😍', 'alice', 'reaction', 'message#alice'], + ['🥰', 'alice', 'reaction', 'message#alice'], + ['😘', 'alice', 'reaction', 'message#alice'], + ['😗', 'alice', 'reaction', 'message#alice'], + ['😙', 'alice', 'reaction', 'message#alice'], + ['😚', 'alice', 'reaction', 'message#alice'], + ['😋', 'alice', 'reaction', 'message#alice'], + ['😛', 'alice', 'reaction', 'message#alice'], + ['😝', 'alice', 'reaction', 'message#alice'], + ['😜', 'alice', 'reaction', 'message#alice'], + ['🤪', 'alice', 'reaction', 'message#alice'], + ['🤨', 'alice', 'reaction', 'message#alice'], + ['🧐', 'alice', 'reaction', 'message#alice'], + ['🤓', 'alice', 'reaction', 'message#alice'], + ['😎', 'alice', 'reaction', 'message#alice'], + ['🥸', 'alice', 'reaction', 'message#alice'], + ['🤩', 'alice', 'reaction', 'message#alice'], + ['🥳', 'alice', 'reaction', 'message#alice'], + ['😏', 'alice', 'reaction', 'message#alice'], + ['😒', 'alice', 'reaction', 'message#alice'], + ['😞', 'alice', 'reaction', 'message#alice'], + ['😔', 'alice', 'reaction', 'message#alice'], + ['😟', 'alice', 'reaction', 'message#alice'], + ['😕', 'alice', 'reaction', 'message#alice'], + ['🙁', 'alice', 'reaction', 'message#alice'], + ['☹️', 'alice', 'reaction', 'message#alice'], + ['😣', 'alice', 'reaction', 'message#alice'], + ['😖', 'alice', 'reaction', 'message#alice'], + ['😫', 'alice', 'reaction', 'message#alice'], + ['😩', 'alice', 'reaction', 'message#alice'], + ['🥺', 'alice', 'reaction', 'message#alice'], + ['😢', 'alice', 'reaction', 'message#alice'], + ['😭', 'alice', 'reaction', 'message#alice'], + ['😮💨', 'alice', 'reaction', 'message#alice'], + ['😤', 'alice', 'reaction', 'message#alice'], + ['😠', 'alice', 'reaction', 'message#alice'], + ['😡', 'alice', 'reaction', 'message#alice'], + ['🤬', 'alice', 'reaction', 'message#alice'], + ['🤯', 'alice', 'reaction', 'message#alice'], + ['😳', 'alice', 'reaction', 'message#alice'], + ['🥵', 'alice', 'reaction', 'message#alice'], + ['🥶', 'alice', 'reaction', 'message#alice'], + ['😱', 'alice', 'reaction', 'message#alice'], + ['😨', 'alice', 'reaction', 'message#alice'], + ['😰', 'alice', 'reaction', 'message#alice'], + ['😥', 'alice', 'reaction', 'message#alice'], + ['😓', 'alice', 'reaction', 'message#alice'], + ['🫣', 'alice', 'reaction', 'message#alice'], + ['🤗', 'alice', 'reaction', 'message#alice'], + ['🫡', 'alice', 'reaction', 'message#alice'], + ['🤔', 'alice', 'reaction', 'message#alice'], + ['🫢', 'alice', 'reaction', 'message#alice'], + ['🤭', 'alice', 'reaction', 'message#alice'], + ['🤫', 'alice', 'reaction', 'message#alice'], + ['🤥', 'alice', 'reaction', 'message#alice'], + ['😶', 'alice', 'reaction', 'message#alice'], + ['😶🌫️', 'alice', 'reaction', 'message#alice'], + ['😐', 'alice', 'reaction', 'message#alice'], + ['😑', 'alice', 'reaction', 'message#alice'], + ['😬', 'alice', 'reaction', 'message#alice'], + ['🫠', 'alice', 'reaction', 'message#alice'], + ['🙄', 'alice', 'reaction', 'message#alice'], + ['😯', 'alice', 'reaction', 'message#alice'], + ['😦', 'alice', 'reaction', 'message#alice'], + ['😧', 'alice', 'reaction', 'message#alice'], + ['😮', 'alice', 'reaction', 'message#alice'], + ['😲', 'alice', 'reaction', 'message#alice'], + ['🥱', 'alice', 'reaction', 'message#alice'], + ['😴', 'alice', 'reaction', 'message#alice'], + ['🤤', 'alice', 'reaction', 'message#alice'], + ['😪', 'alice', 'reaction', 'message#alice'], + ['😵', 'alice', 'reaction', 'message#alice'], + ['😵💫', 'alice', 'reaction', 'message#alice'], + ['🫥', 'alice', 'reaction', 'message#alice'], + ['🤐', 'alice', 'reaction', 'message#alice'], + ['🥴', 'alice', 'reaction', 'message#alice'], + ['🤢', 'alice', 'reaction', 'message#alice'], + ['🤮', 'alice', 'reaction', 'message#alice'], + ['🤧', 'alice', 'reaction', 'message#alice'], + ['😷', 'alice', 'reaction', 'message#alice'], + ['🤒', 'alice', 'reaction', 'message#alice'], + ['🤕', 'alice', 'reaction', 'message#alice'], + ['🤑', 'alice', 'reaction', 'message#alice'], + ['🤠', 'alice', 'reaction', 'message#alice'], + ['😈', 'alice', 'reaction', 'message#alice'], + ['👿', 'alice', 'reaction', 'message#alice'], + ['👹', 'alice', 'reaction', 'message#alice'], + ['👺', 'alice', 'reaction', 'message#alice'], + ['🤡', 'alice', 'reaction', 'message#alice'], + ['💩', 'alice', 'reaction', 'message#alice'], + ['👻', 'alice', 'reaction', 'message#alice'], + ['💀', 'alice', 'reaction', 'message#alice'], + ['☠️', 'alice', 'reaction', 'message#alice'], + ['👽', 'alice', 'reaction', 'message#alice'], + ['👾', 'alice', 'reaction', 'message#alice'], + ['🤖', 'alice', 'reaction', 'message#alice'], + ['🎃', 'alice', 'reaction', 'message#alice'], + ['😺', 'alice', 'reaction', 'message#alice'], + ['😸', 'alice', 'reaction', 'message#alice'], + ['😹', 'alice', 'reaction', 'message#alice'], + ['😻', 'alice', 'reaction', 'message#alice'], + ['😼', 'alice', 'reaction', 'message#alice'], + ['😽', 'alice', 'reaction', 'message#alice'], + ['🙀', 'alice', 'reaction', 'message#alice'], + ['😿', 'alice', 'reaction', 'message#alice'], + ['😾', 'alice', 'reaction', 'message#alice'], + ['👶', 'alice', 'reaction', 'message#alice'], + ['👧', 'alice', 'reaction', 'message#alice'], + ['🧒', 'alice', 'reaction', 'message#alice'], + ['👦', 'alice', 'reaction', 'message#alice'], + ['👩', 'alice', 'reaction', 'message#alice'], + ['🧑', 'alice', 'reaction', 'message#alice'], + ['👨', 'alice', 'reaction', 'message#alice'], + ['👩🦱', 'alice', 'reaction', 'message#alice'], + ['🧑🦱', 'alice', 'reaction', 'message#alice'], + ['👨🦱', 'alice', 'reaction', 'message#alice'], + ['👩🦰', 'alice', 'reaction', 'message#alice'], + ['🧑🦰', 'alice', 'reaction', 'message#alice'], + ['👨🦰', 'alice', 'reaction', 'message#alice'], + ['👱♀️', 'alice', 'reaction', 'message#alice'], + ['👱', 'alice', 'reaction', 'message#alice'], + ['👱♂️', 'alice', 'reaction', 'message#alice'], + ['👩🦳', 'alice', 'reaction', 'message#alice'], + ['🧑🦳', 'alice', 'reaction', 'message#alice'], + ['👨🦳', 'alice', 'reaction', 'message#alice'], + ['👩🦲', 'alice', 'reaction', 'message#alice'], + ['🧑🦲', 'alice', 'reaction', 'message#alice'], + ['👨🦲', 'alice', 'reaction', 'message#alice'], + ['🧔♀️', 'alice', 'reaction', 'message#alice'], + ['🧔', 'alice', 'reaction', 'message#alice'], + ['🧔♂️', 'alice', 'reaction', 'message#alice'], + ['👵', 'alice', 'reaction', 'message#alice'], + ['🧓', 'alice', 'reaction', 'message#alice'], + ['👴', 'alice', 'reaction', 'message#alice'], + ['👲', 'alice', 'reaction', 'message#alice'], + ['👳♀️', 'alice', 'reaction', 'message#alice'], + ['👳', 'alice', 'reaction', 'message#alice'], + ['👳♂️', 'alice', 'reaction', 'message#alice'], + ['🧕', 'alice', 'reaction', 'message#alice'], + ['👮♀️', 'alice', 'reaction', 'message#alice'], + ['👮', 'alice', 'reaction', 'message#alice'], + ['👮♂️', 'alice', 'reaction', 'message#alice'], + ['👷♀️', 'alice', 'reaction', 'message#alice'], + ['👷', 'alice', 'reaction', 'message#alice'], + ['👷♂️', 'alice', 'reaction', 'message#alice'], + ['💂♀️', 'alice', 'reaction', 'message#alice'], + ['💂', 'alice', 'reaction', 'message#alice'], + ['💂♂️', 'alice', 'reaction', 'message#alice'], + ['🕵️♀️', 'alice', 'reaction', 'message#alice'], + ['🕵️', 'alice', 'reaction', 'message#alice'], + ['🕵️♂️', 'alice', 'reaction', 'message#alice'], + ['👩⚕️', 'alice', 'reaction', 'message#alice'], + ['🧑⚕️', 'alice', 'reaction', 'message#alice'], + ['👨⚕️', 'alice', 'reaction', 'message#alice'], + ['👩🌾', 'alice', 'reaction', 'message#alice'], + ['🧑🌾', 'alice', 'reaction', 'message#alice'], + ['👨🌾', 'alice', 'reaction', 'message#alice'], + ['👩🍳', 'alice', 'reaction', 'message#alice'], + ['🧑🍳', 'alice', 'reaction', 'message#alice'], + ['👨🍳', 'alice', 'reaction', 'message#alice'], + ['👩🎓', 'alice', 'reaction', 'message#alice'], + ['🧑🎓', 'alice', 'reaction', 'message#alice'], + ['👨🎓', 'alice', 'reaction', 'message#alice'], + ['👩🎤', 'alice', 'reaction', 'message#alice'], + ['🧑🎤', 'alice', 'reaction', 'message#alice'], + ['👨🎤', 'alice', 'reaction', 'message#alice'], + ['👩🏫', 'alice', 'reaction', 'message#alice'], + ['🧑🏫', 'alice', 'reaction', 'message#alice'], + ['👨🏫', 'alice', 'reaction', 'message#alice'], + ['👩🏭', 'alice', 'reaction', 'message#alice'], + ['🧑🏭', 'alice', 'reaction', 'message#alice'], + ['👨🏭', 'alice', 'reaction', 'message#alice'], + ['👩💻', 'alice', 'reaction', 'message#alice'], + ['🧑💻', 'alice', 'reaction', 'message#alice'], + ['👨💻', 'alice', 'reaction', 'message#alice'], + ['👩💼', 'alice', 'reaction', 'message#alice'], + ['🧑💼', 'alice', 'reaction', 'message#alice'], + ['👨💼', 'alice', 'reaction', 'message#alice'], + ['👩🔧', 'alice', 'reaction', 'message#alice'], + ['🧑🔧', 'alice', 'reaction', 'message#alice'], + ['👨🔧', 'alice', 'reaction', 'message#alice'], + ['👩🔬', 'alice', 'reaction', 'message#alice'], + ['🧑🔬', 'alice', 'reaction', 'message#alice'], + ['👨🔬', 'alice', 'reaction', 'message#alice'], + ['👩🎨', 'alice', 'reaction', 'message#alice'], + ['🧑🎨', 'alice', 'reaction', 'message#alice'], + ['👨🎨', 'alice', 'reaction', 'message#alice'], + ['👩🚒', 'alice', 'reaction', 'message#alice'], + ['🧑🚒', 'alice', 'reaction', 'message#alice'], + ['👨🚒', 'alice', 'reaction', 'message#alice'], + ['👩✈️', 'alice', 'reaction', 'message#alice'], + ['🧑✈️', 'alice', 'reaction', 'message#alice'], + ['👨✈️', 'alice', 'reaction', 'message#alice'], + ['👩🚀', 'alice', 'reaction', 'message#alice'], + ['🧑🚀', 'alice', 'reaction', 'message#alice'], + ['👨🚀', 'alice', 'reaction', 'message#alice'], + ['👩⚖️', 'alice', 'reaction', 'message#alice'], + ['🧑⚖️', 'alice', 'reaction', 'message#alice'], + ['👨⚖️', 'alice', 'reaction', 'message#alice'], + ['👰♀️', 'alice', 'reaction', 'message#alice'], + ['👰', 'alice', 'reaction', 'message#alice'], + ['👰♂️', 'alice', 'reaction', 'message#alice'], + ['🤵♀️', 'alice', 'reaction', 'message#alice'], + ['🤵', 'alice', 'reaction', 'message#alice'], + ['🤵♂️', 'alice', 'reaction', 'message#alice'], + ['👸', 'alice', 'reaction', 'message#alice'], + ['🫅', 'alice', 'reaction', 'message#alice'], + ['🤴', 'alice', 'reaction', 'message#alice'], + ['🥷', 'alice', 'reaction', 'message#alice'], + ['🦸♀️', 'alice', 'reaction', 'message#alice'], + ['🦸', 'alice', 'reaction', 'message#alice'], + ['🦸♂️', 'alice', 'reaction', 'message#alice'], + ['🦹♀️', 'alice', 'reaction', 'message#alice'], + ['🦹', 'alice', 'reaction', 'message#alice'], + ['🦹♂️', 'alice', 'reaction', 'message#alice'], + ['🤶', 'alice', 'reaction', 'message#alice'], + ['🧑🎄', 'alice', 'reaction', 'message#alice'], + ['🎅', 'alice', 'reaction', 'message#alice'], + ['🧙♀️', 'alice', 'reaction', 'message#alice'], + ['🧙', 'alice', 'reaction', 'message#alice'], + ['🧙♂️', 'alice', 'reaction', 'message#alice'], + ['🧝♀️', 'alice', 'reaction', 'message#alice'], + ['🧝', 'alice', 'reaction', 'message#alice'], + ['🧝♂️', 'alice', 'reaction', 'message#alice'], + ['🧛♀️', 'alice', 'reaction', 'message#alice'], + ['🧛', 'alice', 'reaction', 'message#alice'], + ['🧛♂️', 'alice', 'reaction', 'message#alice'], + ['🧟♀️', 'alice', 'reaction', 'message#alice'], + ['🧟', 'alice', 'reaction', 'message#alice'], + ['🧟♂️', 'alice', 'reaction', 'message#alice'], + ['🧞♀️', 'alice', 'reaction', 'message#alice'], + ['🧞', 'alice', 'reaction', 'message#alice'], + ['🧞♂️', 'alice', 'reaction', 'message#alice'], + ['🧜♀️', 'alice', 'reaction', 'message#alice'], + ['🧜', 'alice', 'reaction', 'message#alice'], + ['🧜♂️', 'alice', 'reaction', 'message#alice'], + ['🧚♀️', 'alice', 'reaction', 'message#alice'], + ['🧚', 'alice', 'reaction', 'message#alice'], + ['🧚♂️', 'alice', 'reaction', 'message#alice'], + ['🧌', 'alice', 'reaction', 'message#alice'], + ['👼', 'alice', 'reaction', 'message#alice'], + ['🤰', 'alice', 'reaction', 'message#alice'], + ['🫄', 'alice', 'reaction', 'message#alice'], + ['🫃', 'alice', 'reaction', 'message#alice'], + ['🤱', 'alice', 'reaction', 'message#alice'], + ['👩🍼', 'alice', 'reaction', 'message#alice'], + ['🧑🍼', 'alice', 'reaction', 'message#alice'], + ['👨🍼', 'alice', 'reaction', 'message#alice'], + ['🙇♀️', 'alice', 'reaction', 'message#alice'], + ['🙇', 'alice', 'reaction', 'message#alice'], + ['🙇♂️', 'alice', 'reaction', 'message#alice'], + ['💁♀️', 'alice', 'reaction', 'message#alice'], + ['💁', 'alice', 'reaction', 'message#alice'], + ['💁♂️', 'alice', 'reaction', 'message#alice'], + ['🙅♀️', 'alice', 'reaction', 'message#alice'], + ['🙅', 'alice', 'reaction', 'message#alice'], + ['🙅♂️', 'alice', 'reaction', 'message#alice'], + ['🙆♀️', 'alice', 'reaction', 'message#alice'], + ['🙆', 'alice', 'reaction', 'message#alice'], + ['🙆♂️', 'alice', 'reaction', 'message#alice'], + ['🙋♀️', 'alice', 'reaction', 'message#alice'], + ['🙋', 'alice', 'reaction', 'message#alice'], + ['🙋♂️', 'alice', 'reaction', 'message#alice'], + ['🧏♀️', 'alice', 'reaction', 'message#alice'], + ['🧏', 'alice', 'reaction', 'message#alice'], + ['🧏♂️', 'alice', 'reaction', 'message#alice'], + ['🤦♀️', 'alice', 'reaction', 'message#alice'], + ['🤦', 'alice', 'reaction', 'message#alice'], + ['🤦♂️', 'alice', 'reaction', 'message#alice'], + ['🤷♀️', 'alice', 'reaction', 'message#alice'], + ['🤷', 'alice', 'reaction', 'message#alice'], + ['🤷♂️', 'alice', 'reaction', 'message#alice'], + ['🙎♀️', 'alice', 'reaction', 'message#alice'], + ['🙎', 'alice', 'reaction', 'message#alice'], + ['🙎♂️', 'alice', 'reaction', 'message#alice'], + ['🙍♀️', 'alice', 'reaction', 'message#alice'], + ['🙍', 'alice', 'reaction', 'message#alice'], + ['🙍♂️', 'alice', 'reaction', 'message#alice'], + ['💇♀️', 'alice', 'reaction', 'message#alice'], + ['💇', 'alice', 'reaction', 'message#alice'], + ['💇♂️', 'alice', 'reaction', 'message#alice'], + ['💆♀️', 'alice', 'reaction', 'message#alice'], + ['💆', 'alice', 'reaction', 'message#alice'], + ['💆♂️', 'alice', 'reaction', 'message#alice'], + ['🧖♀️', 'alice', 'reaction', 'message#alice'], + ['🧖', 'alice', 'reaction', 'message#alice'], + ['🧖♂️', 'alice', 'reaction', 'message#alice'], + ['💅', 'alice', 'reaction', 'message#alice'], + ['🤳', 'alice', 'reaction', 'message#alice'], + ['💃', 'alice', 'reaction', 'message#alice'], + ['🕺', 'alice', 'reaction', 'message#alice'], + ['👯♀️', 'alice', 'reaction', 'message#alice'], + ['👯', 'alice', 'reaction', 'message#alice'], + ['👯♂️', 'alice', 'reaction', 'message#alice'], + ['🕴', 'alice', 'reaction', 'message#alice'], + ['👩🦽', 'alice', 'reaction', 'message#alice'], + ['🧑🦽', 'alice', 'reaction', 'message#alice'], + ['👨🦽', 'alice', 'reaction', 'message#alice'], + ['👩🦼', 'alice', 'reaction', 'message#alice'], + ['🧑🦼', 'alice', 'reaction', 'message#alice'], + ['👨🦼', 'alice', 'reaction', 'message#alice'], + ['🚶♀️', 'alice', 'reaction', 'message#alice'], + ['🚶', 'alice', 'reaction', 'message#alice'], + ['🚶♂️', 'alice', 'reaction', 'message#alice'], + ['👩🦯', 'alice', 'reaction', 'message#alice'], + ['🧑🦯', 'alice', 'reaction', 'message#alice'], + ['👨🦯', 'alice', 'reaction', 'message#alice'], + ['🧎♀️', 'alice', 'reaction', 'message#alice'], + ['🧎', 'alice', 'reaction', 'message#alice'], + ['🧎♂️', 'alice', 'reaction', 'message#alice'], + ['🏃♀️', 'alice', 'reaction', 'message#alice'], + ['🏃', 'alice', 'reaction', 'message#alice'], + ['🏃♂️', 'alice', 'reaction', 'message#alice'], + ['🧍♀️', 'alice', 'reaction', 'message#alice'], + ['🧍', 'alice', 'reaction', 'message#alice'], + ['🧍♂️', 'alice', 'reaction', 'message#alice'], + ['👭', 'alice', 'reaction', 'message#alice'], + ['🧑🤝🧑', 'alice', 'reaction', 'message#alice'], + ['👬', 'alice', 'reaction', 'message#alice'], + ['👫', 'alice', 'reaction', 'message#alice'], + ['👩❤️👩', 'alice', 'reaction', 'message#alice'], + ['💑', 'alice', 'reaction', 'message#alice'], + ['👨❤️👨', 'alice', 'reaction', 'message#alice'], + ['👩❤️👨', 'alice', 'reaction', 'message#alice'], + ['👩❤️💋👩', 'alice', 'reaction', 'message#alice'], + ['💏', 'alice', 'reaction', 'message#alice'], + ['👨❤️💋👨', 'alice', 'reaction', 'message#alice'], + ['👩❤️💋👨', 'alice', 'reaction', 'message#alice'], + ['👪', 'alice', 'reaction', 'message#alice'], + ['👨👩👦', 'alice', 'reaction', 'message#alice'], + ['👨👩👧', 'alice', 'reaction', 'message#alice'], + ['👨👩👧👦', 'alice', 'reaction', 'message#alice'], + ['👨👩👦👦', 'alice', 'reaction', 'message#alice'], + ['👨👩👧👧', 'alice', 'reaction', 'message#alice'], + ['👨👨👦', 'alice', 'reaction', 'message#alice'], + ['👨👨👧', 'alice', 'reaction', 'message#alice'], + ['👨👨👧👦', 'alice', 'reaction', 'message#alice'], + ['👨👨👦👦', 'alice', 'reaction', 'message#alice'], + ['👨👨👧👧', 'alice', 'reaction', 'message#alice'], + ['👩👩👦', 'alice', 'reaction', 'message#alice'], + ['👩👩👧', 'alice', 'reaction', 'message#alice'], + ['👩👩👧👦', 'alice', 'reaction', 'message#alice'], + ['👩👩👦👦', 'alice', 'reaction', 'message#alice'], + ['👩👩👧👧', 'alice', 'reaction', 'message#alice'], + ['👨👦', 'alice', 'reaction', 'message#alice'], + ['👨👦👦', 'alice', 'reaction', 'message#alice'], + ['👨👧', 'alice', 'reaction', 'message#alice'], + ['👨👧👦', 'alice', 'reaction', 'message#alice'], + ['👨👧👧', 'alice', 'reaction', 'message#alice'], + ['👩👦', 'alice', 'reaction', 'message#alice'], + ['👩👦👦', 'alice', 'reaction', 'message#alice'], + ['👩👧', 'alice', 'reaction', 'message#alice'], + ['👩👧👦', 'alice', 'reaction', 'message#alice'], + ['👩👧👧', 'alice', 'reaction', 'message#alice'], + ['🗣', 'alice', 'reaction', 'message#alice'], + ['👤', 'alice', 'reaction', 'message#alice'], + ['👥', 'alice', 'reaction', 'message#alice'], + ['🫂', 'alice', 'reaction', 'message#alice'], + ['👋🏽', 'alice', 'reaction', 'message#alice'], + ['🤚🏽', 'alice', 'reaction', 'message#alice'], + ['🖐🏽', 'alice', 'reaction', 'message#alice'], + ['✋🏽', 'alice', 'reaction', 'message#alice'], + ['🖖🏽', 'alice', 'reaction', 'message#alice'], + ['👌🏽', 'alice', 'reaction', 'message#alice'], + ['🤌🏽', 'alice', 'reaction', 'message#alice'], + ['🤏🏽', 'alice', 'reaction', 'message#alice'], + ['✌🏽', 'alice', 'reaction', 'message#alice'], + ['🤞🏽', 'alice', 'reaction', 'message#alice'], + ['🫰🏽', 'alice', 'reaction', 'message#alice'], + ['🤟🏽', 'alice', 'reaction', 'message#alice'], + ['🤘🏽', 'alice', 'reaction', 'message#alice'], + ['🤙🏽', 'alice', 'reaction', 'message#alice'], + ['🫵🏽', 'alice', 'reaction', 'message#alice'], + ['🫱🏽', 'alice', 'reaction', 'message#alice'], + ['🫲🏽', 'alice', 'reaction', 'message#alice'], + ['🫳🏽', 'alice', 'reaction', 'message#alice'], + ['🫴🏽', 'alice', 'reaction', 'message#alice'], + ['👈🏽', 'alice', 'reaction', 'message#alice'], + ['👉🏽', 'alice', 'reaction', 'message#alice'], + ['👆🏽', 'alice', 'reaction', 'message#alice'], + ['🖕🏽', 'alice', 'reaction', 'message#alice'], + ['👇🏽', 'alice', 'reaction', 'message#alice'], + ['☝🏽', 'alice', 'reaction', 'message#alice'], + ['👍🏽', 'alice', 'reaction', 'message#alice'], + ['👎🏽', 'alice', 'reaction', 'message#alice'], + ['✊🏽', 'alice', 'reaction', 'message#alice'], + ['👊🏽', 'alice', 'reaction', 'message#alice'], + ['🤛🏽', 'alice', 'reaction', 'message#alice'], + ['🤜🏽', 'alice', 'reaction', 'message#alice'], + ['👏🏽', 'alice', 'reaction', 'message#alice'], + ['🫶🏽', 'alice', 'reaction', 'message#alice'], + ['🙌🏽', 'alice', 'reaction', 'message#alice'], + ['👐🏽', 'alice', 'reaction', 'message#alice'], + ['🤲🏽', 'alice', 'reaction', 'message#alice'], + ['🙏🏽', 'alice', 'reaction', 'message#alice'], + ['✍🏽', 'alice', 'reaction', 'message#alice'], + ['💅🏽', 'alice', 'reaction', 'message#alice'], + ['🤳🏽', 'alice', 'reaction', 'message#alice'], + ['💪🏽', 'alice', 'reaction', 'message#alice'], + ['🦵🏽', 'alice', 'reaction', 'message#alice'], + ['🦶🏽', 'alice', 'reaction', 'message#alice'], + ['👂🏽', 'alice', 'reaction', 'message#alice'], + ['🦻🏽', 'alice', 'reaction', 'message#alice'], + ['👃🏽', 'alice', 'reaction', 'message#alice'], + ['👶🏽', 'alice', 'reaction', 'message#alice'], + ['👧🏽', 'alice', 'reaction', 'message#alice'], + ['🧒🏽', 'alice', 'reaction', 'message#alice'], + ['👦🏽', 'alice', 'reaction', 'message#alice'], + ['👩🏽', 'alice', 'reaction', 'message#alice'], + ['🧑🏽', 'alice', 'reaction', 'message#alice'], + ['👨🏽', 'alice', 'reaction', 'message#alice'], + ['👩🏽🦱', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🦱', 'alice', 'reaction', 'message#alice'], + ['👨🏽🦱', 'alice', 'reaction', 'message#alice'], + ['👩🏽🦰', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🦰', 'alice', 'reaction', 'message#alice'], + ['👨🏽🦰', 'alice', 'reaction', 'message#alice'], + ['👱🏽♀️', 'alice', 'reaction', 'message#alice'], + ['👱🏽', 'alice', 'reaction', 'message#alice'], + ['👱🏽♂️', 'alice', 'reaction', 'message#alice'], + ['👩🏽🦳', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🦳', 'alice', 'reaction', 'message#alice'], + ['👨🏽🦳', 'alice', 'reaction', 'message#alice'], + ['👩🏽🦲', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🦲', 'alice', 'reaction', 'message#alice'], + ['👨🏽🦲', 'alice', 'reaction', 'message#alice'], + ['🧔🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🧔🏽', 'alice', 'reaction', 'message#alice'], + ['🧔🏽♂️', 'alice', 'reaction', 'message#alice'], + ['👵🏽', 'alice', 'reaction', 'message#alice'], + ['🧓🏽', 'alice', 'reaction', 'message#alice'], + ['👴🏽', 'alice', 'reaction', 'message#alice'], + ['👲🏽', 'alice', 'reaction', 'message#alice'], + ['👳🏽♀️', 'alice', 'reaction', 'message#alice'], + ['👳🏽', 'alice', 'reaction', 'message#alice'], + ['👳🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🧕🏽', 'alice', 'reaction', 'message#alice'], + ['👮🏽♀️', 'alice', 'reaction', 'message#alice'], + ['👮🏽', 'alice', 'reaction', 'message#alice'], + ['👮🏽♂️', 'alice', 'reaction', 'message#alice'], + ['👷🏽♀️', 'alice', 'reaction', 'message#alice'], + ['👷🏽', 'alice', 'reaction', 'message#alice'], + ['👷🏽♂️', 'alice', 'reaction', 'message#alice'], + ['💂🏽♀️', 'alice', 'reaction', 'message#alice'], + ['💂🏽', 'alice', 'reaction', 'message#alice'], + ['💂🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🕵🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🕵🏽', 'alice', 'reaction', 'message#alice'], + ['🕵🏽♂️', 'alice', 'reaction', 'message#alice'], + ['👩🏽⚕️', 'alice', 'reaction', 'message#alice'], + ['🧑🏽⚕️', 'alice', 'reaction', 'message#alice'], + ['👨🏽⚕️', 'alice', 'reaction', 'message#alice'], + ['👩🏽🌾', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🌾', 'alice', 'reaction', 'message#alice'], + ['👨🏽🌾', 'alice', 'reaction', 'message#alice'], + ['👩🏽🍳', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🍳', 'alice', 'reaction', 'message#alice'], + ['👨🏽🍳', 'alice', 'reaction', 'message#alice'], + ['👩🏽🎓', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🎓', 'alice', 'reaction', 'message#alice'], + ['👨🏽🎓', 'alice', 'reaction', 'message#alice'], + ['👩🏽🎤', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🎤', 'alice', 'reaction', 'message#alice'], + ['👨🏽🎤', 'alice', 'reaction', 'message#alice'], + ['👩🏽🏫', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🏫', 'alice', 'reaction', 'message#alice'], + ['👨🏽🏫', 'alice', 'reaction', 'message#alice'], + ['👩🏽🏭', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🏭', 'alice', 'reaction', 'message#alice'], + ['👨🏽🏭', 'alice', 'reaction', 'message#alice'], + ['👩🏽💻', 'alice', 'reaction', 'message#alice'], + ['🧑🏽💻', 'alice', 'reaction', 'message#alice'], + ['👨🏽💻', 'alice', 'reaction', 'message#alice'], + ['👩🏽💼', 'alice', 'reaction', 'message#alice'], + ['🧑🏽💼', 'alice', 'reaction', 'message#alice'], + ['👨🏽💼', 'alice', 'reaction', 'message#alice'], + ['👩🏽🔧', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🔧', 'alice', 'reaction', 'message#alice'], + ['👨🏽🔧', 'alice', 'reaction', 'message#alice'], + ['👩🏽🔬', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🔬', 'alice', 'reaction', 'message#alice'], + ['👨🏽🔬', 'alice', 'reaction', 'message#alice'], + ['👩🏽🎨', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🎨', 'alice', 'reaction', 'message#alice'], + ['👨🏽🎨', 'alice', 'reaction', 'message#alice'], + ['👩🏽🚒', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🚒', 'alice', 'reaction', 'message#alice'], + ['👨🏽🚒', 'alice', 'reaction', 'message#alice'], + ['👩🏽✈️', 'alice', 'reaction', 'message#alice'], + ['🧑🏽✈️', 'alice', 'reaction', 'message#alice'], + ['👨🏽✈️', 'alice', 'reaction', 'message#alice'], + ['👩🏽🚀', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🚀', 'alice', 'reaction', 'message#alice'], + ['👨🏽🚀', 'alice', 'reaction', 'message#alice'], + ['👩🏽⚖️', 'alice', 'reaction', 'message#alice'], + ['🧑🏽⚖️', 'alice', 'reaction', 'message#alice'], + ['👨🏽⚖️', 'alice', 'reaction', 'message#alice'], + ['👰🏽♀️', 'alice', 'reaction', 'message#alice'], + ['👰🏽', 'alice', 'reaction', 'message#alice'], + ['👰🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🤵🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🤵🏽', 'alice', 'reaction', 'message#alice'], + ['🤵🏽♂️', 'alice', 'reaction', 'message#alice'], + ['👸🏽', 'alice', 'reaction', 'message#alice'], + ['🫅🏽', 'alice', 'reaction', 'message#alice'], + ['🤴🏽', 'alice', 'reaction', 'message#alice'], + ['🥷🏽', 'alice', 'reaction', 'message#alice'], + ['🦸🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🦸🏽', 'alice', 'reaction', 'message#alice'], + ['🦸🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🦹🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🦹🏽', 'alice', 'reaction', 'message#alice'], + ['🦹🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🤶🏽', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🎄', 'alice', 'reaction', 'message#alice'], + ['🎅🏽', 'alice', 'reaction', 'message#alice'], + ['🧙🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🧙🏽', 'alice', 'reaction', 'message#alice'], + ['🧙🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🧝🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🧝🏽', 'alice', 'reaction', 'message#alice'], + ['🧝🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🧛🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🧛🏽', 'alice', 'reaction', 'message#alice'], + ['🧛🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🧜🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🧜🏽', 'alice', 'reaction', 'message#alice'], + ['🧜🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🧚🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🧚🏽', 'alice', 'reaction', 'message#alice'], + ['🧚🏽♂️', 'alice', 'reaction', 'message#alice'], + ['👼🏽', 'alice', 'reaction', 'message#alice'], + ['🤰🏽', 'alice', 'reaction', 'message#alice'], + ['🫄🏽', 'alice', 'reaction', 'message#alice'], + ['🫃🏽', 'alice', 'reaction', 'message#alice'], + ['🤱🏽', 'alice', 'reaction', 'message#alice'], + ['👩🏽🍼', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🍼', 'alice', 'reaction', 'message#alice'], + ['👨🏽🍼', 'alice', 'reaction', 'message#alice'], + ['🙇🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🙇🏽', 'alice', 'reaction', 'message#alice'], + ['🙇🏽♂️', 'alice', 'reaction', 'message#alice'], + ['💁🏽♀️', 'alice', 'reaction', 'message#alice'], + ['💁🏽', 'alice', 'reaction', 'message#alice'], + ['💁🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🙅🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🙅🏽', 'alice', 'reaction', 'message#alice'], + ['🙅🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🙆🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🙆🏽', 'alice', 'reaction', 'message#alice'], + ['🙆🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🙋🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🙋🏽', 'alice', 'reaction', 'message#alice'], + ['🙋🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🧏🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🧏🏽', 'alice', 'reaction', 'message#alice'], + ['🧏🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🤦🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🤦🏽', 'alice', 'reaction', 'message#alice'], + ['🤦🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🤷🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🤷🏽', 'alice', 'reaction', 'message#alice'], + ['🤷🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🙎🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🙎🏽', 'alice', 'reaction', 'message#alice'], + ['🙎🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🙍🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🙍🏽', 'alice', 'reaction', 'message#alice'], + ['🙍🏽♂️', 'alice', 'reaction', 'message#alice'], + ['💇🏽♀️', 'alice', 'reaction', 'message#alice'], + ['💇🏽', 'alice', 'reaction', 'message#alice'], + ['💇🏽♂️', 'alice', 'reaction', 'message#alice'], + ['💆🏽♀️', 'alice', 'reaction', 'message#alice'], + ['💆🏽', 'alice', 'reaction', 'message#alice'], + ['💆🏽♂️', 'alice', 'reaction', 'message#alice'], + ['🧖🏽♀️', 'alice', 'reaction', 'message#alice'], + ['🧖🏽', 'alice', 'reaction', 'message#alice'], + ['🧖🏽♂️', 'alice', 'reaction', 'message#alice'], + ['💃🏽', 'alice', 'reaction', 'message#alice'], + ['🕺🏽', 'alice', 'reaction', 'message#alice'], + ['🕴🏽', 'alice', 'reaction', 'message#alice'], + ['👩🏽🦽', 'alice', 'reaction', 'message#alice'], + ['🧑🏽🦽', 'alice', 'reaction', 'message#alice'], + ], + [ + ['😀', 'alice'], + ['😃', 'alice'], + ['😄', 'alice'], + ['😁', 'alice'], + ['😆', 'alice'], + ['😅', 'alice'], + ['😂', 'alice'], + ['🤣', 'alice'], + ['🥲', 'alice'], + ['🥹', 'alice'], + ['☺️', 'alice'], + ['😊', 'alice'], + ['😇', 'alice'], + ['🙂', 'alice'], + ['🙃', 'alice'], + ['😉', 'alice'], + ['😌', 'alice'], + ['😍', 'alice'], + ['🥰', 'alice'], + ['😘', 'alice'], + ['😗', 'alice'], + ['😙', 'alice'], + ['😚', 'alice'], + ['😋', 'alice'], + ['😛', 'alice'], + ['😝', 'alice'], + ['😜', 'alice'], + ['🤪', 'alice'], + ['🤨', 'alice'], + ['🧐', 'alice'], + ['🤓', 'alice'], + ['😎', 'alice'], + ['🥸', 'alice'], + ['🤩', 'alice'], + ['🥳', 'alice'], + ['😏', 'alice'], + ['😒', 'alice'], + ['😞', 'alice'], + ['😔', 'alice'], + ['😟', 'alice'], + ['😕', 'alice'], + ['🙁', 'alice'], + ['☹️', 'alice'], + ['😣', 'alice'], + ['😖', 'alice'], + ['😫', 'alice'], + ['😩', 'alice'], + ['🥺', 'alice'], + ['😢', 'alice'], + ['😭', 'alice'], + ['😮💨', 'alice'], + ['😤', 'alice'], + ['😠', 'alice'], + ['😡', 'alice'], + ['🤬', 'alice'], + ['🤯', 'alice'], + ['😳', 'alice'], + ['🥵', 'alice'], + ['🥶', 'alice'], + ['😱', 'alice'], + ['😨', 'alice'], + ['😰', 'alice'], + ['😥', 'alice'], + ['😓', 'alice'], + ['🫣', 'alice'], + ['🤗', 'alice'], + ['🫡', 'alice'], + ['🤔', 'alice'], + ['🫢', 'alice'], + ['🤭', 'alice'], + ['🤫', 'alice'], + ['🤥', 'alice'], + ['😶', 'alice'], + ['😶🌫️', 'alice'], + ['😐', 'alice'], + ['😑', 'alice'], + ['😬', 'alice'], + ['🫠', 'alice'], + ['🙄', 'alice'], + ['😯', 'alice'], + ['😦', 'alice'], + ['😧', 'alice'], + ['😮', 'alice'], + ['😲', 'alice'], + ['🥱', 'alice'], + ['😴', 'alice'], + ['🤤', 'alice'], + ['😪', 'alice'], + ['😵', 'alice'], + ['😵💫', 'alice'], + ['🫥', 'alice'], + ['🤐', 'alice'], + ['🥴', 'alice'], + ['🤢', 'alice'], + ['🤮', 'alice'], + ['🤧', 'alice'], + ['😷', 'alice'], + ['🤒', 'alice'], + ['🤕', 'alice'], + ['🤑', 'alice'], + ['🤠', 'alice'], + ['😈', 'alice'], + ['👿', 'alice'], + ['👹', 'alice'], + ['👺', 'alice'], + ['🤡', 'alice'], + ['💩', 'alice'], + ['👻', 'alice'], + ['💀', 'alice'], + ['☠️', 'alice'], + ['👽', 'alice'], + ['👾', 'alice'], + ['🤖', 'alice'], + ['🎃', 'alice'], + ['😺', 'alice'], + ['😸', 'alice'], + ['😹', 'alice'], + ['😻', 'alice'], + ['😼', 'alice'], + ['😽', 'alice'], + ['🙀', 'alice'], + ['😿', 'alice'], + ['😾', 'alice'], + ['👶', 'alice'], + ['👧', 'alice'], + ['🧒', 'alice'], + ['👦', 'alice'], + ['👩', 'alice'], + ['🧑', 'alice'], + ['👨', 'alice'], + ['👩🦱', 'alice'], + ['🧑🦱', 'alice'], + ['👨🦱', 'alice'], + ['👩🦰', 'alice'], + ['🧑🦰', 'alice'], + ['👨🦰', 'alice'], + ['👱♀️', 'alice'], + ['👱', 'alice'], + ['👱♂️', 'alice'], + ['👩🦳', 'alice'], + ['🧑🦳', 'alice'], + ['👨🦳', 'alice'], + ['👩🦲', 'alice'], + ['🧑🦲', 'alice'], + ['👨🦲', 'alice'], + ['🧔♀️', 'alice'], + ['🧔', 'alice'], + ['🧔♂️', 'alice'], + ['👵', 'alice'], + ['🧓', 'alice'], + ['👴', 'alice'], + ['👲', 'alice'], + ['👳♀️', 'alice'], + ['👳', 'alice'], + ['👳♂️', 'alice'], + ['🧕', 'alice'], + ['👮♀️', 'alice'], + ['👮', 'alice'], + ['👮♂️', 'alice'], + ['👷♀️', 'alice'], + ['👷', 'alice'], + ['👷♂️', 'alice'], + ['💂♀️', 'alice'], + ['💂', 'alice'], + ['💂♂️', 'alice'], + ['🕵️♀️', 'alice'], + ['🕵️', 'alice'], + ['🕵️♂️', 'alice'], + ['👩⚕️', 'alice'], + ['🧑⚕️', 'alice'], + ['👨⚕️', 'alice'], + ['👩🌾', 'alice'], + ['🧑🌾', 'alice'], + ['👨🌾', 'alice'], + ['👩🍳', 'alice'], + ['🧑🍳', 'alice'], + ['👨🍳', 'alice'], + ['👩🎓', 'alice'], + ['🧑🎓', 'alice'], + ['👨🎓', 'alice'], + ['👩🎤', 'alice'], + ['🧑🎤', 'alice'], + ['👨🎤', 'alice'], + ['👩🏫', 'alice'], + ['🧑🏫', 'alice'], + ['👨🏫', 'alice'], + ['👩🏭', 'alice'], + ['🧑🏭', 'alice'], + ['👨🏭', 'alice'], + ['👩💻', 'alice'], + ['🧑💻', 'alice'], + ['👨💻', 'alice'], + ['👩💼', 'alice'], + ['🧑💼', 'alice'], + ['👨💼', 'alice'], + ['👩🔧', 'alice'], + ['🧑🔧', 'alice'], + ['👨🔧', 'alice'], + ['👩🔬', 'alice'], + ['🧑🔬', 'alice'], + ['👨🔬', 'alice'], + ['👩🎨', 'alice'], + ['🧑🎨', 'alice'], + ['👨🎨', 'alice'], + ['👩🚒', 'alice'], + ['🧑🚒', 'alice'], + ['👨🚒', 'alice'], + ['👩✈️', 'alice'], + ['🧑✈️', 'alice'], + ['👨✈️', 'alice'], + ['👩🚀', 'alice'], + ['🧑🚀', 'alice'], + ['👨🚀', 'alice'], + ['👩⚖️', 'alice'], + ['🧑⚖️', 'alice'], + ['👨⚖️', 'alice'], + ['👰♀️', 'alice'], + ['👰', 'alice'], + ['👰♂️', 'alice'], + ['🤵♀️', 'alice'], + ['🤵', 'alice'], + ['🤵♂️', 'alice'], + ['👸', 'alice'], + ['🫅', 'alice'], + ['🤴', 'alice'], + ['🥷', 'alice'], + ['🦸♀️', 'alice'], + ['🦸', 'alice'], + ['🦸♂️', 'alice'], + ['🦹♀️', 'alice'], + ['🦹', 'alice'], + ['🦹♂️', 'alice'], + ['🤶', 'alice'], + ['🧑🎄', 'alice'], + ['🎅', 'alice'], + ['🧙♀️', 'alice'], + ['🧙', 'alice'], + ['🧙♂️', 'alice'], + ['🧝♀️', 'alice'], + ['🧝', 'alice'], + ['🧝♂️', 'alice'], + ['🧛♀️', 'alice'], + ['🧛', 'alice'], + ['🧛♂️', 'alice'], + ['🧟♀️', 'alice'], + ['🧟', 'alice'], + ['🧟♂️', 'alice'], + ['🧞♀️', 'alice'], + ['🧞', 'alice'], + ['🧞♂️', 'alice'], + ['🧜♀️', 'alice'], + ['🧜', 'alice'], + ['🧜♂️', 'alice'], + ['🧚♀️', 'alice'], + ['🧚', 'alice'], + ['🧚♂️', 'alice'], + ['🧌', 'alice'], + ['👼', 'alice'], + ['🤰', 'alice'], + ['🫄', 'alice'], + ['🫃', 'alice'], + ['🤱', 'alice'], + ['👩🍼', 'alice'], + ['🧑🍼', 'alice'], + ['👨🍼', 'alice'], + ['🙇♀️', 'alice'], + ['🙇', 'alice'], + ['🙇♂️', 'alice'], + ['💁♀️', 'alice'], + ['💁', 'alice'], + ['💁♂️', 'alice'], + ['🙅♀️', 'alice'], + ['🙅', 'alice'], + ['🙅♂️', 'alice'], + ['🙆♀️', 'alice'], + ['🙆', 'alice'], + ['🙆♂️', 'alice'], + ['🙋♀️', 'alice'], + ['🙋', 'alice'], + ['🙋♂️', 'alice'], + ['🧏♀️', 'alice'], + ['🧏', 'alice'], + ['🧏♂️', 'alice'], + ['🤦♀️', 'alice'], + ['🤦', 'alice'], + ['🤦♂️', 'alice'], + ['🤷♀️', 'alice'], + ['🤷', 'alice'], + ['🤷♂️', 'alice'], + ['🙎♀️', 'alice'], + ['🙎', 'alice'], + ['🙎♂️', 'alice'], + ['🙍♀️', 'alice'], + ['🙍', 'alice'], + ['🙍♂️', 'alice'], + ['💇♀️', 'alice'], + ['💇', 'alice'], + ['💇♂️', 'alice'], + ['💆♀️', 'alice'], + ['💆', 'alice'], + ['💆♂️', 'alice'], + ['🧖♀️', 'alice'], + ['🧖', 'alice'], + ['🧖♂️', 'alice'], + ['💅', 'alice'], + ['🤳', 'alice'], + ['💃', 'alice'], + ['🕺', 'alice'], + ['👯♀️', 'alice'], + ['👯', 'alice'], + ['👯♂️', 'alice'], + ['🕴', 'alice'], + ['👩🦽', 'alice'], + ['🧑🦽', 'alice'], + ['👨🦽', 'alice'], + ['👩🦼', 'alice'], + ['🧑🦼', 'alice'], + ['👨🦼', 'alice'], + ['🚶♀️', 'alice'], + ['🚶', 'alice'], + ['🚶♂️', 'alice'], + ['👩🦯', 'alice'], + ['🧑🦯', 'alice'], + ['👨🦯', 'alice'], + ['🧎♀️', 'alice'], + ['🧎', 'alice'], + ['🧎♂️', 'alice'], + ['🏃♀️', 'alice'], + ['🏃', 'alice'], + ['🏃♂️', 'alice'], + ['🧍♀️', 'alice'], + ['🧍', 'alice'], + ['🧍♂️', 'alice'], + ['👭', 'alice'], + ['🧑🤝🧑', 'alice'], + ['👬', 'alice'], + ['👫', 'alice'], + ['👩❤️👩', 'alice'], + ['💑', 'alice'], + ['👨❤️👨', 'alice'], + ['👩❤️👨', 'alice'], + ['👩❤️💋👩', 'alice'], + ['💏', 'alice'], + ['👨❤️💋👨', 'alice'], + ['👩❤️💋👨', 'alice'], + ['👪', 'alice'], + ['👨👩👦', 'alice'], + ['👨👩👧', 'alice'], + ['👨👩👧👦', 'alice'], + ['👨👩👦👦', 'alice'], + ['👨👩👧👧', 'alice'], + ['👨👨👦', 'alice'], + ['👨👨👧', 'alice'], + ['👨👨👧👦', 'alice'], + ['👨👨👦👦', 'alice'], + ['👨👨👧👧', 'alice'], + ['👩👩👦', 'alice'], + ['👩👩👧', 'alice'], + ['👩👩👧👦', 'alice'], + ['👩👩👦👦', 'alice'], + ['👩👩👧👧', 'alice'], + ['👨👦', 'alice'], + ['👨👦👦', 'alice'], + ['👨👧', 'alice'], + ['👨👧👦', 'alice'], + ['👨👧👧', 'alice'], + ['👩👦', 'alice'], + ['👩👦👦', 'alice'], + ['👩👧', 'alice'], + ['👩👧👦', 'alice'], + ['👩👧👧', 'alice'], + ['🗣', 'alice'], + ['👤', 'alice'], + ['👥', 'alice'], + ['🫂', 'alice'], + ['👋🏽', 'alice'], + ['🤚🏽', 'alice'], + ['🖐🏽', 'alice'], + ['✋🏽', 'alice'], + ['🖖🏽', 'alice'], + ['👌🏽', 'alice'], + ['🤌🏽', 'alice'], + ['🤏🏽', 'alice'], + ['✌🏽', 'alice'], + ['🤞🏽', 'alice'], + ['🫰🏽', 'alice'], + ['🤟🏽', 'alice'], + ['🤘🏽', 'alice'], + ['🤙🏽', 'alice'], + ['🫵🏽', 'alice'], + ['🫱🏽', 'alice'], + ['🫲🏽', 'alice'], + ['🫳🏽', 'alice'], + ['🫴🏽', 'alice'], + ['👈🏽', 'alice'], + ['👉🏽', 'alice'], + ['👆🏽', 'alice'], + ['🖕🏽', 'alice'], + ['👇🏽', 'alice'], + ['☝🏽', 'alice'], + ['👍🏽', 'alice'], + ['👎🏽', 'alice'], + ['✊🏽', 'alice'], + ['👊🏽', 'alice'], + ['🤛🏽', 'alice'], + ['🤜🏽', 'alice'], + ['👏🏽', 'alice'], + ['🫶🏽', 'alice'], + ['🙌🏽', 'alice'], + ['👐🏽', 'alice'], + ['🤲🏽', 'alice'], + ['🙏🏽', 'alice'], + ['✍🏽', 'alice'], + ['💅🏽', 'alice'], + ['🤳🏽', 'alice'], + ['💪🏽', 'alice'], + ['🦵🏽', 'alice'], + ['🦶🏽', 'alice'], + ['👂🏽', 'alice'], + ['🦻🏽', 'alice'], + ['👃🏽', 'alice'], + ['👶🏽', 'alice'], + ['👧🏽', 'alice'], + ['🧒🏽', 'alice'], + ['👦🏽', 'alice'], + ['👩🏽', 'alice'], + ['🧑🏽', 'alice'], + ['👨🏽', 'alice'], + ['👩🏽🦱', 'alice'], + ['🧑🏽🦱', 'alice'], + ['👨🏽🦱', 'alice'], + ['👩🏽🦰', 'alice'], + ['🧑🏽🦰', 'alice'], + ['👨🏽🦰', 'alice'], + ['👱🏽♀️', 'alice'], + ['👱🏽', 'alice'], + ['👱🏽♂️', 'alice'], + ['👩🏽🦳', 'alice'], + ['🧑🏽🦳', 'alice'], + ['👨🏽🦳', 'alice'], + ['👩🏽🦲', 'alice'], + ['🧑🏽🦲', 'alice'], + ['👨🏽🦲', 'alice'], + ['🧔🏽♀️', 'alice'], + ['🧔🏽', 'alice'], + ['🧔🏽♂️', 'alice'], + ['👵🏽', 'alice'], + ['🧓🏽', 'alice'], + ['👴🏽', 'alice'], + ['👲🏽', 'alice'], + ['👳🏽♀️', 'alice'], + ['👳🏽', 'alice'], + ['👳🏽♂️', 'alice'], + ['🧕🏽', 'alice'], + ['👮🏽♀️', 'alice'], + ['👮🏽', 'alice'], + ['👮🏽♂️', 'alice'], + ['👷🏽♀️', 'alice'], + ['👷🏽', 'alice'], + ['👷🏽♂️', 'alice'], + ['💂🏽♀️', 'alice'], + ['💂🏽', 'alice'], + ['💂🏽♂️', 'alice'], + ['🕵🏽♀️', 'alice'], + ['🕵🏽', 'alice'], + ['🕵🏽♂️', 'alice'], + ['👩🏽⚕️', 'alice'], + ['🧑🏽⚕️', 'alice'], + ['👨🏽⚕️', 'alice'], + ['👩🏽🌾', 'alice'], + ['🧑🏽🌾', 'alice'], + ['👨🏽🌾', 'alice'], + ['👩🏽🍳', 'alice'], + ['🧑🏽🍳', 'alice'], + ['👨🏽🍳', 'alice'], + ['👩🏽🎓', 'alice'], + ['🧑🏽🎓', 'alice'], + ['👨🏽🎓', 'alice'], + ['👩🏽🎤', 'alice'], + ['🧑🏽🎤', 'alice'], + ['👨🏽🎤', 'alice'], + ['👩🏽🏫', 'alice'], + ['🧑🏽🏫', 'alice'], + ['👨🏽🏫', 'alice'], + ['👩🏽🏭', 'alice'], + ['🧑🏽🏭', 'alice'], + ['👨🏽🏭', 'alice'], + ['👩🏽💻', 'alice'], + ['🧑🏽💻', 'alice'], + ['👨🏽💻', 'alice'], + ['👩🏽💼', 'alice'], + ['🧑🏽💼', 'alice'], + ['👨🏽💼', 'alice'], + ['👩🏽🔧', 'alice'], + ['🧑🏽🔧', 'alice'], + ['👨🏽🔧', 'alice'], + ['👩🏽🔬', 'alice'], + ['🧑🏽🔬', 'alice'], + ['👨🏽🔬', 'alice'], + ['👩🏽🎨', 'alice'], + ['🧑🏽🎨', 'alice'], + ['👨🏽🎨', 'alice'], + ['👩🏽🚒', 'alice'], + ['🧑🏽🚒', 'alice'], + ['👨🏽🚒', 'alice'], + ['👩🏽✈️', 'alice'], + ['🧑🏽✈️', 'alice'], + ['👨🏽✈️', 'alice'], + ['👩🏽🚀', 'alice'], + ['🧑🏽🚀', 'alice'], + ['👨🏽🚀', 'alice'], + ['👩🏽⚖️', 'alice'], + ['🧑🏽⚖️', 'alice'], + ['👨🏽⚖️', 'alice'], + ['👰🏽♀️', 'alice'], + ['👰🏽', 'alice'], + ['👰🏽♂️', 'alice'], + ['🤵🏽♀️', 'alice'], + ['🤵🏽', 'alice'], + ['🤵🏽♂️', 'alice'], + ['👸🏽', 'alice'], + ['🫅🏽', 'alice'], + ['🤴🏽', 'alice'], + ['🥷🏽', 'alice'], + ['🦸🏽♀️', 'alice'], + ['🦸🏽', 'alice'], + ['🦸🏽♂️', 'alice'], + ['🦹🏽♀️', 'alice'], + ['🦹🏽', 'alice'], + ['🦹🏽♂️', 'alice'], + ['🤶🏽', 'alice'], + ['🧑🏽🎄', 'alice'], + ['🎅🏽', 'alice'], + ['🧙🏽♀️', 'alice'], + ['🧙🏽', 'alice'], + ['🧙🏽♂️', 'alice'], + ['🧝🏽♀️', 'alice'], + ['🧝🏽', 'alice'], + ['🧝🏽♂️', 'alice'], + ['🧛🏽♀️', 'alice'], + ['🧛🏽', 'alice'], + ['🧛🏽♂️', 'alice'], + ['🧜🏽♀️', 'alice'], + ['🧜🏽', 'alice'], + ['🧜🏽♂️', 'alice'], + ['🧚🏽♀️', 'alice'], + ['🧚🏽', 'alice'], + ['🧚🏽♂️', 'alice'], + ['👼🏽', 'alice'], + ['🤰🏽', 'alice'], + ['🫄🏽', 'alice'], + ['🫃🏽', 'alice'], + ['🤱🏽', 'alice'], + ['👩🏽🍼', 'alice'], + ['🧑🏽🍼', 'alice'], + ['👨🏽🍼', 'alice'], + ['🙇🏽♀️', 'alice'], + ['🙇🏽', 'alice'], + ['🙇🏽♂️', 'alice'], + ['💁🏽♀️', 'alice'], + ['💁🏽', 'alice'], + ['💁🏽♂️', 'alice'], + ['🙅🏽♀️', 'alice'], + ['🙅🏽', 'alice'], + ['🙅🏽♂️', 'alice'], + ['🙆🏽♀️', 'alice'], + ['🙆🏽', 'alice'], + ['🙆🏽♂️', 'alice'], + ['🙋🏽♀️', 'alice'], + ['🙋🏽', 'alice'], + ['🙋🏽♂️', 'alice'], + ['🧏🏽♀️', 'alice'], + ['🧏🏽', 'alice'], + ['🧏🏽♂️', 'alice'], + ['🤦🏽♀️', 'alice'], + ['🤦🏽', 'alice'], + ['🤦🏽♂️', 'alice'], + ['🤷🏽♀️', 'alice'], + ['🤷🏽', 'alice'], + ['🤷🏽♂️', 'alice'], + ['🙎🏽♀️', 'alice'], + ['🙎🏽', 'alice'], + ['🙎🏽♂️', 'alice'], + ['🙍🏽♀️', 'alice'], + ['🙍🏽', 'alice'], + ['🙍🏽♂️', 'alice'], + ['💇🏽♀️', 'alice'], + ['💇🏽', 'alice'], + ['💇🏽♂️', 'alice'], + ['💆🏽♀️', 'alice'], + ['💆🏽', 'alice'], + ['💆🏽♂️', 'alice'], + ['🧖🏽♀️', 'alice'], + ['🧖🏽', 'alice'], + ['🧖🏽♂️', 'alice'], + ['💃🏽', 'alice'], + ['🕺🏽', 'alice'], + ['🕴🏽', 'alice'], + ['👩🏽🦽', 'alice'], + ['🧑🏽🦽', 'alice'], + ], + ], ]; } diff --git a/tests/lib/DB/MigratorTest.php b/tests/lib/DB/MigratorTest.php index af56730f9f6..4d7d9cab19f 100644 --- a/tests/lib/DB/MigratorTest.php +++ b/tests/lib/DB/MigratorTest.php @@ -76,7 +76,7 @@ class MigratorTest extends \Test\TestCase { } private function getUniqueTableName() { - return strtolower($this->getUniqueID($this->config->getSystemValue('dbtableprefix', 'oc_') . 'test_')); + return strtolower($this->getUniqueID($this->config->getSystemValueString('dbtableprefix', 'oc_') . 'test_')); } protected function tearDown(): void { @@ -160,10 +160,10 @@ class MigratorTest extends \Test\TestCase { } public function testUpgradeDifferentPrefix() { - $oldTablePrefix = $this->config->getSystemValue('dbtableprefix', 'oc_'); + $oldTablePrefix = $this->config->getSystemValueString('dbtableprefix', 'oc_'); $this->config->setSystemValue('dbtableprefix', 'ownc_'); - $this->tableName = strtolower($this->getUniqueID($this->config->getSystemValue('dbtableprefix') . 'test_')); + $this->tableName = strtolower($this->getUniqueID($this->config->getSystemValueString('dbtableprefix') . 'test_')); [$startSchema, $endSchema] = $this->getDuplicateKeySchemas(); $migrator = $this->getMigrator(); @@ -237,6 +237,30 @@ class MigratorTest extends \Test\TestCase { $this->addToAssertionCount(1); } + /** + * Test for nextcloud/server#36803 + */ + public function testColumnCommentsInUpdate() { + $startSchema = new Schema([], [], $this->getSchemaConfig()); + $table = $startSchema->createTable($this->tableName); + $table->addColumn('id', 'integer', ['autoincrement' => true, 'comment' => 'foo']); + $table->setPrimaryKey(['id']); + + $endSchema = new Schema([], [], $this->getSchemaConfig()); + $table = $endSchema->createTable($this->tableName); + $table->addColumn('id', 'integer', ['autoincrement' => true, 'comment' => 'foo']); + // Assert adding comments on existing tables work (or at least does not throw) + $table->addColumn('time', 'integer', ['comment' => 'unix-timestamp', 'notnull' => false]); + $table->setPrimaryKey(['id']); + + $migrator = $this->getMigrator(); + $migrator->migrate($startSchema); + + $migrator->migrate($endSchema); + + $this->addToAssertionCount(1); + } + public function testAddingForeignKey() { $startSchema = new Schema([], [], $this->getSchemaConfig()); $table = $startSchema->createTable($this->tableName); diff --git a/tests/lib/Encryption/DecryptAllTest.php b/tests/lib/Encryption/DecryptAllTest.php index f33f88eb214..69f78f435cf 100644 --- a/tests/lib/Encryption/DecryptAllTest.php +++ b/tests/lib/Encryption/DecryptAllTest.php @@ -77,12 +77,15 @@ class DecryptAllTest extends TestCase { ->disableOriginalConstructor()->getMock(); $this->outputInterface = $this->getMockBuilder(OutputInterface::class) ->disableOriginalConstructor()->getMock(); + $this->outputInterface->expects($this->any())->method('isDecorated') + ->willReturn(false); $this->userInterface = $this->getMockBuilder(UserInterface::class) ->disableOriginalConstructor()->getMock(); /* We need format method to return a string */ $outputFormatter = $this->createMock(OutputFormatterInterface::class); $outputFormatter->method('format')->willReturn('foo'); + $outputFormatter->method('isDecorated')->willReturn(false); $this->outputInterface->expects($this->any())->method('getFormatter') ->willReturn($outputFormatter); @@ -304,6 +307,7 @@ class DecryptAllTest extends TestCase { /* We need format method to return a string */ $outputFormatter = $this->createMock(OutputFormatterInterface::class); + $outputFormatter->method('isDecorated')->willReturn(false); $outputFormatter->method('format')->willReturn('foo'); $output = $this->createMock(OutputInterface::class); diff --git a/tests/lib/Encryption/Keys/StorageTest.php b/tests/lib/Encryption/Keys/StorageTest.php index d1c0257cc6e..a47edb3fdd6 100644 --- a/tests/lib/Encryption/Keys/StorageTest.php +++ b/tests/lib/Encryption/Keys/StorageTest.php @@ -77,7 +77,7 @@ class StorageTest extends TestCase { } public function testSetFileKey() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); $this->util->expects($this->any()) @@ -103,7 +103,7 @@ class StorageTest extends TestCase { } public function testSetFileOld() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.0'); $this->util->expects($this->any()) @@ -145,7 +145,7 @@ class StorageTest extends TestCase { * @param string $expectedKeyContent */ public function testGetFileKey($path, $strippedPartialName, $originalKeyExists, $expectedKeyContent) { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); $this->util->expects($this->any()) @@ -201,7 +201,7 @@ class StorageTest extends TestCase { } public function testSetFileKeySystemWide() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); @@ -233,7 +233,7 @@ class StorageTest extends TestCase { } public function testGetFileKeySystemWide() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); @@ -261,7 +261,7 @@ class StorageTest extends TestCase { } public function testSetSystemUserKey() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); @@ -281,7 +281,7 @@ class StorageTest extends TestCase { } public function testSetUserKey() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); @@ -301,7 +301,7 @@ class StorageTest extends TestCase { } public function testGetSystemUserKey() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); @@ -324,7 +324,7 @@ class StorageTest extends TestCase { } public function testGetUserKey() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); diff --git a/tests/lib/Encryption/ManagerTest.php b/tests/lib/Encryption/ManagerTest.php index 79d2c216080..4e354ad518c 100644 --- a/tests/lib/Encryption/ManagerTest.php +++ b/tests/lib/Encryption/ManagerTest.php @@ -66,7 +66,7 @@ class ManagerTest extends TestCase { } public function testManagerIsEnabled() { - $this->config->expects($this->any())->method('getSystemValue')->willReturn(true); + $this->config->expects($this->any())->method('getSystemValueBool')->willReturn(true); $this->config->expects($this->any())->method('getAppValue')->willReturn('yes'); $this->assertTrue($this->manager->isEnabled()); } @@ -199,7 +199,7 @@ class ManagerTest extends TestCase { // */ // public function testModuleRegistration() { // $config = $this->createMock(IConfig::class); -// $config->expects($this->any())->method('getSystemValue')->willReturn(true); +// $config->expects($this->any())->method('getSystemValueBool')->willReturn(true); // $em = $this->createMock(IEncryptionModule::class); // $em->expects($this->any())->method('getId')->willReturn(0); // $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); @@ -211,7 +211,7 @@ class ManagerTest extends TestCase { // // public function testModuleUnRegistration() { // $config = $this->createMock(IConfig::class); -// $config->expects($this->any())->method('getSystemValue')->willReturn(true); +// $config->expects($this->any())->method('getSystemValueBool')->willReturn(true); // $em = $this->createMock(IEncryptionModule::class); // $em->expects($this->any())->method('getId')->willReturn(0); // $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); @@ -228,7 +228,7 @@ class ManagerTest extends TestCase { // */ // public function testGetEncryptionModuleUnknown() { // $config = $this->createMock(IConfig::class); -// $config->expects($this->any())->method('getSystemValue')->willReturn(true); +// $config->expects($this->any())->method('getSystemValueBool')->willReturn(true); // $em = $this->createMock(IEncryptionModule::class); // $em->expects($this->any())->method('getId')->willReturn(0); // $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); @@ -240,7 +240,7 @@ class ManagerTest extends TestCase { // // public function testGetEncryptionModule() { // $config = $this->createMock(IConfig::class); -// $config->expects($this->any())->method('getSystemValue')->willReturn(true); +// $config->expects($this->any())->method('getSystemValueBool')->willReturn(true); // $em = $this->createMock(IEncryptionModule::class); // $em->expects($this->any())->method('getId')->willReturn(0); // $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); diff --git a/tests/lib/FileChunkingTest.php b/tests/lib/FileChunkingTest.php new file mode 100644 index 00000000000..23f50a5b6f7 --- /dev/null +++ b/tests/lib/FileChunkingTest.php @@ -0,0 +1,72 @@ +<?php +/** + * @author Roeland Jago Douma <rullzer@owncloud.com> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace Test; + +use OCP\ICache; + +class FileChunkingTest extends \Test\TestCase { + public function dataIsComplete() { + return [ + [1, [], false], + [1, [0], true], + [2, [], false], + [2, [0], false], + [2, [1], false], + [2, [0,1], true], + [10, [], false], + [10, [0,1,2,3,4,5,6,7,8], false], + [10, [1,2,3,4,5,6,7,8,9], false], + [10, [0,1,2,3,5,6,7,8,9], false], + [10, [0,1,2,3,4,5,6,7,8,9], true], + ]; + } + + /** + * @dataProvider dataIsComplete + * @param $total + * @param array $present + * @param $expected + */ + public function testIsComplete($total, array $present, $expected) { + $fileChunking = $this->getMockBuilder(\OC_FileChunking::class) + ->setMethods(['getCache']) + ->setConstructorArgs([[ + 'name' => 'file', + 'transferid' => '42', + 'chunkcount' => $total, + ]]) + ->getMock(); + + $cache = $this->createMock(ICache::class); + + $cache->expects($this->atLeastOnce()) + ->method('hasKey') + ->willReturnCallback(function ($key) use ($present) { + $data = explode('-', $key); + return in_array($data[3], $present); + }); + + $fileChunking->method('getCache')->willReturn($cache); + + $this->assertEquals($expected, $fileChunking->isComplete()); + } +} diff --git a/tests/lib/Files/EtagTest.php b/tests/lib/Files/EtagTest.php index 43b92c12391..b9583a6ac7c 100644 --- a/tests/lib/Files/EtagTest.php +++ b/tests/lib/Files/EtagTest.php @@ -41,7 +41,7 @@ class EtagTest extends \Test\TestCase { \OC\Share\Share::registerBackend('folder', 'OCA\Files_Sharing\ShareBackend\Folder', 'file'); $config = \OC::$server->getConfig(); - $this->datadir = $config->getSystemValue('datadirectory'); + $this->datadir = $config->getSystemValueString('datadirectory'); $this->tmpDir = \OC::$server->getTempManager()->getTemporaryFolder(); $config->setSystemValue('datadirectory', $this->tmpDir); diff --git a/tests/lib/Files/FilesystemTest.php b/tests/lib/Files/FilesystemTest.php index 8f34860d85a..96fcab77474 100644 --- a/tests/lib/Files/FilesystemTest.php +++ b/tests/lib/Files/FilesystemTest.php @@ -347,7 +347,7 @@ class FilesystemTest extends \Test\TestCase { \OC\Files\Filesystem::initMountPoints($userId); } - + public function testNullUserThrows() { $this->expectException(\OC\User\NoUserException::class); @@ -427,7 +427,7 @@ class FilesystemTest extends \Test\TestCase { public function testMountDefaultCacheDir() { $userId = $this->getUniqueID('user_'); $config = \OC::$server->getConfig(); - $oldCachePath = $config->getSystemValue('cache_path', ''); + $oldCachePath = $config->getSystemValueString('cache_path', ''); // no cache path configured $config->setSystemValue('cache_path', ''); @@ -457,7 +457,7 @@ class FilesystemTest extends \Test\TestCase { $userId = $this->getUniqueID('user_'); $config = \OC::$server->getConfig(); - $oldCachePath = $config->getSystemValue('cache_path', ''); + $oldCachePath = $config->getSystemValueString('cache_path', ''); // set cache path to temp dir $cachePath = \OC::$server->getTempManager()->getTemporaryFolder() . '/extcache'; $config->setSystemValue('cache_path', $cachePath); diff --git a/tests/lib/Files/Node/FileTest.php b/tests/lib/Files/Node/FileTest.php index 3305f9ac170..218e2531727 100644 --- a/tests/lib/Files/Node/FileTest.php +++ b/tests/lib/Files/Node/FileTest.php @@ -185,7 +185,7 @@ class FileTest extends NodeTest { $root = new \OC\Files\Node\Root( $this->manager, - new $this->view, + $this->view, $this->user, $this->userMountCache, $this->logger, @@ -277,7 +277,7 @@ class FileTest extends NodeTest { $root = new \OC\Files\Node\Root( $this->manager, - new $this->view, + $this->view, $this->user, $this->userMountCache, $this->logger, diff --git a/tests/lib/Files/Node/FolderTest.php b/tests/lib/Files/Node/FolderTest.php index 8a604af3846..d745a05ba17 100644 --- a/tests/lib/Files/Node/FolderTest.php +++ b/tests/lib/Files/Node/FolderTest.php @@ -23,7 +23,6 @@ use OC\Files\Search\SearchOrder; use OC\Files\Search\SearchQuery; use OC\Files\Storage\Temporary; use OC\Files\Storage\Wrapper\Jail; -use OC\Files\View; use OCP\Files\Cache\ICacheEntry; use OCP\Files\Mount\IMountPoint; use OCP\Files\NotFoundException; @@ -40,6 +39,9 @@ use OCP\Files\Storage; */ class FolderTest extends NodeTest { protected function createTestNode($root, $view, $path, array $data = [], $internalPath = '', $storage = null) { + $view->expects($this->any()) + ->method('getRoot') + ->willReturn(''); if ($data || $internalPath || $storage) { return new Folder($root, $view, $path, $this->getFileInfo($data, $internalPath, $storage)); } else { @@ -64,25 +66,26 @@ class FolderTest extends NodeTest { /** * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view */ - $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) + ->setConstructorArgs([$manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->expects($this->any()) ->method('getUser') ->willReturn($this->user); - $view->expects($this->any()) + $this->view->expects($this->any()) ->method('getDirectoryContent') ->with('/bar/foo') ->willReturn([ new FileInfo('/bar/foo/asd', null, 'foo/asd', ['fileid' => 2, 'path' => '/bar/foo/asd', 'name' => 'asd', 'size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain'], null), new FileInfo('/bar/foo/qwerty', null, 'foo/qwerty', ['fileid' => 3, 'path' => '/bar/foo/qwerty', 'name' => 'qwerty', 'size' => 200, 'mtime' => 55, 'mimetype' => 'httpd/unix-directory'], null), ]); - $view->method('getFileInfo') + $this->view->method('getFileInfo') ->willReturn($this->createMock(FileInfo::class)); + $this->view->method('getRelativePath') + ->willReturn('/bar/foo'); - $node = new Folder($root, $view, '/bar/foo'); + $node = new Folder($root, $this->view, '/bar/foo'); $children = $node->getDirectoryListing(); $this->assertEquals(2, count($children)); $this->assertInstanceOf('\OC\Files\Node\File', $children[0]); @@ -95,10 +98,7 @@ class FolderTest extends NodeTest { public function testGet() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); @@ -117,10 +117,7 @@ class FolderTest extends NodeTest { public function testNodeExists() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); @@ -140,10 +137,7 @@ class FolderTest extends NodeTest { public function testNodeExistsNotExists() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); @@ -161,10 +155,7 @@ class FolderTest extends NodeTest { public function testNewFolder() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); @@ -188,10 +179,7 @@ class FolderTest extends NodeTest { public function testNewFolderDeepParent() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); @@ -218,10 +206,7 @@ class FolderTest extends NodeTest { $this->expectException(\OCP\Files\NotPermittedException::class); $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); @@ -238,10 +223,7 @@ class FolderTest extends NodeTest { public function testNewFile() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); @@ -268,10 +250,7 @@ class FolderTest extends NodeTest { $this->expectException(\OCP\Files\NotPermittedException::class); $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); @@ -288,10 +267,7 @@ class FolderTest extends NodeTest { public function testGetFreeSpace() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); @@ -308,10 +284,7 @@ class FolderTest extends NodeTest { public function testSearch() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); @@ -351,10 +324,7 @@ class FolderTest extends NodeTest { public function testSearchInRoot() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setMethods(['getUser', 'getMountsIn', 'getMount']) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) @@ -395,10 +365,7 @@ class FolderTest extends NodeTest { public function testSearchInStorageRoot() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); @@ -438,10 +405,7 @@ class FolderTest extends NodeTest { public function testSearchSubStorages() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); @@ -498,21 +462,18 @@ class FolderTest extends NodeTest { } public function testIsSubNode() { - $file = new Node(null, null, '/foo/bar'); - $folder = new Folder(null, null, '/foo'); + $file = new Node(null, $this->view, '/foo/bar'); + $folder = new Folder(null, $this->view, '/foo'); $this->assertTrue($folder->isSubNode($file)); $this->assertFalse($folder->isSubNode($folder)); - $file = new Node(null, null, '/foobar'); + $file = new Node(null, $this->view, '/foobar'); $this->assertFalse($folder->isSubNode($file)); } public function testGetById() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setMethods(['getMountsIn', 'getMount']) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) @@ -559,10 +520,7 @@ class FolderTest extends NodeTest { public function testGetByIdMountRoot() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setMethods(['getMountsIn', 'getMount']) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) @@ -605,10 +563,7 @@ class FolderTest extends NodeTest { public function testGetByIdOutsideFolder() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setMethods(['getMountsIn', 'getMount']) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) @@ -650,10 +605,7 @@ class FolderTest extends NodeTest { public function testGetByIdMultipleStorages() { $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setMethods(['getMountsIn', 'getMount']) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) @@ -715,10 +667,7 @@ class FolderTest extends NodeTest { public function testGetUniqueName($name, $existingFiles, $expected) { $manager = $this->createMock(Manager::class); $folderPath = '/bar/foo'; - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setMethods(['getUser', 'getMountsIn', 'getMount']) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) @@ -742,10 +691,7 @@ class FolderTest extends NodeTest { public function testRecent(): void { $manager = $this->createMock(Manager::class); $folderPath = '/bar/foo'; - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\Node\Root $root */ $root = $this->getMockBuilder(Root::class) ->setMethods(['getUser', 'getMountsIn', 'getMount']) @@ -810,10 +756,7 @@ class FolderTest extends NodeTest { public function testRecentFolder() { $manager = $this->createMock(Manager::class); $folderPath = '/bar/foo'; - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\Node\Root $root */ $root = $this->getMockBuilder(Root::class) ->setMethods(['getUser', 'getMountsIn', 'getMount']) @@ -877,10 +820,7 @@ class FolderTest extends NodeTest { public function testRecentJail() { $manager = $this->createMock(Manager::class); $folderPath = '/bar/foo'; - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\Node\Root $root */ $root = $this->getMockBuilder(Root::class) ->setMethods(['getUser', 'getMountsIn', 'getMount']) @@ -966,10 +906,7 @@ class FolderTest extends NodeTest { } $manager = $this->createMock(Manager::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->createMock(View::class); + $view = $this->getRootViewMock(); $root = $this->getMockBuilder(Root::class) ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); diff --git a/tests/lib/Files/Node/NodeTest.php b/tests/lib/Files/Node/NodeTest.php index 8c0d4cdb293..b63d287a191 100644 --- a/tests/lib/Files/Node/NodeTest.php +++ b/tests/lib/Files/Node/NodeTest.php @@ -54,6 +54,9 @@ abstract class NodeTest extends \Test\TestCase { $this->view = $this->getMockBuilder(View::class) ->disableOriginalConstructor() ->getMock(); + $this->view->expects($this->any()) + ->method('getRoot') + ->willReturn(''); $this->userMountCache = $this->getMockBuilder('\OCP\Files\Config\IUserMountCache') ->disableOriginalConstructor() ->getMock(); @@ -66,6 +69,17 @@ abstract class NodeTest extends \Test\TestCase { } /** + * @return \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view + */ + protected function getRootViewMock() { + $view = $this->createMock(View::class); + $view->expects($this->any()) + ->method('getRoot') + ->willReturn(''); + return $view; + } + + /** * @param IRootFolder $root * @param View $view * @param string $path diff --git a/tests/lib/Files/Node/RootTest.php b/tests/lib/Files/Node/RootTest.php index 5d8e2a4ac62..aab658c3c36 100644 --- a/tests/lib/Files/Node/RootTest.php +++ b/tests/lib/Files/Node/RootTest.php @@ -52,6 +52,17 @@ class RootTest extends \Test\TestCase { $this->eventDispatcher = $this->createMock(IEventDispatcher::class); } + /** + * @return \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view + */ + protected function getRootViewMock() { + $view = $this->createMock(View::class); + $view->expects($this->any()) + ->method('getRoot') + ->willReturn(''); + return $view; + } + protected function getFileInfo($data) { return new FileInfo('', null, '', $data, null); } @@ -63,12 +74,7 @@ class RootTest extends \Test\TestCase { $storage = $this->getMockBuilder('\OC\Files\Storage\Storage') ->disableOriginalConstructor() ->getMock(); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->getMockBuilder(View::class) - ->disableOriginalConstructor() - ->getMock(); + $view = $this->getRootViewMock(); $root = new \OC\Files\Node\Root( $this->manager, $view, @@ -100,12 +106,7 @@ class RootTest extends \Test\TestCase { $storage = $this->getMockBuilder('\OC\Files\Storage\Storage') ->disableOriginalConstructor() ->getMock(); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->getMockBuilder(View::class) - ->disableOriginalConstructor() - ->getMock(); + $view = $this->getRootViewMock(); $root = new \OC\Files\Node\Root( $this->manager, $view, @@ -129,12 +130,7 @@ class RootTest extends \Test\TestCase { public function testGetInvalidPath() { $this->expectException(\OCP\Files\NotPermittedException::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->getMockBuilder(View::class) - ->disableOriginalConstructor() - ->getMock(); + $view = $this->getRootViewMock(); $root = new \OC\Files\Node\Root( $this->manager, $view, @@ -152,12 +148,7 @@ class RootTest extends \Test\TestCase { public function testGetNoStorages() { $this->expectException(\OCP\Files\NotFoundException::class); - /** - * @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view - */ - $view = $this->getMockBuilder(View::class) - ->disableOriginalConstructor() - ->getMock(); + $view = $this->getRootViewMock(); $root = new \OC\Files\Node\Root( $this->manager, $view, @@ -174,7 +165,7 @@ class RootTest extends \Test\TestCase { public function testGetUserFolder() { $root = new \OC\Files\Node\Root( $this->manager, - $this->createMock(View::class), + $this->getRootViewMock(), $this->user, $this->userMountCache, $this->logger, @@ -215,7 +206,7 @@ class RootTest extends \Test\TestCase { $root = new \OC\Files\Node\Root( $this->createMock(Manager::class), - $this->createMock(View::class), + $this->getRootViewMock(), null, $this->userMountCache, $this->logger, diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php index 7a449c4893b..18a6fca05b0 100644 --- a/tests/lib/Files/ViewTest.php +++ b/tests/lib/Files/ViewTest.php @@ -1096,7 +1096,6 @@ class ViewTest extends \Test\TestCase { ['getMountPoint'], ['resolvePath'], ['getLocalFile'], - ['getLocalFolder'], ['mkdir'], ['rmdir'], ['opendir'], @@ -1296,7 +1295,7 @@ class ViewTest extends \Test\TestCase { public function testNullAsRoot() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(\TypeError::class); new View(null); } diff --git a/tests/lib/GlobalScale/ConfigTest.php b/tests/lib/GlobalScale/ConfigTest.php index e67cb392d64..826a57a2b30 100644 --- a/tests/lib/GlobalScale/ConfigTest.php +++ b/tests/lib/GlobalScale/ConfigTest.php @@ -52,7 +52,7 @@ class ConfigTest extends TestCase { public function testIsGlobalScaleEnabled() { $gsConfig = $this->getInstance(); - $this->config->expects($this->once())->method('getSystemValue') + $this->config->expects($this->once())->method('getSystemValueBool') ->with('gs.enabled', false)->willReturn(true); $result = $gsConfig->isGlobalScaleEnabled(); @@ -73,7 +73,7 @@ class ConfigTest extends TestCase { $gsConfig->expects($this->any())->method('isGlobalScaleEnabled')->willReturn($gsEnabled); - $this->config->expects($this->any())->method('getSystemValue') + $this->config->expects($this->any())->method('getSystemValueString') ->with('gs.federation', 'internal')->willReturn($gsFederation); $this->assertSame($expected, $gsConfig->onlyInternalFederation()); diff --git a/tests/lib/Http/Client/ClientTest.php b/tests/lib/Http/Client/ClientTest.php index 93948a5daf3..9a4fb1c657e 100644 --- a/tests/lib/Http/Client/ClientTest.php +++ b/tests/lib/Http/Client/ClientTest.php @@ -54,22 +54,25 @@ class ClientTest extends \Test\TestCase { public function testGetProxyUri(): void { $this->config - ->method('getSystemValue') - ->with('proxy', null) - ->willReturn(null); + ->method('getSystemValueString') + ->with('proxy', '') + ->willReturn(''); $this->assertNull(self::invokePrivate($this->client, 'getProxyUri')); } public function testGetProxyUriProxyHostEmptyPassword(): void { - $map = [ - ['proxy', '', 'foo'], - ['proxyuserpwd', '', null], - ['proxyexclude', [], []], - ]; - $this->config ->method('getSystemValue') - ->will($this->returnValueMap($map)); + ->will($this->returnValueMap([ + ['proxyexclude', [], []], + ])); + + $this->config + ->method('getSystemValueString') + ->will($this->returnValueMap([ + ['proxy', '', 'foo'], + ['proxyuserpwd', '', ''], + ])); $this->assertEquals([ 'http' => 'foo', @@ -79,32 +82,20 @@ class ClientTest extends \Test\TestCase { public function testGetProxyUriProxyHostWithPassword(): void { $this->config - ->expects($this->exactly(3)) + ->expects($this->once()) ->method('getSystemValue') + ->with('proxyexclude', []) + ->willReturn([]); + $this->config + ->expects($this->exactly(2)) + ->method('getSystemValueString') ->withConsecutive( - [ - $this->equalTo('proxy'), - $this->callback(function ($input) { - return $input === ''; - }) - ], - [ - $this->equalTo('proxyuserpwd'), - $this->callback(function ($input) { - return $input === ''; - }) - ], - [ - $this->equalTo('proxyexclude'), - $this->callback(function ($input) { - return $input === []; - }) - ], + ['proxy', ''], + ['proxyuserpwd', ''], ) ->willReturnOnConsecutiveCalls( 'foo', 'username:password', - [], ); $this->assertEquals([ 'http' => 'username:password@foo', @@ -114,32 +105,20 @@ class ClientTest extends \Test\TestCase { public function testGetProxyUriProxyHostWithPasswordAndExclude(): void { $this->config - ->expects($this->exactly(3)) + ->expects($this->once()) ->method('getSystemValue') + ->with('proxyexclude', []) + ->willReturn(['bar']); + $this->config + ->expects($this->exactly(2)) + ->method('getSystemValueString') ->withConsecutive( - [ - $this->equalTo('proxy'), - $this->callback(function ($input) { - return $input === ''; - }) - ], - [ - $this->equalTo('proxyuserpwd'), - $this->callback(function ($input) { - return $input === ''; - }) - ], - [ - $this->equalTo('proxyexclude'), - $this->callback(function ($input) { - return $input === []; - }) - ], + ['proxy', ''], + ['proxyuserpwd', ''], ) ->willReturnOnConsecutiveCalls( 'foo', 'username:password', - ['bar'], ); $this->assertEquals([ 'http' => 'username:password@foo', @@ -271,19 +250,23 @@ class ClientTest extends \Test\TestCase { } private function setUpDefaultRequestOptions(): void { - $map = [ - ['proxy', '', 'foo'], - ['proxyuserpwd', '', null], - ['proxyexclude', [], []], - ]; - $this->config ->method('getSystemValue') - ->will($this->returnValueMap($map)); + ->will($this->returnValueMap([ + ['proxyexclude', [], []], + ])); + $this->config + ->method('getSystemValueString') + ->will($this->returnValueMap([ + ['proxy', '', 'foo'], + ['proxyuserpwd', '', ''], + ])); $this->config ->method('getSystemValueBool') - ->with('allow_local_remote_servers', false) - ->willReturn(true); + ->will($this->returnValueMap([ + ['installed', false, true], + ['allow_local_remote_servers', false, true], + ])); $this->certificateManager ->expects($this->once()) @@ -467,15 +450,20 @@ class ClientTest extends \Test\TestCase { public function testSetDefaultOptionsWithNotInstalled(): void { $this->config ->expects($this->exactly(2)) - ->method('getSystemValue') + ->method('getSystemValueBool') ->withConsecutive( - ['proxy', ''], ['installed', false], + ['allow_local_remote_servers', false], ) ->willReturnOnConsecutiveCalls( - '', + false, false, ); + $this->config + ->expects($this->once()) + ->method('getSystemValueString') + ->with('proxy', '') + ->willReturn(''); $this->certificateManager ->expects($this->never()) ->method('listCertificates'); @@ -503,19 +491,31 @@ class ClientTest extends \Test\TestCase { public function testSetDefaultOptionsWithProxy(): void { $this->config - ->expects($this->exactly(4)) + ->expects($this->exactly(2)) + ->method('getSystemValueBool') + ->withConsecutive( + ['installed', false], + ['allow_local_remote_servers', false], + ) + ->willReturnOnConsecutiveCalls( + true, + false, + ); + $this->config + ->expects($this->once()) ->method('getSystemValue') + ->with('proxyexclude', []) + ->willReturn([]); + $this->config + ->expects($this->exactly(2)) + ->method('getSystemValueString') ->withConsecutive( ['proxy', ''], ['proxyuserpwd', ''], - ['proxyexclude', []], - ['installed', false], ) ->willReturnOnConsecutiveCalls( 'foo', '', - [], - true, ); $this->certificateManager ->expects($this->once()) @@ -550,19 +550,31 @@ class ClientTest extends \Test\TestCase { public function testSetDefaultOptionsWithProxyAndExclude(): void { $this->config - ->expects($this->exactly(4)) + ->expects($this->exactly(2)) + ->method('getSystemValueBool') + ->withConsecutive( + ['installed', false], + ['allow_local_remote_servers', false], + ) + ->willReturnOnConsecutiveCalls( + true, + false, + ); + $this->config + ->expects($this->once()) ->method('getSystemValue') + ->with('proxyexclude', []) + ->willReturn(['bar']); + $this->config + ->expects($this->exactly(2)) + ->method('getSystemValueString') ->withConsecutive( ['proxy', ''], ['proxyuserpwd', ''], - ['proxyexclude', []], - ['installed', false], ) ->willReturnOnConsecutiveCalls( 'foo', '', - ['bar'], - true, ); $this->certificateManager ->expects($this->once()) diff --git a/tests/lib/InitialStateServiceTest.php b/tests/lib/InitialStateServiceTest.php index f4decb43e1e..554478e123f 100644 --- a/tests/lib/InitialStateServiceTest.php +++ b/tests/lib/InitialStateServiceTest.php @@ -27,6 +27,7 @@ namespace Test; use OC\AppFramework\Bootstrap\Coordinator; use OCP\IServerContainer; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use function json_encode; use JsonSerializable; @@ -36,18 +37,22 @@ use stdClass; class InitialStateServiceTest extends TestCase { /** @var InitialStateService */ private $service; + /** @var MockObject|LoggerInterface|(LoggerInterface&MockObject) */ + protected $logger; protected function setUp(): void { parent::setUp(); + $this->logger = $this->createMock(LoggerInterface::class); + $this->service = new InitialStateService( - $this->createMock(LoggerInterface::class), + $this->logger, $this->createMock(Coordinator::class), $this->createMock(IServerContainer::class) ); } - public function staticData() { + public function staticData(): array { return [ ['string'], [23], @@ -63,7 +68,7 @@ class InitialStateServiceTest extends TestCase { /** * @dataProvider staticData */ - public function testStaticData($value) { + public function testStaticData(mixed $value): void { $this->service->provideInitialState('test', 'key', $value); $data = $this->service->getInitialStates(); @@ -73,7 +78,23 @@ class InitialStateServiceTest extends TestCase { ); } - public function testStaticButInvalidData() { + public function testValidDataButFailsToJSONEncode(): void { + $this->logger->expects($this->once()) + ->method('error'); + + $this->service->provideInitialState('test', 'key', ['upload' => INF]); + $data = $this->service->getInitialStates(); + + $this->assertEquals( + [], + $data + ); + } + + public function testStaticButInvalidData(): void { + $this->logger->expects($this->once()) + ->method('warning'); + $this->service->provideInitialState('test', 'key', new stdClass()); $data = $this->service->getInitialStates(); @@ -86,7 +107,7 @@ class InitialStateServiceTest extends TestCase { /** * @dataProvider staticData */ - public function testLazyData($value) { + public function testLazyData(mixed $value): void { $this->service->provideLazyInitialState('test', 'key', function () use ($value) { return $value; }); diff --git a/tests/lib/IntegrityCheck/CheckerTest.php b/tests/lib/IntegrityCheck/CheckerTest.php index 62938ad6c1b..203e7e97227 100644 --- a/tests/lib/IntegrityCheck/CheckerTest.php +++ b/tests/lib/IntegrityCheck/CheckerTest.php @@ -164,7 +164,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -184,7 +184,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -223,7 +223,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -268,7 +268,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -329,7 +329,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -389,7 +389,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -433,7 +433,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -654,7 +654,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -674,7 +674,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -711,7 +711,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -774,7 +774,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -801,7 +801,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -838,7 +838,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -881,7 +881,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -939,7 +939,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -982,7 +982,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -1104,7 +1104,7 @@ class CheckerTest extends TestCase { ->willReturn('stable'); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(true); @@ -1134,7 +1134,7 @@ class CheckerTest extends TestCase { ->willReturn($channel); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(false); @@ -1152,7 +1152,7 @@ class CheckerTest extends TestCase { ->willReturn($channel); $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('integrity.check.disabled', false) ->willReturn(true); diff --git a/tests/lib/L10N/FactoryTest.php b/tests/lib/L10N/FactoryTest.php index 0b536971e90..2db1e0302e8 100644 --- a/tests/lib/L10N/FactoryTest.php +++ b/tests/lib/L10N/FactoryTest.php @@ -47,6 +47,12 @@ class FactoryTest extends TestCase { $this->cacheFactory = $this->createMock(ICacheFactory::class); $this->serverRoot = \OC::$SERVERROOT; + + $this->config + ->method('getSystemValueBool') + ->willReturnMap([ + ['installed', false, true], + ]); } /** @@ -121,14 +127,12 @@ class FactoryTest extends TestCase { true, ); $this->config - ->expects($this->exactly(2)) + ->expects($this->exactly(1)) ->method('getSystemValue') ->withConsecutive( ['force_language', false], - ['installed', false], )->willReturnOnConsecutiveCalls( false, - true, ); $user = $this->getMockBuilder(IUser::class) ->getMock(); @@ -159,11 +163,10 @@ class FactoryTest extends TestCase { ['MyApp', 'es', true], ]); $this->config - ->expects($this->exactly(3)) + ->expects($this->exactly(2)) ->method('getSystemValue') ->willReturnMap([ ['force_language', false, false], - ['installed', false, true], ['default_language', false, 'es'] ]); $user = $this->getMockBuilder(IUser::class) @@ -195,11 +198,10 @@ class FactoryTest extends TestCase { ['MyApp', 'es', false], ]); $this->config - ->expects($this->exactly(3)) + ->expects($this->exactly(2)) ->method('getSystemValue') ->willReturnMap([ ['force_language', false, false], - ['installed', false, true], ['default_language', false, 'es'] ]); $user = $this->getMockBuilder(IUser::class) @@ -234,11 +236,10 @@ class FactoryTest extends TestCase { ['MyApp', 'es', false], ]); $this->config - ->expects($this->exactly(3)) + ->expects($this->exactly(2)) ->method('getSystemValue') ->willReturnMap([ ['force_language', false, false], - ['installed', false, true], ['default_language', false, 'es'] ]); $user = $this->getMockBuilder(IUser::class) @@ -319,7 +320,7 @@ class FactoryTest extends TestCase { ->willReturn($this->serverRoot . '/apps/files/l10n/'); $this->config ->expects(self::once()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('theme') ->willReturn('abc'); @@ -474,9 +475,7 @@ class FactoryTest extends TestCase { $this->config->expects(self::any()) ->method('getSystemValue') ->willReturnCallback(function ($var, $default) use ($defaultLang) { - if ($var === 'installed') { - return true; - } elseif ($var === 'default_language') { + if ($var === 'default_language') { return $defaultLang; } else { return $default; @@ -562,12 +561,11 @@ class FactoryTest extends TestCase { public function testFindGenericLanguageByUserLanguage(): void { $factory = $this->getFactory(); - $this->config->expects(self::exactly(3)) + $this->config->expects(self::exactly(2)) ->method('getSystemValue') ->willReturnMap([ ['force_language', false, false,], ['default_language', false, false,], - ['installed', false, true], ]); $user = $this->createMock(IUser::class); $this->userSession->expects(self::once()) @@ -590,7 +588,6 @@ class FactoryTest extends TestCase { ->willReturnMap([ ['force_language', false, false,], ['default_language', false, false,], - ['installed', false, true], ]); $user = $this->createMock(IUser::class); $this->userSession->expects(self::once()) @@ -621,7 +618,6 @@ class FactoryTest extends TestCase { ->willReturnMap([ ['force_language', false, false,], ['default_language', false, false,], - ['installed', false, true], ]); $user = $this->createMock(IUser::class); $this->userSession->expects(self::once()) diff --git a/tests/lib/L10N/LanguageIteratorTest.php b/tests/lib/L10N/LanguageIteratorTest.php index bbbbb145c75..1d5335cebaa 100644 --- a/tests/lib/L10N/LanguageIteratorTest.php +++ b/tests/lib/L10N/LanguageIteratorTest.php @@ -82,6 +82,10 @@ class LanguageIteratorTest extends TestCase { ->method('getSystemValue') ->willReturnMap([ ['force_language', false, $forcedLang], + ]); + $this->config->expects($this->any()) + ->method('getSystemValueString') + ->willReturnMap([ ['default_language', 'en', $sysLang], ]); $this->config->expects($this->any()) diff --git a/tests/lib/Mail/MailerTest.php b/tests/lib/Mail/MailerTest.php index 39e4d689a37..ba1d52f4baf 100644 --- a/tests/lib/Mail/MailerTest.php +++ b/tests/lib/Mail/MailerTest.php @@ -84,7 +84,7 @@ class MailerTest extends TestCase { public function testGetSendmailInstanceSendMail($sendmailMode, $binaryParam) { $this->config ->expects($this->exactly(2)) - ->method('getSystemValue') + ->method('getSystemValueString') ->willReturnMap([ ['mail_smtpmode', 'smtp', 'sendmail'], ['mail_sendmailmode', 'smtp', $sendmailMode], @@ -107,7 +107,7 @@ class MailerTest extends TestCase { public function testGetSendmailInstanceSendMailQmail($sendmailMode, $binaryParam) { $this->config ->expects($this->exactly(2)) - ->method('getSystemValue') + ->method('getSystemValueString') ->willReturnMap([ ['mail_smtpmode', 'smtp', 'qmail'], ['mail_sendmailmode', 'smtp', $sendmailMode], @@ -133,7 +133,7 @@ class MailerTest extends TestCase { public function testGetInstanceSendmail() { $this->config - ->method('getSystemValue') + ->method('getSystemValueString') ->willReturnMap([ ['mail_smtpmode', 'smtp', 'sendmail'], ['mail_sendmailmode', 'smtp', 'smtp'], @@ -180,7 +180,7 @@ class MailerTest extends TestCase { public function testCreateMessage() { $this->config ->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('mail_send_plaintext_only', false) ->willReturn(false); $this->assertInstanceOf('\OC\Mail\Message', $this->mailer->createMessage()); @@ -229,7 +229,7 @@ class MailerTest extends TestCase { } public function testCreateEMailTemplate() { - $this->config->method('getSystemValue') + $this->config->method('getSystemValueString') ->with('mail_template_class', '') ->willReturnArgument(1); @@ -239,12 +239,16 @@ class MailerTest extends TestCase { public function testStreamingOptions() { $this->config->method('getSystemValue') ->willReturnMap([ - ['mail_smtpmode', 'smtp', 'smtp'], ['mail_smtpstreamoptions', [], ['foo' => 1]], ['mail_smtphost', '127.0.0.1', '127.0.0.1'], ['mail_smtpport', 25, 25], ['mail_smtptimeout', 10, 10], ]); + $this->config->method('getSystemValueString') + ->willReturnMap([ + ['mail_smtpmode', 'smtp', 'smtp'], + ['overwrite.cli.url', '', ''], + ]); $mailer = self::invokePrivate($this->mailer, 'getInstance'); /** @var EsmtpTransport $transport */ $transport = self::invokePrivate($mailer, 'transport'); @@ -256,12 +260,16 @@ class MailerTest extends TestCase { public function testStreamingOptionsWrongType() { $this->config->method('getSystemValue') ->willReturnMap([ - ['mail_smtpmode', 'smtp', 'smtp'], ['mail_smtpstreamoptions', [], 'bar'], ['mail_smtphost', '127.0.0.1', '127.0.0.1'], ['mail_smtpport', 25, 25], ['mail_smtptimeout', 10, 10], ]); + $this->config->method('getSystemValueString') + ->willReturnMap([ + ['mail_smtpmode', 'smtp', 'smtp'], + ['overwrite.cli.url', '', ''], + ]); $mailer = self::invokePrivate($this->mailer, 'getInstance'); /** @var EsmtpTransport $transport */ $transport = self::invokePrivate($mailer, 'transport'); @@ -272,14 +280,15 @@ class MailerTest extends TestCase { public function testLocalDomain(): void { $this->config->method('getSystemValue') ->willReturnMap([ - ['mail_smtpmode', 'smtp', 'smtp'], ['mail_smtphost', '127.0.0.1', '127.0.0.1'], ['mail_smtpport', 25, 25], ['mail_smtptimeout', 10, 10], ]); $this->config->method('getSystemValueString') - ->with('overwrite.cli.url', '') - ->willReturn('https://some.valid.url.com:8080'); + ->willReturnMap([ + ['mail_smtpmode', 'smtp', 'smtp'], + ['overwrite.cli.url', '', 'https://some.valid.url.com:8080'], + ]); /** @var SymfonyMailer $mailer */ $mailer = self::invokePrivate($this->mailer, 'getInstance'); @@ -294,14 +303,15 @@ class MailerTest extends TestCase { public function testLocalDomainInvalidUrl(): void { $this->config->method('getSystemValue') ->willReturnMap([ - ['mail_smtpmode', 'smtp', 'smtp'], - ['mail_smtphost', '127.0.0.1', '127.0.0.1'], ['mail_smtpport', 25, 25], ['mail_smtptimeout', 10, 10], + ['mail_smtphost', '127.0.0.1', '127.0.0.1'], ]); $this->config->method('getSystemValueString') - ->with('overwrite.cli.url', '') - ->willReturn('https:only.slash.does.not.work:8080'); + ->willReturnMap([ + ['mail_smtpmode', 'smtp', 'smtp'], + ['overwrite.cli.url', '', 'https:only.slash.does.not.work:8080'], + ]); /** @var SymfonyMailer $mailer */ $mailer = self::invokePrivate($this->mailer, 'getInstance'); diff --git a/tests/lib/Metadata/FileMetadataMapperTest.php b/tests/lib/Metadata/FileMetadataMapperTest.php index 1a005f24b8a..4f7708ab9a9 100644 --- a/tests/lib/Metadata/FileMetadataMapperTest.php +++ b/tests/lib/Metadata/FileMetadataMapperTest.php @@ -51,23 +51,23 @@ class FileMetadataMapperTest extends \Test\TestCase { $file1 = new FileMetadata(); $file1->setId(1); $file1->setGroupName('size'); - $file1->setMetadata([]); + $file1->setArrayAsValue([]); $file2 = new FileMetadata(); $file2->setId(2); $file2->setGroupName('size'); - $file2->setMetadata(['width' => 293, 'height' => 23]); + $file2->setArrayAsValue(['width' => 293, 'height' => 23]); // not added, it's the default $file3 = new FileMetadata(); $file3->setId(3); $file3->setGroupName('size'); - $file3->setMetadata([]); + $file3->setArrayAsValue([]); $file4 = new FileMetadata(); $file4->setId(4); $file4->setGroupName('size'); - $file4->setMetadata(['complex' => ["yes", "maybe" => 34.0]]); + $file4->setArrayAsValue(['complex' => ["yes", "maybe" => 34.0]]); $this->mapper->insert($file1); $this->mapper->insert($file2); @@ -75,10 +75,10 @@ class FileMetadataMapperTest extends \Test\TestCase { $files = $this->mapper->findForGroupForFiles([1, 2, 3, 4], 'size'); - $this->assertEquals($files[1]->getMetadata(), $file1->getMetadata()); - $this->assertEquals($files[2]->getMetadata(), $file2->getMetadata()); - $this->assertEquals($files[3]->getMetadata(), $file3->getMetadata()); - $this->assertEquals($files[4]->getMetadata(), $file4->getMetadata()); + $this->assertEquals($files[1]->getValue(), $file1->getValue()); + $this->assertEquals($files[2]->getValue(), $file2->getValue()); + $this->assertEquals($files[3]->getDecodedValue(), $file3->getDecodedValue()); + $this->assertEquals($files[4]->getValue(), $file4->getValue()); $this->mapper->clear(1); $this->mapper->clear(2); diff --git a/tests/lib/Preview/BackgroundCleanupJobTest.php b/tests/lib/Preview/BackgroundCleanupJobTest.php index c1c225bd179..aa15ea7f562 100644 --- a/tests/lib/Preview/BackgroundCleanupJobTest.php +++ b/tests/lib/Preview/BackgroundCleanupJobTest.php @@ -69,7 +69,7 @@ class BackgroundCleanupJobTest extends \Test\TestCase { parent::setUp(); $this->userId = $this->getUniqueID(); - $this->createUser($this->userId, $this->userId); + $user = $this->createUser($this->userId, $this->userId); $storage = new \OC\Files\Storage\Temporary([]); $this->registerMount($this->userId, $storage, ''); @@ -79,7 +79,7 @@ class BackgroundCleanupJobTest extends \Test\TestCase { $this->loginAsUser($this->userId); $appManager = \OC::$server->getAppManager(); - $this->trashEnabled = $appManager->isEnabledForUser('files_trashbin', $this->userId); + $this->trashEnabled = $appManager->isEnabledForUser('files_trashbin', $user); $appManager->disableApp('files_trashbin'); $this->connection = \OC::$server->getDatabaseConnection(); diff --git a/tests/lib/Preview/GeneratorTest.php b/tests/lib/Preview/GeneratorTest.php index 1f6f43dce1e..37fc3935139 100644 --- a/tests/lib/Preview/GeneratorTest.php +++ b/tests/lib/Preview/GeneratorTest.php @@ -105,15 +105,12 @@ class GeneratorTest extends \Test\TestCase { $maxPreview->method('getMimeType') ->willReturn('image/png'); - $previewFolder->method('getDirectoryListing') - ->willReturn([$maxPreview]); - $previewFile = $this->createMock(ISimpleFile::class); $previewFile->method('getSize')->willReturn(1000); + $previewFile->method('getName')->willReturn('256-256.png'); - $previewFolder->method('getFile') - ->with($this->equalTo('256-256.png')) - ->willReturn($previewFile); + $previewFolder->method('getDirectoryListing') + ->willReturn([$maxPreview, $previewFile]); $this->legacyEventDispatcher->expects($this->once()) ->method('dispatch') @@ -344,14 +341,12 @@ class GeneratorTest extends \Test\TestCase { $maxPreview->method('getMimeType') ->willReturn('image/png'); - $previewFolder->method('getDirectoryListing') - ->willReturn([$maxPreview]); - $preview = $this->createMock(ISimpleFile::class); $preview->method('getSize')->willReturn(1000); - $previewFolder->method('getFile') - ->with($this->equalTo('1024-512-crop.png')) - ->willReturn($preview); + $preview->method('getName')->willReturn('1024-512-crop.png'); + + $previewFolder->method('getDirectoryListing') + ->willReturn([$maxPreview, $preview]); $this->previewManager->expects($this->never()) ->method('isMimeSupported'); diff --git a/tests/lib/Repair/ClearGeneratedAvatarCacheTest.php b/tests/lib/Repair/ClearGeneratedAvatarCacheTest.php index 7aa7831e44e..44fc709c72a 100644 --- a/tests/lib/Repair/ClearGeneratedAvatarCacheTest.php +++ b/tests/lib/Repair/ClearGeneratedAvatarCacheTest.php @@ -76,7 +76,7 @@ class ClearGeneratedAvatarCacheTest extends \Test\TestCase { */ public function testShouldRun($from, $expected) { $this->config->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('version', '0.0.0.0') ->willReturn($from); diff --git a/tests/lib/Repair/RepairCollationTest.php b/tests/lib/Repair/RepairCollationTest.php index 902ddcd4539..9e76a81080f 100644 --- a/tests/lib/Repair/RepairCollationTest.php +++ b/tests/lib/Repair/RepairCollationTest.php @@ -66,7 +66,7 @@ class RepairCollationTest extends TestCase { $this->markTestSkipped("Test only relevant on MySql"); } - $dbPrefix = $this->config->getSystemValue("dbtableprefix"); + $dbPrefix = $this->config->getSystemValueString("dbtableprefix"); $this->tableName = $this->getUniqueID($dbPrefix . "_collation_test"); $this->connection->prepare("CREATE TABLE $this->tableName(text VARCHAR(16)) COLLATE utf8_unicode_ci")->execute(); diff --git a/tests/lib/Repair/RepairDavSharesTest.php b/tests/lib/Repair/RepairDavSharesTest.php index 5eeafd7bf9f..394fc985469 100644 --- a/tests/lib/Repair/RepairDavSharesTest.php +++ b/tests/lib/Repair/RepairDavSharesTest.php @@ -71,7 +71,7 @@ class RepairDavSharesTest extends TestCase { public function testRun() { $this->config->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('version', '0.0.0') ->willReturn('20.0.2'); diff --git a/tests/lib/Repair/RepairInvalidSharesTest.php b/tests/lib/Repair/RepairInvalidSharesTest.php index f93940cc3ed..486e11230b8 100644 --- a/tests/lib/Repair/RepairInvalidSharesTest.php +++ b/tests/lib/Repair/RepairInvalidSharesTest.php @@ -36,7 +36,7 @@ class RepairInvalidSharesTest extends TestCase { ->disableOriginalConstructor() ->getMock(); $config->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('version') ->willReturn('12.0.0.0'); diff --git a/tests/lib/Repair/RepairMimeTypesTest.php b/tests/lib/Repair/RepairMimeTypesTest.php index 176bc0ec102..61cf5858241 100644 --- a/tests/lib/Repair/RepairMimeTypesTest.php +++ b/tests/lib/Repair/RepairMimeTypesTest.php @@ -42,7 +42,7 @@ class RepairMimeTypesTest extends \Test\TestCase { ->disableOriginalConstructor() ->getMock(); $config->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('version') ->willReturn('11.0.0.0'); diff --git a/tests/lib/Repair/RepairSqliteAutoincrementTest.php b/tests/lib/Repair/RepairSqliteAutoincrementTest.php index 5b3a388dea3..b4be47d0157 100644 --- a/tests/lib/Repair/RepairSqliteAutoincrementTest.php +++ b/tests/lib/Repair/RepairSqliteAutoincrementTest.php @@ -46,7 +46,7 @@ class RepairSqliteAutoincrementTest extends \Test\TestCase { $this->markTestSkipped("Test only relevant on Sqlite"); } - $dbPrefix = $this->config->getSystemValue('dbtableprefix', 'oc_'); + $dbPrefix = $this->config->getSystemValueString('dbtableprefix', 'oc_'); $this->tableName = $this->getUniqueID($dbPrefix . 'autoinc_test'); $this->connection->prepare('CREATE TABLE ' . $this->tableName . '("someid" INTEGER NOT NULL, "text" VARCHAR(16), PRIMARY KEY("someid"))')->execute(); diff --git a/tests/lib/Security/Bruteforce/ThrottlerTest.php b/tests/lib/Security/Bruteforce/ThrottlerTest.php index 6639f884ae1..f23b15a06d7 100644 --- a/tests/lib/Security/Bruteforce/ThrottlerTest.php +++ b/tests/lib/Security/Bruteforce/ThrottlerTest.php @@ -183,7 +183,7 @@ class ThrottlerTest extends TestCase { ->willReturn(array_keys($whitelists)); $this->config ->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('auth.bruteforce.protection.enabled', true) ->willReturn($enabled); diff --git a/tests/lib/Security/CertificateManagerTest.php b/tests/lib/Security/CertificateManagerTest.php index fdc6b40533e..6ad8231a61d 100644 --- a/tests/lib/Security/CertificateManagerTest.php +++ b/tests/lib/Security/CertificateManagerTest.php @@ -48,7 +48,7 @@ class CertificateManagerTest extends \Test\TestCase { \OC_Util::setupFS($this->username); $config = $this->createMock(IConfig::class); - $config->expects($this->any())->method('getSystemValue') + $config->expects($this->any())->method('getSystemValueBool') ->with('installed', false)->willReturn(true); $this->random = $this->createMock(ISecureRandom::class); diff --git a/tests/lib/Security/CredentialsManagerTest.php b/tests/lib/Security/CredentialsManagerTest.php index 6f535c84275..bb4feb8b6a9 100644 --- a/tests/lib/Security/CredentialsManagerTest.php +++ b/tests/lib/Security/CredentialsManagerTest.php @@ -24,6 +24,9 @@ declare(strict_types=1); namespace Test\Security; +use OCP\Security\ICredentialsManager; +use OCP\Server; + /** * @group DB */ @@ -32,7 +35,7 @@ class CredentialsManagerTest extends \Test\TestCase { * @dataProvider credentialsProvider */ public function testWithDB($userId, $identifier) { - $credentialsManager = \OC::$server->getCredentialsManager(); + $credentialsManager = Server::get(ICredentialsManager::class); $secrets = 'Open Sesame'; @@ -45,7 +48,23 @@ class CredentialsManagerTest extends \Test\TestCase { $this->assertSame(1, $removedRows); } - public function credentialsProvider() { + /** + * @dataProvider credentialsProvider + */ + public function testUpdate($userId, $identifier): void { + $credentialsManager = Server::get(ICredentialsManager::class); + + $secrets = 'Open Sesame'; + $secretsRev = strrev($secrets); + + $credentialsManager->store($userId, $identifier, $secrets); + $credentialsManager->store($userId, $identifier, $secretsRev); + $received = $credentialsManager->retrieve($userId, $identifier); + + $this->assertSame($secretsRev, $received); + } + + public function credentialsProvider(): array { return [ [ 'alice', diff --git a/tests/lib/Security/HasherTest.php b/tests/lib/Security/HasherTest.php index 37e2adcc13c..3848b216f2b 100644 --- a/tests/lib/Security/HasherTest.php +++ b/tests/lib/Security/HasherTest.php @@ -209,7 +209,7 @@ class HasherTest extends \Test\TestCase { $this->markTestSkipped('Need ARGON2 support to test ARGON2 hashes'); } - $this->config->method('getSystemValue') + $this->config->method('getSystemValueBool') ->with('hashing_default_password') ->willReturn(true); @@ -233,7 +233,7 @@ class HasherTest extends \Test\TestCase { $this->markTestSkipped('Need ARGON2ID support to test ARGON2ID hashes'); } - $this->config->method('getSystemValue') + $this->config->method('getSystemValueBool') ->with('hashing_default_password') ->willReturn(false); @@ -251,7 +251,7 @@ class HasherTest extends \Test\TestCase { $this->markTestSkipped('Need ARGON2 support to test ARGON2 hashes'); } - $this->config->method('getSystemValue') + $this->config->method('getSystemValueBool') ->with('hashing_default_password') ->willReturn(true); diff --git a/tests/lib/Security/RateLimiting/Backend/MemoryCacheBackendTest.php b/tests/lib/Security/RateLimiting/Backend/MemoryCacheBackendTest.php index e7cb4a93a29..a48b1211587 100644 --- a/tests/lib/Security/RateLimiting/Backend/MemoryCacheBackendTest.php +++ b/tests/lib/Security/RateLimiting/Backend/MemoryCacheBackendTest.php @@ -28,9 +28,12 @@ use OC\Security\RateLimiting\Backend\MemoryCacheBackend; use OCP\AppFramework\Utility\ITimeFactory; use OCP\ICache; use OCP\ICacheFactory; +use OCP\IConfig; use Test\TestCase; class MemoryCacheBackendTest extends TestCase { + /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ + private $config; /** @var ICacheFactory|\PHPUnit\Framework\MockObject\MockObject */ private $cacheFactory; /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */ @@ -43,6 +46,7 @@ class MemoryCacheBackendTest extends TestCase { protected function setUp(): void { parent::setUp(); + $this->config = $this->createMock(IConfig::class); $this->cacheFactory = $this->createMock(ICacheFactory::class); $this->timeFactory = $this->createMock(ITimeFactory::class); $this->cache = $this->createMock(ICache::class); @@ -53,7 +57,12 @@ class MemoryCacheBackendTest extends TestCase { ->with('OC\Security\RateLimiting\Backend\MemoryCacheBackend') ->willReturn($this->cache); + $this->config->method('getSystemValueBool') + ->with('ratelimit.protection.enabled') + ->willReturn(true); + $this->memoryCache = new MemoryCacheBackend( + $this->config, $this->cacheFactory, $this->timeFactory ); diff --git a/tests/lib/Security/VerificationToken/VerificationTokenTest.php b/tests/lib/Security/VerificationToken/VerificationTokenTest.php index 481646f26ab..a71d2b09f71 100644 --- a/tests/lib/Security/VerificationToken/VerificationTokenTest.php +++ b/tests/lib/Security/VerificationToken/VerificationTokenTest.php @@ -116,7 +116,7 @@ class VerificationTokenTest extends TestCase { ->with('alice', 'core', 'fingerprintToken', null) ->willReturn('encryptedToken'); $this->config->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('secret') ->willReturn('357111317'); @@ -143,7 +143,7 @@ class VerificationTokenTest extends TestCase { ->with('alice', 'core', 'fingerprintToken', null) ->willReturn('encryptedToken'); $this->config->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('secret') ->willReturn('357111317'); @@ -173,7 +173,7 @@ class VerificationTokenTest extends TestCase { ->with('alice', 'core', 'fingerprintToken', null) ->willReturn('encryptedToken'); $this->config->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('secret') ->willReturn('357111317'); @@ -207,7 +207,7 @@ class VerificationTokenTest extends TestCase { ->with('alice', 'core', 'fingerprintToken', null) ->willReturn('encryptedToken'); $this->config->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('secret') ->willReturn('357111317'); @@ -241,7 +241,7 @@ class VerificationTokenTest extends TestCase { ->with('alice', 'core', 'fingerprintToken', null) ->willReturn('encryptedToken'); $this->config->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('secret') ->willReturn('357111317'); @@ -275,7 +275,7 @@ class VerificationTokenTest extends TestCase { ->with('alice', 'core', 'fingerprintToken', null) ->willReturn('encryptedToken'); $this->config->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('secret') ->willReturn('357111317'); diff --git a/tests/lib/Share20/ManagerTest.php b/tests/lib/Share20/ManagerTest.php index 36680b7b926..0e56592e1a5 100644 --- a/tests/lib/Share20/ManagerTest.php +++ b/tests/lib/Share20/ManagerTest.php @@ -1285,7 +1285,7 @@ class ManagerTest extends \Test\TestCase { ['core', 'shareapi_enforce_expire_date', 'no', 'yes'], ['core', 'shareapi_expire_after_n_days', '7', '3'], ['core', 'shareapi_default_expire_date', 'no', 'yes'], - ['core', 'link_defaultExpDays', 3, '3'], + ['core', 'link_defaultExpDays', '3', '3'], ]); $expected = new \DateTime(); @@ -1306,7 +1306,7 @@ class ManagerTest extends \Test\TestCase { ['core', 'shareapi_enforce_expire_date', 'no', 'yes'], ['core', 'shareapi_expire_after_n_days', '7', '3'], ['core', 'shareapi_default_expire_date', 'no', 'yes'], - ['core', 'link_defaultExpDays', 3, '1'], + ['core', 'link_defaultExpDays', '3', '1'], ]); $expected = new \DateTime(); @@ -1416,7 +1416,7 @@ class ManagerTest extends \Test\TestCase { ->willReturnMap([ ['core', 'shareapi_default_expire_date', 'no', 'yes'], ['core', 'shareapi_expire_after_n_days', '7', '3'], - ['core', 'link_defaultExpDays', 3, '3'], + ['core', 'link_defaultExpDays', '3', '3'], ]); $hookListener = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock(); @@ -1445,7 +1445,7 @@ class ManagerTest extends \Test\TestCase { ->willReturnMap([ ['core', 'shareapi_default_expire_date', 'no', 'yes'], ['core', 'shareapi_expire_after_n_days', '7', '3'], - ['core', 'link_defaultExpDays', 3, '1'], + ['core', 'link_defaultExpDays', '3', '1'], ]); $hookListener = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock(); diff --git a/tests/lib/Support/Subscription/RegistryTest.php b/tests/lib/Support/Subscription/RegistryTest.php index f4a278cca4e..2a6d5e5569f 100644 --- a/tests/lib/Support/Subscription/RegistryTest.php +++ b/tests/lib/Support/Subscription/RegistryTest.php @@ -206,7 +206,7 @@ class RegistryTest extends TestCase { ->with('one-click-instance') ->willReturn(true); $this->config->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueInt') ->with('one-click-instance.user-limit') ->willReturn($userLimit); $this->config->expects($this->once()) diff --git a/tests/lib/SystemTag/SystemTagManagerTest.php b/tests/lib/SystemTag/SystemTagManagerTest.php index ef0546dbd88..e261a68aaf7 100644 --- a/tests/lib/SystemTag/SystemTagManagerTest.php +++ b/tests/lib/SystemTag/SystemTagManagerTest.php @@ -259,6 +259,11 @@ class SystemTagManagerTest extends TestCase { $this->tagManager->createTag($name, $userVisible, $userAssignable); } + public function testCreateOverlongName() { + $tag = $this->tagManager->createTag('Zona circundante do Palácio Nacional da Ajuda (Jardim das Damas, Salão de Física, Torre Sineira, Paço Velho e Jardim Botânico)', true, true); + $this->assertSame('Zona circundante do Palácio Nacional da Ajuda (Jardim das Damas', $tag->getName()); // 63 characters but 64 bytes due to "á" + } + /** * @dataProvider oneTagMultipleFlagsProvider */ @@ -281,14 +286,14 @@ class SystemTagManagerTest extends TestCase { $this->assertSameTag($tag2, $tagList[$tag2->getId()]); } - + public function testGetNonExistingTag() { $this->expectException(\OCP\SystemTag\TagNotFoundException::class); $this->tagManager->getTag('nonexist', false, false); } - + public function testGetNonExistingTagsById() { $this->expectException(\OCP\SystemTag\TagNotFoundException::class); @@ -296,7 +301,7 @@ class SystemTagManagerTest extends TestCase { $this->tagManager->getTagsByIds([$tag1->getId(), 100, 101]); } - + public function testGetInvalidTagIdFormat() { $this->expectException(\InvalidArgumentException::class); @@ -391,7 +396,7 @@ class SystemTagManagerTest extends TestCase { $this->assertEmpty($this->tagManager->getAllTags()); } - + public function testDeleteNonExistingTag() { $this->expectException(\OCP\SystemTag\TagNotFoundException::class); diff --git a/tests/lib/SystemTag/SystemTagObjectMapperTest.php b/tests/lib/SystemTag/SystemTagObjectMapperTest.php index c988db69c30..e77709c781f 100644 --- a/tests/lib/SystemTag/SystemTagObjectMapperTest.php +++ b/tests/lib/SystemTag/SystemTagObjectMapperTest.php @@ -141,6 +141,17 @@ class SystemTagObjectMapperTest extends TestCase { $this->assertEquals([], $tagIdMapping); } + public function testGetTagIdsForALotOfObjects() { + $ids = range(1, 10500); + $tagIdMapping = $this->tagMapper->getTagIdsForObjects( + $ids, + 'testtype' + ); + + $this->assertEquals(10500, count($tagIdMapping)); + $this->assertEquals([$this->tag1->getId(), $this->tag2->getId()], $tagIdMapping[1]); + } + public function testGetObjectsForTags() { $objectIds = $this->tagMapper->getObjectIdsForTags( [$this->tag1->getId(), $this->tag2->getId(), $this->tag3->getId()], @@ -165,7 +176,7 @@ class SystemTagObjectMapperTest extends TestCase { ], $objectIds); } - + public function testGetObjectsForTagsLimitWithMultipleTags() { $this->expectException(\InvalidArgumentException::class); @@ -189,7 +200,7 @@ class SystemTagObjectMapperTest extends TestCase { ], $objectIds); } - + public function testGetObjectsForNonExistingTag() { $this->expectException(\OCP\SystemTag\TagNotFoundException::class); @@ -227,7 +238,7 @@ class SystemTagObjectMapperTest extends TestCase { $this->assertTrue(true, 'No error when reassigning/unassigning'); } - + public function testAssignNonExistingTags() { $this->expectException(\OCP\SystemTag\TagNotFoundException::class); @@ -254,7 +265,7 @@ class SystemTagObjectMapperTest extends TestCase { ], $tagIdMapping, 'None of the tags got assigned'); } - + public function testUnassignNonExistingTags() { $this->expectException(\OCP\SystemTag\TagNotFoundException::class); @@ -385,7 +396,7 @@ class SystemTagObjectMapperTest extends TestCase { ); } - + public function testHaveTagNonExisting() { $this->expectException(\OCP\SystemTag\TagNotFoundException::class); diff --git a/tests/lib/Template/JSResourceLocatorTest.php b/tests/lib/Template/JSResourceLocatorTest.php index 20fd79a91b5..627fe676680 100644 --- a/tests/lib/Template/JSResourceLocatorTest.php +++ b/tests/lib/Template/JSResourceLocatorTest.php @@ -26,6 +26,7 @@ namespace Test\Template; use OC\SystemConfig; use OC\Template\JSCombiner; use OC\Template\JSResourceLocator; +use OCP\App\IAppManager; use OCP\Files\IAppData; use OCP\ICacheFactory; use OCP\IURLGenerator; @@ -42,6 +43,8 @@ class JSResourceLocatorTest extends \Test\TestCase { protected $cacheFactory; /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ protected $logger; + /** @var IAppManager|\PHPUnit\Framework\MockObject\MockObject */ + protected $appManager; protected function setUp(): void { parent::setUp(); @@ -51,6 +54,7 @@ class JSResourceLocatorTest extends \Test\TestCase { $this->config = $this->createMock(SystemConfig::class); $this->cacheFactory = $this->createMock(ICacheFactory::class); $this->logger = $this->createMock(LoggerInterface::class); + $this->appManager = $this->createMock(IAppManager::class); } private function jsResourceLocator() { @@ -63,7 +67,8 @@ class JSResourceLocatorTest extends \Test\TestCase { ); return new JSResourceLocator( $this->logger, - $jsCombiner + $jsCombiner, + $this->appManager, ); } @@ -84,25 +89,34 @@ class JSResourceLocatorTest extends \Test\TestCase { } public function testFindWithAppPathSymlink() { + $appName = 'test-js-app'; + // First create new apps path, and a symlink to it $apps_dirname = $this->randomString(); $new_apps_path = sys_get_temp_dir() . '/' . $apps_dirname; $new_apps_path_symlink = $new_apps_path . '_link'; - mkdir($new_apps_path); - symlink($apps_dirname, $new_apps_path_symlink); + $this->assertTrue(( + mkdir($new_apps_path) && symlink($apps_dirname, $new_apps_path_symlink) + ), 'Setup of apps path failed'); // Create an app within that path - mkdir($new_apps_path . '/' . 'test-js-app'); + $this->assertTrue(( + mkdir($new_apps_path . '/' . $appName) && touch($new_apps_path . '/' . $appName . '/' . 'test-file.js') + ), 'Setup of app within the new apps path failed'); // Use the symlink as the app path - \OC::$APPSROOTS[] = [ - 'path' => $new_apps_path_symlink, - 'url' => '/js-apps-test', - 'writable' => false, - ]; - + $this->appManager->expects($this->once()) + ->method('getAppPath') + ->with($appName) + ->willReturn("$new_apps_path_symlink/$appName"); + $this->appManager->expects($this->once()) + ->method('getAppWebPath') + ->with($appName) + ->willReturn("/js-apps-test/$appName"); + + // Run the tests $locator = $this->jsResourceLocator(); - $locator->find(['test-js-app/test-file']); + $locator->find(["$appName/test-file"]); $resources = $locator->getResources(); $this->assertCount(1, $resources); @@ -122,7 +136,45 @@ class JSResourceLocatorTest extends \Test\TestCase { $this->assertEquals($expectedFile, $file); array_pop(\OC::$APPSROOTS); - unlink($new_apps_path_symlink); + //unlink($new_apps_path_symlink); + //$this->rrmdir($new_apps_path); + } + + public function testFindModuleJSWithFallback() { + // First create new apps path, and a symlink to it + $apps_dirname = $this->randomString(); + $new_apps_path = sys_get_temp_dir() . '/' . $apps_dirname; + mkdir($new_apps_path); + + // Create an app within that path + mkdir("$new_apps_path/test-js-app"); + touch("$new_apps_path/test-js-app/module.mjs"); + touch("$new_apps_path/test-js-app/both.mjs"); + touch("$new_apps_path/test-js-app/both.js"); + touch("$new_apps_path/test-js-app/plain.js"); + + // Use the app path + $this->appManager->expects($this->any()) + ->method('getAppPath') + ->with('test-js-app') + ->willReturn("$new_apps_path/test-js-app"); + + $locator = $this->jsResourceLocator(); + $locator->find(['test-js-app/module', 'test-js-app/both', 'test-js-app/plain']); + + $resources = $locator->getResources(); + $this->assertCount(3, $resources); + + $expectedRoot = $new_apps_path . '/test-js-app'; + $expectedWebRoot = \OC::$WEBROOT . '/js-apps-test/test-js-app'; + $expectedFiles = ['module.mjs', 'both.mjs', 'plain.js']; + + for ($idx = 0; $idx++; $idx < 3) { + $this->assertEquals($expectedWebRoot, $resources[$idx][1]); + $this->assertEquals($expectedFiles[$idx], $resources[$idx][2]); + } + + array_pop(\OC::$APPSROOTS); $this->rrmdir($new_apps_path); } } diff --git a/tests/lib/TemplateFunctionsTest.php b/tests/lib/TemplateFunctionsTest.php index caecdfc76ac..b2b25ab654c 100644 --- a/tests/lib/TemplateFunctionsTest.php +++ b/tests/lib/TemplateFunctionsTest.php @@ -57,6 +57,35 @@ class TemplateFunctionsTest extends \Test\TestCase { print_unescaped($string); } + public function testEmitScriptTagWithContent() { + $this->expectOutputRegex('/<script nonce="[^"]+">\nalert\(\)\n<\/script>\n?/'); + emit_script_tag('', 'alert()'); + } + + public function testEmitScriptTagWithSource() { + $this->expectOutputRegex('/<script nonce=".*" defer src="some.js"><\/script>/'); + emit_script_tag('some.js'); + } + + public function testEmitScriptTagWithModuleSource() { + $this->expectOutputRegex('/<script nonce=".*" defer src="some.mjs" type="module"><\/script>/'); + emit_script_tag('some.mjs', '', 'module'); + } + + public function testEmitScriptLoadingTags() { + // Test mjs js and inline content + $pattern = '/src="some\.mjs"[^>]+type="module"[^>]*>.+\n'; // some.mjs with type = module + $pattern .= '<script[^>]+src="other\.js"[^>]*>.+\n'; // other.js as plain javascript + $pattern .= '<script[^>]*>\n?.*inline.*\n?<\/script>'; // inline content + $pattern .= '/'; // no flags + + $this->expectOutputRegex($pattern); + emit_script_loading_tags([ + 'jsfiles' => ['some.mjs', 'other.js'], + 'inline_ocjs' => '// inline' + ]); + } + // --------------------------------------------------------------------------- // Test relative_modified_date with dates only // --------------------------------------------------------------------------- diff --git a/tests/lib/TestCase.php b/tests/lib/TestCase.php index 256fb95a85b..a242a51a887 100644 --- a/tests/lib/TestCase.php +++ b/tests/lib/TestCase.php @@ -266,7 +266,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase { return self::$realDatabase; }); } - $dataDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data-autotest'); + $dataDir = \OC::$server->getConfig()->getSystemValueString('datadirectory', \OC::$SERVERROOT . '/data-autotest'); if (self::$wasDatabaseAllowed && \OC::$server->getDatabaseConnection()) { $db = \OC::$server->getDatabaseConnection(); if ($db->inTransaction()) { diff --git a/tests/lib/Updater/ChangesCheckTest.php b/tests/lib/Updater/ChangesCheckTest.php index 02da6d08401..e96406622f4 100644 --- a/tests/lib/Updater/ChangesCheckTest.php +++ b/tests/lib/Updater/ChangesCheckTest.php @@ -28,7 +28,7 @@ namespace Test\Updater; use OC\Updater\ChangesCheck; use OC\Updater\ChangesMapper; -use OC\Updater\ChangesResult; +use OC\Updater\Changes; use OCP\AppFramework\Db\DoesNotExistException; use OCP\Http\Client\IClient; use OCP\Http\Client\IClientService; @@ -88,7 +88,7 @@ class ChangesCheckTest extends TestCase { public function testCacheResultInsert() { $version = '13.0.4'; - $entry = $this->createMock(ChangesResult::class); + $entry = $this->createMock(Changes::class); $entry->expects($this->exactly(2)) ->method('__call') ->withConsecutive(['getVersion'], ['setVersion', [$version]]) @@ -104,7 +104,7 @@ class ChangesCheckTest extends TestCase { public function testCacheResultUpdate() { $version = '13.0.4'; - $entry = $this->createMock(ChangesResult::class); + $entry = $this->createMock(Changes::class); $entry->expects($this->once()) ->method('__call') ->willReturn($version); @@ -306,7 +306,7 @@ class ChangesCheckTest extends TestCase { */ public function testQueryChangesServer(string $etag) { $uri = 'https://changes.nextcloud.server/?13.0.5'; - $entry = $this->createMock(ChangesResult::class); + $entry = $this->createMock(Changes::class); $entry->expects($this->any()) ->method('__call') ->willReturn($etag); @@ -370,7 +370,7 @@ class ChangesCheckTest extends TestCase { $this->expectException(DoesNotExistException::class); $mocker->willThrowException(new DoesNotExistException('Changes info is not present')); } else { - $entry = $this->createMock(ChangesResult::class); + $entry = $this->createMock(Changes::class); $entry->expects($this->once()) ->method('__call') ->with('getData') @@ -386,7 +386,7 @@ class ChangesCheckTest extends TestCase { } public function testGetChangesForVersionEmptyData() { - $entry = $this->createMock(ChangesResult::class); + $entry = $this->createMock(Changes::class); $entry->expects($this->once()) ->method('__call') ->with('getData') diff --git a/tests/lib/Updater/VersionCheckTest.php b/tests/lib/Updater/VersionCheckTest.php index cc2b0a369aa..1cd632875c3 100644 --- a/tests/lib/Updater/VersionCheckTest.php +++ b/tests/lib/Updater/VersionCheckTest.php @@ -111,21 +111,21 @@ class VersionCheckTest extends \Test\TestCase { ['core', 'lastupdatedat'], ) ->willReturnOnConsecutiveCalls( - 0, + '0', 'installedat', 'installedat', 'lastupdatedat' ); $this->config ->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('updater.server.url', 'https://updates.nextcloud.com/updater_server/') ->willReturnArgument(1); $this->config ->expects($this->exactly(2)) ->method('setAppValue') ->withConsecutive( - ['core', 'lastupdatedat', $this->isType('integer')], + ['core', 'lastupdatedat', $this->isType('string')], ['core', 'lastupdateResult', json_encode($expectedResult)] ); @@ -163,21 +163,21 @@ class VersionCheckTest extends \Test\TestCase { ['core', 'lastupdatedat'], ) ->willReturnOnConsecutiveCalls( - 0, + '0', 'installedat', 'installedat', 'lastupdatedat' ); $this->config ->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('updater.server.url', 'https://updates.nextcloud.com/updater_server/') ->willReturnArgument(1); $this->config ->expects($this->exactly(2)) ->method('setAppValue') ->withConsecutive( - ['core', 'lastupdatedat', $this->isType('integer')], + ['core', 'lastupdatedat', $this->isType('string')], ['core', 'lastupdateResult', '[]'] ); @@ -217,21 +217,21 @@ class VersionCheckTest extends \Test\TestCase { ['core', 'lastupdatedat'], ) ->willReturnOnConsecutiveCalls( - 0, + '0', 'installedat', 'installedat', 'lastupdatedat' ); $this->config ->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('updater.server.url', 'https://updates.nextcloud.com/updater_server/') ->willReturnArgument(1); $this->config ->expects($this->exactly(2)) ->method('setAppValue') ->withConsecutive( - ['core', 'lastupdatedat', $this->isType('integer')], + ['core', 'lastupdatedat', $this->isType('string')], ['core', 'lastupdateResult', $this->isType('string')] ); @@ -270,21 +270,21 @@ class VersionCheckTest extends \Test\TestCase { ['core', 'lastupdatedat'], ) ->willReturnOnConsecutiveCalls( - 0, + '0', 'installedat', 'installedat', 'lastupdatedat' ); $this->config ->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('updater.server.url', 'https://updates.nextcloud.com/updater_server/') ->willReturnArgument(1); $this->config ->expects($this->exactly(2)) ->method('setAppValue') ->withConsecutive( - ['core', 'lastupdatedat', $this->isType('integer')], + ['core', 'lastupdatedat', $this->isType('string')], ['core', 'lastupdateResult', json_encode($expectedResult)] ); @@ -324,21 +324,21 @@ class VersionCheckTest extends \Test\TestCase { ['core', 'lastupdatedat'], ) ->willReturnOnConsecutiveCalls( - 0, + '0', 'installedat', 'installedat', 'lastupdatedat' ); $this->config ->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with('updater.server.url', 'https://updates.nextcloud.com/updater_server/') ->willReturnArgument(1); $this->config ->expects($this->exactly(2)) ->method('setAppValue') ->withConsecutive( - ['core', 'lastupdatedat', $this->isType('integer')], + ['core', 'lastupdatedat', $this->isType('string')], ['core', 'lastupdateResult', $this->isType('string')] ); diff --git a/tests/lib/UpdaterTest.php b/tests/lib/UpdaterTest.php index 5a7422cbad5..579761208db 100644 --- a/tests/lib/UpdaterTest.php +++ b/tests/lib/UpdaterTest.php @@ -105,7 +105,7 @@ class UpdaterTest extends TestCase { */ public function testIsUpgradePossible($oldVersion, $newVersion, $allowedVersions, $result, $debug = false, $vendor = 'nextcloud') { $this->config->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('debug', false) ->willReturn($debug); $this->config->expects($this->any()) diff --git a/tests/lib/UrlGeneratorTest.php b/tests/lib/UrlGeneratorTest.php index 420b2fe4eb9..b95cb115217 100644 --- a/tests/lib/UrlGeneratorTest.php +++ b/tests/lib/UrlGeneratorTest.php @@ -13,7 +13,6 @@ use OCP\ICacheFactory; use OCP\IConfig; use OCP\IRequest; use OCP\IURLGenerator; -use OCP\IUser; use OCP\IUserSession; /** @@ -216,21 +215,16 @@ class UrlGeneratorTest extends \Test\TestCase { ]; } - private function mockLinkToDefaultPageUrl(string $defaultAppConfig = '', bool $ignoreFrontControllerConfig = false) { - $this->config->expects($this->exactly(2)) - ->method('getSystemValue') - ->withConsecutive( - ['defaultapp', $this->anything()], - ['htaccess.IgnoreFrontController', $this->anything()], - ) - ->will($this->onConsecutiveCalls( - $defaultAppConfig, - $ignoreFrontControllerConfig - )); + private function mockLinkToDefaultPageUrl(bool $ignoreFrontControllerConfig = false) { $this->config->expects($this->once()) ->method('getAppValue') ->with('core', 'defaultpage') ->willReturn(''); + + $this->config->expects($this->once()) + ->method('getSystemValueBool') + ->with('htaccess.IgnoreFrontController', $this->anything()) + ->willReturn($ignoreFrontControllerConfig); } public function testLinkToDefaultPageUrlWithRedirectUrlWithoutFrontController() { @@ -246,7 +240,7 @@ class UrlGeneratorTest extends \Test\TestCase { putenv('front_controller_active=false'); $_REQUEST['redirect_url'] = 'myRedirectUrl.com@foo.com:a'; - $this->assertSame('http://localhost' . \OC::$WEBROOT . '/index.php/apps/files/', $this->urlGenerator->linkToDefaultPageUrl()); + $this->assertSame('http://localhost' . \OC::$WEBROOT . '/index.php/apps/dashboard/', $this->urlGenerator->linkToDefaultPageUrl()); } public function testLinkToDefaultPageUrlWithRedirectUrlRedirectBypassWithFrontController() { @@ -255,70 +249,16 @@ class UrlGeneratorTest extends \Test\TestCase { putenv('front_controller_active=true'); $_REQUEST['redirect_url'] = 'myRedirectUrl.com@foo.com:a'; - $this->assertSame('http://localhost' . \OC::$WEBROOT . '/apps/files/', $this->urlGenerator->linkToDefaultPageUrl()); + $this->assertSame('http://localhost' . \OC::$WEBROOT . '/apps/dashboard/', $this->urlGenerator->linkToDefaultPageUrl()); } public function testLinkToDefaultPageUrlWithRedirectUrlWithIgnoreFrontController() { $this->mockBaseUrl(); - $this->mockLinkToDefaultPageUrl('', true); + $this->mockLinkToDefaultPageUrl(true); putenv('front_controller_active=false'); $_REQUEST['redirect_url'] = 'myRedirectUrl.com@foo.com:a'; - $this->assertSame('http://localhost' . \OC::$WEBROOT . '/apps/files/', $this->urlGenerator->linkToDefaultPageUrl()); - } - - /** - * @dataProvider provideDefaultApps - */ - public function testLinkToDefaultPageUrlWithDefaultApps($defaultAppConfig, $expectedPath) { - $userId = $this->getUniqueID(); - - /** @var \PHPUnit\Framework\MockObject\MockObject|IUser $userMock */ - $userMock = $this->createMock(IUser::class); - $userMock->expects($this->once()) - ->method('getUID') - ->willReturn($userId); - - $this->mockBaseUrl(); - $this->mockLinkToDefaultPageUrl($defaultAppConfig); - - $this->config->expects($this->once()) - ->method('getUserValue') - ->with($userId, 'core', 'defaultapp') - ->willReturn(''); - $this->userSession->expects($this->once()) - ->method('isLoggedIn') - ->willReturn(true); - $this->userSession->expects($this->once()) - ->method('getUser') - ->willReturn($userMock); - - $this->assertEquals('http://localhost' . \OC::$WEBROOT . $expectedPath, $this->urlGenerator->linkToDefaultPageUrl()); - } - - public function provideDefaultApps(): array { - return [ - // none specified, default to files - [ - '', - '/index.php/apps/files/', - ], - // unexisting or inaccessible app specified, default to files - [ - 'unexist', - '/index.php/apps/files/', - ], - // non-standard app - [ - 'settings', - '/index.php/apps/settings/', - ], - // non-standard app with fallback - [ - 'unexist,settings', - '/index.php/apps/settings/', - ], - ]; + $this->assertSame('http://localhost' . \OC::$WEBROOT . '/apps/dashboard/', $this->urlGenerator->linkToDefaultPageUrl()); } public function imagePathProvider(): array { diff --git a/tests/lib/User/SessionTest.php b/tests/lib/User/SessionTest.php index 735a3b3d06a..e0afb5330d9 100644 --- a/tests/lib/User/SessionTest.php +++ b/tests/lib/User/SessionTest.php @@ -9,6 +9,7 @@ namespace Test\User; use OC\AppFramework\Http\Request; +use OC\Authentication\Events\LoginFailed; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordLoginForbiddenException; use OC\Authentication\Token\IProvider; @@ -352,7 +353,7 @@ class SessionTest extends \Test\TestCase { ->with('doe') ->will($this->throwException(new InvalidTokenException())); $this->config->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('token_auth_enforced', false) ->willReturn(true); $request @@ -388,7 +389,7 @@ class SessionTest extends \Test\TestCase { ->with('doe') ->will($this->throwException(new InvalidTokenException())); $this->config->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('token_auth_enforced', false) ->willReturn(false); $manager->method('getByEmail') @@ -456,7 +457,7 @@ class SessionTest extends \Test\TestCase { ->with('doe') ->will($this->throwException(new InvalidTokenException())); $this->config->expects($this->once()) - ->method('getSystemValue') + ->method('getSystemValueBool') ->with('token_auth_enforced', false) ->willReturn(false); @@ -1057,4 +1058,100 @@ class SessionTest extends \Test\TestCase { $this->userSession->updateTokens('uid', 'pass'); } + + public function testLogClientInThrottlerUsername() { + $manager = $this->createMock(Manager::class); + $session = $this->createMock(ISession::class); + $request = $this->createMock(IRequest::class); + + /** @var Session $userSession */ + $userSession = $this->getMockBuilder(Session::class) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher]) + ->setMethods(['isTokenPassword', 'login', 'supportsCookies', 'createSessionToken', 'getUser']) + ->getMock(); + + $userSession->expects($this->once()) + ->method('isTokenPassword') + ->willReturn(true); + $userSession->expects($this->once()) + ->method('login') + ->with('john', 'I-AM-AN-PASSWORD') + ->willReturn(false); + + $session->expects($this->never()) + ->method('set'); + $request + ->method('getRemoteAddress') + ->willReturn('192.168.0.1'); + $this->throttler + ->expects($this->exactly(2)) + ->method('sleepDelay') + ->with('192.168.0.1'); + $this->throttler + ->expects($this->any()) + ->method('getDelay') + ->with('192.168.0.1') + ->willReturn(0); + + $this->throttler + ->expects($this->once()) + ->method('registerAttempt') + ->with('login', '192.168.0.1', ['user' => 'john']); + $this->dispatcher + ->expects($this->once()) + ->method('dispatchTyped') + ->with(new LoginFailed('john', 'I-AM-AN-PASSWORD')); + + $this->assertFalse($userSession->logClientIn('john', 'I-AM-AN-PASSWORD', $request, $this->throttler)); + } + + public function testLogClientInThrottlerEmail() { + $manager = $this->createMock(Manager::class); + $session = $this->createMock(ISession::class); + $request = $this->createMock(IRequest::class); + + /** @var Session $userSession */ + $userSession = $this->getMockBuilder(Session::class) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher]) + ->setMethods(['isTokenPassword', 'login', 'supportsCookies', 'createSessionToken', 'getUser']) + ->getMock(); + + $userSession->expects($this->once()) + ->method('isTokenPassword') + ->willReturn(true); + $userSession->expects($this->once()) + ->method('login') + ->with('john@foo.bar', 'I-AM-AN-PASSWORD') + ->willReturn(false); + $manager + ->method('getByEmail') + ->with('john@foo.bar') + ->willReturn([]); + + $session->expects($this->never()) + ->method('set'); + $request + ->method('getRemoteAddress') + ->willReturn('192.168.0.1'); + $this->throttler + ->expects($this->exactly(2)) + ->method('sleepDelay') + ->with('192.168.0.1'); + $this->throttler + ->expects($this->any()) + ->method('getDelay') + ->with('192.168.0.1') + ->willReturn(0); + + $this->throttler + ->expects($this->once()) + ->method('registerAttempt') + ->with('login', '192.168.0.1', ['user' => 'john@foo.bar']); + $this->dispatcher + ->expects($this->once()) + ->method('dispatchTyped') + ->with(new LoginFailed('john@foo.bar', 'I-AM-AN-PASSWORD')); + + $this->assertFalse($userSession->logClientIn('john@foo.bar', 'I-AM-AN-PASSWORD', $request, $this->throttler)); + } } diff --git a/tests/lib/User/UserTest.php b/tests/lib/User/UserTest.php index b8fa8efced0..7f4ca97e18b 100644 --- a/tests/lib/User/UserTest.php +++ b/tests/lib/User/UserTest.php @@ -306,7 +306,7 @@ class UserTest extends TestCase { ->method('getUserValue') ->willReturn(true); $allConfig->expects($this->any()) - ->method('getSystemValue') + ->method('getSystemValueString') ->with($this->equalTo('datadirectory')) ->willReturn('arbitrary/path'); @@ -364,7 +364,12 @@ class UserTest extends TestCase { } }); - $user = new User('foo', $backend, $this->dispatcher); + $config = $this->createMock(IConfig::class); + $config->method('getSystemValueBool') + ->with('allow_user_to_change_display_name') + ->willReturn(true); + + $user = new User('foo', $backend, $this->dispatcher, null, $config); $this->assertTrue($user->canChangeDisplayName()); } @@ -534,6 +539,12 @@ class UserTest extends TestCase { $config->method('getSystemValue') ->willReturnArgument(1); + $config->method('getSystemValueString') + ->willReturnArgument(1); + $config->method('getSystemValueBool') + ->willReturnArgument(1); + $config->method('getSystemValueInt') + ->willReturnArgument(1); if ($result) { $config->expects($this->once()) |