feat: MailJet list handling with DOI, webhook receiver and API endpoint
addresses #869cut134
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
<?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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user