Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\InstallBundle\Tests\Command;
|
||||
|
||||
use Doctrine\Bundle\DoctrineBundle\Registry;
|
||||
use Mautic\CoreBundle\Doctrine\Connection\ConnectionWrapper;
|
||||
use Mautic\InstallBundle\Command\InstallCommand;
|
||||
use Mautic\InstallBundle\Install\InstallService;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Helper\HelperSet;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputDefinition;
|
||||
use Symfony\Component\Console\Output\BufferedOutput;
|
||||
|
||||
class InstallCommandTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var MockObject&InstallService
|
||||
*/
|
||||
private MockObject $installer;
|
||||
|
||||
/**
|
||||
* @var MockObject&Registry
|
||||
*/
|
||||
private MockObject $doctrineRegistry;
|
||||
|
||||
private InstallCommand $command;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->installer = $this->createMock(InstallService::class);
|
||||
$this->doctrineRegistry = $this->createMock(Registry::class);
|
||||
$application = $this->createMock(Application::class);
|
||||
$inputDefinition = $this->createMock(InputDefinition::class);
|
||||
$command = $this->createMock(Command::class);
|
||||
|
||||
$inputDefinition->method('getOptions')->willReturn([]);
|
||||
$inputDefinition->method('getArguments')->willReturn([]);
|
||||
|
||||
$application->method('getHelperSet')->willReturn($this->createMock(HelperSet::class));
|
||||
$application->method('getDefinition')->willReturn($inputDefinition);
|
||||
$application->method('find')->willReturn($command);
|
||||
|
||||
$this->command = new InstallCommand($this->installer, $this->doctrineRegistry);
|
||||
$this->command->setApplication($application);
|
||||
}
|
||||
|
||||
public function testCommandWhenSiteInstalled(): void
|
||||
{
|
||||
$this->installer->method('checkIfInstalled')->willReturnOnConsecutiveCalls(true);
|
||||
|
||||
$input = new ArrayInput(['site_url' => 'localhost']);
|
||||
$output = new BufferedOutput();
|
||||
$this->command->run($input, $output);
|
||||
|
||||
$this->assertSame('Mautic already installed'.PHP_EOL, $output->fetch());
|
||||
}
|
||||
|
||||
public function testCommandWhenSiteNotInstalled(): void
|
||||
{
|
||||
$this->installer->method('checkIfInstalled')->willReturnOnConsecutiveCalls(false);
|
||||
|
||||
$this->doctrineRegistry->method('getConnection')->willReturn($this->createMock(ConnectionWrapper::class));
|
||||
|
||||
$input = new ArrayInput(
|
||||
[
|
||||
'site_url' => 'localhost',
|
||||
'--admin_firstname' => 'Admin',
|
||||
'--admin_lastname' => 'Mautic',
|
||||
'--admin_username' => 'admin',
|
||||
'--admin_email' => 'admin@example.com',
|
||||
'--admin_password' => 'password',
|
||||
]
|
||||
);
|
||||
$output = new BufferedOutput();
|
||||
$this->command->run($input, $output);
|
||||
|
||||
$this->assertStringContainsString('Install complete'.PHP_EOL, $output->fetch());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\InstallBundle\Tests\Controller;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Mautic\CoreBundle\Configurator\Configurator;
|
||||
use Mautic\CoreBundle\Factory\ModelFactory;
|
||||
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
||||
use Mautic\CoreBundle\Helper\PathsHelper;
|
||||
use Mautic\CoreBundle\Helper\UserHelper;
|
||||
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
|
||||
use Mautic\CoreBundle\Service\FlashBag;
|
||||
use Mautic\CoreBundle\Translation\Translator;
|
||||
use Mautic\InstallBundle\Controller\InstallController;
|
||||
use Mautic\InstallBundle\Install\InstallService;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Routing\Router;
|
||||
|
||||
class InstallControllerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \PHPUnit\Framework\MockObject\MockObject $translatorMock;
|
||||
|
||||
private \PHPUnit\Framework\MockObject\MockObject $sessionMock;
|
||||
|
||||
private \PHPUnit\Framework\MockObject\MockObject $containerMock;
|
||||
|
||||
private \PHPUnit\Framework\MockObject\MockObject $routerMock;
|
||||
|
||||
private \PHPUnit\Framework\MockObject\MockObject $flashBagMock;
|
||||
|
||||
private InstallController $controller;
|
||||
|
||||
private \PHPUnit\Framework\MockObject\MockObject $pathsHelper;
|
||||
|
||||
private \PHPUnit\Framework\MockObject\MockObject $configurator;
|
||||
|
||||
private \PHPUnit\Framework\MockObject\MockObject $installer;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->sessionMock = $this->createMock(Session::class);
|
||||
$this->containerMock = $this->createMock(Container::class);
|
||||
$this->routerMock = $this->createMock(Router::class);
|
||||
$this->flashBagMock = $this->createMock(FlashBagInterface::class);
|
||||
$this->pathsHelper = $this->createMock(PathsHelper::class);
|
||||
|
||||
$this->configurator = $this->createMock(Configurator::class);
|
||||
$this->installer = $this->createMock(InstallService::class);
|
||||
$doctrine = $this->createMock(ManagerRegistry::class);
|
||||
$modelFactory = $this->createMock(ModelFactory::class);
|
||||
$userHelper = $this->createMock(UserHelper::class);
|
||||
$coreParametersHelper = $this->createMock(CoreParametersHelper::class);
|
||||
$dispatcher = $this->createMock(EventDispatcherInterface::class);
|
||||
$this->translatorMock = $this->createMock(Translator::class);
|
||||
$flashBag = $this->createMock(FlashBag::class);
|
||||
$requestStack = new RequestStack();
|
||||
$security = $this->createMock(CorePermissions::class);
|
||||
|
||||
$this->controller = new InstallController(
|
||||
$this->configurator,
|
||||
$this->installer,
|
||||
$doctrine,
|
||||
$modelFactory,
|
||||
$userHelper,
|
||||
$coreParametersHelper,
|
||||
$dispatcher,
|
||||
$this->translatorMock,
|
||||
$flashBag,
|
||||
$requestStack,
|
||||
$security
|
||||
);
|
||||
$this->controller->setContainer($this->containerMock);
|
||||
$this->sessionMock->method('getFlashBag')->willReturn($this->flashBagMock);
|
||||
|
||||
$this->containerMock->method('get')
|
||||
->with('router')
|
||||
->willReturn($this->routerMock);
|
||||
}
|
||||
|
||||
public function testStepActionWhenInstalled(): void
|
||||
{
|
||||
$this->installer->expects($this->once())
|
||||
->method('checkIfInstalled')
|
||||
->willReturn(
|
||||
true
|
||||
);
|
||||
|
||||
$this->routerMock->expects($this->once())
|
||||
->method('generate')
|
||||
->with('mautic_dashboard_index', [], UrlGeneratorInterface::ABSOLUTE_PATH)
|
||||
->willReturn('http://localhost/');
|
||||
|
||||
$response = $this->controller->stepAction(
|
||||
new Request(),
|
||||
$this->createMock(EntityManagerInterface::class),
|
||||
$this->pathsHelper,
|
||||
InstallService::CHECK_STEP
|
||||
);
|
||||
$this->assertEquals(302, $response->getStatusCode());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\InstallBundle\Tests\EventListener;
|
||||
|
||||
use Doctrine\DBAL\Schema\Column;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\DBAL\Types\BigIntType;
|
||||
use Doctrine\DBAL\Types\DateTimeType;
|
||||
use Doctrine\DBAL\Types\TextType;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
|
||||
use Mautic\InstallBundle\EventListener\DoctrineEventSubscriber;
|
||||
use PHPUnit\Framework\Assert;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DoctrineEventSubscriberTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var MockObject&EntityManagerInterface
|
||||
*/
|
||||
private MockObject $entityManager;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->entityManager = $this->createMock(EntityManagerInterface::class);
|
||||
}
|
||||
|
||||
public function testSubscriberWillAddCorrectIndexes(): void
|
||||
{
|
||||
$idColumn = new Column('id', new BigIntType());
|
||||
$textColumn = new Column('firstname', new TextType());
|
||||
$dateColumn = new Column('date_added', new DateTimeType());
|
||||
$table = new Table(MAUTIC_TABLE_PREFIX.'leads', [$idColumn, $textColumn, $dateColumn]);
|
||||
$schema = new Schema([$table]);
|
||||
$args = new GenerateSchemaEventArgs($this->entityManager, $schema);
|
||||
$subscriber = new DoctrineEventSubscriber();
|
||||
$subscriber->postGenerateSchema($args);
|
||||
|
||||
Assert::assertTrue($schema->hasTable(MAUTIC_TABLE_PREFIX.'leads'));
|
||||
$contactsTable = $schema->getTable(MAUTIC_TABLE_PREFIX.'leads');
|
||||
Assert::assertTrue($contactsTable->hasIndex('contact_attribution'));
|
||||
Assert::assertTrue($contactsTable->hasIndex('date_added_country_index'));
|
||||
}
|
||||
|
||||
public function testSubscriberWillNotFailWithTablesFromAPlugin(): void
|
||||
{
|
||||
$table = new Table(MAUTIC_TABLE_PREFIX.'some_plugin_table', [new Column('id', new BigIntType())]);
|
||||
$schema = new Schema([$table]);
|
||||
$args = new GenerateSchemaEventArgs($this->entityManager, $schema);
|
||||
$subscriber = new DoctrineEventSubscriber();
|
||||
$subscriber->postGenerateSchema($args);
|
||||
|
||||
Assert::assertTrue($schema->hasTable(MAUTIC_TABLE_PREFIX.'some_plugin_table'));
|
||||
Assert::assertFalse($schema->hasTable(MAUTIC_TABLE_PREFIX.'leads'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\InstallBundle\Tests\Functional;
|
||||
|
||||
use Mautic\CoreBundle\Helper\FileHelper;
|
||||
use Mautic\CoreBundle\Test\IsolatedTestTrait;
|
||||
use Mautic\CoreBundle\Test\MauticMysqlTestCase;
|
||||
use Mautic\InstallBundle\Configurator\Step\CheckStep;
|
||||
use Mautic\LeadBundle\Entity\LeadField;
|
||||
use PHPUnit\Framework\Assert;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* This test must run in a separate process because it sets the global constant
|
||||
* MAUTIC_INSTALLER which breaks other tests.
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\PreserveGlobalState(false)]
|
||||
#[\PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses]
|
||||
class InstallWorkflowTest extends MauticMysqlTestCase
|
||||
{
|
||||
use IsolatedTestTrait;
|
||||
|
||||
protected $useCleanupRollback = false;
|
||||
|
||||
private string $localConfigPath;
|
||||
|
||||
private string $defaultMemoryLimit;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->localConfigPath = static::getContainer()->get('kernel')->getLocalConfigFile();
|
||||
$this->defaultMemoryLimit = ini_get('memory_limit');
|
||||
|
||||
if (file_exists($this->localConfigPath)) {
|
||||
// Move local.php so we can get to the installer.
|
||||
rename($this->localConfigPath, $this->localConfigPath.'.bak');
|
||||
}
|
||||
}
|
||||
|
||||
protected function beforeTearDown(): void
|
||||
{
|
||||
if (file_exists($this->localConfigPath)) {
|
||||
// Remove the local.php generated by this test.
|
||||
unlink($this->localConfigPath);
|
||||
}
|
||||
if (file_exists($this->localConfigPath.'.bak')) {
|
||||
// Restore the local config file in it's original state.
|
||||
rename($this->localConfigPath.'.bak', $this->localConfigPath);
|
||||
}
|
||||
|
||||
ini_set('memory_limit', $this->defaultMemoryLimit);
|
||||
}
|
||||
|
||||
public function testInstallWorkflow(): void
|
||||
{
|
||||
// Step 0: System checks.
|
||||
$crawler = $this->client->request(Request::METHOD_GET, '/installer');
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
$submitButton = $crawler->selectButton('install_check_step[buttons][next]');
|
||||
$form = $submitButton->form();
|
||||
$crawler = $this->client->submit($form);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
// Step 1: DB.
|
||||
$submitButton = $crawler->selectButton('install_doctrine_step[buttons][next]');
|
||||
$form = $submitButton->form();
|
||||
|
||||
$form['install_doctrine_step[host]']->setValue($this->connection->getParams()['host']);
|
||||
$form['install_doctrine_step[port]']->setValue((string) $this->connection->getParams()['port']);
|
||||
$form['install_doctrine_step[name]']->setValue($this->connection->getParams()['dbname']);
|
||||
$form['install_doctrine_step[user]']->setValue($this->connection->getParams()['user']);
|
||||
$form['install_doctrine_step[password]']->setValue($this->connection->getParams()['password']);
|
||||
$form['install_doctrine_step[backup_tables]']->setValue('0');
|
||||
|
||||
$crawler = $this->client->submit($form);
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
// Step 2: Admin user.
|
||||
$submitButton = $crawler->selectButton('install_user_step[buttons][next]');
|
||||
$form = $submitButton->form();
|
||||
|
||||
$form['install_user_step[username]']->setValue('admin');
|
||||
$form['install_user_step[password]']->setValue('maut!cR000cks');
|
||||
$form['install_user_step[firstname]']->setValue('admin');
|
||||
$form['install_user_step[lastname]']->setValue('mautic');
|
||||
$form['install_user_step[email]']->setValue('mautic@example.com');
|
||||
|
||||
$crawler = $this->client->submit($form);
|
||||
$this->assertResponseIsSuccessful();
|
||||
$heading = $crawler->filter('.panel-body.text-center h5');
|
||||
Assert::assertCount(1, $heading, $this->client->getResponse()->getContent());
|
||||
|
||||
$successText = $heading->text();
|
||||
Assert::assertStringContainsString('Mautic is installed', $successText);
|
||||
|
||||
// Assert that the fixtures were loaded
|
||||
$fieldRepository = $this->em->getRepository(LeadField::class);
|
||||
|
||||
$emailField = $fieldRepository->findOneBy(['alias' => 'email']);
|
||||
\assert($emailField instanceof LeadField);
|
||||
Assert::assertSame('Email', $emailField->getLabel());
|
||||
}
|
||||
|
||||
public function testInstallRequirementsAndRecommendations(): void
|
||||
{
|
||||
$limit = FileHelper::convertPHPSizeToBytes(CheckStep::RECOMMENDED_MEMORY_LIMIT);
|
||||
$expectedMemoryMessage = static::getContainer()->get('translator')->trans('mautic.install.memory.limit', ['%min_memory_limit%' => CheckStep::RECOMMENDED_MEMORY_LIMIT]);
|
||||
|
||||
// set the memory limit lower than the recommended value.
|
||||
ini_set('memory_limit', (string) ($limit - 1));
|
||||
$crawler = $this->client->request(Request::METHOD_GET, '/installer');
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
$details = $crawler->filter('#minorDetails ul')->html();
|
||||
Assert::assertStringContainsString($expectedMemoryMessage, $details);
|
||||
|
||||
// set the memory limit higher than the recommended value.
|
||||
ini_set('memory_limit', (string) ($limit + 1));
|
||||
$crawler = $this->client->request(Request::METHOD_GET, '/installer');
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
$details = $crawler->filter('#minorDetails ul')->html();
|
||||
Assert::assertStringNotContainsString($expectedMemoryMessage, $details);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\InstallBundle\Tests\Install;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Schema\AbstractSchemaManager;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Mautic\CoreBundle\Test\EnvLoader;
|
||||
use Mautic\InstallBundle\Helper\SchemaHelper;
|
||||
use PHPUnit\Framework\Assert;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @template T of AbstractPlatform
|
||||
*/
|
||||
class InstallSchemaTest extends TestCase
|
||||
{
|
||||
private Connection $connection;
|
||||
|
||||
/**
|
||||
* @var array<string, mixed>
|
||||
*/
|
||||
private array $dbParams;
|
||||
|
||||
private string $indexTableName;
|
||||
|
||||
/**
|
||||
* @var AbstractSchemaManager<T>
|
||||
*/
|
||||
private AbstractSchemaManager $schemaManager;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
EnvLoader::load();
|
||||
|
||||
$this->dbParams = [
|
||||
'driver' => $_ENV['DB_DRIVER'] ?? 'pdo_mysql',
|
||||
'host' => $_ENV['DB_HOST'],
|
||||
'port' => $_ENV['DB_PORT'],
|
||||
'dbname' => $_ENV['DB_NAME'], // Doctrine needs 'dbname', not 'name'
|
||||
'user' => $_ENV['DB_USER'],
|
||||
'password' => $_ENV['DB_PASSWD'],
|
||||
'table_prefix' => MAUTIC_TABLE_PREFIX,
|
||||
'backup_prefix' => 'bak_',
|
||||
];
|
||||
|
||||
$this->connection = DriverManager::getConnection($this->dbParams);
|
||||
|
||||
$this->indexTableName = 'table_with_index';
|
||||
|
||||
$t = new Table($this->indexTableName);
|
||||
$t->addColumn('a_column', 'text');
|
||||
|
||||
// Create an index that has options, e.g. length of the index
|
||||
$indexOptions = [
|
||||
'lengths' => [
|
||||
0 => 128,
|
||||
],
|
||||
];
|
||||
$t->addIndex(['a_column'], 'index_with_options', [], $indexOptions);
|
||||
$this->schemaManager = $this->connection->createSchemaManager();
|
||||
$this->schemaManager->createTable($t);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
if ($this->schemaManager->tablesExist([$this->indexTableName])) {
|
||||
$this->schemaManager->dropTable($this->indexTableName);
|
||||
}
|
||||
if ($this->schemaManager->tablesExist([$this->dbParams['backup_prefix'].$this->indexTableName])) {
|
||||
$this->schemaManager->dropTable($this->dbParams['backup_prefix'].$this->indexTableName);
|
||||
}
|
||||
}
|
||||
|
||||
public function testBackupIndexesWithConfigOptions(): void
|
||||
{
|
||||
$schemaHelper = new SchemaHelper($this->dbParams);
|
||||
|
||||
// Make the backupExistingSchema method public so we can test that functionality without mocking all the SchemaHelper's functionality.
|
||||
$controllerReflection = new \ReflectionClass(SchemaHelper::class);
|
||||
$method = $controllerReflection->getMethod('backupExistingSchema');
|
||||
$method->setAccessible(true);
|
||||
|
||||
// Set the platform property, as that one is only set in the installSchema method, which we want to avoid.
|
||||
$property = $controllerReflection->getProperty('platform');
|
||||
$property->setAccessible(true);
|
||||
$connection = DriverManager::getConnection($this->dbParams);
|
||||
$property->setValue($schemaHelper, $connection->getDatabasePlatform());
|
||||
|
||||
$tables = [$this->indexTableName];
|
||||
$mauticTables = [$this->indexTableName => $this->dbParams['backup_prefix'].$this->indexTableName];
|
||||
|
||||
$sql = $method->invokeArgs($schemaHelper, [$tables, $mauticTables, $this->dbParams['backup_prefix']]);
|
||||
|
||||
$exceptions = [];
|
||||
if (!empty($sql)) {
|
||||
foreach ($sql as $q) {
|
||||
try {
|
||||
$this->connection->executeStatement($q);
|
||||
} catch (\Exception $exception) {
|
||||
$exceptions[] = $exception->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->connection->close();
|
||||
|
||||
Assert::assertSame([], $exceptions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,379 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\InstallBundle\Tests\Install;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Mautic\CoreBundle\Configurator\Configurator;
|
||||
use Mautic\CoreBundle\Configurator\Step\StepInterface;
|
||||
use Mautic\CoreBundle\Doctrine\Loader\FixturesLoaderInterface;
|
||||
use Mautic\CoreBundle\Helper\CacheHelper;
|
||||
use Mautic\CoreBundle\Helper\PathsHelper;
|
||||
use Mautic\InstallBundle\Install\InstallService;
|
||||
use Mautic\UserBundle\Entity\User;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Symfony\Component\HttpKernel\KernelInterface;
|
||||
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasher;
|
||||
use Symfony\Component\Validator\ConstraintViolationInterface;
|
||||
use Symfony\Component\Validator\ConstraintViolationList;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class InstallServiceTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private MockObject $configurator;
|
||||
|
||||
private MockObject $cacheHelper;
|
||||
|
||||
private MockObject $pathsHelper;
|
||||
|
||||
/**
|
||||
* @var EntityManager&MockObject
|
||||
*/
|
||||
private MockObject $entityManager;
|
||||
|
||||
private MockObject $translator;
|
||||
|
||||
private MockObject $kernel;
|
||||
|
||||
private MockObject $validator;
|
||||
|
||||
private UserPasswordHasher $hasher;
|
||||
|
||||
/**
|
||||
* @var MockObject&FixturesLoaderInterface
|
||||
*/
|
||||
private MockObject $fixtureLoader;
|
||||
|
||||
private InstallService $installer;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->configurator = $this->createMock(Configurator::class);
|
||||
$this->cacheHelper = $this->createMock(CacheHelper::class);
|
||||
$this->pathsHelper = $this->createMock(PathsHelper::class);
|
||||
$this->entityManager = $this->createMock(EntityManager::class);
|
||||
$this->translator = $this->createMock(TranslatorInterface::class);
|
||||
$this->kernel = $this->createMock(KernelInterface::class);
|
||||
$this->validator = $this->createMock(ValidatorInterface::class);
|
||||
$this->hasher = $this->createMock(UserPasswordHasher::class);
|
||||
$this->fixtureLoader = $this->createMock(FixturesLoaderInterface::class);
|
||||
|
||||
$this->installer = new InstallService(
|
||||
$this->configurator,
|
||||
$this->cacheHelper,
|
||||
$this->pathsHelper,
|
||||
$this->entityManager,
|
||||
$this->translator,
|
||||
$this->kernel,
|
||||
$this->validator,
|
||||
$this->hasher,
|
||||
$this->fixtureLoader
|
||||
);
|
||||
}
|
||||
|
||||
public function testCheckIfInstalledWhenNoLocalConfig(): void
|
||||
{
|
||||
$this->pathsHelper->expects($this->once())
|
||||
->method('getSystemPath')
|
||||
->with('root', false)
|
||||
->willReturn(
|
||||
__DIR__.'/../../../../../',
|
||||
);
|
||||
|
||||
$this->assertFalse($this->installer->checkIfInstalled());
|
||||
}
|
||||
|
||||
public function testGetStepWhenNoLocalConfig(): void
|
||||
{
|
||||
$this->pathsHelper->expects($this->once())
|
||||
->method('getSystemPath')
|
||||
->with('root', false)
|
||||
->willReturn(
|
||||
__DIR__.'/../../../../../',
|
||||
);
|
||||
|
||||
$this->configurator->expects($this->exactly(2))
|
||||
->method('getParameters')
|
||||
->willReturn(
|
||||
[]
|
||||
);
|
||||
|
||||
$index = 0;
|
||||
$step = $this->createMock(StepInterface::class);
|
||||
|
||||
$this->configurator->expects($this->once())
|
||||
->method('getStep')
|
||||
->with($index)
|
||||
->willReturn([$step]);
|
||||
|
||||
$this->assertEquals($step, $this->installer->getStep($index));
|
||||
}
|
||||
|
||||
public function testGetStepWhenDbDriverSet(): void
|
||||
{
|
||||
$this->pathsHelper->expects($this->once())
|
||||
->method('getSystemPath')
|
||||
->with('root', false)
|
||||
->willReturn(
|
||||
__DIR__.'/../../../../../',
|
||||
);
|
||||
|
||||
$this->configurator->expects($this->exactly(2))
|
||||
->method('getParameters')
|
||||
->willReturn(
|
||||
['db_driver' => 'test']
|
||||
);
|
||||
|
||||
$index = 0;
|
||||
$step = $this->createMock(StepInterface::class);
|
||||
|
||||
$this->configurator->expects($this->once())
|
||||
->method('getStep')
|
||||
->with($index)
|
||||
->willReturn([$step]);
|
||||
|
||||
$this->assertEquals($step, $this->installer->getStep($index));
|
||||
}
|
||||
|
||||
public function testCheckRequirements(): void
|
||||
{
|
||||
$step = $this->createMock(StepInterface::class);
|
||||
$messages = ['dummy' => 'test'];
|
||||
|
||||
$step->expects($this->once())
|
||||
->method('checkRequirements')
|
||||
->willReturn($messages);
|
||||
|
||||
$this->translator->expects($this->once())
|
||||
->method('trans')
|
||||
->with('test', [], null, null)
|
||||
->willReturn('test');
|
||||
|
||||
$this->assertEquals($messages, $this->installer->checkRequirements($step));
|
||||
}
|
||||
|
||||
public function testCheckOptionalSettings(): void
|
||||
{
|
||||
$step = $this->createMock(StepInterface::class);
|
||||
$messages = ['dummy' => 'test'];
|
||||
|
||||
$step->expects($this->once())
|
||||
->method('checkOptionalSettings')
|
||||
->willReturn($messages);
|
||||
|
||||
$this->translator->expects($this->once())
|
||||
->method('trans')
|
||||
->with('test', [], null, null)
|
||||
->willReturn('test');
|
||||
|
||||
$this->assertEquals($messages, $this->installer->checkOptionalSettings($step));
|
||||
}
|
||||
|
||||
public function testSaveConfigurationWhenNoCacheClear(): void
|
||||
{
|
||||
$params = [];
|
||||
$step = $this->createMock(StepInterface::class);
|
||||
$clearCache = false;
|
||||
|
||||
$messages = [];
|
||||
|
||||
$step->expects($this->once())
|
||||
->method('update')
|
||||
->with($step)
|
||||
->willReturn($params);
|
||||
|
||||
$this->configurator->expects($this->once())
|
||||
->method('write');
|
||||
|
||||
$this->configurator->expects($this->once())
|
||||
->method('mergeParameters');
|
||||
|
||||
$this->assertEquals($messages, $this->installer->saveConfiguration($params, $step, $clearCache));
|
||||
}
|
||||
|
||||
public function testSaveConfigurationWhenCacheClear(): void
|
||||
{
|
||||
$params = [];
|
||||
$step = $this->createMock(StepInterface::class);
|
||||
$clearCache = true;
|
||||
|
||||
$messages = [];
|
||||
|
||||
$step->expects($this->once())
|
||||
->method('update')
|
||||
->with($step)
|
||||
->willReturn($params);
|
||||
|
||||
$this->configurator->expects($this->once())
|
||||
->method('mergeParameters');
|
||||
|
||||
$this->configurator->expects($this->once())
|
||||
->method('write');
|
||||
|
||||
$this->cacheHelper->expects($this->once())
|
||||
->method('refreshConfig');
|
||||
|
||||
$this->assertEquals($messages, $this->installer->saveConfiguration($params, $step, $clearCache));
|
||||
}
|
||||
|
||||
public function testValidateDatabaseParamsWhenNoRequired(): void
|
||||
{
|
||||
$dbParams = [];
|
||||
$messages = [
|
||||
'driver' => null,
|
||||
'host' => null,
|
||||
'port' => null,
|
||||
'name' => null,
|
||||
'user' => null,
|
||||
];
|
||||
|
||||
$this->assertEquals($messages, $this->installer->validateDatabaseParams($dbParams));
|
||||
}
|
||||
|
||||
public function testValidateDatabaseParamsWhenPortNotValid(): void
|
||||
{
|
||||
$dbParams = [
|
||||
'driver' => 'pdo_mysql',
|
||||
'host' => 'localhost',
|
||||
'port' => '-1',
|
||||
'name' => 'mautic',
|
||||
'user' => 'mautic',
|
||||
];
|
||||
$messages = [
|
||||
'port' => null,
|
||||
];
|
||||
|
||||
$this->assertEquals($messages, $this->installer->validateDatabaseParams($dbParams));
|
||||
}
|
||||
|
||||
public function testValidateDatabaseParamsWhenAllValid(): void
|
||||
{
|
||||
$dbParams = [
|
||||
'driver' => 'pdo_mysql',
|
||||
'host' => 'localhost',
|
||||
'port' => '3306',
|
||||
'name' => 'mautic',
|
||||
'user' => 'mautic',
|
||||
];
|
||||
|
||||
$this->assertEquals([], $this->installer->validateDatabaseParams($dbParams));
|
||||
}
|
||||
|
||||
public function testValidateDatabaseParamsWhenDriverNotValid(): void
|
||||
{
|
||||
$dbParams = [
|
||||
'driver' => 'pdo_sqlite',
|
||||
'host' => 'localhost',
|
||||
'port' => '3306',
|
||||
'name' => 'mautic',
|
||||
'user' => 'mautic',
|
||||
];
|
||||
$messages = [
|
||||
'driver' => null,
|
||||
];
|
||||
|
||||
$this->assertEquals($messages, $this->installer->validateDatabaseParams($dbParams));
|
||||
}
|
||||
|
||||
/**
|
||||
* When an exception is raised while creating a database, there must be an array returned.
|
||||
*/
|
||||
public function testCreateDatabaseStepWithErrors(): void
|
||||
{
|
||||
$dbParams = [
|
||||
'driver' => 'pdo_mysql',
|
||||
'host' => 'localhost',
|
||||
'port' => '3306',
|
||||
'name' => 'mautic',
|
||||
'user' => 'mautic',
|
||||
'table_prefix' => 'mautic_',
|
||||
];
|
||||
|
||||
$step = $this->createMock(StepInterface::class);
|
||||
$this->assertEquals(['error' => null], $this->installer->createDatabaseStep($step, $dbParams));
|
||||
}
|
||||
|
||||
/**
|
||||
* When an exception is raised while creating the schema, there must be an array returned.
|
||||
*/
|
||||
public function testCreateSchemaStepWithErrors(): void
|
||||
{
|
||||
$dbParams = [
|
||||
'driver' => 'pdo_mysql',
|
||||
'host' => 'localhost',
|
||||
'port' => '3306',
|
||||
'name' => 'mautic',
|
||||
'user' => 'mautic',
|
||||
'table_prefix' => 'mautic_',
|
||||
];
|
||||
|
||||
$this->assertEquals(['error' => null], $this->installer->createSchemaStep($dbParams));
|
||||
}
|
||||
|
||||
public function testCreateAdminUserStepWhenPasswordIsMissing(): void
|
||||
{
|
||||
$mockRepo = $this->createMock(EntityRepository::class);
|
||||
$mockRepo->expects($this->once())
|
||||
->method('find')
|
||||
->willReturn(0);
|
||||
|
||||
$this->entityManager->expects($this->once())
|
||||
->method('getRepository')
|
||||
->willReturn($mockRepo);
|
||||
|
||||
$data = [
|
||||
'firstname' => 'Demo',
|
||||
'lastname' => 'User',
|
||||
'username' => 'admin',
|
||||
'email' => 'demo@demo.com',
|
||||
];
|
||||
|
||||
$this->assertEquals(['password' => null], $this->installer->createAdminUserStep($data));
|
||||
}
|
||||
|
||||
public function testCreateAdminUserStepWhenPasswordIsNotLongEnough(): void
|
||||
{
|
||||
$mockRepo = $this->createMock(EntityRepository::class);
|
||||
$mockRepo->expects($this->once())
|
||||
->method('find')
|
||||
->willReturn(new User());
|
||||
|
||||
$this->entityManager->expects($this->once())
|
||||
->method('getRepository')
|
||||
->willReturn($mockRepo);
|
||||
|
||||
$data = [
|
||||
'firstname' => 'Demo',
|
||||
'lastname' => 'User',
|
||||
'username' => 'admin',
|
||||
'password' => '1',
|
||||
'email' => 'demo@demo.com',
|
||||
];
|
||||
|
||||
$mockValidation = $this->createMock(ConstraintViolationInterface::class);
|
||||
$mockValidation->expects($this->once())
|
||||
->method('getMessage')
|
||||
->willReturn('password');
|
||||
$matcher = $this->exactly(2);
|
||||
|
||||
$this->validator->expects($matcher)->method('validate')->willReturnCallback(function (...$parameters) use ($matcher, $data, $mockValidation) {
|
||||
if (1 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame($data['email'], $parameters[0]);
|
||||
|
||||
return new ConstraintViolationList([]);
|
||||
}
|
||||
if (2 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame($data['password'], $parameters[0]);
|
||||
|
||||
return new ConstraintViolationList([$mockValidation]);
|
||||
}
|
||||
});
|
||||
|
||||
$this->assertEquals([0 => 'password'], $this->installer->createAdminUserStep($data));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user