diff --git a/core/Command/Config/System/CastHelper.php b/core/Command/Config/System/CastHelper.php new file mode 100644 index 00000000000..f2b838bdf9b --- /dev/null +++ b/core/Command/Config/System/CastHelper.php @@ -0,0 +1,76 @@ + (int)$value, + 'readable-value' => 'integer ' . (int)$value, + ]; + + case 'double': + case 'float': + if (!is_numeric($value)) { + throw new \InvalidArgumentException('Non-numeric value specified'); + } + return [ + 'value' => (float)$value, + 'readable-value' => 'double ' . (float)$value, + ]; + + case 'boolean': + case 'bool': + $value = strtolower($value); + return match ($value) { + 'true' => [ + 'value' => true, + 'readable-value' => 'boolean ' . $value, + ], + 'false' => [ + 'value' => false, + 'readable-value' => 'boolean ' . $value, + ], + default => throw new \InvalidArgumentException('Unable to parse value as boolean'), + }; + + case 'null': + return [ + 'value' => null, + 'readable-value' => 'null', + ]; + + case 'string': + $value = (string)$value; + return [ + 'value' => $value, + 'readable-value' => ($value === '') ? 'empty string' : 'string ' . $value, + ]; + + case 'json': + $value = json_decode($value, true); + return [ + 'value' => $value, + 'readable-value' => 'json ' . json_encode($value), + ]; + + default: + throw new \InvalidArgumentException('Invalid type'); + } + } +} diff --git a/core/Command/Config/System/SetConfig.php b/core/Command/Config/System/SetConfig.php index 62ab7f7120f..1b1bdc66a6e 100644 --- a/core/Command/Config/System/SetConfig.php +++ b/core/Command/Config/System/SetConfig.php @@ -17,6 +17,7 @@ use Symfony\Component\Console\Output\OutputInterface; class SetConfig extends Base { public function __construct( SystemConfig $systemConfig, + private CastHelper $castHelper, ) { parent::__construct($systemConfig); } @@ -57,7 +58,7 @@ class SetConfig extends Base { protected function execute(InputInterface $input, OutputInterface $output): int { $configNames = $input->getArgument('name'); $configName = $configNames[0]; - $configValue = $this->castValue($input->getOption('value'), $input->getOption('type')); + $configValue = $this->castHelper->castValue($input->getOption('value'), $input->getOption('type')); $updateOnly = $input->getOption('update-only'); if (count($configNames) > 1) { @@ -80,80 +81,6 @@ class SetConfig extends Base { return 0; } - /** - * @param string $value - * @param string $type - * @return mixed - * @throws \InvalidArgumentException - */ - protected function castValue($value, $type) { - switch ($type) { - case 'integer': - case 'int': - if (!is_numeric($value)) { - throw new \InvalidArgumentException('Non-numeric value specified'); - } - return [ - 'value' => (int)$value, - 'readable-value' => 'integer ' . (int)$value, - ]; - - case 'double': - case 'float': - if (!is_numeric($value)) { - throw new \InvalidArgumentException('Non-numeric value specified'); - } - return [ - 'value' => (float)$value, - 'readable-value' => 'double ' . (float)$value, - ]; - - case 'boolean': - case 'bool': - $value = strtolower($value); - switch ($value) { - case 'true': - return [ - 'value' => true, - 'readable-value' => 'boolean ' . $value, - ]; - - case 'false': - return [ - 'value' => false, - 'readable-value' => 'boolean ' . $value, - ]; - - default: - throw new \InvalidArgumentException('Unable to parse value as boolean'); - } - - // no break - case 'null': - return [ - 'value' => null, - 'readable-value' => 'null', - ]; - - case 'string': - $value = (string)$value; - return [ - 'value' => $value, - 'readable-value' => ($value === '') ? 'empty string' : 'string ' . $value, - ]; - - case 'json': - $value = json_decode($value, true); - return [ - 'value' => $value, - 'readable-value' => 'json ' . json_encode($value), - ]; - - default: - throw new \InvalidArgumentException('Invalid type'); - } - } - /** * @param array $configNames * @param mixed $existingValues diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 2c1872e23d9..91503349e59 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -1225,6 +1225,7 @@ return array( 'OC\\Core\\Command\\Config\\Import' => $baseDir . '/core/Command/Config/Import.php', 'OC\\Core\\Command\\Config\\ListConfigs' => $baseDir . '/core/Command/Config/ListConfigs.php', 'OC\\Core\\Command\\Config\\System\\Base' => $baseDir . '/core/Command/Config/System/Base.php', + 'OC\\Core\\Command\\Config\\System\\CastHelper' => $baseDir . '/core/Command/Config/System/CastHelper.php', 'OC\\Core\\Command\\Config\\System\\DeleteConfig' => $baseDir . '/core/Command/Config/System/DeleteConfig.php', 'OC\\Core\\Command\\Config\\System\\GetConfig' => $baseDir . '/core/Command/Config/System/GetConfig.php', 'OC\\Core\\Command\\Config\\System\\SetConfig' => $baseDir . '/core/Command/Config/System/SetConfig.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 9e843c976d5..ccc4f6de725 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -1274,6 +1274,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\Core\\Command\\Config\\Import' => __DIR__ . '/../../..' . '/core/Command/Config/Import.php', 'OC\\Core\\Command\\Config\\ListConfigs' => __DIR__ . '/../../..' . '/core/Command/Config/ListConfigs.php', 'OC\\Core\\Command\\Config\\System\\Base' => __DIR__ . '/../../..' . '/core/Command/Config/System/Base.php', + 'OC\\Core\\Command\\Config\\System\\CastHelper' => __DIR__ . '/../../..' . '/core/Command/Config/System/CastHelper.php', 'OC\\Core\\Command\\Config\\System\\DeleteConfig' => __DIR__ . '/../../..' . '/core/Command/Config/System/DeleteConfig.php', 'OC\\Core\\Command\\Config\\System\\GetConfig' => __DIR__ . '/../../..' . '/core/Command/Config/System/GetConfig.php', 'OC\\Core\\Command\\Config\\System\\SetConfig' => __DIR__ . '/../../..' . '/core/Command/Config/System/SetConfig.php', diff --git a/tests/Core/Command/Config/System/CastHelperTest.php b/tests/Core/Command/Config/System/CastHelperTest.php new file mode 100644 index 00000000000..0d3ca032026 --- /dev/null +++ b/tests/Core/Command/Config/System/CastHelperTest.php @@ -0,0 +1,69 @@ +castHelper = new CastHelper(); + } + + public static function castValueProvider(): array { + return [ + [null, 'string', ['value' => '', 'readable-value' => 'empty string']], + + ['abc', 'string', ['value' => 'abc', 'readable-value' => 'string abc']], + + ['123', 'integer', ['value' => 123, 'readable-value' => 'integer 123']], + ['456', 'int', ['value' => 456, 'readable-value' => 'integer 456']], + + ['2.25', 'double', ['value' => 2.25, 'readable-value' => 'double 2.25']], + ['0.5', 'float', ['value' => 0.5, 'readable-value' => 'double 0.5']], + + ['', 'null', ['value' => null, 'readable-value' => 'null']], + + ['true', 'boolean', ['value' => true, 'readable-value' => 'boolean true']], + ['false', 'bool', ['value' => false, 'readable-value' => 'boolean false']], + ]; + } + + /** + * @dataProvider castValueProvider + */ + public function testCastValue($value, $type, $expectedValue): void { + $this->assertSame( + $expectedValue, + $this->castHelper->castValue($value, $type) + ); + } + + public static function castValueInvalidProvider(): array { + return [ + ['123', 'foobar'], + + [null, 'integer'], + ['abc', 'integer'], + ['76ggg', 'double'], + ['true', 'float'], + ['foobar', 'boolean'], + ]; + } + + /** + * @dataProvider castValueInvalidProvider + */ + public function testCastValueInvalid($value, $type): void { + $this->expectException(\InvalidArgumentException::class); + + $this->castHelper->castValue($value, $type); + } +} diff --git a/tests/Core/Command/Config/System/SetConfigTest.php b/tests/Core/Command/Config/System/SetConfigTest.php index 2905af5c3d7..cf44058f670 100644 --- a/tests/Core/Command/Config/System/SetConfigTest.php +++ b/tests/Core/Command/Config/System/SetConfigTest.php @@ -7,6 +7,7 @@ namespace Tests\Core\Command\Config\System; +use OC\Core\Command\Config\System\CastHelper; use OC\Core\Command\Config\System\SetConfig; use OC\SystemConfig; use Symfony\Component\Console\Input\InputInterface; @@ -35,7 +36,7 @@ class SetConfigTest extends TestCase { $this->consoleOutput = $this->getMockBuilder(OutputInterface::class)->getMock(); /** @var \OC\SystemConfig $systemConfig */ - $this->command = new SetConfig($systemConfig); + $this->command = new SetConfig($systemConfig, new CastHelper()); }