diff options
Diffstat (limited to 'tests/Core/Command')
-rw-r--r-- | tests/Core/Command/Apps/AppsDisableTest.php | 8 | ||||
-rw-r--r-- | tests/Core/Command/Apps/AppsEnableTest.php | 13 | ||||
-rw-r--r-- | tests/Core/Command/Encryption/ChangeKeyStorageRootTest.php | 3 | ||||
-rw-r--r-- | tests/Core/Command/Encryption/DecryptAllTest.php | 8 | ||||
-rw-r--r-- | tests/Core/Command/Encryption/SetDefaultModuleTest.php | 2 | ||||
-rw-r--r-- | tests/Core/Command/Log/FileTest.php | 2 | ||||
-rw-r--r-- | tests/Core/Command/Maintenance/Mimetype/UpdateDBTest.php | 6 | ||||
-rw-r--r-- | tests/Core/Command/Preview/RepairTest.php | 2 | ||||
-rw-r--r-- | tests/Core/Command/SystemTag/AddTest.php | 2 | ||||
-rw-r--r-- | tests/Core/Command/SystemTag/DeleteTest.php | 2 | ||||
-rw-r--r-- | tests/Core/Command/SystemTag/EditTest.php | 2 | ||||
-rw-r--r-- | tests/Core/Command/User/AddTest.php | 4 | ||||
-rw-r--r-- | tests/Core/Command/User/ProfileTest.php | 470 | ||||
-rw-r--r-- | tests/Core/Command/User/SettingTest.php | 41 |
14 files changed, 514 insertions, 51 deletions
diff --git a/tests/Core/Command/Apps/AppsDisableTest.php b/tests/Core/Command/Apps/AppsDisableTest.php index ce43222e44e..283727c1a04 100644 --- a/tests/Core/Command/Apps/AppsDisableTest.php +++ b/tests/Core/Command/Apps/AppsDisableTest.php @@ -9,6 +9,8 @@ declare(strict_types=1); namespace Tests\Core\Command\Config; use OC\Core\Command\App\Disable; +use OCP\App\IAppManager; +use OCP\Server; use Symfony\Component\Console\Tester\CommandTester; use Test\TestCase; @@ -25,13 +27,13 @@ class AppsDisableTest extends TestCase { parent::setUp(); $command = new Disable( - \OC::$server->getAppManager() + Server::get(IAppManager::class) ); $this->commandTester = new CommandTester($command); - \OC::$server->getAppManager()->enableApp('admin_audit'); - \OC::$server->getAppManager()->enableApp('comments'); + Server::get(IAppManager::class)->enableApp('admin_audit'); + Server::get(IAppManager::class)->enableApp('comments'); } /** diff --git a/tests/Core/Command/Apps/AppsEnableTest.php b/tests/Core/Command/Apps/AppsEnableTest.php index 59b5dad6406..efaa7da984b 100644 --- a/tests/Core/Command/Apps/AppsEnableTest.php +++ b/tests/Core/Command/Apps/AppsEnableTest.php @@ -10,6 +10,9 @@ namespace Tests\Core\Command\Config; use OC\Core\Command\App\Enable; use OC\Installer; +use OCP\App\IAppManager; +use OCP\IGroupManager; +use OCP\Server; use Symfony\Component\Console\Tester\CommandTester; use Test\TestCase; @@ -26,15 +29,15 @@ class AppsEnableTest extends TestCase { parent::setUp(); $command = new Enable( - \OC::$server->getAppManager(), - \OC::$server->getGroupManager(), - \OC::$server->get(Installer::class), + Server::get(IAppManager::class), + Server::get(IGroupManager::class), + Server::get(Installer::class), ); $this->commandTester = new CommandTester($command); - \OC::$server->getAppManager()->disableApp('admin_audit'); - \OC::$server->getAppManager()->disableApp('comments'); + Server::get(IAppManager::class)->disableApp('admin_audit'); + Server::get(IAppManager::class)->disableApp('comments'); } /** diff --git a/tests/Core/Command/Encryption/ChangeKeyStorageRootTest.php b/tests/Core/Command/Encryption/ChangeKeyStorageRootTest.php index 8232db70504..a2d1434e905 100644 --- a/tests/Core/Command/Encryption/ChangeKeyStorageRootTest.php +++ b/tests/Core/Command/Encryption/ChangeKeyStorageRootTest.php @@ -8,6 +8,7 @@ namespace Tests\Core\Command\Encryption; use OC\Core\Command\Encryption\ChangeKeyStorageRoot; +use OC\Encryption\Keys\Storage; use OC\Encryption\Util; use OC\Files\View; use OCP\IConfig; @@ -157,7 +158,7 @@ class ChangeKeyStorageRootTest extends TestCase { ->willReturn(true); $this->view->expects($this->once())->method('file_put_contents') - ->with('newRoot/' . \OC\Encryption\Keys\Storage::KEY_STORAGE_MARKER, + ->with('newRoot/' . Storage::KEY_STORAGE_MARKER, 'Nextcloud will detect this folder as key storage root only if this file exists')->willReturn(true); $this->invokePrivate($this->changeKeyStorageRoot, 'prepareNewRoot', ['newRoot']); diff --git a/tests/Core/Command/Encryption/DecryptAllTest.php b/tests/Core/Command/Encryption/DecryptAllTest.php index 45b331efb59..ea22c101845 100644 --- a/tests/Core/Command/Encryption/DecryptAllTest.php +++ b/tests/Core/Command/Encryption/DecryptAllTest.php @@ -79,7 +79,7 @@ class DecryptAllTest extends TestCase { ]; $this->config->expects($this->exactly(2)) ->method('setSystemValue') - ->willReturnCallback(function () use (&$calls) { + ->willReturnCallback(function () use (&$calls): void { $expected = array_shift($calls); $this->assertEquals($expected, func_get_args()); }); @@ -137,7 +137,7 @@ class DecryptAllTest extends TestCase { ]; $this->config->expects($this->exactly(2)) ->method('setAppValue') - ->willReturnCallback(function () use (&$calls) { + ->willReturnCallback(function () use (&$calls): void { $expected = array_shift($calls); $this->assertEquals($expected, func_get_args()); }); @@ -188,7 +188,7 @@ class DecryptAllTest extends TestCase { ]; $this->config->expects($this->exactly(2)) ->method('setAppValue') - ->willReturnCallback(function () use (&$calls) { + ->willReturnCallback(function () use (&$calls): void { $expected = array_shift($calls); $this->assertEquals($expected, func_get_args()); }); @@ -208,7 +208,7 @@ class DecryptAllTest extends TestCase { $this->decryptAll->expects($this->once()) ->method('decryptAll') ->with($this->consoleInput, $this->consoleOutput, 'user1') - ->willReturnCallback(function () { + ->willReturnCallback(function (): void { throw new \Exception(); }); diff --git a/tests/Core/Command/Encryption/SetDefaultModuleTest.php b/tests/Core/Command/Encryption/SetDefaultModuleTest.php index 52f14dd4537..4ba7b7e8c97 100644 --- a/tests/Core/Command/Encryption/SetDefaultModuleTest.php +++ b/tests/Core/Command/Encryption/SetDefaultModuleTest.php @@ -119,7 +119,7 @@ class SetDefaultModuleTest extends TestCase { ]; $this->consoleOutput->expects($this->exactly(2)) ->method('writeln') - ->willReturnCallback(function ($message) use (&$calls) { + ->willReturnCallback(function ($message) use (&$calls): void { $expected = array_shift($calls); $this->assertStringContainsString($expected, $message); }); diff --git a/tests/Core/Command/Log/FileTest.php b/tests/Core/Command/Log/FileTest.php index 1286fca35a3..627f2b0e08f 100644 --- a/tests/Core/Command/Log/FileTest.php +++ b/tests/Core/Command/Log/FileTest.php @@ -103,7 +103,7 @@ class FileTest extends TestCase { ]; $this->consoleOutput->expects($this->exactly(3)) ->method('writeln') - ->willReturnCallback(function (string $message) use (&$calls) { + ->willReturnCallback(function (string $message) use (&$calls): void { $expected = array_shift($calls); $this->assertEquals($expected[0], $message); }); diff --git a/tests/Core/Command/Maintenance/Mimetype/UpdateDBTest.php b/tests/Core/Command/Maintenance/Mimetype/UpdateDBTest.php index 2f232837fe2..532e965cc89 100644 --- a/tests/Core/Command/Maintenance/Mimetype/UpdateDBTest.php +++ b/tests/Core/Command/Maintenance/Mimetype/UpdateDBTest.php @@ -65,7 +65,7 @@ class UpdateDBTest extends TestCase { ]; $this->consoleOutput->expects($this->exactly(2)) ->method('writeln') - ->willReturnCallback(function ($message) use (&$calls) { + ->willReturnCallback(function ($message) use (&$calls): void { $expected = array_shift($calls); $this->assertStringContainsString($expected, $message); }); @@ -110,7 +110,7 @@ class UpdateDBTest extends TestCase { ]; $this->consoleOutput->expects($this->exactly(4)) ->method('writeln') - ->willReturnCallback(function ($message) use (&$calls) { + ->willReturnCallback(function ($message) use (&$calls): void { $expected = array_shift($calls); $this->assertStringContainsString($expected, $message); }); @@ -163,7 +163,7 @@ class UpdateDBTest extends TestCase { ]; $this->consoleOutput->expects($this->exactly(3)) ->method('writeln') - ->willReturnCallback(function ($message) use (&$calls) { + ->willReturnCallback(function ($message) use (&$calls): void { $expected = array_shift($calls); $this->assertStringContainsString($expected, $message); }); diff --git a/tests/Core/Command/Preview/RepairTest.php b/tests/Core/Command/Preview/RepairTest.php index d522816e531..7e45a8d3a19 100644 --- a/tests/Core/Command/Preview/RepairTest.php +++ b/tests/Core/Command/Preview/RepairTest.php @@ -79,7 +79,7 @@ class RepairTest extends TestCase { ->willReturn($outputFormatter); $this->output->expects($this->any()) ->method('writeln') - ->willReturnCallback(function ($line) use ($self) { + ->willReturnCallback(function ($line) use ($self): void { $self->outputLines .= $line . "\n"; }); } diff --git a/tests/Core/Command/SystemTag/AddTest.php b/tests/Core/Command/SystemTag/AddTest.php index b697cd1d2f0..68d9b494502 100644 --- a/tests/Core/Command/SystemTag/AddTest.php +++ b/tests/Core/Command/SystemTag/AddTest.php @@ -93,7 +93,7 @@ class AddTest extends TestCase { $tag->method('getAccessLevel')->willReturn(ISystemTag::ACCESS_LEVEL_PUBLIC); $this->systemTagManager->method('createTag') - ->willReturnCallback(function ($tagName, $userVisible, $userAssignable) { + ->willReturnCallback(function ($tagName, $userVisible, $userAssignable): void { throw new TagAlreadyExistsException( 'Tag ("' . $tagName . '", ' . $userVisible . ', ' . $userAssignable . ') already exists' ); diff --git a/tests/Core/Command/SystemTag/DeleteTest.php b/tests/Core/Command/SystemTag/DeleteTest.php index 3c7a6e24c21..716b6a3b830 100644 --- a/tests/Core/Command/SystemTag/DeleteTest.php +++ b/tests/Core/Command/SystemTag/DeleteTest.php @@ -69,7 +69,7 @@ class DeleteTest extends TestCase { }); $this->systemTagManager->method('deleteTags') - ->willReturnCallback(function ($tagId) { + ->willReturnCallback(function ($tagId): void { throw new TagNotFoundException(); }); diff --git a/tests/Core/Command/SystemTag/EditTest.php b/tests/Core/Command/SystemTag/EditTest.php index 637172222eb..cc68f8004f5 100644 --- a/tests/Core/Command/SystemTag/EditTest.php +++ b/tests/Core/Command/SystemTag/EditTest.php @@ -134,7 +134,7 @@ class EditTest extends TestCase { }); $this->systemTagManager->method('updateTag') - ->willReturnCallback(function ($tagId, $tagName, $userVisible, $userAssignable) { + ->willReturnCallback(function ($tagId, $tagName, $userVisible, $userAssignable): void { throw new TagAlreadyExistsException( 'Tag ("' . $tagName . '", ' . $userVisible . ', ' . $userAssignable . ') already exists' ); diff --git a/tests/Core/Command/User/AddTest.php b/tests/Core/Command/User/AddTest.php index 91535ea6670..546061fc2f0 100644 --- a/tests/Core/Command/User/AddTest.php +++ b/tests/Core/Command/User/AddTest.php @@ -111,11 +111,11 @@ class AddTest extends TestCase { ->method('sendMail'); $this->consoleInput->method('getOption') - ->will(static::returnValueMap([ + ->willReturnMap([ ['generate-password', 'true'], ['email', $email], ['group', []], - ])); + ]); $this->invokePrivate($this->addCommand, 'execute', [ $this->consoleInput, diff --git a/tests/Core/Command/User/ProfileTest.php b/tests/Core/Command/User/ProfileTest.php new file mode 100644 index 00000000000..2e3227ab56b --- /dev/null +++ b/tests/Core/Command/User/ProfileTest.php @@ -0,0 +1,470 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace Core\Command\User; + +use OC\Core\Command\User\Profile; +use OCP\Accounts\IAccount; +use OCP\Accounts\IAccountManager; +use OCP\Accounts\IAccountProperty; +use OCP\IDBConnection; +use OCP\IUser; +use OCP\IUserManager; +use PHPUnit\Framework\MockObject\MockObject; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Test\TestCase; + +class ProfileTest extends TestCase { + + protected IAccountManager&MockObject $accountManager; + protected IUserManager&MockObject $userManager; + protected IDBConnection&MockObject $connection; + protected InputInterface&MockObject $consoleInput; + protected OutputInterface&MockObject $consoleOutput; + + protected function setUp(): void { + parent::setUp(); + + $this->accountManager = $this->createMock(IAccountManager::class); + $this->userManager = $this->createMock(IUserManager::class); + $this->connection = $this->createMock(IDBConnection::class); + $this->consoleInput = $this->createMock(InputInterface::class); + $this->consoleOutput = $this->createMock(OutputInterface::class); + } + + public function getCommand(array $methods = []): Profile|MockObject { + if (empty($methods)) { + return new Profile($this->userManager, $this->accountManager); + } else { + return $this->getMockBuilder(Profile::class) + ->setConstructorArgs([ + $this->userManager, + $this->accountManager, + ]) + ->onlyMethods($methods) + ->getMock(); + } + } + + public static function dataCheckInput(): array { + return [ + 'Call with existing user should pass check' => [ + [['uid', 'username']], + [], + [], + true, + null, + ], + 'Call with non-existing user should fail check' => [ + [['uid', 'username']], + [], + [], + false, + 'The user "username" does not exist.', + ], + + 'Call with uid, key and --default value should pass check' => [ + [['uid', 'username'], ['key', 'configkey']], + [], + [['--default-value', false, true]], + true, + null, + ], + 'Call with uid and empty key with default-value option should fail check' => [ + [['uid', 'username'], ['key', '']], + [], + [['--default-value', false, true]], + true, + 'The "default-value" option can only be used when specifying a key.', + ], + + 'Call with uid, key, value should pass check' => [ + [['uid', 'username'], ['key', 'configkey'], ['value', '']], + [], + [], + true, + null, + ], + 'Call with uid, empty key and empty value should fail check' => [ + [['uid', 'username'], ['key', ''], ['value', '']], + [], + [], + true, + 'The value argument can only be used when specifying a key.', + ], + 'Call with uid, key, empty value and default-value option should fail check' => [ + [['uid', 'username'], ['key', 'configkey'], ['value', '']], + [], + [['--default-value', false, true]], + true, + 'The value argument can not be used together with "default-value".', + ], + 'Call with uid, key, empty value and update-only option should pass check' => [ + [['uid', 'username'], ['key', 'configkey'], ['value', '']], + [['update-only', true]], + [], + true, + null, + ], + 'Call with uid, key, null value and update-only option should fail check' => [ + [['uid', 'username'], ['key', 'configkey'], ['value', null]], + [['update-only', true]], + [], + true, + 'The "update-only" option can only be used together with "value".', + ], + + 'Call with uid, key and delete option should pass check' => [ + [['uid', 'username'], ['key', 'configkey']], + [['delete', true]], + [], + true, + null, + ], + 'Call with uid, empty key and delete option should fail check' => [ + [['uid', 'username'], ['key', '']], + [['delete', true]], + [], + true, + 'The "delete" option can only be used when specifying a key.', + ], + 'Call with uid, key, delete option and default-value should fail check' => [ + [['uid', 'username'], ['key', 'configkey']], + [['delete', true]], + [['--default-value', false, true]], + true, + 'The "delete" option can not be used together with "default-value".', + ], + 'Call with uid, key, empty value and delete option should fail check' => [ + [['uid', 'username'], ['key', 'configkey'], ['value', '']], + [['delete', true]], + [], + true, + 'The "delete" option can not be used together with "value".', + ], + 'Call with uid, key, delete and error-if-not-exists should pass check' => [ + [['uid', 'username'], ['key', 'configkey']], + [['delete', true], ['error-if-not-exists', true]], + [], + true, + null, + ], + 'Call with uid, key and error-if-not-exists should fail check' => [ + [['uid', 'username'], ['key', 'configkey']], + [['delete', false], ['error-if-not-exists', true]], + [], + true, + 'The "error-if-not-exists" option can only be used together with "delete".', + ], + ]; + } + + /** + * @dataProvider dataCheckInput + */ + public function testCheckInput(array $arguments, array $options, array $parameterOptions, bool $existingUser, ?string $expectedException): void { + $this->consoleInput->expects($this->any()) + ->method('getArgument') + ->willReturnMap($arguments); + $this->consoleInput->expects($this->any()) + ->method('getOption') + ->willReturnMap($options); + $this->consoleInput->expects($this->any()) + ->method('hasParameterOption') + ->willReturnCallback(function (string|array $values, bool $onlyParams = false) use ($parameterOptions): bool { + $arguments = func_get_args(); + foreach ($parameterOptions as $parameterOption) { + // check the arguments of the function, if they are the same, return the mocked value + if (array_diff($arguments, $parameterOption) === []) { + return end($parameterOption); + } + } + + return false; + }); + + $returnedUser = null; + if ($existingUser) { + $mockUser = $this->createMock(IUser::class); + $mockUser->expects($this->once())->method('getUID')->willReturn('user'); + $returnedUser = $mockUser; + } + $this->userManager->expects($this->once()) + ->method('get') + ->willReturn($returnedUser); + + $command = $this->getCommand(); + try { + $this->invokePrivate($command, 'checkInput', [$this->consoleInput]); + $this->assertNull($expectedException); + } catch (\InvalidArgumentException $e) { + $this->assertEquals($expectedException, $e->getMessage()); + } + } + + public function testCheckInputExceptionCatch(): void { + $command = $this->getCommand(['checkInput']); + $command->expects($this->once()) + ->method('checkInput') + ->willThrowException(new \InvalidArgumentException('test')); + + $this->consoleOutput->expects($this->once()) + ->method('writeln') + ->with('<error>test</error>'); + + $this->assertEquals(1, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput])); + } + + public static function dataExecuteDeleteProfileProperty(): array { + return [ + 'Deleting existing property should succeed' => ['address', 'Berlin', false, null, Command::SUCCESS], + 'Deleting existing property with error-if-not-exists should succeed' => ['address', 'Berlin', true, null, Command::SUCCESS], + 'Deleting non-existing property should succeed' => ['address', '', false, null, Command::SUCCESS], + 'Deleting non-existing property with error-if-not-exists should fail' => ['address', '', true, '<error>The property does not exist for user "username".</error>', Command::FAILURE], + ]; + } + + /** + * Tests the deletion mechanism on profile settings. + * + * @dataProvider dataExecuteDeleteProfileProperty + */ + public function testExecuteDeleteProfileProperty(string $configKey, string $value, bool $errorIfNotExists, ?string $expectedLine, int $expectedReturn): void { + $uid = 'username'; + $appName = 'profile'; + $command = $this->getCommand([ + 'writeArrayInOutputFormat', + 'checkInput', + ]); + + $this->consoleInput->expects($this->any()) + ->method('getArgument') + ->willReturnMap([ + ['uid', $uid], + ['app', $appName], + ['key', $configKey], + ]); + + $mocks = $this->setupProfilePropertiesMock([$configKey => $value]); + + $command->expects($this->once()) + ->method('checkInput') + ->willReturn($mocks['userMock']); + + $this->consoleInput->expects($this->atLeastOnce()) + ->method('hasParameterOption') + ->willReturnMap([ + ['--delete', false, true], + ['--error-if-not-exists', false, $errorIfNotExists], + ]); + + if ($expectedLine === null) { + $this->consoleOutput->expects($this->never()) + ->method('writeln'); + $mocks['profilePropertiesMocks'][0]->expects($this->once()) + ->method('setValue') + ->with(''); + $this->accountManager->expects($this->once()) + ->method('updateAccount') + ->with($mocks['accountMock']); + } else { + $this->consoleOutput->expects($this->once()) + ->method('writeln') + ->with($expectedLine); + $this->accountManager->expects($this->never()) + ->method('updateAccount'); + } + + $this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput])); + } + + public function testExecuteSetProfileProperty(): void { + $command = $this->getCommand([ + 'writeArrayInOutputFormat', + 'checkInput', + ]); + + $uid = 'username'; + $propertyKey = 'address'; + $propertyValue = 'Barcelona'; + + $this->consoleInput->expects($this->atLeast(3)) + ->method('getArgument') + ->willReturnMap([ + ['uid', $uid], + ['key', $propertyKey], + ['value', $propertyValue], + ]); + + $mocks = $this->setupProfilePropertiesMock([$propertyKey => $propertyValue]); + + $command->expects($this->once()) + ->method('checkInput') + ->willReturn($mocks['userMock']); + + $mocks['profilePropertiesMocks'][0]->expects($this->once()) + ->method('setValue') + ->with($propertyValue); + $this->accountManager->expects($this->once()) + ->method('updateAccount') + ->with($mocks['accountMock']); + + $this->assertEquals(0, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput])); + } + + public static function dataExecuteGet(): array { + return [ + 'Get property with set value should pass' => ['configkey', 'value', null, 'value', Command::SUCCESS], + 'Get property with empty value and default-value option should pass' => ['configkey', '', 'default-value', 'default-value', Command::SUCCESS], + 'Get property with empty value should fail' => ['configkey', '', null, '<error>The property does not exist for user "username".</error>', Command::FAILURE], + ]; + } + + /** + * @dataProvider dataExecuteGet + */ + public function testExecuteGet(string $key, string $value, ?string $defaultValue, string $expectedLine, int $expectedReturn): void { + $command = $this->getCommand([ + 'writeArrayInOutputFormat', + 'checkInput', + ]); + + $uid = 'username'; + + $this->consoleInput->expects($this->any()) + ->method('getArgument') + ->willReturnMap([ + ['uid', $uid], + ['key', $key], + ]); + + $mocks = $this->setupProfilePropertiesMock([$key => $value]); + + $command->expects($this->once()) + ->method('checkInput') + ->willReturn($mocks['userMock']); + + if ($value === '') { + if ($defaultValue === null) { + $this->consoleInput->expects($this->atLeastOnce()) + ->method('hasParameterOption') + ->willReturn(false); + } else { + $this->consoleInput->expects($this->atLeastOnce()) + ->method('hasParameterOption') + ->willReturnCallback(fn (string|array $values): bool => $values === '--default-value'); + $this->consoleInput->expects($this->once()) + ->method('getOption') + ->with('default-value') + ->willReturn($defaultValue); + } + } + + $this->consoleOutput->expects($this->once()) + ->method('writeln') + ->with($expectedLine); + + $this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput])); + } + + public function testExecuteList(): void { + $uid = 'username'; + $profileData = [ + 'pronouns' => 'they/them', + 'address' => 'Berlin', + ]; + + $command = $this->getCommand([ + 'writeArrayInOutputFormat', + 'checkInput', + ]); + + $this->consoleInput->expects($this->any()) + ->method('getArgument') + ->willReturnMap([ + ['uid', $uid], + ['key', ''], + ]); + + $mocks = $this->setupProfilePropertiesMock(['address' => $profileData['address'], 'pronouns' => $profileData['pronouns']]); + + $command->expects($this->once()) + ->method('checkInput') + ->willReturn($mocks['userMock']); + + $command->expects($this->once()) + ->method('writeArrayInOutputFormat') + ->with($this->consoleInput, $this->consoleOutput, $profileData); + + + $this->assertEquals(0, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput])); + } + + /** + * Helper to avoid boilerplate in tests in this file when mocking objects + * of IAccountProperty type. + * + * @param array<string, string> $properties the properties to be set up as key => value + * @return array{ + * userMock: IUser&MockObject, + * accountMock: IAccount&MockObject, + * profilePropertiesMocks: IAccountProperty&MockObject[] + * } + */ + private function setupProfilePropertiesMock(array $properties): array { + $userMock = $this->createMock(IUser::class); + $accountMock = $this->createMock(IAccount::class); + $this->accountManager->expects($this->atLeastOnce()) + ->method('getAccount') + ->with($userMock) + ->willReturn($accountMock); + + /** @var IAccountProperty&MockObject[] $propertiesMocks */ + $propertiesMocks = []; + foreach ($properties as $key => $value) { + $propertiesMocks[] = $this->getAccountPropertyMock($key, $value); + } + + if (count($properties) === 1) { + $accountMock->expects($this->atLeastOnce()) + ->method('getProperty') + ->with(array_keys($properties)[0]) + ->willReturn($propertiesMocks[array_key_first($propertiesMocks)]); + } else { + $accountMock->expects($this->atLeastOnce()) + ->method('getAllProperties') + ->willReturnCallback(function () use ($propertiesMocks) { + foreach ($propertiesMocks as $property) { + yield $property; + } + }); + } + + return [ + 'userMock' => $userMock, + 'accountMock' => $accountMock, + 'profilePropertiesMocks' => $propertiesMocks, + ]; + } + + private function getAccountPropertyMock(string $name, string $value): IAccountProperty&MockObject { + $propertyMock = $this->getMockBuilder(IAccountProperty::class) + ->disableOriginalConstructor() + ->getMock(); + $propertyMock->expects($this->any()) + ->method('getName') + ->willReturn($name); + $propertyMock->expects($this->any()) + ->method('getValue') + ->willReturn($value); + + return $propertyMock; + } +} diff --git a/tests/Core/Command/User/SettingTest.php b/tests/Core/Command/User/SettingTest.php index e9e150b78de..dbe81c5af78 100644 --- a/tests/Core/Command/User/SettingTest.php +++ b/tests/Core/Command/User/SettingTest.php @@ -7,44 +7,31 @@ namespace Tests\Core\Command\User; +use InvalidArgumentException; use OC\Core\Command\User\Setting; use OCP\IConfig; use OCP\IDBConnection; use OCP\IUserManager; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Test\TestCase; class SettingTest extends TestCase { - /** @var \OCP\IUserManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $userManager; - /** @var \OCP\IConfig|\PHPUnit\Framework\MockObject\MockObject */ - protected $config; - /** @var \OCP\IDBConnection|\PHPUnit\Framework\MockObject\MockObject */ - protected $connection; - /** @var \Symfony\Component\Console\Input\InputInterface|\PHPUnit\Framework\MockObject\MockObject */ - protected $consoleInput; - /** @var \Symfony\Component\Console\Output\OutputInterface|\PHPUnit\Framework\MockObject\MockObject */ - protected $consoleOutput; + protected IUserManager&MockObject $userManager; + protected IConfig&MockObject $config; + protected IDBConnection&MockObject $connection; + protected InputInterface&MockObject $consoleInput; + protected MockObject&OutputInterface $consoleOutput; protected function setUp(): void { parent::setUp(); - $this->userManager = $this->getMockBuilder(IUserManager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->config = $this->getMockBuilder(IConfig::class) - ->disableOriginalConstructor() - ->getMock(); - $this->connection = $this->getMockBuilder(IDBConnection::class) - ->disableOriginalConstructor() - ->getMock(); - $this->consoleInput = $this->getMockBuilder(InputInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->consoleOutput = $this->getMockBuilder(OutputInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $this->userManager = $this->createMock(IUserManager::class); + $this->config = $this->createMock(IConfig::class); + $this->connection = $this->createMock(IDBConnection::class); + $this->consoleInput = $this->createMock(InputInterface::class); + $this->consoleOutput = $this->createMock(OutputInterface::class); } public function getCommand(array $methods = []) { @@ -217,7 +204,7 @@ class SettingTest extends TestCase { try { $this->invokePrivate($command, 'checkInput', [$this->consoleInput]); $this->assertFalse($expectedException); - } catch (\InvalidArgumentException $e) { + } catch (InvalidArgumentException $e) { $this->assertEquals($expectedException, $e->getMessage()); } } @@ -226,7 +213,7 @@ class SettingTest extends TestCase { $command = $this->getCommand(['checkInput']); $command->expects($this->once()) ->method('checkInput') - ->willThrowException(new \InvalidArgumentException('test')); + ->willThrowException(new InvalidArgumentException('test')); $this->consoleOutput->expects($this->once()) ->method('writeln') |