Spaces:
No application file
No application file
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 | |
{ | |
$this->mockModel->expects($this->exactly(2)) | |
->method('getEntities') | |
->withConsecutive( | |
[ | |
[ | |
'filter' => [ | |
'where' => [ | |
[ | |
'col' => 'e.slotName', | |
'expr' => 'eq', | |
'val' => 'test', | |
], | |
[ | |
'col' => 'e.isPublished', | |
'expr' => 'eq', | |
'val' => 1, | |
], | |
], | |
], | |
'ignore_paginator' => true, | |
], | |
], | |
[ | |
[ | |
'filter' => [ | |
'where' => [ | |
[ | |
'col' => 'e.slotName', | |
'expr' => 'eq', | |
'val' => 'secondtest', | |
], | |
], | |
], | |
'ignore_paginator' => true, | |
], | |
] | |
) | |
->willReturnOnConsecutiveCalls(['some entity'], []); | |
// 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' => '[email protected]', '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); | |
$this->mockDispatcher->expects($this->exactly(2)) | |
->method('dispatch') | |
->withConsecutive( | |
[ | |
$this->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. | |
return true; | |
} | |
), | |
DynamicContentEvents::ON_CONTACTS_FILTER_EVALUATE, | |
], | |
[ | |
$this->callback( | |
function (TokenReplacementEvent $event) use ($contact, $slot) { | |
$this->assertSame($contact, $event->getLead()); | |
$this->assertSame($slot->getContent(), $event->getContent()); | |
return true; | |
} | |
), | |
DynamicContentEvents::TOKEN_REPLACEMENT, | |
] | |
); | |
Assert::assertSame( | |
'<p>test</p>', | |
$this->helper->getDynamicContentSlotForLead($slotName, $contact) | |
); | |
} | |
public function testGetDynamicContentSlotForLeadWithListenerNotFindingMatch(): void | |
{ | |
$slotName = 'test'; | |
$contact = new Lead(); | |
$contact->setFields(['email' => '[email protected]', '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); | |
$this->mockDispatcher->expects($this->once()) | |
->method('dispatch') | |
->withConsecutive( | |
[ | |
$this->callback( | |
function (ContactFiltersEvaluateEvent $event) use ($contact, $slot) { | |
$this->assertSame($contact, $event->getContact()); | |
$this->assertSame($slot->getFilters(), $event->getFilters()); | |
// Match not found in any subscriber. | |
return true; | |
} | |
), | |
DynamicContentEvents::ON_CONTACTS_FILTER_EVALUATE, | |
] | |
); | |
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' => '[email protected]', 'id' => 123]); | |
$slot = new DynamicContent(); | |
$slot->setName($slotName); | |
$slot->setIsCampaignBased(false); | |
$slot->setFilters([['field' => 'email', 'type' => 'email', 'operator' => '=', 'filter' => '[email protected]']]); | |
$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->once()) | |
->method('dispatch') | |
->withConsecutive( | |
[ | |
$this->callback( | |
function (TokenReplacementEvent $event) use ($contact, $slot) { | |
$this->assertSame($contact, $event->getLead()); | |
$this->assertSame($slot->getContent(), $event->getContent()); | |
return true; | |
} | |
), | |
DynamicContentEvents::TOKEN_REPLACEMENT, | |
] | |
); | |
Assert::assertSame( | |
'<p>test</p>', | |
$this->helper->getDynamicContentSlotForLead($slotName, $contact) | |
); | |
} | |
public function testGetDynamicContentSlotForLeadWithNoListenerWithNotMatchingFilter(): void | |
{ | |
$slotName = 'test'; | |
$contact = new Lead(); | |
$contact->setFields(['email' => '[email protected]', 'id' => 123]); | |
$slot = new DynamicContent(); | |
$slot->setName($slotName); | |
$slot->setIsCampaignBased(false); | |
$slot->setFilters([['field' => 'email', 'type' => 'email', 'operator' => '=', 'filter' => '[email protected]']]); | |
$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) | |
); | |
} | |
} | |