diff --git a/IONOS b/IONOS index 724d70e9626c9..0d00d3b21695f 160000 --- a/IONOS +++ b/IONOS @@ -1 +1 @@ -Subproject commit 724d70e9626c92e359a4201ea4d1b6a88a92ada9 +Subproject commit 0d00d3b21695f48eea6e3fbdd766f6153536037a diff --git a/apps/files/lib/Service/UserConfig.php b/apps/files/lib/Service/UserConfig.php index c233996579379..086d54f4b0ea2 100644 --- a/apps/files/lib/Service/UserConfig.php +++ b/apps/files/lib/Service/UserConfig.php @@ -6,6 +6,7 @@ namespace OCA\Files\Service; use OCA\Files\AppInfo\Application; +use OCP\AppFramework\Services\IAppConfig; use OCP\IConfig; use OCP\IUser; use OCP\IUserSession; @@ -52,9 +53,11 @@ class UserConfig { protected IConfig $config; protected ?IUser $user = null; + protected IAppConfig $appConfig; - public function __construct(IConfig $config, IUserSession $userSession) { + public function __construct(IConfig $config, IUserSession $userSession, IAppConfig $appConfig) { $this->config = $config; + $this->appConfig = $appConfig; $this->user = $userSession->getUser(); } @@ -115,7 +118,7 @@ public function setConfig(string $key, $value): void { throw new \InvalidArgumentException('Unknown config key'); } - if (!in_array($value, $this->getAllowedConfigValues($key))) { + if (!in_array($value, $this->getAllowedConfigValues($key), true)) { throw new \InvalidArgumentException('Invalid config value'); } @@ -146,6 +149,13 @@ public function getConfigs(): array { return $value; }, $this->getAllowedConfigKeys()); - return array_combine($this->getAllowedConfigKeys(), $userConfigs); + $userConfigsMerged = array_combine($this->getAllowedConfigKeys(), $userConfigs); + + // override user configs with app configs + $configs = array_map(function (string $key) use ($userConfigsMerged) { + return $this->appConfig->getAppValueBool($key, $userConfigsMerged[$key]); + }, $this->getAllowedConfigKeys()); + + return array_combine($this->getAllowedConfigKeys(), $configs); } } diff --git a/apps/files/tests/Service/UserConfigTest.php b/apps/files/tests/Service/UserConfigTest.php new file mode 100644 index 0000000000000..fb078568ed4fc --- /dev/null +++ b/apps/files/tests/Service/UserConfigTest.php @@ -0,0 +1,226 @@ +configMock = $this->createMock(IConfig::class); + $this->appConfigMock = $this->createMock(IAppConfig::class); + + $this->userUID = static::getUniqueID('user_id-'); + \OC::$server->getUserManager()->createUser($this->userUID, 'test'); + \OC_User::setUserId($this->userUID); + \OC_Util::setupFS($this->userUID); + $this->userMock = $this->getUserMock($this->userUID); + + $this->userSessionMock = $this->createMock(IUserSession::class); + $this->userSessionMock->expects($this->any()) + ->method('getUser') + ->withAnyParameters() + ->willReturn($this->userMock); + + $this->userConfigService = $this->getUserConfigService(['addActivity']); + } + + /** + * @param array $methods + * @return UserConfig|\PHPUnit\Framework\MockObject\MockObject + */ + protected function getUserConfigService(array $methods = []) { + return $this->getMockBuilder(UserConfig::class) + ->setConstructorArgs([ + $this->configMock, + $this->userSessionMock, + $this->appConfigMock, + ]) + ->setMethods($methods) + ->getMock(); + } + + /** + * @param string $uid + * @return IUser|MockObject + */ + protected function getUserMock($uid) { + $user = $this->createMock(IUser::class); + $user->expects($this->any()) + ->method('getUID') + ->willReturn($uid); + return $user; + } + protected function tearDown(): void { + \OC_User::setUserId(''); + $user = \OC::$server->getUserManager()->get($this->userUID); + if ($user !== null) { + $user->delete(); + } + } + public function testThrowsExceptionWhenNoUserLoggedInForSetConfig(): void { + $this->userSessionMock = $this->createMock(IUserSession::class); + $this->userSessionMock->expects($this->any()) + ->method('getUser') + ->withAnyParameters() + ->willReturn(null); + + $this->expectException(\Exception::class); + $this->expectExceptionMessage('No user logged in'); + + $userConfig = new UserConfig($this->configMock, $this->userSessionMock, $this->appConfigMock); + $userConfig->setConfig('crop_image_previews', true); + } + + public function testThrowsInvalidArgumentExceptionForUnknownConfigKey(): void { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Unknown config key'); + + $userConfig = new UserConfig($this->configMock, $this->userSessionMock, $this->appConfigMock); + $userConfig->setConfig('unknown_key', true); + } + + public function testThrowsInvalidArgumentExceptionForInvalidConfigValue(): void { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid config value'); + + $userConfig = new UserConfig($this->configMock, $this->userSessionMock, $this->appConfigMock); + $userConfig->setConfig('crop_image_previews', 'foo'); + } + + public function testSetsConfigSuccessfully(): void { + $this->configMock->expects($this->once()) + ->method('setUserValue') + ->with($this->userUID, Application::APP_ID, 'crop_image_previews', '1'); + $userConfig = new UserConfig($this->configMock, $this->userSessionMock, $this->appConfigMock); + $userConfig->setConfig('crop_image_previews', true); + } + + public function testGetsConfigsWithDefaultValuesSuccessfully(): void { + $this->userSessionMock->method('getUser')->willReturn($this->userMock); + $this->configMock->method('getUserValue') + ->willReturnCallback(function ($userId, $appId, $key, $default) { + return $default; + }); + + // pass the default app settings unchanged + $this->appConfigMock->method('getAppValueBool') + ->willReturnCallback(function ($key, $default) { + return $default; + }); + + $userConfig = new UserConfig($this->configMock, $this->userSessionMock, $this->appConfigMock); + $configs = $userConfig->getConfigs(); + $this->assertEquals([ + 'crop_image_previews' => true, + 'show_hidden' => false, + 'sort_favorites_first' => true, + 'sort_folders_first' => true, + 'grid_view' => false, + 'folder_tree' => true, + ], $configs); + } + + public function testGetsConfigsOverrideWithUserValuesSuccessfully(): void { + $this->userSessionMock->method('getUser')->willReturn($this->userMock); + $this->configMock->method('getUserValue') + ->willReturnCallback(function ($userId, $appId, $key, $default) { + + // Override the default values + if ($key === 'crop_image_previews') { + return !$default; + } elseif ($key === 'show_hidden') { + return !$default; + } + + return $default; + }); + + // pass the default app settings unchanged + $this->appConfigMock->method('getAppValueBool') + ->willReturnCallback(function ($key, $default) { + return $default; + }); + + $userConfig = new UserConfig($this->configMock, $this->userSessionMock, $this->appConfigMock); + $configs = $userConfig->getConfigs(); + $this->assertEquals([ + 'crop_image_previews' => false, + 'show_hidden' => true, + 'sort_favorites_first' => true, + 'sort_folders_first' => true, + 'grid_view' => false, + 'folder_tree' => true, + ], $configs); + } + + public function testGetsConfigsOverrideWithAppsValuesSuccessfully(): void { + $this->userSessionMock->method('getUser')->willReturn($this->userMock); + + // set all user values to true + $this->configMock->method('getUserValue') + ->willReturnCallback(function () { + return true; + }); + + // emulate override by the app config values + $this->appConfigMock->method('getAppValueBool') + ->willReturnCallback(function ($key, $default) { + if ($key === 'crop_image_previews') { + return false; + } elseif ($key === 'show_hidden') { + return false; + } + return $default; + }); + + $userConfig = new UserConfig($this->configMock, $this->userSessionMock, $this->appConfigMock); + $configs = $userConfig->getConfigs(); + $this->assertEquals([ + 'crop_image_previews' => false, + 'show_hidden' => false, + 'sort_favorites_first' => true, + 'sort_folders_first' => true, + 'grid_view' => true, + 'folder_tree' => true, + ], $configs); + } +}