Initial commit: CloudOps infrastructure platform

This commit is contained in:
root
2026-04-09 19:58:57 +02:00
commit 1166a52f26
7762 changed files with 839452 additions and 0 deletions

View File

@@ -0,0 +1,84 @@
<?php
namespace Mautic\CampaignBundle\Tests\Helper;
use Mautic\CampaignBundle\Entity\Campaign;
use Mautic\CampaignBundle\Event\CampaignLeadChangeEvent;
use Mautic\CampaignBundle\Helper\CampaignEventHelper;
use Mautic\CampaignBundle\Tests\CampaignTestAbstract;
class CampaignEventHelperTest extends CampaignTestAbstract
{
public function testValidateLeadChangeTriggerWithEmptyCampaigns(): void
{
$eventDetails = new CampaignLeadChangeEvent(new Campaign(), [], 'badaction');
$event = [
'properties' => [
'campaigns' => [],
'action' => 'added',
],
'campaign' => [
'id' => null,
],
];
$result = CampaignEventHelper::validateLeadChangeTrigger($eventDetails, $event);
$this->assertFalse($result);
}
public function testValidateLeadChangeTriggerWithUnmatchingCampaignsAndInvalidAction(): void
{
$eventDetails = new CampaignLeadChangeEvent(new Campaign(), [], 'badaction');
$event = [
'properties' => [
'campaigns' => [3],
'action' => 'added',
],
'campaign' => [
'id' => 4,
],
];
$result = CampaignEventHelper::validateLeadChangeTrigger($eventDetails, $event);
$this->assertFalse($result);
}
public function testValidateLeadChangeTriggerWithMatchingCampaignsAndInvalidAction(): void
{
$eventDetails = new CampaignLeadChangeEvent(new Campaign(), [], 'removed');
$event = [
'properties' => [
'campaigns' => [3],
'action' => 'added',
],
'campaign' => [
'id' => 3,
],
];
$result = CampaignEventHelper::validateLeadChangeTrigger($eventDetails, $event);
$this->assertFalse($result);
}
public function testValidateLeadChangeTriggerWithMatchingCampaignsAndVariousActions(): void
{
$actions = [
'added' => true,
'removed' => true,
'invalid' => false,
];
foreach ($actions as $action => $expectedResult) {
$campaignId = 3;
$eventDetails = new CampaignLeadChangeEvent(new Campaign(), [], $action);
$event = [
'properties' => [
'campaigns' => [$campaignId, 8],
'action' => $action,
],
'campaign' => [
'id' => $campaignId,
],
];
$result = CampaignEventHelper::validateLeadChangeTrigger($eventDetails, $event);
$this->assertSame($expectedResult, $result);
}
}
}

View File

@@ -0,0 +1,99 @@
<?php
namespace Mautic\CampaignBundle\Tests\Helper;
use Mautic\CampaignBundle\Entity\Event;
use Mautic\CampaignBundle\Entity\LeadEventLog;
use Mautic\CampaignBundle\EventCollector\Accessor\Event\AbstractEventAccessor;
use Mautic\CampaignBundle\Helper\ChannelExtractor;
class ChannelExtractorTest extends \PHPUnit\Framework\TestCase
{
public function testChannelIsSet(): void
{
$event = new Event();
$config = $this->createMock(AbstractEventAccessor::class);
$config->expects($this->once())
->method('getChannel')
->willReturn('email');
$log = new LeadEventLog();
ChannelExtractor::setChannel($log, $event, $config);
$this->assertEquals('email', $log->getChannel());
}
public function testChannelIsIgnoredIfSet(): void
{
$event = new Event();
$config = $this->createMock(AbstractEventAccessor::class);
$config->expects($this->never())
->method('getChannel');
$log = new LeadEventLog();
$log->setChannel('page');
ChannelExtractor::setChannel($log, $event, $config);
$this->assertEquals('page', $log->getChannel());
}
public function testChannelIdIsSet(): void
{
$event = new Event();
$event->setProperties(['email' => 1]);
$config = $this->createMock(AbstractEventAccessor::class);
$config->expects($this->once())
->method('getChannel')
->willReturn('email');
$config->expects($this->once())
->method('getChannelIdField')
->willReturn('email');
$log = new LeadEventLog();
ChannelExtractor::setChannel($log, $event, $config);
$this->assertEquals('email', $log->getChannel());
$this->assertEquals(1, $log->getChannelId());
}
public function testChannelIdIsIgnoredIfPropertiesAreEmpty(): void
{
$event = new Event();
$event->setProperties(null);
$config = $this->createMock(AbstractEventAccessor::class);
$config->expects($this->once())
->method('getChannel')
->willReturn('email');
$config->expects($this->once())
->method('getChannelIdField')
->willReturn('email');
$log = new LeadEventLog();
ChannelExtractor::setChannel($log, $event, $config);
$this->assertEquals('email', $log->getChannel());
$this->assertEquals(null, $log->getChannelId());
}
public function testChannelIdIsIgnoredIfChannelIdFieldIsNotSet(): void
{
$event = new Event();
$event->setProperties(['email' => 1]);
$config = $this->createMock(AbstractEventAccessor::class);
$config->expects($this->once())
->method('getChannel')
->willReturn('email');
$config->expects($this->once())
->method('getChannelIdField')
->willReturn(null);
$log = new LeadEventLog();
ChannelExtractor::setChannel($log, $event, $config);
$this->assertEquals('email', $log->getChannel());
$this->assertEquals(null, $log->getChannelId());
}
}

View File

@@ -0,0 +1,163 @@
<?php
namespace Mautic\CampaignBundle\Tests\Helper;
use Doctrine\Common\Collections\ArrayCollection;
use Mautic\CampaignBundle\Entity\Campaign;
use Mautic\CampaignBundle\Entity\Event;
use Mautic\CampaignBundle\Entity\EventRepository;
use Mautic\CampaignBundle\Entity\LeadEventLog;
use Mautic\CampaignBundle\Entity\LeadEventLogRepository;
use Mautic\CampaignBundle\Entity\LeadRepository;
use Mautic\CampaignBundle\Executioner\ContactFinder\InactiveContactFinder;
use Mautic\CampaignBundle\Executioner\Helper\DecisionHelper;
use Mautic\CampaignBundle\Executioner\Helper\InactiveHelper;
use Mautic\CampaignBundle\Executioner\Scheduler\EventScheduler;
use Mautic\LeadBundle\Entity\Lead;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class InactiveHelperTest extends TestCase
{
/**
* @var EventScheduler|MockObject
*/
private MockObject $scheduler;
/**
* @var InactiveContactFinder|MockObject
*/
private MockObject $inactiveContactFinder;
/**
* @var LeadEventLogRepository|MockObject
*/
private MockObject $eventLogRepository;
/**
* @var EventRepository|MockObject
*/
private MockObject $eventRepository;
/**
* @var LeadRepository|MockObject
*/
private MockObject $leadRepository;
/**
* @var LoggerInterface|MockObject
*/
private MockObject $logger;
private InactiveHelper $inactiveHelper;
private DecisionHelper $decisionHelper;
protected function setUp(): void
{
$this->scheduler = $this->createMock(EventScheduler::class);
$this->inactiveContactFinder = $this->createMock(InactiveContactFinder::class);
$this->eventLogRepository = $this->createMock(LeadEventLogRepository::class);
$this->eventRepository = $this->createMock(EventRepository::class);
$this->leadRepository = $this->createMock(LeadRepository::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->decisionHelper = new DecisionHelper($this->leadRepository);
$this->inactiveHelper = new InactiveHelper(
$this->scheduler,
$this->inactiveContactFinder,
$this->eventLogRepository,
$this->eventRepository,
$this->logger,
$this->decisionHelper
);
}
public function testRemoveContactsThatAreNotApplicable(): void
{
$lastActiveEventId = 6;
// lead not applicable because of parent negative path taken
$leadNegative = new Lead();
$leadNegative->setId(9);
// lead not applicable because of parent positive path taken
$leadNegative2 = new Lead();
$leadNegative2->setId(10);
// applicable lead
$leadPositive = new Lead();
$leadPositive->setId(12);
// lead not applicable because of no parent event log
$leadNegative3 = new Lead();
$leadNegative3->setId(11);
$this->eventLogRepository->expects($this->once())
->method('getDatesExecuted')
->willReturn([
$leadNegative->getId() => \DateTime::createFromFormat('Y-m-d H:i:s', '2022-05-28 21:37:00'),
$leadNegative2->getId() => \DateTime::createFromFormat('Y-m-d H:i:s', '2022-05-28 21:37:00'),
$leadPositive->getId() => \DateTime::createFromFormat('Y-m-d H:i:s', '2022-05-28 21:37:00'),
$leadNegative3->getId() => \DateTime::createFromFormat('Y-m-d H:i:s', '2022-05-28 21:37:00'),
]);
/** @var LeadEventLog&MockObject */
$log = $this->createMock(LeadEventLog::class);
$log->expects($this->exactly(3))
->method('getNonActionPathTaken')
->willReturnOnConsecutiveCalls(1, 0, 1);
/** @var Campaign&MockObject */
$campaign = $this->createMock(Campaign::class);
$campaign->expects($this->any())
->method('getId')
->willReturn(2);
/** @var Event&MockObject */
$parentEvent = $this->createMock(Event::class);
$parentEvent->expects($this->exactly(4))
->method('getLogByContactAndRotation')
->willReturnOnConsecutiveCalls($log, $log, $log, null);
$event = new Event();
$event->setParent($parentEvent);
$event->setDecisionPath('yes');
$event->setCampaign($campaign);
$event->setEventType(Event::TYPE_DECISION);
$parentEvent->expects($this->any())
->method('getNegativeChildren')
->willReturnOnConsecutiveCalls(new ArrayCollection(), new ArrayCollection([$event]));
$parentEvent->expects($this->any())
->method('getPositiveChildren')
->willReturnOnConsecutiveCalls(new ArrayCollection(), new ArrayCollection());
$this->leadRepository->expects($this->exactly(4))
->method('getContactRotations')
->willReturn([]);
$this->scheduler->expects($this->any())
->method('getExecutionDateTime')
->willReturn(\DateTime::createFromFormat('Y-m-d H:i:s', '2022-05-30 12:00:00'));
$now = \DateTime::createFromFormat('Y-m-d H:i:s', '2022-05-31 12:00:00');
$contacts = new ArrayCollection([
$leadNegative->getId() => $leadNegative,
$leadNegative2->getId() => $leadNegative2,
$leadPositive->getId() => $leadPositive,
$leadNegative3->getId() => $leadNegative3,
]);
$this->inactiveHelper->removeContactsThatAreNotApplicable(
$now,
$contacts,
$lastActiveEventId,
new ArrayCollection([new Event()]),
$event
);
$this->assertEquals(1, $contacts->count());
}
}

View File

@@ -0,0 +1,277 @@
<?php
namespace Mautic\CampaignBundle\Tests\Helper;
use Mautic\CampaignBundle\Entity\Campaign;
use Mautic\CampaignBundle\Entity\Event;
use Mautic\CampaignBundle\Executioner\Helper\NotificationHelper;
use Mautic\CoreBundle\Helper\CoreParametersHelper;
use Mautic\CoreBundle\Model\NotificationModel;
use Mautic\CoreBundle\Translation\Translator;
use Mautic\LeadBundle\Entity\Lead;
use Mautic\UserBundle\Entity\User;
use Mautic\UserBundle\Model\UserModel;
use Symfony\Component\Routing\Router;
class NotificationHelperTest extends \PHPUnit\Framework\TestCase
{
/**
* @var \PHPUnit\Framework\MockObject\MockObject|UserModel
*/
private \PHPUnit\Framework\MockObject\MockObject $userModel;
/**
* @var \PHPUnit\Framework\MockObject\MockObject|NotificationModel
*/
private \PHPUnit\Framework\MockObject\MockObject $notificationModel;
/**
* @var \PHPUnit\Framework\MockObject\MockObject|Router
*/
private \PHPUnit\Framework\MockObject\MockObject $router;
/**
* @var \PHPUnit\Framework\MockObject\MockObject|Translator
*/
private \PHPUnit\Framework\MockObject\MockObject $translator;
/**
* @var \PHPUnit\Framework\MockObject\MockObject|CoreParametersHelper
*/
private \PHPUnit\Framework\MockObject\MockObject $coreParametersHelper;
protected function setUp(): void
{
$this->userModel = $this->createMock(UserModel::class);
$this->notificationModel = $this->createMock(NotificationModel::class);
$this->router = $this->createMock(Router::class);
$this->translator = $this->createMock(Translator::class);
$this->coreParametersHelper = $this->createMock(CoreParametersHelper::class);
}
public function testContactOwnerIsNotified(): void
{
$event = new Event();
$campaign = new Campaign();
$event->setCampaign($campaign);
$user = $this->createMock(User::class);
$user->method('getId')
->willReturn('1');
$lead = $this->createMock(Lead::class);
$lead->expects($this->once())
->method('getOwner')
->willReturn($user);
$this->userModel->expects($this->never())
->method('getEntity');
$this->userModel->expects($this->never())
->method('getSystemAdministrator');
$this->notificationModel->expects($this->once())
->method('addNotification')
->with(
' / ',
'error',
false,
$this->anything(),
null,
null,
$user
);
$this->getNotificationHelper()->notifyOfFailure($lead, $event);
}
public function testCampaignCreatorIsNotified(): void
{
$event = new Event();
$campaign = new Campaign();
$event->setCampaign($campaign);
$campaign->setCreatedBy(1);
$user = $this->createMock(User::class);
$user->method('getId')
->willReturn('1');
$lead = $this->createMock(Lead::class);
$lead->expects($this->once())
->method('getOwner')
->willReturn(null);
$this->userModel->expects($this->once())
->method('getEntity')
->willReturn($user);
$this->userModel->expects($this->never())
->method('getSystemAdministrator');
$this->notificationModel->expects($this->once())
->method('addNotification')
->with(
' / ',
'error',
false,
$this->anything(),
null,
null,
$user
);
$this->getNotificationHelper()->notifyOfFailure($lead, $event);
}
public function testSystemAdminIsNotified(): void
{
$event = new Event();
$campaign = new Campaign();
$event->setCampaign($campaign);
$campaign->setCreatedBy(2);
$user = $this->createMock(User::class);
$user->method('getId')
->willReturn('1');
$lead = $this->createMock(Lead::class);
$lead->expects($this->once())
->method('getOwner')
->willReturn(null);
$this->userModel->expects($this->once())
->method('getEntity')
->willReturn(null);
$this->userModel->expects($this->once())
->method('getSystemAdministrator')
->willReturn($user);
$this->notificationModel->expects($this->once())
->method('addNotification')
->with(
' / ',
'error',
false,
$this->anything(),
null,
null,
$user
);
$this->getNotificationHelper()->notifyOfFailure($lead, $event);
}
public function testNotificationIgnoredIfUserNotFound(): void
{
$event = new Event();
$campaign = new Campaign();
$event->setCampaign($campaign);
$campaign->setCreatedBy(2);
$lead = $this->createMock(Lead::class);
$lead->expects($this->once())
->method('getOwner')
->willReturn(null);
$this->userModel->expects($this->once())
->method('getEntity')
->willReturn(null);
$this->userModel->expects($this->once())
->method('getSystemAdministrator')
->willReturn(null);
$this->notificationModel->expects($this->never())
->method('addNotification');
$this->getNotificationHelper()->notifyOfFailure($lead, $event);
}
public function testNotificationOfUnpublishToAuthor(): void
{
$event = new Event();
$user = $this->createMock(User::class);
$this->prepareCommonMocks($event, $user);
$this->coreParametersHelper
->method('get')
->with('campaign_send_notification_to_author')
->willReturn(1);
$this->userModel->expects($this->once())
->method('emailUser')
->with($user, 'test', 'test');
$this->userModel->expects($this->never())
->method('sendMailToEmailAddresses');
$this->getNotificationHelper()->notifyOfUnpublish($event);
}
public function testNotificationOfUnpublishToEmailAddress(): void
{
$event = new Event();
$user = $this->createMock(User::class);
$this->prepareCommonMocks($event, $user);
$emails = 'a@test.co, b@test.co';
$this->coreParametersHelper->expects($this->exactly(2))
->method('get')
->willReturnMap([
['campaign_send_notification_to_author', null, 0],
['campaign_notification_email_addresses', null, $emails],
]);
$this->userModel->expects($this->once())
->method('sendMailToEmailAddresses')
->with(array_map('trim', explode(',', $emails)), 'test', 'test');
$this->userModel->expects($this->never())
->method('emailUser');
$this->getNotificationHelper()->notifyOfUnpublish($event);
}
private function prepareCommonMocks(Event $event, User $user): void
{
$campaign = new Campaign();
$event->setCampaign($campaign);
$campaign->setCreatedBy(2);
$user = $this->createMock(User::class);
$lead = $this->createMock(Lead::class);
$lead->expects($this->any())
->method('getOwner')
->willReturn(null);
$user->expects($this->once())
->method('getId')
->willReturn(1);
$this->userModel->expects($this->once())
->method('getEntity')
->willReturn($user);
$this->translator
->expects($this->any())
->method('trans')
->willReturn('test');
}
/**
* @return NotificationHelper
*/
private function getNotificationHelper()
{
return new NotificationHelper(
$this->userModel,
$this->notificationModel,
$this->translator,
$this->router,
$this->coreParametersHelper
);
}
}