Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\CampaignBundle\Tests\Model;
|
||||
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\ORM\Exception\ORMException;
|
||||
use Doctrine\ORM\OptimisticLockException;
|
||||
use Mautic\CampaignBundle\Entity\Campaign;
|
||||
use Mautic\CampaignBundle\Entity\Event;
|
||||
use Mautic\CampaignBundle\Entity\Lead as CampaignLead;
|
||||
use Mautic\CampaignBundle\Model\CampaignModel;
|
||||
use Mautic\CoreBundle\Entity\IpAddress;
|
||||
use Mautic\CoreBundle\Test\MauticMysqlTestCase;
|
||||
use Mautic\EmailBundle\Entity\Email;
|
||||
use Mautic\EmailBundle\Entity\Stat;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\PageBundle\Entity\Hit;
|
||||
use Mautic\PageBundle\Entity\Redirect;
|
||||
use Mautic\PageBundle\Entity\Trackable;
|
||||
|
||||
class CampaignModelFunctionalTest extends MauticMysqlTestCase
|
||||
{
|
||||
/**
|
||||
* @throws OptimisticLockException
|
||||
* @throws ORMException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testGetEmailsCountryStats(): void
|
||||
{
|
||||
/** @var CampaignModel $model */
|
||||
$model = $this->getContainer()->get('mautic.campaign.model.campaign');
|
||||
|
||||
$dateFrom = new \DateTimeImmutable('2023-07-21');
|
||||
$dateTo = new \DateTimeImmutable('2023-07-24');
|
||||
$leadsPayload = [
|
||||
[
|
||||
'email' => 'example1@test.com',
|
||||
'country' => 'Spain',
|
||||
'read' => true,
|
||||
'click' => true,
|
||||
],
|
||||
[
|
||||
'email' => 'example2@test.com',
|
||||
'country' => 'Spain',
|
||||
'read' => true,
|
||||
'click' => false,
|
||||
],
|
||||
[
|
||||
'email' => 'example3@test.com',
|
||||
'country' => 'Spain',
|
||||
'read' => false,
|
||||
'click' => false,
|
||||
],
|
||||
[
|
||||
'email' => 'example4@test.com',
|
||||
'country' => '',
|
||||
'read' => true,
|
||||
'click' => true,
|
||||
],
|
||||
[
|
||||
'email' => 'example5@test.com',
|
||||
'country' => 'Poland',
|
||||
'read' => true,
|
||||
'click' => false,
|
||||
],
|
||||
[
|
||||
'email' => 'example6@test.com',
|
||||
'country' => 'Poland',
|
||||
'read' => true,
|
||||
'click' => true,
|
||||
],
|
||||
];
|
||||
|
||||
// Create test campaign
|
||||
$campaign = new Campaign();
|
||||
$campaign->setName('Test campaign');
|
||||
$this->em->persist($campaign);
|
||||
$this->em->flush();
|
||||
|
||||
foreach ($leadsPayload as $key => $values) {
|
||||
// Create lead
|
||||
$lead = new Lead();
|
||||
$lead->setEmail($values['email']);
|
||||
$lead->setCountry($values['country']);
|
||||
$this->em->persist($lead);
|
||||
|
||||
$leadsArr[] = [
|
||||
'lead' => $lead,
|
||||
'read' => $values['read'],
|
||||
'click' => $values['click'],
|
||||
];
|
||||
|
||||
// Create campaign lead and assign to lead
|
||||
$campaignLead = new CampaignLead();
|
||||
$campaignLead->setLead($lead);
|
||||
$campaignLead->setDateAdded(new \DateTime('2023-07-22'));
|
||||
$campaignLead->setManuallyAdded(true);
|
||||
$campaignLead->setCampaign($campaign);
|
||||
$this->em->persist($campaignLead);
|
||||
$this->em->flush();
|
||||
|
||||
$campaign->addLead($key, $campaignLead);
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 4; ++$i) {
|
||||
// Create email
|
||||
$email = new Email();
|
||||
$email->setName('Test email '.$i);
|
||||
$this->em->persist($email);
|
||||
$this->em->flush();
|
||||
|
||||
// Create email events
|
||||
$event = new Event();
|
||||
$event->setName('Send email '.$i);
|
||||
$event->setType('email.send');
|
||||
$event->setEventType('action');
|
||||
$event->setChannel('email');
|
||||
$event->setChannelId($email->getId());
|
||||
$event->setCampaign($campaign);
|
||||
$this->em->persist($event);
|
||||
$this->em->flush();
|
||||
|
||||
// Add events to campaign
|
||||
$campaign->addEvent($i, $event);
|
||||
|
||||
// Create campaign email sending statistics
|
||||
foreach ($leadsArr as $value) {
|
||||
$this->emulateEmailStat($value['lead'], $email, $value['read'], $event->getId());
|
||||
|
||||
if ($value['read'] && $value['click']) {
|
||||
$hits = rand(1, 5);
|
||||
$uniqueHits = rand(1, $hits);
|
||||
$this->emulateClick($value['lead'], $email, $hits, $uniqueHits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$results = $model->getCountryStats($campaign, $dateFrom, $dateTo);
|
||||
|
||||
$this->assertCount(4, $campaign->getEmailSendEvents());
|
||||
$this->assertCount(3, $results);
|
||||
$this->assertSame([
|
||||
'contacts' => [
|
||||
[
|
||||
'country' => '',
|
||||
'contacts' => '1',
|
||||
],
|
||||
[
|
||||
'country' => 'Poland',
|
||||
'contacts' => '2',
|
||||
],
|
||||
[
|
||||
'country' => 'Spain',
|
||||
'contacts' => '3',
|
||||
],
|
||||
],
|
||||
'clicked_through_count' => [
|
||||
[
|
||||
'clicked_through_count' => '4',
|
||||
'country' => '',
|
||||
],
|
||||
[
|
||||
'clicked_through_count' => '4',
|
||||
'country' => 'Poland',
|
||||
],
|
||||
[
|
||||
'clicked_through_count' => '4',
|
||||
'country' => 'Spain',
|
||||
],
|
||||
],
|
||||
'read_count' => [
|
||||
[
|
||||
'read_count' => '4',
|
||||
'country' => '',
|
||||
],
|
||||
[
|
||||
'read_count' => '8',
|
||||
'country' => 'Poland',
|
||||
],
|
||||
[
|
||||
'read_count' => '8',
|
||||
'country' => 'Spain',
|
||||
],
|
||||
],
|
||||
], $results);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws OptimisticLockException
|
||||
* @throws ORMException
|
||||
*/
|
||||
public function testGetContextEntity(): void
|
||||
{
|
||||
/** @var CampaignModel $model */
|
||||
$model = $this->getContainer()->get('mautic.campaign.model.campaign');
|
||||
|
||||
$campaign = new Campaign();
|
||||
$campaign->setName('Test email');
|
||||
$this->em->persist($campaign);
|
||||
$this->em->flush();
|
||||
|
||||
$id = $campaign->getId();
|
||||
$result = $model->getEntity($id);
|
||||
|
||||
$this->assertSame($campaign, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws OptimisticLockException
|
||||
* @throws ORMException
|
||||
*/
|
||||
private function emulateEmailStat(Lead $lead, Email $email, bool $isRead, int $sourceId): void
|
||||
{
|
||||
$stat = new Stat();
|
||||
$stat->setEmailAddress('test@test.com');
|
||||
$stat->setLead($lead);
|
||||
$stat->setDateSent(new \DateTime('2023-07-22'));
|
||||
$stat->setEmail($email);
|
||||
$stat->setIsRead($isRead);
|
||||
$stat->setSource('campaign.event');
|
||||
$stat->setSourceId($sourceId);
|
||||
$this->em->persist($stat);
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws OptimisticLockException
|
||||
* @throws ORMException
|
||||
*/
|
||||
private function emulateClick(Lead $lead, Email $email, int $hits, int $uniqueHits): void
|
||||
{
|
||||
$ipAddress = new IpAddress();
|
||||
$ipAddress->setIpAddress('127.0.0.1');
|
||||
$this->em->persist($ipAddress);
|
||||
$this->em->flush();
|
||||
|
||||
$redirect = new Redirect();
|
||||
$redirect->setRedirectId(uniqid());
|
||||
$redirect->setUrl('https://example.com');
|
||||
$redirect->setUniqueHits($uniqueHits);
|
||||
$redirect->setHits($hits);
|
||||
$this->em->persist($redirect);
|
||||
|
||||
$trackable = new Trackable();
|
||||
$trackable->setChannelId($email->getId());
|
||||
$trackable->setHits($hits);
|
||||
$trackable->setChannel('email');
|
||||
$trackable->setUniqueHits($uniqueHits);
|
||||
$trackable->setRedirect($redirect);
|
||||
$this->em->persist($trackable);
|
||||
|
||||
$pageHit = new Hit();
|
||||
$pageHit->setRedirect($redirect);
|
||||
$pageHit->setIpAddress($ipAddress);
|
||||
$pageHit->setEmail($email);
|
||||
$pageHit->setLead($lead);
|
||||
$pageHit->setDateHit(new \DateTime('2023-07-22'));
|
||||
$pageHit->setCode(200);
|
||||
$pageHit->setUrl($redirect->getUrl());
|
||||
$pageHit->setTrackingId($redirect->getRedirectId());
|
||||
$pageHit->setSource('email');
|
||||
$pageHit->setSourceId($email->getId());
|
||||
$this->em->persist($pageHit);
|
||||
$this->em->flush();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\CampaignBundle\Tests\Model;
|
||||
|
||||
use Mautic\CampaignBundle\Tests\CampaignTestAbstract;
|
||||
|
||||
class CampaignModelTest extends CampaignTestAbstract
|
||||
{
|
||||
public function testGetSourceListsWithNull(): void
|
||||
{
|
||||
$model = $this->initCampaignModel();
|
||||
$lists = $model->getSourceLists();
|
||||
$this->assertTrue(isset($lists['lists']));
|
||||
$this->assertSame([parent::$mockId => parent::$mockName], $lists['lists']);
|
||||
$this->assertTrue(isset($lists['forms']));
|
||||
$this->assertSame([parent::$mockId => parent::$mockName], $lists['forms']);
|
||||
}
|
||||
|
||||
public function testGetSourceListsWithLists(): void
|
||||
{
|
||||
$model = $this->initCampaignModel();
|
||||
$lists = $model->getSourceLists('lists');
|
||||
$this->assertSame([parent::$mockId => parent::$mockName], $lists);
|
||||
}
|
||||
|
||||
public function testGetSourceListsWithForms(): void
|
||||
{
|
||||
$model = $this->initCampaignModel();
|
||||
$lists = $model->getSourceLists('forms');
|
||||
$this->assertSame([parent::$mockId => parent::$mockName], $lists);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\CampaignBundle\Tests\Model;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Mautic\CampaignBundle\Entity\Campaign;
|
||||
use Mautic\CampaignBundle\Entity\CampaignRepository;
|
||||
use Mautic\CampaignBundle\EventCollector\EventCollector;
|
||||
use Mautic\CampaignBundle\Membership\MembershipBuilder;
|
||||
use Mautic\CampaignBundle\Model\CampaignModel;
|
||||
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
||||
use Mautic\CoreBundle\Helper\UserHelper;
|
||||
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
|
||||
use Mautic\CoreBundle\Translation\Translator;
|
||||
use Mautic\FormBundle\Model\FormModel;
|
||||
use Mautic\LeadBundle\Model\ListModel;
|
||||
use Mautic\LeadBundle\Tracker\ContactTracker;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
|
||||
class CampaignModelTransactionalTest extends TestCase
|
||||
{
|
||||
private MockObject $entityManagerMock;
|
||||
private MockObject $connectionMock;
|
||||
private MockObject $userHelperMock;
|
||||
private MockObject $campaignRepositoryMock;
|
||||
private MockObject $campaignModel;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->connectionMock = $this->createMock(Connection::class);
|
||||
|
||||
// Create repository mock
|
||||
$this->campaignRepositoryMock = $this->createMock(CampaignRepository::class);
|
||||
$this->campaignRepositoryMock->method('setCurrentUser')
|
||||
->willReturnSelf();
|
||||
|
||||
$this->entityManagerMock = $this->createMock(EntityManager::class);
|
||||
$this->entityManagerMock->method('getConnection')
|
||||
->willReturn($this->connectionMock);
|
||||
|
||||
$this->entityManagerMock->method('getRepository')
|
||||
->with(Campaign::class)
|
||||
->willReturn($this->campaignRepositoryMock);
|
||||
|
||||
// Mock user helper
|
||||
$this->userHelperMock = $this->createMock(UserHelper::class);
|
||||
|
||||
// Create all the required dependencies as mocks
|
||||
$leadListModel = $this->createMock(ListModel::class);
|
||||
$formModel = $this->createMock(FormModel::class);
|
||||
$eventCollector = $this->createMock(EventCollector::class);
|
||||
$membershipBuilder = $this->createMock(MembershipBuilder::class);
|
||||
$contactTracker = $this->createMock(ContactTracker::class);
|
||||
$security = $this->createMock(CorePermissions::class);
|
||||
$dispatcher = $this->createMock(EventDispatcherInterface::class);
|
||||
$router = $this->createMock(UrlGeneratorInterface::class);
|
||||
$translator = $this->createMock(Translator::class);
|
||||
$logger = $this->createMock(LoggerInterface::class);
|
||||
$coreParametersHelper = $this->createMock(CoreParametersHelper::class);
|
||||
|
||||
// Create the campaign model mock
|
||||
$this->campaignModel = $this->getMockBuilder(CampaignModel::class)
|
||||
->setConstructorArgs([
|
||||
$leadListModel,
|
||||
$formModel,
|
||||
$eventCollector,
|
||||
$membershipBuilder,
|
||||
$contactTracker,
|
||||
$this->entityManagerMock,
|
||||
$security,
|
||||
$dispatcher,
|
||||
$router,
|
||||
$translator,
|
||||
$this->userHelperMock,
|
||||
$logger,
|
||||
$coreParametersHelper,
|
||||
])
|
||||
->onlyMethods(['saveEntity'])
|
||||
->getMock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to set up common campaign mock expectations for unpublish tests.
|
||||
*
|
||||
* @param int $campaignId The campaign ID to use
|
||||
* @param int $version The campaign version to use
|
||||
* @param bool $isPublished The current published state
|
||||
*
|
||||
* @return MockObject&Campaign The configured campaign mock
|
||||
*/
|
||||
private function createCampaignMockForUnpublish(
|
||||
int $campaignId = 5,
|
||||
int $version = 1,
|
||||
bool $isPublished = true,
|
||||
): MockObject&Campaign {
|
||||
/** @var MockObject&Campaign $campaignMock */
|
||||
$campaignMock = $this->createMock(Campaign::class);
|
||||
|
||||
$campaignMock->expects($this->once())
|
||||
->method('getId')
|
||||
->willReturn($campaignId);
|
||||
|
||||
// Mock version data from repository
|
||||
$this->campaignRepositoryMock->expects($this->once())
|
||||
->method('getCampaignPublishAndVersionData')
|
||||
->with($campaignId)
|
||||
->willReturn([
|
||||
'is_published' => $isPublished ? 1 : 0,
|
||||
'version' => $version,
|
||||
]);
|
||||
|
||||
$campaignMock->expects($this->once())
|
||||
->method('getVersion')
|
||||
->willReturn($version);
|
||||
|
||||
// Setting published flag
|
||||
$campaignMock->expects($this->once())
|
||||
->method('setIsPublished')
|
||||
->with(false);
|
||||
|
||||
$campaignMock->expects($this->once())
|
||||
->method('markForVersionIncrement');
|
||||
|
||||
return $campaignMock;
|
||||
}
|
||||
|
||||
public function testTransactionalCampaignUnPublish(): void
|
||||
{
|
||||
$campaignMock = $this->createCampaignMockForUnpublish();
|
||||
|
||||
// Saving the entity
|
||||
$this->campaignModel->expects($this->once())
|
||||
->method('saveEntity')
|
||||
->with($campaignMock);
|
||||
|
||||
$this->campaignModel->transactionalCampaignUnPublish($campaignMock);
|
||||
}
|
||||
|
||||
public function testTransactionalCampaignUnPublishWithException(): void
|
||||
{
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('Database error');
|
||||
|
||||
$campaignMock = $this->createCampaignMockForUnpublish();
|
||||
|
||||
// Saving the entity throws an exception
|
||||
$this->campaignModel->expects($this->once())
|
||||
->method('saveEntity')
|
||||
->with($campaignMock)
|
||||
->willThrowException(new \Exception('Database error'));
|
||||
|
||||
$this->campaignModel->transactionalCampaignUnPublish($campaignMock);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\CampaignBundle\Tests\Model;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Mautic\CampaignBundle\CampaignEvents;
|
||||
use Mautic\CampaignBundle\Entity\Event;
|
||||
use Mautic\CampaignBundle\Entity\EventRepository;
|
||||
use Mautic\CampaignBundle\Event\DeleteEvent;
|
||||
use Mautic\CampaignBundle\Model\EventModel;
|
||||
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
||||
use Mautic\CoreBundle\Helper\UserHelper;
|
||||
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
|
||||
use Mautic\CoreBundle\Translation\Translator;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
|
||||
class EventModelTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var EntityManagerInterface|MockObject
|
||||
*/
|
||||
private $entityManagerMock;
|
||||
|
||||
/**
|
||||
* @var EventRepository|MockObject
|
||||
*/
|
||||
private $eventRepositoryMock;
|
||||
|
||||
/**
|
||||
* @var EventDispatcherInterface|MockObject
|
||||
*/
|
||||
private $dispatcherMock;
|
||||
|
||||
private MockObject|EventModel $eventModel;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->entityManagerMock = $this->createMock(EntityManagerInterface::class);
|
||||
$this->eventRepositoryMock = $this->createMock(EventRepository::class);
|
||||
$this->dispatcherMock = $this->createMock(EventDispatcherInterface::class);
|
||||
|
||||
$this->eventModel = new EventModel(
|
||||
$this->entityManagerMock,
|
||||
$this->createMock(CorePermissions::class),
|
||||
$this->dispatcherMock,
|
||||
$this->createMock(UrlGeneratorInterface::class),
|
||||
$this->createMock(Translator::class),
|
||||
$this->createMock(UserHelper::class),
|
||||
$this->createMock(LoggerInterface::class),
|
||||
$this->createMock(CoreParametersHelper::class)
|
||||
);
|
||||
}
|
||||
|
||||
public function testThatClonedEventsDoNotAttemptNullingParentInDeleteEvents(): void
|
||||
{
|
||||
$this->entityManagerMock->expects($this->never())
|
||||
->method('getRepository')
|
||||
->with(Event::class)
|
||||
->willReturn($this->eventRepositoryMock);
|
||||
|
||||
$currentEvents = [
|
||||
'new1',
|
||||
'new2',
|
||||
'new3',
|
||||
];
|
||||
|
||||
$deletedEvents = [
|
||||
'new1',
|
||||
];
|
||||
|
||||
$this->eventModel->deleteEvents($currentEvents, $deletedEvents);
|
||||
}
|
||||
|
||||
public function testThatItDeletesEventLogs(): void
|
||||
{
|
||||
$idToDelete = 'old1';
|
||||
|
||||
$currentEvents = [
|
||||
'new1',
|
||||
];
|
||||
|
||||
$deletedEvents = [
|
||||
'new1',
|
||||
$idToDelete,
|
||||
];
|
||||
|
||||
$this->entityManagerMock->method('getRepository')
|
||||
->with(Event::class)
|
||||
->willReturn($this->eventRepositoryMock);
|
||||
|
||||
$this->eventRepositoryMock->expects($this->once())
|
||||
->method('nullEventRelationships')
|
||||
->with([$idToDelete]);
|
||||
|
||||
$this->eventRepositoryMock->expects($this->once())
|
||||
->method('setEventsAsDeleted')
|
||||
->with([1 => $idToDelete]);
|
||||
|
||||
$this->dispatcherMock->expects($this->once())
|
||||
->method('dispatch')
|
||||
->with(new DeleteEvent([$idToDelete]), CampaignEvents::ON_EVENT_DELETE);
|
||||
|
||||
$this->eventModel->deleteEvents($currentEvents, $deletedEvents);
|
||||
}
|
||||
|
||||
public function testDeleteEventsByCampaignId(): void
|
||||
{
|
||||
/** @var EventModel&MockObject */
|
||||
$mockModel = $this->getMockBuilder(EventModel::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['getRepository', 'deleteEventsByEventIds'])
|
||||
->getMock();
|
||||
|
||||
$mockModel->expects($this->once())
|
||||
->method('getRepository')
|
||||
->willReturn($this->eventRepositoryMock);
|
||||
|
||||
$campaignEvents = ['1', '2', '3'];
|
||||
|
||||
$this->eventRepositoryMock->expects($this->once())
|
||||
->method('getCampaignEventIds')
|
||||
->with(1)
|
||||
->willReturn($campaignEvents);
|
||||
|
||||
$mockModel->expects($this->once())->method('deleteEventsByEventIds')
|
||||
->with($campaignEvents);
|
||||
|
||||
$mockModel->deleteEventsByCampaignId(1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user