Files
myep/tests/Controller/Api/NewsletterSubscriptionControllerTest.php

176 lines
6.6 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Controller\Api;
use App\Controller\Api\NewsletterSubscriptionController;
use App\Exception\NewsletterListNotAllowedException;
use App\Exception\NewsletterProviderException;
use App\Model\NewsletterSubscriptionRequest;
use App\Model\NewsletterSubscriptionRequestResult;
use App\Service\NewsletterManager;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use Symfony\Component\HttpFoundation\Response;
class NewsletterSubscriptionControllerTest extends TestCase
{
public function testValidRequestReturnsAcceptedForNewConfirmation(): void
{
$manager = $this->createMock(NewsletterManager::class);
$manager
->expects(self::once())
->method('requestApiSubscription')
->with('[email protected]', [10321569], [10321569, 12345678], 'Mia', 'Muster')
->willReturn(new NewsletterSubscriptionRequestResult(
'[email protected]',
[10321569],
NewsletterSubscriptionRequestResult::STATE_CONFIRMATION_REQUESTED,
true,
));
$manager
->expects(self::once())
->method('createListIdMapping')
->with([10321569])
->willReturn([
[
'id' => 10321569,
'label' => 'E&P Newsletter',
],
]);
$controller = new NewsletterSubscriptionController($manager, new NullLogger(), [
10321569 => 'E&P Newsletter',
12345678 => 'Partner Updates',
]);
$response = $controller->subscribe($this->request('[email protected]', [10321569], 'Mia', 'Muster'));
$payload = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR);
self::assertSame(Response::HTTP_ACCEPTED, $response->getStatusCode());
self::assertSame([
'success' => true,
'email' => '[email protected]',
'lists' => [
[
'id' => 10321569,
'label' => 'E&P Newsletter',
'state' => NewsletterSubscriptionRequestResult::LIST_STATE_PENDING,
],
],
'state' => NewsletterSubscriptionRequestResult::STATE_CONFIRMATION_REQUESTED,
'confirmationRequested' => true,
], $payload);
}
public function testSubscribedRequestReturnsListWiseStates(): void
{
$manager = $this->createMock(NewsletterManager::class);
$manager
->expects(self::once())
->method('requestApiSubscription')
->with('[email protected]', [10321569, 12345678], [10321569, 12345678])
->willReturn(new NewsletterSubscriptionRequestResult(
'[email protected]',
[10321569, 12345678],
NewsletterSubscriptionRequestResult::STATE_SUBSCRIBED,
false,
[
10321569 => NewsletterSubscriptionRequestResult::LIST_STATE_ALREADY_REGISTERED,
12345678 => NewsletterSubscriptionRequestResult::LIST_STATE_SUCCESS,
],
));
$manager
->expects(self::once())
->method('createListIdMapping')
->with([10321569, 12345678])
->willReturn([
[
'id' => 10321569,
'label' => 'E&P Newsletter',
],
[
'id' => 12345678,
'label' => 'Partner Updates',
],
]);
$controller = new NewsletterSubscriptionController($manager, new NullLogger(), [
10321569 => 'E&P Newsletter',
12345678 => 'Partner Updates',
]);
$response = $controller->subscribe($this->request('[email protected]', [10321569, 12345678]));
$payload = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR);
self::assertSame(Response::HTTP_OK, $response->getStatusCode());
self::assertSame([
[
'id' => 10321569,
'label' => 'E&P Newsletter',
'state' => NewsletterSubscriptionRequestResult::LIST_STATE_ALREADY_REGISTERED,
],
[
'id' => 12345678,
'label' => 'Partner Updates',
'state' => NewsletterSubscriptionRequestResult::LIST_STATE_SUCCESS,
],
], $payload['lists']);
}
public function testNonAllowlistedListIdReturnsBadRequestBeforeSideEffects(): void
{
$manager = $this->createMock(NewsletterManager::class);
$manager
->expects(self::once())
->method('requestApiSubscription')
->with('[email protected]', [12345678], [10321569])
->willThrowException(new NewsletterListNotAllowedException([12345678], [12345678]));
$controller = new NewsletterSubscriptionController($manager, new NullLogger(), [
10321569 => 'E&P Newsletter',
]);
$response = $controller->subscribe($this->request('[email protected]', [12345678]));
$payload = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR);
self::assertSame(Response::HTTP_BAD_REQUEST, $response->getStatusCode());
self::assertSame([
'success' => false,
'message' => 'One or more Mailjet list IDs are not allowed.',
'listIds' => [12345678],
'unknownListIds' => [12345678],
], $payload);
}
public function testProviderFailureReturnsServiceUnavailable(): void
{
$manager = $this->createMock(NewsletterManager::class);
$manager
->expects(self::once())
->method('requestApiSubscription')
->with('[email protected]', [10321569], [10321569])
->willThrowException(new NewsletterProviderException('Mailjet failed'));
$controller = new NewsletterSubscriptionController($manager, new NullLogger(), [
10321569 => 'E&P Newsletter',
]);
$response = $controller->subscribe($this->request('[email protected]', [10321569]));
self::assertSame(Response::HTTP_SERVICE_UNAVAILABLE, $response->getStatusCode());
}
private function request(string $email, array $listIds, ?string $firstName = null, ?string $lastName = null): NewsletterSubscriptionRequest
{
$request = new NewsletterSubscriptionRequest();
$request->email = $email;
$request->listIds = $listIds;
$request->firstName = $firstName;
$request->lastName = $lastName;
return $request;
}
}