Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,371 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\DynamicContentBundle\Tests\EventListener;
|
||||
|
||||
use Mautic\AssetBundle\Helper\TokenHelper as AssetTokenHelper;
|
||||
use Mautic\CoreBundle\Event\TokenReplacementEvent;
|
||||
use Mautic\CoreBundle\Model\AuditLogModel;
|
||||
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
|
||||
use Mautic\DynamicContentBundle\Entity\DynamicContent;
|
||||
use Mautic\DynamicContentBundle\EventListener\DynamicContentSubscriber;
|
||||
use Mautic\DynamicContentBundle\Helper\DynamicContentHelper;
|
||||
use Mautic\DynamicContentBundle\Model\DynamicContentModel;
|
||||
use Mautic\FormBundle\Helper\TokenHelper as FormTokenHelper;
|
||||
use Mautic\LeadBundle\Entity\CompanyLeadRepository;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\LeadBundle\Model\CompanyModel;
|
||||
use Mautic\LeadBundle\Tracker\ContactTracker;
|
||||
use Mautic\PageBundle\Event\PageDisplayEvent;
|
||||
use Mautic\PageBundle\Helper\TokenHelper as PageTokenHelper;
|
||||
use Mautic\PageBundle\Model\TrackableModel;
|
||||
use MauticPlugin\MauticFocusBundle\Helper\TokenHelper as FocusTokenHelper;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
|
||||
class DynamicContentSubscriberTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var MockObject|TrackableModel
|
||||
*/
|
||||
private MockObject $trackableModel;
|
||||
|
||||
/**
|
||||
* @var MockObject|PageTokenHelper
|
||||
*/
|
||||
private MockObject $pageTokenHelper;
|
||||
|
||||
/**
|
||||
* @var MockObject|AssetTokenHelper
|
||||
*/
|
||||
private MockObject $assetTokenHelper;
|
||||
|
||||
/**
|
||||
* @var MockObject|FormTokenHelper
|
||||
*/
|
||||
private MockObject $formTokenHelper;
|
||||
|
||||
/**
|
||||
* @var MockObject|FocusTokenHelper
|
||||
*/
|
||||
private MockObject $focusTokenHelper;
|
||||
|
||||
/**
|
||||
* @var MockObject|AuditLogModel
|
||||
*/
|
||||
private MockObject $auditLogModel;
|
||||
|
||||
/**
|
||||
* @var MockObject|DynamicContentHelper
|
||||
*/
|
||||
private MockObject $dynamicContentHelper;
|
||||
|
||||
/**
|
||||
* @var MockObject|DynamicContentModel
|
||||
*/
|
||||
private MockObject $dynamicContentModel;
|
||||
|
||||
/**
|
||||
* @var MockObject|CorePermissions
|
||||
*/
|
||||
private MockObject $security;
|
||||
|
||||
/**
|
||||
* @var MockObject|ContactTracker
|
||||
*/
|
||||
private MockObject $contactTracker;
|
||||
private \PHPUnit\Framework\MockObject\MockObject|CompanyLeadRepository $companyLeadRepositoryMock;
|
||||
|
||||
private DynamicContentSubscriber $subscriber;
|
||||
/**
|
||||
* @var CompanyModel|(CompanyModel&MockObject)|MockObject
|
||||
*/
|
||||
private MockObject $companyModel;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->trackableModel = $this->createMock(TrackableModel::class);
|
||||
$this->pageTokenHelper = $this->createMock(PageTokenHelper::class);
|
||||
$this->assetTokenHelper = $this->createMock(AssetTokenHelper::class);
|
||||
$this->formTokenHelper = $this->createMock(FormTokenHelper::class);
|
||||
$this->focusTokenHelper = $this->createMock(FocusTokenHelper::class);
|
||||
$this->auditLogModel = $this->createMock(AuditLogModel::class);
|
||||
$this->contactTracker = $this->createMock(ContactTracker::class);
|
||||
$this->dynamicContentHelper = $this->createMock(DynamicContentHelper::class);
|
||||
$this->dynamicContentModel = $this->createMock(DynamicContentModel::class);
|
||||
$this->security = $this->createMock(CorePermissions::class);
|
||||
$this->contactTracker = $this->createMock(ContactTracker::class);
|
||||
$this->companyModel = $this->createMock(CompanyModel::class);
|
||||
$this->companyLeadRepositoryMock = $this->createMock(CompanyLeadRepository::class);
|
||||
$this->subscriber = new DynamicContentSubscriber(
|
||||
$this->trackableModel,
|
||||
$this->pageTokenHelper,
|
||||
$this->assetTokenHelper,
|
||||
$this->formTokenHelper,
|
||||
$this->focusTokenHelper,
|
||||
$this->auditLogModel,
|
||||
$this->dynamicContentHelper,
|
||||
$this->dynamicContentModel,
|
||||
$this->security,
|
||||
$this->contactTracker,
|
||||
$this->companyModel
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This test is ensuring this error won't happen again:.
|
||||
*
|
||||
* DOMDocumentFragment::appendXML(): Entity: line 1: parser error : xmlParseEntityRef: no name
|
||||
*
|
||||
* It happens when there is an ampersand in the DWC content.
|
||||
*/
|
||||
public function testDecodeTokensWithAmpersandDataAttribute(): void
|
||||
{
|
||||
$content = <<< HTML
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>Hello there!</h2>
|
||||
<div data-slot="dwc" data-param-slot-name="test-token"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
HTML;
|
||||
|
||||
$expected = <<< HTML
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>Hello there!</h2>
|
||||
<a href="https://john.doe&son">Link</a>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
HTML;
|
||||
$dwcContent = '<a href="https://john.doe&son">Link</a>';
|
||||
$event = $this->createMock(PageDisplayEvent::class);
|
||||
$contact = new Lead();
|
||||
|
||||
$event->expects($this->once())
|
||||
->method('getContent')
|
||||
->willReturn($content);
|
||||
|
||||
$this->security->expects($this->once())
|
||||
->method('isAnonymous')
|
||||
->willReturn(true);
|
||||
|
||||
$this->contactTracker->expects($this->once())
|
||||
->method('getContact')
|
||||
->willReturn($contact);
|
||||
|
||||
$this->dynamicContentHelper->expects($this->never())
|
||||
->method('convertLeadToArray');
|
||||
|
||||
$this->dynamicContentHelper->expects($this->once())
|
||||
->method('findDwcTokens')
|
||||
->with($content, $contact)
|
||||
->willReturn([]);
|
||||
|
||||
$this->dynamicContentHelper->expects($this->once())
|
||||
->method('getDynamicContentForLead')
|
||||
->with('test-token', $contact)
|
||||
->willReturn($dwcContent);
|
||||
|
||||
$event->expects($this->once())
|
||||
->method('setContent')
|
||||
->with($expected);
|
||||
|
||||
$this->subscriber->decodeTokens($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* This test is ensuring this error won't happen again:.
|
||||
*
|
||||
* DOMDocumentFragment::appendXML(): Entity: line 1: parser error : xmlParseEntityRef: no name
|
||||
*
|
||||
* It happens when there is an ampersand in the DWC content.
|
||||
*/
|
||||
public function testDecodeTokensWithAmpersandInlineDwc(): void
|
||||
{
|
||||
$content = <<< HTML
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>Hello there!</h2>
|
||||
{dwc=test-token}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
HTML;
|
||||
|
||||
$expected = <<< HTML
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>Hello there!</h2>
|
||||
<a href="https://john.doe&son">Link</a>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
HTML;
|
||||
$dwcContent = '<a href="https://john.doe&son">Link</a>';
|
||||
$event = $this->createMock(PageDisplayEvent::class);
|
||||
$contact = new Lead();
|
||||
|
||||
$event->expects($this->once())
|
||||
->method('getContent')
|
||||
->willReturn($content);
|
||||
|
||||
$this->security->expects($this->once())
|
||||
->method('isAnonymous')
|
||||
->willReturn(true);
|
||||
|
||||
$this->contactTracker->expects($this->once())
|
||||
->method('getContact')
|
||||
->willReturn($contact);
|
||||
|
||||
$this->dynamicContentHelper->expects($this->never())
|
||||
->method('convertLeadToArray');
|
||||
|
||||
$this->dynamicContentHelper->expects($this->once())
|
||||
->method('findDwcTokens')
|
||||
->with($content, $contact)
|
||||
->willReturn([
|
||||
'{dwc=test-token}' => [
|
||||
'content' => $dwcContent,
|
||||
'filters' => [
|
||||
[
|
||||
'field' => 'email',
|
||||
'operator' => '!empty',
|
||||
'filter' => '',
|
||||
'type' => 'email',
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->dynamicContentHelper->expects($this->never())
|
||||
->method('getDynamicContentForLead');
|
||||
|
||||
$event->expects($this->once())
|
||||
->method('setContent')
|
||||
->with($expected);
|
||||
|
||||
$this->subscriber->decodeTokens($event);
|
||||
}
|
||||
|
||||
public function testOnTokenReplacement(): void
|
||||
{
|
||||
$content = <<< HTML
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>Hello there!</h2>
|
||||
Company name : {contactfield=companyname}
|
||||
Company Country : {contactfield=companycountry}
|
||||
Company website : {contactfield=companywebsite}
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
$expected = <<< HTML
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>Hello there!</h2>
|
||||
Company name : Doe Corp
|
||||
Company Country : India
|
||||
Company website : https://www.doe.corp
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
$contact = $this->createMock(Lead::class);
|
||||
$event = $this->createMock(TokenReplacementEvent::class);
|
||||
|
||||
$event
|
||||
->expects($this->once())
|
||||
->method('getContent')
|
||||
->willReturn($content);
|
||||
|
||||
$event
|
||||
->expects($this->once())
|
||||
->method('getLead')
|
||||
->willReturn($contact);
|
||||
|
||||
$event
|
||||
->expects($this->once())
|
||||
->method('getClickthrough')
|
||||
->willReturn([
|
||||
'slot' => 'slotOne',
|
||||
'dynamic_content_id' => 1,
|
||||
'lead' => 1,
|
||||
]);
|
||||
|
||||
$contact
|
||||
->expects($this->once())
|
||||
->method('getProfileFields')
|
||||
->willReturn([
|
||||
'id' => 1,
|
||||
'firstname' => 'John',
|
||||
'lastname' => 'Doe',
|
||||
'company' => 'Doe Corp',
|
||||
'email' => 'john@doe.com',
|
||||
]);
|
||||
|
||||
$this->companyModel
|
||||
->expects($this->once())
|
||||
->method('getCompanyLeadRepository')
|
||||
->willReturn($this->companyLeadRepositoryMock);
|
||||
|
||||
$this->companyLeadRepositoryMock->expects($this->once())
|
||||
->method('getPrimaryCompanyByLeadId')
|
||||
->willReturn(
|
||||
[
|
||||
'id' => 1,
|
||||
'companyname' => 'Doe Corp',
|
||||
'companycountry' => 'India',
|
||||
'companywebsite' => 'https://www.doe.corp',
|
||||
'is_primary' => true,
|
||||
]
|
||||
);
|
||||
|
||||
$this->pageTokenHelper
|
||||
->method('findPageTokens')
|
||||
->willReturn([]);
|
||||
$this->assetTokenHelper
|
||||
->method('findAssetTokens')
|
||||
->willReturn([]);
|
||||
$this->formTokenHelper
|
||||
->method('findFormTokens')
|
||||
->willReturn([]);
|
||||
$this->focusTokenHelper
|
||||
->method('findFocusTokens')
|
||||
->willReturn([]);
|
||||
|
||||
$this->trackableModel
|
||||
->method('parseContentForTrackables')
|
||||
->willReturn([
|
||||
$content,
|
||||
[],
|
||||
]);
|
||||
|
||||
$dwc = new DynamicContent();
|
||||
$dwc->setContent($content);
|
||||
|
||||
$this->dynamicContentModel
|
||||
->expects($this->once())
|
||||
->method('getEntity')
|
||||
->willReturn($dwc);
|
||||
|
||||
$event->expects($this->once())
|
||||
->method('setContent')
|
||||
->with($expected);
|
||||
|
||||
$this->subscriber->onTokenReplacement($event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\DynamicContentBundle\Tests\Unit\Helper;
|
||||
|
||||
use Mautic\CampaignBundle\Executioner\RealTimeExecutioner;
|
||||
use Mautic\CoreBundle\Event\TokenReplacementEvent;
|
||||
use Mautic\DynamicContentBundle\DynamicContentEvents;
|
||||
use Mautic\DynamicContentBundle\Entity\DynamicContent;
|
||||
use Mautic\DynamicContentBundle\Event\ContactFiltersEvaluateEvent;
|
||||
use Mautic\DynamicContentBundle\Helper\DynamicContentHelper;
|
||||
use Mautic\DynamicContentBundle\Model\DynamicContentModel;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\LeadBundle\Model\LeadModel;
|
||||
use PHPUnit\Framework\Assert;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
|
||||
class DynamicContentHelperTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var MockObject&DynamicContentModel
|
||||
*/
|
||||
private MockObject $mockModel;
|
||||
|
||||
/**
|
||||
* @var MockObject&RealTimeExecutioner
|
||||
*/
|
||||
private MockObject $realTimeExecutioner;
|
||||
|
||||
/**
|
||||
* @var MockObject&EventDispatcher
|
||||
*/
|
||||
private MockObject $mockDispatcher;
|
||||
|
||||
/**
|
||||
* @var MockObject&LeadModel
|
||||
*/
|
||||
private MockObject $leadModel;
|
||||
|
||||
private DynamicContentHelper $helper;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->mockModel = $this->createMock(DynamicContentModel::class);
|
||||
$this->realTimeExecutioner = $this->createMock(RealTimeExecutioner::class);
|
||||
$this->mockDispatcher = $this->createMock(EventDispatcher::class);
|
||||
$this->leadModel = $this->createMock(LeadModel::class);
|
||||
$this->helper = new DynamicContentHelper(
|
||||
$this->mockModel,
|
||||
$this->realTimeExecutioner,
|
||||
$this->mockDispatcher,
|
||||
$this->leadModel,
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetDwcBySlotNameWithPublished(): void
|
||||
{
|
||||
$matcher = $this->exactly(2);
|
||||
$this->mockModel->expects($matcher)
|
||||
->method('getEntities')->willReturnCallback(function (...$parameters) use ($matcher) {
|
||||
if (1 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame([
|
||||
'filter' => [
|
||||
'where' => [
|
||||
[
|
||||
'col' => 'e.slotName',
|
||||
'expr' => 'eq',
|
||||
'val' => 'test',
|
||||
],
|
||||
[
|
||||
'col' => 'e.isPublished',
|
||||
'expr' => 'eq',
|
||||
'val' => 1,
|
||||
],
|
||||
],
|
||||
],
|
||||
'ignore_paginator' => true,
|
||||
], $parameters[0]);
|
||||
|
||||
return ['some entity'];
|
||||
}
|
||||
if (2 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame([
|
||||
'filter' => [
|
||||
'where' => [
|
||||
[
|
||||
'col' => 'e.slotName',
|
||||
'expr' => 'eq',
|
||||
'val' => 'secondtest',
|
||||
],
|
||||
],
|
||||
],
|
||||
'ignore_paginator' => true,
|
||||
], $parameters[0]);
|
||||
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
// Only get published
|
||||
$this->assertCount(1, $this->helper->getDwcsBySlotName('test', true));
|
||||
|
||||
// Get all
|
||||
$this->assertCount(0, $this->helper->getDwcsBySlotName('secondtest'));
|
||||
}
|
||||
|
||||
public function testGetDynamicContentSlotForLeadWithListenerFindingMatch(): void
|
||||
{
|
||||
$slotName = 'test';
|
||||
$contact = new Lead();
|
||||
$contact->setFields(['email' => 'ma@ka.t', 'id' => 123]);
|
||||
|
||||
$slot = new DynamicContent();
|
||||
$slot->setName($slotName);
|
||||
$slot->setIsCampaignBased(false);
|
||||
// Setting filter that is not known to Mautic, but is for a plugin.
|
||||
$slot->setFilters([['field' => 'unicorn', 'type' => 'text', 'operator' => '=', 'filter' => 'magic']]);
|
||||
$slot->setContent('<p>test</p>');
|
||||
|
||||
$this->mockModel->method('getEntities')
|
||||
->willReturn([$slot]);
|
||||
|
||||
$this->mockModel->method('getTranslatedEntity')
|
||||
->willReturn([$slot, $slot]);
|
||||
|
||||
$this->leadModel->method('getEntity')
|
||||
->with(123)
|
||||
->willReturn($contact);
|
||||
|
||||
$this->mockDispatcher->method('hasListeners')->willReturn(true);
|
||||
$matcher = $this->exactly(2);
|
||||
$this->mockDispatcher->expects($matcher)
|
||||
->method('dispatch')->willReturnCallback(function (...$parameters) use ($matcher, $contact, $slot) {
|
||||
if (1 === $matcher->numberOfInvocations()) {
|
||||
$callback = function (ContactFiltersEvaluateEvent $event) use ($contact, $slot) {
|
||||
$this->assertSame($contact, $event->getContact());
|
||||
$this->assertSame($slot->getFilters(), $event->getFilters());
|
||||
|
||||
$event->setIsEvaluated(true);
|
||||
$event->setIsMatched(true); // Match found in a subscriber.
|
||||
};
|
||||
$callback($parameters[0]);
|
||||
$this->assertSame(DynamicContentEvents::ON_CONTACTS_FILTER_EVALUATE, $parameters[1]);
|
||||
}
|
||||
if (2 === $matcher->numberOfInvocations()) {
|
||||
$callback = function (TokenReplacementEvent $event) use ($contact, $slot) {
|
||||
$this->assertSame($contact, $event->getLead());
|
||||
$this->assertSame($slot->getContent(), $event->getContent());
|
||||
};
|
||||
$callback($parameters[0]);
|
||||
$this->assertSame(DynamicContentEvents::TOKEN_REPLACEMENT, $parameters[1]);
|
||||
}
|
||||
|
||||
return $parameters[0];
|
||||
});
|
||||
|
||||
Assert::assertSame(
|
||||
'<p>test</p>',
|
||||
$this->helper->getDynamicContentSlotForLead($slotName, $contact)
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetDynamicContentSlotForLeadWithListenerNotFindingMatch(): void
|
||||
{
|
||||
$slotName = 'test';
|
||||
$contact = new Lead();
|
||||
$contact->setFields(['email' => 'ma@ka.t', 'id' => 123]);
|
||||
|
||||
$slot = new DynamicContent();
|
||||
$slot->setName($slotName);
|
||||
$slot->setIsCampaignBased(false);
|
||||
// Setting filter that is not known to Mautic, nor any plugin.
|
||||
$slot->setFilters([['field' => 'unicorn', 'type' => 'text', 'operator' => '=', 'filter' => 'magic']]);
|
||||
$slot->setContent('<p>test</p>');
|
||||
|
||||
$this->mockModel->method('getEntities')
|
||||
->willReturn([$slot]);
|
||||
|
||||
$this->mockModel->method('getTranslatedEntity')
|
||||
->willReturn([$slot, $slot]);
|
||||
|
||||
$this->leadModel->method('getEntity')
|
||||
->with(123)
|
||||
->willReturn($contact);
|
||||
|
||||
$this->mockDispatcher->method('hasListeners')->willReturn(true);
|
||||
$matcher = $this->once();
|
||||
$this->mockDispatcher->expects($matcher)
|
||||
->method('dispatch')
|
||||
->willReturnCallback(
|
||||
function (...$parameters) use ($matcher, $contact, $slot) {
|
||||
if (1 === $matcher->numberOfInvocations()) {
|
||||
$callback = function (ContactFiltersEvaluateEvent $event) use ($contact, $slot) {
|
||||
$this->assertSame($contact, $event->getContact());
|
||||
$this->assertSame($slot->getFilters(), $event->getFilters());
|
||||
|
||||
// Match not found in any subscriber.
|
||||
};
|
||||
$callback($parameters[0]);
|
||||
$this->assertSame(DynamicContentEvents::ON_CONTACTS_FILTER_EVALUATE, $parameters[1]);
|
||||
}
|
||||
|
||||
return $parameters[0];
|
||||
}
|
||||
);
|
||||
|
||||
Assert::assertSame(
|
||||
'', // No content returned as the filter did not match anything.
|
||||
$this->helper->getDynamicContentSlotForLead($slotName, $contact)
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetDynamicContentSlotForLeadWithNoListenerWithMatchingFilter(): void
|
||||
{
|
||||
$slotName = 'test';
|
||||
$contact = new Lead();
|
||||
$contact->setFields(['email' => 'ma@ka.t', 'id' => 123]);
|
||||
|
||||
$slot = new DynamicContent();
|
||||
$slot->setName($slotName);
|
||||
$slot->setIsCampaignBased(false);
|
||||
$slot->setFilters([['field' => 'email', 'type' => 'email', 'operator' => '=', 'filter' => 'ma@ka.t']]);
|
||||
$slot->setContent('<p>test</p>');
|
||||
|
||||
$this->mockModel->method('getEntities')
|
||||
->willReturn([$slot]);
|
||||
|
||||
$this->mockModel->method('getTranslatedEntity')
|
||||
->willReturn([$slot, $slot]);
|
||||
|
||||
$this->leadModel->method('getEntity')
|
||||
->with(123)
|
||||
->willReturn($contact);
|
||||
|
||||
$this->mockDispatcher->method('hasListeners')->willReturn(false);
|
||||
$matcher = $this->once();
|
||||
$this->mockDispatcher->expects($matcher)
|
||||
->method('dispatch')
|
||||
->willReturnCallback(
|
||||
function (...$parameters) use ($matcher, $contact, $slot) {
|
||||
if (1 === $matcher->numberOfInvocations()) {
|
||||
$callback = function (TokenReplacementEvent $event) use ($contact, $slot) {
|
||||
$this->assertSame($contact, $event->getLead());
|
||||
$this->assertSame($slot->getContent(), $event->getContent());
|
||||
};
|
||||
$callback($parameters[0]);
|
||||
$this->assertSame(DynamicContentEvents::TOKEN_REPLACEMENT, $parameters[1]);
|
||||
}
|
||||
|
||||
return $parameters[0];
|
||||
}
|
||||
);
|
||||
|
||||
Assert::assertSame(
|
||||
'<p>test</p>',
|
||||
$this->helper->getDynamicContentSlotForLead($slotName, $contact)
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetDynamicContentSlotForLeadWithNoListenerWithNotMatchingFilter(): void
|
||||
{
|
||||
$slotName = 'test';
|
||||
$contact = new Lead();
|
||||
$contact->setFields(['email' => 'ma@ka.t', 'id' => 123]);
|
||||
|
||||
$slot = new DynamicContent();
|
||||
$slot->setName($slotName);
|
||||
$slot->setIsCampaignBased(false);
|
||||
$slot->setFilters([['field' => 'email', 'type' => 'email', 'operator' => '=', 'filter' => 'uni@co.rn']]);
|
||||
$slot->setContent('<p>test</p>');
|
||||
|
||||
$this->mockModel->method('getEntities')
|
||||
->willReturn([$slot]);
|
||||
|
||||
$this->mockModel->method('getTranslatedEntity')
|
||||
->willReturn([$slot, $slot]);
|
||||
|
||||
$this->leadModel->method('getEntity')
|
||||
->with(123)
|
||||
->willReturn($contact);
|
||||
|
||||
$this->mockDispatcher->method('hasListeners')->willReturn(false);
|
||||
$this->mockDispatcher->expects($this->never())->method('dispatch');
|
||||
|
||||
Assert::assertSame(
|
||||
'',
|
||||
$this->helper->getDynamicContentSlotForLead($slotName, $contact)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\DynamicContentBundle\Tests\Unit\Validator\Constraints;
|
||||
|
||||
use Mautic\DynamicContentBundle\Validator\Constraints\NoNesting;
|
||||
use Mautic\DynamicContentBundle\Validator\Constraints\NoNestingValidator;
|
||||
use PHPUnit\Framework\Assert;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Translation\Loader\ArrayLoader;
|
||||
use Symfony\Component\Translation\Translator;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
use Symfony\Component\Validator\Context\ExecutionContext;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
|
||||
class NoNestingValidatorTest extends TestCase
|
||||
{
|
||||
private const TRANSLATED_MESSAGE = 'DWC tokens cannot be used within another DWC.';
|
||||
private NoNesting $constraint;
|
||||
private NoNestingValidator $validator;
|
||||
private ExecutionContextInterface $context;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->constraint = new NoNesting();
|
||||
$this->validator = new NoNestingValidator();
|
||||
$this->context = $this->createContext();
|
||||
$this->context->setConstraint($this->constraint);
|
||||
$this->validator->initialize($this->context);
|
||||
}
|
||||
|
||||
public function testValidateWithInvalidConstraint(): void
|
||||
{
|
||||
$this->expectException(UnexpectedTypeException::class);
|
||||
$this->expectExceptionMessage(sprintf('Expected argument of type "%s"', NoNesting::class));
|
||||
$this->validator->validate('value', new NotBlank());
|
||||
}
|
||||
|
||||
public function testValidateWithInvalidType(): void
|
||||
{
|
||||
$this->expectException(UnexpectedTypeException::class);
|
||||
$this->expectExceptionMessage('Expected argument of type "string", "stdClass" given');
|
||||
$this->validator->validate(new \stdClass(), $this->constraint);
|
||||
}
|
||||
|
||||
public function testValidateWithNull(): void
|
||||
{
|
||||
$this->validator->validate(null, $this->constraint);
|
||||
Assert::assertCount(0, $this->context->getViolations(), 'No violation should be added for a null value.');
|
||||
}
|
||||
|
||||
public function testValidateWithValidValue(): void
|
||||
{
|
||||
$this->validator->validate('Some valid value', $this->constraint);
|
||||
Assert::assertCount(0, $this->context->getViolations(), 'No violation should be added for a valid value.');
|
||||
}
|
||||
|
||||
public function testValidateWithInvalidValue(): void
|
||||
{
|
||||
$this->validator->validate('Some invalid value {dwc=some}', $this->constraint);
|
||||
Assert::assertCount(1, $this->context->getViolations(), 'There should be one violation for an invalid value.');
|
||||
Assert::assertSame(self::TRANSLATED_MESSAGE, $this->context->getViolations()->get(0)->getMessage());
|
||||
}
|
||||
|
||||
private function createContext(): ExecutionContextInterface
|
||||
{
|
||||
$locale = 'en_US';
|
||||
$validator = $this->createMock(ValidatorInterface::class);
|
||||
$translator = new Translator($locale);
|
||||
$translator->addLoader('array', new ArrayLoader());
|
||||
|
||||
$translator->addResource('array', [
|
||||
'mautic.dynamicContent.no_nesting' => self::TRANSLATED_MESSAGE,
|
||||
], $locale, 'validators');
|
||||
|
||||
return new ExecutionContext($validator, null, $translator, 'validators');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user