227 lines
7.3 KiB
PHP
227 lines
7.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace KupShop\BonusProgramBundle\Tests;
|
|
|
|
use KupShop\BonusProgramBundle\Email\BonusPointsExpiryEmail;
|
|
use KupShop\BonusProgramBundle\EventListener\CronListener;
|
|
use KupShop\BonusProgramBundle\Utils\BonusComputer;
|
|
use KupShop\BonusProgramBundle\Utils\BonusProvider;
|
|
use PHPUnit\DbUnit\DataSet\ArrayDataSet;
|
|
|
|
class BonusProgramEmailExpiryTest extends \DatabaseTestCase
|
|
{
|
|
private const REMOVE_TIME = 60;
|
|
private const EXPIRY_EMAIL_TIME = 14;
|
|
|
|
private BonusComputerMock $bonusComputer;
|
|
private BonusProvider $bonusProvider;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->bonusComputer = $this->autowire(BonusComputerMock::class);
|
|
$this->bonusProvider = $this->get(BonusProvider::class);
|
|
}
|
|
|
|
public function testGetUsersWithoutOrdersInLast(): void
|
|
{
|
|
$result = $this->bonusComputer->getUsersWithoutOrdersInLastPub(4);
|
|
|
|
// user 1 has an order today
|
|
// user 2 does not have any recent orders and has active points
|
|
// user 3 does not have active points
|
|
$this->assertEquals(0, $this->bonusProvider->getActivePointsAmount(3));
|
|
$this->assertTrue($this->bonusProvider->getActivePointsAmount(2) > 0);
|
|
|
|
$this->assertEquals([2, 4], $result, 'Špatně načtení uživatelé s bez nedávných objednávek!');
|
|
|
|
$result1 = $this->bonusComputer->getUsersWithoutOrdersInLastPub(40);
|
|
$this->assertEquals([4], $result1, 'Špatně načtení uživatelé s bez nedávných objednávek!');
|
|
|
|
$result2 = $this->bonusComputer->getUsersWithoutOrdersInLastPub(60);
|
|
$this->assertEmpty($result2, 'Špatně načtení uživatelé s bez nedávných objednávek!');
|
|
}
|
|
|
|
public function testGetPointsThatWillExpire(): void
|
|
{
|
|
// user 1 has an order created 3 days ago
|
|
$dateCreated = sqlQueryBuilder()->select('DATE(date_created)')
|
|
->from('orders')
|
|
->where('id_user = 1')
|
|
->execute()->fetchFirstColumn();
|
|
|
|
$this->assertEquals(
|
|
(new \DateTimeImmutable())->sub(new \DateInterval('P3D'))->format('Y-m-d'),
|
|
$dateCreated[0] ?? false,
|
|
);
|
|
|
|
// user 1 has points that are 2 days old
|
|
// remove time will be set to 60
|
|
// -> 60 - 2 = 58
|
|
// -> if the user would be notified today, the expiry_email_time would have to be set to 58 days
|
|
// -> test lookup of today + 58 days (simulate remove_time = 60 & expiry_email_time = 58)
|
|
|
|
$pointsCreatedDate = sqlQueryBuilder()->select('DATE(date_created)')
|
|
->from('bonus_points')
|
|
->where('id_user = 1')
|
|
->execute()->fetchFirstColumn();
|
|
|
|
$this->assertCount(1, $pointsCreatedDate);
|
|
$this->assertEquals(
|
|
(new \DateTimeImmutable())->sub(new \DateInterval('P2D'))->format('Y-m-d'),
|
|
$pointsCreatedDate[0] ?? false,
|
|
);
|
|
|
|
$result = $this->bonusComputer->getPointsThatExpireIn(
|
|
58,
|
|
self::REMOVE_TIME,
|
|
);
|
|
|
|
$this->assertEquals([
|
|
['id_user' => 1, 'points' => 256],
|
|
], $result, 'Neočekávaní uživatelé, kterým by měly expirovat body z BonusProgramu!');
|
|
}
|
|
|
|
public function testEmailGetsSent(): void
|
|
{
|
|
$this->set(
|
|
BonusPointsExpiryEmail::class,
|
|
$this->autowire(PointsExpiryEmailMock::class),
|
|
);
|
|
|
|
$dbcfg = \Settings::getDefault();
|
|
$dbcfg->saveValue('bonus_program', [
|
|
'expiry_email_time' => self::EXPIRY_EMAIL_TIME,
|
|
'remove_time' => self::REMOVE_TIME,
|
|
]);
|
|
|
|
\Settings::clearCache(true);
|
|
$listener = $this->get(CronListener::class);
|
|
|
|
$listener->sendPointsExpiryEmails();
|
|
|
|
$this->assertCount(
|
|
1,
|
|
PointsExpiryEmailMock::$payloads,
|
|
'E-mail o expiraci bodů nebyl odeslán!',
|
|
);
|
|
|
|
// make points 1 day older
|
|
sqlQueryBuilder()->update('bonus_points')
|
|
->where('id = 163')
|
|
->set('date_created', 'date_created - INTERVAL 1 DAY')
|
|
->execute();
|
|
|
|
PointsExpiryEmailMock::$payloads = [];
|
|
$listener->sendPointsExpiryEmails();
|
|
$this->assertCount(
|
|
0,
|
|
PointsExpiryEmailMock::$payloads,
|
|
'E-mail o expiraci bodů byl odeslán vícekrát!',
|
|
);
|
|
|
|
// make points 1 day newer (1 + 1 from previous change)
|
|
sqlQueryBuilder()->update('bonus_points')
|
|
->where('id = 163')
|
|
->set('date_created', 'date_created + INTERVAL 2 DAY')
|
|
->execute();
|
|
|
|
PointsExpiryEmailMock::$payloads = [];
|
|
$listener->sendPointsExpiryEmails();
|
|
$this->assertCount(
|
|
0,
|
|
PointsExpiryEmailMock::$payloads,
|
|
'E-mail o expiraci bodů byl odeslán o den dříve než měl být!',
|
|
);
|
|
}
|
|
|
|
public function testEmailDoesNotGetSent()
|
|
{
|
|
$this->set(
|
|
BonusPointsExpiryEmail::class,
|
|
$this->autowire(PointsExpiryEmailMock::class),
|
|
);
|
|
|
|
$dbcfg = \Settings::getDefault();
|
|
$dbcfg->saveValue('bonus_program', [
|
|
'expiry_email_time' => self::EXPIRY_EMAIL_TIME,
|
|
'remove_time' => self::REMOVE_TIME,
|
|
]);
|
|
|
|
\Settings::clearCache(true);
|
|
$listener = $this->get(CronListener::class);
|
|
|
|
$listener->sendPointsExpiryEmails();
|
|
|
|
$this->assertCount(
|
|
1,
|
|
PointsExpiryEmailMock::$payloads,
|
|
'E-mail o expiraci bodů nebyl odeslán!',
|
|
);
|
|
}
|
|
|
|
protected function getJsonDataSet($string): ArrayDataSet
|
|
{
|
|
$json = json_decode_strict($string, true);
|
|
|
|
$twoDaysAgo = (new \DateTimeImmutable())
|
|
->sub(new \DateInterval('P2D'))
|
|
->format('Y-m-d H:i:s');
|
|
|
|
$threeDaysAgo = (new \DateTimeImmutable())
|
|
->sub(new \DateInterval('P3D'))
|
|
->format('Y-m-d H:i:s');
|
|
|
|
$removeTime = self::REMOVE_TIME;
|
|
$notifyTime = self::EXPIRY_EMAIL_TIME;
|
|
$exactlyNeededTime = (new \DateTimeImmutable())
|
|
->add(new \DateInterval("P{$notifyTime}D"))
|
|
->sub(new \DateInterval("P{$removeTime}D"))
|
|
->format('Y-m-d H:i:s');
|
|
// meaning the user should be notified today
|
|
// there is 60 day ($removeTime) difference between date_created and 14 days from now ($notifyTime)
|
|
|
|
$sixteenDaysAgo = (new \DateTimeImmutable())
|
|
->sub(new \DateInterval('P16D'))
|
|
->format('Y-m-d H:i:s');
|
|
|
|
$orders = &$json['orders'];
|
|
$orders[0]['date_created'] = $threeDaysAgo;
|
|
$orders[1]['date_created'] = $sixteenDaysAgo;
|
|
|
|
$bonusPoints = &$json['bonus_points'];
|
|
$bonusPoints[0]['date_created'] = $twoDaysAgo;
|
|
$bonusPoints[3]['date_created'] = $exactlyNeededTime;
|
|
|
|
return new ArrayDataSet($json);
|
|
}
|
|
|
|
protected function getDataSet()
|
|
{
|
|
return $this->getJsonDataSetFromFile();
|
|
}
|
|
}
|
|
|
|
class BonusComputerMock extends BonusComputer
|
|
{
|
|
public function getUsersWithoutOrdersInLastPub(int $days): array
|
|
{
|
|
return $this->getUsersWithoutOrdersInLast($days);
|
|
}
|
|
}
|
|
|
|
class PointsExpiryEmailMock extends BonusPointsExpiryEmail
|
|
{
|
|
public static array $payloads = [];
|
|
|
|
public function sendEmail($message)
|
|
{
|
|
self::$payloads[] = $message;
|
|
|
|
return parent::sendEmail($message);
|
|
}
|
|
}
|