feat: MailJet list handling with DOI, webhook receiver and API endpoint

addresses #869cut134
This commit is contained in:
Björn Fromme
2026-04-29 09:51:57 +02:00
parent df7885ca1c
commit e4ef2f7adc
46 changed files with 3389 additions and 322 deletions
+47
View File
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace App\Tests\Entity;
use App\Entity\NewsletterConsent;
use PHPUnit\Framework\TestCase;
class NewsletterConsentTest extends TestCase
{
public function testConfirmationAndRevocationAreListScoped(): void
{
$consent = new NewsletterConsent(' [email protected] ', 123, ' Mia ', ' Muster ');
self::assertSame('[email protected]', $consent->getEmail());
self::assertSame(123, $consent->getMailjetListId());
self::assertSame('Mia', $consent->getFirstName());
self::assertSame('Muster', $consent->getLastName());
self::assertFalse($consent->isConfirmed());
$consent->markConfirmed(new \DateTimeImmutable('2026-04-29 10:00:00'), 'New', null);
self::assertTrue($consent->isConfirmed());
self::assertFalse($consent->isRevoked());
self::assertSame('New', $consent->getFirstName());
self::assertSame('Muster', $consent->getLastName());
$consent->markRevoked(new \DateTimeImmutable('2026-04-29 11:00:00'));
self::assertFalse($consent->isConfirmed());
self::assertTrue($consent->isRevoked());
$consent->markConfirmed(new \DateTimeImmutable('2026-04-29 12:00:00'));
self::assertTrue($consent->isConfirmed());
self::assertFalse($consent->isRevoked());
}
public function testRejectsInvalidMailjetListId(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Mailjet list ID must be a positive integer.');
new NewsletterConsent('[email protected]', 0);
}
}
+103
View File
@@ -0,0 +1,103 @@
<?php
declare(strict_types=1);
namespace App\Tests\Entity;
use App\Entity\NewsletterOptInRequest;
use PHPUnit\Framework\TestCase;
class NewsletterOptInRequestTest extends TestCase
{
public function testConstructorNormalizesNames(): void
{
$confirmation = new NewsletterOptInRequest(
'[email protected]',
str_repeat('a', 64),
new \DateTimeImmutable('+1 hour'),
[2, 1],
' Mia ',
' Muster ',
);
self::assertSame('Mia', $confirmation->getFirstName());
self::assertSame('Muster', $confirmation->getLastName());
self::assertSame([1, 2], $confirmation->getMailjetListIds());
}
public function testConstructorConvertsBlankNamesToNull(): void
{
$confirmation = new NewsletterOptInRequest(
'[email protected]',
str_repeat('a', 64),
new \DateTimeImmutable('+1 hour'),
[],
' ',
'',
);
self::assertNull($confirmation->getFirstName());
self::assertNull($confirmation->getLastName());
}
public function testRefreshRequestPreservesMissingNamesAndUpdatesProvidedValues(): void
{
$confirmation = new NewsletterOptInRequest(
'[email protected]',
str_repeat('a', 64),
new \DateTimeImmutable('+1 hour'),
[1],
'Mia',
'Muster',
);
$confirmation->refreshRequest(
str_repeat('b', 64),
new \DateTimeImmutable('+2 hour'),
[2, 1],
null,
'Meyer',
);
self::assertSame('Mia', $confirmation->getFirstName());
self::assertSame('Meyer', $confirmation->getLastName());
self::assertSame([1, 2], $confirmation->getMailjetListIds());
self::assertFalse($confirmation->isConfirmed());
}
public function testMarkRevokedAndConfirmedLifecycleClearsRevocationState(): void
{
$confirmation = new NewsletterOptInRequest(
'[email protected]',
str_repeat('a', 64),
new \DateTimeImmutable('+1 hour'),
[1],
'Mia',
'Muster',
);
$confirmation->markRevoked(new \DateTimeImmutable('2026-04-28 12:00:00'));
self::assertTrue($confirmation->isRevoked());
self::assertNotNull($confirmation->getRevokedAt());
$confirmation->markConfirmed(new \DateTimeImmutable('2026-04-28 12:05:00'));
self::assertFalse($confirmation->isRevoked());
self::assertNull($confirmation->getRevokedAt());
$confirmation->markRevoked(new \DateTimeImmutable('2026-04-28 12:10:00'));
$confirmation->refreshRequest(
str_repeat('b', 64),
new \DateTimeImmutable('+2 hour'),
[2, 1],
'New',
null,
);
self::assertFalse($confirmation->isRevoked());
self::assertNull($confirmation->getRevokedAt());
self::assertSame('New', $confirmation->getFirstName());
self::assertSame('Muster', $confirmation->getLastName());
}
}