Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Helper;
|
||||
|
||||
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
||||
use Mautic\CoreBundle\Helper\PathsHelper;
|
||||
use Mautic\CoreBundle\Twig\Helper\AssetsHelper;
|
||||
use Mautic\CoreBundle\Twig\Helper\GravatarHelper;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\LeadBundle\Twig\Helper\AvatarHelper;
|
||||
use Mautic\LeadBundle\Twig\Helper\DefaultAvatarHelper;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Symfony\Component\Asset\Packages;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
|
||||
class AvatarHelperTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private AssetsHelper $assetsHelperMock;
|
||||
|
||||
/**
|
||||
* @var MockObject&PathsHelper
|
||||
*/
|
||||
private MockObject $pathsHelperMock;
|
||||
|
||||
private GravatarHelper $gravatarHelperMock;
|
||||
|
||||
private DefaultAvatarHelper $defaultAvatarHelperMock;
|
||||
|
||||
/**
|
||||
* @var MockObject&Lead
|
||||
*/
|
||||
private MockObject $leadMock;
|
||||
|
||||
private AvatarHelper $avatarHelper;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$root = realpath(__DIR__.'/../../../../../');
|
||||
|
||||
/** @var Packages&MockObject $packagesMock */
|
||||
$packagesMock = $this->createMock(Packages::class);
|
||||
|
||||
/** @var CoreParametersHelper&MockObject $coreParametersHelper */
|
||||
$coreParametersHelper = $this->createMock(CoreParametersHelper::class);
|
||||
|
||||
$this->assetsHelperMock = new AssetsHelper($packagesMock);
|
||||
$this->pathsHelperMock = $this->createMock(PathsHelper::class);
|
||||
$this->pathsHelperMock->method('getSystemPath')
|
||||
->willReturn('http://localhost');
|
||||
$this->pathsHelperMock->method('getAssetsPath')
|
||||
->willReturn($root.'/app/assets');
|
||||
$this->pathsHelperMock->method('getMediaPath')
|
||||
->willReturn($root.'/media');
|
||||
|
||||
$this->assetsHelperMock->setPathsHelper($this->pathsHelperMock);
|
||||
$this->defaultAvatarHelperMock = new DefaultAvatarHelper($this->assetsHelperMock);
|
||||
$this->gravatarHelperMock = new GravatarHelper($this->defaultAvatarHelperMock, $coreParametersHelper, $this->createMock(RequestStack::class));
|
||||
$this->leadMock = $this->createMock(Lead::class);
|
||||
$this->avatarHelper = new AvatarHelper($this->assetsHelperMock, $this->pathsHelperMock, $this->gravatarHelperMock, $this->defaultAvatarHelperMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to get gravatar.
|
||||
*/
|
||||
public function testGetAvatarWhenGravatar(): void
|
||||
{
|
||||
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
|
||||
$_SERVER['SERVER_PORT'] = '80';
|
||||
$_SERVER['SERVER_NAME'] = 'localhost';
|
||||
$_SERVER['REQUEST_URI'] = 'localhost';
|
||||
|
||||
$this->leadMock->method('getPreferredProfileImage')
|
||||
->willReturn('gravatar');
|
||||
$this->leadMock->method('getSocialCache')
|
||||
->willReturn([]);
|
||||
$this->leadMock->method('getEmail')
|
||||
->willReturn('mautic@acquia.com');
|
||||
$avatar = $this->avatarHelper->getAvatar($this->leadMock);
|
||||
$this->assertSame('https://www.gravatar.com/avatar/96f1b78c73c1ee806cf6a4168fe9bf77?s=250&d=http%3A%2F%2Flocalhost%2Fimages%2Favatar.png', $avatar, 'Gravatar image should be returned');
|
||||
|
||||
unset($_SERVER['SERVER_PROTOCOL']);
|
||||
unset($_SERVER['SERVER_PORT']);
|
||||
unset($_SERVER['SERVER_NAME']);
|
||||
unset($_SERVER['REQUEST_URI']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to get default image.
|
||||
*/
|
||||
public function testGetAvatarWhenDefault(): void
|
||||
{
|
||||
$this->leadMock->method('getPreferredProfileImage')
|
||||
->willReturn('gravatar');
|
||||
$this->leadMock->method('getSocialCache')
|
||||
->willReturn([]);
|
||||
$this->leadMock->method('getEmail')
|
||||
->willReturn('');
|
||||
$avatar = $this->avatarHelper->getAvatar($this->leadMock);
|
||||
|
||||
$this->assertSame('http://localhost/images/avatar.png', $avatar, 'Default image image should be returned');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Helper;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Mautic\CoreBundle\Entity\IpAddress;
|
||||
use Mautic\CoreBundle\Helper\IpLookupHelper;
|
||||
use Mautic\EmailBundle\Entity\Email;
|
||||
use Mautic\EmailBundle\Entity\Stat;
|
||||
use Mautic\EmailBundle\Entity\StatRepository;
|
||||
use Mautic\EmailBundle\Helper\BotRatioHelper;
|
||||
use Mautic\LeadBundle\Deduplicate\ContactMerger;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\LeadBundle\Event\ContactIdentificationEvent;
|
||||
use Mautic\LeadBundle\Helper\ContactRequestHelper;
|
||||
use Mautic\LeadBundle\Model\LeadModel;
|
||||
use Mautic\LeadBundle\Tracker\ContactTracker;
|
||||
use Monolog\Logger;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
|
||||
class ContactRequestHelperTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var MockObject|LeadModel
|
||||
*/
|
||||
private MockObject $leadModel;
|
||||
|
||||
/**
|
||||
* @var MockObject|ContactTracker
|
||||
*/
|
||||
private MockObject $contactTracker;
|
||||
|
||||
/**
|
||||
* @var MockObject|IpLookupHelper
|
||||
*/
|
||||
private MockObject $ipLookupHelper;
|
||||
|
||||
/**
|
||||
* @var MockObject|EventDispatcher
|
||||
*/
|
||||
private MockObject $dispatcher;
|
||||
|
||||
/**
|
||||
* @var MockObject|RequestStack
|
||||
*/
|
||||
private MockObject $requestStack;
|
||||
|
||||
/**
|
||||
* @var MockObject|Logger
|
||||
*/
|
||||
private MockObject $logger;
|
||||
|
||||
/**
|
||||
* @var MockObject|StatRepository
|
||||
*/
|
||||
private MockObject $statRepository;
|
||||
|
||||
/**
|
||||
* @var MockObject|BotRatioHelper
|
||||
*/
|
||||
private MockObject $botRatioHelper;
|
||||
|
||||
/**
|
||||
* @var MockObject|Lead
|
||||
*/
|
||||
private MockObject $trackedContact;
|
||||
|
||||
/**
|
||||
* @var MockObject|ContactMerger
|
||||
*/
|
||||
private MockObject $contactMerger;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->leadModel = $this->createMock(LeadModel::class);
|
||||
$this->contactTracker = $this->createMock(ContactTracker::class);
|
||||
$this->ipLookupHelper = $this->createMock(IpLookupHelper::class);
|
||||
$this->requestStack = $this->createMock(RequestStack::class);
|
||||
$this->logger = $this->createMock(Logger::class);
|
||||
$this->dispatcher = $this->createMock(EventDispatcher::class);
|
||||
$this->trackedContact = $this->createMock(Lead::class);
|
||||
$this->contactMerger = $this->createMock(ContactMerger::class);
|
||||
$this->statRepository = $this->createMock(StatRepository::class);
|
||||
$this->botRatioHelper = $this->createMock(BotRatioHelper::class);
|
||||
|
||||
$this->trackedContact->method('getId')
|
||||
->willReturn(1);
|
||||
|
||||
$this->trackedContact->method('getIpAddresses')
|
||||
->willReturn(new ArrayCollection());
|
||||
|
||||
$this->contactTracker->method('getContact')
|
||||
->willReturn($this->trackedContact);
|
||||
|
||||
$this->ipLookupHelper->method('getIpAddress')
|
||||
->willReturn(new IpAddress());
|
||||
}
|
||||
|
||||
public function testEventDoesNotIdentifyContact(): void
|
||||
{
|
||||
$query = [
|
||||
'ct' => [
|
||||
'lead' => 2,
|
||||
'channel' => [
|
||||
'email' => 1,
|
||||
],
|
||||
'stat' => 'abc123',
|
||||
],
|
||||
];
|
||||
|
||||
$email = $this->createMock(Email::class);
|
||||
$email->method('getId')
|
||||
->willReturn(2);
|
||||
|
||||
$stat = new Stat();
|
||||
$stat->setEmail($email);
|
||||
|
||||
$this->contactMerger->expects($this->never())
|
||||
->method('merge');
|
||||
|
||||
$this->leadModel->expects($this->once())
|
||||
->method('checkForDuplicateContact')
|
||||
->willReturn([$this->trackedContact, []]);
|
||||
|
||||
$helper = $this->getContactRequestHelper();
|
||||
$this->assertEquals($this->trackedContact->getId(), $helper->getContactFromQuery($query)->getId());
|
||||
}
|
||||
|
||||
public function testEventIdentifiesContact(): void
|
||||
{
|
||||
$query = [
|
||||
'ct' => [
|
||||
'lead' => 2,
|
||||
'channel' => [
|
||||
'email' => 1,
|
||||
],
|
||||
'stat' => 'abc123',
|
||||
],
|
||||
];
|
||||
|
||||
$contact = new Lead();
|
||||
|
||||
$this->dispatcher->method('dispatch')
|
||||
->willReturnCallback(function (ContactIdentificationEvent $event) use ($contact) {
|
||||
$event->setIdentifiedContact($contact, 'email');
|
||||
|
||||
return $event;
|
||||
});
|
||||
|
||||
$this->contactMerger->expects($this->never())
|
||||
->method('merge');
|
||||
|
||||
$helper = $this->getContactRequestHelper();
|
||||
$foundContact = $helper->getContactFromQuery($query);
|
||||
|
||||
$this->assertTrue($contact === $foundContact);
|
||||
}
|
||||
|
||||
private function getContactRequestHelper(): ContactRequestHelper
|
||||
{
|
||||
return new ContactRequestHelper(
|
||||
$this->leadModel,
|
||||
$this->contactTracker,
|
||||
$this->ipLookupHelper,
|
||||
$this->requestStack,
|
||||
$this->logger,
|
||||
$this->dispatcher,
|
||||
$this->contactMerger,
|
||||
$this->statRepository,
|
||||
$this->botRatioHelper
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Helper;
|
||||
|
||||
use Mautic\CoreBundle\Helper\DateTimeHelper;
|
||||
use Mautic\LeadBundle\Helper\CustomFieldHelper;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CustomFieldHelperTest extends TestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testFixValueTypeForBooleans(): void
|
||||
{
|
||||
$this->assertNull(CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_BOOLEAN, null));
|
||||
$this->assertTrue(CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_BOOLEAN, 1));
|
||||
$this->assertTrue(CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_BOOLEAN, true));
|
||||
$this->assertTrue(CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_BOOLEAN, '1'));
|
||||
$this->assertFalse(CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_BOOLEAN, '0'));
|
||||
$this->assertFalse(CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_BOOLEAN, ''));
|
||||
$this->assertFalse(CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_BOOLEAN, false));
|
||||
$this->assertFalse(CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_BOOLEAN, 0));
|
||||
}
|
||||
|
||||
public function testFixValueTypeForNumbers(): void
|
||||
{
|
||||
$this->assertNull(CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_NUMBER, null));
|
||||
$this->assertEquals(1, CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_NUMBER, 1));
|
||||
$this->assertEquals(1, CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_NUMBER, true));
|
||||
$this->assertEquals(0, CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_NUMBER, false));
|
||||
$this->assertEquals(5, CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_NUMBER, '5'));
|
||||
$this->assertEquals(0, CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_NUMBER, ''));
|
||||
$this->assertEquals(0, CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_NUMBER, '0'));
|
||||
}
|
||||
|
||||
public function testFixValueTypeForSelect(): void
|
||||
{
|
||||
$this->assertNull(CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_SELECT, null));
|
||||
$this->assertEquals('1', CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_SELECT, true));
|
||||
$this->assertEquals('', CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_SELECT, false));
|
||||
$this->assertEquals('1', CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_SELECT, 1));
|
||||
$this->assertEquals('1', CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_SELECT, '1'));
|
||||
$this->assertEquals('one', CustomFieldHelper::fixValueType(CustomFieldHelper::TYPE_SELECT, 'one'));
|
||||
}
|
||||
|
||||
public function testFieldsValuesTransformerWithoutRelativesDates(): void
|
||||
{
|
||||
$values = [
|
||||
'customdate' => '2020-11-01',
|
||||
'customdatetime' => '2020-11-02 23:59:00',
|
||||
'customtime' => '23:59:00',
|
||||
'customnulldatetime' => null,
|
||||
];
|
||||
|
||||
$fields = [
|
||||
'customdate' => [
|
||||
'type' => 'date',
|
||||
],
|
||||
'customdatetime' => [
|
||||
'type' => 'datetime',
|
||||
],
|
||||
'customtime' => [
|
||||
'type' => 'time',
|
||||
],
|
||||
'customnulldatetime' => [
|
||||
'type' => 'datetime',
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertSame($values, CustomFieldHelper::fieldsValuesTransformer($fields, $values));
|
||||
}
|
||||
|
||||
public function testFieldsValuesTransformerWithRelativesDates(): void
|
||||
{
|
||||
$values = [
|
||||
'customdate' => '-1 day',
|
||||
'customdatetime' => '-1 day',
|
||||
'customtime' => '-20 minutes',
|
||||
'customnulldatetime' => null,
|
||||
];
|
||||
|
||||
$fields = [
|
||||
'customdate' => [
|
||||
'type' => 'date',
|
||||
],
|
||||
'customdatetime' => [
|
||||
'type' => 'datetime',
|
||||
],
|
||||
'customtime' => [
|
||||
'type' => 'time',
|
||||
],
|
||||
'customnulldatetime' => [
|
||||
'type' => 'datetime',
|
||||
],
|
||||
];
|
||||
|
||||
$expected = [
|
||||
'customdate' => (new DateTimeHelper('-1 day'))->toLocalString('Y-m-d'),
|
||||
'customdatetime' => (new DateTimeHelper('-1 day'))->toLocalString('Y-m-d H:i:s'),
|
||||
'customtime' => (new DateTimeHelper('-20 minutes'))->toLocalString('H:i:s'),
|
||||
'customnulldatetime' => null,
|
||||
];
|
||||
|
||||
$this->assertSame($expected, CustomFieldHelper::fieldsValuesTransformer($fields, $values));
|
||||
}
|
||||
|
||||
public function testFieldsValuesWithNullsOrEmptyStringsAreNotTransformedToRelativesDates(): void
|
||||
{
|
||||
$values = [
|
||||
'customdate' => null,
|
||||
'customdatetime' => null,
|
||||
'customtime' => null,
|
||||
'customemptystring' => '',
|
||||
];
|
||||
|
||||
$fields = [
|
||||
'customdate' => [
|
||||
'type' => 'date',
|
||||
],
|
||||
'customdatetime' => [
|
||||
'type' => 'datetime',
|
||||
],
|
||||
'customtime' => [
|
||||
'type' => 'time',
|
||||
],
|
||||
'customemptystring' => [
|
||||
'type' => 'datetime',
|
||||
],
|
||||
];
|
||||
|
||||
$expected = [
|
||||
'customdate' => null,
|
||||
'customdatetime' => null,
|
||||
'customtime' => null,
|
||||
'customemptystring' => null,
|
||||
];
|
||||
|
||||
$this->assertSame($expected, CustomFieldHelper::fieldsValuesTransformer($fields, $values));
|
||||
}
|
||||
|
||||
public function testFieldsValuesTransformerForDifferingValueTypes(): void
|
||||
{
|
||||
$fields = [
|
||||
'select' => [
|
||||
'type' => 'select',
|
||||
],
|
||||
'multiselect' => [
|
||||
'type' => 'multiselect',
|
||||
],
|
||||
'number' => [
|
||||
'type' => 'number',
|
||||
],
|
||||
'string' => [
|
||||
'type' => 'text',
|
||||
],
|
||||
'boolean' => [
|
||||
'type' => 'boolean',
|
||||
],
|
||||
];
|
||||
|
||||
$values = [
|
||||
'select' => 'string',
|
||||
'multiselect' => [
|
||||
'array',
|
||||
],
|
||||
'number' => 100,
|
||||
'string' => 'string',
|
||||
'boolean' => 0,
|
||||
];
|
||||
|
||||
$this->assertSame($values, CustomFieldHelper::fieldsValuesTransformer($fields, $values));
|
||||
}
|
||||
|
||||
public function testFieldValueTransformerWithDateTimeFields(): void
|
||||
{
|
||||
$mockDateTimeHelper = $this->createMock(DateTimeHelper::class);
|
||||
$mockDateTimeHelper->method('toLocalString')
|
||||
->willReturn('2023-05-20 00:00:00');
|
||||
|
||||
$field = ['type' => 'datetime'];
|
||||
$value = 'now';
|
||||
$result = CustomFieldHelper::fieldValueTransfomer($field, $value, $mockDateTimeHelper);
|
||||
$this->assertEquals('2023-05-20 00:00:00', $result, 'FieldValueTransformer was not able to transform datetime field properly');
|
||||
|
||||
$field = ['type' => 'date'];
|
||||
$value = 'today';
|
||||
$result = CustomFieldHelper::fieldValueTransfomer($field, $value, $mockDateTimeHelper);
|
||||
$this->assertEquals('2023-05-20 00:00:00', $result, 'FieldValueTransformer was not able to transform date field properly');
|
||||
|
||||
$field = ['type' => 'time'];
|
||||
$value = 'now';
|
||||
$result = CustomFieldHelper::fieldValueTransfomer($field, $value, $mockDateTimeHelper);
|
||||
$this->assertEquals('2023-05-20 00:00:00', $result, 'FieldValueTransformer was not able to transform time field properly');
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Helper;
|
||||
|
||||
use Mautic\LeadBundle\Helper\CustomFieldValueHelper;
|
||||
use PHPUnit\Framework\Assert;
|
||||
|
||||
class CustomFieldValueHelperTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @param array<int|string> $fieldParams
|
||||
*/
|
||||
private function runNormalizeValueBooleans(array $fieldParams): void
|
||||
{
|
||||
$fields['core']['test'] = $fieldParams;
|
||||
|
||||
$fieldParams['value'] = 0;
|
||||
$fields['core']['test2'] = $fieldParams;
|
||||
|
||||
$fieldParams['value'] = null;
|
||||
$fields['core']['test3'] = $fieldParams;
|
||||
|
||||
$normalizedFields = CustomFieldValueHelper::normalizeValues($fields);
|
||||
|
||||
$this->assertEquals('Yes', $normalizedFields['core']['test']['normalizedValue']);
|
||||
$this->assertEquals('No', $normalizedFields['core']['test2']['normalizedValue']);
|
||||
$this->assertEquals('', $normalizedFields['core']['test3']['normalizedValue']);
|
||||
}
|
||||
|
||||
public function testNormalizeValueBooleans(): void
|
||||
{
|
||||
$fieldParams = [
|
||||
'type' => CustomFieldValueHelper::TYPE_BOOLEAN,
|
||||
'value' => 1,
|
||||
'properties'=> 'a:2:{s:2:"no";s:2:"No";s:3:"yes";s:3:"Yes";}',
|
||||
];
|
||||
|
||||
$this->runNormalizeValueBooleans($fieldParams);
|
||||
}
|
||||
|
||||
public function testNormalizeValueBooleansWithDifferentProperties(): void
|
||||
{
|
||||
$fieldParams = [
|
||||
'type' => CustomFieldValueHelper::TYPE_BOOLEAN,
|
||||
'value' => 1,
|
||||
'properties'=> 'a:2:{s:3:"yes";s:3:"Yes";s:2:"no";s:2:"No";}',
|
||||
];
|
||||
|
||||
$this->runNormalizeValueBooleans($fieldParams);
|
||||
}
|
||||
|
||||
public function testNormalizeValueSelect(): void
|
||||
{
|
||||
$fields['core']['test'] = [
|
||||
'type' => CustomFieldValueHelper::TYPE_SELECT,
|
||||
'value' => 'second',
|
||||
'properties'=> 'a:1:{s:4:"list";a:2:{i:0;a:2:{s:5:"label";s:12:"First option";s:5:"value";s:5:"first";}i:1;a:2:{s:5:"label";s:13:"Second option";s:5:"value";s:6:"second";}}}',
|
||||
];
|
||||
$normalizedFields = CustomFieldValueHelper::normalizeValues($fields);
|
||||
$this->assertEquals('Second option', $normalizedFields['core']['test']['normalizedValue']);
|
||||
}
|
||||
|
||||
public function testNormalizeValueSelectWithoutProperties(): void
|
||||
{
|
||||
$fields['core']['test'] = [
|
||||
'type' => CustomFieldValueHelper::TYPE_SELECT,
|
||||
'value' => 'second',
|
||||
];
|
||||
$normalizedFields = CustomFieldValueHelper::normalizeValues($fields);
|
||||
$this->assertEquals('second', $normalizedFields['core']['test']['normalizedValue']);
|
||||
}
|
||||
|
||||
public function testNormalizeValueMultiSelect(): void
|
||||
{
|
||||
$fieldParams = [
|
||||
'type' => CustomFieldValueHelper::TYPE_MULTISELECT,
|
||||
'value' => 'option 1',
|
||||
'properties'=> 'a:1:{s:4:"list";a:3:{i:0;a:2:{s:5:"label";s:12:"Option 1 yes";s:5:"value";s:8:"option 1";}i:1;a:2:{s:5:"label";s:12:"Option 2 yes";s:5:"value";s:8:"option 2";}i:2;a:2:{s:5:"label";s:12:"Option 3 yes";s:5:"value";s:8:"option 3";}}}',
|
||||
];
|
||||
|
||||
$fields['core']['test'] = $fieldParams;
|
||||
|
||||
$fieldParams['value'] = 'option 4';
|
||||
$fields['core']['test2'] = $fieldParams;
|
||||
|
||||
$normalizedFields = CustomFieldValueHelper::normalizeValues($fields);
|
||||
|
||||
$this->assertEquals('Option 1 yes', $normalizedFields['core']['test']['normalizedValue']);
|
||||
$this->assertEquals('option 4', $normalizedFields['core']['test2']['normalizedValue']);
|
||||
}
|
||||
|
||||
public function testSetValueFromPropertiesListWithoutList(): void
|
||||
{
|
||||
Assert::assertSame(
|
||||
'value_1',
|
||||
CustomFieldValueHelper::setValueFromPropertiesList([], 'value_1')
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetValueFromPropertiesListWithStringList(): void
|
||||
{
|
||||
Assert::assertSame(
|
||||
'value_1',
|
||||
CustomFieldValueHelper::setValueFromPropertiesList(['list' => 'some|string'], 'value_1')
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetValueFromPropertiesListWithAssociativeArrayList(): void
|
||||
{
|
||||
Assert::assertSame(
|
||||
'value_1',
|
||||
CustomFieldValueHelper::setValueFromPropertiesList(
|
||||
['list' => ['value_1' => 'Label 1']],
|
||||
'value_1'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetValueFromPropertiesListWithArrayList(): void
|
||||
{
|
||||
Assert::assertSame(
|
||||
'Label 1',
|
||||
CustomFieldValueHelper::setValueFromPropertiesList(
|
||||
[
|
||||
'list' => [
|
||||
['value' => 'value_1', 'label' => 'Label 1'],
|
||||
],
|
||||
],
|
||||
'value_1'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Helper;
|
||||
|
||||
use Mautic\LeadBundle\Entity\LeadField;
|
||||
use Mautic\LeadBundle\Entity\LeadFieldRepository;
|
||||
use Mautic\LeadBundle\Helper\FieldAliasHelper;
|
||||
use Mautic\LeadBundle\Model\FieldModel;
|
||||
|
||||
class FieldAliasHelperTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \PHPUnit\Framework\MockObject\MockObject $fieldModel;
|
||||
|
||||
private \PHPUnit\Framework\MockObject\MockObject $fieldRepository;
|
||||
|
||||
private FieldAliasHelper $helper;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->fieldRepository = $this->createMock(LeadFieldRepository::class);
|
||||
$this->fieldModel = $this->getMockBuilder(FieldModel::class)
|
||||
->onlyMethods(['cleanAlias', 'getRepository'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->fieldRepository->method('getAliases')->willReturn([
|
||||
'title',
|
||||
'firstname',
|
||||
'lastname',
|
||||
]);
|
||||
|
||||
$this->fieldModel->method('cleanAlias')->willReturnCallback(fn () => func_get_args()[0]);
|
||||
|
||||
$this->fieldModel->method('getRepository')->willReturn($this->fieldRepository);
|
||||
|
||||
$this->helper = new FieldAliasHelper($this->fieldModel);
|
||||
}
|
||||
|
||||
public function testDuplicatedAliasWithAliasSet(): void
|
||||
{
|
||||
$field = new LeadField();
|
||||
$field->setAlias('title');
|
||||
$field = $this->helper->makeAliasUnique($field);
|
||||
|
||||
$this->assertEquals('title1', $field->getAlias());
|
||||
}
|
||||
|
||||
public function testDuplicatedAliasWithAliasEmpty(): void
|
||||
{
|
||||
$field = new LeadField();
|
||||
$field->setName('title');
|
||||
$field = $this->helper->makeAliasUnique($field);
|
||||
|
||||
$this->assertEquals('title1', $field->getAlias());
|
||||
}
|
||||
|
||||
public function testUniqueAliasWithAliasEmpty(): void
|
||||
{
|
||||
$field = new LeadField();
|
||||
$field->setName('phone');
|
||||
$field = $this->helper->makeAliasUnique($field);
|
||||
|
||||
$this->assertEquals('phone', $field->getAlias());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Helper;
|
||||
|
||||
use Mautic\LeadBundle\Helper\FormFieldHelper;
|
||||
use PHPUnit\Framework\Assert;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class FormFieldHelperTest extends TestCase
|
||||
{
|
||||
private ?string $defaultUploadDir;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->defaultUploadDir = $_ENV['MAUTIC_UPLOAD_DIR'] ?? null;
|
||||
$_ENV['MAUTIC_UPLOAD_DIR'] = __DIR__; // may not be set unless Symfony is booted
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$_ENV['MAUTIC_UPLOAD_DIR'] = $this->defaultUploadDir;
|
||||
}
|
||||
|
||||
public function testDefaultCountryList(): void
|
||||
{
|
||||
$list = FormFieldHelper::getCountryChoices();
|
||||
$first = array_shift($list);
|
||||
$last = array_pop($list);
|
||||
Assert::assertEquals('Afghanistan', $first);
|
||||
Assert::assertEquals('Zimbabwe', $last);
|
||||
}
|
||||
|
||||
public function testCustomCountryList(): void
|
||||
{
|
||||
$_ENV['MAUTIC_UPLOAD_DIR'] = __DIR__.'/files';
|
||||
$list = FormFieldHelper::getCountryChoices();
|
||||
$first = array_shift($list);
|
||||
$last = array_pop($list);
|
||||
Assert::assertEquals('Middle Earth', $first);
|
||||
Assert::assertEquals('Fillory', $last);
|
||||
}
|
||||
|
||||
public function testDefaultRegionList(): void
|
||||
{
|
||||
$list = FormFieldHelper::getRegionChoices();
|
||||
$firstCountry = array_shift($list);
|
||||
$firstCountryRegion = array_shift($firstCountry);
|
||||
$lastCountry = array_pop($list);
|
||||
$lastCountryRegion = array_pop($lastCountry);
|
||||
Assert::assertEquals('Alabama', $firstCountryRegion);
|
||||
Assert::assertEquals('St. Maarten', $lastCountryRegion);
|
||||
}
|
||||
|
||||
public function testCustomRegionList(): void
|
||||
{
|
||||
$_ENV['MAUTIC_UPLOAD_DIR'] = __DIR__.'/files';
|
||||
$list = FormFieldHelper::getRegionChoices();
|
||||
$firstCountry = array_shift($list);
|
||||
$firstCountryRegion = array_shift($firstCountry);
|
||||
$lastCountry = array_pop($list);
|
||||
$lastCountryRegion = array_pop($lastCountry);
|
||||
Assert::assertEquals('The Westlands', $firstCountryRegion);
|
||||
Assert::assertEquals('Darkling Woods', $lastCountryRegion);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Helper;
|
||||
|
||||
use Mautic\LeadBundle\Helper\IdentifyCompanyHelper;
|
||||
use Mautic\LeadBundle\Model\CompanyModel;
|
||||
|
||||
class IdentifyCompanyHelperTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testDomainExistsRealDomain(): void
|
||||
{
|
||||
$helper = new IdentifyCompanyHelper();
|
||||
$reflection = new \ReflectionClass(IdentifyCompanyHelper::class);
|
||||
$method = $reflection->getMethod('domainExists');
|
||||
$method->setAccessible(true);
|
||||
$result = $method->invokeArgs($helper, ['hello@mautic.org']);
|
||||
|
||||
$this->assertTrue(is_string($result));
|
||||
$this->assertGreaterThan(0, strlen($result));
|
||||
}
|
||||
|
||||
public function testDomainExistsWithFakeDomain(): void
|
||||
{
|
||||
$helper = new IdentifyCompanyHelper();
|
||||
$reflection = new \ReflectionClass(IdentifyCompanyHelper::class);
|
||||
$method = $reflection->getMethod('domainExists');
|
||||
$method->setAccessible(true);
|
||||
$result = $method->invokeArgs($helper, ['hello@domain.fake']);
|
||||
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
public function testFindCompanyByName(): void
|
||||
{
|
||||
$company = [
|
||||
'company' => 'Mautic',
|
||||
];
|
||||
|
||||
$expected = [
|
||||
'companyname' => 'Mautic',
|
||||
];
|
||||
|
||||
$model = $this->createMock(CompanyModel::class);
|
||||
|
||||
$model->expects($this->once())
|
||||
->method('checkForDuplicateCompanies')
|
||||
->willReturn([]);
|
||||
|
||||
$model->expects($this->any())
|
||||
->method('fetchCompanyFields')
|
||||
->willReturn([['alias' => 'companyname']]);
|
||||
|
||||
$helper = new IdentifyCompanyHelper();
|
||||
$reflection = new \ReflectionClass(IdentifyCompanyHelper::class);
|
||||
$method = $reflection->getMethod('findCompany');
|
||||
$method->setAccessible(true);
|
||||
[$resultCompany, $entities] = $method->invokeArgs($helper, [$company, $model]);
|
||||
|
||||
$this->assertEquals($expected, $resultCompany);
|
||||
}
|
||||
|
||||
public function testFindCompanyByNameWithValidEmail(): void
|
||||
{
|
||||
$company = [
|
||||
'company' => 'Mautic',
|
||||
'companyemail' => 'hello@mautic.org',
|
||||
];
|
||||
|
||||
$expected = [
|
||||
'companyname' => 'Mautic',
|
||||
'companyemail' => 'hello@mautic.org',
|
||||
];
|
||||
|
||||
$model = $this->createMock(CompanyModel::class);
|
||||
|
||||
$model->expects($this->once())
|
||||
->method('checkForDuplicateCompanies')
|
||||
->willReturn([]);
|
||||
|
||||
$model->expects($this->any())
|
||||
->method('fetchCompanyFields')
|
||||
->willReturn([['alias' => 'companyname']]);
|
||||
|
||||
$helper = new IdentifyCompanyHelper();
|
||||
$reflection = new \ReflectionClass(IdentifyCompanyHelper::class);
|
||||
$method = $reflection->getMethod('findCompany');
|
||||
$method->setAccessible(true);
|
||||
[$resultCompany, $entities] = $method->invokeArgs($helper, [$company, $model]);
|
||||
|
||||
$this->assertEquals($expected, $resultCompany);
|
||||
}
|
||||
|
||||
public function testFindCompanyByNameWithValidEmailAndCustomWebsite(): void
|
||||
{
|
||||
$company = [
|
||||
'company' => 'Mautic',
|
||||
'companyemail' => 'hello@mautic.org',
|
||||
'companywebsite' => 'https://mautic.org',
|
||||
];
|
||||
|
||||
$expected = [
|
||||
'companyname' => 'Mautic',
|
||||
'companywebsite' => 'https://mautic.org',
|
||||
'companyemail' => 'hello@mautic.org',
|
||||
];
|
||||
|
||||
$model = $this->createMock(CompanyModel::class);
|
||||
|
||||
$model->expects($this->once())
|
||||
->method('checkForDuplicateCompanies')
|
||||
->willReturn([]);
|
||||
|
||||
$model->expects($this->any())
|
||||
->method('fetchCompanyFields')
|
||||
->willReturn([['alias' => 'companyname']]);
|
||||
|
||||
$helper = new IdentifyCompanyHelper();
|
||||
$reflection = new \ReflectionClass(IdentifyCompanyHelper::class);
|
||||
$method = $reflection->getMethod('findCompany');
|
||||
$method->setAccessible(true);
|
||||
[$resultCompany, $entities] = $method->invokeArgs($helper, [$company, $model]);
|
||||
|
||||
$this->assertEquals($expected, $resultCompany);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Helper;
|
||||
|
||||
use Mautic\LeadBundle\Entity\DoNotContact;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\LeadBundle\Event\ChannelSubscriptionChange;
|
||||
use Mautic\LeadBundle\Event\LeadEvent;
|
||||
use Mautic\LeadBundle\Event\LeadUtmTagsEvent;
|
||||
use Mautic\LeadBundle\Event\PointsChangeEvent;
|
||||
use Mautic\LeadBundle\Helper\LeadChangeEventDispatcher;
|
||||
use Mautic\LeadBundle\LeadEvents;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
|
||||
class LeadChangeEventDispatcherTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Test that date identified change dispatches correct event')]
|
||||
public function testDateIdentifiedEventIsDispatched(): void
|
||||
{
|
||||
$dispatcher = $this->createMock(EventDispatcher::class);
|
||||
|
||||
$lead = new Lead();
|
||||
$event = new LeadEvent($lead);
|
||||
|
||||
$dispatcher->expects($this->once())
|
||||
->method('dispatch')
|
||||
->with(
|
||||
$event,
|
||||
LeadEvents::LEAD_IDENTIFIED
|
||||
);
|
||||
|
||||
$leadEventDispatcher = new LeadChangeEventDispatcher($dispatcher);
|
||||
|
||||
$leadEventDispatcher->dispatchEvents($event, ['dateIdentified' => ['foo', 'bar']]);
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Test that point changes dispatches correct event')]
|
||||
public function testPointChangeEventIsDispatched(): void
|
||||
{
|
||||
$dispatcher = $this->createMock(EventDispatcher::class);
|
||||
|
||||
$lead = new Lead();
|
||||
$event = new LeadEvent($lead);
|
||||
$pointsEvent = new PointsChangeEvent($lead, 10, 20);
|
||||
$dispatcher->expects($this->once())
|
||||
->method('dispatch')
|
||||
->with(
|
||||
$pointsEvent,
|
||||
LeadEvents::LEAD_POINTS_CHANGE
|
||||
);
|
||||
|
||||
$leadEventDispatcher = new LeadChangeEventDispatcher($dispatcher);
|
||||
|
||||
$leadEventDispatcher->dispatchEvents($event, ['points' => [10, 20]]);
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Test that points change event is not dispatched if we did an import')]
|
||||
public function testPointChangeEventIsNotDispatchedWithImport(): void
|
||||
{
|
||||
$dispatcher = $this->createMock(EventDispatcher::class);
|
||||
|
||||
$lead = new Lead();
|
||||
$lead->imported = true;
|
||||
|
||||
$event = new LeadEvent($lead);
|
||||
|
||||
$dispatcher->expects($this->never())
|
||||
->method('dispatch');
|
||||
|
||||
$leadEventDispatcher = new LeadChangeEventDispatcher($dispatcher);
|
||||
|
||||
$leadEventDispatcher->dispatchEvents($event, ['points' => [10, 20]]);
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Test that points change event is not dispatched if points are empty (false positive)')]
|
||||
public function testPointChangeEventIsNotDispatchedWithEmptyPoints(): void
|
||||
{
|
||||
$dispatcher = $this->createMock(EventDispatcher::class);
|
||||
|
||||
$lead = new Lead();
|
||||
$event = new LeadEvent($lead);
|
||||
|
||||
$dispatcher->expects($this->never())
|
||||
->method('dispatch');
|
||||
|
||||
$leadEventDispatcher = new LeadChangeEventDispatcher($dispatcher);
|
||||
|
||||
$leadEventDispatcher->dispatchEvents($event, ['points' => [0, 0]]);
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Test that points change event is dispatched if points are changed from something to nothing')]
|
||||
public function testPointChangeEventIsDispatchedWithPointsChangedToZero(): void
|
||||
{
|
||||
$dispatcher = $this->createMock(EventDispatcher::class);
|
||||
|
||||
$lead = new Lead();
|
||||
$event = new LeadEvent($lead);
|
||||
$pointsEvent = new PointsChangeEvent($lead, 10, 0);
|
||||
$dispatcher->expects($this->once())
|
||||
->method('dispatch')
|
||||
->with(
|
||||
$pointsEvent,
|
||||
LeadEvents::LEAD_POINTS_CHANGE
|
||||
);
|
||||
|
||||
$leadEventDispatcher = new LeadChangeEventDispatcher($dispatcher);
|
||||
|
||||
$leadEventDispatcher->dispatchEvents($event, ['points' => [10, 0]]);
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Test that points change event is not dispatched if this is a new Lead')]
|
||||
public function testPointChangeEventIsNotDispatchedWithNewContact(): void
|
||||
{
|
||||
$dispatcher = $this->createMock(EventDispatcher::class);
|
||||
|
||||
$lead = new Lead();
|
||||
$event = new LeadEvent($lead, true);
|
||||
$dispatcher->expects($this->never())
|
||||
->method('dispatch');
|
||||
|
||||
$leadEventDispatcher = new LeadChangeEventDispatcher($dispatcher);
|
||||
|
||||
$leadEventDispatcher->dispatchEvents($event, ['points' => [10, 0]]);
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Test that utm event is dispatched')]
|
||||
public function testUtmTagsChangeEventIsDispatched(): void
|
||||
{
|
||||
$dispatcher = $this->createMock(EventDispatcher::class);
|
||||
|
||||
$lead = new Lead();
|
||||
$event = new LeadEvent($lead);
|
||||
$changes = ['utmtags' => ['foo', 'bar']];
|
||||
$utmTagsEvent = new LeadUtmTagsEvent($lead, $changes['utmtags']);
|
||||
$dispatcher->expects($this->once())
|
||||
->method('dispatch')
|
||||
->with(
|
||||
$utmTagsEvent,
|
||||
LeadEvents::LEAD_UTMTAGS_ADD
|
||||
);
|
||||
|
||||
$leadEventDispatcher = new LeadChangeEventDispatcher($dispatcher);
|
||||
|
||||
$leadEventDispatcher->dispatchEvents($event, $changes);
|
||||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\TestDox('Test that channel subscription changes are dispatched')]
|
||||
public function testChannelSubscriptionChangeEventIsDispatched(): void
|
||||
{
|
||||
$dispatcher = $this->createMock(EventDispatcher::class);
|
||||
|
||||
$lead = new Lead();
|
||||
$event = new LeadEvent($lead);
|
||||
$changes = ['dnc_channel_status' => ['email' => ['old_reason' => DoNotContact::IS_CONTACTABLE, 'reason' => DoNotContact::UNSUBSCRIBED]]];
|
||||
|
||||
$dncEvent = new ChannelSubscriptionChange($lead, 'email', DoNotContact::IS_CONTACTABLE, DoNotContact::UNSUBSCRIBED);
|
||||
$dispatcher->expects($this->once())
|
||||
->method('dispatch')
|
||||
->with(
|
||||
$dncEvent,
|
||||
LeadEvents::CHANNEL_SUBSCRIPTION_CHANGED
|
||||
);
|
||||
|
||||
$leadEventDispatcher = new LeadChangeEventDispatcher($dispatcher);
|
||||
|
||||
$leadEventDispatcher->dispatchEvents($event, $changes);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Helper;
|
||||
|
||||
use Mautic\LeadBundle\Entity\CompanyLeadRepository;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\LeadBundle\Helper\PrimaryCompanyHelper;
|
||||
use PHPUnit\Framework\Exception;
|
||||
|
||||
class PrimaryCompanyHelperTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var CompanyLeadRepository|Exception
|
||||
*/
|
||||
private \PHPUnit\Framework\MockObject\MockObject $leadRepository;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->leadRepository = $this->createMock(CompanyLeadRepository::class);
|
||||
|
||||
$this->leadRepository->expects($this->once())
|
||||
->method('getCompaniesByLeadId')
|
||||
->willReturn(
|
||||
[
|
||||
[
|
||||
'score' => 0,
|
||||
'date_added' => '2018-06-02 00:00:00',
|
||||
'date_associated' => '2018-06-02 00:00:00',
|
||||
'is_primary' => 1,
|
||||
'companywebsite' => 'https://foo.com',
|
||||
],
|
||||
[
|
||||
'score' => 0,
|
||||
'date_added' => '2018-06-02 00:00:00',
|
||||
'date_associated' => '2018-06-02 00:00:00',
|
||||
'is_primary' => 0,
|
||||
'companywebsite' => 'https://bar.com',
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function testProfileFieldsReturnedWithPrimaryCompany(): void
|
||||
{
|
||||
$lead = $this->createMock(Lead::class);
|
||||
$lead->expects($this->once())
|
||||
->method('getProfileFields')
|
||||
->willReturn(
|
||||
[
|
||||
'email' => 'test@test.com',
|
||||
]
|
||||
);
|
||||
|
||||
$profileFields = $this->getPrimaryCompanyHelper()->getProfileFieldsWithPrimaryCompany($lead);
|
||||
|
||||
$this->assertEquals(['email' => 'test@test.com', 'companywebsite' => 'https://foo.com'], $profileFields);
|
||||
}
|
||||
|
||||
public function testPrimaryCompanyMergedIntoProfileFields(): void
|
||||
{
|
||||
$leadFields = [
|
||||
'email' => 'test@test.com',
|
||||
];
|
||||
|
||||
$profileFields = $this->getPrimaryCompanyHelper()->mergePrimaryCompanyWithProfileFields(1, $leadFields);
|
||||
|
||||
$this->assertEquals(['email' => 'test@test.com', 'companywebsite' => 'https://foo.com'], $profileFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PrimaryCompanyHelper
|
||||
*/
|
||||
private function getPrimaryCompanyHelper()
|
||||
{
|
||||
return new PrimaryCompanyHelper($this->leadRepository);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Helper;
|
||||
|
||||
use Mautic\CacheBundle\Cache\CacheProviderInterface;
|
||||
use Mautic\LeadBundle\Helper\SegmentCountCacheHelper;
|
||||
use PHPUnit\Framework\Assert;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
|
||||
class SegmentCountCacheHelperTest extends TestCase
|
||||
{
|
||||
private MockObject&CacheProviderInterface $cacheProviderMock;
|
||||
|
||||
private SegmentCountCacheHelper $segmentCountCacheHelper;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->cacheProviderMock = $this->createMock(CacheProviderInterface::class);
|
||||
$this->segmentCountCacheHelper = new SegmentCountCacheHelper($this->cacheProviderMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CacheItem instance using reflection since the constructor is private.
|
||||
*/
|
||||
private function createCacheItem(string $key, mixed $value = null, bool $isHit = false): CacheItem
|
||||
{
|
||||
$item = (new \ReflectionClass(CacheItem::class))->newInstanceWithoutConstructor();
|
||||
|
||||
$keyProperty = new \ReflectionProperty(CacheItem::class, 'key');
|
||||
$keyProperty->setValue($item, $key);
|
||||
|
||||
$valueProperty = new \ReflectionProperty(CacheItem::class, 'value');
|
||||
$valueProperty->setValue($item, $value);
|
||||
|
||||
$isHitProperty = new \ReflectionProperty(CacheItem::class, 'isHit');
|
||||
$isHitProperty->setValue($item, $isHit);
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
public function testGetSegmentContactCount(): void
|
||||
{
|
||||
$segmentId = 1;
|
||||
$cacheItem = $this->createCacheItem('segment.'.$segmentId.'.lead', 1, true);
|
||||
|
||||
$this->cacheProviderMock
|
||||
->method('getItem')
|
||||
->with('segment.'.$segmentId.'.lead')
|
||||
->willReturn($cacheItem);
|
||||
|
||||
$count = $this->segmentCountCacheHelper->getSegmentContactCount($segmentId);
|
||||
Assert::assertSame(1, $count);
|
||||
}
|
||||
|
||||
public function testSetSegmentContactCount(): void
|
||||
{
|
||||
$segmentId = 1;
|
||||
$count = 2;
|
||||
$cacheItem = $this->createCacheItem('segment.'.$segmentId.'.lead');
|
||||
|
||||
$this->cacheProviderMock
|
||||
->method('getItem')
|
||||
->with('segment.'.$segmentId.'.lead')
|
||||
->willReturn($cacheItem);
|
||||
|
||||
$this->cacheProviderMock
|
||||
->method('hasItem')
|
||||
->with('segment.'.$segmentId.'.lead.recount')
|
||||
->willReturn(false);
|
||||
|
||||
$this->cacheProviderMock
|
||||
->expects(self::never())
|
||||
->method('deleteItem')
|
||||
->with('segment.'.$segmentId.'.lead.recount');
|
||||
|
||||
$this->segmentCountCacheHelper->setSegmentContactCount($segmentId, $count);
|
||||
}
|
||||
|
||||
public function testSetSegmentContactCountIfRecountExist(): void
|
||||
{
|
||||
$segmentId = 1;
|
||||
$count = 2;
|
||||
$cacheItem = $this->createCacheItem('segment.'.$segmentId.'.lead');
|
||||
|
||||
$this->cacheProviderMock
|
||||
->method('getItem')
|
||||
->with('segment.'.$segmentId.'.lead')
|
||||
->willReturn($cacheItem);
|
||||
|
||||
$this->cacheProviderMock
|
||||
->expects(self::exactly(1))
|
||||
->method('hasItem')
|
||||
->with('segment.'.$segmentId.'.lead.recount')
|
||||
->willReturn(true);
|
||||
|
||||
$this->cacheProviderMock
|
||||
->expects(self::exactly(1))
|
||||
->method('deleteItem')
|
||||
->with('segment.'.$segmentId.'.lead.recount')
|
||||
->willReturn(true);
|
||||
|
||||
$this->segmentCountCacheHelper->setSegmentContactCount($segmentId, $count);
|
||||
}
|
||||
|
||||
public function testSetSegmentContactCountWithInvalidatedSegment(): void
|
||||
{
|
||||
$segmentId = 1;
|
||||
$cacheItem = $this->createCacheItem('segment.'.$segmentId.'.lead.recount');
|
||||
|
||||
$this->cacheProviderMock
|
||||
->expects(self::once())
|
||||
->method('getItem')
|
||||
->with('segment.'.$segmentId.'.lead.recount')
|
||||
->willReturn($cacheItem);
|
||||
|
||||
$this->cacheProviderMock
|
||||
->expects(self::once())
|
||||
->method('save')
|
||||
->with($cacheItem);
|
||||
|
||||
$this->segmentCountCacheHelper->invalidateSegmentContactCount($segmentId);
|
||||
}
|
||||
|
||||
public function testDecrementSegmentContactCountHasNoCache(): void
|
||||
{
|
||||
$segmentId = 1;
|
||||
$this->cacheProviderMock
|
||||
->expects(self::exactly(1))
|
||||
->method('hasItem')
|
||||
->with('segment.'.$segmentId.'.lead')
|
||||
->willReturn(false);
|
||||
$this->segmentCountCacheHelper->decrementSegmentContactCount($segmentId);
|
||||
}
|
||||
|
||||
public function testDeleteSegmentContactCountIfNotExist(): void
|
||||
{
|
||||
$segmentId = 1;
|
||||
$this->cacheProviderMock
|
||||
->expects(self::exactly(1))
|
||||
->method('hasItem')
|
||||
->with('segment.'.$segmentId.'.lead')
|
||||
->willReturn(false);
|
||||
$this->segmentCountCacheHelper->deleteSegmentContactCount($segmentId);
|
||||
}
|
||||
|
||||
public function testDeleteSegmentContactCountIfExist(): void
|
||||
{
|
||||
$segmentId = 1;
|
||||
$this->cacheProviderMock
|
||||
->expects(self::exactly(1))
|
||||
->method('hasItem')
|
||||
->with('segment.'.$segmentId.'.lead')
|
||||
->willReturn(true);
|
||||
|
||||
$this->cacheProviderMock
|
||||
->expects(self::exactly(1))
|
||||
->method('deleteItem')
|
||||
->with('segment.'.$segmentId.'.lead')
|
||||
->willReturn(true);
|
||||
|
||||
$this->segmentCountCacheHelper->deleteSegmentContactCount($segmentId);
|
||||
}
|
||||
|
||||
public function testDecrementSegmentContactCount(): void
|
||||
{
|
||||
$segmentId = 1;
|
||||
$cacheItem = $this->createCacheItem('segment.'.$segmentId.'.lead', 5, true);
|
||||
|
||||
$this->cacheProviderMock
|
||||
->method('hasItem')
|
||||
->willReturnCallback(function ($key) use ($segmentId) {
|
||||
if ($key === 'segment.'.$segmentId.'.lead') {
|
||||
return true;
|
||||
}
|
||||
if ($key === 'segment.'.$segmentId.'.lead.recount') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$this->cacheProviderMock
|
||||
->method('getItem')
|
||||
->willReturnCallback(function ($key) use ($segmentId, $cacheItem) {
|
||||
if ($key === 'segment.'.$segmentId.'.lead') {
|
||||
return $cacheItem;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
$this->cacheProviderMock
|
||||
->expects(self::once())
|
||||
->method('save')
|
||||
->with($cacheItem);
|
||||
|
||||
$this->segmentCountCacheHelper->decrementSegmentContactCount($segmentId);
|
||||
|
||||
// Verify the count was decremented from 5 to 4
|
||||
Assert::assertSame(4, $cacheItem->get());
|
||||
}
|
||||
|
||||
public function testDecrementSegmentCountIsNotNegative(): void
|
||||
{
|
||||
$segmentId = 1;
|
||||
$cacheItem = $this->createCacheItem('segment.'.$segmentId.'.lead', 0, true);
|
||||
|
||||
$this->cacheProviderMock
|
||||
->expects(self::exactly(2))
|
||||
->method('hasItem')
|
||||
->willReturnCallback(function ($key) use ($segmentId) {
|
||||
if ($key === 'segment.'.$segmentId.'.lead') {
|
||||
return true;
|
||||
}
|
||||
if ($key === 'segment.'.$segmentId.'.lead.recount') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
$this->cacheProviderMock
|
||||
->method('getItem')
|
||||
->willReturnCallback(function ($key) use ($segmentId, $cacheItem) {
|
||||
if (in_array($key, ['segment.'.$segmentId.'.lead', 'segment.'.$segmentId.'.lead.recount'])) {
|
||||
return $cacheItem;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
// Edge case. Should not decrement below 0.
|
||||
$this->segmentCountCacheHelper->decrementSegmentContactCount($segmentId);
|
||||
|
||||
// Assert that the cache item value is still 0 (not negative)
|
||||
Assert::assertSame(0, $cacheItem->get());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tests\Helper;
|
||||
|
||||
use Mautic\LeadBundle\Entity\LeadFieldRepository;
|
||||
use Mautic\LeadBundle\Entity\LeadRepository;
|
||||
use Mautic\LeadBundle\Helper\TokenHelper;
|
||||
|
||||
class TokenHelperTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private $lead = [
|
||||
'firstname' => 'Bob',
|
||||
'lastname' => 'Smith',
|
||||
'country' => '',
|
||||
'date' => '2000-05-05 12:45:50',
|
||||
'select' => 'first',
|
||||
'bool' => 1,
|
||||
'companies' => [
|
||||
[
|
||||
'companyzip' => '77008',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$reflectionProperty = new \ReflectionProperty(TokenHelper::class, 'parameters');
|
||||
$reflectionProperty->setAccessible(true);
|
||||
$reflectionProperty->setValue(null, [
|
||||
'date_format_dateonly' => 'F j, Y',
|
||||
'date_format_timeonly' => 'g:i a',
|
||||
]);
|
||||
|
||||
$fields = [
|
||||
'select' => [
|
||||
'type' => 'select',
|
||||
'properties' => 'a:1:{s:4:"list";a:2:{i:0;a:2:{s:5:"label";s:12:"First option";s:5:"value";s:5:"first";}i:1;a:2:{s:5:"label";s:13:"Second option";s:5:"value";s:6:"second";}}}',
|
||||
],
|
||||
'bool' => [
|
||||
'type' => 'boolean',
|
||||
'properties' => 'a:2:{s:2:"no";s:2:"No";s:3:"yes";s:3:"Yes";}',
|
||||
],
|
||||
];
|
||||
$leadFieldRepository = $this->createMock(LeadFieldRepository::class);
|
||||
$leadFieldRepository
|
||||
->method('getFields')
|
||||
->willReturn($fields);
|
||||
|
||||
$reflectionProperty = new \ReflectionProperty(LeadRepository::class, 'leadFieldRepository');
|
||||
$reflectionProperty->setAccessible(true);
|
||||
$reflectionProperty->setValue(null, $leadFieldRepository);
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testContactTokensAreReplaced(): void
|
||||
{
|
||||
$lead = [
|
||||
'firstname' => 'Bob',
|
||||
'lastname' => 'Smith',
|
||||
'country' => 'USA',
|
||||
'companies' => [
|
||||
[
|
||||
'companyzip' => '77008',
|
||||
],
|
||||
],
|
||||
];
|
||||
$token = '{contactfield=country}';
|
||||
|
||||
$tokenList = TokenHelper::findLeadTokens($token, $lead);
|
||||
$this->assertEquals([$token => 'USA'], $tokenList);
|
||||
}
|
||||
|
||||
public function testCompanyTokensAreReplaced(): void
|
||||
{
|
||||
$leads = [
|
||||
[
|
||||
'firstname' => 'Bob',
|
||||
'lastname' => 'Smith',
|
||||
'companies' => [
|
||||
[
|
||||
'companyzip' => '77009',
|
||||
'is_primary' => 0,
|
||||
],
|
||||
[
|
||||
'companyzip' => '77008',
|
||||
'is_primary' => 1,
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'firstname' => 'Jane',
|
||||
'lastname' => 'Smith',
|
||||
],
|
||||
[
|
||||
'firstname' => 'Joey',
|
||||
'lastname' => 'Smith',
|
||||
'companies' => [],
|
||||
],
|
||||
];
|
||||
|
||||
$token = '{contactfield=companyzip}';
|
||||
|
||||
$tokenList = TokenHelper::findLeadTokens($token, $leads[0]);
|
||||
$this->assertEquals([$token => '77008'], $tokenList);
|
||||
|
||||
$tokenList = TokenHelper::findLeadTokens($token, $leads[1]);
|
||||
$this->assertEquals([$token => ''], $tokenList);
|
||||
|
||||
$tokenList = TokenHelper::findLeadTokens($token, $leads[2]);
|
||||
$this->assertEquals([$token => ''], $tokenList);
|
||||
}
|
||||
|
||||
public function testDefaultValueIsUsed(): void
|
||||
{
|
||||
$lead = [
|
||||
'firstname' => 'Bob',
|
||||
'lastname' => 'Smith',
|
||||
'country' => '',
|
||||
'companies' => [
|
||||
[
|
||||
'companyzip' => '77008',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$token = '{contactfield=country|USA}';
|
||||
|
||||
$tokenList = TokenHelper::findLeadTokens($token, $lead);
|
||||
$this->assertEquals([$token => 'USA'], $tokenList);
|
||||
}
|
||||
|
||||
public function testValueIsUrlEncoded(): void
|
||||
{
|
||||
$lead = [
|
||||
'firstname' => 'Bob',
|
||||
'lastname' => 'Smith',
|
||||
'country' => 'Somewhere&Else',
|
||||
'companies' => [
|
||||
[
|
||||
'companyzip' => '77008',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$token = '{contactfield=country|true}';
|
||||
|
||||
$tokenList = TokenHelper::findLeadTokens($token, $lead);
|
||||
$this->assertEquals([$token => 'Somewhere%26Else'], $tokenList);
|
||||
}
|
||||
|
||||
public function testGetValueFromTokensWhenSomeValue(): void
|
||||
{
|
||||
$token = '{contactfield=website}';
|
||||
$tokens = [
|
||||
'{contactfield=website}' => 'https://mautic.org',
|
||||
];
|
||||
$this->assertEquals(
|
||||
'https://mautic.org',
|
||||
TokenHelper::getValueFromTokens($tokens, $token)
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetValueFromTokensWhenSomeValueWithDefaultValue(): void
|
||||
{
|
||||
$token = '{contactfield=website|ftp://default.url}';
|
||||
$tokens = [
|
||||
'{contactfield=website}' => 'https://mautic.org',
|
||||
];
|
||||
$this->assertEquals(
|
||||
'https://mautic.org',
|
||||
TokenHelper::getValueFromTokens($tokens, $token)
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetValueFromTokensWhenNoValueWithDefaultValue(): void
|
||||
{
|
||||
$token = '{contactfield=website|ftp://default.url}';
|
||||
$tokens = [
|
||||
'{contactfield=website}' => '',
|
||||
];
|
||||
$this->assertEquals(
|
||||
'ftp://default.url',
|
||||
TokenHelper::getValueFromTokens($tokens, $token)
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetValueFromTokensWhenNoValueWithoutDefaultValue(): void
|
||||
{
|
||||
$token = '{contactfield=website}';
|
||||
$tokens = [
|
||||
'{contactfield=website}' => '',
|
||||
];
|
||||
$this->assertEquals(
|
||||
'',
|
||||
TokenHelper::getValueFromTokens($tokens, $token)
|
||||
);
|
||||
}
|
||||
|
||||
public function testDateTimeFormatValue(): void
|
||||
{
|
||||
$token = '{contactfield=date|datetime}';
|
||||
$tokenList = TokenHelper::findLeadTokens($token, $this->lead);
|
||||
$this->assertNotSame($this->lead['date'], $tokenList[$token]);
|
||||
}
|
||||
|
||||
public function testDateFormatValue(): void
|
||||
{
|
||||
$token = '{contactfield=date|date}';
|
||||
$tokenList = TokenHelper::findLeadTokens($token, $this->lead);
|
||||
$this->assertNotSame($this->lead['date'], $tokenList[$token]);
|
||||
}
|
||||
|
||||
public function testTimeFormatValue(): void
|
||||
{
|
||||
$token = '{contactfield=date|time}';
|
||||
$tokenList = TokenHelper::findLeadTokens($token, $this->lead);
|
||||
$this->assertNotSame($this->lead['date'], $tokenList[$token]);
|
||||
}
|
||||
|
||||
public function testDateFormatForEmptyValue(): void
|
||||
{
|
||||
$lead = $this->lead;
|
||||
$lead['date'] = '';
|
||||
|
||||
$token = '{contactfield=date|time}';
|
||||
$tokenList = TokenHelper::findLeadTokens($token, $lead);
|
||||
$this->assertEmpty($tokenList[$token]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|int $result
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataLabelProvider')]
|
||||
public function testLabelFormatForSelect(string $token, $result): void
|
||||
{
|
||||
$lead = $this->lead;
|
||||
$tokenList = TokenHelper::findLeadTokens($token, $lead);
|
||||
$this->assertEquals($result, $tokenList[$token]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<int, int|string>>
|
||||
*/
|
||||
public static function dataLabelProvider(): array
|
||||
{
|
||||
return
|
||||
[
|
||||
['{contactfield=select}', 'first'],
|
||||
['{contactfield=select|label}', 'First option'],
|
||||
['{contactfield=bool}', 1],
|
||||
['{contactfield=bool|label}', 'Yes'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
[
|
||||
"Middle Earth",
|
||||
"Fillory"
|
||||
]
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Middle Earth": [
|
||||
"The Westlands"
|
||||
],
|
||||
"Fillory": [
|
||||
"Darkling Woods"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user