Initial commit: CloudOps infrastructure platform

This commit is contained in:
root
2026-04-09 19:58:57 +02:00
commit 1166a52f26
7762 changed files with 839452 additions and 0 deletions

View File

@@ -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);
}
}

View File

@@ -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));
}
}