diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2024-02-12 18:09:13 -0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-12 18:09:13 -0100 |
commit | 592012034e8ee3438d20f33486e785a29b819c2f (patch) | |
tree | 515d7ea4a623cccdace2f09e1cea9e000830c468 /tests | |
parent | 919288603a6657ffb5d2461e02f82c1c157e07a9 (diff) | |
parent | 809e0fe923adf23d34a6707bd7a65562736a071c (diff) | |
download | nextcloud-server-592012034e8ee3438d20f33486e785a29b819c2f.tar.gz nextcloud-server-592012034e8ee3438d20f33486e785a29b819c2f.zip |
Merge pull request #43370 from nextcloud/test-iappconfig
[IAppConfig] new tests
Diffstat (limited to 'tests')
-rw-r--r-- | tests/lib/AppConfigTest.php | 1486 |
1 files changed, 1241 insertions, 245 deletions
diff --git a/tests/lib/AppConfigTest.php b/tests/lib/AppConfigTest.php index a4d4119ba96..fe3f1b8385b 100644 --- a/tests/lib/AppConfigTest.php +++ b/tests/lib/AppConfigTest.php @@ -1,16 +1,33 @@ <?php + +declare(strict_types=1); /** - * Copyright (c) 2013 Christopher Schäpers <christopher@schaepers.it> - * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. + * @copyright Copyright (c) 2024, Maxence Lange <maxence@artificial-owl.com> + * + * @author Maxence Lange <maxence@artificial-owl.com> + * + * @license AGPL-3.0 or later + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * */ - namespace Test; +use InvalidArgumentException; use OC\AppConfig; -use OCP\IConfig; +use OCP\Exceptions\AppConfigTypeConflictException; +use OCP\Exceptions\AppConfigUnknownKeyException; +use OCP\IAppConfig; use OCP\IDBConnection; use Psr\Log\LoggerInterface; @@ -22,13 +39,62 @@ use Psr\Log\LoggerInterface; * @package Test */ class AppConfigTest extends TestCase { - /** @var \OCP\IAppConfig */ - protected $appConfig; - + protected IAppConfig $appConfig; protected IDBConnection $connection; private LoggerInterface $logger; + private array $originalConfig; - protected $originalConfig; + /** + * @var array<string, array<array<string, string, int, bool, bool>>> + * [appId => [configKey, configValue, valueType, lazy, sensitive]] + */ + private static array $baseStruct = + [ + 'testapp' => [ + ['enabled', 'true'], + ['installed_version', '1.2.3'], + ['depends_on', 'someapp'], + ['deletethis', 'deletethis'], + ['key', 'value'] + ], + 'someapp' => [ + ['key', 'value'], + ['otherkey', 'othervalue'] + ], + '123456' => [ + ['enabled', 'true'], + ['key', 'value'] + ], + 'anotherapp' => [ + ['enabled', 'false'], + ['key', 'value'] + ], + 'non-sensitive-app' => [ + ['lazy-key', 'value', IAppConfig::VALUE_STRING, true, false], + ['non-lazy-key', 'value', IAppConfig::VALUE_STRING, false, false], + ], + 'sensitive-app' => [ + ['lazy-key', 'value', IAppConfig::VALUE_STRING, true, true], + ['non-lazy-key', 'value', IAppConfig::VALUE_STRING, false, true], + ], + 'only-lazy' => [ + ['lazy-key', 'value', IAppConfig::VALUE_STRING, true] + ], + 'typed' => [ + ['mixed', 'mix', IAppConfig::VALUE_MIXED], + ['string', 'value', IAppConfig::VALUE_STRING], + ['int', '42', IAppConfig::VALUE_INT], + ['float', '3.14', IAppConfig::VALUE_FLOAT], + ['bool', '1', IAppConfig::VALUE_BOOL], + ['array', '{"test": 1}', IAppConfig::VALUE_ARRAY], + ], + 'prefix-app' => [ + ['key1', 'value'], + ['prefix1', 'value'], + ['prefix-2', 'value'], + ['key-2', 'value'], + ] + ]; protected function setUp(): void { parent::setUp(); @@ -36,101 +102,68 @@ class AppConfigTest extends TestCase { $this->connection = \OC::$server->get(IDBConnection::class); $this->logger = \OC::$server->get(LoggerInterface::class); + // storing current config and emptying the data table $sql = $this->connection->getQueryBuilder(); $sql->select('*') ->from('appconfig'); - $result = $sql->execute(); + $result = $sql->executeQuery(); $this->originalConfig = $result->fetchAll(); $result->closeCursor(); $sql = $this->connection->getQueryBuilder(); $sql->delete('appconfig'); - $sql->execute(); + $sql->executeStatement(); - $this->overwriteService(AppConfig::class, new \OC\AppConfig($this->connection, $this->logger)); + // $this->overwriteService(AppConfig::class, new \OC\AppConfig($this->connection, $this->logger)); $sql = $this->connection->getQueryBuilder(); $sql->insert('appconfig') - ->values([ - 'appid' => $sql->createParameter('appid'), - 'configkey' => $sql->createParameter('configkey'), - 'configvalue' => $sql->createParameter('configvalue') - ]); - - $sql->setParameters([ - 'appid' => 'testapp', - 'configkey' => 'enabled', - 'configvalue' => 'true' - ])->execute(); - $sql->setParameters([ - 'appid' => 'testapp', - 'configkey' => 'installed_version', - 'configvalue' => '1.2.3', - ])->execute(); - $sql->setParameters([ - 'appid' => 'testapp', - 'configkey' => 'depends_on', - 'configvalue' => 'someapp', - ])->execute(); - $sql->setParameters([ - 'appid' => 'testapp', - 'configkey' => 'deletethis', - 'configvalue' => 'deletethis', - ])->execute(); - $sql->setParameters([ - 'appid' => 'testapp', - 'configkey' => 'key', - 'configvalue' => 'value', - ])->execute(); - - $sql->setParameters([ - 'appid' => 'someapp', - 'configkey' => 'key', - 'configvalue' => 'value', - ])->execute(); - $sql->setParameters([ - 'appid' => 'someapp', - 'configkey' => 'otherkey', - 'configvalue' => 'othervalue', - ])->execute(); - - $sql->setParameters([ - 'appid' => '123456', - 'configkey' => 'key', - 'configvalue' => 'value', - ])->execute(); - $sql->setParameters([ - 'appid' => '123456', - 'configkey' => 'enabled', - 'configvalue' => 'false', - ])->execute(); - - $sql->setParameters([ - 'appid' => 'anotherapp', - 'configkey' => 'key', - 'configvalue' => 'value', - ])->execute(); - $sql->setParameters([ - 'appid' => 'anotherapp', - 'configkey' => 'enabled', - 'configvalue' => 'false', - ])->execute(); + ->values( + [ + 'appid' => $sql->createParameter('appid'), + 'configkey' => $sql->createParameter('configkey'), + 'configvalue' => $sql->createParameter('configvalue'), + 'type' => $sql->createParameter('type'), + 'lazy' => $sql->createParameter('lazy') + ] + ); + + foreach (self::$baseStruct as $appId => $appData) { + foreach ($appData as $row) { + $type = $row[2] ?? IAppConfig::VALUE_MIXED; + if (($row[4] ?? false) === true) { + $type = $type | IAppConfig::VALUE_SENSITIVE; + } + + $sql->setParameters( + [ + 'appid' => $appId, + 'configkey' => $row[0], + 'configvalue' => $row[1], + 'type' => $type, + 'lazy' => (($row[3] ?? false) === true) ? 1 : 0 + ] + )->executeStatement(); + } + } } protected function tearDown(): void { $sql = $this->connection->getQueryBuilder(); $sql->delete('appconfig'); - $sql->execute(); + $sql->executeStatement(); $sql = $this->connection->getQueryBuilder(); $sql->insert('appconfig') - ->values([ - 'appid' => $sql->createParameter('appid'), - 'configkey' => $sql->createParameter('configkey'), - 'configvalue' => $sql->createParameter('configvalue'), - 'lazy' => $sql->createParameter('lazy'), - 'type' => $sql->createParameter('type'), - ]); + ->values( + [ + 'appid' => $sql->createParameter('appid'), + 'configkey' => $sql->createParameter('configkey'), + 'configvalue' => $sql->createParameter('configvalue'), + 'lazy' => $sql->createParameter('lazy'), + 'type' => $sql->createParameter('type'), + ] + ); foreach ($this->originalConfig as $configs) { $sql->setParameter('appid', $configs['appid']) @@ -138,228 +171,1191 @@ class AppConfigTest extends TestCase { ->setParameter('configvalue', $configs['configvalue']) ->setParameter('lazy', ($configs['lazy'] === '1') ? '1' : '0') ->setParameter('type', $configs['type']); - $sql->execute(); + $sql->executeStatement(); } - $this->restoreService(AppConfig::class); + // $this->restoreService(AppConfig::class); parent::tearDown(); } - public function testGetApps() { - $config = new \OC\AppConfig(\OC::$server->get(IDBConnection::class), \OC::$server->get(LoggerInterface::class)); + /** + * @param bool $preLoading TRUE will preload the 'fast' cache, which is the normal behavior of usual + * IAppConfig + * + * @return IAppConfig + */ + private function generateAppConfig(bool $preLoading = true): IAppConfig { + /** @var AppConfig $config */ + $config = new \OC\AppConfig($this->connection, $this->logger); + $msg = ' generateAppConfig() failed to confirm cache status'; + + // confirm cache status + $status = $config->statusCache(); + $this->assertSame(false, $status['fastLoaded'], $msg); + $this->assertSame(false, $status['lazyLoaded'], $msg); + $this->assertSame([], $status['fastCache'], $msg); + $this->assertSame([], $status['lazyCache'], $msg); + if ($preLoading) { + // simple way to initiate the load of non-lazy config values in cache + $config->getValueString('core', 'preload', ''); + + // confirm cache status + $status = $config->statusCache(); + $this->assertSame(true, $status['fastLoaded'], $msg); + $this->assertSame(false, $status['lazyLoaded'], $msg); + + $apps = array_values(array_diff(array_keys(self::$baseStruct), ['only-lazy'])); + $this->assertEqualsCanonicalizing($apps, array_keys($status['fastCache']), $msg); + $this->assertSame([], array_keys($status['lazyCache']), $msg); + } - $this->assertEqualsCanonicalizing([ - 'anotherapp', - 'someapp', - 'testapp', - 123456, - ], $config->getApps()); + return $config; } - public function testGetKeys() { - $config = new \OC\AppConfig(\OC::$server->get(IDBConnection::class), \OC::$server->get(LoggerInterface::class)); + public function testGetApps(): void { + $config = $this->generateAppConfig(false); - $keys = $config->getKeys('testapp'); - $this->assertEqualsCanonicalizing([ - 'deletethis', - 'depends_on', - 'enabled', - 'installed_version', - 'key', - ], $keys); + $this->assertEqualsCanonicalizing(array_keys(self::$baseStruct), $config->getApps()); } - public function testGetValue() { - $config = new \OC\AppConfig(\OC::$server->get(IDBConnection::class), \OC::$server->get(LoggerInterface::class)); + /** + * returns list of app and their keys + * + * @return array<string, string[]> ['appId' => ['key1', 'key2', ]] + * @see testGetKeys + */ + public function providerGetAppKeys(): array { + $appKeys = []; + foreach (self::$baseStruct as $appId => $appData) { + $keys = []; + foreach ($appData as $row) { + $keys[] = $row[0]; + } + $appKeys[] = [(string)$appId, $keys]; + } - $value = $config->getValue('testapp', 'installed_version'); - $this->assertConfigKey('testapp', 'installed_version', $value); + return $appKeys; + } - $value = $config->getValue('testapp', 'nonexistant'); - $this->assertNull($value); + /** + * returns list of config keys + * + * @return array<string, string, string, int, bool, bool> [appId, key, value, type, lazy, sensitive] + * @see testIsSensitive + * @see testIsLazy + * @see testGetKeys + */ + public function providerGetKeys(): array { + $appKeys = []; + foreach (self::$baseStruct as $appId => $appData) { + foreach ($appData as $row) { + $appKeys[] = [ + (string)$appId, $row[0], $row[1], $row[2] ?? IAppConfig::VALUE_MIXED, $row[3] ?? false, + $row[4] ?? false + ]; + } + } - $value = $config->getValue('testapp', 'nonexistant', 'default'); - $this->assertEquals('default', $value); + return $appKeys; } - public function testHasKey() { - $config = new \OC\AppConfig(\OC::$server->get(IDBConnection::class), \OC::$server->get(LoggerInterface::class)); + /** + * @dataProvider providerGetAppKeys + * + * @param string $appId + * @param array $expectedKeys + */ + public function testGetKeys(string $appId, array $expectedKeys): void { + $config = $this->generateAppConfig(); + $this->assertEqualsCanonicalizing($expectedKeys, $config->getKeys($appId)); + } - $this->assertTrue($config->hasKey('testapp', 'installed_version')); - $this->assertFalse($config->hasKey('testapp', 'nonexistant')); - $this->assertFalse($config->hasKey('nonexistant', 'nonexistant')); + public function testGetKeysOnUnknownAppShouldReturnsEmptyArray(): void { + $config = $this->generateAppConfig(); + $this->assertEqualsCanonicalizing([], $config->getKeys('unknown-app')); } - public function testSetValueUpdate() { - $config = new \OC\AppConfig(\OC::$server->get(IDBConnection::class), \OC::$server->get(LoggerInterface::class)); + /** + * @dataProvider providerGetKeys + * + * @param string $appId + * @param string $configKey + * @param string $value + * @param bool $lazy + */ + public function testHasKey(string $appId, string $configKey, string $value, int $type, bool $lazy): void { + $config = $this->generateAppConfig(); + $this->assertEquals(true, $config->hasKey($appId, $configKey, $lazy)); + } - $this->assertEquals('1.2.3', $config->getValue('testapp', 'installed_version')); - $this->assertConfigKey('testapp', 'installed_version', '1.2.3'); + public function testHasKeyOnNonExistentKeyReturnsFalse(): void { + $config = $this->generateAppConfig(); + $this->assertEquals(false, $config->hasKey(array_keys(self::$baseStruct)[0], 'inexistant-key')); + } - $wasModified = $config->setValue('testapp', 'installed_version', '1.2.3'); - if (!(\OC::$server->get(IDBConnection::class) instanceof \OC\DB\OracleConnection)) { - $this->assertFalse($wasModified); - } + public function testHasKeyOnUnknownAppReturnsFalse(): void { + $config = $this->generateAppConfig(); + $this->assertEquals(false, $config->hasKey('inexistant-app', 'inexistant-key')); + } - $this->assertEquals('1.2.3', $config->getValue('testapp', 'installed_version')); - $this->assertConfigKey('testapp', 'installed_version', '1.2.3'); + public function testHasKeyOnMistypedAsLazyReturnsFalse(): void { + $config = $this->generateAppConfig(); + $this->assertSame(false, $config->hasKey('non-sensitive-app', 'non-lazy-key', true)); + } - $this->assertTrue($config->setValue('testapp', 'installed_version', '1.33.7')); + public function testHasKeyOnMistypeAsNonLazyReturnsFalse(): void { + $config = $this->generateAppConfig(); + $this->assertSame(false, $config->hasKey('non-sensitive-app', 'lazy-key', false)); + } + public function testHasKeyOnMistypeAsNonLazyReturnsTrueWithLazyArgumentIsNull(): void { + $config = $this->generateAppConfig(); + $this->assertSame(true, $config->hasKey('non-sensitive-app', 'lazy-key', null)); + } - $this->assertEquals('1.33.7', $config->getValue('testapp', 'installed_version')); - $this->assertConfigKey('testapp', 'installed_version', '1.33.7'); + /** + * @dataProvider providerGetKeys + */ + public function testIsSensitive( + string $appId, string $configKey, string $configValue, int $type, bool $lazy, bool $sensitive + ): void { + $config = $this->generateAppConfig(); + $this->assertEquals($sensitive, $config->isSensitive($appId, $configKey, $lazy)); + } - $config->setValue('someapp', 'somekey', 'somevalue'); - $this->assertConfigKey('someapp', 'somekey', 'somevalue'); + public function testIsSensitiveOnNonExistentKeyThrowsException(): void { + $config = $this->generateAppConfig(); + $this->expectException(AppConfigUnknownKeyException::class); + $config->isSensitive(array_keys(self::$baseStruct)[0], 'inexistant-key'); } - public function testSetValueInsert() { - $config = new \OC\AppConfig(\OC::$server->get(IDBConnection::class), \OC::$server->get(LoggerInterface::class)); + public function testIsSensitiveOnUnknownAppThrowsException(): void { + $config = $this->generateAppConfig(); + $this->expectException(AppConfigUnknownKeyException::class); + $config->isSensitive('unknown-app', 'inexistant-key'); + } - $this->assertFalse($config->hasKey('someapp', 'somekey')); - $this->assertNull($config->getValue('someapp', 'somekey')); + public function testIsSensitiveOnSensitiveMistypedAsLazy(): void { + $config = $this->generateAppConfig(); + $this->assertSame(true, $config->isSensitive('sensitive-app', 'non-lazy-key', true)); + } - $this->assertTrue($config->setValue('someapp', 'somekey', 'somevalue')); + public function testIsSensitiveOnNonSensitiveMistypedAsLazy(): void { + $config = $this->generateAppConfig(); + $this->assertSame(false, $config->isSensitive('non-sensitive-app', 'non-lazy-key', true)); + } - $this->assertTrue($config->hasKey('someapp', 'somekey')); - $this->assertEquals('somevalue', $config->getValue('someapp', 'somekey')); - $this->assertConfigKey('someapp', 'somekey', 'somevalue'); + public function testIsSensitiveOnSensitiveMistypedAsNonLazyThrowsException(): void { + $config = $this->generateAppConfig(); + $this->expectException(AppConfigUnknownKeyException::class); + $config->isSensitive('sensitive-app', 'lazy-key', false); + } - $wasInserted = $config->setValue('someapp', 'somekey', 'somevalue'); - if (!(\OC::$server->get(IDBConnection::class) instanceof \OC\DB\OracleConnection)) { - $this->assertFalse($wasInserted); - } + public function testIsSensitiveOnNonSensitiveMistypedAsNonLazyThrowsException(): void { + $config = $this->generateAppConfig(); + $this->expectException(AppConfigUnknownKeyException::class); + $config->isSensitive('non-sensitive-app', 'lazy-key', false); } - public function testDeleteKey() { - $config = new \OC\AppConfig(\OC::$server->get(IDBConnection::class), \OC::$server->get(LoggerInterface::class)); + /** + * @dataProvider providerGetKeys + */ + public function testIsLazy(string $appId, string $configKey, string $configValue, int $type, bool $lazy + ): void { + $config = $this->generateAppConfig(); + $this->assertEquals($lazy, $config->isLazy($appId, $configKey)); + } - $this->assertTrue($config->hasKey('testapp', 'deletethis')); + public function testIsLazyOnNonExistentKeyThrowsException(): void { + $config = $this->generateAppConfig(); + $this->expectException(AppConfigUnknownKeyException::class); + $config->isLazy(array_keys(self::$baseStruct)[0], 'inexistant-key'); + } - $config->deleteKey('testapp', 'deletethis'); + public function testIsLazyOnUnknownAppThrowsException(): void { + $config = $this->generateAppConfig(); + $this->expectException(AppConfigUnknownKeyException::class); + $config->isLazy('unknown-app', 'inexistant-key'); + } - $this->assertFalse($config->hasKey('testapp', 'deletethis')); + public function testGetAllValuesWithEmptyApp(): void { + $config = $this->generateAppConfig(); + $this->expectException(InvalidArgumentException::class); + $config->getAllValues(''); + } - $sql = \OC::$server->getDatabaseConnection()->getQueryBuilder(); - $sql->select('configvalue') - ->from('appconfig') - ->where($sql->expr()->eq('appid', $sql->createParameter('appid'))) - ->andWhere($sql->expr()->eq('configkey', $sql->createParameter('configkey'))) - ->setParameter('appid', 'testapp') - ->setParameter('configkey', 'deletethis'); - $query = $sql->execute(); - $result = $query->fetch(); - $query->closeCursor(); - $this->assertFalse($result); + /** + * @dataProvider providerGetAppKeys + * + * @param string $appId + * @param array $keys + */ + public function testGetAllValuesWithEmptyKey(string $appId, array $keys): void { + $config = $this->generateAppConfig(); + $this->assertEqualsCanonicalizing($keys, array_keys($config->getAllValues($appId, ''))); } - public function testDeleteApp() { - $config = new \OC\AppConfig(\OC::$server->get(IDBConnection::class), \OC::$server->get(LoggerInterface::class)); + public function testGetAllValuesWithPrefix(): void { + $config = $this->generateAppConfig(); + $this->assertEqualsCanonicalizing(['prefix1', 'prefix-2'], array_keys($config->getAllValues('prefix-app', 'prefix'))); + } - $this->assertTrue($config->hasKey('someapp', 'otherkey')); + public function testSearchValues(): void { + $config = $this->generateAppConfig(); + $this->assertEqualsCanonicalizing(['testapp' => 'true', '123456' => 'true', 'anotherapp' => 'false'], $config->searchValues('enabled')); + } - $config->deleteApp('someapp'); + public function testGetValueString(): void { + $config = $this->generateAppConfig(); + $this->assertSame('value', $config->getValueString('typed', 'string', '')); + } - $this->assertFalse($config->hasKey('someapp', 'otherkey')); + public function testGetValueStringOnUnknownAppReturnsDefault(): void { + $config = $this->generateAppConfig(); + $this->assertSame('default-1', $config->getValueString('typed-1', 'string', 'default-1')); + } - $sql = \OC::$server->getDatabaseConnection()->getQueryBuilder(); - $sql->select('configvalue') - ->from('appconfig') - ->where($sql->expr()->eq('appid', $sql->createParameter('appid'))) - ->setParameter('appid', 'someapp'); - $query = $sql->execute(); - $result = $query->fetch(); - $query->closeCursor(); - $this->assertFalse($result); + public function testGetValueStringOnNonExistentKeyReturnsDefault(): void { + $config = $this->generateAppConfig(); + $this->assertSame('default-2', $config->getValueString('typed', 'string-2', 'default-2')); } - public function testGetValuesNotAllowed() { - $config = new \OC\AppConfig(\OC::$server->get(IDBConnection::class), \OC::$server->get(LoggerInterface::class)); + public function testGetValueStringOnWrongType(): void { + $config = $this->generateAppConfig(); + $this->expectException(AppConfigTypeConflictException::class); + $config->getValueString('typed', 'int'); + } - $this->assertFalse($config->getValues('testapp', 'enabled')); + public function testGetNonLazyValueStringAsLazy(): void { + $config = $this->generateAppConfig(); + $this->assertSame('value', $config->getValueString('non-sensitive-app', 'non-lazy-key', 'default', lazy: true)); + } - $this->assertFalse($config->getValues(false, false)); + public function testGetValueInt() { + $config = $this->generateAppConfig(); + $this->assertSame(42, $config->getValueInt('typed', 'int', 0)); } - public function testGetValues() { - $config = new \OC\AppConfig(\OC::$server->get(IDBConnection::class), \OC::$server->get(LoggerInterface::class)); + public function testGetValueIntOnUnknownAppReturnsDefault(): void { + $config = $this->generateAppConfig(); + $this->assertSame(1, $config->getValueInt('typed-1', 'int', 1)); + } - $sql = \OC::$server->getDatabaseConnection()->getQueryBuilder(); - $sql->select(['configkey', 'configvalue']) - ->from('appconfig') - ->where($sql->expr()->eq('appid', $sql->createParameter('appid'))) - ->setParameter('appid', 'testapp'); - $query = $sql->execute(); - $expected = []; - while ($row = $query->fetch()) { - $expected[$row['configkey']] = $row['configvalue']; - } - $query->closeCursor(); - - $values = $config->getValues('testapp', false); - $this->assertEquals($expected, $values); - - $sql = \OC::$server->getDatabaseConnection()->getQueryBuilder(); - $sql->select(['appid', 'configvalue']) - ->from('appconfig') - ->where($sql->expr()->eq('configkey', $sql->createParameter('configkey'))) - ->setParameter('configkey', 'enabled'); - $query = $sql->execute(); - $expected = []; - while ($row = $query->fetch()) { - $expected[$row['appid']] = $row['configvalue']; - } - $query->closeCursor(); + public function testGetValueIntOnNonExistentKeyReturnsDefault() { + $config = $this->generateAppConfig(); + $this->assertSame(2, $config->getValueInt('typed', 'int-2', 2)); + } - $values = $config->getValues(false, 'enabled'); - $this->assertEquals($expected, $values); + public function testGetValueIntOnWrongType(): void { + $config = $this->generateAppConfig(); + $this->expectException(AppConfigTypeConflictException::class); + $config->getValueInt('typed', 'float'); } - public function testGetFilteredValues() { - $config = new \OC\AppConfig(\OC::$server->get(IDBConnection::class), \OC::$server->get(LoggerInterface::class)); - $config->setValue('user_ldap', 'ldap_agent_password', 'secret'); - $config->setValue('user_ldap', 's42ldap_agent_password', 'secret'); - $config->setValue('user_ldap', 'ldap_dn', 'dn'); + public function testGetValueFloat() { + $config = $this->generateAppConfig(); + $this->assertSame(3.14, $config->getValueFloat('typed', 'float', 0)); + } + + public function testGetValueFloatOnNonUnknownAppReturnsDefault(): void { + $config = $this->generateAppConfig(); + $this->assertSame(1.11, $config->getValueFloat('typed-1', 'float', 1.11)); + } + + public function testGetValueFloatOnNonExistentKeyReturnsDefault() { + $config = $this->generateAppConfig(); + $this->assertSame(2.22, $config->getValueFloat('typed', 'float-2', 2.22)); + } - $values = $config->getFilteredValues('user_ldap'); - $this->assertEquals([ - 'ldap_agent_password' => IConfig::SENSITIVE_VALUE, - 's42ldap_agent_password' => IConfig::SENSITIVE_VALUE, - 'ldap_dn' => 'dn', - ], $values); + public function testGetValueFloatOnWrongType(): void { + $config = $this->generateAppConfig(); + $this->expectException(AppConfigTypeConflictException::class); + $config->getValueFloat('typed', 'bool'); } - public function testSettingConfigParallel() { - $appConfig1 = new \OC\AppConfig(\OC::$server->get(IDBConnection::class), \OC::$server->get(LoggerInterface::class)); - $appConfig2 = new \OC\AppConfig(\OC::$server->get(IDBConnection::class), \OC::$server->get(LoggerInterface::class)); - $appConfig1->getValue('testapp', 'foo', 'v1'); - $appConfig2->getValue('testapp', 'foo', 'v1'); + public function testGetValueBool(): void { + $config = $this->generateAppConfig(); + $this->assertSame(true, $config->getValueBool('typed', 'bool')); + } - $appConfig1->setValue('testapp', 'foo', 'v1'); - $this->assertConfigKey('testapp', 'foo', 'v1'); + public function testGetValueBoolOnUnknownAppReturnsDefault(): void { + $config = $this->generateAppConfig(); + $this->assertSame(false, $config->getValueBool('typed-1', 'bool', false)); + } - $appConfig2->setValue('testapp', 'foo', 'v2'); - $this->assertConfigKey('testapp', 'foo', 'v2'); + public function testGetValueBoolOnNonExistentKeyReturnsDefault(): void { + $config = $this->generateAppConfig(); + $this->assertSame(false, $config->getValueBool('typed', 'bool-2')); } + public function testGetValueBoolOnWrongType(): void { + $config = $this->generateAppConfig(); + $this->expectException(AppConfigTypeConflictException::class); + $config->getValueBool('typed', 'array'); + } + + public function testGetValueArray(): void { + $config = $this->generateAppConfig(); + $this->assertEqualsCanonicalizing(['test' => 1], $config->getValueArray('typed', 'array', [])); + } + + public function testGetValueArrayOnUnknownAppReturnsDefault(): void { + $config = $this->generateAppConfig(); + $this->assertSame([1], $config->getValueArray('typed-1', 'array', [1])); + } + + public function testGetValueArrayOnNonExistentKeyReturnsDefault(): void { + $config = $this->generateAppConfig(); + $this->assertSame([1, 2], $config->getValueArray('typed', 'array-2', [1, 2])); + } + + public function testGetValueArrayOnWrongType(): void { + $config = $this->generateAppConfig(); + $this->expectException(AppConfigTypeConflictException::class); + $config->getValueArray('typed', 'string'); + } + + /** - * @param string $app + * @return array + * @see testGetValueType + * + * @see testGetValueMixed + */ + public function providerGetValueMixed(): array { + return [ + // key, value, type + ['mixed', 'mix', IAppConfig::VALUE_MIXED], + ['string', 'value', IAppConfig::VALUE_STRING], + ['int', '42', IAppConfig::VALUE_INT], + ['float', '3.14', IAppConfig::VALUE_FLOAT], + ['bool', '1', IAppConfig::VALUE_BOOL], + ['array', '{"test": 1}', IAppConfig::VALUE_ARRAY], + ]; + } + + /** + * @dataProvider providerGetValueMixed + * + * @param string $key + * @param string $value + */ + public function testGetValueMixed(string $key, string $value): void { + $config = $this->generateAppConfig(); + $this->assertSame($value, $config->getValueMixed('typed', $key)); + } + + /** + * @dataProvider providerGetValueMixed + * * @param string $key - * @param string $expected + * @param string $value + * @param int $type */ - protected function assertConfigKey($app, $key, $expected) { - $sql = \OC::$server->getDatabaseConnection()->getQueryBuilder(); - $sql->select('configvalue') - ->from('appconfig') - ->where($sql->expr()->eq('appid', $sql->createParameter('appid'))) - ->andWhere($sql->expr()->eq('configkey', $sql->createParameter('configkey'))) - ->setParameter('appid', $app) - ->setParameter('configkey', $key); - $query = $sql->execute(); - $actual = $query->fetch(); - $query->closeCursor(); - - $this->assertEquals($expected, $actual['configvalue']); + public function testGetValueType(string $key, string $value, int $type): void { + $config = $this->generateAppConfig(); + $this->assertSame($type, $config->getValueType('typed', $key)); + } + + public function testGetValueTypeOnUnknownApp(): void { + $config = $this->generateAppConfig(); + $this->expectException(AppConfigUnknownKeyException::class); + $config->getValueType('typed-1', 'string'); + } + + public function testGetValueTypeOnNonExistentKey(): void { + $config = $this->generateAppConfig(); + $this->expectException(AppConfigUnknownKeyException::class); + $config->getValueType('typed', 'string-2'); + } + + public function testSetValueString(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1'); + $this->assertSame('value-1', $config->getValueString('feed', 'string', '')); + } + + public function testSetValueStringCache(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1'); + $status = $config->statusCache(); + $this->assertSame('value-1', $status['fastCache']['feed']['string']); + } + + public function testSetValueStringDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1'); + $config->clearCache(); + $this->assertSame('value-1', $config->getValueString('feed', 'string', '')); + } + + public function testSetValueStringIsUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1'); + $this->assertSame(true, $config->setValueString('feed', 'string', 'value-2')); + } + + public function testSetValueStringIsNotUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1'); + $this->assertSame(false, $config->setValueString('feed', 'string', 'value-1')); + } + + public function testSetValueStringIsUpdatedCache(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1'); + $config->setValueString('feed', 'string', 'value-2'); + $status = $config->statusCache(); + $this->assertSame('value-2', $status['fastCache']['feed']['string']); + } + + public function testSetValueStringIsUpdatedDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1'); + $config->setValueString('feed', 'string', 'value-2'); + $config->clearCache(); + $this->assertSame('value-2', $config->getValueString('feed', 'string', '')); + } + + public function testSetValueInt(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42); + $this->assertSame(42, $config->getValueInt('feed', 'int', 0)); + } + + public function testSetValueIntCache(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42); + $status = $config->statusCache(); + $this->assertSame('42', $status['fastCache']['feed']['int']); + } + + public function testSetValueIntDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42); + $config->clearCache(); + $this->assertSame(42, $config->getValueInt('feed', 'int', 0)); + } + + public function testSetValueIntIsUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42); + $this->assertSame(true, $config->setValueInt('feed', 'int', 17)); + } + + public function testSetValueIntIsNotUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42); + $this->assertSame(false, $config->setValueInt('feed', 'int', 42)); + } + + public function testSetValueIntIsUpdatedCache(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42); + $config->setValueInt('feed', 'int', 17); + $status = $config->statusCache(); + $this->assertSame('17', $status['fastCache']['feed']['int']); + } + + public function testSetValueIntIsUpdatedDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42); + $config->setValueInt('feed', 'int', 17); + $config->clearCache(); + $this->assertSame(17, $config->getValueInt('feed', 'int', 0)); + } + + public function testSetValueFloat(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14); + $this->assertSame(3.14, $config->getValueFloat('feed', 'float', 0)); + } + + public function testSetValueFloatCache(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14); + $status = $config->statusCache(); + $this->assertSame('3.14', $status['fastCache']['feed']['float']); + } + + public function testSetValueFloatDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14); + $config->clearCache(); + $this->assertSame(3.14, $config->getValueFloat('feed', 'float', 0)); + } + + public function testSetValueFloatIsUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14); + $this->assertSame(true, $config->setValueFloat('feed', 'float', 1.23)); + } + + public function testSetValueFloatIsNotUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14); + $this->assertSame(false, $config->setValueFloat('feed', 'float', 3.14)); + } + + public function testSetValueFloatIsUpdatedCache(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14); + $config->setValueFloat('feed', 'float', 1.23); + $status = $config->statusCache(); + $this->assertSame('1.23', $status['fastCache']['feed']['float']); + } + + public function testSetValueFloatIsUpdatedDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14); + $config->setValueFloat('feed', 'float', 1.23); + $config->clearCache(); + $this->assertSame(1.23, $config->getValueFloat('feed', 'float', 0)); + } + + public function testSetValueBool(): void { + $config = $this->generateAppConfig(); + $config->setValueBool('feed', 'bool', true); + $this->assertSame(true, $config->getValueBool('feed', 'bool', false)); + } + + public function testSetValueBoolCache(): void { + $config = $this->generateAppConfig(); + $config->setValueBool('feed', 'bool', true); + $status = $config->statusCache(); + $this->assertSame('1', $status['fastCache']['feed']['bool']); + } + + public function testSetValueBoolDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueBool('feed', 'bool', true); + $config->clearCache(); + $this->assertSame(true, $config->getValueBool('feed', 'bool', false)); + } + + public function testSetValueBoolIsUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueBool('feed', 'bool', true); + $this->assertSame(true, $config->setValueBool('feed', 'bool', false)); + } + + public function testSetValueBoolIsNotUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueBool('feed', 'bool', true); + $this->assertSame(false, $config->setValueBool('feed', 'bool', true)); + } + + public function testSetValueBoolIsUpdatedCache(): void { + $config = $this->generateAppConfig(); + $config->setValueBool('feed', 'bool', true); + $config->setValueBool('feed', 'bool', false); + $status = $config->statusCache(); + $this->assertSame('0', $status['fastCache']['feed']['bool']); + } + + public function testSetValueBoolIsUpdatedDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueBool('feed', 'bool', true); + $config->setValueBool('feed', 'bool', false); + $config->clearCache(); + $this->assertSame(false, $config->getValueBool('feed', 'bool', true)); + } + + + public function testSetValueArray(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1]); + $this->assertSame(['test' => 1], $config->getValueArray('feed', 'array', [])); + } + + public function testSetValueArrayCache(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1]); + $status = $config->statusCache(); + $this->assertSame('{"test":1}', $status['fastCache']['feed']['array']); + } + + public function testSetValueArrayDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1]); + $config->clearCache(); + $this->assertSame(['test' => 1], $config->getValueArray('feed', 'array', [])); + } + + public function testSetValueArrayIsUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1]); + $this->assertSame(true, $config->setValueArray('feed', 'array', ['test' => 2])); + } + + public function testSetValueArrayIsNotUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1]); + $this->assertSame(false, $config->setValueArray('feed', 'array', ['test' => 1])); + } + + public function testSetValueArrayIsUpdatedCache(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1]); + $config->setValueArray('feed', 'array', ['test' => 2]); + $status = $config->statusCache(); + $this->assertSame('{"test":2}', $status['fastCache']['feed']['array']); + } + + public function testSetValueArrayIsUpdatedDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1]); + $config->setValueArray('feed', 'array', ['test' => 2]); + $config->clearCache(); + $this->assertSame(['test' => 2], $config->getValueArray('feed', 'array', [])); + } + + public function testSetLazyValueString(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1', true); + $this->assertSame('value-1', $config->getValueString('feed', 'string', '', true)); + } + + public function testSetLazyValueStringCache(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1', true); + $status = $config->statusCache(); + $this->assertSame('value-1', $status['lazyCache']['feed']['string']); + } + + public function testSetLazyValueStringDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1', true); + $config->clearCache(); + $this->assertSame('value-1', $config->getValueString('feed', 'string', '', true)); + } + + public function testSetLazyValueStringAsNonLazy(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1', true); + $config->setValueString('feed', 'string', 'value-1', false); + $this->assertSame('value-1', $config->getValueString('feed', 'string', '')); + } + + public function testSetNonLazyValueStringAsLazy(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1', false); + $config->setValueString('feed', 'string', 'value-1', true); + $this->assertSame('value-1', $config->getValueString('feed', 'string', '', true)); + } + + public function testSetSensitiveValueString(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1', sensitive: true); + $this->assertSame('value-1', $config->getValueString('feed', 'string', '')); + } + + public function testSetSensitiveValueStringCache(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1', sensitive: true); + $status = $config->statusCache(); + // TODO: this value will be encrypted with #43114 + $this->assertSame('value-1', $status['fastCache']['feed']['string']); + } + + public function testSetSensitiveValueStringDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1', sensitive: true); + $config->clearCache(); + $this->assertSame('value-1', $config->getValueString('feed', 'string', '')); + } + + public function testSetNonSensitiveValueStringAsSensitive(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1', sensitive: false); + $config->setValueString('feed', 'string', 'value-1', sensitive: true); + $this->assertSame(true, $config->isSensitive('feed', 'string')); + } + + public function testSetSensitiveValueStringAsNonSensitiveStaysSensitive(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1', sensitive: true); + $config->setValueString('feed', 'string', 'value-2', sensitive: false); + $this->assertSame(true, $config->isSensitive('feed', 'string')); + } + + public function testSetSensitiveValueStringAsNonSensitiveAreStillUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1', sensitive: true); + $config->setValueString('feed', 'string', 'value-2', sensitive: false); + $this->assertSame('value-2', $config->getValueString('feed', 'string', '')); + } + + public function testSetSensitiveValueStringAsNonSensitiveWouldFailForSameValue(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', 'value-1', sensitive: true); + $this->assertSame(false, $config->setValueString('feed', 'string', 'value-1')); + } + + public function testSetLazyValueInt(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42, true); + $this->assertSame(42, $config->getValueInt('feed', 'int', 0, true)); + } + + public function testSetLazyValueIntCache(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42, true); + $status = $config->statusCache(); + $this->assertSame('42', $status['lazyCache']['feed']['int']); + } + + public function testSetLazyValueIntDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42, true); + $config->clearCache(); + $this->assertSame(42, $config->getValueInt('feed', 'int', 0, true)); + } + + public function testSetLazyValueIntAsNonLazy(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42, true); + $config->setValueInt('feed', 'int', 42, false); + $this->assertSame(42, $config->getValueInt('feed', 'int', 0)); + } + + public function testSetNonLazyValueIntAsLazy(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42, false); + $config->setValueInt('feed', 'int', 42, true); + $this->assertSame(42, $config->getValueInt('feed', 'int', 0, true)); + } + + public function testSetSensitiveValueInt(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42, sensitive: true); + $this->assertSame(42, $config->getValueInt('feed', 'int', 0)); + } + + public function testSetSensitiveValueIntCache(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42, sensitive: true); + $status = $config->statusCache(); + // TODO: this value will be encrypted with #43114 + $this->assertSame('42', $status['fastCache']['feed']['int']); + } + + public function testSetSensitiveValueIntDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42, sensitive: true); + $config->clearCache(); + $this->assertSame(42, $config->getValueInt('feed', 'int', 0)); + } + + public function testSetNonSensitiveValueIntAsSensitive(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42); + $config->setValueInt('feed', 'int', 42, sensitive: true); + $this->assertSame(true, $config->isSensitive('feed', 'int')); + } + + public function testSetSensitiveValueIntAsNonSensitiveStaysSensitive(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42, sensitive: true); + $config->setValueInt('feed', 'int', 17); + $this->assertSame(true, $config->isSensitive('feed', 'int')); + } + + public function testSetSensitiveValueIntAsNonSensitiveAreStillUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42, sensitive: true); + $config->setValueInt('feed', 'int', 17); + $this->assertSame(17, $config->getValueInt('feed', 'int', 0)); + } + + public function testSetSensitiveValueIntAsNonSensitiveWouldFailForSameValue(): void { + $config = $this->generateAppConfig(); + $config->setValueInt('feed', 'int', 42, sensitive: true); + $this->assertSame(false, $config->setValueInt('feed', 'int', 42)); + } + + public function testSetLazyValueFloat(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14, true); + $this->assertSame(3.14, $config->getValueFloat('feed', 'float', 0, true)); + } + + public function testSetLazyValueFloatCache(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14, true); + $status = $config->statusCache(); + $this->assertSame('3.14', $status['lazyCache']['feed']['float']); + } + + public function testSetLazyValueFloatDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14, true); + $config->clearCache(); + $this->assertSame(3.14, $config->getValueFloat('feed', 'float', 0, true)); + } + + public function testSetLazyValueFloatAsNonLazy(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14, true); + $config->setValueFloat('feed', 'float', 3.14, false); + $this->assertSame(3.14, $config->getValueFloat('feed', 'float', 0)); + } + + public function testSetNonLazyValueFloatAsLazy(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14, false); + $config->setValueFloat('feed', 'float', 3.14, true); + $this->assertSame(3.14, $config->getValueFloat('feed', 'float', 0, true)); + } + + public function testSetSensitiveValueFloat(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14, sensitive: true); + $this->assertSame(3.14, $config->getValueFloat('feed', 'float', 0)); + } + + public function testSetSensitiveValueFloatCache(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14, sensitive: true); + $status = $config->statusCache(); + // TODO: this value will be encrypted with #43114 + $this->assertSame('3.14', $status['fastCache']['feed']['float']); + } + + public function testSetSensitiveValueFloatDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14, sensitive: true); + $config->clearCache(); + $this->assertSame(3.14, $config->getValueFloat('feed', 'float', 0)); + } + + public function testSetNonSensitiveValueFloatAsSensitive(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14); + $config->setValueFloat('feed', 'float', 3.14, sensitive: true); + $this->assertSame(true, $config->isSensitive('feed', 'float')); + } + + public function testSetSensitiveValueFloatAsNonSensitiveStaysSensitive(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14, sensitive: true); + $config->setValueFloat('feed', 'float', 1.23); + $this->assertSame(true, $config->isSensitive('feed', 'float')); + } + + public function testSetSensitiveValueFloatAsNonSensitiveAreStillUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14, sensitive: true); + $config->setValueFloat('feed', 'float', 1.23); + $this->assertSame(1.23, $config->getValueFloat('feed', 'float', 0)); + } + + public function testSetSensitiveValueFloatAsNonSensitiveWouldFailForSameValue(): void { + $config = $this->generateAppConfig(); + $config->setValueFloat('feed', 'float', 3.14, sensitive: true); + $this->assertSame(false, $config->setValueFloat('feed', 'float', 3.14)); + } + + public function testSetLazyValueBool(): void { + $config = $this->generateAppConfig(); + $config->setValueBool('feed', 'bool', true, true); + $this->assertSame(true, $config->getValueBool('feed', 'bool', false, true)); + } + + public function testSetLazyValueBoolCache(): void { + $config = $this->generateAppConfig(); + $config->setValueBool('feed', 'bool', true, true); + $status = $config->statusCache(); + $this->assertSame('1', $status['lazyCache']['feed']['bool']); + } + + public function testSetLazyValueBoolDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueBool('feed', 'bool', true, true); + $config->clearCache(); + $this->assertSame(true, $config->getValueBool('feed', 'bool', false, true)); + } + + public function testSetLazyValueBoolAsNonLazy(): void { + $config = $this->generateAppConfig(); + $config->setValueBool('feed', 'bool', true, true); + $config->setValueBool('feed', 'bool', true, false); + $this->assertSame(true, $config->getValueBool('feed', 'bool', false)); + } + + public function testSetNonLazyValueBoolAsLazy(): void { + $config = $this->generateAppConfig(); + $config->setValueBool('feed', 'bool', true, false); + $config->setValueBool('feed', 'bool', true, true); + $this->assertSame(true, $config->getValueBool('feed', 'bool', false, true)); + } + + public function testSetLazyValueArray(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1], true); + $this->assertSame(['test' => 1], $config->getValueArray('feed', 'array', [], true)); + } + + public function testSetLazyValueArrayCache(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1], true); + $status = $config->statusCache(); + $this->assertSame('{"test":1}', $status['lazyCache']['feed']['array']); + } + + public function testSetLazyValueArrayDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1], true); + $config->clearCache(); + $this->assertSame(['test' => 1], $config->getValueArray('feed', 'array', [], true)); + } + + public function testSetLazyValueArrayAsNonLazy(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1], true); + $config->setValueArray('feed', 'array', ['test' => 1], false); + $this->assertSame(['test' => 1], $config->getValueArray('feed', 'array', [])); + } + + public function testSetNonLazyValueArrayAsLazy(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1], false); + $config->setValueArray('feed', 'array', ['test' => 1], true); + $this->assertSame(['test' => 1], $config->getValueArray('feed', 'array', [], true)); + } + + + public function testSetSensitiveValueArray(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1], sensitive: true); + $this->assertEqualsCanonicalizing(['test' => 1], $config->getValueArray('feed', 'array', [])); + } + + public function testSetSensitiveValueArrayCache(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1], sensitive: true); + $status = $config->statusCache(); + // TODO: this value will be encrypted with #43114 + $this->assertSame('{"test":1}', $status['fastCache']['feed']['array']); + } + + public function testSetSensitiveValueArrayDatabase(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1], sensitive: true); + $config->clearCache(); + $this->assertEqualsCanonicalizing(['test' => 1], $config->getValueArray('feed', 'array', [])); + } + + public function testSetNonSensitiveValueArrayAsSensitive(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1]); + $config->setValueArray('feed', 'array', ['test' => 1], sensitive: true); + $this->assertSame(true, $config->isSensitive('feed', 'array')); + } + + public function testSetSensitiveValueArrayAsNonSensitiveStaysSensitive(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1], sensitive: true); + $config->setValueArray('feed', 'array', ['test' => 2]); + $this->assertSame(true, $config->isSensitive('feed', 'array')); + } + + public function testSetSensitiveValueArrayAsNonSensitiveAreStillUpdated(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1], sensitive: true); + $config->setValueArray('feed', 'array', ['test' => 2]); + $this->assertEqualsCanonicalizing(['test' => 2], $config->getValueArray('feed', 'array', [])); + } + + public function testSetSensitiveValueArrayAsNonSensitiveWouldFailForSameValue(): void { + $config = $this->generateAppConfig(); + $config->setValueArray('feed', 'array', ['test' => 1], sensitive: true); + $this->assertSame(false, $config->setValueArray('feed', 'array', ['test' => 1])); + } + + public function testUpdateNotSensitiveToSensitive(): void { + $config = $this->generateAppConfig(); + $config->updateSensitive('non-sensitive-app', 'lazy-key', true); + $this->assertSame(true, $config->isSensitive('non-sensitive-app', 'lazy-key', true)); + } + + public function testUpdateSensitiveToNotSensitive(): void { + $config = $this->generateAppConfig(); + $config->updateSensitive('sensitive-app', 'lazy-key', false); + $this->assertSame(false, $config->isSensitive('sensitive-app', 'lazy-key', true)); + } + + public function testUpdateSensitiveToSensitiveReturnsFalse(): void { + $config = $this->generateAppConfig(); + $this->assertSame(false, $config->updateSensitive('sensitive-app', 'lazy-key', true)); + } + + public function testUpdateNotSensitiveToNotSensitiveReturnsFalse(): void { + $config = $this->generateAppConfig(); + $this->assertSame(false, $config->updateSensitive('non-sensitive-app', 'lazy-key', false)); + } + + public function testUpdateSensitiveOnUnknownKeyReturnsFalse(): void { + $config = $this->generateAppConfig(); + $this->assertSame(false, $config->updateSensitive('non-sensitive-app', 'unknown-key', true)); + } + + public function testUpdateNotLazyToLazy(): void { + $config = $this->generateAppConfig(); + $config->updateLazy('non-sensitive-app', 'non-lazy-key', true); + $this->assertSame(true, $config->isLazy('non-sensitive-app', 'non-lazy-key')); + } + + public function testUpdateLazyToNotLazy(): void { + $config = $this->generateAppConfig(); + $config->updateLazy('non-sensitive-app', 'lazy-key', false); + $this->assertSame(false, $config->isLazy('non-sensitive-app', 'lazy-key')); + } + + public function testUpdateLazyToLazyReturnsFalse(): void { + $config = $this->generateAppConfig(); + $this->assertSame(false, $config->updateLazy('non-sensitive-app', 'lazy-key', true)); + } + + public function testUpdateNotLazyToNotLazyReturnsFalse(): void { + $config = $this->generateAppConfig(); + $this->assertSame(false, $config->updateLazy('non-sensitive-app', 'non-lazy-key', false)); + } + + public function testUpdateLazyOnUnknownKeyReturnsFalse(): void { + $config = $this->generateAppConfig(); + $this->assertSame(false, $config->updateLazy('non-sensitive-app', 'unknown-key', true)); + } + + public function testGetDetails(): void { + $config = $this->generateAppConfig(); + $this->assertEqualsCanonicalizing( + [ + 'app' => 'sensitive-app', + 'key' => 'lazy-key', + 'value' => 'value', + 'type' => 4, + 'lazy' => true, + 'typeString' => 'string', + 'sensitive' => true + ], + $config->getDetails('sensitive-app', 'lazy-key') + ); + } + + public function testGetDetailsInt(): void { + $config = $this->generateAppConfig(); + $this->assertEqualsCanonicalizing( + [ + 'app' => 'typed', + 'key' => 'int', + 'value' => '42', + 'type' => 8, + 'lazy' => false, + 'typeString' => 'integer', + 'sensitive' => false + ], + $config->getDetails('typed', 'int') + ); + } + + public function testGetDetailsFloat(): void { + $config = $this->generateAppConfig(); + $this->assertEqualsCanonicalizing( + [ + 'app' => 'typed', + 'key' => 'float', + 'value' => '3.14', + 'type' => 16, + 'lazy' => false, + 'typeString' => 'float', + 'sensitive' => false + ], + $config->getDetails('typed', 'float') + ); + } + + public function testGetDetailsBool(): void { + $config = $this->generateAppConfig(); + $this->assertEqualsCanonicalizing( + [ + 'app' => 'typed', + 'key' => 'bool', + 'value' => '1', + 'type' => 32, + 'lazy' => false, + 'typeString' => 'boolean', + 'sensitive' => false + ], + $config->getDetails('typed', 'bool') + ); + } + + public function testGetDetailsArray(): void { + $config = $this->generateAppConfig(); + $this->assertEqualsCanonicalizing( + [ + 'app' => 'typed', + 'key' => 'array', + 'value' => '{"test": 1}', + 'type' => 64, + 'lazy' => false, + 'typeString' => 'array', + 'sensitive' => false + ], + $config->getDetails('typed', 'array') + ); + } + + public function testDeleteKey(): void { + $config = $this->generateAppConfig(); + $config->deleteKey('anotherapp', 'key'); + $this->assertSame('default', $config->getValueString('anotherapp', 'key', 'default')); + } + + public function testDeleteKeyCache(): void { + $config = $this->generateAppConfig(); + $config->deleteKey('anotherapp', 'key'); + $status = $config->statusCache(); + $this->assertEqualsCanonicalizing(['enabled' => 'false'], $status['fastCache']['anotherapp']); + } + + public function testDeleteKeyDatabase(): void { + $config = $this->generateAppConfig(); + $config->deleteKey('anotherapp', 'key'); + $config->clearCache(); + $this->assertSame('default', $config->getValueString('anotherapp', 'key', 'default')); + } + + public function testDeleteApp(): void { + $config = $this->generateAppConfig(); + $config->deleteApp('anotherapp'); + $this->assertSame('default', $config->getValueString('anotherapp', 'key', 'default')); + $this->assertSame('default', $config->getValueString('anotherapp', 'enabled', 'default')); + } + + public function testDeleteAppCache(): void { + $config = $this->generateAppConfig(); + $status = $config->statusCache(); + $this->assertSame(true, isset($status['fastCache']['anotherapp'])); + $config->deleteApp('anotherapp'); + $status = $config->statusCache(); + $this->assertSame(false, isset($status['fastCache']['anotherapp'])); + } + + public function testDeleteAppDatabase(): void { + $config = $this->generateAppConfig(); + $config->deleteApp('anotherapp'); + $config->clearCache(); + $this->assertSame('default', $config->getValueString('anotherapp', 'key', 'default')); + $this->assertSame('default', $config->getValueString('anotherapp', 'enabled', 'default')); + } + + public function testClearCache(): void { + $config = $this->generateAppConfig(); + $config->setValueString('feed', 'string', '123454'); + $config->clearCache(); + $status = $config->statusCache(); + $this->assertSame([], $status['fastCache']); } } |