Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Tracker;
|
||||
|
||||
use Mautic\CoreBundle\Entity\IpAddress;
|
||||
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
||||
use Mautic\CoreBundle\Helper\IpLookupHelper;
|
||||
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\LeadBundle\Entity\LeadDevice;
|
||||
use Mautic\LeadBundle\Entity\LeadRepository;
|
||||
use Mautic\LeadBundle\Event\LeadChangeEvent;
|
||||
use Mautic\LeadBundle\LeadEvents;
|
||||
use Mautic\LeadBundle\Model\FieldModel;
|
||||
use Mautic\LeadBundle\Tracker\ContactTracker;
|
||||
use Mautic\LeadBundle\Tracker\DeviceTracker;
|
||||
use Mautic\LeadBundle\Tracker\Service\ContactTrackingService\ContactTrackingServiceInterface;
|
||||
use Monolog\Logger;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
|
||||
class ContactTrackerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var MockObject|LeadRepository
|
||||
*/
|
||||
private MockObject $leadRepositoryMock;
|
||||
|
||||
/**
|
||||
* @var MockObject|ContactTrackingServiceInterface
|
||||
*/
|
||||
private MockObject $contactTrackingServiceMock;
|
||||
|
||||
/**
|
||||
* @var MockObject|DeviceTracker
|
||||
*/
|
||||
private MockObject $deviceTrackerMock;
|
||||
|
||||
/**
|
||||
* @var MockObject|CorePermissions
|
||||
*/
|
||||
private MockObject $securityMock;
|
||||
|
||||
/**
|
||||
* @var MockObject|Logger
|
||||
*/
|
||||
private MockObject $loggerMock;
|
||||
|
||||
/**
|
||||
* @var MockObject|IpLookupHelper
|
||||
*/
|
||||
private MockObject $ipLookupHelperMock;
|
||||
|
||||
private RequestStack $requestStack;
|
||||
|
||||
/**
|
||||
* @var MockObject|CoreParametersHelper
|
||||
*/
|
||||
private MockObject $coreParametersHelperMock;
|
||||
|
||||
/**
|
||||
* @var MockObject|EventDispatcher
|
||||
*/
|
||||
private MockObject $dispatcherMock;
|
||||
|
||||
/**
|
||||
* @var MockObject|FieldModel
|
||||
*/
|
||||
private MockObject $leadFieldModelMock;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->leadRepositoryMock = $this->createMock(LeadRepository::class);
|
||||
$this->contactTrackingServiceMock = $this->createMock(ContactTrackingServiceInterface::class);
|
||||
$this->deviceTrackerMock = $this->createMock(DeviceTracker::class);
|
||||
$this->securityMock = $this->createMock(CorePermissions::class);
|
||||
$this->coreParametersHelperMock = $this->createMock(CoreParametersHelper::class);
|
||||
$this->dispatcherMock = $this->createMock(EventDispatcher::class);
|
||||
$this->leadFieldModelMock = $this->createMock(FieldModel::class);
|
||||
$this->loggerMock = $this->createMock(Logger::class);
|
||||
$this->ipLookupHelperMock = $this->createMock(IpLookupHelper::class);
|
||||
$this->requestStack = new RequestStack();
|
||||
|
||||
$this->securityMock->method('isAnonymous')
|
||||
->willReturn(true);
|
||||
|
||||
$this->requestStack->push(new Request());
|
||||
}
|
||||
|
||||
public function testSystemContactIsUsedOverTrackedContact(): void
|
||||
{
|
||||
$contactTracker = $this->getContactTracker();
|
||||
|
||||
$this->leadRepositoryMock->expects($this->any())
|
||||
->method('getFieldValues')
|
||||
->willReturn([]);
|
||||
|
||||
$lead1 = new Lead();
|
||||
$lead1->setEmail('lead1@test.com');
|
||||
$contactTracker->setTrackedContact($lead1);
|
||||
$this->assertEquals($lead1->getEmail(), $contactTracker->getContact()->getEmail());
|
||||
|
||||
$lead2 = new Lead();
|
||||
$lead1->setEmail('lead2@test.com');
|
||||
$contactTracker->setSystemContact($lead2);
|
||||
$this->assertEquals($lead2->getEmail(), $contactTracker->getContact()->getEmail());
|
||||
}
|
||||
|
||||
public function testContactIsTrackedByDevice(): void
|
||||
{
|
||||
$contactTracker = $this->getContactTracker();
|
||||
|
||||
$this->leadRepositoryMock->expects($this->once())
|
||||
->method('getFieldValues')
|
||||
->willReturn(
|
||||
[
|
||||
'core' => [
|
||||
'email' => [
|
||||
'alias' => 'email',
|
||||
'type' => 'email',
|
||||
'value' => 'test@test.com',
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$device = new LeadDevice();
|
||||
$lead = new Lead();
|
||||
$device->setLead($lead);
|
||||
|
||||
$this->deviceTrackerMock->method('getTrackedDevice')
|
||||
->willReturn($device);
|
||||
|
||||
$contact = $contactTracker->getContact();
|
||||
|
||||
$this->assertEquals('test@test.com', $contact->getFieldValue('email'));
|
||||
}
|
||||
|
||||
public function testContactIsTrackedByOldCookie(): void
|
||||
{
|
||||
$contactTracker = $this->getContactTracker();
|
||||
|
||||
$this->leadRepositoryMock->expects($this->never())
|
||||
->method('getFieldValues');
|
||||
|
||||
$lead = new Lead();
|
||||
$lead->setEmail('test@test.com');
|
||||
|
||||
$this->contactTrackingServiceMock->expects($this->once())
|
||||
->method('getTrackedLead')
|
||||
->willReturn($lead);
|
||||
|
||||
$contact = $contactTracker->getContact();
|
||||
|
||||
$this->assertEquals('test@test.com', $contact->getEmail());
|
||||
}
|
||||
|
||||
public function testContactIsTrackedByIp(): void
|
||||
{
|
||||
$contactTracker = $this->getContactTracker();
|
||||
|
||||
$this->ipLookupHelperMock->expects($this->exactly(2))
|
||||
->method('getIpAddress')
|
||||
->willReturn(new IpAddress());
|
||||
|
||||
$this->leadRepositoryMock->expects($this->never())
|
||||
->method('getFieldValues');
|
||||
|
||||
$lead = new Lead();
|
||||
$lead->setEmail('test@test.com');
|
||||
|
||||
$this->contactTrackingServiceMock->expects($this->once())
|
||||
->method('getTrackedLead')
|
||||
->willReturn(null);
|
||||
|
||||
$this->coreParametersHelperMock->expects($this->any())
|
||||
->method('get')
|
||||
->willReturn(true);
|
||||
|
||||
$this->leadRepositoryMock->expects($this->once())
|
||||
->method('getLeadsByIp')
|
||||
->willReturn([$lead]);
|
||||
|
||||
$contact = $contactTracker->getContact();
|
||||
|
||||
$this->assertEquals('test@test.com', $contact->getEmail());
|
||||
}
|
||||
|
||||
public function testNewContactIsCreated(): void
|
||||
{
|
||||
$contactTracker = $this->getContactTracker();
|
||||
|
||||
$this->leadRepositoryMock->expects($this->once())
|
||||
->method('getFieldValues')
|
||||
->willReturn([]);
|
||||
|
||||
$this->ipLookupHelperMock->expects($this->exactly(2))
|
||||
->method('getIpAddress')
|
||||
->willReturn(new IpAddress());
|
||||
|
||||
$this->contactTrackingServiceMock->expects($this->once())
|
||||
->method('getTrackedLead')
|
||||
->willReturn(null);
|
||||
|
||||
$this->coreParametersHelperMock->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn(false);
|
||||
|
||||
$this->leadRepositoryMock->expects($this->never())
|
||||
->method('getLeadsByIp');
|
||||
$this->leadFieldModelMock->expects($this->any())->method('getFieldListWithProperties')->willReturn([]);
|
||||
|
||||
$contact = $contactTracker->getContact();
|
||||
$this->assertEquals(true, $contact->isNewlyCreated());
|
||||
}
|
||||
|
||||
public function testEventIsDispatchedWithChangeOfContact(): void
|
||||
{
|
||||
$contactTracker = $this->getContactTracker();
|
||||
|
||||
$device = new LeadDevice();
|
||||
$device->setTrackingId('abc123');
|
||||
|
||||
$lead = $this->createMock(Lead::class);
|
||||
$lead->method('getId')
|
||||
->willReturn(1);
|
||||
|
||||
$lead2 = $this->createMock(Lead::class);
|
||||
$lead2->method('getId')
|
||||
->willReturn(2);
|
||||
|
||||
$leadDevice1 = new LeadDevice();
|
||||
$leadDevice2 = new LeadDevice();
|
||||
|
||||
$leadDevice1->setTrackingId('abc123');
|
||||
$leadDevice2->setTrackingId('def456');
|
||||
|
||||
$this->deviceTrackerMock->method('getTrackedDevice')
|
||||
->willReturnOnConsecutiveCalls($leadDevice1, $leadDevice2, null);
|
||||
|
||||
$this->dispatcherMock->expects($this->once())
|
||||
->method('hasListeners')
|
||||
->with(LeadEvents::CURRENT_LEAD_CHANGED)
|
||||
->willReturn(true);
|
||||
|
||||
$this->dispatcherMock->expects($this->once())
|
||||
->method('dispatch')
|
||||
->with(new LeadChangeEvent($lead, 'def456', $lead2, null), LeadEvents::CURRENT_LEAD_CHANGED)
|
||||
->willReturn(new \stdClass());
|
||||
|
||||
$contactTracker->setTrackedContact($lead);
|
||||
$contactTracker->setTrackedContact($lead2);
|
||||
}
|
||||
|
||||
private function getContactTracker(): ContactTracker
|
||||
{
|
||||
return new ContactTracker(
|
||||
$this->leadRepositoryMock,
|
||||
$this->contactTrackingServiceMock,
|
||||
$this->deviceTrackerMock,
|
||||
$this->securityMock,
|
||||
$this->loggerMock,
|
||||
$this->ipLookupHelperMock,
|
||||
$this->requestStack,
|
||||
$this->coreParametersHelperMock,
|
||||
$this->dispatcherMock,
|
||||
$this->leadFieldModelMock
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Tracker;
|
||||
|
||||
use Mautic\CacheBundle\Cache\CacheProvider;
|
||||
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\LeadBundle\Entity\LeadDevice;
|
||||
use Mautic\LeadBundle\Tracker\DeviceTracker;
|
||||
use Mautic\LeadBundle\Tracker\Factory\DeviceDetectorFactory\DeviceDetectorFactory;
|
||||
use Mautic\LeadBundle\Tracker\Service\DeviceCreatorService\DeviceCreatorService;
|
||||
use Mautic\LeadBundle\Tracker\Service\DeviceTrackingService\DeviceTrackingServiceInterface;
|
||||
use Monolog\Logger;
|
||||
use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
class DeviceTrackerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private DeviceCreatorService $deviceCreatorService;
|
||||
|
||||
private DeviceDetectorFactory $deviceDetectorFactory;
|
||||
|
||||
/**
|
||||
* @var DeviceTrackingServiceInterface
|
||||
*/
|
||||
private \PHPUnit\Framework\MockObject\MockObject $deviceTrackingService;
|
||||
|
||||
/**
|
||||
* @var Logger
|
||||
*/
|
||||
private \PHPUnit\Framework\MockObject\MockObject $logger;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36';
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$createCacheItem = \Closure::bind(
|
||||
function ($key) {
|
||||
$item = new CacheItem();
|
||||
$item->key = $key;
|
||||
$item->isHit = false;
|
||||
|
||||
return $item;
|
||||
},
|
||||
$this,
|
||||
CacheItem::class
|
||||
);
|
||||
|
||||
$cacheAdapter = $this->createMock(TagAwareAdapterInterface::class);
|
||||
$cacheAdapter->expects($this->atLeastOnce())
|
||||
->method('getItem')
|
||||
->withAnyParameters()
|
||||
->willReturn($createCacheItem('test'));
|
||||
$cacheAdapter->expects($this->atLeastOnce())
|
||||
->method('save')
|
||||
->willReturn(true);
|
||||
|
||||
$coreParametersHelper = $this->createMock(CoreParametersHelper::class);
|
||||
$coreParametersHelper->expects($this->once())
|
||||
->method('get')
|
||||
->with($this->equalTo('cache_adapter'))
|
||||
->willReturn('mautic.cache.adapter.filesystem');
|
||||
|
||||
$container = $this->createMock(ContainerInterface::class);
|
||||
$container
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->with($this->equalTo('mautic.cache.adapter.filesystem'))
|
||||
->willReturn($cacheAdapter);
|
||||
|
||||
$cacheProvider = new CacheProvider($coreParametersHelper, $container);
|
||||
$this->deviceDetectorFactory = new DeviceDetectorFactory($cacheProvider);
|
||||
$this->deviceCreatorService = new DeviceCreatorService();
|
||||
$this->deviceTrackingService = $this->createMock(DeviceTrackingServiceInterface::class);
|
||||
|
||||
$this->logger = $this->createMock(Logger::class);
|
||||
}
|
||||
|
||||
public function testDeviceCreatedByUserAgent(): void
|
||||
{
|
||||
$lead = new Lead();
|
||||
$device = new LeadDevice();
|
||||
$device->setDeviceBrand('apple');
|
||||
|
||||
$this->deviceTrackingService->expects($this->once())
|
||||
->method('trackCurrentDevice')
|
||||
->willReturn($device);
|
||||
|
||||
$tracker = new DeviceTracker($this->deviceCreatorService, $this->deviceDetectorFactory, $this->deviceTrackingService, $this->logger);
|
||||
|
||||
$device = $tracker->createDeviceFromUserAgent($lead, $this->userAgent);
|
||||
$this->assertEquals('3dfc9e6dff07948058df37455718cb98', $device->getSignature());
|
||||
|
||||
// Subsequent calls should not create a new tracking ID
|
||||
$device2 = $tracker->createDeviceFromUserAgent($lead, $this->userAgent);
|
||||
$this->assertEquals($device->getTrackingId(), $device2->getTrackingId());
|
||||
$this->assertEquals('apple', $device2->getDeviceBrand());
|
||||
$this->assertEquals($device->getSignature(), $device2->getSignature());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Tracker\Service\ContactTrackingService;
|
||||
|
||||
use Mautic\CoreBundle\Helper\CookieHelper;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\LeadBundle\Entity\LeadDeviceRepository;
|
||||
use Mautic\LeadBundle\Entity\LeadRepository;
|
||||
use Mautic\LeadBundle\Entity\MergeRecordRepository;
|
||||
use Mautic\LeadBundle\Tracker\Service\ContactTrackingService\ContactTrackingService;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
|
||||
final class ContactTrackingServiceTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var MockObject|CookieHelper
|
||||
*/
|
||||
private MockObject $cookieHelperMock;
|
||||
|
||||
/**
|
||||
* @var MockObject|LeadDeviceRepository
|
||||
*/
|
||||
private MockObject $leadDeviceRepositoryMock;
|
||||
|
||||
/**
|
||||
* @var MockObject|LeadRepository
|
||||
*/
|
||||
private MockObject $leadRepositoryMock;
|
||||
|
||||
/**
|
||||
* @var MockObject|RequestStack
|
||||
*/
|
||||
private MockObject $requestStackMock;
|
||||
|
||||
/**
|
||||
* @var MockObject|MergeRecordRepository
|
||||
*/
|
||||
private MockObject $mergeRecordRepository;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->cookieHelperMock = $this->createMock(CookieHelper::class);
|
||||
$this->leadDeviceRepositoryMock = $this->createMock(LeadDeviceRepository::class);
|
||||
$this->leadRepositoryMock = $this->createMock(LeadRepository::class);
|
||||
$this->requestStackMock = $this->createMock(RequestStack::class);
|
||||
$this->mergeRecordRepository = $this->createMock(MergeRecordRepository::class);
|
||||
}
|
||||
|
||||
public function testGetTrackedIdentifier(): void
|
||||
{
|
||||
$trackingId = 'randomTrackingId';
|
||||
|
||||
$this->cookieHelperMock->expects($this->once())
|
||||
->method('getCookie')
|
||||
->with('mautic_session_id', null)
|
||||
->willReturn($trackingId);
|
||||
|
||||
$contactTrackingService = $this->getContactTrackingService();
|
||||
$this->assertSame($trackingId, $contactTrackingService->getTrackedIdentifier());
|
||||
}
|
||||
|
||||
public function testGetTrackedLeadNoRequest(): void
|
||||
{
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn(null);
|
||||
|
||||
$contactTrackingService = $this->getContactTrackingService();
|
||||
$this->assertNull($contactTrackingService->getTrackedLead());
|
||||
}
|
||||
|
||||
public function testGetTrackedLeadNoTrackedIdentifier(): void
|
||||
{
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
|
||||
$this->cookieHelperMock->expects($this->once())
|
||||
->method('getCookie')
|
||||
->with('mautic_session_id', null)
|
||||
->willReturn(null);
|
||||
|
||||
$contactTrackingService = $this->getContactTrackingService();
|
||||
$this->assertNull($contactTrackingService->getTrackedLead());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test no lead id found.
|
||||
*/
|
||||
public function testGetTrackedLeadNoLeadId(): void
|
||||
{
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
$trackingId = 'randomTrackingId';
|
||||
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
$matcher = $this->exactly(2);
|
||||
|
||||
$this->cookieHelperMock->expects($matcher)
|
||||
->method('getCookie')->willReturnCallback(function (...$parameters) use ($matcher, $trackingId) {
|
||||
if (1 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame('mautic_session_id', $parameters[0]);
|
||||
$this->assertNull($parameters[1]);
|
||||
|
||||
return $trackingId;
|
||||
}
|
||||
if (2 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame($trackingId, $parameters[0]);
|
||||
$this->assertNull($parameters[1]);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
$requestMock->expects($this->once())
|
||||
->method('get')
|
||||
->with('mtc_id', null)
|
||||
->willReturn(null);
|
||||
|
||||
$contactTrackingService = $this->getContactTrackingService();
|
||||
$this->assertNull($contactTrackingService->getTrackedLead());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test lead id found in request but no lead entity found.
|
||||
*/
|
||||
public function testGetTrackedLeadRequestLeadIdAndNoLeadFound(): void
|
||||
{
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
$trackingId = 'randomTrackingId';
|
||||
$leadId = 1;
|
||||
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
$matcher = $this->exactly(2);
|
||||
|
||||
$this->cookieHelperMock->expects($matcher)
|
||||
->method('getCookie')->willReturnCallback(function (...$parameters) use ($matcher, $trackingId) {
|
||||
if (1 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame('mautic_session_id', $parameters[0]);
|
||||
$this->assertNull($parameters[1]);
|
||||
|
||||
return $trackingId;
|
||||
}
|
||||
if (2 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame($trackingId, $parameters[0]);
|
||||
$this->assertNull($parameters[1]);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
$requestMock->expects($this->once())
|
||||
->method('get')
|
||||
->with('mtc_id', null)
|
||||
->willReturn($leadId);
|
||||
|
||||
$this->leadRepositoryMock->expects($this->once())
|
||||
->method('getEntity')
|
||||
->with($leadId)
|
||||
->willReturn(null);
|
||||
|
||||
$contactTrackingService = $this->getContactTrackingService();
|
||||
$this->assertNull($contactTrackingService->getTrackedLead());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test lead id found in request and another device is already tracked and associated with lead.
|
||||
*/
|
||||
public function testGetTrackedLeadRequestLeadIdAndAnotherDeviceAlreadyTracked(): void
|
||||
{
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
$trackingId = 'randomTrackingId';
|
||||
$leadId = 1;
|
||||
$leadMock = $this->createMock(Lead::class);
|
||||
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
$matcher = $this->exactly(2);
|
||||
|
||||
$this->cookieHelperMock->expects($matcher)
|
||||
->method('getCookie')->willReturnCallback(function (...$parameters) use ($matcher, $trackingId) {
|
||||
if (1 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame('mautic_session_id', $parameters[0]);
|
||||
$this->assertNull($parameters[1]);
|
||||
|
||||
return $trackingId;
|
||||
}
|
||||
if (2 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame($trackingId, $parameters[0]);
|
||||
$this->assertNull($parameters[1]);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
$requestMock->expects($this->once())
|
||||
->method('get')
|
||||
->with('mtc_id', null)
|
||||
->willReturn($leadId);
|
||||
|
||||
$this->leadRepositoryMock->expects($this->once())
|
||||
->method('getEntity')
|
||||
->with($leadId)
|
||||
->willReturn($leadMock);
|
||||
|
||||
$this->leadDeviceRepositoryMock->expects($this->once())
|
||||
->method('isAnyLeadDeviceTracked')
|
||||
->with($leadMock)
|
||||
->willReturn(true);
|
||||
|
||||
$contactTrackingService = $this->getContactTrackingService();
|
||||
$this->assertNull($contactTrackingService->getTrackedLead());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test lead id found in request and another device is not tracked and associated with lead.
|
||||
*/
|
||||
public function testGetTrackedLeadRequestLeadIdAndAnotherDeviceNotTracked(): void
|
||||
{
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
$trackingId = 'randomTrackingId';
|
||||
$leadId = 1;
|
||||
$leadMock = $this->createMock(Lead::class);
|
||||
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
$matcher = $this->exactly(2);
|
||||
|
||||
$this->cookieHelperMock->expects($matcher)
|
||||
->method('getCookie')->willReturnCallback(function (...$parameters) use ($matcher, $trackingId) {
|
||||
if (1 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame('mautic_session_id', $parameters[0]);
|
||||
$this->assertNull($parameters[1]);
|
||||
|
||||
return $trackingId;
|
||||
}
|
||||
if (2 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame($trackingId, $parameters[0]);
|
||||
$this->assertNull($parameters[1]);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
$requestMock->expects($this->once())
|
||||
->method('get')
|
||||
->with('mtc_id', null)
|
||||
->willReturn($leadId);
|
||||
|
||||
$this->leadRepositoryMock->expects($this->once())
|
||||
->method('getEntity')
|
||||
->with($leadId)
|
||||
->willReturn($leadMock);
|
||||
|
||||
$this->leadDeviceRepositoryMock->expects($this->once())
|
||||
->method('isAnyLeadDeviceTracked')
|
||||
->with($leadMock)
|
||||
->willReturn(false);
|
||||
|
||||
$contactTrackingService = $this->getContactTrackingService();
|
||||
$this->assertSame($leadMock, $contactTrackingService->getTrackedLead());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test lead id found in request and another device is not tracked and associated with lead.
|
||||
*/
|
||||
public function testGetTrackedLeadCookieLeadIdAndAnotherDeviceNotTracked(): void
|
||||
{
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
$trackingId = 'randomTrackingId';
|
||||
$leadId = 1;
|
||||
$leadMock = $this->createMock(Lead::class);
|
||||
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
$matcher = $this->exactly(2);
|
||||
|
||||
$this->cookieHelperMock->expects($matcher)
|
||||
->method('getCookie')->willReturnCallback(function (...$parameters) use ($matcher, $trackingId, $leadId) {
|
||||
if (1 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame('mautic_session_id', $parameters[0]);
|
||||
$this->assertNull($parameters[1]);
|
||||
|
||||
return $trackingId;
|
||||
}
|
||||
if (2 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame($trackingId, $parameters[0]);
|
||||
$this->assertNull($parameters[1]);
|
||||
|
||||
return $leadId;
|
||||
}
|
||||
});
|
||||
|
||||
$this->leadRepositoryMock->expects($this->once())
|
||||
->method('getEntity')
|
||||
->with($leadId)
|
||||
->willReturn($leadMock);
|
||||
|
||||
$this->leadDeviceRepositoryMock->expects($this->once())
|
||||
->method('isAnyLeadDeviceTracked')
|
||||
->with($leadMock)
|
||||
->willReturn(false);
|
||||
|
||||
$contactTrackingService = $this->getContactTrackingService();
|
||||
$this->assertSame($leadMock, $contactTrackingService->getTrackedLead());
|
||||
}
|
||||
|
||||
private function getContactTrackingService(): ContactTrackingService
|
||||
{
|
||||
return new ContactTrackingService(
|
||||
$this->cookieHelperMock,
|
||||
$this->leadDeviceRepositoryMock,
|
||||
$this->leadRepositoryMock,
|
||||
$this->mergeRecordRepository,
|
||||
$this->requestStackMock
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,383 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Tracker\Service\DeviceTrackingService;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Mautic\CoreBundle\Helper\CookieHelper;
|
||||
use Mautic\CoreBundle\Helper\RandomHelper\RandomHelperInterface;
|
||||
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\LeadBundle\Entity\LeadDevice;
|
||||
use Mautic\LeadBundle\Entity\LeadDeviceRepository;
|
||||
use Mautic\LeadBundle\Tracker\Service\DeviceTrackingService\DeviceTrackingService;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
|
||||
final class DeviceTrackingServiceTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \PHPUnit\Framework\MockObject\MockObject $cookieHelperMock;
|
||||
|
||||
private \PHPUnit\Framework\MockObject\MockObject $entityManagerMock;
|
||||
|
||||
private \PHPUnit\Framework\MockObject\MockObject $randomHelperMock;
|
||||
|
||||
private \PHPUnit\Framework\MockObject\MockObject $leadDeviceRepositoryMock;
|
||||
|
||||
private \PHPUnit\Framework\MockObject\MockObject $requestStackMock;
|
||||
|
||||
private \PHPUnit\Framework\MockObject\MockObject $security;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->cookieHelperMock = $this->createMock(CookieHelper::class);
|
||||
$this->entityManagerMock = $this->createMock(EntityManagerInterface::class);
|
||||
$this->randomHelperMock = $this->createMock(RandomHelperInterface::class);
|
||||
$this->leadDeviceRepositoryMock = $this->createMock(LeadDeviceRepository::class);
|
||||
$this->requestStackMock = $this->createMock(RequestStack::class);
|
||||
$this->security = $this->createMock(CorePermissions::class);
|
||||
}
|
||||
|
||||
public function testIsTrackedTrue(): void
|
||||
{
|
||||
$trackingId = 'randomTrackingId';
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
|
||||
$this->cookieHelperMock->expects($this->once())
|
||||
->method('getCookie')
|
||||
->with('mautic_device_id', null)
|
||||
->willReturn($trackingId);
|
||||
$leadDeviceMock = $this->createMock(LeadDevice::class);
|
||||
|
||||
$this->security->expects($this->once())
|
||||
->method('isAnonymous')
|
||||
->willReturn(true);
|
||||
|
||||
$this->leadDeviceRepositoryMock->expects($this->once())
|
||||
->method('getByTrackingId')
|
||||
->with($trackingId)
|
||||
->willReturn($leadDeviceMock);
|
||||
|
||||
$this->assertTrue($this->getDeviceTrackingService()->isTracked());
|
||||
}
|
||||
|
||||
public function testIsTrackedFalse(): void
|
||||
{
|
||||
$trackingId = 'randomTrackingId';
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
|
||||
$this->cookieHelperMock->expects($this->once())
|
||||
->method('getCookie')
|
||||
->with('mautic_device_id', null)
|
||||
->willReturn($trackingId);
|
||||
|
||||
$this->security->expects($this->once())
|
||||
->method('isAnonymous')
|
||||
->willReturn(true);
|
||||
|
||||
$this->leadDeviceRepositoryMock->expects($this->once())
|
||||
->method('getByTrackingId')
|
||||
->with($trackingId)
|
||||
->willReturn(null);
|
||||
|
||||
$this->assertFalse($this->getDeviceTrackingService()->isTracked());
|
||||
}
|
||||
|
||||
public function testGetTrackedDeviceCookie(): void
|
||||
{
|
||||
$trackingId = 'randomTrackingId';
|
||||
$leadDeviceMock = $this->createMock(LeadDevice::class);
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
|
||||
$this->cookieHelperMock->expects($this->once())
|
||||
->method('getCookie')
|
||||
->with('mautic_device_id', null)
|
||||
->willReturn($trackingId);
|
||||
|
||||
$this->security->expects($this->once())
|
||||
->method('isAnonymous')
|
||||
->willReturn(true);
|
||||
|
||||
$this->leadDeviceRepositoryMock->expects($this->once())
|
||||
->method('getByTrackingId')
|
||||
->with($trackingId)
|
||||
->willReturn($leadDeviceMock);
|
||||
|
||||
$this->assertSame($leadDeviceMock, $this->getDeviceTrackingService()->getTrackedDevice());
|
||||
}
|
||||
|
||||
public function testGetTrackedDeviceGetFromRequest(): void
|
||||
{
|
||||
$trackingId = 'randomTrackingId';
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
$leadDeviceMock = $this->createMock(LeadDevice::class);
|
||||
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
|
||||
$this->cookieHelperMock->expects($this->once())
|
||||
->method('getCookie')
|
||||
->with('mautic_device_id', null)
|
||||
->willReturn(null);
|
||||
|
||||
$requestMock->expects($this->once())
|
||||
->method('get')
|
||||
->with('mautic_device_id', null)
|
||||
->willReturn($trackingId);
|
||||
|
||||
$this->security->expects($this->once())
|
||||
->method('isAnonymous')
|
||||
->willReturn(true);
|
||||
|
||||
$this->leadDeviceRepositoryMock->expects($this->once())
|
||||
->method('getByTrackingId')
|
||||
->with($trackingId)
|
||||
->willReturn($leadDeviceMock);
|
||||
|
||||
$this->assertSame($leadDeviceMock, $this->getDeviceTrackingService()->getTrackedDevice());
|
||||
}
|
||||
|
||||
public function testGetTrackedDeviceNoTrackingId(): void
|
||||
{
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
|
||||
$this->cookieHelperMock->expects($this->once())
|
||||
->method('getCookie')
|
||||
->with('mautic_device_id', null)
|
||||
->willReturn(null);
|
||||
|
||||
$requestMock->expects($this->once())
|
||||
->method('get')
|
||||
->with('mautic_device_id', null)
|
||||
->willReturn(null);
|
||||
|
||||
$this->security->expects($this->once())
|
||||
->method('isAnonymous')
|
||||
->willReturn(true);
|
||||
|
||||
$this->leadDeviceRepositoryMock->expects($this->never())
|
||||
->method('getByTrackingId');
|
||||
|
||||
$this->assertNull($this->getDeviceTrackingService()->getTrackedDevice());
|
||||
}
|
||||
|
||||
public function testGetTrackedDeviceNoRequest(): void
|
||||
{
|
||||
$deviceTrackingService = $this->getDeviceTrackingService();
|
||||
$this->assertNull($deviceTrackingService->getTrackedDevice());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test tracking device with already tracked current device.
|
||||
*/
|
||||
public function testTrackCurrentDeviceAlreadyTracked(): void
|
||||
{
|
||||
$leadDeviceMock = $this->createMock(LeadDevice::class);
|
||||
$trackingId = 'randomTrackingId';
|
||||
$trackedLeadDeviceMock = $this->createMock(LeadDevice::class);
|
||||
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
|
||||
$this->cookieHelperMock->expects($this->once())
|
||||
->method('getCookie')
|
||||
->with('mautic_device_id', null)
|
||||
->willReturn($trackingId);
|
||||
|
||||
$this->security->expects($this->once())
|
||||
->method('isAnonymous')
|
||||
->willReturn(true);
|
||||
|
||||
$this->leadDeviceRepositoryMock->expects($this->once())
|
||||
->method('getByTrackingId')
|
||||
->with($trackingId)
|
||||
->willReturn($trackedLeadDeviceMock);
|
||||
|
||||
$deviceTrackingService = $this->getDeviceTrackingService();
|
||||
|
||||
$deviceTrackingService->trackCurrentDevice($leadDeviceMock, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test tracking device with already tracked current device, replace existing tracking.
|
||||
*/
|
||||
public function testTrackCurrentDeviceAlreadyTrackedReplaceExistingTracking(): void
|
||||
{
|
||||
$leadDeviceMock = $this->createMock(LeadDevice::class);
|
||||
$trackedLeadDeviceMock = $this->createMock(LeadDevice::class);
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
$trackingId = 'randomTrackingId';
|
||||
$uniqueTrackingIdentifier = '1234567890abcdefghij123';
|
||||
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
|
||||
$this->cookieHelperMock->expects($this->once())
|
||||
->method('getCookie')
|
||||
->with('mautic_device_id', null)
|
||||
->willReturn($trackingId);
|
||||
|
||||
$this->security->expects($this->once())
|
||||
->method('isAnonymous')
|
||||
->willReturn(true);
|
||||
$matcher = $this->any();
|
||||
|
||||
$this->leadDeviceRepositoryMock->expects($matcher)->method('getByTrackingId')
|
||||
->willReturnCallback(function (...$parameters) use ($matcher, $trackingId, $trackedLeadDeviceMock) {
|
||||
if (1 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame($trackingId, $parameters[0]);
|
||||
|
||||
return $trackedLeadDeviceMock;
|
||||
}
|
||||
});
|
||||
|
||||
$this->randomHelperMock->expects($this->once())
|
||||
->method('generate')
|
||||
->with(23)
|
||||
->willReturn($uniqueTrackingIdentifier);
|
||||
|
||||
$this->entityManagerMock->expects($this->once())
|
||||
->method('persist')
|
||||
->with($leadDeviceMock);
|
||||
|
||||
// index 0-3 for leadDeviceRepository::findOneBy
|
||||
$leadDeviceMock->method('getTrackingId')
|
||||
->willReturnOnConsecutiveCalls(null, $uniqueTrackingIdentifier);
|
||||
|
||||
$leadDeviceMock->expects($this->once())
|
||||
->method('setTrackingId')
|
||||
->with($uniqueTrackingIdentifier)
|
||||
->willReturn($leadDeviceMock);
|
||||
|
||||
$leadDeviceMock->expects($this->once())
|
||||
->method('getLead')
|
||||
->willReturn(new Lead());
|
||||
$matcher = $this->any();
|
||||
|
||||
$this->cookieHelperMock->expects($matcher)->method('setCookie')
|
||||
->willReturnCallback(function (...$parameters) use ($matcher, $uniqueTrackingIdentifier) {
|
||||
if (1 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame('mautic_device_id', $parameters[0]);
|
||||
$this->assertSame($uniqueTrackingIdentifier, $parameters[1]);
|
||||
$this->assertSame(31_536_000, $parameters[2]);
|
||||
}
|
||||
});
|
||||
|
||||
$deviceTrackingService = $this->getDeviceTrackingService();
|
||||
$deviceTrackingService->trackCurrentDevice($leadDeviceMock, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test tracking device without already tracked current device.
|
||||
*/
|
||||
public function testTrackCurrentDeviceNotTrackedYet(): void
|
||||
{
|
||||
$leadDeviceMock = $this->createMock(LeadDevice::class);
|
||||
$uniqueTrackingIdentifier = '1234567890abcdefghij123';
|
||||
$requestMock = $this->createMock(Request::class);
|
||||
|
||||
$this->requestStackMock->expects($this->once())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($requestMock);
|
||||
|
||||
$this->cookieHelperMock->expects($this->once())
|
||||
->method('getCookie')
|
||||
->with('mautic_device_id', null)
|
||||
->willReturn(null);
|
||||
|
||||
$requestMock->expects($this->once())
|
||||
->method('get')
|
||||
->with('mautic_device_id', null)
|
||||
->willReturn(null);
|
||||
|
||||
$this->randomHelperMock->expects($this->once())
|
||||
->method('generate')
|
||||
->with(23)
|
||||
->willReturn($uniqueTrackingIdentifier);
|
||||
|
||||
$this->security->expects($this->once())
|
||||
->method('isAnonymous')
|
||||
->willReturn(true);
|
||||
|
||||
// index 0-3 for leadDeviceRepository::findOneBy
|
||||
$leadDeviceMock->method('getTrackingId')
|
||||
->willReturnOnConsecutiveCalls(null, $uniqueTrackingIdentifier);
|
||||
|
||||
$leadDeviceMock->expects($this->once())
|
||||
->method('setTrackingId')
|
||||
->with($uniqueTrackingIdentifier)
|
||||
->willReturn($leadDeviceMock);
|
||||
|
||||
$leadDeviceMock->expects($this->once())
|
||||
->method('getLead')
|
||||
->willReturn(new Lead());
|
||||
|
||||
$matcher = $this->any();
|
||||
$this->cookieHelperMock->expects($matcher)->method('setCookie')
|
||||
->willReturnCallback(function (...$parameters) use ($matcher, $uniqueTrackingIdentifier) {
|
||||
if (1 === $matcher->numberOfInvocations()) {
|
||||
$this->assertSame('mautic_device_id', $parameters[0]);
|
||||
$this->assertSame($uniqueTrackingIdentifier, $parameters[1]);
|
||||
$this->assertSame(31_536_000, $parameters[2]);
|
||||
}
|
||||
});
|
||||
|
||||
$this->entityManagerMock->expects($this->once())
|
||||
->method('persist')
|
||||
->with($leadDeviceMock);
|
||||
|
||||
$this->entityManagerMock->expects($this->once())
|
||||
->method('flush');
|
||||
|
||||
$deviceTrackingService = $this->getDeviceTrackingService();
|
||||
$deviceTrackingService->trackCurrentDevice($leadDeviceMock, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a user is not tracked.
|
||||
*/
|
||||
public function testUserIsNotTracked(): void
|
||||
{
|
||||
$this->leadDeviceRepositoryMock->expects($this->never())
|
||||
->method('getByTrackingId');
|
||||
|
||||
$this->security->expects($this->once())
|
||||
->method('isAnonymous')
|
||||
->willReturn(false);
|
||||
|
||||
$this->getDeviceTrackingService()->getTrackedDevice();
|
||||
}
|
||||
|
||||
private function getDeviceTrackingService(): DeviceTrackingService
|
||||
{
|
||||
return new DeviceTrackingService(
|
||||
$this->cookieHelperMock,
|
||||
$this->entityManagerMock,
|
||||
$this->leadDeviceRepositoryMock,
|
||||
$this->randomHelperMock,
|
||||
$this->requestStackMock,
|
||||
$this->security
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user