Skip to content
Snippets Groups Projects
Commit bda5e317 authored by Volodymyr Kublytskyi's avatar Volodymyr Kublytskyi Committed by GitHub
Browse files

MAGETWO-84180: Add a --no-update option to sampledata:deploy and sampledata:remove commands #12359

parents e691e953 29a67849
Branches
No related merge requests found
...@@ -12,6 +12,7 @@ use Magento\Setup\Model\PackagesAuth; ...@@ -12,6 +12,7 @@ use Magento\Setup\Model\PackagesAuth;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
/** /**
...@@ -19,6 +20,8 @@ use Symfony\Component\Console\Output\OutputInterface; ...@@ -19,6 +20,8 @@ use Symfony\Component\Console\Output\OutputInterface;
*/ */
class SampleDataDeployCommand extends Command class SampleDataDeployCommand extends Command
{ {
const OPTION_NO_UPDATE = 'no-update';
/** /**
* @var \Magento\Framework\Filesystem * @var \Magento\Framework\Filesystem
*/ */
...@@ -66,6 +69,12 @@ class SampleDataDeployCommand extends Command ...@@ -66,6 +69,12 @@ class SampleDataDeployCommand extends Command
{ {
$this->setName('sampledata:deploy') $this->setName('sampledata:deploy')
->setDescription('Deploy sample data modules'); ->setDescription('Deploy sample data modules');
$this->addOption(
self::OPTION_NO_UPDATE,
null,
InputOption::VALUE_NONE,
'Update composer.json without executing composer update'
);
parent::configure(); parent::configure();
} }
...@@ -80,6 +89,9 @@ class SampleDataDeployCommand extends Command ...@@ -80,6 +89,9 @@ class SampleDataDeployCommand extends Command
if (!empty($sampleDataPackages)) { if (!empty($sampleDataPackages)) {
$baseDir = $this->filesystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath(); $baseDir = $this->filesystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath();
$commonArgs = ['--working-dir' => $baseDir, '--no-progress' => 1]; $commonArgs = ['--working-dir' => $baseDir, '--no-progress' => 1];
if ($input->getOption(self::OPTION_NO_UPDATE)) {
$commonArgs['--no-update'] = 1;
}
$packages = []; $packages = [];
foreach ($sampleDataPackages as $name => $version) { foreach ($sampleDataPackages as $name => $version) {
$packages[] = "$name:$version"; $packages[] = "$name:$version";
......
...@@ -8,6 +8,7 @@ namespace Magento\SampleData\Console\Command; ...@@ -8,6 +8,7 @@ namespace Magento\SampleData\Console\Command;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Magento\SampleData\Model\Dependency; use Magento\SampleData\Model\Dependency;
use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\ArrayInput;
...@@ -22,6 +23,8 @@ use Composer\Console\ApplicationFactory; ...@@ -22,6 +23,8 @@ use Composer\Console\ApplicationFactory;
*/ */
class SampleDataRemoveCommand extends Command class SampleDataRemoveCommand extends Command
{ {
const OPTION_NO_UPDATE = 'no-update';
/** /**
* @var Filesystem * @var Filesystem
*/ */
...@@ -69,6 +72,12 @@ class SampleDataRemoveCommand extends Command ...@@ -69,6 +72,12 @@ class SampleDataRemoveCommand extends Command
{ {
$this->setName('sampledata:remove') $this->setName('sampledata:remove')
->setDescription('Remove all sample data packages from composer.json'); ->setDescription('Remove all sample data packages from composer.json');
$this->addOption(
self::OPTION_NO_UPDATE,
null,
InputOption::VALUE_NONE,
'Update composer.json without executing composer update'
);
parent::configure(); parent::configure();
} }
...@@ -81,6 +90,9 @@ class SampleDataRemoveCommand extends Command ...@@ -81,6 +90,9 @@ class SampleDataRemoveCommand extends Command
if (!empty($sampleDataPackages)) { if (!empty($sampleDataPackages)) {
$baseDir = $this->filesystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath(); $baseDir = $this->filesystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath();
$commonArgs = ['--working-dir' => $baseDir, '--no-interaction' => 1, '--no-progress' => 1]; $commonArgs = ['--working-dir' => $baseDir, '--no-interaction' => 1, '--no-progress' => 1];
if ($input->getOption(self::OPTION_NO_UPDATE)) {
$commonArgs['--no-update'] = 1;
}
$packages = array_keys($sampleDataPackages); $packages = array_keys($sampleDataPackages);
$arguments = array_merge(['command' => 'remove', 'packages' => $packages], $commonArgs); $arguments = array_merge(['command' => 'remove', 'packages' => $packages], $commonArgs);
$commandInput = new ArrayInput($arguments); $commandInput = new ArrayInput($arguments);
......
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\SampleData\Test\Unit\Console\Command;
use Composer\Console\Application;
use Composer\Console\ApplicationFactory;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\ReadInterface;
use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\SampleData\Model\Dependency;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\ArrayInputFactory;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
abstract class AbstractSampleDataCommandTest extends TestCase
{
/**
* @var ReadInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $directoryReadMock;
/**
* @var WriteInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $directoryWriteMock;
/**
* @var Filesystem|\PHPUnit_Framework_MockObject_MockObject
*/
protected $filesystemMock;
/**
* @var Dependency|\PHPUnit_Framework_MockObject_MockObject
*/
protected $sampleDataDependencyMock;
/**
* @var ArrayInputFactory|\PHPUnit_Framework_MockObject_MockObject
*/
protected $arrayInputFactoryMock;
/**
* @var Application|\PHPUnit_Framework_MockObject_MockObject
*/
protected $applicationMock;
/**
* @var ApplicationFactory|\PHPUnit_Framework_MockObject_MockObject
*/
protected $applicationFactoryMock;
/**
* @return void
*/
protected function setUp()
{
$this->directoryReadMock = $this->createMock(ReadInterface::class);
$this->directoryWriteMock = $this->createMock(WriteInterface::class);
$this->filesystemMock = $this->createMock(Filesystem::class);
$this->sampleDataDependencyMock = $this->createMock(Dependency::class);
$this->arrayInputFactoryMock = $this->createMock(ArrayInputFactory::class);
$this->applicationMock = $this->createMock(Application::class);
$this->applicationFactoryMock = $this->createPartialMock(ApplicationFactory::class, ['create']);
}
/**
* @param array $sampleDataPackages Array in form [package_name => version_constraint]
* @param string $pathToComposerJson Fake path to composer.json
* @param int $appRunResult Composer exit code
* @param array $additionalComposerArgs Additional arguments that composer expects
*/
protected function setupMocks(
$sampleDataPackages,
$pathToComposerJson,
$appRunResult,
$additionalComposerArgs = []
) {
$this->directoryReadMock->expects($this->any())->method('getAbsolutePath')->willReturn($pathToComposerJson);
$this->filesystemMock->expects($this->any())->method('getDirectoryRead')->with(DirectoryList::ROOT)->willReturn(
$this->directoryReadMock
);
$this->sampleDataDependencyMock->expects($this->any())->method('getSampleDataPackages')->willReturn(
$sampleDataPackages
);
$this->arrayInputFactoryMock->expects($this->never())->method('create');
$this->applicationMock->expects($this->any())
->method('run')
->with(
new ArrayInput(
array_merge(
$this->expectedComposerArguments(
$sampleDataPackages,
$pathToComposerJson
),
$additionalComposerArgs
)
),
$this->anything()
)
->willReturn($appRunResult);
if (($appRunResult !== 0) && !empty($sampleDataPackages)) {
$this->applicationMock->expects($this->once())->method('resetComposer')->willReturnSelf();
}
$this->applicationFactoryMock->expects($this->any())
->method('create')
->willReturn($this->applicationMock);
}
/**
* Expected arguments for composer based on sample data packages and composer.json path
*
* @param array $sampleDataPackages
* @param string $pathToComposerJson
* @return array
*/
abstract protected function expectedComposerArguments(
array $sampleDataPackages,
string $pathToComposerJson
) : array;
}
...@@ -9,66 +9,26 @@ use Magento\Framework\App\Filesystem\DirectoryList; ...@@ -9,66 +9,26 @@ use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\SampleData\Console\Command\SampleDataDeployCommand; use Magento\SampleData\Console\Command\SampleDataDeployCommand;
use Magento\Setup\Model\PackagesAuth; use Magento\Setup\Model\PackagesAuth;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\ReadInterface;
use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\SampleData\Model\Dependency;
use Symfony\Component\Console\Input\ArrayInputFactory;
use Composer\Console\ApplicationFactory;
use Composer\Console\Application;
/** class SampleDataDeployCommandTest extends AbstractSampleDataCommandTest
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase
{ {
/** /**
* @var ReadInterface|\PHPUnit_Framework_MockObject_MockObject * @param bool $authExist True to test with existing auth.json, false without
*/
private $directoryReadMock;
/**
* @var WriteInterface|\PHPUnit_Framework_MockObject_MockObject
*/
private $directoryWriteMock;
/**
* @var Filesystem|\PHPUnit_Framework_MockObject_MockObject
*/
private $filesystemMock;
/**
* @var Dependency|\PHPUnit_Framework_MockObject_MockObject
*/
private $sampleDataDependencyMock;
/**
* @var ArrayInputFactory|\PHPUnit_Framework_MockObject_MockObject
*/
private $arrayInputFactoryMock;
/**
* @var Application|\PHPUnit_Framework_MockObject_MockObject
*/
private $applicationMock;
/**
* @var ApplicationFactory|\PHPUnit_Framework_MockObject_MockObject
*/ */
private $applicationFactoryMock; protected function setupMocksForAuthFile($authExist)
/**
* @return void
*/
protected function setUp()
{ {
$this->directoryReadMock = $this->createMock(ReadInterface::class); $this->directoryWriteMock->expects($this->once())
$this->directoryWriteMock = $this->createMock(WriteInterface::class); ->method('isExist')
$this->filesystemMock = $this->createMock(Filesystem::class); ->with(PackagesAuth::PATH_TO_AUTH_FILE)
$this->sampleDataDependencyMock = $this->createMock(Dependency::class); ->willReturn($authExist);
$this->arrayInputFactoryMock = $this->createMock(ArrayInputFactory::class); $this->directoryWriteMock->expects($authExist ? $this->never() : $this->once())->method('writeFile')->with(
$this->applicationMock = $this->createMock(Application::class); PackagesAuth::PATH_TO_AUTH_FILE,
$this->applicationFactoryMock = $this->createPartialMock(ApplicationFactory::class, ['create']); '{}'
);
$this->filesystemMock->expects($this->once())
->method('getDirectoryWrite')
->with(DirectoryList::COMPOSER_HOME)
->willReturn($this->directoryWriteMock);
} }
/** /**
...@@ -82,68 +42,36 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase ...@@ -82,68 +42,36 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase
*/ */
public function testExecute(array $sampleDataPackages, $appRunResult, $expectedMsg, $authExist) public function testExecute(array $sampleDataPackages, $appRunResult, $expectedMsg, $authExist)
{ {
$pathToComposerJson = '/path/to/composer.json'; $this->setupMocks($sampleDataPackages, '/path/to/composer.json', $appRunResult);
$this->setupMocksForAuthFile($authExist);
$this->directoryReadMock->expects($this->any()) $commandTester = $this->createCommandTester();
->method('getAbsolutePath') $commandTester->execute([]);
->willReturn($pathToComposerJson);
$this->directoryWriteMock->expects($this->once())
->method('isExist')
->with(PackagesAuth::PATH_TO_AUTH_FILE)
->willReturn($authExist);
$this->directoryWriteMock->expects($authExist ? $this->never() : $this->once())
->method('writeFile')
->with(PackagesAuth::PATH_TO_AUTH_FILE, '{}');
$this->filesystemMock->expects($this->any())
->method('getDirectoryRead')
->with(DirectoryList::ROOT)
->willReturn($this->directoryReadMock);
$this->filesystemMock->expects($this->once())
->method('getDirectoryWrite')
->with(DirectoryList::COMPOSER_HOME)
->willReturn($this->directoryWriteMock);
$this->sampleDataDependencyMock->expects($this->any())
->method('getSampleDataPackages')
->willReturn($sampleDataPackages);
$this->arrayInputFactoryMock->expects($this->never())
->method('create');
array_walk($sampleDataPackages, function (&$v, $k) {
$v = "$k:$v";
});
$packages = array_values($sampleDataPackages);
$requireArgs = [
'command' => 'require',
'--working-dir' => $pathToComposerJson,
'--no-progress' => 1,
'packages' => $packages,
];
$commandInput = new \Symfony\Component\Console\Input\ArrayInput($requireArgs);
$this->applicationMock->expects($this->any())
->method('run')
->with($commandInput, $this->anything())
->willReturn($appRunResult);
if (($appRunResult !== 0) && !empty($sampleDataPackages)) {
$this->applicationMock->expects($this->once())->method('resetComposer')->willReturnSelf();
}
$this->applicationFactoryMock->expects($this->any()) $this->assertEquals($expectedMsg, $commandTester->getDisplay());
->method('create') }
->willReturn($this->applicationMock);
$commandTester = new CommandTester( /**
new SampleDataDeployCommand( * @param array $sampleDataPackages
$this->filesystemMock, * @param int $appRunResult - int 0 if everything went fine, or an error code
$this->sampleDataDependencyMock, * @param string $expectedMsg
$this->arrayInputFactoryMock, * @param bool $authExist
$this->applicationFactoryMock * @return void
) *
* @dataProvider processDataProvider
*/
public function testExecuteWithNoUpdate(array $sampleDataPackages, $appRunResult, $expectedMsg, $authExist)
{
$this->setupMocks(
$sampleDataPackages,
'/path/to/composer.json',
$appRunResult,
['--no-update' => 1]
); );
$commandTester->execute([]); $this->setupMocksForAuthFile($authExist);
$commandInput = ['--no-update' => 1];
$commandTester = $this->createCommandTester();
$commandTester->execute($commandInput);
$this->assertEquals($expectedMsg, $commandTester->getDisplay()); $this->assertEquals($expectedMsg, $commandTester->getDisplay());
} }
...@@ -154,13 +82,13 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase ...@@ -154,13 +82,13 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase
public function processDataProvider() public function processDataProvider()
{ {
return [ return [
[ 'No sample data found' => [
'sampleDataPackages' => [], 'sampleDataPackages' => [],
'appRunResult' => 1, 'appRunResult' => 1,
'expectedMsg' => 'There is no sample data for current set of modules.' . PHP_EOL, 'expectedMsg' => 'There is no sample data for current set of modules.' . PHP_EOL,
'authExist' => true, 'authExist' => true,
], ],
[ 'No auth.json found' => [
'sampleDataPackages' => [ 'sampleDataPackages' => [
'magento/module-cms-sample-data' => '1.0.0-beta', 'magento/module-cms-sample-data' => '1.0.0-beta',
], ],
...@@ -169,7 +97,7 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase ...@@ -169,7 +97,7 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase
. PHP_EOL, . PHP_EOL,
'authExist' => false, 'authExist' => false,
], ],
[ 'Successful sample data installation' => [
'sampleDataPackages' => [ 'sampleDataPackages' => [
'magento/module-cms-sample-data' => '1.0.0-beta', 'magento/module-cms-sample-data' => '1.0.0-beta',
], ],
...@@ -204,6 +132,14 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase ...@@ -204,6 +132,14 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase
->with(DirectoryList::COMPOSER_HOME) ->with(DirectoryList::COMPOSER_HOME)
->willReturn($this->directoryWriteMock); ->willReturn($this->directoryWriteMock);
$this->createCommandTester()->execute([]);
}
/**
* @return CommandTester
*/
private function createCommandTester(): CommandTester
{
$commandTester = new CommandTester( $commandTester = new CommandTester(
new SampleDataDeployCommand( new SampleDataDeployCommand(
$this->filesystemMock, $this->filesystemMock,
...@@ -212,6 +148,36 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase ...@@ -212,6 +148,36 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase
$this->applicationFactoryMock $this->applicationFactoryMock
) )
); );
$commandTester->execute([]); return $commandTester;
}
/**
* @param $sampleDataPackages
* @param $pathToComposerJson
* @return array
*/
protected function expectedComposerArguments(
array $sampleDataPackages,
string $pathToComposerJson
) : array {
return [
'command' => 'require',
'--working-dir' => $pathToComposerJson,
'--no-progress' => 1,
'packages' => $this->packageVersionStrings($sampleDataPackages),
];
}
/**
* @param array $sampleDataPackages
* @return array
*/
private function packageVersionStrings(array $sampleDataPackages): array
{
array_walk($sampleDataPackages, function (&$v, $k) {
$v = "$k:$v";
});
return array_values($sampleDataPackages);
} }
} }
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\SampleData\Test\Unit\Console\Command;
use Magento\SampleData\Console\Command\SampleDataRemoveCommand;
use Symfony\Component\Console\Tester\CommandTester;
class SampleDataRemoveCommandTest extends AbstractSampleDataCommandTest
{
/**
* @param array $sampleDataPackages
* @param int $appRunResult - int 0 if everything went fine, or an error code
* @param string $expectedMsg
* @return void
*
* @dataProvider processDataProvider
*/
public function testExecute(array $sampleDataPackages, $appRunResult, $expectedMsg)
{
$this->setupMocks($sampleDataPackages, '/path/to/composer.json', $appRunResult);
$commandTester = $this->createCommandTester();
$commandTester->execute([]);
$this->assertEquals($expectedMsg, $commandTester->getDisplay());
}
/**
* @param array $sampleDataPackages
* @param int $appRunResult - int 0 if everything went fine, or an error code
* @param string $expectedMsg
* @return void
*
* @dataProvider processDataProvider
*/
public function testExecuteWithNoUpdate(array $sampleDataPackages, $appRunResult, $expectedMsg)
{
$this->setupMocks(
$sampleDataPackages,
'/path/to/composer.json',
$appRunResult,
['--no-update' => 1]
);
$commandInput = ['--no-update' => 1];
$commandTester = $this->createCommandTester();
$commandTester->execute($commandInput);
$this->assertEquals($expectedMsg, $commandTester->getDisplay());
}
/**
* @return array
*/
public function processDataProvider()
{
return [
'No sample data found' => [
'sampleDataPackages' => [],
'appRunResult' => 1,
'expectedMsg' => 'There is no sample data for current set of modules.' . PHP_EOL,
],
'Successful sample data installation' => [
'sampleDataPackages' => [
'magento/module-cms-sample-data' => '1.0.0-beta',
],
'appRunResult' => 0,
'expectedMsg' => '',
],
];
}
/**
* @return CommandTester
*/
private function createCommandTester(): CommandTester
{
$commandTester = new CommandTester(
new SampleDataRemoveCommand(
$this->filesystemMock,
$this->sampleDataDependencyMock,
$this->arrayInputFactoryMock,
$this->applicationFactoryMock
)
);
return $commandTester;
}
/**
* @param $sampleDataPackages
* @param $pathToComposerJson
* @return array
*/
protected function expectedComposerArguments(
array $sampleDataPackages,
string $pathToComposerJson
) : array {
return [
'command' => 'remove',
'--working-dir' => $pathToComposerJson,
'--no-interaction' => 1,
'--no-progress' => 1,
'packages' => array_keys($sampleDataPackages),
];
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment