21 use Magento\Setup\Validator\DbValidator;
37 private $filePermissions;
42 private $configWriter;
47 private $configReader;
62 private $moduleLoader;
67 private $directoryList;
72 private $adminFactory;
92 private $maintenanceMode;
102 private $objectManager;
107 private $configModel;
112 private $cleanupFiles;
117 private $dbValidator;
122 private $setupFactory;
127 private $dataSetupFactory;
132 private $sampleDataState;
137 private $componentRegistrar;
142 private $phpReadinessCheck;
147 private $declarationInstallerMock;
152 private $schemaListenerMock;
158 private static $dbConfig = [
170 private $contextMock;
175 private $patchApplierMock;
180 private $patchApplierFactoryMock;
184 $this->filePermissions = $this->createMock(\
Magento\Framework\
Setup\FilePermissions::class);
187 $this->config = $this->createMock(\
Magento\Framework\
App\DeploymentConfig::class);
189 $this->moduleList = $this->getMockForAbstractClass(\
Magento\Framework\
Module\ModuleListInterface::class);
190 $this->moduleList->expects($this->any())->method(
'getOne')->willReturn(
191 [
'setup_version' =>
'2.0.0']
193 $this->moduleList->expects($this->any())->method(
'getNames')->willReturn(
194 [
'Foo_One',
'Bar_Two']
197 $this->directoryList =
199 $this->adminFactory = $this->createMock(\
Magento\
Setup\Model\AdminAccountFactory::class);
200 $this->logger = $this->getMockForAbstractClass(\
Magento\Framework\
Setup\LoggerInterface::class);
201 $this->random = $this->createMock(\
Magento\Framework\Math\Random::class);
202 $this->connection = $this->getMockForAbstractClass(\
Magento\Framework\DB\Adapter\AdapterInterface::class);
203 $this->maintenanceMode = $this->createMock(\
Magento\Framework\
App\MaintenanceMode::class);
204 $this->filesystem = $this->createMock(\
Magento\Framework\Filesystem::class);
205 $this->objectManager = $this->getMockForAbstractClass(\
Magento\Framework\ObjectManagerInterface::class);
208 $this->configModel = $this->createMock(\
Magento\
Setup\Model\ConfigModel::class);
209 $this->cleanupFiles = $this->createMock(\
Magento\Framework\
App\
State\CleanupFiles::class);
212 $this->dataSetupFactory = $this->createMock(\
Magento\
Setup\
Module\DataSetupFactory::class);
213 $this->sampleDataState = $this->createMock(\
Magento\Framework\
Setup\SampleData\State::class);
214 $this->componentRegistrar =
215 $this->createMock(\
Magento\Framework\Component\ComponentRegistrar::class);
216 $this->phpReadinessCheck = $this->createMock(\
Magento\
Setup\Model\PhpReadinessCheck::class);
217 $this->declarationInstallerMock = $this->createMock(DeclarationInstaller::class);
218 $this->schemaListenerMock = $this->createMock(SchemaListener::class);
219 $this->patchApplierFactoryMock = $this->createMock(PatchApplierFactory::class);
220 $this->patchApplierMock = $this->createMock(PatchApplier::class);
221 $this->patchApplierFactoryMock->expects($this->any())->method(
'create')->willReturn(
222 $this->patchApplierMock
224 $this->
object = $this->createObject();
233 private function createObject($connectionFactory =
false, $objectManagerProvider =
false)
235 if (!$connectionFactory) {
236 $connectionFactory = $this->createMock(\
Magento\
Setup\
Module\ConnectionFactory::class);
237 $connectionFactory->expects($this->any())->method(
'create')->willReturn($this->connection);
239 if (!$objectManagerProvider) {
240 $objectManagerProvider =
241 $this->createMock(\
Magento\Setup\Model\ObjectManagerProvider::class);
242 $objectManagerProvider->expects($this->any())->method(
'get')->willReturn($this->objectManager);
245 return new Installer(
246 $this->filePermissions,
255 $this->maintenanceMode,
257 $objectManagerProvider,
263 $this->dataSetupFactory,
264 $this->sampleDataState,
265 $this->componentRegistrar,
266 $this->phpReadinessCheck,
267 $this->declarationInstallerMock
279 $this->config->expects($this->atLeastOnce())
285 [
'modules/Magento_User',
null,
'1']
288 $allModules = [
'Foo_One' => [],
'Bar_Two' => []];
290 $this->declarationInstallerMock->expects($this->once())->method(
'installSchema');
291 $this->moduleLoader->expects($this->any())->method(
'load')->willReturn($allModules);
293 $table = $this->createMock(\
Magento\Framework\DB\Ddl\Table::class);
294 $connection = $this->getMockBuilder(\
Magento\Framework\DB\Adapter\AdapterInterface::class)
295 ->setMethods([
'getSchemaListener',
'newTable'])
296 ->getMockForAbstractClass();
297 $connection->expects($this->any())->method(
'getSchemaListener')->willReturn($this->schemaListenerMock);
298 $setup->expects($this->any())->method(
'getConnection')->willReturn($connection);
299 $table->expects($this->any())->method(
'addColumn')->willReturn(
$table);
300 $table->expects($this->any())->method(
'setComment')->willReturn(
$table);
301 $table->expects($this->any())->method(
'addIndex')->willReturn(
$table);
302 $connection->expects($this->any())->method(
'newTable')->willReturn(
$table);
304 $this->contextMock->expects($this->any())->method(
'getResources')->willReturn(
$resource);
305 $resource->expects($this->any())->method(
'getConnection')->will($this->returnValue($connection));
307 $dataSetup->expects($this->any())->method(
'getConnection')->willReturn($connection);
308 $cacheManager = $this->createMock(\
Magento\Framework\
App\
Cache\Manager::class);
309 $cacheManager->expects($this->any())->method(
'getAvailableTypes')->willReturn([
'foo',
'bar']);
310 $cacheManager->expects($this->once())->method(
'setEnabled')->willReturn([
'foo',
'bar']);
311 $cacheManager->expects($this->any())->method(
'clean');
312 $appState = $this->getMockBuilder(\
Magento\Framework\
App\State::class)
313 ->disableOriginalConstructor()
314 ->disableArgumentCloning()
316 $appState->expects($this->once())
317 ->method(
'setAreaCode')
318 ->with(\
Magento\Framework\
App\Area::AREA_GLOBAL);
320 $this->setupFactory->expects($this->atLeastOnce())->method(
'create')->with(
$resource)->willReturn(
$setup);
321 $this->dataSetupFactory->expects($this->atLeastOnce())->method(
'create')->willReturn($dataSetup);
322 $this->objectManager->expects($this->any())
324 ->will($this->returnValueMap([
326 [\
Magento\Framework\
App\State::class, [], $appState],
328 PatchApplierFactory::class,
329 [
'objectManager' => $this->objectManager],
330 $this->patchApplierFactoryMock
333 $this->patchApplierMock->expects($this->exactly(2))->method(
'applySchemaPatch')->willReturnMap(
339 $this->patchApplierMock->expects($this->exactly(2))->method(
'applyDataPatch')->willReturnMap(
345 $this->objectManager->expects($this->any())
347 ->will($this->returnValueMap([
348 [\
Magento\Framework\
App\State::class, $appState],
350 [\
Magento\
Setup\Model\DeclarationInstaller::class, $this->declarationInstallerMock],
353 $this->adminFactory->expects($this->any())->method(
'create')->willReturn(
354 $this->createMock(\
Magento\
Setup\Model\AdminAccount::class)
356 $this->sampleDataState->expects($this->once())->method(
'hasError')->willReturn(
true);
357 $this->phpReadinessCheck->expects($this->once())->method(
'checkPhpExtensions')->willReturn(
360 $this->filePermissions->expects($this->any())
361 ->method(
'getMissingWritablePathsForInstallation')
363 $this->filePermissions->expects($this->once())
364 ->method(
'getMissingWritableDirectoriesForDbUpgrade')
366 call_user_func_array(
368 $this->logger->expects($this->exactly(count($logMessages)))->method(
'log'),
373 $this->logger->expects($this->exactly(2))
374 ->method(
'logSuccess')
376 [
'Magento installation complete.'],
377 [
'Magento Admin URI: /']
380 $this->
object->install($request);
395 ConfigOptionsList::INPUT_KEY_BACKEND_FRONTNAME =>
'backend',
398 [
'Starting Magento installation:'],
399 [
'File permissions check...'],
400 [
'Required extensions check...'],
401 [
'Enabling Maintenance Mode...'],
402 [
'Installing deployment configuration...'],
403 [
'Installing database schema:'],
404 [
'Schema creation/updates:'],
405 [
'Module \'Foo_One\':'],
406 [
'Module \'Bar_Two\':'],
407 [
'Schema post-updates:'],
408 [
'Module \'Foo_One\':'],
409 [
'Module \'Bar_Two\':'],
410 [
'Installing user configuration...'],
411 [
'Enabling caches:'],
414 [
'Installing data...'],
415 [
'Data install/update:'],
416 [
'Module \'Foo_One\':'],
417 [
'Module \'Bar_Two\':'],
418 [
'Data post-updates:'],
419 [
'Module \'Foo_One\':'],
420 [
'Module \'Bar_Two\':'],
422 [
'Caches clearing:'],
423 [
'Cache cleared successfully'],
424 [
'Disabling Maintenance Mode:'],
425 [
'Post installation file permissions check...'],
426 [
'Write installation date...'],
427 [
'Sample Data is installed with errors. See log file for details']
436 ConfigOptionsList::INPUT_KEY_BACKEND_FRONTNAME =>
'backend',
444 [
'Starting Magento installation:'],
445 [
'File permissions check...'],
446 [
'Required extensions check...'],
447 [
'Enabling Maintenance Mode...'],
448 [
'Installing deployment configuration...'],
449 [
'Installing database schema:'],
450 [
'Schema creation/updates:'],
451 [
'Module \'Foo_One\':'],
452 [
'Module \'Bar_Two\':'],
453 [
'Schema post-updates:'],
454 [
'Module \'Foo_One\':'],
455 [
'Module \'Bar_Two\':'],
456 [
'Installing user configuration...'],
457 [
'Enabling caches:'],
460 [
'Installing data...'],
461 [
'Data install/update:'],
462 [
'Module \'Foo_One\':'],
463 [
'Module \'Bar_Two\':'],
464 [
'Data post-updates:'],
465 [
'Module \'Foo_One\':'],
466 [
'Module \'Bar_Two\':'],
467 [
'Installing admin user...'],
468 [
'Caches clearing:'],
469 [
'Cache cleared successfully'],
470 [
'Disabling Maintenance Mode:'],
471 [
'Post installation file permissions check...'],
472 [
'Write installation date...'],
473 [
'Sample Data is installed with errors. See log file for details']
481 $this->filePermissions
482 ->expects($this->once())
483 ->method(
'getMissingWritablePathsForInstallation')
485 $this->
object->checkInstallationFilePermissions();
494 $this->filePermissions
495 ->expects($this->once())
496 ->method(
'getMissingWritablePathsForInstallation')
497 ->willReturn([
'foo',
'bar']);
498 $this->
object->checkInstallationFilePermissions();
503 $this->phpReadinessCheck->expects($this->once())->method(
'checkPhpExtensions')->willReturn(
506 $this->
object->checkExtensions();
515 $this->phpReadinessCheck->expects($this->once())->method(
'checkPhpExtensions')->willReturn(
518 'data' => [
'required' => [
'foo',
'bar'],
'missing' => [
'foo']]
521 $this->
object->checkExtensions();
526 $this->filePermissions
527 ->expects($this->once())
528 ->method(
'getUnnecessaryWritableDirectoriesForApplication')
529 ->willReturn([
'foo',
'bar']);
530 $expectedMessage =
"For security, remove write permissions from these directories: 'foo' 'bar'";
531 $this->logger->expects($this->once())->method(
'log')->with($expectedMessage);
532 $this->
object->checkApplicationFilePermissions();
533 $this->assertSame([
'message' => [$expectedMessage]], $this->object->getInstallInfo());
538 $this->cleanupFiles->expects($this->once())->method(
'clearCodeGeneratedFiles')->will(
541 "The directory '/generation' doesn't exist - skipping cleanup",
545 $installer = $this->prepareForUpdateModulesTests();
547 $this->logger->expects($this->at(0))->method(
'log')->with(
'Cache cleared successfully');
548 $this->logger->expects($this->at(1))->method(
'log')->with(
'File system cleanup:');
549 $this->logger->expects($this->at(2))->method(
'log')
550 ->with(
'The directory \'/generation\' doesn\'t exist - skipping cleanup');
551 $this->logger->expects($this->at(3))->method(
'log')->with(
'Updating modules:');
557 $this->cleanupFiles->expects($this->never())->method(
'clearCodeGeneratedClasses');
559 $installer = $this->prepareForUpdateModulesTests();
561 $this->logger->expects($this->at(0))->method(
'log')->with(
'Cache cleared successfully');
562 $this->logger->expects($this->at(1))->method(
'log')->with(
'Updating modules:');
568 $this->config->expects($this->once())
572 $this->configReader->expects($this->once())->method(
'getFiles')->willReturn([
576 $configDir = $this->getMockForAbstractClass(
580 ->expects($this->exactly(2))
581 ->method(
'getAbsolutePath')
583 $this->returnValueMap(
585 [
'ConfigOne.php',
'/config/ConfigOne.php'],
586 [
'ConfigTwo.php',
'/config/ConfigTwo.php']
591 ->expects($this->any())
592 ->method(
'getDirectoryWrite')
593 ->will($this->returnValueMap([
596 $this->logger->expects($this->at(0))->method(
'log')->with(
'Starting Magento uninstallation:');
598 ->expects($this->at(2))
600 ->with(
'No database connection defined - skipping database cleanup');
601 $cacheManager = $this->createMock(\
Magento\Framework\
App\
Cache\Manager::class);
602 $cacheManager->expects($this->once())->method(
'getAvailableTypes')->willReturn([
'foo',
'bar']);
603 $cacheManager->expects($this->once())->method(
'clean');
604 $this->objectManager->expects($this->any())
607 ->willReturn($cacheManager);
608 $this->logger->expects($this->at(1))->method(
'log')->with(
'Cache cleared successfully');
609 $this->logger->expects($this->at(3))->method(
'log')->with(
'File system cleanup:');
611 ->expects($this->at(4))
613 ->with(
"The directory '/var' doesn't exist - skipping cleanup");
615 ->expects($this->at(5))
617 ->with(
"The directory '/static' doesn't exist - skipping cleanup");
619 ->expects($this->at(6))
621 ->with(
"The file '/config/ConfigOne.php' doesn't exist - skipping cleanup");
623 ->expects($this->at(7))
625 ->with(
"The file '/config/ConfigTwo.php' doesn't exist - skipping cleanup");
626 $this->logger->expects($this->once())->method(
'logSuccess')->with(
'Magento uninstallation complete.');
627 $this->cleanupFiles->expects($this->once())->method(
'clearAllFiles')->will(
630 "The directory '/var' doesn't exist - skipping cleanup",
631 "The directory '/static' doesn't exist - skipping cleanup" 636 $this->
object->uninstall();
641 $this->config->expects($this->once())
644 ->willReturn(self::$dbConfig);
645 $this->connection->expects($this->at(0))->method(
'quoteIdentifier')->with(
'magento')->willReturn(
648 $this->connection->expects($this->at(1))->method(
'query')->with(
'DROP DATABASE IF EXISTS `magento`');
649 $this->connection->expects($this->at(2))->method(
'query')->with(
'CREATE DATABASE IF NOT EXISTS `magento`');
650 $this->logger->expects($this->once())->method(
'log')->with(
'Cleaning up database `magento`');
651 $this->
object->cleanupDb();
658 private function prepareForUpdateModulesTests()
666 $cacheManager = $this->createMock(\
Magento\Framework\
App\
Cache\Manager::class);
667 $cacheManager->expects($this->once())->method(
'getAvailableTypes')->willReturn([
'foo',
'bar']);
668 $cacheManager->expects($this->once())->method(
'clean');
669 $this->objectManager->expects($this->any())
671 ->will($this->returnValueMap([
674 $this->moduleLoader->expects($this->once())->method(
'load')->willReturn($allModules);
686 $this->config->expects($this->atLeastOnce())
691 $newObject = $this->createObject(
false,
false);
692 $this->configReader->expects($this->once())->method(
'load')
693 ->willReturn([
'modules' => [
'Bar_Two' => 0,
'Foo_One' => 1,
'Old_Module' => 0]]);
694 $this->configWriter->expects($this->once())->method(
'saveConfig')->with($expectedModules);
710 return [
'mock_function_one',
'mock_function_two'];
testUpdateModulesSequenceKeepGenerated()
testCheckApplicationFilePermissions()
const CONFIG_PATH_DB_CONNECTION_DEFAULT
const CONFIG_PATH_CRYPT_KEY
testInstall(array $request, array $logMessages)
testCheckInstallationFilePermissions()
const RESPONSE_TYPE_SUCCESS
const CONFIG_PATH_DB_CONNECTIONS
const RESPONSE_TYPE_ERROR
const INPUT_KEY_ENCRYPTION_KEY
testCheckExtensionsError()
testCheckInstallationFilePermissionsError()
testUpdateModulesSequence()