at the end of the day, it was inevitable

This commit is contained in:
Mo Elzubeir
2022-12-09 08:36:26 -06:00
commit 1218570914
1768 changed files with 887087 additions and 0 deletions
@@ -0,0 +1,119 @@
<?php
namespace UserBundle\Entity\Notification\Schedule;
use Doctrine\ORM\Mapping as ORM;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class DailyNotificationScheduleTest
*/
class DailyNotificationScheduleTest extends TestCase
{
/**
* @return void
*/
public function testComputeDate()
{
$schedule = DailyNotificationSchedule::create()
->setDays(DailyNotificationSchedule::DAYS_ALL)
->setTime(DailyNotificationSchedule::TIME_30_M);
$start = new \DateTime();
$start->setTime($start->format('H'), $start->format('i'), 0);
$end = clone $start;
$end->modify('+ 1 day');
$dates = $schedule->computeDates($start, $end);
/** @var \DateTime $date */
$checkStart = clone $start;
foreach ($dates as $date) {
$this->assertSame(
$checkStart->modify('+ 30 minute')->format('c'),
$date->format('c')
);
}
}
/**
* @return void
*/
public function testComputeDateWeekends()
{
$schedule = DailyNotificationSchedule::create()
->setDays(DailyNotificationSchedule::DAYS_WEEKENDS)
->setTime(DailyNotificationSchedule::TIME_4_H);
$start = new \DateTime();
$start->modify('first friday');
$start->setTime(23, 0, 0);
$end = clone $start;
$end->modify('+ 1 day');
$dates = $schedule->computeDates($start, $end);
/** @var \DateTime $date */
$checkStart = clone $start;
foreach ($dates as $date) {
$this->assertSame(
$checkStart->modify('+ 4 hour')->format('c'),
$date->format('c')
);
$this->assertLessThanOrEqual((int) $date->format('N'), 5);
}
}
/**
* @return void
*/
public function testComputeDateWeekdays()
{
$schedule = DailyNotificationSchedule::create()
->setDays(DailyNotificationSchedule::DAYS_WEEKDAYS)
->setTime(DailyNotificationSchedule::TIME_1_H);
$start = new \DateTime();
$start->modify('first sunday');
$start->setTime(23, 0, 0);
$end = clone $start;
$end->modify('+ 1 day');
$dates = $schedule->computeDates($start, $end);
/** @var \DateTime $date */
$checkStart = clone $start;
foreach ($dates as $date) {
$this->assertSame(
$checkStart->modify('+ 1 hour')->format('c'),
$date->format('c')
);
$this->assertGreaterThan((int) $date->format('N'), 5);
}
}
/**
* @return void
*/
public function testComputeDateWithSpecifiedDates()
{
$schedule = DailyNotificationSchedule::create()
->setDays(DailyNotificationSchedule::DAYS_ALL)
->setTime(DailyNotificationSchedule::TIME_15_M);
$start = new \DateTime();
$start
->setDate(2017, 6, 9)
->setTime(0, 0, 0);
$end = clone $start;
$end->modify('+ 30 minutes');
$dates = $schedule->computeDates($start, $end);
$this->assertCount(2, $dates);
$this->assertSame('2017-06-09 00:15:00', $dates[0]->format('Y-m-d H:i:s'));
$this->assertSame('2017-06-09 00:30:00', $dates[1]->format('Y-m-d H:i:s'));
}
}
@@ -0,0 +1,109 @@
<?php
namespace UserBundle\Entity\Notification\Schedule;
use Doctrine\ORM\Mapping as ORM;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class MonthlyNotificationScheduleTest
*
* @ORM\Entity
*/
class MonthlyNotificationScheduleTest extends TestCase
{
/**
* @return void
*/
public function testComputeDate()
{
$schedule = MonthlyNotificationSchedule::create()
->setDay(5)
->setHour(12)
->setMinute(35);
$start = date_create()->modify('first day of this month')->setTime(0, 0, 0);
$end = date_create()->modify('last day of next month')->setTime(0, 0, 0);
$dates = $schedule->computeDates($start, $end);
$this->assertCount(2, $dates);
$this->assertSame($dates[0]->format('Y-m-d'), date_create()->modify('first day of this month')->modify('4 day')->format('Y-m-d'));
$this->assertSame(5, (int) $dates[0]->format('j'));
$this->assertSame(12, (int) $dates[0]->format('H'));
$this->assertSame(35, (int) $dates[0]->format('i'));
$this->assertSame($dates[1]->format('Y-m-d'), date_create()->modify('first day of next month')->modify('4 day')->format('Y-m-d'));
$this->assertSame(5, (int) $dates[1]->format('j'));
$this->assertSame(12, (int) $dates[1]->format('H'));
$this->assertSame(35, (int) $dates[1]->format('i'));
$schedule = MonthlyNotificationSchedule::create()
->setDay(2)
->setHour(8)
->setMinute(50);
$start = date_create()->modify('first day of this month')->modify('1 day')->setTime(0, 0, 0);
$end = date_create()->modify('next month')->modify('first day of next month')->modify('1 day')->setTime(0, 0, 0);
$dates = $schedule->computeDates($start, $end);
$this->assertCount(3, $dates);
$this->assertSame($dates[0]->format('Y-m-d'), date_create()->modify('first day of this month')->modify('1 day')->format('Y-m-d'));
$this->assertSame(2, (int) $dates[0]->format('j'));
$this->assertSame(8, (int) $dates[0]->format('H'));
$this->assertSame(50, (int) $dates[0]->format('i'));
$this->assertSame($dates[1]->format('Y-m-d'), date_create()->modify('first day of next month')->modify('1 day')->format('Y-m-d'));
$this->assertSame(2, (int) $dates[1]->format('j'));
$this->assertSame(8, (int) $dates[1]->format('H'));
$this->assertSame(50, (int) $dates[1]->format('i'));
$this->assertSame($dates[2]->format('Y-m-d'), date_create()->modify('next month')->modify('first day of next month')->modify('1 day')->format('Y-m-d'));
$this->assertSame(2, (int) $dates[2]->format('j'));
$this->assertSame(8, (int) $dates[2]->format('H'));
$this->assertSame(50, (int) $dates[2]->format('i'));
}
/**
* @return void
*/
public function testComputeDateLast()
{
$schedule = MonthlyNotificationSchedule::create()
->setDay(MonthlyNotificationSchedule::DAY_LAST)
->setHour(12)
->setMinute(35);
$start = date_create()->modify('first day of this month')->setTime(0, 0, 0);
$end = date_create()->modify('last day of next month')->setTime(0, 0, 0);
$dates = $schedule->computeDates($start, $end);
$this->assertCount(2, $dates);
$this->assertSame($dates[0]->format('Y-m-d'), date_create()->modify('last day of this month')->format('Y-m-d'));
$this->assertSame(12, (int) $dates[0]->format('H'));
$this->assertSame(35, (int) $dates[0]->format('i'));
$this->assertSame($dates[1]->format('Y-m-d'), date_create()->modify('last day of next month')->format('Y-m-d'));
$this->assertSame(12, (int) $dates[1]->format('H'));
$this->assertSame(35, (int) $dates[1]->format('i'));
$schedule = MonthlyNotificationSchedule::create()
->setDay(MonthlyNotificationSchedule::DAY_LAST)
->setHour(2)
->setMinute(15);
$start = date_create()->modify('last day of this month')->setTime(0, 0, 0);
$end = date_create()->modify('first day of next month')->setTime(0, 0, 0);
$dates = $schedule->computeDates($start, $end);
$this->assertCount(1, $dates);
$this->assertSame($dates[0]->format('Y-m-d'), date_create()->modify('last day of this month')->format('Y-m-d'));
$this->assertSame(2, (int) $dates[0]->format('H'));
$this->assertSame(15, (int) $dates[0]->format('i'));
}
}
@@ -0,0 +1,117 @@
<?php
namespace UserBundle\Entity\Notification\Schedule;
use Doctrine\ORM\Mapping as ORM;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class WeeklyNotificationSchedule
*
* @ORM\Entity
*/
class WeeklyNotificationScheduleTest extends TestCase
{
/**
* @return void
*/
public function testComputeDate()
{
$schedule = WeeklyNotificationSchedule::create()
->setPeriod(WeeklyNotificationSchedule::PERIOD_SECOND)
->setDay(WeeklyNotificationSchedule::DAY_FRIDAY)
->setHour(12)
->setMinute(35);
$start = date_create()->modify('first day of this month')->setTime(0, 0, 0);
$end = date_create()->modify('second friday of next month')->setTime(0, 0, 0);
$dates = $schedule->computeDates($start, $end);
$this->assertCount(2, $dates);
$this->assertSame($dates[0]->format('Y-m-d'), date_create()->modify('second friday of this month')->format('Y-m-d'));
$this->assertSame(12, (int) $dates[0]->format('H'));
$this->assertSame(35, (int) $dates[0]->format('i'));
$this->assertSame($dates[1]->format('Y-m-d'), date_create()->modify('second friday of next month')->format('Y-m-d'));
$this->assertSame(12, (int) $dates[1]->format('H'));
$this->assertSame(35, (int) $dates[1]->format('i'));
$schedule = WeeklyNotificationSchedule::create()
->setPeriod(WeeklyNotificationSchedule::PERIOD_FIRST)
->setDay(WeeklyNotificationSchedule::DAY_TUESDAY);
$start = date_create()->modify('first day of this month')->setTime(0, 0, 0);
$end = date_create()->modify('second friday of next month')->setTime(0, 0, 0);
$dates = $schedule->computeDates($start, $end);
$this->assertCount(2, $dates);
$this->assertSame($dates[0]->format('Y-m-d'), date_create()->modify('first tuesday of this month')->format('Y-m-d'));
$this->assertSame(0, (int) $dates[0]->format('H'));
$this->assertSame(0, (int) $dates[0]->format('i'));
$this->assertSame($dates[1]->format('Y-m-d'), date_create()->modify('first tuesday of next month')->format('Y-m-d'));
$this->assertSame(0, (int) $dates[1]->format('H'));
$this->assertSame(0, (int) $dates[1]->format('i'));
}
/**
* @return void
*/
public function testComputeDateEvery()
{
$schedule = WeeklyNotificationSchedule::create()
->setPeriod(WeeklyNotificationSchedule::PERIOD_EVERY)
->setDay(WeeklyNotificationSchedule::DAY_MONDAY)
->setHour(10)
->setMinute(45);
$start = date_create()->modify('first day of this month')->setTime(0, 0, 0);
$end = date_create()->modify('last day of next month')->setTime(0, 0, 0);
$dates = $schedule->computeDates($start, $end);
/** @var \DateTime $date */
foreach ($dates as $date) {
$this->assertSame(
1,
(int) $date->format('N')
);
$this->assertSame(10, (int) $date->format('H'));
$this->assertSame(45, (int) $date->format('i'));
}
}
/**
* @return void
*/
public function testComputeDateLast()
{
$schedule = WeeklyNotificationSchedule::create()
->setPeriod(WeeklyNotificationSchedule::PERIOD_LAST)
->setDay(WeeklyNotificationSchedule::DAY_SUNDAY)
->setHour(10)
->setMinute(45);
$start = date_create()->modify('first day of this month')->setTime(0, 0, 0);
$end = date_create()->modify('next month')->modify('last day of next month')->setTime(0, 0, 0);
$dates = $schedule->computeDates($start, $end);
$this->assertCount(3, $dates);
$this->assertSame($dates[0]->format('Y-m-d'), date_create()->modify('last sunday of this month')->format('Y-m-d'));
$this->assertSame(10, (int) $dates[0]->format('H'));
$this->assertSame(45, (int) $dates[0]->format('i'));
$this->assertSame($dates[1]->format('Y-m-d'), date_create()->modify('last sunday of next month')->format('Y-m-d'));
$this->assertSame(10, (int) $dates[1]->format('H'));
$this->assertSame(45, (int) $dates[1]->format('i'));
$this->assertSame($dates[2]->format('Y-m-d'), date_create()->modify('next month')->modify('last sunday of next month')->format('Y-m-d'));
$this->assertSame(10, (int) $dates[2]->format('H'));
$this->assertSame(45, (int) $dates[2]->format('i'));
}
}
@@ -0,0 +1,103 @@
<?php
namespace UserBundle\Entity\Recipient;
use Tests\AppTestCase;
use UserBundle\Entity\User;
/**
* Class PersonRecipientTest
*
* @package UserBundle\Entity
*/
class PersonRecipientTest extends AppTestCase
{
/**
* @var PersonRecipient
*/
private $recipient;
/**
* @return void
*/
public function testSetFirstNameWithoutAssignedUser()
{
$this->recipient->setFirstName('first name');
$this->assertEquals('first name', $this->recipient->getFirstName());
}
/**
* @return void
*/
public function testSetFirstNameWithAssignedUser()
{
$user = new User();
$this->recipient
->setAssociatedUser($user)
->setFirstName('first name');
$this->assertEquals('first name', $this->recipient->getFirstName());
$this->assertEquals('first name', $user->getFirstName());
}
/**
* @return void
*/
public function testSetLastNameWithoutAssignedUser()
{
$this->recipient->setLastName('last name');
$this->assertEquals('last name', $this->recipient->getLastName());
}
/**
* @return void
*/
public function testSetLastNameWithAssignedUser()
{
$user = new User();
$this->recipient
->setAssociatedUser($user)
->setLastName('last name');
$this->assertEquals('last name', $this->recipient->getLastName());
$this->assertEquals('last name', $user->getLastName());
}
/**
* @return void
*/
public function testSetEmailWithoutAssignedUser()
{
$this->recipient->setEmail('test@test.test');
$this->assertEquals('test@test.test', $this->recipient->getEmail());
}
/**
* @return void
*/
public function testSetEmailWithAssignedUser()
{
$user = new User();
$this->recipient
->setAssociatedUser($user)
->setEmail('test@test.test');
$this->assertEquals('test@test.test', $this->recipient->getEmail());
$this->assertEquals('test@test.test', $user->getEmail());
}
/**
* Sets up the fixture, for example, open a network connection.
* This method is called before a test is executed.
*
* @return void
*/
protected function setUp()
{
$this->recipient = new PersonRecipient();
}
}
@@ -0,0 +1,43 @@
<?php
namespace UserBundle\Entity\Traits;
use Tests\AppTestCase;
use UserBundle\Enum\AppLimitEnum;
/**
* Class LimitAwareTraitTest
*
* @package UserBundle\Entity\Traits
*/
class LimitAwareTraitTest extends AppTestCase
{
/**
* @var LimitAwareTrait
*/
private $trait;
/**
* @return void
*/
public function testLimitValue()
{
/** @var AppLimitEnum $value */
foreach (AppLimitEnum::getValues() as $value) {
$this->trait->setLimitValue($value, 1);
$this->assertEquals(1, $this->trait->getLimitValue($value));
}
}
/**
* Sets up the fixture, for example, open a network connection.
* This method is called before a test is executed.
*
* @return void
*/
protected function setUp()
{
$this->trait = $this->getMockForTrait(LimitAwareTrait::class);
}
}
+221
View File
@@ -0,0 +1,221 @@
<?php
namespace UserBundle\Entity;
use Tests\AppTestCase;
use UserBundle\Entity\Recipient\PersonRecipient;
use UserBundle\Entity\Subscription\AbstractSubscription;
use UserBundle\Entity\Subscription\PersonalSubscription;
use UserBundle\Enum\AppLimitEnum;
use UserBundle\Enum\AppPermissionEnum;
/**
* Class UserTest
*
* @package UserBundle\Entity
*/
class UserTest extends AppTestCase
{
/**
* @var Plan|\PHPUnit_Framework_MockObject_MockObject
*/
private $plan;
/**
* @var AbstractSubscription|\PHPUnit_Framework_MockObject_MockObject
*/
private $subscription;
/**
* @var User|\PHPUnit_Framework_MockObject_MockObject
*/
private $user;
/**
* @return void
*/
public function testIsAllowedTo()
{
$this->plan->setAnalytics(true);
$this->assertTrue($this->user->isAllowedTo(AppPermissionEnum::analytics()));
$this->plan->setAnalytics(false);
$this->assertFalse($this->user->isAllowedTo(AppPermissionEnum::analytics()));
}
/**
* @return void
*/
public function testUseLimit()
{
/** @var AppLimitEnum $value */
foreach (AppLimitEnum::getValues() as $value) {
$this->plan->setLimitValue($value, 4);
$this->subscription->setLimitValue($value, 1);
$this->user->useLimit($value);
$this->assertEquals(2, $this->user->getUsedLimit($value));
$this->user->useLimit($value, 2);
$this->assertEquals(4, $this->user->getUsedLimit($value));
}
}
/**
* @return void
*/
public function testReleaseLimit()
{
/** @var AppLimitEnum $value */
foreach (AppLimitEnum::getValues() as $value) {
$this->subscription->setLimitValue($value, 4);
$this->user->releaseLimit($value);
$this->assertEquals(3, $this->user->getUsedLimit($value));
$this->user->releaseLimit($value, 2);
$this->assertEquals(1, $this->user->getUsedLimit($value));
}
}
/**
* @expectedException \AppBundle\Exception\LimitExceedException
*
* @return void
*/
public function testUseLimitExceed()
{
$this->plan->setSearchesPerDay(4);
$this->subscription->setSearchesPerDay(3);
$this->user->useLimit(AppLimitEnum::searches(), 2);
}
/**
* @return void
*/
public function testGetRestrictions()
{
$limits = [];
/** @var AppLimitEnum $value */
foreach (AppLimitEnum::getValues() as $value) {
$limit = mt_rand(5, 10);
$current = mt_rand(0, $limit);
$limits[$value->getValue()] = [
'limit' => $limit,
'current' => $current,
];
$this->plan->setLimitValue($value, $limit);
$this->subscription->setLimitValue($value, $current);
}
$permissions = [];
/** @var AppPermissionEnum $value */
foreach (AppPermissionEnum::getValues() as $value) {
$allow = (boolean) mt_rand(0, 1);
$permissions[$value->getValue()] = $allow;
$this->plan->setPermission($value, $allow);
}
$restrictions = $this->user->getRestrictions();
$this->assertCount(2, $restrictions);
$this->assertArrayHasKey('limits', $restrictions);
$this->assertArrayHasKey('permissions', $restrictions);
$this->assertEquals($limits, $restrictions['limits']);
$this->assertEquals($permissions, $restrictions['permissions']);
}
/**
* @return void
*/
public function setFirstNameWithoutRecipient()
{
$this->user->setFirstName('first name');
$this->assertEquals('first name', $this->user->getFirstName());
}
/**
* @return void
*/
public function setFirstNameWithRecipient()
{
$recipient = new PersonRecipient();
$this->user
->setRecipient($recipient)
->setFirstName('first name');
$this->assertEquals('first name', $this->user->getFirstName());
$this->assertEquals('first name', $recipient->getFirstName());
}
/**
* @return void
*/
public function setLastNameWithoutRecipient()
{
$this->user->setLastName('last name');
$this->assertEquals('last name', $this->user->getLastName());
}
/**
* @return void
*/
public function setLastNameWithRecipient()
{
$recipient = new PersonRecipient();
$this->user
->setRecipient($recipient)
->setLastName('last name');
$this->assertEquals('last name', $this->user->getLastName());
$this->assertEquals('last name', $recipient->getLastName());
}
/**
* @return void
*/
public function setEmailWithoutRecipient()
{
$this->user->setEmail('test@test.test');
$this->assertEquals('test@test.test', $this->user->getEmail());
}
/**
* @return void
*/
public function setEmailWithRecipient()
{
$recipient = new PersonRecipient();
$this->user
->setRecipient($recipient)
->setEmail('test@test.test');
$this->assertEquals('test@test.test', $this->user->getEmail());
$this->assertEquals('test@test.test', $recipient->getEmail());
}
/**
* Sets up the fixture, for example, open a network connection.
* This method is called before a test is executed.
*
* @return void
*/
protected function setUp()
{
$this->plan = new Plan();
$this->subscription = new PersonalSubscription();
$this->subscription->setPlan($this->plan);
$this->user = new User();
$this->user->setBillingSubscription($this->subscription);
}
}
@@ -0,0 +1,126 @@
<?php
namespace UserBundle\Form\Type;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\Context\ExecutionContext;
use Symfony\Component\Validator\Violation\ConstraintViolationBuilder;
/**
* Class ColorTypeTest
*
* @package UserBundle\Form\Type
*/
class ColorTypeTest extends TestCase
{
/**
* @var ColorType
*/
private $type;
/**
* Sets up the fixture, for example, open a network connection.
* This method is called before a test is executed.
*
* @return void
*/
protected function setUp()
{
$this->type = new ColorType();
}
/**
* @dataProvider validProvider
*
* @param mixed $color Validated color.
*
* @return void
*/
public function testValidateSuccess($color)
{
$context = $this->getMockBuilder(ExecutionContext::class)
->disableOriginalConstructor()
->setMethods([ 'buildViolation' ])
->getMock();
$context->expects($this->never())
->method('buildViolation')
->willReturnCallback(function () {
$mock = $this->getMockBuilder(ConstraintViolationBuilder::class)
->disableOriginalConstructor()
->setMethods([ 'addViolation' ])
->getMock();
$mock->expects($this->never())
->method('addViolation');
return $mock;
});
$this->type->validate($color, $context);
}
/**
* @dataProvider notValidProvider
*
* @param mixed $color Validated color.
*
* @return void
*/
public function testValidateFail($color)
{
$context = $this->getMockBuilder(ExecutionContext::class)
->disableOriginalConstructor()
->setMethods([ 'buildViolation' ])
->getMock();
$context->expects($this->once())
->method('buildViolation')
->willReturnCallback(function () {
$mock = $this->getMockBuilder(ConstraintViolationBuilder::class)
->disableOriginalConstructor()
->setMethods([ 'addViolation' ])
->getMock();
$mock->expects($this->once())
->method('addViolation');
return $mock;
});
$this->type->validate($color, $context);
}
/**
* @return array
*/
public function validProvider()
{
return [
[ 'rgba(100, 100, 100, .0)' ],
[ 'rgba(125, 100, 100, 1.0)' ],
[ 'rgba(255, 255, 255, 1)' ],
[ 'rgba(1, 12, 123, .0000034)' ],
[ 'rgba(43, 234, 23, .2)' ],
[ 'rgba(0, 0, 0, .1)' ],
];
}
/**
* @return array
*/
public function notValidProvider()
{
return [
[ 'rgba(100, 100, 100, .0' ],
[ 'rgba(125, 256, 100, 1.0)' ],
[ 'rgba(255, 255, 255)' ],
[ 'rgba(1, 12, 123, -1)' ],
[ 'rgba(43, 234, -23, .2)' ],
[ 'rgba(0, 0, 0, 1.001)' ],
[ 'rgba(0, 20, 0, 100%)' ],
];
}
}
@@ -0,0 +1,88 @@
<?php
namespace UserBundle\Manager\Notification;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Tests\AppTestCaseTrait;
use UserBundle\Entity\Notification\Notification;
use UserBundle\Entity\Notification\NotificationTheme;
use UserBundle\Entity\Notification\NotificationThemeOptions;
use UserBundle\Enum\ThemeTypeEnum;
use UserBundle\Manager\Notification\Model\FeedData;
/**
* Class AbstractSendableNotificationTest
*
* @package UserBundle\Manager\Notification
*/
abstract class AbstractSendableNotificationTest extends KernelTestCase
{
use AppTestCaseTrait;
const PATTERN_TPL = '/%s[^\{]*?\{[^\}]*%s[^\}]*\}/i';
/**
* @var EngineInterface
*/
private static $templating;
/**
* @beforeClass
*
* @return void
*/
public static function getServices()
{
self::bootKernel();
self::$templating = self::$kernel->getContainer()->get('templating');
}
/**
* @param ThemeTypeEnum $themeType A ThemeTypeEnum instance.
* @param array $diffs Notification theme diffs.
* @param FeedData[] $data Array of feed data.
*
* @return string
*/
protected function render(ThemeTypeEnum $themeType, array $diffs = [], array $data = [])
{
$notification = Notification::create()
->setTheme(
NotificationTheme::create()
->setEnhanced(NotificationThemeOptions::createDefault())
->setPlain(NotificationThemeOptions::createDefault())
)
->setThemeType($themeType);
switch ($themeType->getValue()) {
case ThemeTypeEnum::ENHANCED:
$notification->setEnhancedThemeOptionsDiff($diffs);
break;
case ThemeTypeEnum::PLAIN:
$notification->setPlainThemeOptionsDiff($diffs);
break;
default:
throw new \DomainException('Unhandled theme type: '. $themeType->getValue());
}
$sendableNotification = new SendableNotification(
new SendableNotificationConfig(
0,
0,
0,
0,
'<p>empty</p>',
0
),
$notification,
$data
);
return $sendableNotification->render(self::$templating);
}
}
@@ -0,0 +1,862 @@
<?php
namespace UserBundle\Manager\Notification;
use CacheBundle\Entity\Comment;
use IndexBundle\Index\Strategy\IndexStrategyInterface;
use Symfony\Component\DomCrawler\Crawler;
use Tests\Helper\HtmlAsserter;
use UserBundle\Entity\User;
use UserBundle\Enum\ThemeOptionsTableOfContentsEnum;
use UserBundle\Enum\ThemeOptionsUserCommentsEnum;
use UserBundle\Enum\ThemeTypeEnum;
use UserBundle\Manager\Notification\Model\FeedData;
use IndexBundle\Model\ArticleDocument;
/**
* Class NotificationContentRenderTest
*
* @package UserBundle\Manager\Notification
*/
class NotificationContentRenderTest extends AbstractSendableNotificationTest
{
const FIRST_FEED_COUNT = 1;
const SECOND_FEED_COUNT = 1;
const THIRD_FEED_COUNT = 0;
/**
* @return void
*/
public function testSummaryAndConclusion()
{
//
// Plain
//
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::simple(),
])
->hasNotNode('.email-summary')
->hasNotNode('.email-conclusion');
$this->createAsserter(ThemeTypeEnum::plain(), [
'summary' => 'summary text',
'conclusion' => 'conclusion text',
])
->with('.email-summary')->contains('summary text')->end()
->with('.email-conclusion')->contains('conclusion text')->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'conclusion' => 'conclusion text',
])
->hasNotNode('.email-summary')
->with('.email-conclusion')->contains('conclusion text')->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'summary' => 'summary text',
])
->with('.email-summary')->contains('summary text')->end()
->hasNotNode('.email-conclusion');
//
// Enhanced
//
$this->createAsserter(ThemeTypeEnum::enhanced())
->hasNotNode('.email-summary')
->hasNotNode('.email-conclusion');
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'summary' => 'summary text',
'conclusion' => 'conclusion text',
])
->with('.email-summary')->contains('summary text')->end()
->with('.email-conclusion')->contains('conclusion text')->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'conclusion' => 'conclusion text',
])
->hasNotNode('.email-summary')
->with('.email-conclusion')->contains('conclusion text')->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'summary' => 'summary text',
])
->with('.email-summary')->contains('summary text')->end()
->hasNotNode('.email-conclusion');
}
/**
* @return void
*/
public function testTableOfContentsPlain()
{
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::no(),
'content:showInfo:articleCount' => true,
])
->hasNotNode('.table-of-contents')->end()
->hasNotNode('.table-of-contents .feed-document-count')->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::no(),
'content:showInfo:articleCount' => false,
])
->hasNotNode('.table-of-contents')->end()
->hasNotNode('.table-of-contents .feed-document-count')->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::simple(),
'content:showInfo:articleCount' => true,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->with('.feed-document-count')
->child(0)->contains(sprintf('(%d articles)', self::FIRST_FEED_COUNT))->end()
->child(1)->contains(sprintf('(%d articles)', self::SECOND_FEED_COUNT))->end()
->child(2)->contains(sprintf('(%d articles)', self::THIRD_FEED_COUNT))->end()
->end()
->hasNotNode('.documents .document')
->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::simple(),
'content:showInfo:articleCount' => false,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->hasNotNode('.feed-document-count')
->hasNotNode('.documents .document')
->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::headline(),
'content:showInfo:articleCount' => true,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->with('.feed-document-count')
->child(0)->contains(sprintf('(%d articles)', self::FIRST_FEED_COUNT))->end()
->child(1)->contains(sprintf('(%d articles)', self::SECOND_FEED_COUNT))->end()
->child(2)->contains(sprintf('(%d articles)', self::THIRD_FEED_COUNT))->end()
->end()
->with('.documents .document')
->child(0)
->with('a')
->hasAttr('href', 'http://permalink')
->contains('Feed1 Document1', true)
->end()
->end()
->end()
->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::headline(),
'content:showInfo:articleCount' => false,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->hasNotNode('.feed-document-count')
->with('.documents .document')
->child(0)
->with('a')
->hasAttr('href', 'http://permalink')
->contains('Feed1 Document1', true)
->end()
->end()
->end()
->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::headlineSourceDate(),
'content:showInfo:articleCount' => true,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->with('.feed-document-count')
->child(0)->contains(sprintf('(%d articles)', self::FIRST_FEED_COUNT))->end()
->child(1)->contains(sprintf('(%d articles)', self::SECOND_FEED_COUNT))->end()
->child(2)->contains(sprintf('(%d articles)', self::THIRD_FEED_COUNT))->end()
->end()
->with('.documents .document')
->child(0)
->with('a')
->hasAttr('href', 'http://permalink')
->contains('Feed1 Document1 | CNN | January 01, 2017')
->end()
->end()
->end()
->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::headlineSourceDate(),
'content:showInfo:articleCount' => false,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->hasNotNode('.feed-document-count')
->with('.documents .document')
->child(0)
->with('a')
->hasAttr('href', 'http://permalink')
->contains('Feed1 Document1 | CNN | January 01, 2017')
->end()
->end()
->end()
->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::sourceHeadlineDate(),
'content:showInfo:articleCount' => true,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->with('.feed-document-count')
->child(0)->contains(sprintf('(%d articles)', self::FIRST_FEED_COUNT))->end()
->child(1)->contains(sprintf('(%d articles)', self::SECOND_FEED_COUNT))->end()
->child(2)->contains(sprintf('(%d articles)', self::THIRD_FEED_COUNT))->end()
->end()
->with('.documents .document')
->child(0)
->with('a')
->hasAttr('href', 'http://permalink')
->contains('CNN | Feed1 Document1 | January 01, 2017')
->end()
->end()
->end()
->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::sourceHeadlineDate(),
'content:showInfo:articleCount' => false,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->hasNotNode('.feed-document-count')
->with('.documents .document')
->child(0)
->with('a')
->hasAttr('href', 'http://permalink')
->contains('CNN | Feed1 Document1 | January 01, 2017')
->end()
->end()
->end()
->end();
}
/**
* @return void
*/
public function testTableOfContainsEnhanced()
{
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::no(),
'content:showInfo:articleCount' => true,
])
->hasNotNode('.table-of-contents')->end()
->hasNotNode('.table-of-contents .feed-document-count')->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::no(),
'content:showInfo:articleCount' => false,
])
->hasNotNode('.table-of-contents')->end()
->hasNotNode('.table-of-contents .feed-document-count')->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::simple(),
'content:showInfo:articleCount' => true,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->with('.feed-document-count')
->child(0)->contains(sprintf('%d articles', self::FIRST_FEED_COUNT))->end()
->child(1)->contains(sprintf('%d articles', self::SECOND_FEED_COUNT))->end()
->child(2)->contains(sprintf('%d articles', self::THIRD_FEED_COUNT))->end()
->end()
->hasNotNode('.documents .document')
->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::simple(),
'content:showInfo:articleCount' => false,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->hasNotNode('.feed-document-count')
->hasNotNode('.documents .document')
->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::headline(),
'content:showInfo:articleCount' => true,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->with('.feed-document-count')
->child(0)->contains(sprintf('%d articles', self::FIRST_FEED_COUNT))->end()
->child(1)->contains(sprintf('%d articles', self::SECOND_FEED_COUNT))->end()
->child(2)->contains(sprintf('%d articles', self::THIRD_FEED_COUNT))->end()
->end()
->with('.documents .document')
->child(0)
->with('a')
->hasAttr('href', 'http://permalink')
->contains('Feed1 Document1', true)
->end()
->end()
->end()
->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::headline(),
'content:showInfo:articleCount' => false,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->hasNotNode('.feed-document-count')
->with('.documents .document')
->child(0)
->with('a')
->hasAttr('href', 'http://permalink')
->contains('Feed1 Document1', true)
->end()
->end()
->end()
->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::headlineSourceDate(),
'content:showInfo:articleCount' => true,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->with('.feed-document-count')
->child(0)->contains(sprintf('%d articles', self::FIRST_FEED_COUNT))->end()
->child(1)->contains(sprintf('%d articles', self::SECOND_FEED_COUNT))->end()
->child(2)->contains(sprintf('%d articles', self::THIRD_FEED_COUNT))->end()
->end()
->with('.documents .document')
->child(0)
->with('a')
->hasAttr('href', 'http://permalink')
->contains('Feed1 Document1 | CNN | January 01, 2017')
->end()
->end()
->end()
->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::headlineSourceDate(),
'content:showInfo:articleCount' => false,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->hasNotNode('.feed-document-count')
->with('.documents .document')
->child(0)
->with('a')
->hasAttr('href', 'http://permalink')
->contains('Feed1 Document1 | CNN | January 01, 2017')
->end()
->end()
->end()
->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::sourceHeadlineDate(),
'content:showInfo:articleCount' => true,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->with('.feed-document-count')
->child(0)->contains(sprintf('%d articles', self::FIRST_FEED_COUNT))->end()
->child(1)->contains(sprintf('%d articles', self::SECOND_FEED_COUNT))->end()
->child(2)->contains(sprintf('%d articles', self::THIRD_FEED_COUNT))->end()
->end()
->with('.documents .document')
->child(0)
->with('a')
->hasAttr('href', 'http://permalink')
->contains('CNN | Feed1 Document1 | January 01, 2017')
->end()
->end()
->end()
->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'content:showInfo:tableOfContents' => ThemeOptionsTableOfContentsEnum::sourceHeadlineDate(),
'content:showInfo:articleCount' => false,
])
->with('.table-of-contents')
->with('.feed-name')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->hasNotNode('.feed-document-count')
->with('.documents .document')
->child(0)
->with('a')
->hasAttr('href', 'http://permalink')
->contains('CNN | Feed1 Document1 | January 01, 2017')
->end()
->end()
->end()
->end();
}
/**
* @return void
*/
public function testContentPlain()
{
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:sectionDivider' => false,
'content:showInfo:sourceCountry' => false,
'content:showInfo:userComments' => ThemeOptionsUserCommentsEnum::no(),
'content:showInfo:images' => false,
])
->with('.content')
->with('.feed-title')
->child(0)->contains('feed1:')->end()
->child(1)->contains('feed2:')->end()
->child(2)->contains('feed3:')->end()
->end()
->hasNotNode('.feed-title img')
->notContains('<b>Comments</b>')
->with('.documents')
->hasNotNode('.document-aside')
->with('.document')
->child(0)
->with('.document-headline a')
->hasAttr('href', 'http://permalink')
->contains('Feed1 Document1')
->end()
->with('.document-source')
->contains('CNN')
->notContains('(Russian)')
->end()
->with('.document-author')->contains('John Smith')->end()
->with('.document-date')
->contains('-')
->contains(date_create('2017-01-01 10:00:00')->format('F d, Y H:i'))
->end()
->with('.document-content')->contains('Feed1 Document1 Main')->end()
->hasNotNode('.comments')
->hasNotNode('.document-image')
->end()
->child(1)
->with('.document-headline a')
->hasAttr('href', 'http://permalink_next')
->contains('Feed2 Document1')
->end()
->with('.document-source')
->contains('Test')
->notContains('(USA)')
->end()
->hasNotNode('.document-author')
->with('.document-date')
->contains('-')
->contains(date_create('2017-01-10 10:00:00')->format('F d, Y H:i'))
->end()
->with('.document-content')->contains('Feed2 Document1 Main')->end()
->hasNotNode('.comments')
->hasNotNode('.document-image')
->end()
->end()
->end()
->hasNotNode('.feed-divider')
->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:sectionDivider' => true,
'content:showInfo:sourceCountry' => true,
'content:showInfo:userComments' => ThemeOptionsUserCommentsEnum::withAuthorDate(),
'content:showInfo:images' => true,
])
->with('.content')
->with('.feed-title')
->child(0)->contains('feed1:')->end()
->child(1)->contains('feed2:')->end()
->child(2)->contains('feed3:')->end()
->end()
->hasNotNode('.feed-title img')
->notContains('<b>Comments</b>')
->with('.documents')
->hasNotNode('.document-aside')
->with('.document')
->child(0)
->with('.document-headline a')
->hasAttr('href', 'http://permalink')
->contains('Feed1 Document1')
->end()
->with('.document-source')
->contains('CNN')
->contains('(Russian)')
->end()
->with('.document-author')->contains('John Smith')->end()
->with('.document-date')
->contains('-')
->contains(date_create('2017-01-01 10:00:00')->format('F d, Y H:i'))
->end()
->with('.document-content')->contains('Feed1 Document1 Main')->end()
->hasNotNode('.comments')
->hasNotNode('.document-image')
->end()
->child(1)
->with('.document-headline a')
->hasAttr('href', 'http://permalink_next')
->contains('Feed2 Document1')
->end()
->with('.document-source')->contains('Test')->end()
->hasNotNode('.document-author')
->with('.document-date')
->contains('-')
->contains(date_create('2017-01-10 10:00:00')->format('F d, Y H:i'))
->end()
->with('.document-content')->contains('Feed2 Document1 Main')->end()
->with('.comments .comment')
->child(0)
->with('.comment-title')->contains('Feed2 Document1 comment1 title')->end()
->with('.comment-author')
->contains('User1 first name')
->contains('User1 last name')
->end()
->with('.comment-date')
->contains(date_create('2017-01-02 10:00:00')->format('F d, Y H:i'))
->end()
->with('.comment-body')->contains('Feed2 Document1 comment1')->end()
->end()
->child(1)
->hasNotNode('.comment-title')
->with('.comment-author')
->contains('User2 first name')
->contains('User2 last name')
->end()
->with('.comment-date')
->contains(date_create('2017-01-03 10:00:00')->format('F d, Y H:i'))
->end()
->with('.comment-body')->contains('Feed2 Document1 comment2')->end()
->end()
->end()
->hasNotNode('.document-image')
->end()
->end()
->end()
->hasNode('.feed-divider', 2)
->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'content:showInfo:userComments' => ThemeOptionsUserCommentsEnum::withoutAuthorDate(),
])
->with('.content')
->with('.document')
->child(1)
->with('.comments')
->hasNotNode('.comment-date')
->end()
->end()
->end()
->end();
}
/**
* @return void
*/
public function testContentEnhanced()
{
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'content:showInfo:sectionDivider' => false,
'content:showInfo:sourceCountry' => false,
'content:showInfo:userComments' => ThemeOptionsUserCommentsEnum::no(),
'content:showInfo:images' => false,
])
->with('.content')
->with('.feed-title')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->hasNode('.feed-title img', 3)
->with('.documents')
->hasNode('.document-aside', 2)
->with('.document')
->child(0)
->with('.document-headline a')
->hasAttr('href', 'http://permalink')
->contains('Feed1 Document1')
->end()
->with('.document-source')
->contains('CNN')
->notContains('(Russian)')
->end()
->with('.document-author')->contains('John Smith')->end()
->with('.document-date')
->contains('|')
->contains(date_create('2017-01-01 10:00:00')->format('F d, Y H:i'))
->end()
->with('.document-content')->contains('Feed1 Document1 Main')->end()
->hasNotNode('.comments')
->hasNotNode('.document-image')
->end()
->child(1)
->with('.document-headline a')
->hasAttr('href', 'http://permalink_next')
->contains('Feed2 Document1')
->end()
->with('.document-source')
->contains('Test')
->notContains('(USA)')
->end()
->hasNotNode('.document-author')
->with('.document-date')
->contains('|')
->contains(date_create('2017-01-10 10:00:00')->format('F d, Y H:i'))
->end()
->with('.document-content')->contains('Feed2 Document1 Main')->end()
->hasNotNode('.comments')
->hasNotNode('.document-image')
->end()
->end()
->end()
->hasNotNode('.feed-divider')
->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'content:showInfo:sectionDivider' => true,
'content:showInfo:sourceCountry' => true,
'content:showInfo:userComments' => ThemeOptionsUserCommentsEnum::withAuthorDate(),
'content:showInfo:images' => true,
])
->with('.content')
->with('.feed-title')
->child(0)->contains('feed1')->end()
->child(1)->contains('feed2')->end()
->child(2)->contains('feed3')->end()
->end()
->hasNode('.feed-title img', 3)
->with('.documents')
->hasNode('.document-aside', 2)
->with('.document')
->child(0)
->with('.document-headline a')
->hasAttr('href', 'http://permalink')
->contains('Feed1 Document1')
->end()
->with('.document-source')
->contains('CNN')
->contains('(Russian)')
->end()
->with('.document-author')->contains('John Smith')->end()
->with('.document-date')
->contains('|')
->contains(date_create('2017-01-01 10:00:00')->format('F d, Y H:i'))
->end()
->with('.document-content')->contains('Feed1 Document1 Main')->end()
->hasNotNode('.comments')
->hasNode('.document-image')
->end()
->child(1)
->with('.document-headline a')
->hasAttr('href', 'http://permalink_next')
->contains('Feed2 Document1')
->end()
->with('.document-source')->contains('Test')->end()
->hasNotNode('.document-author')
->with('.document-date')
->contains('|')
->contains(date_create('2017-01-10 10:00:00')->format('F d, Y H:i'))
->end()
->with('.document-content')->contains('Feed2 Document1 Main')->end()
->with('.comments .comment')
->child(0)
->with('.comment-title')->contains('Feed2 Document1 comment1 title')->end()
->with('.comment-author')
->contains('User1 first name')
->contains('User1 last name')
->end()
->with('.comment-date')
->contains(date_create('2017-01-02 10:00:00')->format('F d, Y H:i'))
->end()
->with('.comment-body')->contains('Feed2 Document1 comment1')->end()
->end()
->child(1)
->hasNotNode('.comment-title')
->with('.comment-author')
->contains('User2 first name')
->contains('User2 last name')
->end()
->with('.comment-date')
->contains(date_create('2017-01-03 10:00:00')->format('F d, Y H:i'))
->end()
->with('.comment-body')->contains('Feed2 Document1 comment2')->end()
->end()
->end()
->hasNotNode('.document-image')
->end()
->end()
->end()
->hasNotNode('.feed-divider')
->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'content:showInfo:userComments' => ThemeOptionsUserCommentsEnum::withoutAuthorDate(),
])
->with('.content')
->with('.document')
->child(1)
->with('.comments')
->hasNotNode('.comment-date')
->end()
->end()
->end()
->end();
}
/**
* @param ThemeTypeEnum $themeType A ThemeTypeEnum instance.
* @param array $diffs Notification theme diffs.
*
* @return HtmlAsserter
*/
private function createAsserter(ThemeTypeEnum $themeType, array $diffs = [])
{
$comment1 = new Comment(
User::create('some@main.com')
->setFirstName('User1 first name')
->setLastName('User1 last name'),
'Feed2 Document1 comment1',
'Feed2 Document1 comment1 title'
);
$comment1->setCreatedAt(date_create('2017-01-02 10:00:00'));
$comment2 = new Comment(
User::create('some@main.com')
->setFirstName('User2 first name')
->setLastName('User2 last name'),
'Feed2 Document1 comment2'
);
$comment2->setCreatedAt(date_create('2017-01-03 10:00:00'));
/** @var IndexStrategyInterface|\PHPUnit_Framework_MockObject_MockObject $strategy */
$strategy = $this->getMockForInterface(IndexStrategyInterface::class);
$strategy
->method('normalizeDocumentData')
->willReturnCallback(function (array $data) {
return $data;
});
$strategy
->method('normalizeFieldName')
->willReturnCallback(function ($fieldName) {
return $fieldName;
});
$strategy
->method('normalizePublisherType')
->willReturnCallback(function ($type) {
return $type;
});
$crawler = new Crawler($this->render($themeType, $diffs, [
new FeedData('feed1', [
new ArticleDocument($strategy, [
'title' => 'Feed1 Document1',
'permalink' => 'http://permalink',
'content' => 'Feed1 Document1 Main',
'published' => date_create('2017-01-01 10:00:00'),
'source' => [
'title' => 'CNN',
'country' => 'Russian',
],
'author' => [
'name' => 'John Smith',
],
'image' => 'http://image.dev',
]),
]),
new FeedData('feed2', [
new ArticleDocument($strategy, [
'title' => 'Feed2 Document1',
'permalink' => 'http://permalink_next',
'content' => 'Feed2 Document1 Main',
'published' => date_create('2017-01-10 10:00:00'),
'source' => [
'title' => 'Test',
'country' => 'USA',
],
'comments' => [
$comment1,
$comment2,
],
]),
]),
new FeedData('feed3', []),
]));
return new HtmlAsserter($crawler);
}
}
@@ -0,0 +1,502 @@
<?php
namespace UserBundle\Manager\Notification;
use AppBundle\Configuration\ConfigurationImmutableInterface;
use CacheBundle\Document\Extractor\DocumentContentExtractorInterface;
use CacheBundle\Feed\Fetcher\Factory\FeedFetcherFactoryInterface;
use Doctrine\DBAL\Connection;
use Doctrine\ORM\EntityManagerInterface;
use Tests\AppTestCase;
use Tests\UserBundle\Manager\Notification\RecipientFixture;
use UserBundle\Entity\Notification\Notification;
use UserBundle\Entity\Recipient\AbstractRecipient;
/**
* Class NotificationManagerTest
* @package UserBundle\Manager\Notification
*/
class NotificationManagerTest extends AppTestCase
{
/**
* @var Connection|\PHPUnit_Framework_MockObject_MockObject
*/
private $conn;
/**
* @var EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
private $em;
/**
* @var FeedFetcherFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
*/
private $feedFetcherFactory;
/**
* @var ConfigurationImmutableInterface|\PHPUnit_Framework_MockObject_MockObject
*/
private $configuration;
/**
* @var DocumentContentExtractorInterface|\PHPUnit_Framework_MockObject_MockObject
*/
private $extractor;
/**
* @var NotificationManager
*/
private $manager;
/**
* @return void
*/
public function testNormalizeNotificationsSingle()
{
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification */
$notification = $this->getMockBuilder(Notification::class)->getMock();
$this->assertEquals([ $notification ], $this->call($this->manager, 'normalizeNotifications', [ $notification ]));
}
/**
* @return void
*/
public function testNormalizeNotificationsMany()
{
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification1 */
$notification1 = $this->getMockBuilder(Notification::class)->getMock();
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification2 */
$notification2 = $this->getMockBuilder(Notification::class)->getMock();
$notifications = [ $notification1, $notification2 ];
$this->assertEquals($notifications, $this->call($this->manager, 'normalizeNotifications', [ $notifications ]));
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Expects single
*
* @return void
*/
public function testNormalizeNotificationsManyFail()
{
$notifications = [ 'invalid', 123 ];
$this->assertEquals($notifications, $this->call($this->manager, 'normalizeNotifications', [ $notifications ]));
}
/**
* @return void
*/
public function testActivatedToggleSingleTrue()
{
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification */
$notification = $this->getMockBuilder(Notification::class)
->setMethods([ 'setActive' ])
->getMock();
$notification
->expects($this->once())
->method('setActive')
->with($this->equalTo(true));
$this->em
->expects($this->once())
->method('persist')
->with($this->equalTo($notification));
$this->em
->expects($this->once())
->method('flush');
$this->manager->activatedToggle($notification);
}
/**
* @return void
*/
public function testActivatedToggleSingleFalse()
{
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification */
$notification = $this->getMockBuilder(Notification::class)
->setMethods([ 'setActive' ])
->getMock();
$notification
->expects($this->once())
->method('setActive')
->with($this->equalTo(false));
$this->em
->expects($this->once())
->method('persist')
->with($this->equalTo($notification));
$this->em
->expects($this->once())
->method('flush');
$this->manager->activatedToggle($notification, false);
}
/**
* @return void
*/
public function testActivatedToggleMany()
{
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification */
$notification1 = $this->getMockBuilder(Notification::class)
->setMethods([ 'setActive' ])
->getMock();
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification */
$notification2 = $this->getMockBuilder(Notification::class)
->setMethods([ 'setActive' ])
->getMock();
$notification1
->expects($this->once())
->method('setActive')
->with($this->equalTo(false));
$notification2
->expects($this->once())
->method('setActive')
->with($this->equalTo(false));
$this->em
->expects($this->at(0))
->method('persist')
->with($this->equalTo($notification1));
$this->em
->expects($this->at(1))
->method('persist')
->with($this->equalTo($notification2));
$this->em
->expects($this->once())
->method('flush');
$this->manager->activatedToggle([ $notification1, $notification2 ], false);
}
/**
* @return void
*/
public function testPublishedToggleSingleTrue()
{
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification */
$notification = $this->getMockBuilder(Notification::class)
->setMethods([ 'setPublished' ])
->getMock();
$notification
->expects($this->once())
->method('setPublished')
->with($this->equalTo(true));
$this->em
->expects($this->once())
->method('persist')
->with($this->equalTo($notification));
$this->em
->expects($this->once())
->method('flush');
$this->manager->publishedToggle($notification);
}
/**
* @return void
*/
public function testPublishedToggleSingleFalse()
{
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification */
$notification = $this->getMockBuilder(Notification::class)
->setMethods([ 'setPublished' ])
->getMock();
$notification
->expects($this->once())
->method('setPublished')
->with($this->equalTo(false));
$this->em
->expects($this->once())
->method('persist')
->with($this->equalTo($notification));
$this->em
->expects($this->once())
->method('flush');
$this->manager->publishedToggle($notification, false);
}
/**
* @return void
*/
public function testPublishedToggleManyFalse()
{
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification */
$notification1 = $this->getMockBuilder(Notification::class)
->setMethods([ 'setPublished' ])
->getMock();
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification */
$notification2 = $this->getMockBuilder(Notification::class)
->setMethods([ 'setPublished' ])
->getMock();
$notification1
->expects($this->once())
->method('setPublished')
->with($this->equalTo(false));
$notification2
->expects($this->once())
->method('setPublished')
->with($this->equalTo(false));
$this->em
->expects($this->at(0))
->method('persist')
->with($this->equalTo($notification1));
$this->em
->expects($this->at(1))
->method('persist')
->with($this->equalTo($notification2));
$this->em
->expects($this->once())
->method('flush');
$this->manager->publishedToggle([ $notification1, $notification2 ], false);
}
/**
* @return void
*/
public function testSubscriptionToggleTrue()
{
$recipient = $this->getMockForAbstractClass(AbstractRecipient::class);
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification */
$notification = $this->getMockBuilder(Notification::class)
->setMethods([ 'getRecipients', 'addRecipient' ])
->getMock();
$notification
->expects($this->once())
->method('getRecipients')
->willReturn([]);
$notification
->expects($this->once())
->method('addRecipient')
->with($this->equalTo($recipient));
$this->em
->expects($this->once())
->method('persist')
->with($this->equalTo($notification));
$this->em
->expects($this->once())
->method('flush');
$this->manager->subscriptionToggle($recipient, $notification);
}
/**
* @return void
*/
public function testSubscriptionToggleTrueWithExists()
{
$recipient1 = new RecipientFixture(1);
$recipient2 = new RecipientFixture(2);
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification1 */
$notification1 = $this->getMockBuilder(Notification::class)
->setMethods([ 'getRecipients', 'addRecipient' ])
->getMock();
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification2 */
$notification2 = $this->getMockBuilder(Notification::class)
->setMethods([ 'getRecipients', 'addRecipient' ])
->getMock();
$notification1
->expects($this->once())
->method('getRecipients')
->willReturn([ $recipient1, $recipient2 ]);
$notification1
->expects($this->never())
->method('addRecipient');
$notification2
->expects($this->once())
->method('getRecipients')
->willReturn([ $recipient2 ]);
$notification2
->expects($this->once())
->method('addRecipient')
->with($this->equalTo($recipient1));
$this->em
->expects($this->once())
->method('persist')
->with($this->equalTo($notification2));
$this->em
->expects($this->once())
->method('flush');
$this->manager->subscriptionToggle($recipient1, [ $notification1, $notification2 ]);
}
/**
* @return void
*/
public function testSubscriptionToggleFalse()
{
$recipient = $this->getMockForAbstractClass(AbstractRecipient::class);
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification */
$notification = $this->getMockBuilder(Notification::class)
->setMethods([ 'getRecipients', 'removeRecipient' ])
->getMock();
$notification
->expects($this->never())
->method('getRecipients');
$notification
->expects($this->once())
->method('removeRecipient')
->with($this->equalTo($recipient));
$this->em
->expects($this->once())
->method('persist')
->with($this->equalTo($notification));
$this->em
->expects($this->once())
->method('flush');
$this->manager->subscriptionToggle($recipient, $notification, false);
}
/**
* @return void
*/
public function testRemoveSingle()
{
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification */
$notification = $this->getMockBuilder(Notification::class)
->setMethods([ 'getId' ])
->getMock();
$notification
->expects($this->once())
->method('getId')
->willReturn(1);
$this->em
->expects($this->once())
->method('remove')
->with($this->equalTo($notification));
$this->em
->expects($this->once())
->method('flush');
$this->conn
->expects($this->once())
->method('executeQuery')
->with($this->stringContains('WHERE notification_id in (1)'));
$this->manager->remove($notification);
}
/**
* @return void
*/
public function testRemoveMany()
{
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification1 */
$notification1 = $this->getMockBuilder(Notification::class)
->setMethods([ 'getId' ])
->getMock();
/** @var Notification|\PHPUnit_Framework_MockObject_MockObject $notification2 */
$notification2 = $this->getMockBuilder(Notification::class)
->setMethods([ 'getId' ])
->getMock();
$notification1
->expects($this->once())
->method('getId')
->willReturn(1);
$notification2
->expects($this->once())
->method('getId')
->willReturn(2);
$this->em
->expects($this->at(0))
->method('remove')
->with($this->equalTo($notification1));
$this->em
->expects($this->at(1))
->method('remove')
->with($this->equalTo($notification2));
$this->em
->expects($this->once())
->method('flush');
$this->conn
->expects($this->once())
->method('executeQuery')
->with($this->stringContains('WHERE notification_id in (1,2)'));
$this->manager->remove([ $notification1, $notification2 ]);
}
/**
* Sets up the fixture, for example, open a network connection.
* This method is called before a test is executed.
*
* @return void
*/
protected function setUp()
{
$this->conn = $this->getMockForInterface(Connection::class);
$this->em = $this->getMockForInterface(EntityManagerInterface::class);
$this->feedFetcherFactory = $this->getMockForInterface(FeedFetcherFactoryInterface::class);
$this->configuration = $this->getMockForInterface(ConfigurationImmutableInterface::class);
$this->extractor = $this->getMockForInterface(DocumentContentExtractorInterface::class);
$this->em
->expects($this->any())
->method('getConnection')
->willReturn($this->conn);
$this->manager = new NotificationManager(
$this->em,
$this->feedFetcherFactory,
$this->configuration,
$this->extractor
);
}
}
@@ -0,0 +1,756 @@
<?php
namespace UserBundle\Manager\Notification;
use Tests\Helper\CssAssertBuilder;
use Tests\Helper\CssAsserter;
use UserBundle\Entity\Notification\NotificationThemeOptions;
use UserBundle\Entity\Notification\ThemeOption\ThemeOptionColorsBackground;
use UserBundle\Entity\Notification\ThemeOption\ThemeOptionColorsText;
use UserBundle\Entity\Notification\ThemeOption\ThemeOptionFont;
use UserBundle\Entity\Notification\ThemeOption\ThemeOptionFontStyle;
use UserBundle\Enum\FontFamilyEnum;
use UserBundle\Enum\ThemeTypeEnum;
use UserBundle\Manager\Notification\Model\FeedData;
/**
* Class NotificationStylesRenderTest
*
* @package UserBundle\Manager\Notification
*/
class NotificationStylesRenderTest extends AbstractSendableNotificationTest
{
/**
* @return void
*/
public function testLayout()
{
$defaultEmailBodyBG = ThemeOptionColorsBackground::DEFAULT_EMAIL_BODY;
$defaultAccentBG = ThemeOptionColorsBackground::DEFAULT_ACCENT;
$defaultArticleContentFG = ThemeOptionColorsText::DEFAULT_ARTICLE_CONTENT;
$customEmailBodyBG = 'rgba(123, 44, 55, 0.32)';
$customAccentBG = 'rgba(124, 45, 56, 0.33)';
$customArticleContentFG = 'rgba(125, 46, 57, 0.34)';
$this->createAsserter(ThemeTypeEnum::plain())
->with('.email')->hasNot('border')->end()
->with('html')->hasNot('background')->end()
->with('body')->hasNot('background')->end()
->with('.email-body-content')->has('color', $defaultArticleContentFG)->end();
$this->createAsserter(ThemeTypeEnum::plain(), [
'colors:background:emailBody' => $customEmailBodyBG,
'colors:background:accent' => $customAccentBG,
'colors:text:articleContent' => $customArticleContentFG,
])
->with('.email')->hasNot('border')->end()
->with('html')->hasNot('background')->end()
->with('body')->hasNot('background')->end()
->with('.email-body-content')->has('color', $customArticleContentFG)->end();
$this->createAsserter(ThemeTypeEnum::enhanced())
->with('.email')->has('border', '4px solid '. $defaultAccentBG)->end()
->with('html')->has('background', $defaultEmailBodyBG)->end()
->with('body')->has('background', $defaultEmailBodyBG)->end()
->with('.email-body-content')->has('color', $defaultArticleContentFG)->end();
$this->createAsserter(ThemeTypeEnum::enhanced(), [
'colors:background:emailBody' => $customEmailBodyBG,
'colors:background:accent' => $customAccentBG,
'colors:text:articleContent' => $customArticleContentFG,
])
->with('.email')->has('border', '4px solid '. $customAccentBG)->end()
->with('html')->has('background', $customEmailBodyBG)->end()
->with('body')->has('background', $customEmailBodyBG)->end()
->with('.email-body-content')->has('color', $customArticleContentFG)->end();
}
/**
* @return void
*/
public function testHeader()
{
$this->assertCssRender(ThemeTypeEnum::plain(), [
$this->createCssAssertBuilder('.email-header')
->propertyShouldBe('color', 'white')
->propertyShouldNotBe('height', '105px'),
$this->createCssAssertBuilder('.email-header-info-title')
->hasFont(new ThemeOptionFont(
FontFamilyEnum::arial(),
NotificationThemeOptions::DEFAULT_HEADER_SIZE
))
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_HEADER),
$this->createCssAssertBuilder('.email-header-info-date')
->propertyShouldBe('color', ThemeOptionColorsBackground::DEFAULT_ACCENT),
]);
$this->assertCssRender(ThemeTypeEnum::plain(), [
$this->createCssAssertBuilder('.email-header')
->propertyShouldBe('color', 'white')
->propertyShouldBe('height', '105px'),
$this->createCssAssertBuilder('.email-header-info-title')
->hasFont(new ThemeOptionFont(
FontFamilyEnum::calibri(),
10,
new ThemeOptionFontStyle(true, true, true)
))
->propertyShouldBe('color', 'rgba(124, 45, 56, 0.33)'),
$this->createCssAssertBuilder('.email-header-info-date')
->propertyShouldBe('color', 'rgba(123, 44, 55, 0.32)'),
], [
'header:imageUrl' => 'http://pic.com',
'colors:background:accent' => 'rgba(123, 44, 55, 0.32)',
'colors:text:header' => 'rgba(124, 45, 56, 0.33)',
'fonts:header:family' => FontFamilyEnum::calibri(),
'fonts:header:size' => 10,
'fonts:header:style:bold' => true,
'fonts:header:style:italic' => true,
'fonts:header:style:underline' => true,
]);
}
/**
* @return void
*/
public function testTableOfContents()
{
$this->tableOfContentsDefault();
$this->tableOfContentsCustom();
}
/**
* @return void
*/
public function testContents()
{
$this->contentsDefault();
$this->contentsCustom();
}
/**
* @return void
*/
public function testFooter()
{
$this->createAsserter(ThemeTypeEnum::plain())
->with('footer')
->has('border-top', '3px double #fff')
->end();
$this->createAsserter(ThemeTypeEnum::plain())
->with('footer')
->hasNot('border-top')
->end();
}
/**
* @return void
*/
private function tableOfContentsDefault()
{
$defaultFont = new ThemeOptionFont(
FontFamilyEnum::arial(),
NotificationThemeOptions::DEFAULT_TABLE_OF_CONTENTS_SIZE
);
$this->assertCssRender(ThemeTypeEnum::plain(), [
// .table-of-contents
$this->createCssAssertBuilder('.table-of-contents .feeds li')->shouldNotExists(),
$this->createCssAssertBuilder('.table-of-contents .feeds > li')->shouldNotExists(),
$this->createCssAssertBuilder('.table-of-contents .feeds > li:before')->shouldNotExists(),
$this->createCssAssertBuilder('.table-of-contents .documents > li:before')->shouldNotExists(),
$this->createCssAssertBuilder('.table-of-contents li:before')
->propertyShouldBe('font-size', NotificationThemeOptions::DEFAULT_TABLE_OF_CONTENTS_SIZE)
->propertyShouldNotBe('font-weight', 'bold')
->propertyShouldNotBe('font-style', 'italic')
->propertyShouldBe('text-decoration', 'none'),
// .feed-name
$this->createCssAssertBuilder('.table-of-contents .feeds .feed .feed-name')
->propertyShouldNotBe('width', '48%')
->propertyShouldNotBe('display', 'inline-block')
->propertyShouldNotBe('margin-left', '20px')
->hasFont($defaultFont),
// .feed-document-count
$this->createCssAssertBuilder('.table-of-contents .feeds .feed .feed-document-count')
->propertyShouldNotBe('width', '48%')
->propertyShouldNotBe('display', 'inline-block')
->hasFont($defaultFont),
// Document link
$this->createCssAssertBuilder('.table-of-contents .documents .document a')
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_ARTICLE_HEADLINE)
->hasFont($defaultFont),
// Misc
$this->createCssAssertBuilder('.table-of-contents .feeds .feed .feed-document-count:before')
->propertyShouldBe('content', ' '),
$this->createCssAssertBuilder('.table-of-contents .documents .document a:after')
->propertyShouldBe('content', 'url(data:image')
->propertyShouldBe('padding-left', '3px'),
$this->createCssAssertBuilder('.table-of-contents .documents .document .source')
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_SOURCE),
]);
$this->assertCssRender(ThemeTypeEnum::enhanced(), [
// .table-of-contents
$this->createCssAssertBuilder('.table-of-contents .feeds li')
->propertyShouldBe('background', 'white')
->propertyShouldBe('display', 'block')
->propertyShouldBe('padding', '5px 10px'),
$this->createCssAssertBuilder('.table-of-contents .feeds > li')
->propertyShouldBe('margin-bottom', '1px')
->propertyShouldBe('border-bottom', '1px solid #e6e6e6'),
$this->createCssAssertBuilder('.table-of-contents .feeds > li:before')
->propertyShouldBe('width', '6px')
->propertyShouldBe('height', '8px')
->propertyShouldBe('content', 'url(data:image'),
$this->createCssAssertBuilder('.table-of-contents .documents > li:before')
->propertyShouldBe('font-size', NotificationThemeOptions::DEFAULT_ARTICLE_CONTENT_SIZE)
->propertyShouldNotBe('font-weight', 'bold')
->propertyShouldNotBe('font-style', 'italic')
->propertyShouldBe('text-decoration', 'none'),
$this->createCssAssertBuilder('.table-of-contents li:before')->shouldNotExists(),
// .feed-name
$this->createCssAssertBuilder('.table-of-contents .feeds .feed .feed-name')
->propertyShouldBe('width', '48%')
->propertyShouldBe('display', 'inline-block')
->propertyShouldBe('margin-left', '20px')
->hasFont($defaultFont),
// .feed-document-count
$this->createCssAssertBuilder('.table-of-contents .feeds .feed .feed-document-count')
->propertyShouldBe('width', '48%')
->propertyShouldBe('display', 'inline-block')
->hasFont($defaultFont),
// Document link
$this->createCssAssertBuilder('.table-of-contents .documents .document a')
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_ARTICLE_CONTENT)
->hasFont(new ThemeOptionFont(
FontFamilyEnum::arial(),
NotificationThemeOptions::DEFAULT_ARTICLE_CONTENT_SIZE
)),
// Misc
$this->createCssAssertBuilder('.table-of-contents .feeds .feed .feed-document-count:before')->shouldNotExists(),
$this->createCssAssertBuilder('.table-of-contents .documents .document a:after')->shouldNotExists(),
$this->createCssAssertBuilder('.table-of-contents .documents .document .source')
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_SOURCE),
]);
}
/**
* @return void
*/
private function tableOfContentsCustom()
{
$customFont = new ThemeOptionFont(
FontFamilyEnum::calibri(),
10,
new ThemeOptionFontStyle(true, true, true)
);
$this->assertCssRender(ThemeTypeEnum::plain(), [
// .table-of-contents
$this->createCssAssertBuilder('.table-of-contents .feeds li')->shouldNotExists(),
$this->createCssAssertBuilder('.table-of-contents .feeds > li')->shouldNotExists(),
$this->createCssAssertBuilder('.table-of-contents .feeds > li:before')->shouldNotExists(),
$this->createCssAssertBuilder('.table-of-contents .documents > li:before')->shouldNotExists(),
$this->createCssAssertBuilder('.table-of-contents li:before')
->propertyShouldBe('font-size', 10)
->propertyShouldBe('font-weight', 'bold')
->propertyShouldBe('font-style', 'italic')
->propertyShouldBe('text-decoration', 'none'),
// .feed-name
$this->createCssAssertBuilder('.table-of-contents .feeds .feed .feed-name')
->propertyShouldNotBe('width', '48%')
->propertyShouldNotBe('display', 'inline-block')
->propertyShouldNotBe('margin-left', '20px')
->hasFont($customFont),
// .feed-document-count
$this->createCssAssertBuilder('.table-of-contents .feeds .feed .feed-document-count')
->propertyShouldNotBe('width', '48%')
->propertyShouldNotBe('display', 'inline-block')
->hasFont($customFont),
// Document link
$this->createCssAssertBuilder('.table-of-contents .documents .document a')
->propertyShouldBe('color', 'rgba(123, 44, 55, 0.32)')
->hasFont($customFont),
// Misc
$this->createCssAssertBuilder('.table-of-contents .feeds .feed .feed-document-count:before')
->propertyShouldBe('content', ' '),
$this->createCssAssertBuilder('.table-of-contents .documents .document a:after')
->propertyShouldBe('content', 'url(data:image')
->propertyShouldBe('padding-left', '3px'),
$this->createCssAssertBuilder('.table-of-contents .documents .document .source')
->propertyShouldBe('color', 'rgba(124, 45, 56, 0.33)'),
], [
'colors:text:articleHeadline' => 'rgba(123, 44, 55, 0.32)',
'colors:text:source' => 'rgba(124, 45, 56, 0.33)',
'fonts:tableOfContents:family' => $customFont->getFamily(),
'fonts:tableOfContents:size' => $customFont->getSize(),
'fonts:tableOfContents:style:bold' => $customFont->getStyle()->isBold(),
'fonts:tableOfContents:style:italic' => $customFont->getStyle()->isItalic(),
'fonts:tableOfContents:style:underline' => $customFont->getStyle()->isUnderline(),
]);
$this->assertCssRender(ThemeTypeEnum::enhanced(), [
// .table-of-contents
$this->createCssAssertBuilder('.table-of-contents .feeds li')
->propertyShouldBe('background', 'white')
->propertyShouldBe('display', 'block')
->propertyShouldBe('padding', '5px 10px'),
$this->createCssAssertBuilder('.table-of-contents .feeds > li')
->propertyShouldBe('margin-bottom', '1px')
->propertyShouldBe('border-bottom', '1px solid #e6e6e6'),
$this->createCssAssertBuilder('.table-of-contents .feeds > li:before')
->propertyShouldBe('width', '6px')
->propertyShouldBe('height', '8px')
->propertyShouldBe('content', 'url(data:image'),
$this->createCssAssertBuilder('.table-of-contents .documents > li:before')
->propertyShouldBe('font-size', 11)
->propertyShouldNotBe('font-weight', 'bold')
->propertyShouldBe('font-style', 'italic')
->propertyShouldBe('text-decoration', 'none'),
$this->createCssAssertBuilder('.table-of-contents li:before')->shouldNotExists(),
// .feed-name
$this->createCssAssertBuilder('.table-of-contents .feeds .feed .feed-name')
->propertyShouldBe('width', '48%')
->propertyShouldBe('display', 'inline-block')
->propertyShouldBe('margin-left', '20px')
->hasFont($customFont),
// .feed-document-count
$this->createCssAssertBuilder('.table-of-contents .feeds .feed .feed-document-count')
->propertyShouldBe('width', '48%')
->propertyShouldBe('display', 'inline-block')
->hasFont($customFont),
// Document link
$this->createCssAssertBuilder('.table-of-contents .documents .document a')
->propertyShouldBe('color', 'rgba(123, 44, 55, 0.32)')
->hasFont(new ThemeOptionFont(
FontFamilyEnum::courierNew(),
11,
new ThemeOptionFontStyle(false, true, true)
)),
// Misc
$this->createCssAssertBuilder('.table-of-contents .feeds .feed .feed-document-count:before')->shouldNotExists(),
$this->createCssAssertBuilder('.table-of-contents .documents .document a:after')->shouldNotExists(),
$this->createCssAssertBuilder('.table-of-contents .documents .document .source')
->propertyShouldBe('color', 'rgba(124, 45, 56, 0.33)'),
], [
'colors:text:articleContent' => 'rgba(123, 44, 55, 0.32)',
'colors:text:source' => 'rgba(124, 45, 56, 0.33)',
'fonts:tableOfContents:family' => $customFont->getFamily(),
'fonts:tableOfContents:size' => $customFont->getSize(),
'fonts:tableOfContents:style:bold' => $customFont->getStyle()->isBold(),
'fonts:tableOfContents:style:italic' => $customFont->getStyle()->isItalic(),
'fonts:tableOfContents:style:underline' => $customFont->getStyle()->isUnderline(),
'fonts:articleContent:family' => FontFamilyEnum::courierNew(),
'fonts:articleContent:size' => 11,
'fonts:articleContent:style:bold' => false,
'fonts:articleContent:style:italic' => true,
'fonts:articleContent:style:underline' => true,
]);
}
/**
* @return void
*/
private function contentsDefault()
{
//
// Plain
//
$feedTitleFont = new ThemeOptionFont(
FontFamilyEnum::arial(),
NotificationThemeOptions::DEFAULT_FEED_TITLE_SIZE
);
$dateFont = new ThemeOptionFont(
FontFamilyEnum::arial(),
NotificationThemeOptions::DEFAULT_DATE_SIZE
);
$articleContentFont = new ThemeOptionFont(
FontFamilyEnum::arial(),
NotificationThemeOptions::DEFAULT_ARTICLE_CONTENT_SIZE
);
$articleHeadlineFont = new ThemeOptionFont(
FontFamilyEnum::arial(),
NotificationThemeOptions::DEFAULT_ARTICLE_HEADLINE_SIZE
);
$sourceFont = new ThemeOptionFont(
FontFamilyEnum::arial(),
NotificationThemeOptions::DEFAULT_SOURCE_SIZE
);
$authorFont = new ThemeOptionFont(
FontFamilyEnum::arial(),
NotificationThemeOptions::DEFAULT_AUTHOR_SIZE
);
$this->assertCssRender(ThemeTypeEnum::plain(), [
// .feed-title
$this->createCssAssertBuilder('.content .feed-title')
->hasFont($feedTitleFont)
->propertyShouldNotExists('background')
->propertyShouldNotExists('color'),
// .document
$this->createCssAssertBuilder('.content .documents .document')
->propertyShouldBe('margin-top', '10px')
->propertyShouldBe('margin-left', '5px')
->propertyShouldNotExists('display')
->propertyShouldNotExists('flex'),
$this->createCssAssertBuilder('.content .documents .document:last-child'),
$this->createCssAssertBuilder('.content .documents .document-aside')->shouldNotExists(),
$this->createCssAssertBuilder('.content .documents .document-main')->shouldNotExists(),
$this->createCssAssertBuilder('.content .documents .document-body')->shouldNotExists(),
$this->createCssAssertBuilder('.content .documents .document-image')->shouldNotExists(),
$this->createCssAssertBuilder('.content .documents .document-image img')->shouldNotExists(),
// .document-headline link
$this->createCssAssertBuilder('.content .documents .document-headline a')
->hasFont($articleHeadlineFont)
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_ARTICLE_HEADLINE),
// .document-source
$this->createCssAssertBuilder('.content .documents .document-source')
->hasFont($sourceFont)
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_SOURCE),
// .document-author
$this->createCssAssertBuilder('.content .documents .document-author')
->hasFont($authorFont)
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_AUTHOR),
// .document-date
$this->createCssAssertBuilder('.content .documents .document-date')
->hasFont($dateFont)
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_PUBLISH_DATE),
// .document-content
$this->createCssAssertBuilder('.content .document .document-content')
->hasFont($articleContentFont),
// Comments
$this->createCssAssertBuilder('.content .comments .comment-title')->shouldNotExists(),
$this->createCssAssertBuilder('.content .comments .comment-author')
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_AUTHOR)
->hasFont($authorFont),
$this->createCssAssertBuilder('.content .comments .comment-date')
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_PUBLISH_DATE)
->hasFont($dateFont),
]);
//
// Enhanced
//
$this->assertCssRender(ThemeTypeEnum::enhanced(), [
// .feed-title
$this->createCssAssertBuilder('.content .feed-title')
->hasFont($feedTitleFont)
->propertyShouldBe('background', ThemeOptionColorsBackground::DEFAULT_ACCENT)
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_HEADER),
// .document
$this->createCssAssertBuilder('.content .documents .document')
->propertyShouldBe('margin-top', '5px')
->propertyShouldNotExists('margin-left', '5px')
->propertyShouldExists('display')
->propertyShouldExists('flex'),
$this->createCssAssertBuilder('.content .documents .document:last-child')->shouldNotExists(),
$this->createCssAssertBuilder('.content .documents .document-aside'),
$this->createCssAssertBuilder('.content .documents .document-main'),
$this->createCssAssertBuilder('.content .documents .document-body'),
$this->createCssAssertBuilder('.content .documents .document-image'),
$this->createCssAssertBuilder('.content .documents .document-image img'),
// .document-headline link
$this->createCssAssertBuilder('.content .documents .document-headline a')
->hasFont($articleHeadlineFont)
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_ARTICLE_HEADLINE),
// .document-source
$this->createCssAssertBuilder('.content .documents .document-source')
->hasFont($sourceFont)
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_SOURCE),
// .document-author
$this->createCssAssertBuilder('.content .documents .document-author')
->hasFont($authorFont)
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_AUTHOR),
// .document-date
$this->createCssAssertBuilder('.content .documents .document-date')
->hasFont($articleContentFont)
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_ARTICLE_CONTENT),
// .document-content
$this->createCssAssertBuilder('.content .document .document-content')
->hasFont($articleContentFont),
// Comments
$this->createCssAssertBuilder('.content .comments .comment-title'),
$this->createCssAssertBuilder('.content .comments .comment-author')
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_AUTHOR)
->hasNotAnyFonts(),
$this->createCssAssertBuilder('.content .comments .comment-date')
->propertyShouldBe('color', ThemeOptionColorsText::DEFAULT_ARTICLE_CONTENT)
->hasNotAnyFonts(),
]);
}
/**
* @return void
*/
private function contentsCustom()
{
$feedTitleFont = new ThemeOptionFont(
FontFamilyEnum::calibri(),
11,
new ThemeOptionFontStyle(true, true, true)
);
$dateFont = new ThemeOptionFont(
FontFamilyEnum::centuryGothic(),
12,
new ThemeOptionFontStyle(true, false, true)
);
$articleContentFont = new ThemeOptionFont(
FontFamilyEnum::georgia(),
13,
new ThemeOptionFontStyle(true, true, false)
);
$articleHeadlineFont = new ThemeOptionFont(
FontFamilyEnum::lucidaSansUnicode(),
14,
new ThemeOptionFontStyle(false, true, true)
);
$sourceFont = new ThemeOptionFont(
FontFamilyEnum::courierNew(),
15,
new ThemeOptionFontStyle(false, true, false)
);
$authorFont = new ThemeOptionFont(
FontFamilyEnum::tahoma(),
16,
new ThemeOptionFontStyle(true, true, false)
);
$diffs = [
'colors:background:accent' => 'rgba(123, 44, 55, 0.32)',
'colors:text:header' => 'rgba(124, 45, 56, 0.33)',
'colors:text:publishDate' => 'rgba(125, 46, 57, 0.34)',
'colors:text:articleContent' => 'rgba(126, 47, 58, 0.35)',
'colors:text:articleHeadline' => 'rgba(127, 48, 59, 0.36)',
'colors:text:source' => 'rgba(128, 49, 60, 0.37)',
'colors:text:author' => 'rgba(129, 50, 61, 0.38)',
'fonts:feedTitle:family' => $feedTitleFont->getFamily(),
'fonts:feedTitle:size' => $feedTitleFont->getSize(),
'fonts:feedTitle:style:bold' => $feedTitleFont->getStyle()->isBold(),
'fonts:feedTitle:style:italic' => $feedTitleFont->getStyle()->isItalic(),
'fonts:feedTitle:style:underline' => $feedTitleFont->getStyle()->isUnderline(),
'fonts:date:family' => $dateFont->getFamily(),
'fonts:date:size' => $dateFont->getSize(),
'fonts:date:style:bold' => $dateFont->getStyle()->isBold(),
'fonts:date:style:italic' => $dateFont->getStyle()->isItalic(),
'fonts:date:style:underline' => $dateFont->getStyle()->isUnderline(),
'fonts:articleContent:family' => $articleContentFont->getFamily(),
'fonts:articleContent:size' => $articleContentFont->getSize(),
'fonts:articleContent:style:bold' => $articleContentFont->getStyle()->isBold(),
'fonts:articleContent:style:italic' => $articleContentFont->getStyle()->isItalic(),
'fonts:articleContent:style:underline' => $articleContentFont->getStyle()->isUnderline(),
'fonts:articleHeadline:family' => $articleHeadlineFont->getFamily(),
'fonts:articleHeadline:size' => $articleHeadlineFont->getSize(),
'fonts:articleHeadline:style:bold' => $articleHeadlineFont->getStyle()->isBold(),
'fonts:articleHeadline:style:italic' => $articleHeadlineFont->getStyle()->isItalic(),
'fonts:articleHeadline:style:underline' => $articleHeadlineFont->getStyle()->isUnderline(),
'fonts:source:family' => $sourceFont->getFamily(),
'fonts:source:size' => $sourceFont->getSize(),
'fonts:source:style:bold' => $sourceFont->getStyle()->isBold(),
'fonts:source:style:italic' => $sourceFont->getStyle()->isItalic(),
'fonts:source:style:underline' => $sourceFont->getStyle()->isUnderline(),
'fonts:author:family' => $authorFont->getFamily(),
'fonts:author:size' => $authorFont->getSize(),
'fonts:author:style:bold' => $authorFont->getStyle()->isBold(),
'fonts:author:style:italic' => $authorFont->getStyle()->isItalic(),
'fonts:author:style:underline' => $authorFont->getStyle()->isUnderline(),
];
//
// Plain
//
$this->assertCssRender(ThemeTypeEnum::plain(), [
// .feed-title
$this->createCssAssertBuilder('.content .feed-title')
->hasFont($feedTitleFont)
->propertyShouldNotExists('background')
->propertyShouldNotExists('color'),
// .document
$this->createCssAssertBuilder('.content .documents .document')
->propertyShouldBe('margin-top', '10px')
->propertyShouldBe('margin-left', '5px')
->propertyShouldNotExists('display')
->propertyShouldNotExists('flex'),
$this->createCssAssertBuilder('.content .documents .document:last-child'),
$this->createCssAssertBuilder('.content .documents .document-aside')->shouldNotExists(),
$this->createCssAssertBuilder('.content .documents .document-main')->shouldNotExists(),
$this->createCssAssertBuilder('.content .documents .document-body')->shouldNotExists(),
$this->createCssAssertBuilder('.content .documents .document-image')->shouldNotExists(),
$this->createCssAssertBuilder('.content .documents .document-image img')->shouldNotExists(),
// .document-headline link
$this->createCssAssertBuilder('.content .documents .document-headline a')
->hasFont($articleHeadlineFont)
->propertyShouldBe('color', 'rgba(127, 48, 59, 0.36)'),
// .document-source
$this->createCssAssertBuilder('.content .documents .document-source')
->hasFont($sourceFont)
->propertyShouldBe('color', 'rgba(128, 49, 60, 0.37)'),
// .document-author
$this->createCssAssertBuilder('.content .documents .document-author')
->hasFont($authorFont)
->propertyShouldBe('color', 'rgba(129, 50, 61, 0.38)'),
// .document-date
$this->createCssAssertBuilder('.content .documents .document-date')
->hasFont($dateFont)
->propertyShouldBe('color', 'rgba(125, 46, 57, 0.34)'),
// .document-content
$this->createCssAssertBuilder('.content .document .document-content')
->hasFont($articleContentFont),
// Comments
$this->createCssAssertBuilder('.content .comments .comment-title')->shouldNotExists(),
$this->createCssAssertBuilder('.content .comments .comment-author')
->propertyShouldBe('color', 'rgba(129, 50, 61, 0.38)')
->hasFont($authorFont),
$this->createCssAssertBuilder('.content .comments .comment-date')
->propertyShouldBe('color', 'rgba(125, 46, 57, 0.34)')
->hasFont($dateFont),
], $diffs);
//
// Enhanced
//
$this->assertCssRender(ThemeTypeEnum::enhanced(), [
// .feed-title
$this->createCssAssertBuilder('.content .feed-title')
->hasFont($feedTitleFont)
->propertyShouldBe('background', 'rgba(123, 44, 55, 0.32)')
->propertyShouldBe('color', 'rgba(124, 45, 56, 0.33)'),
// .document
$this->createCssAssertBuilder('.content .documents .document')
->propertyShouldBe('margin-top', '5px')
->propertyShouldNotExists('margin-left', '5px')
->propertyShouldExists('display')
->propertyShouldExists('flex'),
$this->createCssAssertBuilder('.content .documents .document:last-child')->shouldNotExists(),
$this->createCssAssertBuilder('.content .documents .document-aside'),
$this->createCssAssertBuilder('.content .documents .document-main'),
$this->createCssAssertBuilder('.content .documents .document-body'),
$this->createCssAssertBuilder('.content .documents .document-image'),
$this->createCssAssertBuilder('.content .documents .document-image img'),
// .document-headline link
$this->createCssAssertBuilder('.content .documents .document-headline a')
->hasFont($articleHeadlineFont)
->propertyShouldBe('color', 'rgba(127, 48, 59, 0.36)'),
// .document-source
$this->createCssAssertBuilder('.content .documents .document-source')
->hasFont($sourceFont)
->propertyShouldBe('color', 'rgba(128, 49, 60, 0.37)'),
// .document-author
$this->createCssAssertBuilder('.content .documents .document-author')
->hasFont($authorFont)
->propertyShouldBe('color', 'rgba(129, 50, 61, 0.38)'),
// .document-date
$this->createCssAssertBuilder('.content .documents .document-date')
->hasFont($dateFont)
->propertyShouldBe('color', 'rgba(126, 47, 58, 0.35)'),
// .document-content
$this->createCssAssertBuilder('.content .document .document-content')
->hasFont($articleContentFont),
// Comments
$this->createCssAssertBuilder('.content .comments .comment-title'),
$this->createCssAssertBuilder('.content .comments .comment-author')
->propertyShouldBe('color', 'rgba(129, 50, 61, 0.38)')
->hasNotAnyFonts(),
$this->createCssAssertBuilder('.content .comments .comment-date')
->propertyShouldBe('color', 'rgba(126, 47, 58, 0.35)')
->hasNotAnyFonts(),
], $diffs);
}
/**
* @param string $selector A base css element selector.
* @param boolean $escape Should escape specific pattern symbols or not.
*
* @return CssAssertBuilder
*/
private function createCssAssertBuilder($selector, $escape = true)
{
return new CssAssertBuilder($selector, $escape);
}
/**
* @param ThemeTypeEnum $themeType A ThemeTypeEnum instance.
* @param CssAssertBuilder[] $asserts Array of css assert builders.
*
* @param array $diffs Notification theme diffs.
*
* @return void
*/
private function assertCssRender(ThemeTypeEnum $themeType, array $asserts, array $diffs = [])
{
$html = $this->render($themeType, $diffs, [ new FeedData('test', []) ]);
/** @var CssAssertBuilder $assert */
foreach ($asserts as $assert) {
$assert->assert($html);
}
}
/**
* @param ThemeTypeEnum $themeType A ThemeTypeEnum instance.
* @param array $diffs Notification theme diffs.
*
* @return CssAsserter
*/
private function createAsserter(ThemeTypeEnum $themeType, array $diffs = [])
{
return CssAsserter::createFromHtml($this->render($themeType, $diffs, [ new FeedData('test', []) ]));
}
}
@@ -0,0 +1,55 @@
<?php
namespace Tests\UserBundle\Manager\Notification;
use ApiBundle\Serializer\Metadata\Metadata;
use UserBundle\Entity\Recipient\AbstractRecipient;
/**
* Class NotificationManagerTest
* @package UserBundle\Manager\Notification
*/
class RecipientFixture extends AbstractRecipient
{
/**
* RecipientFixture constructor.
*
* @param string|integer $id Entity id.
*/
public function __construct($id)
{
parent::__construct();
$this->id = $id;
}
/**
* Return fqcn of form used for creating this entity.
*
* @return string
*/
public function getCreateFormClass()
{
return '';
}
/**
* Return fqcn of form used for updating this entity.
*
* @return string
*/
public function getUpdateFormClass()
{
return '';
}
/**
* Return metadata for current entity.
*
* @return \ApiBundle\Serializer\Metadata\Metadata
*/
public function getMetadata()
{
return new Metadata(static::class);
}
}