Skip to content

Commit

Permalink
[paypal-ec] add support of cancel request.
Browse files Browse the repository at this point in the history
  • Loading branch information
makasim committed Sep 15, 2016
1 parent b63682a commit 9f53df6
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 183 deletions.
3 changes: 2 additions & 1 deletion Action/Api/DoVoidAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ public function __construct()

/**
* {@inheritdoc}
*
* @param $request DoVoid
*/
public function execute($request)
{
/** @var $request DoCapture */
RequestNotSupportedException::assertSupports($this, $request);

$model = ArrayObject::ensureArrayObject($request->getModel());
Expand Down
23 changes: 12 additions & 11 deletions Action/CancelAction.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
<?php
namespace Payum\Paypal\ExpressCheckout\Nvp\Action;

use Payum\Core\Action\GatewayAwareAction;
use Payum\Core\Action\ActionInterface;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\GatewayAwareInterface;
use Payum\Core\GatewayAwareTrait;
use Payum\Core\Request\Cancel;
use Payum\Core\Request\Sync;
use Payum\Paypal\ExpressCheckout\Nvp\Api;
use Payum\Paypal\ExpressCheckout\Nvp\Request\Api\DoVoid;

class CancelAction extends GatewayAwareAction
class CancelAction implements ActionInterface, GatewayAwareInterface
{
use GatewayAwareTrait;

/**
* {@inheritDoc}
*/
Expand All @@ -21,17 +24,15 @@ public function execute($request)

$details = ArrayObject::ensureArrayObject($request->getModel());

$details['PAYMENTREQUEST_0_PAYMENTACTION'] = Api::PAYMENTACTION_VOID;
if (empty($details['AUTHORIZATIONID']) && !empty($details['TRANSACTIONID'])) {
$details['AUTHORIZATIONID'] = $details['TRANSACTIONID'];
if (!$details['TRANSACTIONID']) {
return;
}

foreach (range(0, 9) as $index) {
if (Api::PENDINGREASON_AUTHORIZATION == $details['PAYMENTINFO_'.$index.'_PENDINGREASON']) {
$this->gateway->execute(new DoVoid($details, $index));
}
}
$voidDetails = new ArrayObject([
'AUTHORIZATIONID' => $details['TRANSACTIONID'],
]);

$this->gateway->execute(new DoVoid($voidDetails));
$this->gateway->execute(new Sync($request->getModel()));
}

Expand Down
5 changes: 0 additions & 5 deletions Api.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,6 @@ class Api
*/
const PAYMENTACTION_ORDER = 'Order';

/**
* Void – This is the voiding of an authorized order that has not been captured.
*/
const PAYMENTACTION_VOID = 'Void';

/**
* Payment has not been authorized by the user.
*/
Expand Down
184 changes: 18 additions & 166 deletions Tests/Action/CancelActionTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<?php
namespace Payum\Paypal\ExpressCheckout\Nvp\Tests\Action;

use Payum\Core\Action\ActionInterface;
use Payum\Core\GatewayAwareInterface;
use Payum\Core\GatewayInterface;
use Payum\Core\Request\Cancel;
use Payum\Core\Request\Sync;
use Payum\Paypal\ExpressCheckout\Nvp\Action\CancelAction;
Expand All @@ -12,51 +15,29 @@ class CancelActionTest extends \PHPUnit_Framework_TestCase
/**
* @test
*/
public function shouldBeSubClassOfGatewayAwareAction()
public function shouldImplementActionInterface()
{
$rc = new \ReflectionClass('Payum\Paypal\ExpressCheckout\Nvp\Action\CancelAction');
$rc = new \ReflectionClass(CancelAction::class);

$this->assertTrue($rc->isSubclassOf('Payum\Core\Action\GatewayAwareAction'));
$this->assertTrue($rc->isSubclassOf(ActionInterface::class));
}

/**
* @test
*/
public function couldBeConstructedWithoutAnyArguments()
public function shouldImplementGatewayAwareInterface()
{
new CancelAction();
}
$rc = new \ReflectionClass(CancelAction::class);

/**
* @test
*/
public function shouldSetZeroGatewayActionAsVoid()
{
$action = new CancelAction();
$action->setGateway($this->createGatewayMock());

$action->execute($request = new Cancel([]));

$model = $request->getModel();
$this->assertArrayHasKey('PAYMENTREQUEST_0_PAYMENTACTION', $model);
$this->assertEquals(Api::PAYMENTACTION_VOID, $model['PAYMENTREQUEST_0_PAYMENTACTION']);
$this->assertTrue($rc->isSubclassOf(GatewayAwareInterface::class));
}

/**
* @test
*/
public function shouldForcePaymentActionVoid()
public function couldBeConstructedWithoutAnyArguments()
{
$action = new CancelAction();
$action->setGateway($this->createGatewayMock());

$action->execute($request = new Cancel([
'PAYMENTREQUEST_0_PAYMENTACTION' => 'FooBarBaz',
]));

$model = $request->getModel();
$this->assertArrayHasKey('PAYMENTREQUEST_0_PAYMENTACTION', $model);
$this->assertEquals(Api::PAYMENTACTION_VOID, $model['PAYMENTREQUEST_0_PAYMENTACTION']);
new CancelAction();
}

/**
Expand All @@ -66,7 +47,7 @@ public function shouldSupportEmptyModel()
{
$action = new CancelAction();

$request = new Cancel(array());
$request = new Cancel([]);

$this->assertTrue($action->supports($request));
}
Expand Down Expand Up @@ -140,27 +121,26 @@ public function throwIfNotSupportedRequestGivenAsArgumentForExecute()
/**
* @test
*/
public function shouldNotExecuteDoVoidIfPaymentInfoPendingReasonNotSet()
public function shouldNotExecuteDoVoidIfTransactionIdNotSet()
{
$gatewayMock = $this->createGatewayMock();
$gatewayMock
->expects($this->once())
->expects($this->never())
->method('execute')
->with($this->isInstanceOf(Sync::class))
;

$action = new CancelAction();
$action->setGateway($gatewayMock);

$request = new Cancel(array());
$request = new Cancel([]);

$action->execute($request);
}

/**
* @test
*/
public function shouldExecuteDoVoidIfPaymentInfoPendingReasonSet()
public function shouldExecuteDoVoidIfTransactionIdSet()
{
$gatewayMock = $this->createGatewayMock();
$gatewayMock
Expand All @@ -176,145 +156,17 @@ public function shouldExecuteDoVoidIfPaymentInfoPendingReasonSet()
$action->setGateway($gatewayMock);

$request = new Cancel(array(
'PAYMENTINFO_0_PENDINGREASON' => Api::PENDINGREASON_AUTHORIZATION,
));

$action->execute($request);
}

/**
* @test
*/
public function shouldExecuteDoVoidForEachPaymentInfoPendingReasonSetIndexedToNine()
{
$gatewayMock = $this->createGatewayMock();
$gatewayMock
->expects($this->exactly(4))
->method('execute')
->withConsecutive(
array($this->isInstanceOf(DoVoid::class)),
array($this->isInstanceOf(DoVoid::class)),
array($this->isInstanceOf(DoVoid::class)),
array($this->isInstanceOf(Sync::class))
)
;

$action = new CancelAction();
$action->setGateway($gatewayMock);

$request = new Cancel(array(
'PAYMENTINFO_0_PENDINGREASON' => Api::PENDINGREASON_AUTHORIZATION,
'PAYMENTINFO_1_PENDINGREASON' => Api::PENDINGREASON_AUTHORIZATION,
'PAYMENTINFO_9_PENDINGREASON' => Api::PENDINGREASON_AUTHORIZATION,
'TRANSACTIONID' => 'theId',
));

$action->execute($request);
}

/**
* @test
*/
public function shouldNotExecuteDoVoidForPaymentInfoPendingReasonIndexedOverNine()
{
$gatewayMock = $this->createGatewayMock();
$gatewayMock
->expects($this->once())
->method('execute')
->with($this->isInstanceOf(Sync::class))
;

$action = new CancelAction();
$action->setGateway($gatewayMock);

$request = new Cancel(array(
'PAYMENTINFO_10_PENDINGREASON' => Api::PENDINGREASON_AUTHORIZATION,
));

$action->execute($request);
}

/**
* @test
*/
public function shouldNotSetAuthorizationIdFromTransactionIdIfBothNotSet()
{
$gatewayMock = $this->createGatewayMock();
$gatewayMock
->expects($this->at(0))
->method('execute')
->with($this->isInstanceOf(Sync::class))
;

$action = new CancelAction();
$action->setGateway($gatewayMock);

$request = new Cancel(array());

$action->execute($request);

$details = $request->getModel();

$this->assertFalse(isset($details['AUTHORIZATIONID']));
}

/**
* @test
*/
public function shouldSetAuthorizationIdFromTransactionIdIfNotSet()
{
$gatewayMock = $this->createGatewayMock();
$gatewayMock
->expects($this->at(0))
->method('execute')
->with($this->isInstanceOf(Sync::class))
;

$action = new CancelAction();
$action->setGateway($gatewayMock);

$request = new Cancel(array(
'TRANSACTIONID' => 'theOriginalTransactionId',
));

$action->execute($request);

$details = $request->getModel();

$this->assertEquals($details['AUTHORIZATIONID'], 'theOriginalTransactionId');
}

/**
* @test
*/
public function shouldNotOverrideAuthorizationIdWithTransactionIdIfSet()
{
$gatewayMock = $this->createGatewayMock();
$gatewayMock
->expects($this->at(0))
->method('execute')
->with($this->isInstanceOf(Sync::class))
;

$action = new CancelAction();
$action->setGateway($gatewayMock);

$request = new Cancel(array(
'TRANSACTIONID' => 'theReauthorizedTransactionId',
'AUTHORIZATIONID' => 'theOriginalTransactionId',
));

$action->execute($request);

$details = $request->getModel();

$this->assertEquals($details['AUTHORIZATIONID'], 'theOriginalTransactionId');
}

/**
* @return \PHPUnit_Framework_MockObject_MockObject|\Payum\Core\GatewayInterface
*/
protected function createGatewayMock()
{
return $this->getMock('Payum\Core\GatewayInterface');
return $this->getMock(GatewayInterface::class);
}
}

0 comments on commit 9f53df6

Please sign in to comment.