Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MauticPlugin\GrapesJsBuilderBundle\Tests\Functional\Controller;
|
||||
|
||||
use Mautic\CoreBundle\Test\MauticMysqlTestCase;
|
||||
use Mautic\CoreBundle\Translation\Translator;
|
||||
use Mautic\EmailBundle\Entity\Email;
|
||||
use Mautic\PluginBundle\Entity\Integration;
|
||||
use Mautic\PluginBundle\Entity\Plugin;
|
||||
use MauticPlugin\GrapesJsBuilderBundle\Entity\GrapesJsBuilder;
|
||||
use MauticPlugin\GrapesJsBuilderBundle\Entity\GrapesJsBuilderRepository;
|
||||
|
||||
class AssertCustomMjmlTest extends MauticMysqlTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->createIntegration();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Doctrine\ORM\OptimisticLockException
|
||||
* @throws \Doctrine\ORM\Exception\ORMException
|
||||
*/
|
||||
public function testAssertCustomMjml(): void
|
||||
{
|
||||
// Create email & add GrapesJs to it.
|
||||
$email = $this->createEmail();
|
||||
$this->addToGrapesJsBuilder($email);
|
||||
$emailId = $email->getId();
|
||||
|
||||
// Get the Email via API and assert customMjml.
|
||||
$this->client->request('GET', '/api/emails/'.$emailId);
|
||||
$this->assertResponseStatusCodeSame(200);
|
||||
$content = json_decode($this->client->getResponse()->getContent(), true);
|
||||
$this->assertNotEmpty($content['email']['grapesjsbuilder']['customMjml']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Doctrine\ORM\Exception\NotSupported
|
||||
*/
|
||||
public function testAssertCustomHtmlAndCustomMjml(): void
|
||||
{
|
||||
// Create email using an API call and add GrapesJS into it.
|
||||
$responseData = $this->createEmailViaApi();
|
||||
$emailId = $responseData['email']['id'];
|
||||
$email = $this->em->getRepository(Email::class)->find($emailId);
|
||||
$this->addToGrapesJsBuilder($email);
|
||||
|
||||
// Get email & check for both customHtml & customMjml in the response.
|
||||
$this->client->request('GET', '/api/emails/'.$emailId);
|
||||
$this->assertResponseStatusCodeSame(200);
|
||||
$content = json_decode($this->client->getResponse()->getContent(), true);
|
||||
$this->assertNotEmpty($content['email']['customHtml']);
|
||||
$this->assertNotEmpty($content['email']['grapesjsbuilder']['customMjml']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Doctrine\ORM\Exception\NotSupported
|
||||
*/
|
||||
private function getRepository(): GrapesJsBuilderRepository
|
||||
{
|
||||
/** @var GrapesJsBuilderRepository $repository */
|
||||
$repository = $this->em->getRepository(GrapesJsBuilder::class);
|
||||
|
||||
$repository->setTranslator($this->getTranslatorMock());
|
||||
|
||||
return $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Doctrine\ORM\Exception\ORMException
|
||||
* @throws \Doctrine\ORM\OptimisticLockException
|
||||
*/
|
||||
private function createEmail(): Email
|
||||
{
|
||||
$email = new Email();
|
||||
$email->setName('Test email');
|
||||
$email->setSubject('Test email subject');
|
||||
$email->setEmailType('template');
|
||||
$email->setCustomHtml('<html></html>');
|
||||
$email->setIsPublished(true);
|
||||
$this->em->persist($email);
|
||||
$this->em->flush();
|
||||
|
||||
return $email;
|
||||
}
|
||||
|
||||
private function getTranslatorMock(): Translator
|
||||
{
|
||||
$translator = $this->createMock(Translator::class);
|
||||
$translator->method('hasId')
|
||||
->willReturn(false);
|
||||
|
||||
return $translator;
|
||||
}
|
||||
|
||||
private function addToGrapesJsBuilder(Email $email): void
|
||||
{
|
||||
$grapesJsBuilder = new GrapesJsBuilder();
|
||||
$grapesJsBuilder->setEmail($email);
|
||||
$grapesJsBuilder->setCustomMjml('<mjml>></mjml>');
|
||||
$this->getRepository()->saveEntity($grapesJsBuilder);
|
||||
}
|
||||
|
||||
private function createEmailViaApi(): mixed
|
||||
{
|
||||
$emailData = [
|
||||
'name' => 'Test email',
|
||||
'subject' => 'Test email subject',
|
||||
'emailType' => 'template',
|
||||
'customHtml' => '<html></html>',
|
||||
'isPublished' => true,
|
||||
];
|
||||
|
||||
$this->client->request('POST', '/api/emails/new', [], [], ['CONTENT_TYPE' => 'application/json'], json_encode($emailData));
|
||||
$this->assertResponseStatusCodeSame(201);
|
||||
|
||||
return json_decode($this->client->getResponse()->getContent(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Doctrine\ORM\Exception\ORMException
|
||||
* @throws \Doctrine\ORM\OptimisticLockException
|
||||
*/
|
||||
private function createIntegration(): void
|
||||
{
|
||||
$plugin = new Plugin();
|
||||
$plugin->setName('GrapesJS Builder');
|
||||
$plugin->setBundle('GrapesJsBuilderBundle');
|
||||
$this->em->persist($plugin);
|
||||
|
||||
$integration = new Integration();
|
||||
$integration->setPlugin($plugin);
|
||||
$integration->setIsPublished(true);
|
||||
$integration->setName('grapesjsbuilder');
|
||||
$this->em->persist($integration);
|
||||
$this->em->flush();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MauticPlugin\GrapesJsBuilderBundle\Tests\Functional\Controller;
|
||||
|
||||
use Mautic\CoreBundle\Test\MauticMysqlTestCase;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
final class FileManagerControllerFunctionalTest extends MauticMysqlTestCase
|
||||
{
|
||||
private const ASSETS_ENDPOINT = '/s/grapesjsbuilder/media';
|
||||
private const UPLOAD_ENDPOINT = '/s/grapesjsbuilder/upload';
|
||||
private const DELETE_ENDPOINT = '/s/grapesjsbuilder/delete';
|
||||
private const IMAGE_COUNT = 3;
|
||||
|
||||
/** @var array<string> */
|
||||
private array $tempFilePaths = [];
|
||||
|
||||
protected function beforeTearDown(): void
|
||||
{
|
||||
$this->cleanupTempFiles();
|
||||
}
|
||||
|
||||
public function testAssetsManagerWorkflow(): void
|
||||
{
|
||||
$initialAssetCount = $this->getAssetCount();
|
||||
|
||||
$uploadedFiles = $this->uploadImages();
|
||||
$this->assertUploadSuccessful($uploadedFiles);
|
||||
|
||||
$newAssetCount = $this->getAssetCount();
|
||||
$this->assertEquals($initialAssetCount + self::IMAGE_COUNT, $newAssetCount);
|
||||
|
||||
$this->testPagination($newAssetCount);
|
||||
$this->testRecentlyAddedFilesAppearFirst($uploadedFiles);
|
||||
|
||||
$this->deleteUploadedFiles($uploadedFiles);
|
||||
|
||||
$finalAssetCount = $this->getAssetCount();
|
||||
$this->assertEquals($initialAssetCount, $finalAssetCount);
|
||||
}
|
||||
|
||||
private function getAssetCount(): int
|
||||
{
|
||||
$response = $this->makeRequest('GET', self::ASSETS_ENDPOINT);
|
||||
$content = $this->getJsonResponse($response);
|
||||
|
||||
$this->assertArrayHasKey('data', $content);
|
||||
$this->assertArrayHasKey('page', $content);
|
||||
$this->assertArrayHasKey('limit', $content);
|
||||
$this->assertArrayHasKey('totalItems', $content);
|
||||
$this->assertArrayHasKey('totalPages', $content);
|
||||
$this->assertArrayHasKey('hasNextPage', $content);
|
||||
$this->assertArrayHasKey('hasPreviousPage', $content);
|
||||
|
||||
return $content['totalItems'];
|
||||
}
|
||||
|
||||
private function testPagination(int $totalAssets): void
|
||||
{
|
||||
$limit = 2;
|
||||
$totalPages = ceil($totalAssets / $limit);
|
||||
|
||||
for ($page = 1; $page <= $totalPages; ++$page) {
|
||||
$response = $this->makeRequest('GET', self::ASSETS_ENDPOINT."?limit={$limit}&page={$page}");
|
||||
$content = $this->getJsonResponse($response);
|
||||
|
||||
$this->assertArrayHasKey('data', $content);
|
||||
$this->assertArrayHasKey('page', $content);
|
||||
$this->assertArrayHasKey('limit', $content);
|
||||
$this->assertArrayHasKey('totalItems', $content);
|
||||
$this->assertArrayHasKey('totalPages', $content);
|
||||
$this->assertArrayHasKey('hasNextPage', $content);
|
||||
$this->assertArrayHasKey('hasPreviousPage', $content);
|
||||
|
||||
$this->assertEquals($page, $content['page']);
|
||||
$this->assertEquals($limit, $content['limit']);
|
||||
$this->assertEquals($totalAssets, $content['totalItems']);
|
||||
$this->assertEquals($totalPages, $content['totalPages']);
|
||||
|
||||
$this->assertEquals($page < $totalPages, $content['hasNextPage']);
|
||||
$this->assertEquals($page > 1, $content['hasPreviousPage']);
|
||||
|
||||
$expectedItemCount = ($page < $totalPages) ? $limit : (($totalAssets % $limit) ?: $limit);
|
||||
$this->assertCount($expectedItemCount, $content['data']);
|
||||
|
||||
foreach ($content['data'] as $item) {
|
||||
$this->assertArrayHasKey('src', $item);
|
||||
$this->assertArrayHasKey('width', $item);
|
||||
$this->assertArrayHasKey('height', $item);
|
||||
$this->assertArrayHasKey('type', $item);
|
||||
}
|
||||
}
|
||||
|
||||
// Test invalid page
|
||||
$response = $this->makeRequest('GET', self::ASSETS_ENDPOINT."?limit={$limit}&page=".($totalPages + 1));
|
||||
$content = $this->getJsonResponse($response);
|
||||
$this->assertEmpty($content['data']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string> $uploadedFiles
|
||||
*/
|
||||
private function testRecentlyAddedFilesAppearFirst(array $uploadedFiles): void
|
||||
{
|
||||
$response = $this->makeRequest('GET', self::ASSETS_ENDPOINT);
|
||||
$content = $this->getJsonResponse($response);
|
||||
|
||||
$this->assertArrayHasKey('data', $content);
|
||||
$this->assertNotEmpty($content['data']);
|
||||
|
||||
$assetList = $content['data'];
|
||||
$uploadedFileNames = array_map([$this, 'getFileNameFromUrl'], $uploadedFiles);
|
||||
|
||||
// Check if the first 'IMAGE_COUNT' assets in the list are the recently uploaded files
|
||||
for ($i = 0; $i < self::IMAGE_COUNT; ++$i) {
|
||||
$this->assertArrayHasKey($i, $assetList);
|
||||
$this->assertArrayHasKey('src', $assetList[$i]);
|
||||
$assetFileName = $this->getFileNameFromUrl($assetList[$i]['src']);
|
||||
$this->assertContains($assetFileName, $uploadedFileNames, 'Recently uploaded file not found in the first {self::IMAGE_COUNT} assets');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string>
|
||||
*/
|
||||
private function uploadImages(): array
|
||||
{
|
||||
$imageFiles = $this->createTempImageFiles();
|
||||
$response = $this->makeRequest('POST', self::UPLOAD_ENDPOINT, [], ['files' => $imageFiles]);
|
||||
|
||||
return $this->getJsonResponse($response)['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<UploadedFile>
|
||||
*/
|
||||
private function createTempImageFiles(): array
|
||||
{
|
||||
$imageFiles = [];
|
||||
for ($i = 1; $i <= self::IMAGE_COUNT; ++$i) {
|
||||
$imagePath = sys_get_temp_dir()."/test-image-{$i}.png";
|
||||
$this->createImage($imagePath);
|
||||
$this->tempFilePaths[] = $imagePath;
|
||||
$imageFiles[] = new UploadedFile($imagePath, "test-image-{$i}.png", 'image/png', null, true);
|
||||
}
|
||||
|
||||
return $imageFiles;
|
||||
}
|
||||
|
||||
private function createImage(string $path): void
|
||||
{
|
||||
$image = imagecreatetruecolor(100, 100);
|
||||
imagepng($image, $path);
|
||||
imagedestroy($image);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string> $uploadedFiles
|
||||
*/
|
||||
private function assertUploadSuccessful(array $uploadedFiles): void
|
||||
{
|
||||
$this->assertCount(self::IMAGE_COUNT, $uploadedFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string> $uploadedFiles
|
||||
*/
|
||||
private function deleteUploadedFiles(array $uploadedFiles): void
|
||||
{
|
||||
foreach ($uploadedFiles as $uploadedFile) {
|
||||
$fileName = $this->getFileNameFromUrl($uploadedFile);
|
||||
$this->makeRequest('GET', self::DELETE_ENDPOINT."?filename={$fileName}");
|
||||
}
|
||||
}
|
||||
|
||||
private function getFileNameFromUrl(string $url): string
|
||||
{
|
||||
$fileUrlParts = explode('/', $url);
|
||||
|
||||
return end($fileUrlParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $parameters
|
||||
* @param array<string, mixed> $files
|
||||
*/
|
||||
private function makeRequest(string $method, string $endpoint, array $parameters = [], array $files = []): Response
|
||||
{
|
||||
$this->client->request($method, $endpoint, $parameters, $files);
|
||||
$response = $this->client->getResponse();
|
||||
$this->assertSame(Response::HTTP_OK, $response->getStatusCode());
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function getJsonResponse(Response $response): array
|
||||
{
|
||||
return json_decode($response->getContent(), true);
|
||||
}
|
||||
|
||||
private function cleanupTempFiles(): void
|
||||
{
|
||||
foreach ($this->tempFilePaths as $path) {
|
||||
if (file_exists($path)) {
|
||||
unlink($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MauticPlugin\GrapesJsBuilderBundle\Tests\InstallFixtures\ORM;
|
||||
|
||||
use Mautic\CoreBundle\Test\MauticMysqlTestCase;
|
||||
use Mautic\PluginBundle\Entity\Integration;
|
||||
use Mautic\PluginBundle\Entity\Plugin;
|
||||
use MauticPlugin\GrapesJsBuilderBundle\InstallFixtures\ORM\GrapesJsData;
|
||||
use PHPUnit\Framework\Assert;
|
||||
|
||||
class GrapeJsDataTest extends MauticMysqlTestCase
|
||||
{
|
||||
protected $useCleanupRollback = false;
|
||||
|
||||
public function testGetGroups(): void
|
||||
{
|
||||
Assert::assertSame(['group_install', 'group_mautic_install_data'], GrapesJsData::getGroups());
|
||||
}
|
||||
|
||||
public function testLoad(): void
|
||||
{
|
||||
$findOneByCriteria = [
|
||||
'name' => 'GrapesJS Builder',
|
||||
'description' => 'GrapesJS Builder with MJML support for Mautic',
|
||||
'version' => '1.0.0',
|
||||
'author' => 'Mautic Community',
|
||||
'bundle' => 'GrapesJsBuilderBundle',
|
||||
];
|
||||
$plugin = $this->em->getRepository(Plugin::class)->findOneBy($findOneByCriteria);
|
||||
self::assertNull($plugin);
|
||||
|
||||
$this->loadFixtures([GrapesJsData::class]);
|
||||
|
||||
$plugin = $this->em->getRepository(Plugin::class)->findOneBy($findOneByCriteria);
|
||||
self::assertInstanceOf(Plugin::class, $plugin);
|
||||
|
||||
$integration = $this->em->getRepository(Integration::class)->findOneBy(
|
||||
[
|
||||
'isPublished' => true,
|
||||
'name' => 'GrapesJsBuilder',
|
||||
'plugin' => $plugin,
|
||||
]
|
||||
);
|
||||
self::assertInstanceOf(Integration::class, $integration);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MauticPlugin\GrapesJsBuilderBundle\Tests\Unit\EventSubscriber;
|
||||
|
||||
use Mautic\EmailBundle\Entity\Email;
|
||||
use Mautic\EmailBundle\Entity\EmailRepository;
|
||||
use Mautic\EmailBundle\Event\EmailEditSubmitEvent;
|
||||
use Mautic\EmailBundle\Helper\EmailConfigInterface;
|
||||
use Mautic\EmailBundle\Model\EmailModel;
|
||||
use MauticPlugin\GrapesJsBuilderBundle\Entity\GrapesJsBuilder;
|
||||
use MauticPlugin\GrapesJsBuilderBundle\Entity\GrapesJsBuilderRepository;
|
||||
use MauticPlugin\GrapesJsBuilderBundle\EventSubscriber\EmailSubscriber;
|
||||
use MauticPlugin\GrapesJsBuilderBundle\Integration\Config;
|
||||
use MauticPlugin\GrapesJsBuilderBundle\Model\GrapesJsBuilderModel;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class EmailSubscriberTest extends TestCase
|
||||
{
|
||||
/** @var MockObject&Config */
|
||||
private MockObject $config;
|
||||
/** @var MockObject&GrapesJsBuilderModel */
|
||||
private MockObject $grapesJsBuilderModel;
|
||||
/** @var MockObject&GrapesJsBuilderRepository */
|
||||
private MockObject $grapesJsBuilderRepo;
|
||||
private EmailModel|MockObject $emailModel;
|
||||
private EmailConfigInterface|MockObject $emailConfig;
|
||||
private EmailSubscriber $subscriber;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->config = $this->createMock(Config::class);
|
||||
$this->grapesJsBuilderModel = $this->createMock(GrapesJsBuilderModel::class);
|
||||
$this->emailModel = $this->createMock(EmailModel::class);
|
||||
$this->emailConfig = $this->createMock(EmailConfigInterface::class);
|
||||
$this->grapesJsBuilderRepo = $this->createMock(GrapesJsBuilderRepository::class);
|
||||
$this->subscriber = new EmailSubscriber($this->config, $this->grapesJsBuilderModel, $this->emailModel, $this->emailConfig);
|
||||
|
||||
$this->emailModel->method('getRepository')
|
||||
->willReturn($this->createMock(EmailRepository::class));
|
||||
|
||||
$this->grapesJsBuilderModel->method('getRepository')
|
||||
->willReturn($this->grapesJsBuilderRepo);
|
||||
}
|
||||
|
||||
public function testManageEmailDraftExitsWhenPluginNotPublished(): void
|
||||
{
|
||||
$event = $this->createMock(EmailEditSubmitEvent::class);
|
||||
|
||||
$event->expects($this->never())
|
||||
->method('getCurrentEmail');
|
||||
|
||||
$this->config->expects($this->once())
|
||||
->method('isPublished')
|
||||
->willReturn(false);
|
||||
|
||||
$this->subscriber->manageEmailDraft($event);
|
||||
}
|
||||
|
||||
public function testManageEmailDraftHandlesSaveAsDraft(): void
|
||||
{
|
||||
$event = $this->createMock(EmailEditSubmitEvent::class);
|
||||
|
||||
$event->expects($this->once())
|
||||
->method('getCurrentEmail')
|
||||
->willReturn($this->createMock(Email::class));
|
||||
|
||||
$event->expects($this->once())
|
||||
->method('isSaveAsDraft')
|
||||
->willReturn(true);
|
||||
|
||||
$this->grapesJsBuilderRepo->method('findOneBy')
|
||||
->willReturn($grapesJsBuilder = $this->createMock(GrapesJsBuilder::class));
|
||||
|
||||
$this->config->expects($this->once())
|
||||
->method('isPublished')
|
||||
->willReturn(true);
|
||||
|
||||
$grapesJsBuilder->expects($this->once())->method('setDraftCustomMjml');
|
||||
$grapesJsBuilder->expects($this->once())->method('setCustomMjml');
|
||||
|
||||
$this->subscriber->manageEmailDraft($event);
|
||||
}
|
||||
|
||||
public function testManageEmailDraftHandlesApply(): void
|
||||
{
|
||||
$event = $this->createMock(EmailEditSubmitEvent::class);
|
||||
|
||||
$event->expects($this->once())
|
||||
->method('getCurrentEmail')
|
||||
->willReturn($this->createMock(Email::class));
|
||||
|
||||
$event->expects($this->once())
|
||||
->method('isApplyDraft')
|
||||
->willReturn(true);
|
||||
|
||||
$this->grapesJsBuilderRepo->method('findOneBy')
|
||||
->willReturn($grapesJsBuilder = $this->createMock(GrapesJsBuilder::class));
|
||||
|
||||
$this->config->expects($this->once())
|
||||
->method('isPublished')
|
||||
->willReturn(true);
|
||||
|
||||
$grapesJsBuilder->expects($this->once())->method('setDraftCustomMjml');
|
||||
$grapesJsBuilder->expects($this->never())->method('setCustomMjml');
|
||||
|
||||
$this->subscriber->manageEmailDraft($event);
|
||||
}
|
||||
|
||||
public function testManageEmailDraftHandlesDiscardDraft(): void
|
||||
{
|
||||
$event = $this->createMock(EmailEditSubmitEvent::class);
|
||||
|
||||
$event->expects($this->once())
|
||||
->method('getCurrentEmail')
|
||||
->willReturn($mockEmail = $this->createMock(Email::class));
|
||||
|
||||
$event->expects($this->once())
|
||||
->method('isDiscardDraft')
|
||||
->willReturn(true);
|
||||
|
||||
$mockEmail->expects($this->once())
|
||||
->method('hasDraft')
|
||||
->willReturn(true);
|
||||
|
||||
$this->grapesJsBuilderRepo->method('findOneBy')
|
||||
->willReturn($grapesJsBuilder = $this->createMock(GrapesJsBuilder::class));
|
||||
|
||||
$this->config->expects($this->once())
|
||||
->method('isPublished')
|
||||
->willReturn(true);
|
||||
|
||||
$grapesJsBuilder->expects($this->once())
|
||||
->method('setDraftCustomMjml')
|
||||
->with(null);
|
||||
|
||||
$this->subscriber->manageEmailDraft($event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MauticPlugin\GrapesJsBuilderBundle\Tests\Unit\Model;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
||||
use Mautic\CoreBundle\Helper\UserHelper;
|
||||
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
|
||||
use Mautic\CoreBundle\Translation\Translator;
|
||||
use Mautic\EmailBundle\Entity\Email;
|
||||
use Mautic\EmailBundle\Entity\EmailRepository;
|
||||
use Mautic\EmailBundle\Model\EmailModel;
|
||||
use MauticPlugin\GrapesJsBuilderBundle\Entity\GrapesJsBuilder;
|
||||
use MauticPlugin\GrapesJsBuilderBundle\Entity\GrapesJsBuilderRepository;
|
||||
use MauticPlugin\GrapesJsBuilderBundle\Model\GrapesJsBuilderModel;
|
||||
use PHPUnit\Framework\Assert;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Routing\Router;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
|
||||
class GrapesJsBuilderModelTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testAddOrEditEntityWithoutMatchingEntityAndNoRequestQuery(): void
|
||||
{
|
||||
$requestStack = new class extends RequestStack {
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function getCurrentRequest(): Request
|
||||
{
|
||||
return new Request();
|
||||
}
|
||||
};
|
||||
|
||||
$emailRepository = new class extends EmailRepository {
|
||||
public int $saveEntityCallCount = 0;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function saveEntity($entity, $flush = true): void
|
||||
{
|
||||
++$this->saveEntityCallCount;
|
||||
}
|
||||
};
|
||||
|
||||
$emailModel = $this->getEmailModel($emailRepository);
|
||||
|
||||
$grapesJsBuilderRepository = new class extends GrapesJsBuilderRepository {
|
||||
public int $saveEntityCallCount = 0;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function findOneBy(array $criteria, ?array $orderBy = null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function saveEntity($entity, $flush = true): void
|
||||
{
|
||||
++$this->saveEntityCallCount;
|
||||
}
|
||||
};
|
||||
|
||||
$entityManager = new class($grapesJsBuilderRepository) extends EntityManager {
|
||||
public function __construct(
|
||||
private GrapesJsBuilderRepository $grapesJsBuilderRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getRepository($entityName)
|
||||
{
|
||||
Assert::assertSame(GrapesJsBuilder::class, $entityName);
|
||||
|
||||
return $this->grapesJsBuilderRepository; // @phpstan-ignore-line
|
||||
}
|
||||
};
|
||||
|
||||
$email = new Email();
|
||||
|
||||
$grapeJsBuilderModel = new GrapesJsBuilderModel(
|
||||
$requestStack,
|
||||
$emailModel,
|
||||
$entityManager,
|
||||
$this->createMock(CorePermissions::class),
|
||||
$this->createMock(EventDispatcherInterface::class),
|
||||
$this->createMock(Router::class),
|
||||
$this->getTranslator(),
|
||||
$this->createMock(UserHelper::class),
|
||||
$this->createMock(LoggerInterface::class),
|
||||
$this->createMock(CoreParametersHelper::class)
|
||||
);
|
||||
|
||||
$grapeJsBuilderModel->addOrEditEntity($email);
|
||||
|
||||
// Not a GrapeJs email, so we are not saving anything.
|
||||
Assert::assertSame(0, $grapesJsBuilderRepository->saveEntityCallCount);
|
||||
Assert::assertSame(0, $emailRepository->saveEntityCallCount);
|
||||
}
|
||||
|
||||
public function testAddOrEditEntityWithoutMatchingEntityAndGrapeRequestQuery(): void
|
||||
{
|
||||
$requestStack = new class extends RequestStack {
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function getCurrentRequest(): Request
|
||||
{
|
||||
return new Request(
|
||||
[],
|
||||
[
|
||||
'grapesjsbuilder' => [
|
||||
'customMjml' => '</mjml>',
|
||||
],
|
||||
'emailform' => [
|
||||
'customHtml' => '</html>',
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
$emailRepository = new class extends EmailRepository {
|
||||
public int $saveEntityCallCount = 0;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Email $entity
|
||||
*/
|
||||
public function saveEntity($entity, $flush = true): void
|
||||
{
|
||||
++$this->saveEntityCallCount;
|
||||
|
||||
Assert::assertSame('</html>', $entity->getCustomHtml());
|
||||
}
|
||||
};
|
||||
|
||||
$emailModel = $this->getEmailModel($emailRepository);
|
||||
|
||||
$grapesJsBuilderRepository = new class extends GrapesJsBuilderRepository {
|
||||
public int $saveEntityCallCount = 0;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function findOneBy(array $criteria, ?array $orderBy = null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GrapesJsBuilder $entity
|
||||
*/
|
||||
public function saveEntity($entity, $flush = true): void
|
||||
{
|
||||
++$this->saveEntityCallCount;
|
||||
|
||||
Assert::assertSame('</mjml>', $entity->getCustomMjml());
|
||||
}
|
||||
};
|
||||
|
||||
$entityManager = new class($grapesJsBuilderRepository) extends EntityManager {
|
||||
public function __construct(
|
||||
private GrapesJsBuilderRepository $grapesJsBuilderRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getRepository($entityName)
|
||||
{
|
||||
Assert::assertSame(GrapesJsBuilder::class, $entityName);
|
||||
|
||||
return $this->grapesJsBuilderRepository; // @phpstan-ignore-line
|
||||
}
|
||||
};
|
||||
|
||||
$email = new Email();
|
||||
|
||||
$grapeJsBuilderModel = new GrapesJsBuilderModel(
|
||||
$requestStack,
|
||||
$emailModel,
|
||||
$entityManager,
|
||||
$this->createMock(CorePermissions::class),
|
||||
$this->createMock(EventDispatcherInterface::class),
|
||||
$this->createMock(Router::class),
|
||||
$this->getTranslator(),
|
||||
$this->createMock(UserHelper::class),
|
||||
$this->createMock(LoggerInterface::class),
|
||||
$this->createMock(CoreParametersHelper::class)
|
||||
);
|
||||
|
||||
$grapeJsBuilderModel->addOrEditEntity($email);
|
||||
|
||||
// Saving the entities now.
|
||||
Assert::assertSame(1, $grapesJsBuilderRepository->saveEntityCallCount);
|
||||
Assert::assertSame(1, $emailRepository->saveEntityCallCount);
|
||||
}
|
||||
|
||||
private function getEmailModel(EmailRepository $emailRepository): EmailModel
|
||||
{
|
||||
return new class($emailRepository) extends EmailModel {
|
||||
public function __construct(
|
||||
private EmailRepository $emailRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getRepository(): EmailRepository
|
||||
{
|
||||
return $this->emailRepository;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private function getTranslator(): Translator
|
||||
{
|
||||
return new class extends Translator {
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user