Skip to content

Commit 596c74f

Browse files
MAGETWO-65308: CLI command config:set fails on configurations which requires session
1 parent e1aad10 commit 596c74f

File tree

4 files changed

+144
-197
lines changed

4 files changed

+144
-197
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Config\Console\Command\ConfigSet;
7+
8+
use Magento\Config\Console\Command\ConfigSetCommand;
9+
use Magento\Framework\App\Scope\ValidatorInterface;
10+
use Magento\Config\Model\Config\PathValidator;
11+
use Magento\Framework\Exception\LocalizedException;
12+
13+
/**
14+
* Processor facade for config:set command.
15+
*
16+
* @see ConfigSetCommand
17+
*/
18+
class ProcessorFacade
19+
{
20+
/**
21+
* The scope validator.
22+
*
23+
* @var ValidatorInterface
24+
*/
25+
private $scopeValidator;
26+
27+
/**
28+
* The path validator.
29+
*
30+
* @var PathValidator
31+
*/
32+
private $pathValidator;
33+
34+
/**
35+
* The factory for config:set processors.
36+
*
37+
* @var ConfigSetProcessorFactory
38+
*/
39+
private $configSetProcessorFactory;
40+
41+
/**
42+
* @param ValidatorInterface $scopeValidator The scope validator
43+
* @param PathValidator $pathValidator The path validator
44+
* @param ConfigSetProcessorFactory $configSetProcessorFactory The factory for config:set processors
45+
*/
46+
public function __construct(
47+
ValidatorInterface $scopeValidator,
48+
PathValidator $pathValidator,
49+
ConfigSetProcessorFactory $configSetProcessorFactory
50+
) {
51+
$this->scopeValidator = $scopeValidator;
52+
$this->pathValidator = $pathValidator;
53+
$this->configSetProcessorFactory = $configSetProcessorFactory;
54+
}
55+
56+
/**
57+
* @param string $path The configuration path in format group/section/field_name
58+
* @param string $value The configuration value
59+
* @param string $scope The configuration scope (default, website, or store)
60+
* @param string $scopeCode The scope code
61+
* @return string Processor response message
62+
* @throws LocalizedException If validation or processor failed
63+
*/
64+
public function process($path, $value, $scope, $scopeCode, $lock)
65+
{
66+
$this->scopeValidator->isValid($scope, $scopeCode);
67+
$this->pathValidator->validate($path);
68+
69+
$processor = $lock
70+
? $this->configSetProcessorFactory->create(ConfigSetProcessorFactory::TYPE_LOCK)
71+
: $this->configSetProcessorFactory->create(ConfigSetProcessorFactory::TYPE_DEFAULT);
72+
$message = $lock
73+
? 'Value was saved and locked.'
74+
: 'Value was saved.';
75+
76+
// The processing flow depends on --lock option.
77+
$processor->process($path, $value, $scope, $scopeCode);
78+
79+
return $message;
80+
}
81+
}

app/code/Magento/Config/Console/Command/ConfigSetCommand.php

Lines changed: 31 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,17 @@
55
*/
66
namespace Magento\Config\Console\Command;
77

8-
use Magento\Config\Console\Command\ConfigSet\ConfigSetProcessorFactory;
9-
use Magento\Config\Model\Config\PathValidatorFactory;
108
use Magento\Framework\App\Area;
11-
use Magento\Framework\App\Config\ScopeConfigInterface;
12-
use Magento\Framework\App\Scope\ValidatorInterface;
9+
use Magento\Framework\App\State;
1310
use Magento\Framework\Config\ScopeInterface;
11+
use Magento\Framework\App\Config\ScopeConfigInterface;
1412
use Magento\Framework\Console\Cli;
1513
use Symfony\Component\Console\Command\Command;
1614
use Symfony\Component\Console\Input\InputArgument;
1715
use Symfony\Component\Console\Input\InputInterface;
1816
use Symfony\Component\Console\Input\InputOption;
1917
use Symfony\Component\Console\Output\OutputInterface;
18+
use Magento\Config\Console\Command\ConfigSet\ProcessorFacadeFactory;
2019

2120
/**
2221
* Command provides possibility to change system configuration.
@@ -34,49 +33,39 @@ class ConfigSetCommand extends Command
3433
/**#@-*/
3534

3635
/**
37-
* The factory for config:set processors.
36+
* Scope manager.
3837
*
39-
* @var ConfigSetProcessorFactory
38+
* @var ScopeInterface
4039
*/
41-
private $configSetProcessorFactory;
40+
private $scope;
4241

4342
/**
44-
* Scope validator.
43+
* Application state.
4544
*
46-
* @var ValidatorInterface
45+
* @var State
4746
*/
48-
private $validator;
47+
private $state;
4948

5049
/**
51-
* Scope manager.
50+
* The processor facade factory
5251
*
53-
* @var ScopeInterface
52+
* @var ProcessorFacadeFactory
5453
*/
55-
private $scope;
54+
private $processorFacadeFactory;
5655

5756
/**
58-
* The factory for path validator.
59-
*
60-
* @var PathValidatorFactory
61-
*/
62-
private $pathValidatorFactory;
63-
64-
/**
65-
* @param ConfigSetProcessorFactory $configSetProcessorFactory The factory for config:set processors
66-
* @param ValidatorInterface $validator Scope validator
6757
* @param ScopeInterface $scope Scope manager
68-
* @param PathValidatorFactory $pathValidatorFactory The factory for path validator
58+
* @param State $state Application state
59+
* @param ProcessorFacadeFactory $processorFacadeFactory The processor facade factory
6960
*/
7061
public function __construct(
71-
ConfigSetProcessorFactory $configSetProcessorFactory,
72-
ValidatorInterface $validator,
7362
ScopeInterface $scope,
74-
PathValidatorFactory $pathValidatorFactory
63+
State $state,
64+
ProcessorFacadeFactory $processorFacadeFactory
7565
) {
76-
$this->configSetProcessorFactory = $configSetProcessorFactory;
77-
$this->validator = $validator;
7866
$this->scope = $scope;
79-
$this->pathValidatorFactory = $pathValidatorFactory;
67+
$this->state = $state;
68+
$this->processorFacadeFactory = $processorFacadeFactory;
8069

8170
parent::__construct();
8271
}
@@ -127,38 +116,20 @@ protected function configure()
127116
protected function execute(InputInterface $input, OutputInterface $output)
128117
{
129118
try {
130-
$this->validator->isValid(
131-
$input->getOption(static::OPTION_SCOPE),
132-
$input->getOption(static::OPTION_SCOPE_CODE)
133-
);
134-
135119
// Emulating adminhtml scope to be able to read configs.
136-
$this->scope->setCurrentScope(Area::AREA_ADMINHTML);
137-
138-
/**
139-
* Validates the entered config path.
140-
* Requires emulated area.
141-
*/
142-
$this->pathValidatorFactory->create()->validate(
143-
$input->getArgument(ConfigSetCommand::ARG_PATH)
144-
);
145-
146-
$processor = $input->getOption(static::OPTION_LOCK)
147-
? $this->configSetProcessorFactory->create(ConfigSetProcessorFactory::TYPE_LOCK)
148-
: $this->configSetProcessorFactory->create(ConfigSetProcessorFactory::TYPE_DEFAULT);
149-
$message = $input->getOption(static::OPTION_LOCK)
150-
? 'Value was saved and locked.'
151-
: 'Value was saved.';
152-
153-
// The processing flow depends on --lock option.
154-
$processor->process(
155-
$input->getArgument(ConfigSetCommand::ARG_PATH),
156-
$input->getArgument(ConfigSetCommand::ARG_VALUE),
157-
$input->getOption(ConfigSetCommand::OPTION_SCOPE),
158-
$input->getOption(ConfigSetCommand::OPTION_SCOPE_CODE)
159-
);
160-
161-
$output->writeln('<info>' . $message . '</info>');
120+
$this->state->emulateAreaCode(Area::AREA_ADMINHTML, function () use ($input, $output) {
121+
$this->scope->setCurrentScope(Area::AREA_ADMINHTML);
122+
123+
$message = $this->processorFacadeFactory->create()->process(
124+
$input->getArgument(static::ARG_PATH),
125+
$input->getArgument(static::ARG_VALUE),
126+
$input->getOption(static::OPTION_SCOPE),
127+
$input->getOption(static::OPTION_SCOPE_CODE),
128+
$input->getOption(static::OPTION_LOCK)
129+
);
130+
131+
$output->writeln('<info>' . $message . '</info>');
132+
});
162133

163134
return Cli::RETURN_SUCCESS;
164135
} catch (\Exception $exception) {

app/code/Magento/Config/Test/Unit/Console/Command/ConfigSetCommandTest.php

Lines changed: 23 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55
*/
66
namespace Magento\Config\Test\Unit\Console\Command;
77

8-
use Magento\Config\Console\Command\ConfigSet\ConfigSetProcessorFactory;
9-
use Magento\Config\Console\Command\ConfigSet\ConfigSetProcessorInterface;
8+
use Magento\Config\Console\Command\ConfigSet\ProcessorFacade;
9+
use Magento\Config\Console\Command\ConfigSet\ProcessorFacadeFactory;
1010
use Magento\Config\Console\Command\ConfigSetCommand;
11-
use Magento\Config\Model\Config\PathValidator;
12-
use Magento\Config\Model\Config\PathValidatorFactory;
13-
use Magento\Framework\App\Scope\ValidatorInterface;
11+
use Magento\Framework\App\State;
1412
use Magento\Framework\Config\ScopeInterface;
1513
use Magento\Framework\Console\Cli;
16-
use Magento\Framework\Exception\LocalizedException;
1714
use Magento\Framework\Exception\ValidatorException;
1815
use PHPUnit_Framework_MockObject_MockObject as Mock;
1916
use Symfony\Component\Console\Tester\CommandTester;
@@ -22,7 +19,6 @@
2219
* Test for ConfigSetCommand.
2320
*
2421
* @see ConfigSetCommand
25-
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2622
*/
2723
class ConfigSetCommandTest extends \PHPUnit_Framework_TestCase
2824
{
@@ -32,129 +28,59 @@ class ConfigSetCommandTest extends \PHPUnit_Framework_TestCase
3228
private $command;
3329

3430
/**
35-
* @var ConfigSetProcessorFactory|Mock
36-
*/
37-
private $configSetProcessorFactoryMock;
38-
39-
/**
40-
* @var ValidatorInterface|Mock
41-
*/
42-
private $validatorMock;
43-
44-
/**
45-
* @var ConfigSetProcessorInterface|Mock
31+
* @var ScopeInterface|Mock
4632
*/
47-
private $processorMock;
33+
private $scopeMock;
4834

4935
/**
50-
* @var ScopeInterface|Mock
36+
* @var State|Mock
5137
*/
52-
private $scopeMock;
38+
private $stateMock;
5339

5440
/**
55-
* @var PathValidatorFactory|Mock
41+
* @var ProcessorFacadeFactory|Mock
5642
*/
57-
private $pathValidatorFactoryMock;
43+
private $processorFacadeFactoryMock;
5844

5945
/**
60-
* @var PathValidator|Mock
46+
* @var ProcessorFacade|Mock
6147
*/
62-
private $pathValidator;
48+
private $processorFacadeMock;
6349

6450
/**
6551
* @inheritdoc
6652
*/
6753
protected function setUp()
6854
{
69-
$this->configSetProcessorFactoryMock = $this->getMockBuilder(ConfigSetProcessorFactory::class)
70-
->disableOriginalConstructor()
71-
->setMethods(['create'])
72-
->getMock();
73-
$this->validatorMock = $this->getMockBuilder(ValidatorInterface::class)
74-
->getMockForAbstractClass();
75-
$this->processorMock = $this->getMockBuilder(ConfigSetProcessorInterface::class)
76-
->getMockForAbstractClass();
7755
$this->scopeMock = $this->getMockBuilder(ScopeInterface::class)
7856
->getMockForAbstractClass();
79-
$this->pathValidatorFactoryMock = $this->getMockBuilder(PathValidatorFactory::class)
57+
$this->stateMock = $this->getMockBuilder(State::class)
58+
->disableOriginalConstructor()
59+
->getMock();
60+
$this->processorFacadeFactoryMock = $this->getMockBuilder(ProcessorFacadeFactory::class)
8061
->disableOriginalConstructor()
81-
->setMethods(['create'])
8262
->getMock();
83-
$this->pathValidator = $this->getMockBuilder(PathValidator::class)
63+
$this->processorFacadeMock = $this->getMockBuilder(ProcessorFacade::class)
8464
->disableOriginalConstructor()
8565
->getMock();
8666

87-
$this->pathValidatorFactoryMock->expects($this->any())
67+
$this->processorFacadeFactoryMock->expects($this->any())
8868
->method('create')
89-
->willReturn($this->pathValidator);
69+
->willReturn($this->processorFacadeMock);
9070

9171
$this->command = new ConfigSetCommand(
92-
$this->configSetProcessorFactoryMock,
93-
$this->validatorMock,
9472
$this->scopeMock,
95-
$this->pathValidatorFactoryMock
73+
$this->stateMock,
74+
$this->processorFacadeFactoryMock
9675
);
9776
}
9877

99-
public function testExecute()
100-
{
101-
$this->validatorMock->expects($this->once())
102-
->method('isValid')
103-
->willReturn(true);
104-
$this->configSetProcessorFactoryMock->expects($this->once())
105-
->method('create')
106-
->with(ConfigSetProcessorFactory::TYPE_DEFAULT)
107-
->willReturn($this->processorMock);
108-
109-
$tester = new CommandTester($this->command);
110-
$tester->execute([
111-
ConfigSetCommand::ARG_PATH => 'test/test/test',
112-
ConfigSetCommand::ARG_VALUE => 'value'
113-
]);
114-
}
115-
116-
public function testExecuteLock()
117-
{
118-
$this->validatorMock->expects($this->once())
119-
->method('isValid')
120-
->willReturn(true);
121-
$this->configSetProcessorFactoryMock->expects($this->once())
122-
->method('create')
123-
->with(ConfigSetProcessorFactory::TYPE_LOCK)
124-
->willReturn($this->processorMock);
125-
126-
$tester = new CommandTester($this->command);
127-
$tester->execute([
128-
ConfigSetCommand::ARG_PATH => 'test/test/test',
129-
ConfigSetCommand::ARG_VALUE => 'value',
130-
'--' . ConfigSetCommand::OPTION_LOCK => true
131-
]);
132-
}
133-
134-
public function testExecuteNotValidScope()
135-
{
136-
$this->validatorMock->expects($this->once())
137-
->method('isValid')
138-
->willThrowException(new LocalizedException(__('Test exception')));
139-
140-
$tester = new CommandTester($this->command);
141-
$tester->execute([
142-
ConfigSetCommand::ARG_PATH => 'test/test/test',
143-
ConfigSetCommand::ARG_VALUE => 'value'
144-
]);
145-
146-
$this->assertSame(Cli::RETURN_FAILURE, $tester->getStatusCode());
147-
}
148-
14978
public function testExecuteWithException()
15079
{
151-
$this->validatorMock->expects($this->once())
152-
->method('isValid')
153-
->willReturn(true);
154-
$this->pathValidator->expects($this->once())
155-
->method('validate')
80+
$this->stateMock->expects($this->once())
81+
->method('emulateAreaCode')
15682
->willThrowException(new ValidatorException(__('The "test/test/test" path does not exists')));
157-
$this->configSetProcessorFactoryMock->expects($this->never())
83+
$this->processorFacadeFactoryMock->expects($this->never())
15884
->method('create');
15985

16086
$tester = new CommandTester($this->command);

0 commit comments

Comments
 (0)