mautic / app /bundles /EmailBundle /Tests /Model /EmailModelFunctionalTest.php
chrisbryan17's picture
Upload folder using huggingface_hub
d2897cd verified
<?php
declare(strict_types=1);
namespace Mautic\EmailBundle\Tests\Model;
use Doctrine\DBAL\Exception;
use Doctrine\ORM\Exception\ORMException;
use Doctrine\ORM\OptimisticLockException;
use Mautic\CoreBundle\Entity\IpAddress;
use Mautic\CoreBundle\Test\MauticMysqlTestCase;
use Mautic\EmailBundle\Entity\Email;
use Mautic\EmailBundle\Entity\Stat;
use Mautic\EmailBundle\Model\EmailModel;
use Mautic\LeadBundle\Entity\Lead;
use Mautic\LeadBundle\Entity\LeadList;
use Mautic\LeadBundle\Entity\ListLead;
use Mautic\LeadBundle\Model\LeadModel;
use Mautic\PageBundle\Entity\Hit;
use Mautic\PageBundle\Entity\Redirect;
use Mautic\PageBundle\Entity\Trackable;
class EmailModelFunctionalTest extends MauticMysqlTestCase
{
protected function beforeBeginTransaction(): void
{
$this->resetAutoincrement(['leads']);
}
public function testSendEmailToListsInThreads(): void
{
$contacts = $this->generateContacts(23);
$segment = $this->createSegment();
$this->addContactsToSegment($contacts, $segment);
$email = $this->createEmail($segment);
$emailModel = static::getContainer()->get('mautic.email.model.email');
\assert($emailModel instanceof EmailModel);
[$sentCount] = $emailModel->sendEmailToLists($email, [$segment], null, null, null, null, null, 3, 1);
$this->assertEquals($sentCount, 7);
[$sentCount] = $emailModel->sendEmailToLists($email, [$segment], null, null, null, null, null, 3, 2);
$this->assertEquals($sentCount, 8);
[$sentCount] = $emailModel->sendEmailToLists($email, [$segment], null, null, null, null, null, 3, 3);
$this->assertEquals($sentCount, 8);
}
/**
* @return Lead[]
*/
private function generateContacts(int $howMany): array
{
$contacts = [];
for ($i = 0; $i < $howMany; ++$i) {
$contact = new Lead();
$contact->setEmail("test{$i}@some.email");
$contacts[] = $contact;
}
$contactModel = static::getContainer()->get('mautic.lead.model.lead');
\assert($contactModel instanceof LeadModel);
$contactModel->saveEntities($contacts);
return $contacts;
}
private function createSegment(): LeadList
{
$segment = new LeadList();
$segment->setName('Segment A');
$segment->setPublicName('Segment A');
$segment->setAlias('segment-a');
$this->em->persist($segment);
$this->em->flush();
return $segment;
}
/**
* @param Lead[] $contacts
*/
private function addContactsToSegment(array $contacts, LeadList $segment): void
{
foreach ($contacts as $contact) {
$reference = new ListLead();
$reference->setLead($contact);
$reference->setList($segment);
$reference->setDateAdded(new \DateTime());
$this->em->persist($reference);
}
$this->em->flush();
}
private function createEmail(LeadList $segment): Email
{
$email = new Email();
$email->setName('Email');
$email->setSubject('Email Subject');
$email->setCustomHtml('Email content');
$email->setEmailType('list');
$email->setPublishUp(new \DateTime('-1 day'));
$email->setIsPublished(true);
$email->addList($segment);
$this->em->persist($email);
$this->em->flush();
return $email;
}
public function testSendEmailToLists(): void
{
$contacts = $this->generateContacts(10);
$segment = $this->createSegment();
$this->addContactsToSegment($contacts, $segment);
$email = $this->createEmail($segment);
$emailModel = static::getContainer()->get('mautic.email.model.email');
[$sentCount, $failedCount, $failedRecipientsByList] = $emailModel->sendEmailToLists($email, [$segment], 4, 2);
$this->assertEquals($sentCount, 4);
[$sentCount, $failedCount, $failedRecipientsByList] = $emailModel->sendEmailToLists($email, [$segment], 3, 2);
$this->assertEquals($sentCount, 3);
[$sentCount, $failedCount, $failedRecipientsByList] = $emailModel->sendEmailToLists($email, [$segment], 2);
$this->assertEquals($sentCount, 2);
[$sentCount, $failedCount, $failedRecipientsByList] = $emailModel->sendEmailToLists($email, [$segment], 4);
$this->assertEquals($sentCount, 1);
$email = $this->createEmail($segment);
[$sentCount, $failedCount, $failedRecipientsByList] = $emailModel->sendEmailToLists($email, [$segment]);
$this->assertEquals($sentCount, 10);
$email = $this->createEmail($segment);
[$sentCount, $failedCount, $failedRecipientsByList] = $emailModel->sendEmailToLists($email, [$segment], null, 2);
$this->assertEquals($sentCount, 10);
}
public function testNotOverwriteChildrenTranslationEmailAfterSaveParent(): void
{
$segment = new LeadList();
$segmentName = 'Test_segment';
$segment->setName($segmentName);
$segment->setPublicName($segmentName);
$segment->setAlias($segmentName);
$this->em->persist($segment);
$emailName = 'Test';
$customHtmlParent = 'test EN';
$parentEmail = new Email();
$parentEmail->setName($emailName);
$parentEmail->setSubject($emailName);
$parentEmail->setCustomHTML($customHtmlParent);
$parentEmail->setEmailType('template');
$parentEmail->setLanguage('en');
$this->em->persist($parentEmail);
$customHtmlChildren = 'test FR';
$childrenEmail = clone $parentEmail;
$childrenEmail->setLanguage('fr');
$childrenEmail->setCustomHTML($customHtmlChildren);
$childrenEmail->setTranslationParent($parentEmail);
$this->em->persist($parentEmail);
$this->em->detach($segment);
$this->em->detach($parentEmail);
$this->em->detach($childrenEmail);
/** @var EmailModel $emailModel */
$emailModel = static::getContainer()->get('mautic.email.model.email');
$parentEmail->setName('Test change');
$emailModel->saveEntity($parentEmail);
self::assertSame($customHtmlParent, $parentEmail->getCustomHtml());
self::assertSame($customHtmlChildren, $childrenEmail->getCustomHtml());
}
/**
* @throws OptimisticLockException
* @throws ORMException
*/
private function emulateEmailStat(Lead $lead, Email $email, bool $isRead): void
{
$stat = new Stat();
$stat->setEmailAddress('[email protected]');
$stat->setLead($lead);
$stat->setDateSent(new \DateTime('2023-07-22'));
$stat->setEmail($email);
$stat->setIsRead($isRead);
$this->em->persist($stat);
}
/**
* @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->setHits($hits);
$redirect->setUniqueHits($uniqueHits);
$this->em->persist($redirect);
$trackable = new Trackable();
$trackable->setChannelId($email->getId());
$trackable->setChannel('email');
$trackable->setHits($hits);
$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());
$pageHit->setCode(200);
$pageHit->setUrl($redirect->getUrl());
$pageHit->setTrackingId($redirect->getRedirectId());
$pageHit->setSource('email');
$pageHit->setSourceId($email->getId());
$this->em->persist($pageHit);
}
/**
* @throws ORMException
* @throws Exception
*/
public function testGetEmailCountryStatsSingleEmail(): void
{
/** @var EmailModel $emailModel */
$emailModel = $this->getContainer()->get('mautic.email.model.email');
$dateFrom = new \DateTimeImmutable('2023-07-21');
$dateTo = new \DateTimeImmutable('2023-07-24');
$leadsPayload = [
[
'email' => '[email protected]',
'country' => 'Italy',
'read' => true,
'click' => true,
],
[
'email' => '[email protected]',
'country' => 'Italy',
'read' => true,
'click' => false,
],
[
'email' => '[email protected]',
'country' => 'Italy',
'read' => false,
'click' => false,
],
[
'email' => '[email protected]',
'country' => '',
'read' => true,
'click' => true,
],
[
'email' => '[email protected]',
'country' => 'Poland',
'read' => true,
'click' => false,
],
[
'email' => '[email protected]',
'country' => 'Poland',
'read' => true,
'click' => true,
],
];
$email = new Email();
$email->setName('Test email');
$this->em->persist($email);
$this->em->flush();
foreach ($leadsPayload as $l) {
$lead = new Lead();
$lead->setEmail($l['email']);
$lead->setCountry($l['country']);
$this->em->persist($lead);
$this->emulateEmailStat($lead, $email, $l['read']);
if ($l['read'] && $l['click']) {
$hits = rand(1, 5);
$uniqueHits = rand(1, $hits);
$this->emulateClick($lead, $email, $hits, $uniqueHits);
}
}
$this->em->flush();
$results = $emailModel->getCountryStats($email, $dateFrom, $dateTo);
$this->assertCount(2, $results);
$this->assertSame([
'clicked_through_count' => [
[
'clicked_through_count' => '1',
'country' => '',
],
[
'clicked_through_count' => '1',
'country' => 'Italy',
],
[
'clicked_through_count' => '1',
'country' => 'Poland',
],
],
'read_count' => [
[
'read_count' => '1',
'country' => '',
],
[
'read_count' => '2',
'country' => 'Italy',
],
[
'read_count' => '2',
'country' => 'Poland',
],
],
], $results);
}
/**
* @throws OptimisticLockException
* @throws ORMException
*/
public function testGetContextEntity(): void
{
/** @var EmailModel $emailModel */
$emailModel = $this->getContainer()->get('mautic.email.model.email');
$email = new Email();
$email->setName('Test email');
$this->em->persist($email);
$this->em->flush();
$id = $email->getId();
$result = $emailModel->getEntity($id);
$this->assertSame($email, $result);
}
}