diff options
Diffstat (limited to 'apps/settings/tests/Controller')
8 files changed, 453 insertions, 1518 deletions
diff --git a/apps/settings/tests/Controller/AdminSettingsControllerTest.php b/apps/settings/tests/Controller/AdminSettingsControllerTest.php index acdcaa136aa..fbdc506457b 100644 --- a/apps/settings/tests/Controller/AdminSettingsControllerTest.php +++ b/apps/settings/tests/Controller/AdminSettingsControllerTest.php @@ -1,40 +1,24 @@ <?php + /** - * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch> - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Jan C. Borchardt <hey@jancborchardt.net> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * 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 - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Settings\Tests\Controller; use OCA\Settings\Controller\AdminSettingsController; use OCA\Settings\Settings\Personal\ServerDevNotice; use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Services\IInitialState; use OCP\Group\ISubAdmin; use OCP\IGroupManager; use OCP\INavigationManager; use OCP\IRequest; use OCP\IUser; +use OCP\IUserManager; use OCP\IUserSession; +use OCP\Server; +use OCP\Settings\IDeclarativeManager; use OCP\Settings\IManager; use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; @@ -48,22 +32,17 @@ use Test\TestCase; */ class AdminSettingsControllerTest extends TestCase { - /** @var AdminSettingsController */ - private $adminSettingsController; - /** @var IRequest|MockObject */ - private $request; - /** @var INavigationManager|MockObject */ - private $navigationManager; - /** @var IManager|MockObject */ - private $settingsManager; - /** @var IUserSession|MockObject */ - private $userSession; - /** @var IGroupManager|MockObject */ - private $groupManager; - /** @var ISubAdmin|MockObject */ - private $subAdmin; - /** @var string */ - private $adminUid = 'lololo'; + private IRequest&MockObject $request; + private INavigationManager&MockObject $navigationManager; + private IManager&MockObject $settingsManager; + private IUserSession&MockObject $userSession; + private IGroupManager&MockObject $groupManager; + private ISubAdmin&MockObject $subAdmin; + private IDeclarativeManager&MockObject $declarativeSettingsManager; + private IInitialState&MockObject $initialState; + + private string $adminUid = 'lololo'; + private AdminSettingsController $adminSettingsController; protected function setUp(): void { parent::setUp(); @@ -74,6 +53,8 @@ class AdminSettingsControllerTest extends TestCase { $this->userSession = $this->createMock(IUserSession::class); $this->groupManager = $this->createMock(IGroupManager::class); $this->subAdmin = $this->createMock(ISubAdmin::class); + $this->declarativeSettingsManager = $this->createMock(IDeclarativeManager::class); + $this->initialState = $this->createMock(IInitialState::class); $this->adminSettingsController = new AdminSettingsController( 'settings', @@ -82,21 +63,27 @@ class AdminSettingsControllerTest extends TestCase { $this->settingsManager, $this->userSession, $this->groupManager, - $this->subAdmin + $this->subAdmin, + $this->declarativeSettingsManager, + $this->initialState, ); - $user = \OC::$server->getUserManager()->createUser($this->adminUid, 'mylongrandompassword'); + $user = Server::get(IUserManager::class)->createUser($this->adminUid, 'mylongrandompassword'); \OC_User::setUserId($user->getUID()); - \OC::$server->getGroupManager()->createGroup('admin')->addUser($user); + Server::get(IGroupManager::class)->createGroup('admin')->addUser($user); } protected function tearDown(): void { - \OC::$server->getUserManager()->get($this->adminUid)->delete(); + Server::get(IUserManager::class) + ->get($this->adminUid) + ->delete(); + \OC_User::setUserId(null); + Server::get(IUserSession::class)->setUser(null); parent::tearDown(); } - public function testIndex() { + public function testIndex(): void { $user = $this->createMock(IUser::class); $this->userSession ->method('getUser') @@ -110,6 +97,12 @@ class AdminSettingsControllerTest extends TestCase { ->method('isSubAdmin') ->with($user) ->willReturn(false); + + $form = new TemplateResponse('settings', 'settings/empty'); + $setting = $this->createMock(ServerDevNotice::class); + $setting->expects(self::any()) + ->method('getForm') + ->willReturn($form); $this->settingsManager ->expects($this->once()) ->method('getAdminSections') @@ -122,7 +115,12 @@ class AdminSettingsControllerTest extends TestCase { ->expects($this->once()) ->method('getAllowedAdminSettings') ->with('test') - ->willReturn([5 => $this->createMock(ServerDevNotice::class)]); + ->willReturn([5 => [$setting]]); + $this->declarativeSettingsManager + ->expects($this->any()) + ->method('getFormIDs') + ->with($user, 'admin', 'test') + ->willReturn([]); $idx = $this->adminSettingsController->index('test'); diff --git a/apps/settings/tests/Controller/AppSettingsControllerTest.php b/apps/settings/tests/Controller/AppSettingsControllerTest.php index 28d77dc3696..392bb7b561d 100644 --- a/apps/settings/tests/Controller/AppSettingsControllerTest.php +++ b/apps/settings/tests/Controller/AppSettingsControllerTest.php @@ -1,42 +1,25 @@ <?php + /** - * @copyright Copyright (c) 2016, Lukas Reschke <lukas@statuscode.ch> - * @copyright Copyright (c) 2015, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ <skjnldsv@protonmail.com> - * @author Julius Härtl <jus@bitgrid.net> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @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/> - * + * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2015 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Settings\Tests\Controller; +use OC\App\AppManager; use OC\App\AppStore\Bundles\BundleFetcher; +use OC\App\AppStore\Fetcher\AppDiscoverFetcher; use OC\App\AppStore\Fetcher\AppFetcher; use OC\App\AppStore\Fetcher\CategoryFetcher; use OC\Installer; use OCA\Settings\Controller\AppSettingsController; -use OCP\App\IAppManager; use OCP\AppFramework\Http\ContentSecurityPolicy; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Services\IInitialState; +use OCP\Files\AppData\IAppDataFactory; +use OCP\Http\Client\IClientService; use OCP\IConfig; use OCP\IL10N; use OCP\INavigationManager; @@ -55,44 +38,36 @@ use Test\TestCase; * @group DB */ class AppSettingsControllerTest extends TestCase { - /** @var AppSettingsController */ - private $appSettingsController; - /** @var IRequest|MockObject */ - private $request; - /** @var IL10N|MockObject */ - private $l10n; - /** @var IConfig|MockObject */ - private $config; - /** @var INavigationManager|MockObject */ - private $navigationManager; - /** @var IAppManager|MockObject */ - private $appManager; - /** @var CategoryFetcher|MockObject */ - private $categoryFetcher; - /** @var AppFetcher|MockObject */ - private $appFetcher; - /** @var IFactory|MockObject */ - private $l10nFactory; - /** @var BundleFetcher|MockObject */ - private $bundleFetcher; - /** @var Installer|MockObject */ - private $installer; - /** @var IURLGenerator|MockObject */ - private $urlGenerator; - /** @var LoggerInterface|MockObject */ - private $logger; + private IRequest&MockObject $request; + private IL10N&MockObject $l10n; + private IConfig&MockObject $config; + private INavigationManager&MockObject $navigationManager; + private AppManager&MockObject $appManager; + private CategoryFetcher&MockObject $categoryFetcher; + private AppFetcher&MockObject $appFetcher; + private IFactory&MockObject $l10nFactory; + private BundleFetcher&MockObject $bundleFetcher; + private Installer&MockObject $installer; + private IURLGenerator&MockObject $urlGenerator; + private LoggerInterface&MockObject $logger; + private IInitialState&MockObject $initialState; + private IAppDataFactory&MockObject $appDataFactory; + private AppDiscoverFetcher&MockObject $discoverFetcher; + private IClientService&MockObject $clientService; + private AppSettingsController $appSettingsController; protected function setUp(): void { parent::setUp(); $this->request = $this->createMock(IRequest::class); + $this->appDataFactory = $this->createMock(IAppDataFactory::class); $this->l10n = $this->createMock(IL10N::class); $this->l10n->expects($this->any()) ->method('t') ->willReturnArgument(0); $this->config = $this->createMock(IConfig::class); $this->navigationManager = $this->createMock(INavigationManager::class); - $this->appManager = $this->createMock(IAppManager::class); + $this->appManager = $this->createMock(AppManager::class); $this->categoryFetcher = $this->createMock(CategoryFetcher::class); $this->appFetcher = $this->createMock(AppFetcher::class); $this->l10nFactory = $this->createMock(IFactory::class); @@ -100,10 +75,14 @@ class AppSettingsControllerTest extends TestCase { $this->installer = $this->createMock(Installer::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); $this->logger = $this->createMock(LoggerInterface::class); + $this->initialState = $this->createMock(IInitialState::class); + $this->discoverFetcher = $this->createMock(AppDiscoverFetcher::class); + $this->clientService = $this->createMock(IClientService::class); $this->appSettingsController = new AppSettingsController( 'settings', $this->request, + $this->appDataFactory, $this->l10n, $this->config, $this->navigationManager, @@ -114,63 +93,56 @@ class AppSettingsControllerTest extends TestCase { $this->bundleFetcher, $this->installer, $this->urlGenerator, - $this->logger + $this->logger, + $this->initialState, + $this->discoverFetcher, + $this->clientService, ); } - public function testListCategories() { + public function testListCategories(): void { $this->installer->expects($this->any()) ->method('isUpdateAvailable') ->willReturn(false); $expected = new JSONResponse([ [ 'id' => 'auth', - 'ident' => 'auth', 'displayName' => 'Authentication & authorization', ], [ 'id' => 'customization', - 'ident' => 'customization', 'displayName' => 'Customization', ], [ 'id' => 'files', - 'ident' => 'files', 'displayName' => 'Files', ], [ 'id' => 'integration', - 'ident' => 'integration', 'displayName' => 'Integration', ], [ 'id' => 'monitoring', - 'ident' => 'monitoring', 'displayName' => 'Monitoring', ], [ 'id' => 'multimedia', - 'ident' => 'multimedia', 'displayName' => 'Multimedia', ], [ 'id' => 'office', - 'ident' => 'office', 'displayName' => 'Office & text', ], [ 'id' => 'organization', - 'ident' => 'organization', 'displayName' => 'Organization', ], [ 'id' => 'social', - 'ident' => 'social', 'displayName' => 'Social & communication', ], [ 'id' => 'tools', - 'ident' => 'tools', 'displayName' => 'Tools', ], ]); @@ -183,7 +155,7 @@ class AppSettingsControllerTest extends TestCase { $this->assertEquals($expected, $this->appSettingsController->listCategories()); } - public function testViewApps() { + public function testViewApps(): void { $this->bundleFetcher->expects($this->once())->method('getBundles')->willReturn([]); $this->installer->expects($this->any()) ->method('isUpdateAvailable') @@ -198,18 +170,17 @@ class AppSettingsControllerTest extends TestCase { ->method('setActiveEntry') ->with('core_apps'); + $this->initialState + ->expects($this->exactly(4)) + ->method('provideInitialState'); + $policy = new ContentSecurityPolicy(); $policy->addAllowedImageDomain('https://usercontent.apps.nextcloud.com'); $expected = new TemplateResponse('settings', - 'settings-vue', + 'settings/empty', [ - 'serverData' => [ - 'updateCount' => 0, - 'appstoreEnabled' => true, - 'bundles' => [], - 'developerDocumentation' => '' - ] + 'pageTitle' => 'Settings' ], 'user'); $expected->setContentSecurityPolicy($policy); @@ -217,7 +188,7 @@ class AppSettingsControllerTest extends TestCase { $this->assertEquals($expected, $this->appSettingsController->viewApps()); } - public function testViewAppsAppstoreNotEnabled() { + public function testViewAppsAppstoreNotEnabled(): void { $this->installer->expects($this->any()) ->method('isUpdateAvailable') ->willReturn(false); @@ -232,18 +203,17 @@ class AppSettingsControllerTest extends TestCase { ->method('setActiveEntry') ->with('core_apps'); + $this->initialState + ->expects($this->exactly(4)) + ->method('provideInitialState'); + $policy = new ContentSecurityPolicy(); $policy->addAllowedImageDomain('https://usercontent.apps.nextcloud.com'); $expected = new TemplateResponse('settings', - 'settings-vue', + 'settings/empty', [ - 'serverData' => [ - 'updateCount' => 0, - 'appstoreEnabled' => false, - 'bundles' => [], - 'developerDocumentation' => '' - ] + 'pageTitle' => 'Settings' ], 'user'); $expected->setContentSecurityPolicy($policy); diff --git a/apps/settings/tests/Controller/AuthSettingsControllerTest.php b/apps/settings/tests/Controller/AuthSettingsControllerTest.php index b744b942e09..d195dbf83d3 100644 --- a/apps/settings/tests/Controller/AuthSettingsControllerTest.php +++ b/apps/settings/tests/Controller/AuthSettingsControllerTest.php @@ -1,31 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Daniel Kesselberg <mail@danielkesselberg.de> - * @author Fabrizio Steiner <fabrizio.steiner@gmail.com> - * @author Greta Doci <gretadoci@gmail.com> - * @author Joas Schilling <coding@schilljs.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Sergej Nikolaev <kinolaev@gmail.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/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace Test\Settings\Controller; @@ -51,24 +29,15 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class AuthSettingsControllerTest extends TestCase { - - /** @var AuthSettingsController */ - private $controller; - /** @var IRequest|MockObject */ - private $request; - /** @var IProvider|MockObject */ - private $tokenProvider; - /** @var ISession|MockObject */ - private $session; - /**@var IUserSession|MockObject */ - private $userSession; - /** @var ISecureRandom|MockObject */ - private $secureRandom; - /** @var IManager|MockObject */ - private $activityManager; - /** @var RemoteWipe|MockObject */ - private $remoteWipe; - private $uid = 'jane'; + private IRequest&MockObject $request; + private IProvider&MockObject $tokenProvider; + private ISession&MockObject $session; + private IUserSession&MockObject $userSession; + private ISecureRandom&MockObject $secureRandom; + private IManager&MockObject $activityManager; + private RemoteWipe&MockObject $remoteWipe; + private string $uid = 'jane'; + private AuthSettingsController $controller; protected function setUp(): void { parent::setUp(); @@ -80,7 +49,7 @@ class AuthSettingsControllerTest extends TestCase { $this->secureRandom = $this->createMock(ISecureRandom::class); $this->activityManager = $this->createMock(IManager::class); $this->remoteWipe = $this->createMock(RemoteWipe::class); - /** @var LoggerInterface|MockObject $logger */ + /** @var LoggerInterface&MockObject $logger */ $logger = $this->createMock(LoggerInterface::class); $this->controller = new AuthSettingsController( @@ -97,7 +66,7 @@ class AuthSettingsControllerTest extends TestCase { ); } - public function testCreate() { + public function testCreate(): void { $name = 'Nexus 4'; $sessionToken = $this->createMock(IToken::class); $deviceToken = $this->createMock(IToken::class); @@ -146,12 +115,12 @@ class AuthSettingsControllerTest extends TestCase { $this->assertEquals($expected, $response->getData()); } - public function testCreateSessionNotAvailable() { + public function testCreateSessionNotAvailable(): void { $name = 'personal phone'; $this->session->expects($this->once()) ->method('getId') - ->will($this->throwException(new SessionNotAvailableException())); + ->willThrowException(new SessionNotAvailableException()); $expected = new JSONResponse(); $expected->setStatus(Http::STATUS_SERVICE_UNAVAILABLE); @@ -159,7 +128,7 @@ class AuthSettingsControllerTest extends TestCase { $this->assertEquals($expected, $this->controller->create($name)); } - public function testCreateInvalidToken() { + public function testCreateInvalidToken(): void { $name = 'Company IPhone'; $this->session->expects($this->once()) @@ -168,7 +137,7 @@ class AuthSettingsControllerTest extends TestCase { $this->tokenProvider->expects($this->once()) ->method('getToken') ->with('sessionid') - ->will($this->throwException(new InvalidTokenException())); + ->willThrowException(new InvalidTokenException()); $expected = new JSONResponse(); $expected->setStatus(Http::STATUS_SERVICE_UNAVAILABLE); @@ -176,7 +145,7 @@ class AuthSettingsControllerTest extends TestCase { $this->assertEquals($expected, $this->controller->create($name)); } - public function testDestroy() { + public function testDestroy(): void { $tokenId = 124; $token = $this->createMock(PublicKeyToken::class); @@ -198,7 +167,7 @@ class AuthSettingsControllerTest extends TestCase { $this->assertEquals([], $this->controller->destroy($tokenId)); } - public function testDestroyExpired() { + public function testDestroyExpired(): void { $tokenId = 124; $token = $this->createMock(PublicKeyToken::class); @@ -222,7 +191,7 @@ class AuthSettingsControllerTest extends TestCase { $this->assertSame([], $this->controller->destroy($tokenId)); } - public function testDestroyWrongUser() { + public function testDestroyWrongUser(): void { $tokenId = 124; $token = $this->createMock(PublicKeyToken::class); @@ -237,19 +206,14 @@ class AuthSettingsControllerTest extends TestCase { $this->assertSame(\OCP\AppFramework\Http::STATUS_NOT_FOUND, $response->getStatus()); } - public function dataRenameToken(): array { + public static function dataRenameToken(): array { return [ 'App password => Other token name' => ['App password', 'Other token name'], 'Other token name => App password' => ['Other token name', 'App password'], ]; } - /** - * @dataProvider dataRenameToken - * - * @param string $name - * @param string $newName - */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataRenameToken')] public function testUpdateRename(string $name, string $newName): void { $tokenId = 42; $token = $this->createMock(PublicKeyToken::class); @@ -267,7 +231,7 @@ class AuthSettingsControllerTest extends TestCase { $token->expects($this->once()) ->method('getScopeAsArray') - ->willReturn(['filesystem' => true]); + ->willReturn([IToken::SCOPE_FILESYSTEM => true]); $token->expects($this->once()) ->method('setName') @@ -277,22 +241,17 @@ class AuthSettingsControllerTest extends TestCase { ->method('updateToken') ->with($this->equalTo($token)); - $this->assertSame([], $this->controller->update($tokenId, ['filesystem' => true], $newName)); + $this->assertSame([], $this->controller->update($tokenId, [IToken::SCOPE_FILESYSTEM => true], $newName)); } - public function dataUpdateFilesystemScope(): array { + public static function dataUpdateFilesystemScope(): array { return [ 'Grant filesystem access' => [false, true], 'Revoke filesystem access' => [true, false], ]; } - /** - * @dataProvider dataUpdateFilesystemScope - * - * @param bool $filesystem - * @param bool $newFilesystem - */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataUpdateFilesystemScope')] public function testUpdateFilesystemScope(bool $filesystem, bool $newFilesystem): void { $tokenId = 42; $token = $this->createMock(PublicKeyToken::class); @@ -310,17 +269,17 @@ class AuthSettingsControllerTest extends TestCase { $token->expects($this->once()) ->method('getScopeAsArray') - ->willReturn(['filesystem' => $filesystem]); + ->willReturn([IToken::SCOPE_FILESYSTEM => $filesystem]); $token->expects($this->once()) ->method('setScope') - ->with($this->equalTo(['filesystem' => $newFilesystem])); + ->with($this->equalTo([IToken::SCOPE_FILESYSTEM => $newFilesystem])); $this->tokenProvider->expects($this->once()) ->method('updateToken') ->with($this->equalTo($token)); - $this->assertSame([], $this->controller->update($tokenId, ['filesystem' => $newFilesystem], 'App password')); + $this->assertSame([], $this->controller->update($tokenId, [IToken::SCOPE_FILESYSTEM => $newFilesystem], 'App password')); } public function testUpdateNoChange(): void { @@ -339,7 +298,7 @@ class AuthSettingsControllerTest extends TestCase { $token->expects($this->once()) ->method('getScopeAsArray') - ->willReturn(['filesystem' => true]); + ->willReturn([IToken::SCOPE_FILESYSTEM => true]); $token->expects($this->never()) ->method('setName'); @@ -351,10 +310,10 @@ class AuthSettingsControllerTest extends TestCase { ->method('updateToken') ->with($this->equalTo($token)); - $this->assertSame([], $this->controller->update($tokenId, ['filesystem' => true], 'App password')); + $this->assertSame([], $this->controller->update($tokenId, [IToken::SCOPE_FILESYSTEM => true], 'App password')); } - public function testUpdateExpired() { + public function testUpdateExpired(): void { $tokenId = 42; $token = $this->createMock(PublicKeyToken::class); @@ -371,10 +330,10 @@ class AuthSettingsControllerTest extends TestCase { ->method('updateToken') ->with($this->equalTo($token)); - $this->assertSame([], $this->controller->update($tokenId, ['filesystem' => true], 'App password')); + $this->assertSame([], $this->controller->update($tokenId, [IToken::SCOPE_FILESYSTEM => true], 'App password')); } - public function testUpdateTokenWrongUser() { + public function testUpdateTokenWrongUser(): void { $tokenId = 42; $token = $this->createMock(PublicKeyToken::class); @@ -389,12 +348,12 @@ class AuthSettingsControllerTest extends TestCase { $this->tokenProvider->expects($this->never()) ->method('updateToken'); - $response = $this->controller->update($tokenId, ['filesystem' => true], 'App password'); + $response = $this->controller->update($tokenId, [IToken::SCOPE_FILESYSTEM => true], 'App password'); $this->assertSame([], $response->getData()); $this->assertSame(\OCP\AppFramework\Http::STATUS_NOT_FOUND, $response->getStatus()); } - public function testUpdateTokenNonExisting() { + public function testUpdateTokenNonExisting(): void { $this->tokenProvider->expects($this->once()) ->method('getTokenById') ->with($this->equalTo(42)) @@ -403,7 +362,7 @@ class AuthSettingsControllerTest extends TestCase { $this->tokenProvider->expects($this->never()) ->method('updateToken'); - $response = $this->controller->update(42, ['filesystem' => true], 'App password'); + $response = $this->controller->update(42, [IToken::SCOPE_FILESYSTEM => true], 'App password'); $this->assertSame([], $response->getData()); $this->assertSame(\OCP\AppFramework\Http::STATUS_NOT_FOUND, $response->getStatus()); } diff --git a/apps/settings/tests/Controller/CheckSetupControllerTest.php b/apps/settings/tests/Controller/CheckSetupControllerTest.php index b7dd96ae653..a8e89260573 100644 --- a/apps/settings/tests/Controller/CheckSetupControllerTest.php +++ b/apps/settings/tests/Controller/CheckSetupControllerTest.php @@ -1,67 +1,25 @@ <?php + /** - * @copyright Copyright (c) 2015, ownCloud, Inc. - * - * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Daniel Kesselberg <mail@danielkesselberg.de> - * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ <skjnldsv@protonmail.com> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Michael Weimann <mail@michael-weimann.eu> - * @author Morris Jobke <hey@morrisjobke.de> - * @author nhirokinet <nhirokinet@nhiroki.net> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Sylvia van Os <sylvia@hackerchick.me> - * @author Timo Förster <tfoerster@webfoersterei.de> - * - * @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/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2015 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Settings\Tests\Controller; -use bantu\IniGetWrapper\IniGetWrapper; -use Doctrine\DBAL\Platforms\SqlitePlatform; -use OC; -use OC\DB\Connection; use OC\IntegrityCheck\Checker; -use OC\MemoryInfo; -use OC\Security\SecureRandom; use OCA\Settings\Controller\CheckSetupController; -use OCP\App\IAppManager; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataDisplayResponse; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\RedirectResponse; -use OCP\Http\Client\IClientService; use OCP\IConfig; -use OCP\IDateTimeFormatter; -use OCP\IDBConnection; use OCP\IL10N; use OCP\IRequest; -use OCP\IServerContainer; -use OCP\ITempManager; use OCP\IURLGenerator; -use OCP\Lock\ILockingProvider; -use OCP\Notification\IManager; +use OCP\SetupCheck\ISetupCheckManager; use PHPUnit\Framework\MockObject\MockObject; -use Psr\Http\Message\ResponseInterface; use Psr\Log\LoggerInterface; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Test\TestCase; /** @@ -71,514 +29,60 @@ use Test\TestCase; * @package Tests\Settings\Controller */ class CheckSetupControllerTest extends TestCase { - /** @var CheckSetupController | \PHPUnit\Framework\MockObject\MockObject */ - private $checkSetupController; - /** @var IRequest | \PHPUnit\Framework\MockObject\MockObject */ - private $request; - /** @var IConfig | \PHPUnit\Framework\MockObject\MockObject */ - private $config; - /** @var IClientService | \PHPUnit\Framework\MockObject\MockObject*/ - private $clientService; - /** @var IURLGenerator | \PHPUnit\Framework\MockObject\MockObject */ - private $urlGenerator; - /** @var IL10N | \PHPUnit\Framework\MockObject\MockObject */ - private $l10n; - /** @var LoggerInterface */ - private $logger; - /** @var Checker|\PHPUnit\Framework\MockObject\MockObject */ - private $checker; - /** @var EventDispatcherInterface|\PHPUnit\Framework\MockObject\MockObject */ - private $dispatcher; - /** @var Connection|\PHPUnit\Framework\MockObject\MockObject */ - private $db; - /** @var ILockingProvider|\PHPUnit\Framework\MockObject\MockObject */ - private $lockingProvider; - /** @var IDateTimeFormatter|\PHPUnit\Framework\MockObject\MockObject */ - private $dateTimeFormatter; - /** @var MemoryInfo|MockObject */ - private $memoryInfo; - /** @var SecureRandom|\PHPUnit\Framework\MockObject\MockObject */ - private $secureRandom; - /** @var IniGetWrapper|\PHPUnit\Framework\MockObject\MockObject */ - private $iniGetWrapper; - /** @var IDBConnection|\PHPUnit\Framework\MockObject\MockObject */ - private $connection; - /** @var ITempManager|\PHPUnit\Framework\MockObject\MockObject */ - private $tempManager; - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ - private $notificationManager; - /** @var IAppManager|MockObject */ - private $appManager; - /** @var IServerContainer|MockObject */ - private $serverContainer; - - /** - * Holds a list of directories created during tests. - * - * @var array - */ - private $dirsToRemove = []; + private IRequest&MockObject $request; + private IConfig&MockObject $config; + private IURLGenerator&MockObject $urlGenerator; + private IL10N&MockObject $l10n; + private LoggerInterface&MockObject $logger; + private Checker&MockObject $checker; + private ISetupCheckManager&MockObject $setupCheckManager; + private CheckSetupController $checkSetupController; protected function setUp(): void { parent::setUp(); - $this->request = $this->getMockBuilder(IRequest::class) - ->disableOriginalConstructor()->getMock(); - $this->config = $this->getMockBuilder(IConfig::class) - ->disableOriginalConstructor()->getMock(); - $this->clientService = $this->getMockBuilder(IClientService::class) - ->disableOriginalConstructor()->getMock(); - $this->urlGenerator = $this->getMockBuilder(IURLGenerator::class) - ->disableOriginalConstructor()->getMock(); - $this->l10n = $this->getMockBuilder(IL10N::class) - ->disableOriginalConstructor()->getMock(); + $this->request = $this->createMock(IRequest::class); + $this->config = $this->createMock(IConfig::class); + $this->urlGenerator = $this->createMock(IURLGenerator::class); + $this->l10n = $this->createMock(IL10N::class); $this->l10n->expects($this->any()) ->method('t') ->willReturnCallback(function ($message, array $replace) { return vsprintf($message, $replace); }); - $this->dispatcher = $this->getMockBuilder(EventDispatcherInterface::class) - ->disableOriginalConstructor()->getMock(); - $this->checker = $this->getMockBuilder('\OC\IntegrityCheck\Checker') - ->disableOriginalConstructor()->getMock(); - $this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock(); - $this->db = $this->getMockBuilder(Connection::class) - ->disableOriginalConstructor()->getMock(); - $this->lockingProvider = $this->getMockBuilder(ILockingProvider::class)->getMock(); - $this->dateTimeFormatter = $this->getMockBuilder(IDateTimeFormatter::class)->getMock(); - $this->memoryInfo = $this->getMockBuilder(MemoryInfo::class) - ->setMethods(['isMemoryLimitSufficient',]) - ->getMock(); - $this->secureRandom = $this->getMockBuilder(SecureRandom::class)->getMock(); - $this->iniGetWrapper = $this->getMockBuilder(IniGetWrapper::class)->getMock(); - $this->connection = $this->getMockBuilder(IDBConnection::class) - ->disableOriginalConstructor()->getMock(); - $this->tempManager = $this->getMockBuilder(ITempManager::class)->getMock(); - $this->notificationManager = $this->getMockBuilder(IManager::class)->getMock(); - $this->appManager = $this->createMock(IAppManager::class); - $this->serverContainer = $this->createMock(IServerContainer::class); - $this->checkSetupController = $this->getMockBuilder(CheckSetupController::class) - ->setConstructorArgs([ - 'settings', - $this->request, - $this->config, - $this->clientService, - $this->urlGenerator, - $this->l10n, - $this->checker, - $this->logger, - $this->dispatcher, - $this->db, - $this->lockingProvider, - $this->dateTimeFormatter, - $this->memoryInfo, - $this->secureRandom, - $this->iniGetWrapper, - $this->connection, - $this->tempManager, - $this->notificationManager, - $this->appManager, - $this->serverContainer, - ]) - ->setMethods([ - 'isReadOnlyConfig', - 'wasEmailTestSuccessful', - 'hasValidTransactionIsolationLevel', - 'hasFileinfoInstalled', - 'hasWorkingFileLocking', - 'getLastCronInfo', - 'getSuggestedOverwriteCliURL', - 'getCurlVersion', - 'isPhpOutdated', - 'getOpcacheSetupRecommendations', - 'hasFreeTypeSupport', - 'hasMissingIndexes', - 'hasMissingPrimaryKeys', - 'isSqliteUsed', - 'isPHPMailerUsed', - 'getAppDirsWithDifferentOwner', - 'isImagickEnabled', - 'areWebauthnExtensionsEnabled', - 'hasRecommendedPHPModules', - 'hasBigIntConversionPendingColumns', - 'isMysqlUsedWithoutUTF8MB4', - 'isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed', - ])->getMock(); - } - - /** - * Removes directories created during tests. - * - * @after - * @return void - */ - public function removeTestDirectories() { - foreach ($this->dirsToRemove as $dirToRemove) { - rmdir($dirToRemove); - } - $this->dirsToRemove = []; - } - - public function testIsInternetConnectionWorkingDisabledViaConfig() { - $this->config->expects($this->once()) - ->method('getSystemValue') - ->with('has_internet_connection', true) - ->willReturn(false); - - $this->assertFalse( - self::invokePrivate( - $this->checkSetupController, - 'hasInternetConnectivityProblems' - ) - ); - } - - public function testIsInternetConnectionWorkingCorrectly() { - $this->config->expects($this->at(0)) - ->method('getSystemValue') - ->with('has_internet_connection', true) - ->willReturn(true); - - $this->config->expects($this->at(1)) - ->method('getSystemValue') - ->with('connectivity_check_domains', ['www.nextcloud.com', 'www.startpage.com', 'www.eff.org', 'www.edri.org']) - ->willReturn(['www.nextcloud.com', 'www.startpage.com', 'www.eff.org', 'www.edri.org']); - - $client = $this->getMockBuilder('\OCP\Http\Client\IClient') - ->disableOriginalConstructor()->getMock(); - $client->expects($this->any()) - ->method('get'); - - $this->clientService->expects($this->once()) - ->method('newClient') - ->willReturn($client); - - - $this->assertFalse( - self::invokePrivate( - $this->checkSetupController, - 'hasInternetConnectivityProblems' - ) - ); - } - - public function testIsInternetConnectionFail() { - $this->config->expects($this->at(0)) - ->method('getSystemValue') - ->with('has_internet_connection', true) - ->willReturn(true); - - $this->config->expects($this->at(1)) - ->method('getSystemValue') - ->with('connectivity_check_domains', ['www.nextcloud.com', 'www.startpage.com', 'www.eff.org', 'www.edri.org']) - ->willReturn(['www.nextcloud.com', 'www.startpage.com', 'www.eff.org', 'www.edri.org']); - - $client = $this->getMockBuilder('\OCP\Http\Client\IClient') - ->disableOriginalConstructor()->getMock(); - $client->expects($this->any()) - ->method('get') - ->will($this->throwException(new \Exception())); - - $this->clientService->expects($this->exactly(4)) - ->method('newClient') - ->willReturn($client); - - $this->assertTrue( - self::invokePrivate( - $this->checkSetupController, - 'hasInternetConnectivityProblems' - ) - ); - } - - - public function testIsMemcacheConfiguredFalse() { - $this->config->expects($this->once()) - ->method('getSystemValue') - ->with('memcache.local', null) - ->willReturn(null); - - $this->assertFalse( - self::invokePrivate( - $this->checkSetupController, - 'isMemcacheConfigured' - ) - ); - } - - public function testIsMemcacheConfiguredTrue() { - $this->config->expects($this->once()) - ->method('getSystemValue') - ->with('memcache.local', null) - ->willReturn('SomeProvider'); - - $this->assertTrue( - self::invokePrivate( - $this->checkSetupController, - 'isMemcacheConfigured' - ) - ); - } - - public function testIsPhpSupportedFalse() { - $this->checkSetupController - ->expects($this->once()) - ->method('isPhpOutdated') - ->willReturn(true); - - $this->assertEquals( - ['eol' => true, 'version' => PHP_VERSION], - self::invokePrivate($this->checkSetupController, 'isPhpSupported') - ); - } - - public function testIsPhpSupportedTrue() { - $this->checkSetupController - ->expects($this->exactly(2)) - ->method('isPhpOutdated') - ->willReturn(false); - - $this->assertEquals( - ['eol' => false, 'version' => PHP_VERSION], - self::invokePrivate($this->checkSetupController, 'isPhpSupported') - ); - - - $this->assertEquals( - ['eol' => false, 'version' => PHP_VERSION], - self::invokePrivate($this->checkSetupController, 'isPhpSupported') - ); - } - - /** - * @dataProvider dataForwardedForHeadersWorking - * - * @param array $trustedProxies - * @param string $remoteAddrNotForwarded - * @param string $remoteAddr - * @param bool $result - */ - public function testForwardedForHeadersWorking(array $trustedProxies, string $remoteAddrNotForwarded, string $remoteAddr, bool $result): void { - $this->config->expects($this->once()) - ->method('getSystemValue') - ->with('trusted_proxies', []) - ->willReturn($trustedProxies); - $this->request->expects($this->atLeastOnce()) - ->method('getHeader') - ->willReturnMap([ - ['REMOTE_ADDR', $remoteAddrNotForwarded], - ['X-Forwarded-Host', ''] - ]); - $this->request->expects($this->any()) - ->method('getRemoteAddress') - ->willReturn($remoteAddr); - - $this->assertEquals( - $result, - self::invokePrivate($this->checkSetupController, 'forwardedForHeadersWorking') - ); - } - - public function dataForwardedForHeadersWorking(): array { - return [ - // description => trusted proxies, getHeader('REMOTE_ADDR'), getRemoteAddr, expected result - 'no trusted proxies' => [[], '2.2.2.2', '2.2.2.2', true], - 'trusted proxy, remote addr not trusted proxy' => [['1.1.1.1'], '2.2.2.2', '2.2.2.2', true], - 'trusted proxy, remote addr is trusted proxy, x-forwarded-for working' => [['1.1.1.1'], '1.1.1.1', '2.2.2.2', true], - 'trusted proxy, remote addr is trusted proxy, x-forwarded-for not set' => [['1.1.1.1'], '1.1.1.1', '1.1.1.1', false], - ]; - } - - public function testForwardedHostPresentButTrustedProxiesNotAnArray(): void { - $this->config->expects($this->once()) - ->method('getSystemValue') - ->with('trusted_proxies', []) - ->willReturn('1.1.1.1'); - $this->request->expects($this->atLeastOnce()) - ->method('getHeader') - ->willReturnMap([ - ['REMOTE_ADDR', '1.1.1.1'], - ['X-Forwarded-Host', 'nextcloud.test'] - ]); - $this->request->expects($this->any()) - ->method('getRemoteAddress') - ->willReturn('1.1.1.1'); - - $this->assertEquals( - false, - self::invokePrivate($this->checkSetupController, 'forwardedForHeadersWorking') + $this->checker = $this->createMock(Checker::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->setupCheckManager = $this->createMock(ISetupCheckManager::class); + $this->checkSetupController = new CheckSetupController( + 'settings', + $this->request, + $this->config, + $this->urlGenerator, + $this->l10n, + $this->checker, + $this->logger, + $this->setupCheckManager, ); } - public function testForwardedHostPresentButTrustedProxiesEmpty(): void { - $this->config->expects($this->once()) - ->method('getSystemValue') - ->with('trusted_proxies', []) - ->willReturn([]); - $this->request->expects($this->atLeastOnce()) - ->method('getHeader') + public function testCheck(): void { + $this->config->expects($this->any()) + ->method('getAppValue') ->willReturnMap([ - ['REMOTE_ADDR', '1.1.1.1'], - ['X-Forwarded-Host', 'nextcloud.test'] + ['files_external', 'user_certificate_scan', '', '["a", "b"]'], + ['dav', 'needs_system_address_book_sync', 'no', 'no'], ]); - $this->request->expects($this->any()) - ->method('getRemoteAddress') - ->willReturn('1.1.1.1'); - - $this->assertEquals( - false, - self::invokePrivate($this->checkSetupController, 'forwardedForHeadersWorking') - ); - } - - public function testCheck() { - $this->config->expects($this->at(0)) - ->method('getAppValue') - ->with('files_external', 'user_certificate_scan', false) - ->willReturn('["a", "b"]'); - $this->config->expects($this->at(1)) - ->method('getAppValue') - ->with('core', 'cronErrors') - ->willReturn(''); - $this->config->expects($this->at(3)) - ->method('getSystemValue') - ->with('connectivity_check_domains', ['www.nextcloud.com', 'www.startpage.com', 'www.eff.org', 'www.edri.org']) - ->willReturn(['www.nextcloud.com', 'www.startpage.com', 'www.eff.org', 'www.edri.org']); - $this->config->expects($this->at(4)) - ->method('getSystemValue') - ->with('memcache.local', null) - ->willReturn('SomeProvider'); - $this->config->expects($this->at(5)) - ->method('getSystemValue') - ->with('has_internet_connection', true) - ->willReturn(true); - $this->config->expects($this->at(6)) + $this->config->expects($this->any()) ->method('getSystemValue') - ->with('appstoreenabled', true) - ->willReturn(false); - - $this->request->expects($this->atLeastOnce()) - ->method('getHeader') ->willReturnMap([ - ['REMOTE_ADDR', '4.3.2.1'], - ['X-Forwarded-Host', ''] + ['connectivity_check_domains', ['www.nextcloud.com', 'www.startpage.com', 'www.eff.org', 'www.edri.org'], ['www.nextcloud.com', 'www.startpage.com', 'www.eff.org', 'www.edri.org']], + ['memcache.local', null, 'SomeProvider'], + ['has_internet_connection', true, true], + ['appstoreenabled', true, false], ]); - $client = $this->getMockBuilder('\OCP\Http\Client\IClient') - ->disableOriginalConstructor()->getMock(); - $client->expects($this->at(0)) - ->method('get') - ->with('http://www.nextcloud.com/', []) - ->will($this->throwException(new \Exception())); - $client->expects($this->at(1)) - ->method('get') - ->with('http://www.startpage.com/', []) - ->will($this->throwException(new \Exception())); - $client->expects($this->at(2)) - ->method('get') - ->with('http://www.eff.org/', []) - ->will($this->throwException(new \Exception())); - $client->expects($this->at(3)) - ->method('get') - ->with('http://www.edri.org/', []) - ->will($this->throwException(new \Exception())); - $this->clientService->expects($this->exactly(4)) - ->method('newClient') - ->willReturn($client); - $this->checkSetupController - ->expects($this->once()) - ->method('isPhpOutdated') - ->willReturn(true); - $this->checkSetupController - ->expects($this->once()) - ->method('getOpcacheSetupRecommendations') - ->willReturn(['recommendation1', 'recommendation2']); - $this->checkSetupController - ->method('hasFreeTypeSupport') - ->willReturn(false); - $this->checkSetupController - ->method('hasMissingIndexes') - ->willReturn([]); - $this->checkSetupController - ->method('hasMissingPrimaryKeys') - ->willReturn([]); - $this->checkSetupController - ->method('isSqliteUsed') - ->willReturn(false); - $this->checkSetupController - ->expects($this->once()) - ->method('isReadOnlyConfig') - ->willReturn(false); - $this->checkSetupController - ->expects($this->once()) - ->method('wasEmailTestSuccessful') - ->willReturn(false); - $this->checkSetupController - ->expects($this->once()) - ->method('hasValidTransactionIsolationLevel') - ->willReturn(true); - $this->checkSetupController - ->expects($this->once()) - ->method('hasFileinfoInstalled') - ->willReturn(true); - $this->checkSetupController - ->expects($this->once()) - ->method('hasWorkingFileLocking') - ->willReturn(true); - $this->checkSetupController - ->expects($this->once()) - ->method('getSuggestedOverwriteCliURL') - ->willReturn(''); - $this->checkSetupController - ->expects($this->once()) - ->method('getLastCronInfo') - ->willReturn([ - 'diffInSeconds' => 123, - 'relativeTime' => '2 hours ago', - 'backgroundJobsUrl' => 'https://example.org', - ]); - $this->checker - ->expects($this->once()) - ->method('hasPassedCheck') - ->willReturn(true); - $this->memoryInfo - ->method('isMemoryLimitSufficient') - ->willReturn(true); - - $this->checkSetupController - ->expects($this->once()) - ->method('getAppDirsWithDifferentOwner') - ->willReturn([]); - - $this->checkSetupController - ->expects($this->once()) - ->method('isImagickEnabled') - ->willReturn(false); - - $this->checkSetupController - ->expects($this->once()) - ->method('areWebauthnExtensionsEnabled') - ->willReturn(false); - - $this->checkSetupController - ->expects($this->once()) - ->method('hasRecommendedPHPModules') - ->willReturn([]); - - $this->checkSetupController - ->expects($this->once()) - ->method('hasBigIntConversionPendingColumns') - ->willReturn([]); - - $this->checkSetupController - ->expects($this->once()) - ->method('isMysqlUsedWithoutUTF8MB4') - ->willReturn(false); - - $this->checkSetupController - ->expects($this->once()) - ->method('isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed') - ->willReturn(true); + $this->request->expects($this->never()) + ->method('getHeader'); $this->urlGenerator->method('linkToDocs') ->willReturnCallback(function (string $key): string { @@ -610,365 +114,16 @@ class CheckSetupControllerTest extends TestCase { } return ''; }); - $sqlitePlatform = $this->getMockBuilder(SqlitePlatform::class)->getMock(); - $this->connection->method('getDatabasePlatform') - ->willReturn($sqlitePlatform); $expected = new DataResponse( [ - 'isGetenvServerWorking' => true, - 'isReadOnlyConfig' => false, - 'wasEmailTestSuccessful' => false, - 'hasValidTransactionIsolationLevel' => true, - 'hasFileinfoInstalled' => true, - 'hasWorkingFileLocking' => true, - 'suggestedOverwriteCliURL' => '', - 'cronInfo' => [ - 'diffInSeconds' => 123, - 'relativeTime' => '2 hours ago', - 'backgroundJobsUrl' => 'https://example.org', - ], - 'cronErrors' => [], - 'serverHasInternetConnectionProblems' => true, - 'isMemcacheConfigured' => true, - 'memcacheDocs' => 'http://docs.example.org/server/go.php?to=admin-performance', - 'isRandomnessSecure' => self::invokePrivate($this->checkSetupController, 'isRandomnessSecure'), - 'securityDocs' => 'https://docs.example.org/server/8.1/admin_manual/configuration_server/hardening.html', - 'isUsedTlsLibOutdated' => '', - 'phpSupported' => [ - 'eol' => true, - 'version' => PHP_VERSION - ], - 'forwardedForHeadersWorking' => false, - 'reverseProxyDocs' => 'reverse-proxy-doc-link', - 'isCorrectMemcachedPHPModuleInstalled' => true, - 'hasPassedCodeIntegrityCheck' => true, - 'codeIntegrityCheckerDocumentation' => 'http://docs.example.org/server/go.php?to=admin-code-integrity', - 'OpcacheSetupRecommendations' => ['recommendation1', 'recommendation2'], - 'isSettimelimitAvailable' => true, - 'hasFreeTypeSupport' => false, - 'isSqliteUsed' => false, - 'databaseConversionDocumentation' => 'http://docs.example.org/server/go.php?to=admin-db-conversion', - 'missingIndexes' => [], - 'missingPrimaryKeys' => [], - 'missingColumns' => [], - 'isMemoryLimitSufficient' => true, - 'appDirsWithDifferentOwner' => [], - 'isImagickEnabled' => false, - 'areWebauthnExtensionsEnabled' => false, - 'recommendedPHPModules' => [], - 'pendingBigIntConversionColumns' => [], - 'isMysqlUsedWithoutUTF8MB4' => false, - 'isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed' => true, - 'reverseProxyGeneratedURL' => 'https://server/index.php', - 'OCA\Settings\SetupChecks\PhpDefaultCharset' => ['pass' => true, 'description' => 'PHP configuration option default_charset should be UTF-8', 'severity' => 'warning'], - 'OCA\Settings\SetupChecks\PhpOutputBuffering' => ['pass' => true, 'description' => 'PHP configuration option output_buffering must be disabled', 'severity' => 'error'], - 'OCA\Settings\SetupChecks\LegacySSEKeyFormat' => ['pass' => true, 'description' => 'The old server-side-encryption format is enabled. We recommend disabling this.', 'severity' => 'warning', 'linkToDocumentation' => ''], - 'OCA\Settings\SetupChecks\CheckUserCertificates' => ['pass' => false, 'description' => 'There are some user imported SSL certificates present, that are not used anymore with Nextcloud 21. They can be imported on the command line via "occ security:certificates:import" command. Their paths inside the data directory are shown below.', 'severity' => 'warning', 'elements' => ['a', 'b']], - 'imageMagickLacksSVGSupport' => false, - 'isDefaultPhoneRegionSet' => false, - 'OCA\Settings\SetupChecks\SupportedDatabase' => ['pass' => true, 'description' => '', 'severity' => 'info'], - 'isFairUseOfFreePushService' => false, - 'temporaryDirectoryWritable' => false, - \OCA\Settings\SetupChecks\LdapInvalidUuids::class => ['pass' => true, 'description' => 'Invalid UUIDs of LDAP users or groups have been found. Please review your "Override UUID detection" settings in the Expert part of the LDAP configuration and use "occ ldap:update-uuid" to update them.', 'severity' => 'warning'], + 'generic' => [], ] ); $this->assertEquals($expected, $this->checkSetupController->check()); } - public function testGetCurlVersion() { - $checkSetupController = $this->getMockBuilder(CheckSetupController::class) - ->setConstructorArgs([ - 'settings', - $this->request, - $this->config, - $this->clientService, - $this->urlGenerator, - $this->l10n, - $this->checker, - $this->logger, - $this->dispatcher, - $this->db, - $this->lockingProvider, - $this->dateTimeFormatter, - $this->memoryInfo, - $this->secureRandom, - $this->iniGetWrapper, - $this->connection, - $this->tempManager, - $this->notificationManager, - $this->appManager, - $this->serverContainer - ]) - ->setMethods(null)->getMock(); - - $this->assertArrayHasKey('ssl_version', $this->invokePrivate($checkSetupController, 'getCurlVersion')); - } - - public function testIsUsedTlsLibOutdatedWithAnotherLibrary() { - $this->config->expects($this->any()) - ->method('getSystemValue') - ->willReturn(true); - $this->checkSetupController - ->expects($this->once()) - ->method('getCurlVersion') - ->willReturn(['ssl_version' => 'SSLlib']); - $this->assertSame('', $this->invokePrivate($this->checkSetupController, 'isUsedTlsLibOutdated')); - } - - public function testIsUsedTlsLibOutdatedWithMisbehavingCurl() { - $this->config->expects($this->any()) - ->method('getSystemValue') - ->willReturn(true); - $this->checkSetupController - ->expects($this->once()) - ->method('getCurlVersion') - ->willReturn([]); - $this->assertSame('', $this->invokePrivate($this->checkSetupController, 'isUsedTlsLibOutdated')); - } - - public function testIsUsedTlsLibOutdatedWithOlderOpenSsl() { - $this->config->expects($this->any()) - ->method('getSystemValue') - ->willReturn(true); - $this->checkSetupController - ->expects($this->once()) - ->method('getCurlVersion') - ->willReturn(['ssl_version' => 'OpenSSL/1.0.1c']); - $this->assertSame('cURL is using an outdated OpenSSL version (OpenSSL/1.0.1c). Please update your operating system or features such as installing and updating apps via the App Store or Federated Cloud Sharing will not work reliably.', $this->invokePrivate($this->checkSetupController, 'isUsedTlsLibOutdated')); - } - - public function testIsUsedTlsLibOutdatedWithOlderOpenSslAndWithoutAppstore() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('has_internet_connection', true) - ->willReturn(true); - $this->checkSetupController - ->expects($this->once()) - ->method('getCurlVersion') - ->willReturn(['ssl_version' => 'OpenSSL/1.0.1c']); - $this->assertSame('cURL is using an outdated OpenSSL version (OpenSSL/1.0.1c). Please update your operating system or features such as Federated Cloud Sharing will not work reliably.', $this->invokePrivate($this->checkSetupController, 'isUsedTlsLibOutdated')); - } - - public function testIsUsedTlsLibOutdatedWithOlderOpenSsl1() { - $this->config->expects($this->any()) - ->method('getSystemValue') - ->willReturn(true); - $this->checkSetupController - ->expects($this->once()) - ->method('getCurlVersion') - ->willReturn(['ssl_version' => 'OpenSSL/1.0.2a']); - $this->assertSame('cURL is using an outdated OpenSSL version (OpenSSL/1.0.2a). Please update your operating system or features such as installing and updating apps via the App Store or Federated Cloud Sharing will not work reliably.', $this->invokePrivate($this->checkSetupController, 'isUsedTlsLibOutdated')); - } - - public function testIsUsedTlsLibOutdatedWithMatchingOpenSslVersion() { - $this->config->expects($this->any()) - ->method('getSystemValue') - ->willReturn(true); - $this->checkSetupController - ->expects($this->once()) - ->method('getCurlVersion') - ->willReturn(['ssl_version' => 'OpenSSL/1.0.1d']); - $this->assertSame('', $this->invokePrivate($this->checkSetupController, 'isUsedTlsLibOutdated')); - } - - public function testIsUsedTlsLibOutdatedWithMatchingOpenSslVersion1() { - $this->config->expects($this->any()) - ->method('getSystemValue') - ->willReturn(true); - $this->checkSetupController - ->expects($this->once()) - ->method('getCurlVersion') - ->willReturn(['ssl_version' => 'OpenSSL/1.0.2b']); - $this->assertSame('', $this->invokePrivate($this->checkSetupController, 'isUsedTlsLibOutdated')); - } - - /** - * Setups a temp directory and some subdirectories. - * Then calls the 'getAppDirsWithDifferentOwner' method. - * The result is expected to be empty since - * there are no directories with different owners than the current user. - * - * @return void - */ - public function testAppDirectoryOwnersOk() { - $tempDir = tempnam(sys_get_temp_dir(), 'apps') . 'dir'; - mkdir($tempDir); - mkdir($tempDir . DIRECTORY_SEPARATOR . 'app1'); - mkdir($tempDir . DIRECTORY_SEPARATOR . 'app2'); - $this->dirsToRemove[] = $tempDir . DIRECTORY_SEPARATOR . 'app1'; - $this->dirsToRemove[] = $tempDir . DIRECTORY_SEPARATOR . 'app2'; - $this->dirsToRemove[] = $tempDir; - OC::$APPSROOTS = [ - [ - 'path' => $tempDir, - 'url' => '/apps', - 'writable' => true, - ], - ]; - $this->assertSame( - [], - $this->invokePrivate($this->checkSetupController, 'getAppDirsWithDifferentOwner') - ); - } - - /** - * Calls the check for a none existing app root that is marked as not writable. - * It's expected that no error happens since the check shouldn't apply. - * - * @return void - */ - public function testAppDirectoryOwnersNotWritable() { - $tempDir = tempnam(sys_get_temp_dir(), 'apps') . 'dir'; - OC::$APPSROOTS = [ - [ - 'path' => $tempDir, - 'url' => '/apps', - 'writable' => false, - ], - ]; - $this->assertSame( - [], - $this->invokePrivate($this->checkSetupController, 'getAppDirsWithDifferentOwner') - ); - } - - public function testIsBuggyNss400() { - $this->config->expects($this->any()) - ->method('getSystemValue') - ->willReturn(true); - $this->checkSetupController - ->expects($this->once()) - ->method('getCurlVersion') - ->willReturn(['ssl_version' => 'NSS/1.0.2b']); - $client = $this->getMockBuilder('\OCP\Http\Client\IClient') - ->disableOriginalConstructor()->getMock(); - $exception = $this->getMockBuilder('\GuzzleHttp\Exception\ClientException') - ->disableOriginalConstructor()->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor()->getMock(); - $response->expects($this->once()) - ->method('getStatusCode') - ->willReturn(400); - $exception->expects($this->once()) - ->method('getResponse') - ->willReturn($response); - - $client->expects($this->at(0)) - ->method('get') - ->with('https://nextcloud.com/', []) - ->will($this->throwException($exception)); - - $this->clientService->expects($this->once()) - ->method('newClient') - ->willReturn($client); - - $this->assertSame('cURL is using an outdated NSS version (NSS/1.0.2b). Please update your operating system or features such as installing and updating apps via the App Store or Federated Cloud Sharing will not work reliably.', $this->invokePrivate($this->checkSetupController, 'isUsedTlsLibOutdated')); - } - - - public function testIsBuggyNss200() { - $this->config->expects($this->any()) - ->method('getSystemValue') - ->willReturn(true); - $this->checkSetupController - ->expects($this->once()) - ->method('getCurlVersion') - ->willReturn(['ssl_version' => 'NSS/1.0.2b']); - $client = $this->getMockBuilder('\OCP\Http\Client\IClient') - ->disableOriginalConstructor()->getMock(); - $exception = $this->getMockBuilder('\GuzzleHttp\Exception\ClientException') - ->disableOriginalConstructor()->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor()->getMock(); - $response->expects($this->once()) - ->method('getStatusCode') - ->willReturn(200); - $exception->expects($this->once()) - ->method('getResponse') - ->willReturn($response); - - $client->expects($this->at(0)) - ->method('get') - ->with('https://nextcloud.com/', []) - ->will($this->throwException($exception)); - - $this->clientService->expects($this->once()) - ->method('newClient') - ->willReturn($client); - - $this->assertSame('', $this->invokePrivate($this->checkSetupController, 'isUsedTlsLibOutdated')); - } - - public function testIsUsedTlsLibOutdatedWithInternetDisabled() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('has_internet_connection', true) - ->willReturn(false); - $this->assertSame('', $this->invokePrivate($this->checkSetupController, 'isUsedTlsLibOutdated')); - } - - public function testIsUsedTlsLibOutdatedWithAppstoreDisabledAndServerToServerSharingEnabled() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('has_internet_connection', true) - ->willReturn(true); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->willReturn(false); - $this->config - ->expects($this->at(2)) - ->method('getAppValue') - ->with('files_sharing', 'outgoing_server2server_share_enabled', 'yes') - ->willReturn('no'); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('files_sharing', 'incoming_server2server_share_enabled', 'yes') - ->willReturn('yes'); - - $this->checkSetupController - ->expects($this->once()) - ->method('getCurlVersion') - ->willReturn([]); - $this->assertSame('', $this->invokePrivate($this->checkSetupController, 'isUsedTlsLibOutdated')); - } - - public function testIsUsedTlsLibOutdatedWithAppstoreDisabledAndServerToServerSharingDisabled() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('has_internet_connection', true) - ->willReturn(true); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->willReturn(false); - $this->config - ->expects($this->at(2)) - ->method('getAppValue') - ->with('files_sharing', 'outgoing_server2server_share_enabled', 'yes') - ->willReturn('no'); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('files_sharing', 'incoming_server2server_share_enabled', 'yes') - ->willReturn('no'); - - $this->checkSetupController - ->expects($this->never()) - ->method('getCurlVersion') - ->willReturn([]); - $this->assertSame('', $this->invokePrivate($this->checkSetupController, 'isUsedTlsLibOutdated')); - } - - public function testRescanFailedIntegrityCheck() { + public function testRescanFailedIntegrityCheck(): void { $this->checker ->expects($this->once()) ->method('runInstanceVerification'); @@ -982,7 +137,7 @@ class CheckSetupControllerTest extends TestCase { $this->assertEquals($expected, $this->checkSetupController->rescanFailedIntegrityCheck()); } - public function testGetFailedIntegrityCheckDisabled() { + public function testGetFailedIntegrityCheckDisabled(): void { $this->checker ->expects($this->once()) ->method('isCodeCheckEnforced') @@ -993,7 +148,7 @@ class CheckSetupControllerTest extends TestCase { } - public function testGetFailedIntegrityCheckFilesWithNoErrorsFound() { + public function testGetFailedIntegrityCheckFilesWithNoErrorsFound(): void { $this->checker ->expects($this->once()) ->method('isCodeCheckEnforced') @@ -1004,27 +159,27 @@ class CheckSetupControllerTest extends TestCase { ->willReturn([]); $expected = new DataDisplayResponse( - 'No errors have been found.', - Http::STATUS_OK, - [ - 'Content-Type' => 'text/plain', - ] + 'No errors have been found.', + Http::STATUS_OK, + [ + 'Content-Type' => 'text/plain', + ] ); $this->assertEquals($expected, $this->checkSetupController->getFailedIntegrityCheckFiles()); } - public function testGetFailedIntegrityCheckFilesWithSomeErrorsFound() { + public function testGetFailedIntegrityCheckFilesWithSomeErrorsFound(): void { $this->checker ->expects($this->once()) ->method('isCodeCheckEnforced') ->willReturn(true); $this->checker - ->expects($this->once()) - ->method('getResults') - ->willReturn([ 'core' => [ 'EXTRA_FILE' => ['/testfile' => []], 'INVALID_HASH' => [ '/.idea/workspace.xml' => [ 'expected' => 'f1c5e2630d784bc9cb02d5a28f55d6f24d06dae2a0fee685f3c2521b050955d9d452769f61454c9ddfa9c308146ade10546cfa829794448eaffbc9a04a29d216', 'current' => 'ce08bf30bcbb879a18b49239a9bec6b8702f52452f88a9d32142cad8d2494d5735e6bfa0d8642b2762c62ca5be49f9bf4ec231d4a230559d4f3e2c471d3ea094', ], '/lib/private/integritycheck/checker.php' => [ 'expected' => 'c5a03bacae8dedf8b239997901ba1fffd2fe51271d13a00cc4b34b09cca5176397a89fc27381cbb1f72855fa18b69b6f87d7d5685c3b45aee373b09be54742ea', 'current' => '88a3a92c11db91dec1ac3be0e1c87f862c95ba6ffaaaa3f2c3b8f682187c66f07af3a3b557a868342ef4a271218fe1c1e300c478e6c156c5955ed53c40d06585', ], '/settings/controller/checksetupcontroller.php' => [ 'expected' => '3e1de26ce93c7bfe0ede7c19cb6c93cadc010340225b375607a7178812e9de163179b0dc33809f451e01f491d93f6f5aaca7929685d21594cccf8bda732327c4', 'current' => '09563164f9904a837f9ca0b5f626db56c838e5098e0ccc1d8b935f68fa03a25c5ec6f6b2d9e44a868e8b85764dafd1605522b4af8db0ae269d73432e9a01e63a', ], ], ], 'bookmarks' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'dav' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'encryption' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'external' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'federation' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_antivirus' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_drop' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_external' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_pdfviewer' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_sharing' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_trashbin' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_versions' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_videoviewer' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'firstrunwizard' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'gitsmart' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'logreader' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature could not get verified.', ], ], 'password_policy' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'provisioning_api' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'sketch' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'threatblock' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'two_factor_auth' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'user_ldap' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'user_shibboleth' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], ]); + ->expects($this->once()) + ->method('getResults') + ->willReturn([ 'core' => [ 'EXTRA_FILE' => ['/testfile' => []], 'INVALID_HASH' => [ '/.idea/workspace.xml' => [ 'expected' => 'f1c5e2630d784bc9cb02d5a28f55d6f24d06dae2a0fee685f3c2521b050955d9d452769f61454c9ddfa9c308146ade10546cfa829794448eaffbc9a04a29d216', 'current' => 'ce08bf30bcbb879a18b49239a9bec6b8702f52452f88a9d32142cad8d2494d5735e6bfa0d8642b2762c62ca5be49f9bf4ec231d4a230559d4f3e2c471d3ea094', ], '/lib/private/integritycheck/checker.php' => [ 'expected' => 'c5a03bacae8dedf8b239997901ba1fffd2fe51271d13a00cc4b34b09cca5176397a89fc27381cbb1f72855fa18b69b6f87d7d5685c3b45aee373b09be54742ea', 'current' => '88a3a92c11db91dec1ac3be0e1c87f862c95ba6ffaaaa3f2c3b8f682187c66f07af3a3b557a868342ef4a271218fe1c1e300c478e6c156c5955ed53c40d06585', ], '/settings/controller/checksetupcontroller.php' => [ 'expected' => '3e1de26ce93c7bfe0ede7c19cb6c93cadc010340225b375607a7178812e9de163179b0dc33809f451e01f491d93f6f5aaca7929685d21594cccf8bda732327c4', 'current' => '09563164f9904a837f9ca0b5f626db56c838e5098e0ccc1d8b935f68fa03a25c5ec6f6b2d9e44a868e8b85764dafd1605522b4af8db0ae269d73432e9a01e63a', ], ], ], 'bookmarks' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'dav' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'encryption' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'external' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'federation' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_antivirus' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_drop' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_external' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_pdfviewer' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_sharing' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_trashbin' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_versions' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'files_videoviewer' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'firstrunwizard' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'gitsmart' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'logreader' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature could not get verified.', ], ], 'password_policy' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'provisioning_api' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'sketch' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'threatblock' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'two_factor_auth' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'user_ldap' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], 'user_shibboleth' => [ 'EXCEPTION' => [ 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', 'message' => 'Signature data not found.', ], ], ]); $expected = new DataDisplayResponse( - 'Technical information + 'Technical information ===================== The following list covers which files have failed the integrity check. Please read the previous linked documentation to learn more about the errors and how to fix @@ -1416,119 +571,11 @@ Array ) ', - Http::STATUS_OK, - [ - 'Content-Type' => 'text/plain', - ] + Http::STATUS_OK, + [ + 'Content-Type' => 'text/plain', + ] ); $this->assertEquals($expected, $this->checkSetupController->getFailedIntegrityCheckFiles()); } - - public function dataForIsMysqlUsedWithoutUTF8MB4() { - return [ - ['sqlite', false, false], - ['sqlite', true, false], - ['postgres', false, false], - ['postgres', true, false], - ['oci', false, false], - ['oci', true, false], - ['mysql', false, true], - ['mysql', true, false], - ]; - } - - /** - * @dataProvider dataForIsMysqlUsedWithoutUTF8MB4 - */ - public function testIsMysqlUsedWithoutUTF8MB4(string $db, bool $useUTF8MB4, bool $expected) { - $this->config->method('getSystemValue') - ->willReturnCallback(function ($key, $default) use ($db, $useUTF8MB4) { - if ($key === 'dbtype') { - return $db; - } - if ($key === 'mysql.utf8mb4') { - return $useUTF8MB4; - } - return $default; - }); - - $checkSetupController = new CheckSetupController( - 'settings', - $this->request, - $this->config, - $this->clientService, - $this->urlGenerator, - $this->l10n, - $this->checker, - $this->logger, - $this->dispatcher, - $this->db, - $this->lockingProvider, - $this->dateTimeFormatter, - $this->memoryInfo, - $this->secureRandom, - $this->iniGetWrapper, - $this->connection, - $this->tempManager, - $this->notificationManager, - $this->appManager, - $this->serverContainer - ); - - $this->assertSame($expected, $this->invokePrivate($checkSetupController, 'isMysqlUsedWithoutUTF8MB4')); - } - - public function dataForIsEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed() { - return [ - ['singlebucket', 'OC\\Files\\ObjectStore\\Swift', true], - ['multibucket', 'OC\\Files\\ObjectStore\\Swift', true], - ['singlebucket', 'OC\\Files\\ObjectStore\\Custom', true], - ['multibucket', 'OC\Files\\ObjectStore\\Custom', true], - ['singlebucket', 'OC\Files\ObjectStore\Swift', true], - ['multibucket', 'OC\Files\ObjectStore\Swift', true], - ['singlebucket', 'OC\Files\ObjectStore\Custom', true], - ['multibucket', 'OC\Files\ObjectStore\Custom', true], - ]; - } - - /** - * @dataProvider dataForIsEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed - */ - public function testIsEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(string $mode, string $className, bool $expected) { - $this->config->method('getSystemValue') - ->willReturnCallback(function ($key, $default) use ($mode, $className) { - if ($key === 'objectstore' && $mode === 'singlebucket') { - return ['class' => $className]; - } - if ($key === 'objectstore_multibucket' && $mode === 'multibucket') { - return ['class' => $className]; - } - return $default; - }); - - $checkSetupController = new CheckSetupController( - 'settings', - $this->request, - $this->config, - $this->clientService, - $this->urlGenerator, - $this->l10n, - $this->checker, - $this->logger, - $this->dispatcher, - $this->db, - $this->lockingProvider, - $this->dateTimeFormatter, - $this->memoryInfo, - $this->secureRandom, - $this->iniGetWrapper, - $this->connection, - $this->tempManager, - $this->notificationManager, - $this->appManager, - $this->serverContainer - ); - - $this->assertSame($expected, $this->invokePrivate($checkSetupController, 'isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed')); - } } diff --git a/apps/settings/tests/Controller/DelegationControllerTest.php b/apps/settings/tests/Controller/DelegationControllerTest.php index 64157427fa4..c4cbe67466b 100644 --- a/apps/settings/tests/Controller/DelegationControllerTest.php +++ b/apps/settings/tests/Controller/DelegationControllerTest.php @@ -1,56 +1,33 @@ <?php + /** - * @copyright Copyright (c) 2021 Nextcloud GmbH - * - * @author Carl Schwan <carl@carlschwan.eu> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * 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 - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ - - namespace OCA\Settings\Tests\Controller\Admin; use OC\Settings\AuthorizedGroup; use OCA\Settings\Controller\AuthorizedGroupController; use OCA\Settings\Service\AuthorizedGroupService; use OCP\IRequest; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class DelegationControllerTest extends TestCase { - - /** @var AuthorizedGroupService */ - private $service; - - /** @var IRequest */ - private $request; - - /** @var AuthorizedGroupController */ - private $controller; + private AuthorizedGroupService&MockObject $service; + private IRequest&MockObject $request; + private AuthorizedGroupController $controller; protected function setUp(): void { parent::setUp(); - $this->request = $this->getMockBuilder(IRequest::class)->getMock(); - $this->service = $this->getMockBuilder(AuthorizedGroupService::class)->disableOriginalConstructor()->getMock(); + $this->request = $this->createMock(IRequest::class); + $this->service = $this->createMock(AuthorizedGroupService::class); $this->controller = new AuthorizedGroupController( 'settings', $this->request, $this->service ); } - public function testSaveSettings() { + public function testSaveSettings(): void { $setting = 'MySecretSetting'; $oldGroups = []; $oldGroups[] = AuthorizedGroup::fromParams(['groupId' => 'hello', 'class' => $setting]); @@ -59,7 +36,7 @@ class DelegationControllerTest extends TestCase { $this->service->expects($this->once()) ->method('findExistingGroupsForClass') ->with('MySecretSetting') - ->will($this->returnValue($oldGroups)); + ->willReturn($oldGroups); $this->service->expects($this->once()) ->method('delete') @@ -68,7 +45,7 @@ class DelegationControllerTest extends TestCase { $this->service->expects($this->once()) ->method('create') ->with('world', 'MySecretSetting') - ->will($this->returnValue(AuthorizedGroup::fromParams(['groupId' => 'world', 'class' => $setting]))); + ->willReturn(AuthorizedGroup::fromParams(['groupId' => 'world', 'class' => $setting])); $result = $this->controller->saveSettings([['gid' => 'hello'], ['gid' => 'world']], 'MySecretSetting'); diff --git a/apps/settings/tests/Controller/MailSettingsControllerTest.php b/apps/settings/tests/Controller/MailSettingsControllerTest.php index 54461201201..1bc05ca4718 100644 --- a/apps/settings/tests/Controller/MailSettingsControllerTest.php +++ b/apps/settings/tests/Controller/MailSettingsControllerTest.php @@ -1,30 +1,9 @@ <?php + +declare(strict_types=1); /** - * @copyright 2014 Lukas Reschke lukas@nextcloud.com - * @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Daniel Kesselberg <mail@danielkesselberg.de> - * @author Joas Schilling <coding@schilljs.com> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * 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 - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Settings\Tests\Controller; @@ -35,29 +14,22 @@ use OCP\AppFramework\Http; use OCP\IConfig; use OCP\IL10N; use OCP\IRequest; +use OCP\IURLGenerator; use OCP\IUserSession; use OCP\Mail\IEMailTemplate; use OCP\Mail\IMailer; -use OCP\IURLGenerator; +use PHPUnit\Framework\MockObject\MockObject; /** * @package Tests\Settings\Controller */ class MailSettingsControllerTest extends \Test\TestCase { - - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $config; - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - private $userSession; - /** @var IMailer|\PHPUnit\Framework\MockObject\MockObject */ - private $mailer; - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - private $l; - /** @var IURLGenerator */ - private $urlGenerator; - - /** @var MailSettingsController */ - private $mailController; + private IConfig&MockObject $config; + private IUserSession&MockObject $userSession; + private IMailer&MockObject $mailer; + private IL10N&MockObject $l; + private IURLGenerator&MockObject $urlGenerator; + private MailSettingsController $mailController; protected function setUp(): void { parent::setUp(); @@ -67,7 +39,7 @@ class MailSettingsControllerTest extends \Test\TestCase { $this->userSession = $this->createMock(IUserSession::class); $this->mailer = $this->createMock(IMailer::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); - /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject $request */ + /** @var IRequest&MockObject $request */ $request = $this->createMock(IRequest::class); $this->mailController = new MailSettingsController( 'settings', @@ -77,39 +49,40 @@ class MailSettingsControllerTest extends \Test\TestCase { $this->userSession, $this->urlGenerator, $this->mailer, - 'no-reply@nextcloud.com' ); } - public function testSetMailSettings() { + public function testSetMailSettings(): void { + $calls = [ + [[ + 'mail_domain' => 'nextcloud.com', + 'mail_from_address' => 'demo@nextcloud.com', + 'mail_smtpmode' => 'smtp', + 'mail_smtpsecure' => 'ssl', + 'mail_smtphost' => 'mx.nextcloud.org', + 'mail_smtpauth' => 1, + 'mail_smtpport' => '25', + 'mail_sendmailmode' => 'smtp', + ]], + [[ + 'mail_domain' => 'nextcloud.com', + 'mail_from_address' => 'demo@nextcloud.com', + 'mail_smtpmode' => 'smtp', + 'mail_smtpsecure' => 'ssl', + 'mail_smtphost' => 'mx.nextcloud.org', + 'mail_smtpauth' => null, + 'mail_smtpport' => '25', + 'mail_smtpname' => null, + 'mail_smtppassword' => null, + 'mail_sendmailmode' => 'smtp', + ]], + ]; $this->config->expects($this->exactly(2)) ->method('setSystemValues') - ->withConsecutive( - [[ - 'mail_domain' => 'nextcloud.com', - 'mail_from_address' => 'demo@nextcloud.com', - 'mail_smtpmode' => 'smtp', - 'mail_smtpsecure' => 'ssl', - 'mail_smtphost' => 'mx.nextcloud.org', - 'mail_smtpauthtype' => 'NTLM', - 'mail_smtpauth' => 1, - 'mail_smtpport' => '25', - 'mail_sendmailmode' => null, - ]], - [[ - 'mail_domain' => 'nextcloud.com', - 'mail_from_address' => 'demo@nextcloud.com', - 'mail_smtpmode' => 'smtp', - 'mail_smtpsecure' => 'ssl', - 'mail_smtphost' => 'mx.nextcloud.org', - 'mail_smtpauthtype' => 'NTLM', - 'mail_smtpauth' => null, - 'mail_smtpport' => '25', - 'mail_smtpname' => null, - 'mail_smtppassword' => null, - 'mail_sendmailmode' => null, - ]] - ); + ->willReturnCallback(function () use (&$calls): void { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); // With authentication $response = $this->mailController->setMailSettings( @@ -118,10 +91,9 @@ class MailSettingsControllerTest extends \Test\TestCase { 'smtp', 'ssl', 'mx.nextcloud.org', - 'NTLM', - 1, + '1', '25', - null + 'smtp' ); $this->assertSame(Http::STATUS_OK, $response->getStatus()); @@ -132,15 +104,14 @@ class MailSettingsControllerTest extends \Test\TestCase { 'smtp', 'ssl', 'mx.nextcloud.org', - 'NTLM', - 0, + '0', '25', - null + 'smtp' ); $this->assertSame(Http::STATUS_OK, $response->getStatus()); } - public function testStoreCredentials() { + public function testStoreCredentials(): void { $this->config ->expects($this->once()) ->method('setSystemValues') @@ -153,7 +124,7 @@ class MailSettingsControllerTest extends \Test\TestCase { $this->assertSame(Http::STATUS_OK, $response->getStatus()); } - public function testSendTestMail() { + public function testSendTestMail(): void { $user = $this->createMock(User::class); $user->expects($this->any()) ->method('getUID') @@ -175,7 +146,7 @@ class MailSettingsControllerTest extends \Test\TestCase { // Ensure that it fails when no mail address has been specified $response = $this->mailController->sendTestMail(); $this->assertSame(Http::STATUS_BAD_REQUEST, $response->getStatus()); - $this->assertSame('You need to set your user email before being able to send test emails. Go to for that.', $response->getData()); + $this->assertSame('You need to set your account email before being able to send test emails. Go to for that.', $response->getData()); // If no exception is thrown it should work $this->config diff --git a/apps/settings/tests/Controller/TwoFactorSettingsControllerTest.php b/apps/settings/tests/Controller/TwoFactorSettingsControllerTest.php index a19db6a3380..9f8d53d4f9f 100644 --- a/apps/settings/tests/Controller/TwoFactorSettingsControllerTest.php +++ b/apps/settings/tests/Controller/TwoFactorSettingsControllerTest.php @@ -1,25 +1,9 @@ <?php + +declare(strict_types=1); /** - * @copyright 2018 Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * 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 - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Settings\Tests\Controller; @@ -32,15 +16,9 @@ use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class TwoFactorSettingsControllerTest extends TestCase { - - /** @var IRequest|MockObject */ - private $request; - - /** @var MandatoryTwoFactor|MockObject */ - private $mandatoryTwoFactor; - - /** @var TwoFactorSettingsController */ - private $controller; + private IRequest&MockObject $request; + private MandatoryTwoFactor&MockObject $mandatoryTwoFactor; + private TwoFactorSettingsController $controller; protected function setUp(): void { parent::setUp(); @@ -55,7 +33,7 @@ class TwoFactorSettingsControllerTest extends TestCase { ); } - public function testIndex() { + public function testIndex(): void { $state = new EnforcementState(true); $this->mandatoryTwoFactor->expects($this->once()) ->method('getState') @@ -67,7 +45,7 @@ class TwoFactorSettingsControllerTest extends TestCase { $this->assertEquals($expected, $resp); } - public function testUpdate() { + public function testUpdate(): void { $state = new EnforcementState(true); $this->mandatoryTwoFactor->expects($this->once()) ->method('setState') diff --git a/apps/settings/tests/Controller/UsersControllerTest.php b/apps/settings/tests/Controller/UsersControllerTest.php index 797fa1621fa..1012557bfc4 100644 --- a/apps/settings/tests/Controller/UsersControllerTest.php +++ b/apps/settings/tests/Controller/UsersControllerTest.php @@ -1,32 +1,10 @@ <?php + +declare(strict_types=1); /** - * @copyright 2014-2015 Lukas Reschke lukas@owncloud.com - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Daniel Calviño Sánchez <danxuliu@gmail.com> - * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ <skjnldsv@protonmail.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * 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 - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2014-2015 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Settings\Tests\Controller; @@ -35,6 +13,7 @@ use OC\Encryption\Exceptions\ModuleDoesNotExistsException; use OC\ForbiddenException; use OC\Group\Manager; use OC\KnownUser\KnownUserService; +use OC\User\Manager as UserManager; use OCA\Settings\Controller\UsersController; use OCP\Accounts\IAccount; use OCP\Accounts\IAccountManager; @@ -42,22 +21,19 @@ use OCP\Accounts\IAccountProperty; use OCP\Accounts\PropertyDoesNotExistException; use OCP\App\IAppManager; use OCP\AppFramework\Http; +use OCP\AppFramework\Services\IInitialState; use OCP\BackgroundJob\IJobList; use OCP\Encryption\IEncryptionModule; use OCP\Encryption\IManager; use OCP\EventDispatcher\IEventDispatcher; -use OCP\IAvatarManager; use OCP\IConfig; use OCP\IGroupManager; use OCP\IL10N; -use OCP\ILogger; use OCP\IRequest; use OCP\IUser; -use OCP\IUserManager; use OCP\IUserSession; use OCP\L10N\IFactory; use OCP\Mail\IMailer; -use OCP\Security\ISecureRandom; use PHPUnit\Framework\MockObject\MockObject; /** @@ -66,49 +42,27 @@ use PHPUnit\Framework\MockObject\MockObject; * @package Tests\Settings\Controller */ class UsersControllerTest extends \Test\TestCase { - /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */ - private $groupManager; - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ - private $userManager; - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - private $userSession; - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $config; - /** @var ILogger|\PHPUnit\Framework\MockObject\MockObject */ - private $logger; - /** @var IMailer|\PHPUnit\Framework\MockObject\MockObject */ - private $mailer; - /** @var IFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $l10nFactory; - /** @var IAppManager|\PHPUnit\Framework\MockObject\MockObject */ - private $appManager; - /** @var IAvatarManager|\PHPUnit\Framework\MockObject\MockObject */ - private $avatarManager; - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - private $l; - /** @var AccountManager | \PHPUnit\Framework\MockObject\MockObject */ - private $accountManager; - /** @var ISecureRandom | \PHPUnit\Framework\MockObject\MockObject */ - private $secureRandom; - /** @var \OCA\Settings\Mailer\NewUserMailHelper|\PHPUnit\Framework\MockObject\MockObject */ - private $newUserMailHelper; - /** @var IJobList | \PHPUnit\Framework\MockObject\MockObject */ - private $jobList; - /** @var \OC\Security\IdentityProof\Manager |\PHPUnit\Framework\MockObject\MockObject */ - private $securityManager; - /** @var IManager | \PHPUnit\Framework\MockObject\MockObject */ - private $encryptionManager; - /** @var KnownUserService|\PHPUnit\Framework\MockObject\MockObject */ - private $knownUserService; - /** @var IEncryptionModule | \PHPUnit\Framework\MockObject\MockObject */ - private $encryptionModule; - /** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */ - private $dispatcher; + private IGroupManager&MockObject $groupManager; + private UserManager&MockObject $userManager; + private IUserSession&MockObject $userSession; + private IConfig&MockObject $config; + private IMailer&MockObject $mailer; + private IFactory&MockObject $l10nFactory; + private IAppManager&MockObject $appManager; + private IL10N&MockObject $l; + private AccountManager&MockObject $accountManager; + private IJobList&MockObject $jobList; + private \OC\Security\IdentityProof\Manager&MockObject $securityManager; + private IManager&MockObject $encryptionManager; + private KnownUserService&MockObject $knownUserService; + private IEncryptionModule&MockObject $encryptionModule; + private IEventDispatcher&MockObject $dispatcher; + private IInitialState&MockObject $initialState; protected function setUp(): void { parent::setUp(); - $this->userManager = $this->createMock(IUserManager::class); + $this->userManager = $this->createMock(UserManager::class); $this->groupManager = $this->createMock(Manager::class); $this->userSession = $this->createMock(IUserSession::class); $this->config = $this->createMock(IConfig::class); @@ -117,11 +71,12 @@ class UsersControllerTest extends \Test\TestCase { $this->l10nFactory = $this->createMock(IFactory::class); $this->appManager = $this->createMock(IAppManager::class); $this->accountManager = $this->createMock(AccountManager::class); - $this->securityManager = $this->getMockBuilder(\OC\Security\IdentityProof\Manager::class)->disableOriginalConstructor()->getMock(); + $this->securityManager = $this->createMock(\OC\Security\IdentityProof\Manager::class); $this->jobList = $this->createMock(IJobList::class); $this->encryptionManager = $this->createMock(IManager::class); $this->knownUserService = $this->createMock(KnownUserService::class); $this->dispatcher = $this->createMock(IEventDispatcher::class); + $this->initialState = $this->createMock(IInitialState::class); $this->l->method('t') ->willReturnCallback(function ($text, $parameters = []) { @@ -137,9 +92,13 @@ class UsersControllerTest extends \Test\TestCase { /** * @param bool $isAdmin - * @return UsersController | \PHPUnit\Framework\MockObject\MockObject + * @return UsersController|MockObject */ - protected function getController($isAdmin = false, $mockedMethods = []) { + protected function getController(bool $isAdmin = false, array $mockedMethods = []) { + $this->groupManager->expects($this->any()) + ->method('isAdmin') + ->willReturn($isAdmin); + if (empty($mockedMethods)) { return new UsersController( 'settings', @@ -148,7 +107,6 @@ class UsersControllerTest extends \Test\TestCase { $this->groupManager, $this->userSession, $this->config, - $isAdmin, $this->l, $this->mailer, $this->l10nFactory, @@ -158,7 +116,8 @@ class UsersControllerTest extends \Test\TestCase { $this->jobList, $this->encryptionManager, $this->knownUserService, - $this->dispatcher + $this->dispatcher, + $this->initialState, ); } else { return $this->getMockBuilder(UsersController::class) @@ -170,7 +129,6 @@ class UsersControllerTest extends \Test\TestCase { $this->groupManager, $this->userSession, $this->config, - $isAdmin, $this->l, $this->mailer, $this->l10nFactory, @@ -180,9 +138,12 @@ class UsersControllerTest extends \Test\TestCase { $this->jobList, $this->encryptionManager, $this->knownUserService, - $this->dispatcher + $this->dispatcher, + $this->initialState, ] - )->setMethods($mockedMethods)->getMock(); + ) + ->onlyMethods($mockedMethods) + ->getMock(); } } @@ -204,7 +165,7 @@ class UsersControllerTest extends \Test\TestCase { return $property; } - protected function getDefaultAccountMock(bool $useDefaultValues = true): MockObject { + protected function getDefaultAccountMock(): MockObject { $propertyMocks = [ IAccountManager::PROPERTY_DISPLAYNAME => $this->buildPropertyMock( IAccountManager::PROPERTY_DISPLAYNAME, @@ -241,6 +202,26 @@ class UsersControllerTest extends \Test\TestCase { 'Default twitter', IAccountManager::SCOPE_LOCAL, ), + IAccountManager::PROPERTY_BLUESKY => $this->buildPropertyMock( + IAccountManager::PROPERTY_BLUESKY, + 'Default bluesky', + IAccountManager::SCOPE_LOCAL, + ), + IAccountManager::PROPERTY_FEDIVERSE => $this->buildPropertyMock( + IAccountManager::PROPERTY_FEDIVERSE, + 'Default fediverse', + IAccountManager::SCOPE_LOCAL, + ), + IAccountManager::PROPERTY_BIRTHDATE => $this->buildPropertyMock( + IAccountManager::PROPERTY_BIRTHDATE, + 'Default birthdate', + IAccountManager::SCOPE_LOCAL, + ), + IAccountManager::PROPERTY_PRONOUNS => $this->buildPropertyMock( + IAccountManager::PROPERTY_PRONOUNS, + 'Default pronouns', + IAccountManager::SCOPE_LOCAL, + ), ]; $account = $this->createMock(IAccount::class); @@ -259,14 +240,8 @@ class UsersControllerTest extends \Test\TestCase { return $account; } - /** - * @dataProvider dataTestSetUserSettings - * - * @param string $email - * @param bool $validEmail - * @param $expectedStatus - */ - public function testSetUserSettings($email, $validEmail, $expectedStatus) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestSetUserSettings')] + public function testSetUserSettings(string $email, bool $validEmail, int $expectedStatus): void { $controller = $this->getController(false, ['saveUserSettings']); $user = $this->createMock(IUser::class); $user->method('getUID')->willReturn('johndoe'); @@ -292,7 +267,7 @@ class UsersControllerTest extends \Test\TestCase { $controller->expects($this->never())->method('saveUserSettings'); } - $result = $controller->setUserSettings(// + $result = $controller->setUserSettings( AccountManager::SCOPE_FEDERATED, 'displayName', AccountManager::SCOPE_FEDERATED, @@ -305,13 +280,19 @@ class UsersControllerTest extends \Test\TestCase { 'street and city', AccountManager::SCOPE_FEDERATED, '@nextclouders', - AccountManager::SCOPE_FEDERATED + AccountManager::SCOPE_FEDERATED, + '@nextclouders', + AccountManager::SCOPE_FEDERATED, + '2020-01-01', + AccountManager::SCOPE_FEDERATED, + 'they/them', + AccountManager::SCOPE_FEDERATED, ); $this->assertSame($expectedStatus, $result->getStatus()); } - public function dataTestSetUserSettings() { + public static function dataTestSetUserSettings(): array { return [ ['', true, Http::STATUS_OK], ['', false, Http::STATUS_OK], @@ -320,7 +301,7 @@ class UsersControllerTest extends \Test\TestCase { ]; } - public function testSetUserSettingsWhenUserDisplayNameChangeNotAllowed() { + public function testSetUserSettingsWhenUserDisplayNameChangeNotAllowed(): void { $controller = $this->getController(false, ['saveUserSettings']); $avatarScope = IAccountManager::SCOPE_PUBLISHED; @@ -336,6 +317,12 @@ class UsersControllerTest extends \Test\TestCase { $addressScope = IAccountManager::SCOPE_PUBLISHED; $twitter = '@nextclouders'; $twitterScope = IAccountManager::SCOPE_PUBLISHED; + $fediverse = '@nextclouders@floss.social'; + $fediverseScope = IAccountManager::SCOPE_PUBLISHED; + $birtdate = '2020-01-01'; + $birthdateScope = IAccountManager::SCOPE_PUBLISHED; + $pronouns = 'she/her'; + $pronounsScope = IAccountManager::SCOPE_PUBLISHED; $user = $this->createMock(IUser::class); $user->method('getUID')->willReturn('johndoe'); @@ -410,11 +397,17 @@ class UsersControllerTest extends \Test\TestCase { $address, $addressScope, $twitter, - $twitterScope + $twitterScope, + $fediverse, + $fediverseScope, + $birtdate, + $birthdateScope, + $pronouns, + $pronounsScope, ); } - public function testSetUserSettingsWhenFederatedFilesharingNotEnabled() { + public function testSetUserSettingsWhenFederatedFilesharingNotEnabled(): void { $controller = $this->getController(false, ['saveUserSettings']); $user = $this->createMock(IUser::class); $user->method('getUID')->willReturn('johndoe'); @@ -447,6 +440,14 @@ class UsersControllerTest extends \Test\TestCase { $addressScope = IAccountManager::SCOPE_PUBLISHED; $twitter = '@nextclouders'; $twitterScope = IAccountManager::SCOPE_PUBLISHED; + $bluesky = 'nextclouders.net'; + $blueskyScope = IAccountManager::SCOPE_PUBLISHED; + $fediverse = '@nextclouders@floss.social'; + $fediverseScope = IAccountManager::SCOPE_PUBLISHED; + $birthdate = '2020-01-01'; + $birthdateScope = IAccountManager::SCOPE_PUBLISHED; + $pronouns = 'she/her'; + $pronounsScope = IAccountManager::SCOPE_PUBLISHED; // All settings are changed (in the past phone, website, address and // twitter were not changed). @@ -464,6 +465,14 @@ class UsersControllerTest extends \Test\TestCase { $expectedProperties[IAccountManager::PROPERTY_ADDRESS]['scope'] = $addressScope; $expectedProperties[IAccountManager::PROPERTY_TWITTER]['value'] = $twitter; $expectedProperties[IAccountManager::PROPERTY_TWITTER]['scope'] = $twitterScope; + $expectedProperties[IAccountManager::PROPERTY_BLUESKY]['value'] = $bluesky; + $expectedProperties[IAccountManager::PROPERTY_BLUESKY]['scope'] = $blueskyScope; + $expectedProperties[IAccountManager::PROPERTY_FEDIVERSE]['value'] = $fediverse; + $expectedProperties[IAccountManager::PROPERTY_FEDIVERSE]['scope'] = $fediverseScope; + $expectedProperties[IAccountManager::PROPERTY_BIRTHDATE]['value'] = $birthdate; + $expectedProperties[IAccountManager::PROPERTY_BIRTHDATE]['scope'] = $birthdateScope; + $expectedProperties[IAccountManager::PROPERTY_PRONOUNS]['value'] = $pronouns; + $expectedProperties[IAccountManager::PROPERTY_PRONOUNS]['scope'] = $pronounsScope; $this->mailer->expects($this->once())->method('validateMailAddress') ->willReturn(true); @@ -485,24 +494,27 @@ class UsersControllerTest extends \Test\TestCase { $address, $addressScope, $twitter, - $twitterScope + $twitterScope, + $bluesky, + $blueskyScope, + $fediverse, + $fediverseScope, + $birthdate, + $birthdateScope, + $pronouns, + $pronounsScope, ); } - /** - * @dataProvider dataTestSetUserSettingsSubset - * - * @param string $property - * @param string $propertyValue - */ - public function testSetUserSettingsSubset($property, $propertyValue) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestSetUserSettingsSubset')] + public function testSetUserSettingsSubset(string $property, string $propertyValue): void { $controller = $this->getController(false, ['saveUserSettings']); $user = $this->createMock(IUser::class); $user->method('getUID')->willReturn('johndoe'); $this->userSession->method('getUser')->willReturn($user); - /** @var IAccount|MockObject $userAccount */ + /** @var IAccount&MockObject $userAccount */ $userAccount = $this->getDefaultAccountMock(); $this->accountManager->expects($this->once()) @@ -523,10 +535,18 @@ class UsersControllerTest extends \Test\TestCase { $addressScope = ($property === 'addressScope') ? $propertyValue : null; $twitter = ($property === 'twitter') ? $propertyValue : null; $twitterScope = ($property === 'twitterScope') ? $propertyValue : null; - - /** @var IAccountProperty[]|MockObject[] $expectedProperties */ + $bluesky = ($property === 'bluesky') ? $propertyValue : null; + $blueskyScope = ($property === 'blueskyScope') ? $propertyValue : null; + $fediverse = ($property === 'fediverse') ? $propertyValue : null; + $fediverseScope = ($property === 'fediverseScope') ? $propertyValue : null; + $birthdate = ($property === 'birthdate') ? $propertyValue : null; + $birthdateScope = ($property === 'birthdateScope') ? $propertyValue : null; + $pronouns = ($property === 'pronouns') ? $propertyValue : null; + $pronounsScope = ($property === 'pronounsScope') ? $propertyValue : null; + + /** @var IAccountProperty[]&MockObject[] $expectedProperties */ $expectedProperties = $userAccount->getProperties(); - $isScope = strrpos($property, 'Scope') === strlen($property) - strlen(5); + $isScope = strrpos($property, 'Scope') === strlen($property) - strlen('5'); switch ($property) { case 'avatarScope': $propertyId = IAccountManager::PROPERTY_AVATAR; @@ -555,6 +575,22 @@ class UsersControllerTest extends \Test\TestCase { case 'twitterScope': $propertyId = IAccountManager::PROPERTY_TWITTER; break; + case 'bluesky': + case 'blueskyScope': + $propertyId = IAccountManager::PROPERTY_BLUESKY; + break; + case 'fediverse': + case 'fediverseScope': + $propertyId = IAccountManager::PROPERTY_FEDIVERSE; + break; + case 'birthdate': + case 'birthdateScope': + $propertyId = IAccountManager::PROPERTY_BIRTHDATE; + break; + case 'pronouns': + case 'pronounsScope': + $propertyId = IAccountManager::PROPERTY_PRONOUNS; + break; default: $propertyId = '404'; } @@ -564,7 +600,7 @@ class UsersControllerTest extends \Test\TestCase { if (!empty($email)) { $this->mailer->expects($this->once())->method('validateMailAddress') - ->willReturn(true); + ->willReturn(true); } $controller->expects($this->once()) @@ -584,11 +620,19 @@ class UsersControllerTest extends \Test\TestCase { $address, $addressScope, $twitter, - $twitterScope + $twitterScope, + $bluesky, + $blueskyScope, + $fediverse, + $fediverseScope, + $birthdate, + $birthdateScope, + $pronouns, + $pronounsScope, ); } - public function dataTestSetUserSettingsSubset() { + public static function dataTestSetUserSettingsSubset(): array { return [ ['avatarScope', IAccountManager::SCOPE_PUBLISHED], ['displayName', 'Display name'], @@ -603,20 +647,19 @@ class UsersControllerTest extends \Test\TestCase { ['addressScope', IAccountManager::SCOPE_PUBLISHED], ['twitter', '@nextclouders'], ['twitterScope', IAccountManager::SCOPE_PUBLISHED], + ['bluesky', 'nextclouders.net'], + ['blueskyScope', IAccountManager::SCOPE_PUBLISHED], + ['fediverse', '@nextclouders@floss.social'], + ['fediverseScope', IAccountManager::SCOPE_PUBLISHED], + ['birthdate', '2020-01-01'], + ['birthdateScope', IAccountManager::SCOPE_PUBLISHED], + ['pronouns', 'he/him'], + ['pronounsScope', IAccountManager::SCOPE_PUBLISHED], ]; } - /** - * @dataProvider dataTestSaveUserSettings - * - * @param array $data - * @param string $oldEmailAddress - * @param string $oldDisplayName - */ - public function testSaveUserSettings($data, - $oldEmailAddress, - $oldDisplayName - ) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestSaveUserSettings')] + public function testSaveUserSettings(array $data, ?string $oldEmailAddress, ?string $oldDisplayName): void { $controller = $this->getController(); $user = $this->createMock(IUser::class); @@ -624,16 +667,14 @@ class UsersControllerTest extends \Test\TestCase { $user->method('getSystemEMailAddress')->willReturn($oldEmailAddress); $user->method('canChangeDisplayName')->willReturn(true); - if ($data[IAccountManager::PROPERTY_EMAIL]['value'] === $oldEmailAddress || - ($oldEmailAddress === null && $data[IAccountManager::PROPERTY_EMAIL]['value'] === '')) { + if (strtolower($data[IAccountManager::PROPERTY_EMAIL]['value']) === strtolower($oldEmailAddress ?? '')) { $user->expects($this->never())->method('setSystemEMailAddress'); } else { $user->expects($this->once())->method('setSystemEMailAddress') ->with($data[IAccountManager::PROPERTY_EMAIL]['value']); } - if ($data[IAccountManager::PROPERTY_DISPLAYNAME]['value'] === $oldDisplayName || - ($oldDisplayName === null && $data[IAccountManager::PROPERTY_DISPLAYNAME]['value'] === '')) { + if ($data[IAccountManager::PROPERTY_DISPLAYNAME]['value'] === $oldDisplayName ?? '') { $user->expects($this->never())->method('setDisplayName'); } else { $user->expects($this->once())->method('setDisplayName') @@ -670,7 +711,7 @@ class UsersControllerTest extends \Test\TestCase { $this->invokePrivate($controller, 'saveUserSettings', [$account]); } - public function dataTestSaveUserSettings() { + public static function dataTestSaveUserSettings(): array { return [ [ [ @@ -720,20 +761,26 @@ class UsersControllerTest extends \Test\TestCase { 'john@example.com', null ], + [ + [ + IAccountManager::PROPERTY_EMAIL => ['value' => 'john@example.com'], + IAccountManager::PROPERTY_DISPLAYNAME => ['value' => 'john doe'], + ], + 'JOHN@example.com', + null + ], ]; } - /** - * @dataProvider dataTestSaveUserSettingsException - */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestSaveUserSettingsException')] public function testSaveUserSettingsException( array $data, string $oldEmailAddress, string $oldDisplayName, - bool $setDisplayNameResult, - bool $canChangeEmail - ) { + bool $setDisplayNameResult, + bool $canChangeEmail, + ): void { $this->expectException(ForbiddenException::class); $controller = $this->getController(); @@ -773,7 +820,7 @@ class UsersControllerTest extends \Test\TestCase { } - public function dataTestSaveUserSettingsException() { + public static function dataTestSaveUserSettingsException(): array { return [ [ [ @@ -809,20 +856,13 @@ class UsersControllerTest extends \Test\TestCase { ]; } - /** - * @param string $account - * @param string $type - * @param array $dataBefore - * @param array $expectedData - * - * @dataProvider dataTestGetVerificationCode - */ - public function testGetVerificationCode($account, $type, $dataBefore, $expectedData, $onlyVerificationCode) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestGetVerificationCode')] + public function testGetVerificationCode(string $account, string $type, array $dataBefore, array $expectedData, bool $onlyVerificationCode): void { $message = 'Use my Federated Cloud ID to share with me: user@nextcloud.com'; $signature = 'theSignature'; $code = $message . ' ' . $signature; - if ($type === IAccountManager::PROPERTY_TWITTER) { + if ($type === IAccountManager::PROPERTY_TWITTER || $type === IAccountManager::PROPERTY_FEDIVERSE) { $code = $message . ' ' . md5($signature); } @@ -876,7 +916,7 @@ class UsersControllerTest extends \Test\TestCase { $this->assertSame($code, $data['code']); } - public function dataTestGetVerificationCode() { + public static function dataTestGetVerificationCode(): array { $accountDataBefore = [ IAccountManager::PROPERTY_WEBSITE => ['value' => 'https://nextcloud.com', 'verified' => IAccountManager::NOT_VERIFIED], IAccountManager::PROPERTY_TWITTER => ['value' => '@nextclouders', 'verified' => IAccountManager::NOT_VERIFIED, 'signature' => 'theSignature'], @@ -903,7 +943,7 @@ class UsersControllerTest extends \Test\TestCase { /** * test get verification code in case no valid user was given */ - public function testGetVerificationCodeInvalidUser() { + public function testGetVerificationCodeInvalidUser(): void { $controller = $this->getController(); $this->userSession->expects($this->once())->method('getUser')->willReturn(null); $result = $controller->getVerificationCode('account', false); @@ -911,18 +951,13 @@ class UsersControllerTest extends \Test\TestCase { $this->assertSame(Http::STATUS_BAD_REQUEST, $result->getStatus()); } - /** - * @dataProvider dataTestCanAdminChangeUserPasswords - * - * @param bool $encryptionEnabled - * @param bool $encryptionModuleLoaded - * @param bool $masterKeyEnabled - * @param bool $expected - */ - public function testCanAdminChangeUserPasswords($encryptionEnabled, - $encryptionModuleLoaded, - $masterKeyEnabled, - $expected) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestCanAdminChangeUserPasswords')] + public function testCanAdminChangeUserPasswords( + bool $encryptionEnabled, + bool $encryptionModuleLoaded, + bool $masterKeyEnabled, + bool $expected, + ): void { $controller = $this->getController(); $this->encryptionManager->expects($this->any()) @@ -945,7 +980,7 @@ class UsersControllerTest extends \Test\TestCase { $this->assertSame($expected, $result); } - public function dataTestCanAdminChangeUserPasswords() { + public static function dataTestCanAdminChangeUserPasswords(): array { return [ // encryptionEnabled, encryptionModuleLoaded, masterKeyEnabled, expectedResult [true, true, true, true], |