Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,314 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\ConfigBundle\Tests\Controller;
|
||||
|
||||
use Mautic\CoreBundle\Test\MauticMysqlTestCase;
|
||||
use PHPUnit\Framework\Assert;
|
||||
use Symfony\Component\DomCrawler\Field\ChoiceFormField;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class ConfigControllerFunctionalTest extends MauticMysqlTestCase
|
||||
{
|
||||
private const SUBDOMAIN_URL = 'subdomain_url.com';
|
||||
|
||||
private string $prefix;
|
||||
|
||||
protected $useCleanupRollback = false;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->configParams['config_allowed_parameters'] = [
|
||||
'kernel.project_dir',
|
||||
];
|
||||
|
||||
$this->configParams['locale'] = 'en_US';
|
||||
$this->configParams['subdomain_url'] = self::SUBDOMAIN_URL;
|
||||
|
||||
parent::setUp();
|
||||
|
||||
$this->prefix = MAUTIC_TABLE_PREFIX;
|
||||
}
|
||||
|
||||
public function testValuesAreEscapedProperly(): void
|
||||
{
|
||||
$trackIps = "%ip1%\n%ip2%\n%kernel.project_dir%";
|
||||
$googleAnalytics = 'reveal pass: %mautic.db_password%';
|
||||
|
||||
// request config edit page
|
||||
$crawler = $this->client->request(Request::METHOD_GET, '/s/config/edit');
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
// Find save & close button
|
||||
$buttonCrawler = $crawler->selectButton('config[buttons][save]');
|
||||
$form = $buttonCrawler->form();
|
||||
$form->setValues(
|
||||
[
|
||||
'config[coreconfig][site_url]' => 'https://mautic-community.local', // required
|
||||
'config[coreconfig][do_not_track_ips]' => $trackIps,
|
||||
'config[pageconfig][google_analytics]' => $googleAnalytics,
|
||||
'config[leadconfig][contact_columns]' => ['name', 'email', 'id'],
|
||||
]
|
||||
);
|
||||
|
||||
$crawler = $this->client->submit($form);
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
// Check for a flash error
|
||||
$response = $this->client->getResponse()->getContent();
|
||||
$message = $crawler->filterXPath("//div[@id='flashes']//span")->count()
|
||||
?
|
||||
$crawler->filterXPath("//div[@id='flashes']//span")->first()->text()
|
||||
:
|
||||
'';
|
||||
Assert::assertStringNotContainsString('Could not save updated configuration:', $response, $message);
|
||||
|
||||
// Check values are escaped properly in the config file
|
||||
$configParameters = $this->getConfigParameters();
|
||||
Assert::assertArrayHasKey('do_not_track_ips', $configParameters);
|
||||
Assert::assertSame(
|
||||
[
|
||||
$this->escape('%ip1%'),
|
||||
$this->escape('%ip2%'),
|
||||
'%kernel.project_dir%',
|
||||
],
|
||||
$configParameters['do_not_track_ips']
|
||||
);
|
||||
Assert::assertArrayHasKey('google_analytics', $configParameters);
|
||||
Assert::assertSame($this->escape($googleAnalytics), $configParameters['google_analytics']);
|
||||
// Check values are unescaped properly in the edit form
|
||||
$crawler = $this->client->request(Request::METHOD_GET, '/s/config/edit');
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
$buttonCrawler = $crawler->selectButton('config[buttons][save]');
|
||||
$form = $buttonCrawler->form();
|
||||
Assert::assertEquals($trackIps, $form['config[coreconfig][do_not_track_ips]']->getValue());
|
||||
Assert::assertEquals($googleAnalytics, $form['config[pageconfig][google_analytics]']->getValue());
|
||||
}
|
||||
|
||||
private function getConfigPath(): string
|
||||
{
|
||||
return static::getContainer()->get('kernel')->getLocalConfigFile();
|
||||
}
|
||||
|
||||
private function getConfigParameters(): array
|
||||
{
|
||||
$parameters = [];
|
||||
include $this->getConfigPath();
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
private function escape(string $value): string
|
||||
{
|
||||
return str_replace('%', '%%', $value);
|
||||
}
|
||||
|
||||
public function testConfigNotFoundPageConfiguration(): void
|
||||
{
|
||||
// insert published record
|
||||
$this->connection->insert($this->prefix.'pages', [
|
||||
'is_published' => 1,
|
||||
'date_added' => (new \DateTime())->format('Y-m-d H:i:s'),
|
||||
'title' => 'page1',
|
||||
'alias' => 'page1',
|
||||
'template' => 'blank',
|
||||
'custom_html' => 'Page1 Test Html',
|
||||
'hits' => 0,
|
||||
'unique_hits' => 0,
|
||||
'variant_hits' => 0,
|
||||
'revision' => 0,
|
||||
'lang' => 'en',
|
||||
]);
|
||||
$page1 = $this->connection->lastInsertId();
|
||||
|
||||
// insert unpublished record
|
||||
$this->connection->insert($this->prefix.'pages', [
|
||||
'is_published' => 0,
|
||||
'date_added' => (new \DateTime())->format('Y-m-d H:i:s'),
|
||||
'title' => 'page2',
|
||||
'alias' => 'page2',
|
||||
'template' => 'blank',
|
||||
'custom_html' => 'Page2 Test Html',
|
||||
'hits' => 0,
|
||||
'unique_hits' => 0,
|
||||
'variant_hits' => 0,
|
||||
'revision' => 0,
|
||||
'lang' => 'en',
|
||||
]);
|
||||
$this->connection->lastInsertId();
|
||||
|
||||
// insert published record
|
||||
$this->connection->insert($this->prefix.'pages', [
|
||||
'is_published' => 1,
|
||||
'date_added' => (new \DateTime())->format('Y-m-d H:i:s'),
|
||||
'title' => 'page3',
|
||||
'alias' => 'page3',
|
||||
'template' => 'blank',
|
||||
'custom_html' => 'Page3 Test Html',
|
||||
'hits' => 0,
|
||||
'unique_hits' => 0,
|
||||
'variant_hits' => 0,
|
||||
'revision' => 0,
|
||||
'lang' => 'en',
|
||||
]);
|
||||
$page3 = $this->connection->lastInsertId();
|
||||
|
||||
// request config edit page
|
||||
$crawler = $this->client->request(Request::METHOD_GET, '/s/config/edit');
|
||||
|
||||
// Find save & close button
|
||||
$buttonCrawler = $crawler->selectButton('config[buttons][save]');
|
||||
$form = $buttonCrawler->form();
|
||||
|
||||
// Fetch available option for 404_page field
|
||||
$availableOptions = $form['config[coreconfig][404_page]']->availableOptionValues();
|
||||
|
||||
// page 2 should not be available in option list because it is unpublished
|
||||
$this->assertEquals(['', $page1, $page3], $availableOptions);
|
||||
|
||||
// page 3 for 404_page
|
||||
$form->setValues(
|
||||
[
|
||||
'config[coreconfig][site_url]' => 'https://mautic-community.local', // required
|
||||
'config[leadconfig][contact_columns]' => ['name', 'email', 'id'],
|
||||
'config[coreconfig][404_page]' => $page3,
|
||||
]
|
||||
);
|
||||
|
||||
$crawler = $this->client->submit($form);
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
$crawler = $this->client->request(Request::METHOD_GET, '/s/config/edit');
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
$buttonCrawler = $crawler->selectButton('config[buttons][save]');
|
||||
$form = $buttonCrawler->form();
|
||||
Assert::assertEquals($page3, $form['config[coreconfig][404_page]']->getValue());
|
||||
// re-create the Symfony client to make config changes applied
|
||||
$this->setUpSymfony($this->configParams);
|
||||
|
||||
// Request not found url page3 page content should be rendered
|
||||
$crawler = $this->client->request(Request::METHOD_GET, '/notfoundurlblablabla');
|
||||
$this->assertResponseStatusCodeSame(Response::HTTP_NOT_FOUND);
|
||||
$this->assertStringContainsString('Page3 Test Html', $crawler->text());
|
||||
}
|
||||
|
||||
public function testConfigNotificationConfiguration(): void
|
||||
{
|
||||
$crawler = $this->client->request(Request::METHOD_GET, '/s/config/edit');
|
||||
|
||||
$buttonCrawler = $crawler->selectButton('config[buttons][save]');
|
||||
$form = $buttonCrawler->form();
|
||||
|
||||
$send_notification_to_author = '0';
|
||||
$campaign_notification_email_addresses = 'a@test.com, b@test.com';
|
||||
$webhook_notification_email_addresses = 'a@webhook.com, b@webhook.com';
|
||||
|
||||
$form->setValues(
|
||||
[
|
||||
'config[coreconfig][site_url]' => 'https://mautic-community.local', // required
|
||||
'config[leadconfig][contact_columns]' => ['name', 'email', 'id'],
|
||||
'config[notification_config][campaign_send_notification_to_author]' => $send_notification_to_author,
|
||||
'config[notification_config][campaign_notification_email_addresses]' => $campaign_notification_email_addresses,
|
||||
'config[notification_config][webhook_send_notification_to_author]' => $send_notification_to_author,
|
||||
'config[notification_config][webhook_notification_email_addresses]' => $webhook_notification_email_addresses,
|
||||
]
|
||||
);
|
||||
|
||||
$this->client->submit($form);
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
$crawler = $this->client->request(Request::METHOD_GET, '/s/config/edit');
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
$buttonCrawler = $crawler->selectButton('config[buttons][save]');
|
||||
$form = $buttonCrawler->form();
|
||||
|
||||
Assert::assertEquals($send_notification_to_author, $form['config[notification_config][campaign_send_notification_to_author]']->getValue());
|
||||
Assert::assertEquals($campaign_notification_email_addresses, $form['config[notification_config][campaign_notification_email_addresses]']->getValue());
|
||||
Assert::assertEquals($send_notification_to_author, $form['config[notification_config][webhook_send_notification_to_author]']->getValue());
|
||||
Assert::assertEquals($webhook_notification_email_addresses, $form['config[notification_config][webhook_notification_email_addresses]']->getValue());
|
||||
}
|
||||
|
||||
public function testUserAndSystemLocale(): void
|
||||
{
|
||||
// 1. Change user locale in account - should change _locale session
|
||||
$accountCrawler = $this->client->request(Request::METHOD_GET, '/s/account');
|
||||
$this->assertResponseIsSuccessful();
|
||||
$accountSaveButton = $accountCrawler->selectButton('user[buttons][save]');
|
||||
$accountForm = $accountSaveButton->form();
|
||||
$accountForm->setValues(
|
||||
[
|
||||
'user[locale]' => 'en_US',
|
||||
]
|
||||
);
|
||||
$this->client->submit($accountForm);
|
||||
$this->assertResponseIsSuccessful();
|
||||
Assert::assertSame('en_US', $this->client->getRequest()->getSession()->get('_locale'));
|
||||
|
||||
// 2. Change system locale in configuration - should not change _locale session
|
||||
$configCrawler = $this->client->request(Request::METHOD_GET, '/s/config/edit');
|
||||
$configSaveButton = $configCrawler->selectButton('config[buttons][save]');
|
||||
$configForm = $configSaveButton->form();
|
||||
$configForm->setValues(
|
||||
[
|
||||
'config[coreconfig][locale]' => 'en_US',
|
||||
'config[coreconfig][site_url]' => 'https://mautic-cloud.local', // required
|
||||
]
|
||||
);
|
||||
$this->client->submit($configForm);
|
||||
$this->assertResponseIsSuccessful();
|
||||
Assert::assertSame('en_US', $this->client->getRequest()->getSession()->get('_locale'));
|
||||
|
||||
// 3. Change user locale to system default in account - should change _locale session to system default
|
||||
$accountCrawler = $this->client->request(Request::METHOD_GET, '/s/account');
|
||||
$accountSaveButton = $accountCrawler->selectButton('user[buttons][save]');
|
||||
$accountForm = $accountSaveButton->form();
|
||||
$accountForm->setValues(
|
||||
[
|
||||
'user[locale]' => '',
|
||||
]
|
||||
);
|
||||
$this->client->submit($accountForm);
|
||||
$this->assertResponseIsSuccessful();
|
||||
Assert::assertSame('en_US', $this->client->getRequest()->getSession()->get('_locale'));
|
||||
|
||||
// 2. Change system locale in configuration to en_US - should change _locale session
|
||||
$configCrawler = $this->client->request(Request::METHOD_GET, '/s/config/edit');
|
||||
$configSaveButton = $configCrawler->selectButton('config[buttons][save]');
|
||||
$configForm = $configSaveButton->form();
|
||||
$configForm->setValues(
|
||||
[
|
||||
'config[coreconfig][locale]' => 'en_US',
|
||||
'config[coreconfig][site_url]' => 'https://mautic-cloud.local', // required
|
||||
]
|
||||
);
|
||||
$this->client->submit($configForm);
|
||||
$this->assertResponseIsSuccessful();
|
||||
Assert::assertSame('en_US', $this->client->getRequest()->getSession()->get('_locale'));
|
||||
}
|
||||
|
||||
public function testSSOSettingEntityId(): void
|
||||
{
|
||||
$configCrawler = $this->client->request(Request::METHOD_GET, '/s/config/edit');
|
||||
$configSaveButton = $configCrawler->selectButton('config[buttons][apply]');
|
||||
$configForm = $configSaveButton->form();
|
||||
|
||||
/** @var ChoiceFormField $entityIdField */
|
||||
$entityIdField = $configForm['config[userconfig][saml_idp_entity_id]'];
|
||||
$availableOptions = $entityIdField->availableOptionValues();
|
||||
Assert::assertCount(3, $availableOptions);
|
||||
$configForm->setValues(
|
||||
[
|
||||
'config[userconfig][saml_idp_entity_id]' => $availableOptions[1],
|
||||
'config[coreconfig][site_url]' => 'https://mautic-cloud.local', // required
|
||||
]
|
||||
);
|
||||
$this->client->submit($configForm);
|
||||
$this->assertResponseIsSuccessful();
|
||||
Assert::assertEquals($availableOptions[1], $configForm['config[userconfig][saml_idp_entity_id]']->getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\ConfigBundle\Tests\Controller;
|
||||
|
||||
use Mautic\ConfigBundle\Model\SysinfoModel;
|
||||
use Mautic\CoreBundle\Test\MauticMysqlTestCase;
|
||||
use PHPUnit\Framework\Assert;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class SysinfoControllerTest extends MauticMysqlTestCase
|
||||
{
|
||||
public function testDbInfoIsShown(): void
|
||||
{
|
||||
$sysinfoModel = static::getContainer()->get(SysinfoModel::class);
|
||||
\assert($sysinfoModel instanceof SysinfoModel);
|
||||
$dbInfo = $sysinfoModel->getDbInfo();
|
||||
|
||||
// Request sysinfo page
|
||||
$crawler = $this->client->request(Request::METHOD_GET, '/s/sysinfo');
|
||||
Assert::assertTrue($this->client->getResponse()->isOk());
|
||||
|
||||
$dbVersion = $crawler->filterXPath("//td[@id='dbinfo-version']")->text();
|
||||
$dbDriver = $crawler->filterXPath("//td[@id='dbinfo-driver']")->text();
|
||||
$dbPlatform = $crawler->filterXPath("//td[@id='dbinfo-platform']")->text();
|
||||
$recommendations = $crawler->filter('#recommendations');
|
||||
|
||||
Assert::assertSame($dbInfo['version'], $dbVersion);
|
||||
Assert::assertSame($dbInfo['driver'], $dbDriver);
|
||||
Assert::assertSame($dbInfo['platform'], $dbPlatform);
|
||||
Assert::assertGreaterThan(0, $recommendations->count());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\ConfigBundle\Tests\Event;
|
||||
|
||||
use Mautic\ConfigBundle\Event\ConfigBuilderEvent;
|
||||
use Mautic\CoreBundle\Tests\CommonMocks;
|
||||
|
||||
class ConfigBuilderEventTest extends CommonMocks
|
||||
{
|
||||
public function testAddForm(): void
|
||||
{
|
||||
$event = $this->initEvent();
|
||||
$form = ['formAlias' => 'testform'];
|
||||
$result = $event->addForm($form);
|
||||
|
||||
$this->assertTrue($result instanceof ConfigBuilderEvent);
|
||||
|
||||
$forms = $event->getForms();
|
||||
|
||||
$this->assertEquals($form, $forms[$form['formAlias']]);
|
||||
}
|
||||
|
||||
public function testRemoveForm(): void
|
||||
{
|
||||
$event = $this->initEvent();
|
||||
$form = ['formAlias' => 'testform'];
|
||||
|
||||
$event->addForm($form);
|
||||
|
||||
$result = $event->removeForm($form['formAlias']);
|
||||
$forms = $event->getForms();
|
||||
|
||||
$this->assertEquals([], $forms);
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
protected function initEvent()
|
||||
{
|
||||
return new ConfigBuilderEvent($this->getBundleHelperMock());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\ConfigBundle\Tests\Event;
|
||||
|
||||
use Mautic\ConfigBundle\Event\ConfigEvent;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
|
||||
class ConfigEventTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testGetSetConfig(): void
|
||||
{
|
||||
// Config not defined
|
||||
$config = [];
|
||||
$paramBag = $this->createMock(ParameterBag::class);
|
||||
$event = new ConfigEvent($config, $paramBag);
|
||||
$key = 'undefined';
|
||||
$this->assertEquals([], $event->getConfig($key));
|
||||
|
||||
// Config defined with setter
|
||||
$key = 'defined';
|
||||
$config = ['config' => []];
|
||||
$event->setConfig($config, $key);
|
||||
$this->assertEquals($config, $event->getConfig($key));
|
||||
|
||||
// Config not found by key so complete config returned;
|
||||
$undefinedKey = 'undefined';
|
||||
$this->assertEquals([], $event->getConfig($undefinedKey));
|
||||
|
||||
// Get complete config
|
||||
$config = [$key => $config];
|
||||
$this->assertEquals($config, $event->getConfig());
|
||||
}
|
||||
|
||||
public function testGetSetPreserved(): void
|
||||
{
|
||||
$config = [];
|
||||
$paramBag = $this->createMock(ParameterBag::class);
|
||||
$event = new ConfigEvent($config, $paramBag);
|
||||
|
||||
$this->assertEquals([], $event->getPreservedFields());
|
||||
|
||||
$preserved = 'preserved';
|
||||
$result = [$preserved];
|
||||
$event->unsetIfEmpty($preserved);
|
||||
$this->assertEquals($result, $event->getPreservedFields());
|
||||
|
||||
$preserved = ['preserved' => 'value'];
|
||||
$result = array_merge($result, $preserved);
|
||||
$event->unsetIfEmpty($preserved);
|
||||
$this->assertEquals($result, $event->getPreservedFields());
|
||||
}
|
||||
|
||||
public function testGetSetErrors(): void
|
||||
{
|
||||
$config = [];
|
||||
$paramBag = $this->createMock(ParameterBag::class);
|
||||
$event = new ConfigEvent($config, $paramBag);
|
||||
|
||||
$this->assertEquals([], $event->getErrors());
|
||||
|
||||
$message = 'message';
|
||||
$messages = [$message => []];
|
||||
$this->assertEquals($event, $event->setError($message));
|
||||
$this->assertEquals($messages, $event->getErrors());
|
||||
|
||||
$message = 'message';
|
||||
$messageVars = ['var' => 'value'];
|
||||
$messages = [$message => $messageVars];
|
||||
$this->assertEquals($event, $event->setError($message, $messageVars));
|
||||
$this->assertEquals($messages, $event->getErrors());
|
||||
|
||||
$message = 'message';
|
||||
$messageVars = ['var' => 'value'];
|
||||
$key = 'key';
|
||||
$field = 'field';
|
||||
$fieldErrors[$key][$field] = [
|
||||
$message,
|
||||
$messageVars,
|
||||
];
|
||||
$this->assertEquals($event, $event->setError($message, $messageVars, $key, $field));
|
||||
$this->assertEquals($fieldErrors, $event->getFieldErrors());
|
||||
}
|
||||
|
||||
public function testGetFileContent(): void
|
||||
{
|
||||
$config = [];
|
||||
$paramBag = $this->createMock(ParameterBag::class);
|
||||
$event = new ConfigEvent($config, $paramBag);
|
||||
|
||||
$fileContent = 'content';
|
||||
$fileHandler = tmpfile();
|
||||
$realPath = stream_get_meta_data($fileHandler)['uri'];
|
||||
fwrite($fileHandler, ' '.$fileContent);
|
||||
|
||||
$uploadedFile = $this->createMock(UploadedFile::class);
|
||||
$uploadedFile->expects($this->once())
|
||||
->method('getRealPath')
|
||||
->willReturn($realPath);
|
||||
|
||||
$this->assertEquals($fileContent, $event->getFileContent($uploadedFile));
|
||||
$this->assertFalse(file_exists($realPath));
|
||||
}
|
||||
|
||||
public function testEncodeFileContents(): void
|
||||
{
|
||||
$config = [];
|
||||
$paramBag = $this->createMock(ParameterBag::class);
|
||||
$event = new ConfigEvent($config, $paramBag);
|
||||
|
||||
$string = 'řčžýřžýčř';
|
||||
$result = 'xZnEjcW+w73FmcW+w73EjcWZ';
|
||||
$this->assertEquals($result, $event->encodeFileContents($string));
|
||||
}
|
||||
|
||||
public function testNormalizedDataGetSet(): void
|
||||
{
|
||||
$config = [];
|
||||
$paramBag = $this->createMock(ParameterBag::class);
|
||||
$event = new ConfigEvent($config, $paramBag);
|
||||
|
||||
$origNormData = ['orig'];
|
||||
|
||||
$this->assertInstanceOf(ConfigEvent::class, $event->setOriginalNormData($origNormData));
|
||||
$this->assertEquals($origNormData, $event->getOriginalNormData());
|
||||
|
||||
$normData = ['norm'];
|
||||
|
||||
$event->setNormData($normData);
|
||||
$this->assertEquals($normData, $event->getNormData());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\ConfigBundle\Tests\EventListener;
|
||||
|
||||
use Mautic\ConfigBundle\ConfigEvents;
|
||||
use Mautic\ConfigBundle\Event\ConfigEvent;
|
||||
use Mautic\ConfigBundle\EventListener\ConfigSubscriber;
|
||||
use Mautic\ConfigBundle\Service\ConfigChangeLogger;
|
||||
use Mautic\CoreBundle\Entity\AuditLogRepository;
|
||||
use Mautic\CoreBundle\Entity\IpAddressRepository;
|
||||
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ConfigSubscriberTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var ConfigChangeLogger|MockObject
|
||||
*/
|
||||
private MockObject $logger;
|
||||
|
||||
private ConfigSubscriber $subscriber;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->logger = $this->createMock(ConfigChangeLogger::class);
|
||||
$ipAddressRepo = $this->createMock(IpAddressRepository::class);
|
||||
$coreParamHelper = $this->createMock(CoreParametersHelper::class);
|
||||
$auditLogRepo = $this->createMock(AuditLogRepository::class);
|
||||
$this->subscriber = new ConfigSubscriber($this->logger, $ipAddressRepo, $coreParamHelper, $auditLogRepo);
|
||||
}
|
||||
|
||||
public function testGetSubscribedEvents(): void
|
||||
{
|
||||
$this->assertEquals(
|
||||
[
|
||||
ConfigEvents::CONFIG_POST_SAVE => ['onConfigPostSave', 0],
|
||||
],
|
||||
$this->subscriber->getSubscribedEvents()
|
||||
);
|
||||
}
|
||||
|
||||
public function testNothingToLogOnConfigPostSave(): void
|
||||
{
|
||||
// Test nothing to log
|
||||
$this->logger->expects($this->never())
|
||||
->method('log');
|
||||
$event = $this->createMock(ConfigEvent::class);
|
||||
$event->expects($this->once())
|
||||
->method('getOriginalNormData')
|
||||
->willReturn(null);
|
||||
|
||||
$this->subscriber->onConfigPostSave($event);
|
||||
}
|
||||
|
||||
public function testSomethingToLogOnConfigPostSave(): void
|
||||
{
|
||||
// Test something to log
|
||||
$originalNormData = ['orig'];
|
||||
$normData = ['norm'];
|
||||
|
||||
$event = $this->createMock(ConfigEvent::class);
|
||||
$event->expects($this->once())
|
||||
->method('getOriginalNormData')
|
||||
->willReturn($originalNormData);
|
||||
$event->expects($this->once())
|
||||
->method('getNormData')
|
||||
->willReturn($normData);
|
||||
$this->logger->expects($this->once())
|
||||
->method('setOriginalNormData')
|
||||
->with($originalNormData)
|
||||
->willReturn($this->logger);
|
||||
$this->logger->expects($this->once())
|
||||
->method('log')
|
||||
->with($normData);
|
||||
|
||||
$this->subscriber->onConfigPostSave($event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\ConfigBundle\Tests\Form\Helper;
|
||||
|
||||
use Mautic\ConfigBundle\Form\DataTransformer\DsnTransformerFactory;
|
||||
use Mautic\ConfigBundle\Form\Helper\RestrictionHelper;
|
||||
use Mautic\ConfigBundle\Form\Type\ConfigType;
|
||||
use Mautic\ConfigBundle\Form\Type\DsnType;
|
||||
use Mautic\ConfigBundle\Form\Type\EscapeTransformer;
|
||||
use Mautic\CoreBundle\Form\Type\ButtonGroupType;
|
||||
use Mautic\CoreBundle\Form\Type\FormButtonsType;
|
||||
use Mautic\CoreBundle\Form\Type\StandAloneButtonType;
|
||||
use Mautic\CoreBundle\Form\Type\YesNoButtonGroupType;
|
||||
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
||||
use Mautic\CoreBundle\Translation\Translator;
|
||||
use Mautic\EmailBundle\EventListener\ProcessBounceSubscriber;
|
||||
use Mautic\EmailBundle\EventListener\ProcessUnsubscribeSubscriber;
|
||||
use Mautic\EmailBundle\Form\Type\ConfigMonitoredEmailType;
|
||||
use Mautic\EmailBundle\Form\Type\ConfigMonitoredMailboxesType;
|
||||
use Mautic\EmailBundle\Form\Type\ConfigType as EmailConfigType;
|
||||
use Mautic\EmailBundle\MonitoredEmail\Mailbox;
|
||||
use Mautic\EmailBundle\MonitoredEmail\Processor\Bounce;
|
||||
use Mautic\EmailBundle\MonitoredEmail\Processor\FeedbackLoop;
|
||||
use Mautic\EmailBundle\MonitoredEmail\Processor\Unsubscribe;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\NumberType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
|
||||
use Symfony\Component\Form\Form;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\Forms;
|
||||
use Symfony\Component\Form\PreloadedExtension;
|
||||
use Symfony\Component\Form\Test\TypeTestCase;
|
||||
use Symfony\Component\Validator\ConstraintViolationList;
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
|
||||
/**
|
||||
* Mocking a representative ConfigForm by leveraging Symfony's TypeTestCase to test RestrictionHelper.
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\CoversClass(RestrictionHelper::class)]
|
||||
class RestrictionHelperTest extends TypeTestCase
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $displayMode = RestrictionHelper::MODE_REMOVE;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $restrictedFields = [
|
||||
'monitored_email' => [
|
||||
'EmailBundle_bounces',
|
||||
'EmailBundle_unsubscribes' => [
|
||||
'address',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
private $forms = [
|
||||
'emailconfig' => [
|
||||
'bundle' => 'EmailBundle',
|
||||
'formAlias' => 'emailconfig',
|
||||
'formType' => EmailConfigType::class,
|
||||
'formTheme' => 'MauticEmailBundle:FormTheme\\Config',
|
||||
'parameters' => [
|
||||
'mailer_from_name' => 'Mautic',
|
||||
'mailer_from_email' => 'email@yoursite.com',
|
||||
'mailer_return_path' => null,
|
||||
'mailer_transport' => 'mail',
|
||||
'mailer_append_tracking_pixel' => true,
|
||||
'mailer_convert_embed_images' => false,
|
||||
'mailer_dsn' => 'smtp://null:25',
|
||||
'messenger_dsn_email' => 'doctrine://default',
|
||||
'messenger_retry_strategy_max_retries' => 3,
|
||||
'messenger_retry_strategy_delay' => 1000,
|
||||
'messenger_retry_strategy_multiplier' => 2,
|
||||
'messenger_retry_strategy_max_delay' => 0,
|
||||
'unsubscribe_text' => null,
|
||||
'webview_text' => null,
|
||||
'unsubscribe_message' => null,
|
||||
'resubscribe_message' => null,
|
||||
'monitored_email' => [
|
||||
'general' => [
|
||||
'address' => null,
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
],
|
||||
'EmailBundle_bounces' => [
|
||||
'address' => null,
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => null,
|
||||
],
|
||||
'EmailBundle_unsubscribes' => [
|
||||
'address' => null,
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => null,
|
||||
],
|
||||
'EmailBundle_replies' => [
|
||||
'address' => null,
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => null,
|
||||
],
|
||||
],
|
||||
'mailer_is_owner' => false,
|
||||
'default_signature_text' => null,
|
||||
'email_frequency_number' => null,
|
||||
'email_frequency_time' => null,
|
||||
'show_contact_preferences' => false,
|
||||
'show_contact_frequency' => false,
|
||||
'show_contact_pause_dates' => false,
|
||||
'show_contact_preferred_channels' => false,
|
||||
'show_contact_categories' => false,
|
||||
'show_contact_segments' => false,
|
||||
'mailer_mailjet_sandbox' => false,
|
||||
'mailer_mailjet_sandbox_default_mail' => null,
|
||||
'disable_trackable_urls' => false,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Test that the restricted fields are removed from the config')]
|
||||
public function testRestrictedFieldsAreRemoved(): void
|
||||
{
|
||||
$form = $this->factory->create(ConfigType::class, $this->forms);
|
||||
|
||||
$this->assertTrue($form->has('emailconfig'));
|
||||
|
||||
$emailConfig = $form->get('emailconfig');
|
||||
|
||||
// monitored_email is partially restricted so should be included
|
||||
$this->assertTrue($emailConfig->has('monitored_email'));
|
||||
|
||||
$monitoredEmail = $emailConfig->get('monitored_email');
|
||||
|
||||
// EmailBundle_bounces is restricted in entirety and thus should not be included
|
||||
$this->assertFalse($monitoredEmail->has('EmailBundle_bounces'));
|
||||
|
||||
// EmailBundle_unsubscribes is partially restricted so should be included
|
||||
$this->assertTrue($monitoredEmail->has('EmailBundle_unsubscribes'));
|
||||
|
||||
$unsubscribes = $monitoredEmail->get('EmailBundle_unsubscribes');
|
||||
|
||||
// address under EmailBundle_unsubscribes is restricted so should not be included
|
||||
$this->assertFalse($unsubscribes->has('address'));
|
||||
|
||||
// host under EmailBundle_unsubscribes is not restricted so should be included
|
||||
$this->assertTrue($unsubscribes->has('host'));
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Test that the restricted fields are masked')]
|
||||
public function testRestrictedFieldsAreMasked(): void
|
||||
{
|
||||
$this->displayMode = RestrictionHelper::MODE_MASK;
|
||||
|
||||
// Rebuild factory to get updated RestrictionHelper
|
||||
$this->factory = Forms::createFormFactoryBuilder()
|
||||
->addExtensions($this->getExtensions())
|
||||
->getFormFactory();
|
||||
|
||||
$form = $this->factory->create(ConfigType::class, $this->forms);
|
||||
/** @var FormInterface<mixed> $address */
|
||||
$address = $form['emailconfig']['monitored_email']['EmailBundle_unsubscribes']['address'];
|
||||
|
||||
$this->assertTrue($address->getConfig()->getOption('attr')['readonly']);
|
||||
$this->assertTrue($address->getConfig()->getOption('disabled'));
|
||||
$this->assertEquals(
|
||||
[
|
||||
'class' => 'form-control',
|
||||
'tooltip' => 'mautic.email.config.monitored_email_address.tooltip',
|
||||
'data-show-on' => '{"config_emailconfig_monitored_email_EmailBundle_unsubscribes_override_settings_1": "checked"}',
|
||||
'placeholder' => 'mautic.config.restricted',
|
||||
'readonly' => true,
|
||||
],
|
||||
$address->getConfig()->getOption('attr')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getExtensions()
|
||||
{
|
||||
$translator = $this->createMock(Translator::class);
|
||||
$translator->method('trans')
|
||||
->willReturnCallback(
|
||||
fn ($key) => $key
|
||||
);
|
||||
|
||||
$validator = $this->createMock(ValidatorInterface::class);
|
||||
$validator
|
||||
->method('validate')
|
||||
->willReturn(new ConstraintViolationList());
|
||||
$validator
|
||||
->method('getMetadataFor')
|
||||
->willReturn(new ClassMetadata(Form::class));
|
||||
|
||||
$imapHelper = $this->createMock(Mailbox::class);
|
||||
|
||||
// Register monitored email listeners
|
||||
$dispatcher = new EventDispatcher();
|
||||
$bouncer = $this->createMock(Bounce::class);
|
||||
$dispatcher->addSubscriber(new ProcessBounceSubscriber($bouncer));
|
||||
|
||||
$unsubscriber = $this->createMock(Unsubscribe::class);
|
||||
$looper = $this->createMock(FeedbackLoop::class);
|
||||
$dispatcher->addSubscriber(new ProcessUnsubscribeSubscriber($unsubscriber, $looper));
|
||||
|
||||
// This is what we're really testing here
|
||||
$restrictionHelper = new RestrictionHelper($translator, $this->restrictedFields, $this->displayMode);
|
||||
$escapeTransformer = new EscapeTransformer([]);
|
||||
|
||||
return [
|
||||
// register the type instances with the PreloadedExtension
|
||||
new PreloadedExtension(
|
||||
[
|
||||
new TextType(),
|
||||
new ChoiceType(),
|
||||
new YesNoButtonGroupType(),
|
||||
new PasswordType(),
|
||||
new StandAloneButtonType(),
|
||||
new NumberType(),
|
||||
new FormButtonsType(),
|
||||
new ButtonGroupType(),
|
||||
new EmailConfigType($translator),
|
||||
new DsnType($this->createMock(DsnTransformerFactory::class), $this->createMock(CoreParametersHelper::class)),
|
||||
new ConfigMonitoredEmailType($dispatcher),
|
||||
new ConfigMonitoredMailboxesType($imapHelper),
|
||||
new ConfigType($restrictionHelper, $escapeTransformer),
|
||||
],
|
||||
[]
|
||||
),
|
||||
new ValidatorExtension($validator),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\ConfigBundle\Tests\Mapper;
|
||||
|
||||
use Mautic\ConfigBundle\Exception\BadFormConfigException;
|
||||
use Mautic\ConfigBundle\Mapper\ConfigMapper;
|
||||
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\CoversClass(BadFormConfigException::class)]
|
||||
#[\PHPUnit\Framework\Attributes\CoversClass(ConfigMapper::class)]
|
||||
class ConfigMapperTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private $forms = [
|
||||
'emailconfig' => [
|
||||
'bundle' => 'EmailBundle',
|
||||
'formAlias' => 'emailconfig',
|
||||
'formTheme' => 'MauticEmailBundle:FormTheme\\Config',
|
||||
'parameters' => [
|
||||
'mailer_from_name' => 'Mautic',
|
||||
'mailer_from_email' => 'email@yoursite.com',
|
||||
'mailer_return_path' => null,
|
||||
'mailer_transport' => 'mail',
|
||||
'mailer_append_tracking_pixel' => true,
|
||||
'mailer_convert_embed_images' => false,
|
||||
'mailer_dsn' => 'smtp://null:25',
|
||||
'messenger_dsn_email' => 'doctrine://default',
|
||||
'messenger_retry_strategy_max_retries' => 3,
|
||||
'messenger_retry_strategy_delay' => 1000,
|
||||
'messenger_retry_strategy_multiplier' => 2,
|
||||
'messenger_retry_strategy_max_delay' => 0,
|
||||
'unsubscribe_text' => null,
|
||||
'webview_text' => null,
|
||||
'unsubscribe_message' => null,
|
||||
'resubscribe_message' => null,
|
||||
'monitored_email' => [
|
||||
'general' => [
|
||||
'address' => null,
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
],
|
||||
'EmailBundle_bounces' => [
|
||||
'address' => null,
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => null,
|
||||
],
|
||||
'EmailBundle_unsubscribes' => [
|
||||
'address' => null,
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => null,
|
||||
],
|
||||
'EmailBundle_replies' => [
|
||||
'address' => null,
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => null,
|
||||
],
|
||||
],
|
||||
'mailer_is_owner' => false,
|
||||
'default_signature_text' => null,
|
||||
'email_frequency_number' => null,
|
||||
'email_frequency_time' => null,
|
||||
'show_contact_preferences' => false,
|
||||
'show_contact_frequency' => false,
|
||||
'show_contact_pause_dates' => false,
|
||||
'show_contact_preferred_channels' => false,
|
||||
'show_contact_categories' => false,
|
||||
'show_contact_segments' => false,
|
||||
'mailer_mailjet_sandbox' => false,
|
||||
'mailer_mailjet_sandbox_default_mail' => null,
|
||||
'disable_trackable_urls' => false,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
private $config = [
|
||||
'db_host' => 'dbhost',
|
||||
'db_user' => 'dbuser',
|
||||
'monitored_email' => [
|
||||
'general' => [
|
||||
'address' => 'test@test.com',
|
||||
'host' => 'test.com',
|
||||
'port' => '143',
|
||||
'encryption' => '/tls/novalidate-cert',
|
||||
'user' => 'test@test.com',
|
||||
'password' => 'password',
|
||||
],
|
||||
'EmailBundle_bounces' => [
|
||||
'address' => 'test2@test.com',
|
||||
'host' => 'test2.com',
|
||||
'port' => '143',
|
||||
'encryption' => '/tls/novalidate-cert',
|
||||
'user' => 'test2@test.com',
|
||||
'password' => 'password',
|
||||
'override_settings' => 1,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
'EmailBundle_unsubscribes' => [
|
||||
'address' => 'test3@test.com',
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
'EmailBundle_replies' => [
|
||||
'address' => 'test4@test.com',
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Exception should be thrown if parameters key is not found in a form config')]
|
||||
public function testExceptionIsThrownOnBadFormConfig(): void
|
||||
{
|
||||
$this->expectException(BadFormConfigException::class);
|
||||
|
||||
$forms = [
|
||||
'emailconfig' => [
|
||||
'bundle' => 'EmailBundle',
|
||||
'formAlias' => 'emailconfig',
|
||||
'formTheme' => 'MauticEmailBundle:FormTheme\Config',
|
||||
],
|
||||
];
|
||||
|
||||
$parameterHelper = $this->createMock(CoreParametersHelper::class);
|
||||
|
||||
$mapper = new ConfigMapper($parameterHelper, []);
|
||||
|
||||
$mapper->bindFormConfigsWithRealValues($forms);
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Defaults should be bound when local config has no values')]
|
||||
public function testParametersAreBoundToDefaults(): void
|
||||
{
|
||||
$parameterHelper = $this->createMock(CoreParametersHelper::class);
|
||||
|
||||
$mapper = new ConfigMapper($parameterHelper, []);
|
||||
|
||||
$processedForms = $mapper->bindFormConfigsWithRealValues($this->forms);
|
||||
|
||||
$this->assertEquals($this->forms, $processedForms);
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Defaults should be merged with local config values')]
|
||||
public function testParametersAreBoundToDefaultsWithLocalConfig(): void
|
||||
{
|
||||
$parameterHelper = $this->createMock(CoreParametersHelper::class);
|
||||
|
||||
$parameterHelper->method('get')
|
||||
->willReturnCallback(
|
||||
fn ($param, $defaultValue) => array_key_exists($param, $this->config) ? $this->config[$param] : $defaultValue
|
||||
);
|
||||
|
||||
$mapper = new ConfigMapper($parameterHelper, []);
|
||||
|
||||
$forms = $this->forms;
|
||||
$processedForms = $mapper->bindFormConfigsWithRealValues($forms);
|
||||
|
||||
// Update expected
|
||||
$forms['emailconfig']['parameters']['monitored_email'] = [
|
||||
'general' => [
|
||||
'address' => 'test@test.com',
|
||||
'host' => 'test.com',
|
||||
'port' => '143',
|
||||
'encryption' => '/tls/novalidate-cert',
|
||||
'user' => 'test@test.com',
|
||||
'password' => 'password',
|
||||
],
|
||||
'EmailBundle_bounces' => [
|
||||
'address' => 'test2@test.com',
|
||||
'host' => 'test2.com',
|
||||
'port' => '143',
|
||||
'encryption' => '/tls/novalidate-cert',
|
||||
'user' => 'test2@test.com',
|
||||
'password' => 'password',
|
||||
'override_settings' => 1,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
'EmailBundle_unsubscribes' => [
|
||||
'address' => 'test3@test.com',
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
'EmailBundle_replies' => [
|
||||
'address' => 'test4@test.com',
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($forms, $processedForms);
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Defaults should be merged with local config values but restricted fields should be removed')]
|
||||
public function testParametersAreBoundToDefaultsWithLocalConfigAndRestrictionsAppied(): void
|
||||
{
|
||||
$parameterHelper = $this->createMock(CoreParametersHelper::class);
|
||||
|
||||
$parameterHelper->method('get')
|
||||
->willReturnCallback(
|
||||
fn ($param, $defaultValue) => array_key_exists($param, $this->config) ? $this->config[$param] : $defaultValue
|
||||
);
|
||||
|
||||
$mapper = new ConfigMapper($parameterHelper, ['monitored_email']);
|
||||
|
||||
$forms = $this->forms;
|
||||
$processedForms = $mapper->bindFormConfigsWithRealValues($forms);
|
||||
|
||||
// Expected should have had monitored_email unset due to it being restricted
|
||||
unset($forms['emailconfig']['parameters']['monitored_email']);
|
||||
|
||||
$this->assertEquals($forms, $processedForms);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\ConfigBundle\Tests\Mapper\Helper;
|
||||
|
||||
use Mautic\ConfigBundle\Mapper\Helper\ConfigHelper;
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\CoversClass(ConfigHelper::class)]
|
||||
class ConfigHelperTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Ensure a mixed numeric/string keyed array is formatted to all string based keys')]
|
||||
public function testNestedLocalParametersAreBoundCorrectly(): void
|
||||
{
|
||||
$defaults = [
|
||||
'db_host' => null,
|
||||
'db_user' => null,
|
||||
'api_enabled' => 1,
|
||||
'monitored_email' => [
|
||||
'general' => [
|
||||
'address' => null,
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
],
|
||||
'EmailBundle_bounces' => [
|
||||
'address' => 'test2@test.com',
|
||||
'host' => 'test2.com',
|
||||
'port' => '143',
|
||||
'encryption' => '/tls/novalidate-cert',
|
||||
'user' => 'test2@test.com',
|
||||
'password' => 'password',
|
||||
'override_settings' => 1,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
'EmailBundle_unsubscribes' => [
|
||||
'address' => 'test3@test.com',
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$config = [
|
||||
'db_host' => 'dbhost',
|
||||
'db_user' => 'dbuser',
|
||||
'monitored_email' => [
|
||||
'general' => [
|
||||
'address' => 'test@test.com',
|
||||
'host' => 'test.com',
|
||||
'port' => '143',
|
||||
'encryption' => '/tls/novalidate-cert',
|
||||
'user' => 'test@test.com',
|
||||
'password' => 'password',
|
||||
],
|
||||
'EmailBundle_bounces' => null,
|
||||
'EmailBundle_unsubscribes' => [
|
||||
'address' => 'test3@test.com',
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
'EmailBundle_replies' => [
|
||||
'address' => 'test4@test.com',
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$expected = [
|
||||
// from config
|
||||
'db_host' => 'dbhost',
|
||||
'db_user' => 'dbuser',
|
||||
// from defaults
|
||||
'api_enabled' => 1,
|
||||
'monitored_email' => [
|
||||
// from config
|
||||
'general' => [
|
||||
'address' => 'test@test.com',
|
||||
'host' => 'test.com',
|
||||
'port' => '143',
|
||||
'encryption' => '/tls/novalidate-cert',
|
||||
'user' => 'test@test.com',
|
||||
'password' => 'password',
|
||||
],
|
||||
'EmailBundle_bounces' => [
|
||||
// from defaults
|
||||
'address' => 'test2@test.com',
|
||||
'host' => 'test2.com',
|
||||
'port' => '143',
|
||||
'encryption' => '/tls/novalidate-cert',
|
||||
'user' => 'test2@test.com',
|
||||
'password' => 'password',
|
||||
'override_settings' => 1,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
// from config
|
||||
'EmailBundle_unsubscribes' => [
|
||||
'address' => 'test3@test.com',
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
// from config
|
||||
'EmailBundle_replies' => [
|
||||
'address' => 'test4@test.com',
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, ConfigHelper::bindNestedConfigValues($config, $defaults));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\ConfigBundle\Tests\Mapper\Helper;
|
||||
|
||||
use Mautic\ConfigBundle\Mapper\Helper\RestrictionHelper;
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\CoversClass(RestrictionHelper::class)]
|
||||
class RestrictionHelperTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $restrictedFields = [
|
||||
'db_host',
|
||||
'db_user',
|
||||
'monitored_email' => [
|
||||
'EmailBundle_bounces',
|
||||
'EmailBundle_unsubscribes' => [
|
||||
'address',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Ensure a mixed numeric/string keyed array is formatted to all string based keys')]
|
||||
public function testRestrictedConfigArrayIsFormattedCorrectly(): void
|
||||
{
|
||||
$expected = [
|
||||
'db_host' => 'db_host',
|
||||
'db_user' => 'db_user',
|
||||
'monitored_email' => [
|
||||
'EmailBundle_bounces' => 'EmailBundle_bounces',
|
||||
'EmailBundle_unsubscribes' => [
|
||||
'address' => 'address',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, RestrictionHelper::prepareRestrictions($this->restrictedFields));
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Ensure a restrictions are recursively applied')]
|
||||
public function testApplyingRestrictionsToConfigArray(): void
|
||||
{
|
||||
$config = [
|
||||
'db_host' => 'dbhost',
|
||||
'db_user' => 'dbuser',
|
||||
'api_enabled' => 1,
|
||||
'monitored_email' => [
|
||||
'general' => [
|
||||
'address' => 'test@test.com',
|
||||
'host' => 'test.com',
|
||||
'port' => '143',
|
||||
'encryption' => '/tls/novalidate-cert',
|
||||
'user' => 'test@test.com',
|
||||
'password' => 'password',
|
||||
],
|
||||
'EmailBundle_bounces' => [
|
||||
'address' => '',
|
||||
'host' => '',
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => '',
|
||||
'password' => '',
|
||||
'override_settings' => 0,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
'EmailBundle_unsubscribes' => [
|
||||
'address' => null,
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$expected = [
|
||||
'api_enabled' => 1,
|
||||
'monitored_email' => [
|
||||
'general' => [
|
||||
'address' => 'test@test.com',
|
||||
'host' => 'test.com',
|
||||
'port' => '143',
|
||||
'encryption' => '/tls/novalidate-cert',
|
||||
'user' => 'test@test.com',
|
||||
'password' => 'password',
|
||||
],
|
||||
'EmailBundle_unsubscribes' => [
|
||||
'host' => null,
|
||||
'port' => '993',
|
||||
'encryption' => '/ssl',
|
||||
'user' => null,
|
||||
'password' => null,
|
||||
'override_settings' => 0,
|
||||
'folder' => 'INBOX',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$restrictedFields = RestrictionHelper::prepareRestrictions($this->restrictedFields);
|
||||
$this->assertEquals($expected, RestrictionHelper::applyRestrictions($config, $restrictedFields));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\ConfigBundle\Tests\Service;
|
||||
|
||||
use Mautic\ConfigBundle\Service\ConfigChangeLogger;
|
||||
use Mautic\CoreBundle\Helper\IpLookupHelper;
|
||||
use Mautic\CoreBundle\Model\AuditLogModel;
|
||||
|
||||
class ConfigChangeLoggerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testSetOriginalNormData(): void
|
||||
{
|
||||
$ipLookupHelper = $this->createMock(IpLookupHelper::class);
|
||||
$auditLogModel = $this->createMock(AuditLogModel::class);
|
||||
$logger = new ConfigChangeLogger($ipLookupHelper, $auditLogModel);
|
||||
|
||||
$this->assertEquals($logger, $logger->setOriginalNormData([]));
|
||||
}
|
||||
|
||||
public function testOriginalNormDataExpected(): void
|
||||
{
|
||||
$this->expectException(\RuntimeException::class);
|
||||
|
||||
$ipLookupHelper = $this->createMock(IpLookupHelper::class);
|
||||
$ipLookupHelper->expects($this->never())->method('getIpAddressFromRequest');
|
||||
$auditLogModel = $this->createMock(AuditLogModel::class);
|
||||
$auditLogModel->expects($this->never())->method('writeToLog');
|
||||
$logger = new ConfigChangeLogger($ipLookupHelper, $auditLogModel);
|
||||
$logger->log([]);
|
||||
}
|
||||
|
||||
public function testNothingToLog(): void
|
||||
{
|
||||
$ipLookupHelper = $this->createMock(IpLookupHelper::class);
|
||||
$ipLookupHelper->expects($this->never())->method('getIpAddressFromRequest');
|
||||
$auditLogModel = $this->createMock(AuditLogModel::class);
|
||||
$auditLogModel->expects($this->never())->method('writeToLog');
|
||||
$logger = new ConfigChangeLogger($ipLookupHelper, $auditLogModel);
|
||||
|
||||
$originalData = $postData = [
|
||||
'bundle' => [
|
||||
'key' => 'value',
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($logger, $logger->setOriginalNormData($originalData));
|
||||
$logger->log($postData);
|
||||
}
|
||||
|
||||
public function testLog(): void
|
||||
{
|
||||
$change = [
|
||||
'key2' => 'changedValue',
|
||||
];
|
||||
|
||||
$filterMe = [
|
||||
'transifex_password' => 'dhjsakjfda',
|
||||
'mailer_is_owner' => 'lksajhd',
|
||||
];
|
||||
|
||||
$log = [
|
||||
'bundle' => 'config',
|
||||
'object' => 'config',
|
||||
'objectId' => 0,
|
||||
'action' => 'update',
|
||||
'details' => $change,
|
||||
'ipAddress' => null,
|
||||
];
|
||||
|
||||
$ipLookupHelper = $this->createMock(IpLookupHelper::class);
|
||||
$ipLookupHelper->expects($this->once())->method('getIpAddressFromRequest');
|
||||
$auditLogModel = $this->createMock(AuditLogModel::class);
|
||||
$auditLogModel->expects($this->once())->method('writeToLog')->with($log);
|
||||
$logger = new ConfigChangeLogger($ipLookupHelper, $auditLogModel);
|
||||
|
||||
$originalData = [
|
||||
'bundle' => [
|
||||
'key' => 'value',
|
||||
],
|
||||
'bundle2' => [
|
||||
'parameters' => [
|
||||
'key2' => 'value2',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$postData = [
|
||||
'bundle' => [
|
||||
'key' => 'value',
|
||||
],
|
||||
'bundle2' => array_merge($change, $filterMe),
|
||||
];
|
||||
|
||||
$this->assertEquals($logger, $logger->setOriginalNormData($originalData));
|
||||
$logger->log($postData);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user