mirror of
https://github.com/nextcloud/server.git
synced 2026-03-12 05:33:11 -04:00
Merge pull request #52435 from nextcloud/backport/52429/stable31
[stable31] fix(occ): Fix autocompletion of config:app:* commands
This commit is contained in:
commit
97d8b69fb2
7 changed files with 81 additions and 141 deletions
|
|
@ -1,15 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OC\Core\Command\Config\App;
|
||||
|
||||
use OCP\IConfig;
|
||||
use OCP\IAppConfig;
|
||||
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
|
||||
|
||||
abstract class Base extends \OC\Core\Command\Base {
|
||||
protected IConfig $config;
|
||||
public function __construct(
|
||||
protected IAppConfig $appConfig,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $argumentName
|
||||
|
|
@ -18,12 +24,12 @@ abstract class Base extends \OC\Core\Command\Base {
|
|||
*/
|
||||
public function completeArgumentValues($argumentName, CompletionContext $context) {
|
||||
if ($argumentName === 'app') {
|
||||
return \OC_App::getAllApps();
|
||||
return $this->appConfig->getApps();
|
||||
}
|
||||
|
||||
if ($argumentName === 'name') {
|
||||
$appName = $context->getWordAtIndex($context->getWordIndex() - 1);
|
||||
return $this->config->getAppKeys($appName);
|
||||
return $this->appConfig->getKeys($appName);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
|
|
@ -7,19 +8,12 @@
|
|||
*/
|
||||
namespace OC\Core\Command\Config\App;
|
||||
|
||||
use OCP\IConfig;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class DeleteConfig extends Base {
|
||||
public function __construct(
|
||||
protected IConfig $config,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure() {
|
||||
parent::configure();
|
||||
|
||||
|
|
@ -49,12 +43,12 @@ class DeleteConfig extends Base {
|
|||
$appName = $input->getArgument('app');
|
||||
$configName = $input->getArgument('name');
|
||||
|
||||
if ($input->hasParameterOption('--error-if-not-exists') && !in_array($configName, $this->config->getAppKeys($appName))) {
|
||||
if ($input->hasParameterOption('--error-if-not-exists') && !in_array($configName, $this->appConfig->getKeys($appName), true)) {
|
||||
$output->writeln('<error>Config ' . $configName . ' of app ' . $appName . ' could not be deleted because it did not exist</error>');
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->config->deleteAppValue($appName, $configName);
|
||||
$this->appConfig->deleteKey($appName, $configName);
|
||||
$output->writeln('<info>Config value ' . $configName . ' of app ' . $appName . ' deleted</info>');
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,19 +9,12 @@ declare(strict_types=1);
|
|||
namespace OC\Core\Command\Config\App;
|
||||
|
||||
use OCP\Exceptions\AppConfigUnknownKeyException;
|
||||
use OCP\IAppConfig;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class GetConfig extends Base {
|
||||
public function __construct(
|
||||
protected IAppConfig $appConfig,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure() {
|
||||
parent::configure();
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,6 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||
use Symfony\Component\Console\Question\Question;
|
||||
|
||||
class SetConfig extends Base {
|
||||
public function __construct(
|
||||
protected IAppConfig $appConfig,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure() {
|
||||
parent::configure();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
|
|
@ -8,37 +10,31 @@
|
|||
namespace Tests\Core\Command\Config\App;
|
||||
|
||||
use OC\Core\Command\Config\App\DeleteConfig;
|
||||
use OCP\IConfig;
|
||||
use OCP\IAppConfig;
|
||||
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 DeleteConfigTest extends TestCase {
|
||||
/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
|
||||
protected $config;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject */
|
||||
protected $consoleInput;
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject */
|
||||
protected $consoleOutput;
|
||||
|
||||
/** @var \Symfony\Component\Console\Command\Command */
|
||||
protected $command;
|
||||
protected IAppConfig&MockObject $appConfig;
|
||||
protected InputInterface&MockObject $consoleInput;
|
||||
protected OutputInterface&MockObject $consoleOutput;
|
||||
protected Command $command;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->config = $this->getMockBuilder(IConfig::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->consoleInput = $this->getMockBuilder(InputInterface::class)->getMock();
|
||||
$this->consoleOutput = $this->getMockBuilder(OutputInterface::class)->getMock();
|
||||
$this->appConfig = $this->createMock(IAppConfig::class);
|
||||
$this->consoleInput = $this->createMock(InputInterface::class);
|
||||
$this->consoleOutput = $this->createMock(OutputInterface::class);
|
||||
|
||||
$this->command = new DeleteConfig($this->config);
|
||||
$this->command = new DeleteConfig($this->appConfig);
|
||||
}
|
||||
|
||||
|
||||
public function deleteData() {
|
||||
public static function dataDelete(): array {
|
||||
return [
|
||||
[
|
||||
'name',
|
||||
|
|
@ -72,22 +68,16 @@ class DeleteConfigTest extends TestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dataProvider deleteData
|
||||
*
|
||||
* @param string $configName
|
||||
* @param bool $configExists
|
||||
* @param bool $checkIfExists
|
||||
* @param int $expectedReturn
|
||||
* @param string $expectedMessage
|
||||
* @dataProvider dataDelete
|
||||
*/
|
||||
public function testDelete($configName, $configExists, $checkIfExists, $expectedReturn, $expectedMessage): void {
|
||||
$this->config->expects(($checkIfExists) ? $this->once() : $this->never())
|
||||
->method('getAppKeys')
|
||||
public function testDelete(string $configName, bool $configExists, bool $checkIfExists, int $expectedReturn, string $expectedMessage): void {
|
||||
$this->appConfig->expects(($checkIfExists) ? $this->once() : $this->never())
|
||||
->method('getKeys')
|
||||
->with('app-name')
|
||||
->willReturn($configExists ? [$configName] : []);
|
||||
|
||||
$this->config->expects(($expectedReturn === 0) ? $this->once() : $this->never())
|
||||
->method('deleteAppValue')
|
||||
$this->appConfig->expects(($expectedReturn === 0) ? $this->once() : $this->never())
|
||||
->method('deleteKey')
|
||||
->with('app-name', $configName);
|
||||
|
||||
$this->consoleInput->expects($this->exactly(2))
|
||||
|
|
@ -96,15 +86,13 @@ class DeleteConfigTest extends TestCase {
|
|||
['app', 'app-name'],
|
||||
['name', $configName],
|
||||
]);
|
||||
$this->consoleInput->expects($this->any())
|
||||
->method('hasParameterOption')
|
||||
$this->consoleInput->method('hasParameterOption')
|
||||
->with('--error-if-not-exists')
|
||||
->willReturn($checkIfExists);
|
||||
|
||||
$this->consoleOutput->expects($this->any())
|
||||
->method('writeln')
|
||||
$this->consoleOutput->method('writeln')
|
||||
->with($this->stringContains($expectedMessage));
|
||||
|
||||
$this->assertSame($expectedReturn, $this->invokePrivate($this->command, 'execute', [$this->consoleInput, $this->consoleOutput]));
|
||||
$this->assertSame($expectedReturn, self::invokePrivate($this->command, 'execute', [$this->consoleInput, $this->consoleOutput]));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
|
|
@ -7,40 +9,33 @@
|
|||
|
||||
namespace Tests\Core\Command\Config\App;
|
||||
|
||||
use OC\AppConfig;
|
||||
use OC\Core\Command\Config\App\GetConfig;
|
||||
use OCP\Exceptions\AppConfigUnknownKeyException;
|
||||
use OCP\IAppConfig;
|
||||
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 GetConfigTest extends TestCase {
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject */
|
||||
protected $config;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject */
|
||||
protected $consoleInput;
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject */
|
||||
protected $consoleOutput;
|
||||
|
||||
/** @var \Symfony\Component\Console\Command\Command */
|
||||
protected $command;
|
||||
protected IAppConfig&MockObject $appConfig;
|
||||
protected InputInterface&MockObject $consoleInput;
|
||||
protected OutputInterface&MockObject $consoleOutput;
|
||||
protected Command $command;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$config = $this->config = $this->getMockBuilder(AppConfig::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->consoleInput = $this->getMockBuilder(InputInterface::class)->getMock();
|
||||
$this->consoleOutput = $this->getMockBuilder(OutputInterface::class)->getMock();
|
||||
$this->appConfig = $this->createMock(IAppConfig::class);
|
||||
$this->consoleInput = $this->createMock(InputInterface::class);
|
||||
$this->consoleOutput = $this->createMock(OutputInterface::class);
|
||||
|
||||
/** @var \OCP\IAppConfig $config */
|
||||
$this->command = new GetConfig($config);
|
||||
$this->command = new GetConfig($this->appConfig);
|
||||
}
|
||||
|
||||
|
||||
public function getData() {
|
||||
public static function dataGet(): array {
|
||||
return [
|
||||
// String output as json
|
||||
['name', 'newvalue', true, null, false, 'json', 0, json_encode('newvalue')],
|
||||
|
|
@ -83,21 +78,12 @@ class GetConfigTest extends TestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getData
|
||||
*
|
||||
* @param string $configName
|
||||
* @param mixed $value
|
||||
* @param bool $configExists
|
||||
* @param mixed $defaultValue
|
||||
* @param bool $hasDefault
|
||||
* @param string $outputFormat
|
||||
* @param int $expectedReturn
|
||||
* @param string $expectedMessage
|
||||
* @dataProvider dataGet
|
||||
*/
|
||||
public function testGet($configName, $value, $configExists, $defaultValue, $hasDefault, $outputFormat, $expectedReturn, $expectedMessage): void {
|
||||
public function testGet(string $configName, mixed $value, bool $configExists, mixed $defaultValue, bool $hasDefault, string $outputFormat, int $expectedReturn, ?string $expectedMessage): void {
|
||||
if (!$expectedReturn) {
|
||||
if ($configExists) {
|
||||
$this->config->expects($this->once())
|
||||
$this->appConfig->expects($this->once())
|
||||
->method('getDetails')
|
||||
->with('app-name', $configName)
|
||||
->willReturn(['value' => $value]);
|
||||
|
|
@ -105,7 +91,7 @@ class GetConfigTest extends TestCase {
|
|||
}
|
||||
|
||||
if (!$configExists) {
|
||||
$this->config->expects($this->once())
|
||||
$this->appConfig->expects($this->once())
|
||||
->method('getDetails')
|
||||
->with('app-name', $configName)
|
||||
->willThrowException(new AppConfigUnknownKeyException());
|
||||
|
|
@ -117,14 +103,12 @@ class GetConfigTest extends TestCase {
|
|||
['app', 'app-name'],
|
||||
['name', $configName],
|
||||
]);
|
||||
$this->consoleInput->expects($this->any())
|
||||
->method('getOption')
|
||||
$this->consoleInput->method('getOption')
|
||||
->willReturnMap([
|
||||
['default-value', $defaultValue],
|
||||
['output', $outputFormat],
|
||||
]);
|
||||
$this->consoleInput->expects($this->any())
|
||||
->method('hasParameterOption')
|
||||
$this->consoleInput->method('hasParameterOption')
|
||||
->willReturnMap([
|
||||
['--output', false, true],
|
||||
['--default-value', false, $hasDefault],
|
||||
|
|
@ -134,8 +118,7 @@ class GetConfigTest extends TestCase {
|
|||
global $output;
|
||||
|
||||
$output = '';
|
||||
$this->consoleOutput->expects($this->any())
|
||||
->method('writeln')
|
||||
$this->consoleOutput->method('writeln')
|
||||
->willReturnCallback(function ($value) {
|
||||
global $output;
|
||||
$output .= $value . "\n";
|
||||
|
|
@ -143,7 +126,7 @@ class GetConfigTest extends TestCase {
|
|||
});
|
||||
}
|
||||
|
||||
$this->assertSame($expectedReturn, $this->invokePrivate($this->command, 'execute', [$this->consoleInput, $this->consoleOutput]));
|
||||
$this->assertSame($expectedReturn, self::invokePrivate($this->command, 'execute', [$this->consoleInput, $this->consoleOutput]));
|
||||
|
||||
if ($expectedMessage !== null) {
|
||||
global $output;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
|
|
@ -11,37 +13,30 @@ use OC\AppConfig;
|
|||
use OC\Core\Command\Config\App\SetConfig;
|
||||
use OCP\Exceptions\AppConfigUnknownKeyException;
|
||||
use OCP\IAppConfig;
|
||||
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 SetConfigTest extends TestCase {
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject */
|
||||
protected $config;
|
||||
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject */
|
||||
protected $consoleInput;
|
||||
/** @var \PHPUnit\Framework\MockObject\MockObject */
|
||||
protected $consoleOutput;
|
||||
|
||||
/** @var \Symfony\Component\Console\Command\Command */
|
||||
protected $command;
|
||||
protected IAppConfig&MockObject $appConfig;
|
||||
protected InputInterface&MockObject $consoleInput;
|
||||
protected OutputInterface&MockObject $consoleOutput;
|
||||
protected Command $command;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$config = $this->config = $this->getMockBuilder(AppConfig::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->consoleInput = $this->getMockBuilder(InputInterface::class)->getMock();
|
||||
$this->consoleOutput = $this->getMockBuilder(OutputInterface::class)->getMock();
|
||||
$this->appConfig = $this->createMock(AppConfig::class);
|
||||
$this->consoleInput = $this->createMock(InputInterface::class);
|
||||
$this->consoleOutput = $this->createMock(OutputInterface::class);
|
||||
|
||||
/** @var \OCP\IAppConfig $config */
|
||||
$this->command = new SetConfig($config);
|
||||
$this->command = new SetConfig($this->appConfig);
|
||||
}
|
||||
|
||||
|
||||
public function setData() {
|
||||
public static function dataSet(): array {
|
||||
return [
|
||||
[
|
||||
'name',
|
||||
|
|
@ -63,33 +58,23 @@ class SetConfigTest extends TestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dataProvider setData
|
||||
*
|
||||
* @param string $configName
|
||||
* @param mixed $newValue
|
||||
* @param bool $configExists
|
||||
* @param bool $updateOnly
|
||||
* @param bool $updated
|
||||
* @param string $expectedMessage
|
||||
* @dataProvider dataSet
|
||||
*/
|
||||
public function testSet($configName, $newValue, $configExists, $updateOnly, $updated, $expectedMessage): void {
|
||||
$this->config->expects($this->any())
|
||||
->method('hasKey')
|
||||
public function testSet(string $configName, mixed $newValue, bool $configExists, bool $updateOnly, bool $updated, string $expectedMessage): void {
|
||||
$this->appConfig->method('hasKey')
|
||||
->with('app-name', $configName)
|
||||
->willReturn($configExists);
|
||||
|
||||
if (!$configExists) {
|
||||
$this->config->expects($this->any())
|
||||
->method('getValueType')
|
||||
$this->appConfig->method('getValueType')
|
||||
->willThrowException(new AppConfigUnknownKeyException());
|
||||
} else {
|
||||
$this->config->expects($this->any())
|
||||
->method('getValueType')
|
||||
$this->appConfig->method('getValueType')
|
||||
->willReturn(IAppConfig::VALUE_MIXED);
|
||||
}
|
||||
|
||||
if ($updated) {
|
||||
$this->config->expects($this->once())
|
||||
$this->appConfig->expects($this->once())
|
||||
->method('setValueMixed')
|
||||
->with('app-name', $configName, $newValue);
|
||||
}
|
||||
|
|
@ -100,25 +85,22 @@ class SetConfigTest extends TestCase {
|
|||
['app', 'app-name'],
|
||||
['name', $configName],
|
||||
]);
|
||||
$this->consoleInput->expects($this->any())
|
||||
->method('getOption')
|
||||
$this->consoleInput->method('getOption')
|
||||
->willReturnMap([
|
||||
['value', $newValue],
|
||||
['lazy', null],
|
||||
['sensitive', null],
|
||||
['no-interaction', true],
|
||||
]);
|
||||
$this->consoleInput->expects($this->any())
|
||||
->method('hasParameterOption')
|
||||
$this->consoleInput->method('hasParameterOption')
|
||||
->willReturnMap([
|
||||
['--type', false, false],
|
||||
['--value', false, true],
|
||||
['--update-only', false, $updateOnly]
|
||||
]);
|
||||
$this->consoleOutput->expects($this->any())
|
||||
->method('writeln')
|
||||
$this->consoleOutput->method('writeln')
|
||||
->with($this->stringContains($expectedMessage));
|
||||
|
||||
$this->invokePrivate($this->command, 'execute', [$this->consoleInput, $this->consoleOutput]);
|
||||
self::invokePrivate($this->command, 'execute', [$this->consoleInput, $this->consoleOutput]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue