176 lines
6.6 KiB
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;
|
|
}
|
|
}
|