145 lines
5.9 KiB
PHP
145 lines
5.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\MessageHandler;
|
|
|
|
use App\Entity\NewsletterConsent;
|
|
use App\Message\MailjetNewsletterEventMessage;
|
|
use App\MessageHandler\MailjetNewsletterEventHandler;
|
|
use App\Repository\NewsletterConsentRepository;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class MailjetNewsletterEventHandlerTest extends TestCase
|
|
{
|
|
public function testUnsubscribeRevokesExistingConsent(): void
|
|
{
|
|
$consent = new NewsletterConsent('[email protected]', 123);
|
|
$consent->markConfirmed(new \DateTimeImmutable('2026-04-29T10:00:00+00:00'));
|
|
|
|
$repository = $this->createMock(NewsletterConsentRepository::class);
|
|
$repository
|
|
->expects(self::once())
|
|
->method('findOneByEmailAndListId')
|
|
->with('[email protected]', 123)
|
|
->willReturn($consent);
|
|
|
|
$entityManager = $this->createMock(EntityManagerInterface::class);
|
|
$entityManager->expects(self::never())->method('persist');
|
|
$entityManager->expects(self::once())->method('flush');
|
|
|
|
$handler = new MailjetNewsletterEventHandler($repository, $entityManager);
|
|
$handler(new MailjetNewsletterEventMessage(
|
|
email: '[email protected]',
|
|
mailjetListId: 123,
|
|
event: MailjetNewsletterEventMessage::EVENT_UNSUBSCRIBE,
|
|
eventAt: new \DateTimeImmutable('2026-04-29T11:00:00+00:00'),
|
|
));
|
|
|
|
self::assertTrue($consent->isRevoked());
|
|
self::assertSame('2026-04-29T11:00:00+00:00', $consent->getRevokedAt()?->format(DATE_ATOM));
|
|
}
|
|
|
|
public function testUnsubscribeCreatesRevokedTombstoneForUnknownConsent(): void
|
|
{
|
|
$persistedConsent = null;
|
|
$repository = $this->createMock(NewsletterConsentRepository::class);
|
|
$repository
|
|
->expects(self::once())
|
|
->method('findOneByEmailAndListId')
|
|
->with('[email protected]', 123)
|
|
->willReturn(null);
|
|
|
|
$entityManager = $this->createMock(EntityManagerInterface::class);
|
|
$entityManager
|
|
->expects(self::once())
|
|
->method('persist')
|
|
->with(self::callback(static function (NewsletterConsent $consent) use (&$persistedConsent): bool {
|
|
$persistedConsent = $consent;
|
|
|
|
return true;
|
|
}));
|
|
$entityManager->expects(self::once())->method('flush');
|
|
|
|
$handler = new MailjetNewsletterEventHandler($repository, $entityManager);
|
|
$handler(new MailjetNewsletterEventMessage(
|
|
email: '[email protected]',
|
|
mailjetListId: 123,
|
|
event: MailjetNewsletterEventMessage::EVENT_UNSUBSCRIBE,
|
|
eventAt: new \DateTimeImmutable('2026-04-29T11:00:00+00:00'),
|
|
));
|
|
|
|
self::assertInstanceOf(NewsletterConsent::class, $persistedConsent);
|
|
self::assertSame('[email protected]', $persistedConsent->getEmail());
|
|
self::assertSame(123, $persistedConsent->getMailjetListId());
|
|
self::assertTrue($persistedConsent->isRevoked());
|
|
}
|
|
|
|
public function testDuplicateOlderUnsubscribeDoesNotRewriteConsent(): void
|
|
{
|
|
$consent = new NewsletterConsent('[email protected]', 123);
|
|
$consent->markRevoked(new \DateTimeImmutable('2026-04-29T11:00:00+00:00'));
|
|
|
|
$repository = $this->createMock(NewsletterConsentRepository::class);
|
|
$repository->method('findOneByEmailAndListId')->willReturn($consent);
|
|
|
|
$entityManager = $this->createMock(EntityManagerInterface::class);
|
|
$entityManager->expects(self::never())->method('flush');
|
|
|
|
$handler = new MailjetNewsletterEventHandler($repository, $entityManager);
|
|
$handler(new MailjetNewsletterEventMessage(
|
|
email: '[email protected]',
|
|
mailjetListId: 123,
|
|
event: MailjetNewsletterEventMessage::EVENT_UNSUBSCRIBE,
|
|
eventAt: new \DateTimeImmutable('2026-04-29T10:00:00+00:00'),
|
|
));
|
|
|
|
self::assertSame('2026-04-29T11:00:00+00:00', $consent->getRevokedAt()?->format(DATE_ATOM));
|
|
}
|
|
|
|
public function testOlderUnsubscribeDoesNotRevokeNewerConfirmation(): void
|
|
{
|
|
$consent = new NewsletterConsent('[email protected]', 123);
|
|
$consent->markConfirmed(new \DateTimeImmutable('2026-04-29T11:00:00+00:00'));
|
|
|
|
$repository = $this->createMock(NewsletterConsentRepository::class);
|
|
$repository->method('findOneByEmailAndListId')->willReturn($consent);
|
|
|
|
$entityManager = $this->createMock(EntityManagerInterface::class);
|
|
$entityManager->expects(self::never())->method('flush');
|
|
|
|
$handler = new MailjetNewsletterEventHandler($repository, $entityManager);
|
|
$handler(new MailjetNewsletterEventMessage(
|
|
email: '[email protected]',
|
|
mailjetListId: 123,
|
|
event: MailjetNewsletterEventMessage::EVENT_UNSUBSCRIBE,
|
|
eventAt: new \DateTimeImmutable('2026-04-29T10:00:00+00:00'),
|
|
));
|
|
|
|
self::assertTrue($consent->isConfirmed());
|
|
self::assertNull($consent->getRevokedAt());
|
|
}
|
|
|
|
public function testDuplicateUnsubscribeWithoutTimestampDoesNotRewriteConsent(): void
|
|
{
|
|
$consent = new NewsletterConsent('[email protected]', 123);
|
|
$consent->markRevoked(new \DateTimeImmutable('2026-04-29T11:00:00+00:00'));
|
|
|
|
$repository = $this->createMock(NewsletterConsentRepository::class);
|
|
$repository->method('findOneByEmailAndListId')->willReturn($consent);
|
|
|
|
$entityManager = $this->createMock(EntityManagerInterface::class);
|
|
$entityManager->expects(self::never())->method('flush');
|
|
|
|
$handler = new MailjetNewsletterEventHandler($repository, $entityManager);
|
|
$handler(new MailjetNewsletterEventMessage(
|
|
email: '[email protected]',
|
|
mailjetListId: 123,
|
|
event: MailjetNewsletterEventMessage::EVENT_UNSUBSCRIBE,
|
|
));
|
|
|
|
self::assertSame('2026-04-29T11:00:00+00:00', $consent->getRevokedAt()?->format(DATE_ATOM));
|
|
}
|
|
}
|