first commit

This commit is contained in:
2025-08-02 16:30:27 +02:00
commit 23646bfcee
14851 changed files with 1750626 additions and 0 deletions

View File

@@ -0,0 +1,226 @@
<?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);
}
}