feat: create ClickUp task after confirming accommodation booking

This commit is contained in:
Björn Fromme
2026-08-20 17:56:29 +02:00
parent 0a1683667f
commit 7c5f6dd5ef
18 changed files with 535 additions and 48 deletions
+99
View File
@@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
namespace App\Tests\ClickUp;
use App\ClickUp\ApiClient;
use App\ClickUp\Exception\ClickUpException;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\MockResponse;
class ApiClientTest extends TestCase
{
public function testCreateTaskFromTemplatePostsTheNameAndReturnsTheTaskId(): void
{
$requests = [];
$http = new MockHttpClient(function (string $method, string $url, array $options) use (&$requests): MockResponse {
$requests[] = [$method, $url, $options];
return new MockResponse(json_encode(['id' => 'abc123'], JSON_THROW_ON_ERROR), [
'response_headers' => ['content-type' => 'application/json'],
]);
});
$taskId = $this->client($http)->createTaskFromTemplate('WIEN01 2026-08-20 Müller');
self::assertSame('abc123', $taskId);
self::assertSame('POST', $requests[0][0]);
self::assertSame('https://clickup.test/list/555/taskTemplate/tpl-7', $requests[0][1]);
self::assertSame(['name' => 'WIEN01 2026-08-20 Müller'], json_decode((string) $requests[0][2]['body'], true, 512, JSON_THROW_ON_ERROR));
self::assertContains('Authorization: pk_secret', $requests[0][2]['headers']);
}
public function testUpdateTaskStatusPutsTheStatus(): void
{
$requests = [];
$http = new MockHttpClient(function (string $method, string $url, array $options) use (&$requests): MockResponse {
$requests[] = [$method, $url, $options];
return new MockResponse(json_encode(['id' => 'abc123'], JSON_THROW_ON_ERROR), [
'response_headers' => ['content-type' => 'application/json'],
]);
});
$this->client($http)->updateTaskStatus('abc123', 'GRO');
self::assertSame('PUT', $requests[0][0]);
self::assertSame('https://clickup.test/task/abc123', $requests[0][1]);
self::assertSame(['status' => 'GRO'], json_decode((string) $requests[0][2]['body'], true, 512, JSON_THROW_ON_ERROR));
}
public function testAResponseWithoutATaskIdIsAnError(): void
{
$http = new MockHttpClient(new MockResponse(json_encode(['err' => 'nope'], JSON_THROW_ON_ERROR), [
'response_headers' => ['content-type' => 'application/json'],
]));
$this->expectException(ClickUpException::class);
$this->client($http)->createTaskFromTemplate('WIEN01 2026-08-20 Müller');
}
public function testAnHttpErrorIsWrappedInADomainException(): void
{
$http = new MockHttpClient(new MockResponse('rate limited', ['http_code' => 429]));
$this->expectException(ClickUpException::class);
$this->client($http)->createTaskFromTemplate('WIEN01 2026-08-20 Müller');
}
public function testAnUnconfiguredClientReportsItselfAndRefusesToRequest(): void
{
$http = new MockHttpClient(function (): MockResponse {
self::fail('No request must be made when the client is unconfigured.');
});
$client = new ApiClient($http, new NullLogger(), 'pk_secret', '', 'tpl-7', 'https://clickup.test');
self::assertFalse($client->isConfigured());
$this->expectException(ClickUpException::class);
$client->createTaskFromTemplate('WIEN01 2026-08-20 Müller');
}
public function testAFullyConfiguredClientReportsItself(): void
{
self::assertTrue($this->client(new MockHttpClient())->isConfigured());
self::assertFalse((new ApiClient(new MockHttpClient(), new NullLogger()))->isConfigured());
}
private function client(MockHttpClient $http): ApiClient
{
return new ApiClient($http, new NullLogger(), 'pk_secret', '555', 'tpl-7', 'https://clickup.test');
}
}
@@ -5,7 +5,7 @@ declare(strict_types=1);
namespace App\Tests\Command;
use App\Command\MailjetNewsletterWebhookCommand;
use App\Service\MailjetApiClient;
use App\Mailjet\ApiClient;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Command\Command;
@@ -15,7 +15,7 @@ class MailjetNewsletterWebhookCommandTest extends TestCase
{
public function testRegisterCreatesWebhookAndPrintsPayload(): void
{
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailjet->expects(self::once())
->method('createEventCallbackUrl')
->with(
@@ -43,7 +43,7 @@ class MailjetNewsletterWebhookCommandTest extends TestCase
public function testRemoveDeletesWebhookById(): void
{
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailjet->expects(self::never())->method('createEventCallbackUrl');
$mailjet->expects(self::once())
->method('deleteEventCallbackUrl')
@@ -58,7 +58,7 @@ class MailjetNewsletterWebhookCommandTest extends TestCase
public function testDeactivateUsesRemoveFlow(): void
{
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailjet->expects(self::never())->method('createEventCallbackUrl');
$mailjet->expects(self::once())
->method('deleteEventCallbackUrl')
@@ -73,7 +73,7 @@ class MailjetNewsletterWebhookCommandTest extends TestCase
public function testRemoveFailsWithoutCallbackId(): void
{
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailjet->expects(self::never())->method('createEventCallbackUrl');
$mailjet->expects(self::never())->method('deleteEventCallbackUrl');
@@ -84,7 +84,7 @@ class MailjetNewsletterWebhookCommandTest extends TestCase
self::assertStringContainsString('A numeric callback ID is required', $tester->getDisplay());
}
private function createCommand(MailjetApiClient $mailjetApiClient): MailjetNewsletterWebhookCommand
private function createCommand(ApiClient $mailjetApiClient): MailjetNewsletterWebhookCommand
{
return new MailjetNewsletterWebhookCommand(
$mailjetApiClient,
@@ -7,11 +7,15 @@ namespace App\Tests\Controller\Admin\AccommodationBooking;
use App\Controller\Admin\AccommodationBooking\ConfirmController;
use App\Entity\Groups\AccommodationBooking;
use App\Enum\Groups\AccommodationBookingStatus;
use App\Message\CreateClickUpBookingTaskMessage;
use App\Service\AccommodationBookingService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
/**
@@ -25,7 +29,7 @@ class ConfirmControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('confirmBooking');
$controller = new TestableConfirmController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableConfirmController($bookingService, $this->neverDispatchingBus(), $this->createMock(LoggerInterface::class));
$response = $controller->index($this->receivedBooking(), Request::create('/admin/accommodation-booking/1/confirm'));
@@ -40,7 +44,14 @@ class ConfirmControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::once())->method('confirmBooking')->with($booking);
$controller = new TestableConfirmController($bookingService, $this->createMock(LoggerInterface::class));
// The ClickUp task is created asynchronously because the ClickUp API is slow.
$messageBus = $this->createMock(MessageBusInterface::class);
$messageBus->expects(self::once())
->method('dispatch')
->with(self::isInstanceOf(CreateClickUpBookingTaskMessage::class))
->willReturnCallback(static fn (object $message): Envelope => new Envelope($message));
$controller = new TestableConfirmController($bookingService, $messageBus, $this->createMock(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/confirm', 'POST'));
@@ -52,7 +63,7 @@ class ConfirmControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('confirmBooking');
$controller = new TestableConfirmController($bookingService, $this->createMock(LoggerInterface::class), tokenValid: false);
$controller = new TestableConfirmController($bookingService, $this->neverDispatchingBus(), $this->createMock(LoggerInterface::class), tokenValid: false);
$this->expectException(AccessDeniedException::class);
@@ -70,7 +81,7 @@ class ConfirmControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('confirmBooking');
$controller = new TestableConfirmController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableConfirmController($bookingService, $this->neverDispatchingBus(), $this->createMock(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/confirm', 'POST'));
@@ -97,7 +108,7 @@ class ConfirmControllerTest extends TestCase
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->expects(self::never())->method('confirmBooking');
$controller = new TestableConfirmController($bookingService, $this->createMock(LoggerInterface::class));
$controller = new TestableConfirmController($bookingService, $this->neverDispatchingBus(), $this->createMock(LoggerInterface::class));
$response = $controller->index($booking, Request::create('/admin/accommodation-booking/1/confirm', 'POST'));
@@ -105,6 +116,17 @@ class ConfirmControllerTest extends TestCase
self::assertStringContainsString('app_admin_accommodationbooking_edit', (string) $response->headers->get('HX-Redirect'));
}
/**
* @return MessageBusInterface&MockObject
*/
private function neverDispatchingBus(): MessageBusInterface
{
$messageBus = $this->createMock(MessageBusInterface::class);
$messageBus->expects(self::never())->method('dispatch');
return $messageBus;
}
private function receivedBooking(): AccommodationBooking
{
$booking = new AccommodationBooking();
@@ -125,10 +147,11 @@ final class TestableConfirmController extends ConfirmController
public function __construct(
AccommodationBookingService $bookingService,
MessageBusInterface $messageBus,
LoggerInterface $logger,
private readonly bool $tokenValid = true,
) {
parent::__construct($bookingService, $logger);
parent::__construct($bookingService, $messageBus, $logger);
}
protected function isCsrfTokenValid(string $id, #[\SensitiveParameter] ?string $token): bool
@@ -2,15 +2,15 @@
declare(strict_types=1);
namespace App\Tests\Service;
namespace App\Tests\Mailjet;
use App\Service\MailjetApiClient;
use App\Mailjet\ApiClient;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\MockResponse;
class MailjetApiClientTest extends TestCase
class ApiClientTest extends TestCase
{
public function testChecksSubscriptionAgainstSuppliedListId(): void
{
@@ -37,7 +37,7 @@ class MailjetApiClientTest extends TestCase
], JSON_THROW_ON_ERROR));
});
$mailjet = new MailjetApiClient($client, new NullLogger(), 'key', 'secret', 'https://mailjet.test', '111');
$mailjet = new ApiClient($client, new NullLogger(), 'key', 'secret', 'https://mailjet.test', '111');
$subscribed = $mailjet->isSubscribed(' [email protected] ', 123);
@@ -70,7 +70,7 @@ class MailjetApiClientTest extends TestCase
], JSON_THROW_ON_ERROR));
});
$mailjet = new MailjetApiClient(
$mailjet = new ApiClient(
$client,
new NullLogger(),
'key',
@@ -134,7 +134,7 @@ class MailjetApiClientTest extends TestCase
return new MockResponse(json_encode(['Data' => []], JSON_THROW_ON_ERROR));
});
$mailjet = new MailjetApiClient(
$mailjet = new ApiClient(
$client,
new NullLogger(),
'key',
@@ -166,7 +166,7 @@ class MailjetApiClientTest extends TestCase
return new MockResponse(json_encode(['Data' => []], JSON_THROW_ON_ERROR));
});
$mailjet = new MailjetApiClient($client, new NullLogger(), 'key', 'secret', 'https://mailjet.test', '111');
$mailjet = new ApiClient($client, new NullLogger(), 'key', 'secret', 'https://mailjet.test', '111');
$mailjet->upsertContact(' [email protected] ');
@@ -182,7 +182,7 @@ class MailjetApiClientTest extends TestCase
return new MockResponse(json_encode(['Data' => []], JSON_THROW_ON_ERROR));
});
$mailjet = new MailjetApiClient($client, new NullLogger(), 'key', 'secret', 'https://mailjet.test', '111');
$mailjet = new ApiClient($client, new NullLogger(), 'key', 'secret', 'https://mailjet.test', '111');
$mailjet->ensureSubscribed(' [email protected] ', 456);
@@ -2,9 +2,9 @@
declare(strict_types=1);
namespace App\Tests\Service;
namespace App\Tests\Mailjet;
use App\Service\MailjetApiClient;
use App\Mailjet\ApiClient;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use Symfony\Component\HttpClient\MockHttpClient;
@@ -33,7 +33,7 @@ class MailjetNewsletterWebhookClientTest extends TestCase
], JSON_THROW_ON_ERROR));
});
$mailjet = new MailjetApiClient($client, new NullLogger(), 'key', 'secret', 'https://mailjet.test', '111');
$mailjet = new ApiClient($client, new NullLogger(), 'key', 'secret', 'https://mailjet.test', '111');
$response = $mailjet->createEventCallbackUrl('unsub', 'https://my.ep-reisen.de/webhooks/mailjet/newsletter');
self::assertSame(456, $response['Data'][0]['ID']);
@@ -48,7 +48,7 @@ class MailjetNewsletterWebhookClientTest extends TestCase
return new MockResponse('', ['http_code' => 204]);
});
$mailjet = new MailjetApiClient($client, new NullLogger(), 'key', 'secret', 'https://mailjet.test', '111');
$mailjet = new ApiClient($client, new NullLogger(), 'key', 'secret', 'https://mailjet.test', '111');
$mailjet->deleteEventCallbackUrl(456);
}
}
@@ -0,0 +1,132 @@
<?php
declare(strict_types=1);
namespace App\Tests\MessageHandler;
use App\ClickUp\ApiClient;
use App\ClickUp\Exception\ClickUpException;
use App\Entity\Groups\Accommodation;
use App\Entity\Groups\AccommodationBooking;
use App\Message\CreateClickUpBookingTaskMessage;
use App\MessageHandler\CreateClickUpBookingTaskHandler;
use App\Repository\Groups\AccommodationBookingRepository;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
class CreateClickUpBookingTaskHandlerTest extends TestCase
{
public function testCreatesTheTaskAndMovesItIntoTheGroupsStatus(): void
{
$repository = $this->createMock(AccommodationBookingRepository::class);
$repository->method('find')->with(42)->willReturn($this->booking());
$client = $this->createMock(ApiClient::class);
$client->method('isConfigured')->willReturn(true);
$client->expects(self::once())
->method('createTaskFromTemplate')
->with('WIEN01 2026-08-20 Anna Müller')
->willReturn('abc123');
$client->expects(self::once())
->method('updateTaskStatus')
->with('abc123', CreateClickUpBookingTaskHandler::TASK_STATUS);
$this->handler($repository, $client)(new CreateClickUpBookingTaskMessage(42));
}
public function testAnUnconfiguredClientIsSkippedWithoutTouchingTheDatabase(): void
{
$repository = $this->createMock(AccommodationBookingRepository::class);
$repository->expects(self::never())->method('find');
$client = $this->createMock(ApiClient::class);
$client->method('isConfigured')->willReturn(false);
$client->expects(self::never())->method('createTaskFromTemplate');
$this->handler($repository, $client)(new CreateClickUpBookingTaskMessage(42));
}
public function testAVanishedBookingIsSkipped(): void
{
$repository = $this->createMock(AccommodationBookingRepository::class);
$repository->method('find')->willReturn(null);
$client = $this->createMock(ApiClient::class);
$client->method('isConfigured')->willReturn(true);
$client->expects(self::never())->method('createTaskFromTemplate');
$this->handler($repository, $client)(new CreateClickUpBookingTaskMessage(42));
}
/**
* @dataProvider incompleteBookings
*/
public function testABookingWithoutTheDataForATaskNameIsSkipped(callable $mutate): void
{
$booking = $this->booking();
$mutate($booking);
$repository = $this->createMock(AccommodationBookingRepository::class);
$repository->method('find')->willReturn($booking);
$client = $this->createMock(ApiClient::class);
$client->method('isConfigured')->willReturn(true);
$client->expects(self::never())->method('createTaskFromTemplate');
$this->handler($repository, $client)(new CreateClickUpBookingTaskMessage(42));
}
/**
* @return iterable<string, array{callable(AccommodationBooking): void}>
*/
public static function incompleteBookings(): iterable
{
yield 'without an accommodation' => [static fn (AccommodationBooking $b) => $b->setAccommodation(null)];
yield 'without a contact name' => [static function (AccommodationBooking $b): void {
$b->setFirstName(null);
$b->setLastName(null);
}];
yield 'with a blank contact name' => [static function (AccommodationBooking $b): void {
$b->setFirstName(' ');
$b->setLastName(' ');
}];
}
public function testAFailingStatusUpdateDoesNotRetryTheTaskCreation(): void
{
$repository = $this->createMock(AccommodationBookingRepository::class);
$repository->method('find')->willReturn($this->booking());
$client = $this->createMock(ApiClient::class);
$client->method('isConfigured')->willReturn(true);
$client->method('createTaskFromTemplate')->willReturn('abc123');
$client->method('updateTaskStatus')->willThrowException(new ClickUpException('boom'));
$this->handler($repository, $client)(new CreateClickUpBookingTaskMessage(42));
// Reaching this point is the assertion: the exception must not bubble up into the
// transport, because a retry would create a second ClickUp task.
self::assertTrue(true);
}
private function handler(
AccommodationBookingRepository $repository,
ApiClient $client,
): CreateClickUpBookingTaskHandler {
return new CreateClickUpBookingTaskHandler($repository, $client, new NullLogger());
}
private function booking(): AccommodationBooking
{
$accommodation = new Accommodation();
$accommodation->setCalendarCode('WIEN01');
$booking = new AccommodationBooking();
$booking->setAccommodation($accommodation);
$booking->setDateFrom(new \DateTimeImmutable('2026-08-20'));
$booking->setFirstName('Anna');
$booking->setLastName('Müller');
return $booking;
}
}
+18 -18
View File
@@ -8,11 +8,11 @@ use App\Email\Mailer;
use App\Entity\NewsletterConsent;
use App\Entity\NewsletterOptInRequest;
use App\Exception\NewsletterListNotAllowedException;
use App\Mailjet\ApiClient;
use App\Model\NewsletterConfirmationResult;
use App\Model\NewsletterSubscriptionRequestResult;
use App\Repository\NewsletterConsentRepository;
use App\Repository\NewsletterOptInRequestRepository;
use App\Service\MailjetApiClient;
use App\Service\NewsletterManager;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\MockObject\MockObject;
@@ -26,7 +26,7 @@ class NewsletterManagerTest extends TestCase
$repository = $this->createMock(NewsletterOptInRequestRepository::class);
$consents = $this->createMock(NewsletterConsentRepository::class);
$entityManager = $this->createMock(EntityManagerInterface::class);
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailer = $this->createMock(Mailer::class);
$mailjet->expects(self::never())->method('isSubscribed');
@@ -83,7 +83,7 @@ class NewsletterManagerTest extends TestCase
$repository = $this->createMock(NewsletterOptInRequestRepository::class);
$consents = $this->createMock(NewsletterConsentRepository::class);
$entityManager = $this->createMock(EntityManagerInterface::class);
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailer = $this->createMock(Mailer::class);
$mailjet->expects(self::never())->method('isSubscribed');
@@ -114,7 +114,7 @@ class NewsletterManagerTest extends TestCase
$repository = $this->createMock(NewsletterOptInRequestRepository::class);
$consents = $this->createMock(NewsletterConsentRepository::class);
$entityManager = $this->createMock(EntityManagerInterface::class);
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailer = $this->createMock(Mailer::class);
$mailjet->expects(self::never())->method('isSubscribed');
@@ -147,7 +147,7 @@ class NewsletterManagerTest extends TestCase
$repository = $this->createMock(NewsletterOptInRequestRepository::class);
$consents = $this->createMock(NewsletterConsentRepository::class);
$entityManager = $this->createMock(EntityManagerInterface::class);
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailer = $this->createMock(Mailer::class);
$mailjet->expects(self::never())->method('isSubscribed');
@@ -191,7 +191,7 @@ class NewsletterManagerTest extends TestCase
$repository = $this->createMock(NewsletterOptInRequestRepository::class);
$consents = $this->createMock(NewsletterConsentRepository::class);
$entityManager = $this->createMock(EntityManagerInterface::class);
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailer = $this->createMock(Mailer::class);
$mailjet->expects(self::never())->method('isSubscribed');
@@ -219,7 +219,7 @@ class NewsletterManagerTest extends TestCase
$repository = $this->createMock(NewsletterOptInRequestRepository::class);
$consents = $this->createMock(NewsletterConsentRepository::class);
$entityManager = $this->createMock(EntityManagerInterface::class);
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailer = $this->createMock(Mailer::class);
$mailjet->expects(self::never())->method('isSubscribed');
@@ -251,7 +251,7 @@ class NewsletterManagerTest extends TestCase
$repository = $this->createMock(NewsletterOptInRequestRepository::class);
$consents = $this->createMock(NewsletterConsentRepository::class);
$entityManager = $this->createMock(EntityManagerInterface::class);
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailer = $this->createMock(Mailer::class);
$mailjet->expects(self::never())->method('isSubscribed');
@@ -276,7 +276,7 @@ class NewsletterManagerTest extends TestCase
$repository = $this->createMock(NewsletterOptInRequestRepository::class);
$consents = $this->createMock(NewsletterConsentRepository::class);
$entityManager = $this->createMock(EntityManagerInterface::class);
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailer = $this->createMock(Mailer::class);
$mailjet->expects(self::never())->method('ensureSubscribed');
@@ -303,7 +303,7 @@ class NewsletterManagerTest extends TestCase
$repository = $this->createMock(NewsletterOptInRequestRepository::class);
$consents = $this->createMock(NewsletterConsentRepository::class);
$entityManager = $this->createMock(EntityManagerInterface::class);
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailer = $this->createMock(Mailer::class);
$mailjet->expects(self::never())->method('ensureSubscribed');
@@ -339,7 +339,7 @@ class NewsletterManagerTest extends TestCase
$repository = $this->createMock(NewsletterOptInRequestRepository::class);
$consents = $this->createMock(NewsletterConsentRepository::class);
$entityManager = $this->createMock(EntityManagerInterface::class);
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailer = $this->createMock(Mailer::class);
$repository->expects(self::once())->method('findByTokenHash')->with(hash('sha256', $token))->willReturn($confirmation);
@@ -370,7 +370,7 @@ class NewsletterManagerTest extends TestCase
$repository = $this->createMock(NewsletterOptInRequestRepository::class);
$consents = $this->createMock(NewsletterConsentRepository::class);
$entityManager = $this->createMock(EntityManagerInterface::class);
$mailjet = $this->createMock(MailjetApiClient::class);
$mailjet = $this->createMock(ApiClient::class);
$mailer = $this->createMock(Mailer::class);
$repository->expects(self::once())->method('findByTokenHash')->with(hash('sha256', $token))->willReturn($confirmation);
@@ -434,17 +434,17 @@ class NewsletterManagerTest extends TestCase
/**
* @param MockObject&NewsletterOptInRequestRepository $repository
* @param MockObject&NewsletterConsentRepository $consents
* @param MockObject&EntityManagerInterface $entityManager
* @param MockObject&MailjetApiClient $mailjet
* @param MockObject&Mailer $mailer
* @param array<int, string> $mailjetLists
* @param MockObject&NewsletterConsentRepository $consents
* @param MockObject&EntityManagerInterface $entityManager
* @param MockObject&ApiClient $mailjet
* @param MockObject&Mailer $mailer
* @param array<int, string> $mailjetLists
*/
private function createManager(
NewsletterOptInRequestRepository $repository,
NewsletterConsentRepository $consents,
EntityManagerInterface $entityManager,
MailjetApiClient $mailjet,
ApiClient $mailjet,
Mailer $mailer,
array $mailjetLists = [
10321569 => 'E&P Newsletter',