Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Process notification payloads with undefined items #96

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
24 changes: 16 additions & 8 deletions src/Controller/Shop/ProcessNotificationsAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,34 @@
namespace BitBag\SyliusAdyenPlugin\Controller\Shop;

use BitBag\SyliusAdyenPlugin\Bus\DispatcherInterface;
use BitBag\SyliusAdyenPlugin\Resolver\Notification\NotificationResolver;
use BitBag\SyliusAdyenPlugin\Exception\NotificationItemsEmptyException;
use BitBag\SyliusAdyenPlugin\Resolver\Notification\NotificationResolver\NoCommandResolvedException;
use BitBag\SyliusAdyenPlugin\Resolver\Notification\NotificationToCommandResolver;
use BitBag\SyliusAdyenPlugin\Resolver\Notification\NotificationResolverInterface;
use BitBag\SyliusAdyenPlugin\Resolver\Notification\NotificationToCommandResolverInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class ProcessNotificationsAction
{
public const EXPECTED_ADYEN_RESPONSE = '[accepted]';
private const EXPECTED_ADYEN_RESPONSE = '[accepted]';

/** @var DispatcherInterface */
private $dispatcher;

/** @var NotificationToCommandResolver */
/** @var NotificationToCommandResolverInterface */
private $notificationCommandResolver;

/** @var NotificationResolver */
/** @var NotificationResolverInterface */
private $notificationResolver;

/** @var LoggerInterface */
private $logger;

public function __construct(
DispatcherInterface $dispatcher,
NotificationToCommandResolver $notificationCommandResolver,
NotificationResolver $notificationResolver,
NotificationToCommandResolverInterface $notificationCommandResolver,
NotificationResolverInterface $notificationResolver,
LoggerInterface $logger,
) {
$this->dispatcher = $dispatcher;
Expand All @@ -49,7 +50,14 @@ public function __construct(

public function __invoke(string $code, Request $request): Response
{
foreach ($this->notificationResolver->resolve($code, $request) as $notificationItem) {
try {
$notifications = $this->notificationResolver->resolve($code, $request);
} catch (NotificationItemsEmptyException) {
$this->logger->error('Request payload did not contain any notification items');
$notifications = [];
}

foreach ($notifications as $notificationItem) {
if (null === $notificationItem || false === $notificationItem->success) {
$this->logger->error(\sprintf(
'Payment with pspReference [%s] did not return success',
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/NotificationItemsEmptyException.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@

namespace BitBag\SyliusAdyenPlugin\Exception;

class NotificationItemsEmptyException extends \InvalidArgumentException
final class NotificationItemsEmptyException extends \InvalidArgumentException
{
}
8 changes: 5 additions & 3 deletions src/Resolver/Notification/NotificationResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace BitBag\SyliusAdyenPlugin\Resolver\Notification;

use BitBag\SyliusAdyenPlugin\Exception\NotificationItemsEmptyException;
use BitBag\SyliusAdyenPlugin\Resolver\Notification\Struct\NotificationItemData;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
Expand Down Expand Up @@ -48,11 +49,12 @@ public function __construct(
*/
private function denormalizeRequestData(Request $request): array
{
$result = [];
$payload = $request->request->all();

/** @var array $notificationItems */
$notificationItems = $payload['notificationItems'];
$result = [];
$notificationItems = $payload['notificationItems']
?? throw new NotificationItemsEmptyException();

/** @var array $notificationItem */
foreach ($notificationItems as $notificationItem) {
Expand All @@ -70,7 +72,7 @@ private function denormalizeRequestData(Request $request): array
}

/**
* @return NotificationItemData[]
* @inheritDoc
*/
public function resolve(string $paymentCode, Request $request): array
{
Expand Down
3 changes: 3 additions & 0 deletions src/Resolver/Notification/NotificationResolverInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@

namespace BitBag\SyliusAdyenPlugin\Resolver\Notification;

use BitBag\SyliusAdyenPlugin\Exception\NotificationItemsEmptyException;
use BitBag\SyliusAdyenPlugin\Resolver\Notification\Struct\NotificationItemData;
use Symfony\Component\HttpFoundation\Request;

interface NotificationResolverInterface
{
/**
* @return NotificationItemData[]
*
* @throws NotificationItemsEmptyException
*/
public function resolve(string $paymentCode, Request $request): array;
}
4 changes: 2 additions & 2 deletions src/Resolver/Notification/Struct/NotificationRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ class NotificationRequest
/** @var ?bool */
public $live;

/** @var ?NotificationItem[] */
public $notificationItems;
/** @var NotificationItem[] */
public $notificationItems = [];
}
38 changes: 38 additions & 0 deletions tests/Unit/Controller/Shop/ProcessNotificationsActionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* You can find more information about us on https://bitbag.io and write us
* an email on [email protected].
*/

declare(strict_types=1);

namespace Tests\BitBag\SyliusAdyenPlugin\Unit\Controller\Shop;

use BitBag\SyliusAdyenPlugin\Bus\DispatcherInterface;
use BitBag\SyliusAdyenPlugin\Controller\Shop\ProcessNotificationsAction;
use BitBag\SyliusAdyenPlugin\Resolver\Notification\NotificationResolverInterface;
use BitBag\SyliusAdyenPlugin\Resolver\Notification\NotificationToCommandResolverInterface;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use Tests\BitBag\SyliusAdyenPlugin\Unit\Mock\RequestMother;

final class ProcessNotificationsActionTest extends TestCase
{
public function testUndefinedNotificationItemsRequestIsHandledProperly(): void
{
$action = new ProcessNotificationsAction(
$this->createMock(DispatcherInterface::class),
$this->createMock(NotificationToCommandResolverInterface::class),
$this->createMock(NotificationResolverInterface::class),
new NullLogger(),
);

$response = $action('dummy-code', RequestMother::createDummy());

self::assertSame(200, $response->getStatusCode());
self::assertSame('[accepted]', $response->getContent());
}
}
13 changes: 10 additions & 3 deletions tests/Unit/Mock/RequestMother.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,21 @@

final class RequestMother
{
public const TEST_LOCALE = 'pl_PL';
private const ROOT_PATH = '/';

private const TEST_LOCALE = 'pl_PL';

public const WHERE_YOUR_HOME_IS = '127.0.0.1';

public static function createDummy(): Request
{
return Request::create(self::ROOT_PATH);
}

public static function createWithSession(): Request
{
$session = new Session(new MockArraySessionStorage());
$request = Request::create('/');
$request = Request::create(self::ROOT_PATH);
$request->setSession($session);

return $request;
Expand All @@ -49,7 +56,7 @@ public static function createWithSessionForSpecifiedQueryToken(): Request

public static function createWithLocaleSet(): Request
{
$result = Request::create('/', 'GET', [], [], [], ['REMOTE_ADDR' => self::WHERE_YOUR_HOME_IS]);
$result = Request::create(self::ROOT_PATH, 'GET', [], [], [], ['REMOTE_ADDR' => self::WHERE_YOUR_HOME_IS]);
$result->setLocale(self::TEST_LOCALE);

return $result;
Expand Down
36 changes: 36 additions & 0 deletions tests/Unit/Resolver/Notification/NotificationResolverTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* You can find more information about us on https://bitbag.io and write us
* an email on [email protected].
*/

declare(strict_types=1);

namespace Tests\BitBag\SyliusAdyenPlugin\Unit\Resolver\Notification;

use BitBag\SyliusAdyenPlugin\Exception\NotificationItemsEmptyException;
use BitBag\SyliusAdyenPlugin\Resolver\Notification\NotificationResolver;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Tests\BitBag\SyliusAdyenPlugin\Unit\Mock\RequestMother;

final class NotificationResolverTest extends TestCase
{
public function testUndefinedNotificationItemsRequestIsHandledProperly(): void
{
$resolver = new NotificationResolver(
$this->createMock(DenormalizerInterface::class),
$this->createMock(ValidatorInterface::class),
new NullLogger(),
);

$this->expectException(NotificationItemsEmptyException::class);

$resolver->resolve('dummy-payment-code', RequestMother::createDummy());
}
}
Loading