357 lines
12 KiB
PHP
357 lines
12 KiB
PHP
<?php
|
|
|
|
namespace Omnipay\SagePay\Message;
|
|
|
|
use Omnipay\Tests\TestCase;
|
|
|
|
class DirectAuthorizeRequestTest extends TestCase
|
|
{
|
|
/**
|
|
* @var \Omnipay\Common\Message\AbstractRequest $request
|
|
*/
|
|
protected $request;
|
|
|
|
public function setUp()
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->request = new DirectAuthorizeRequest($this->getHttpClient(), $this->getHttpRequest());
|
|
$this->request->initialize(
|
|
array(
|
|
'amount' => '12.00',
|
|
'currency' => 'GBP',
|
|
'transactionId' => '123',
|
|
'card' => $this->getValidCard(),
|
|
)
|
|
);
|
|
}
|
|
|
|
public function testGetDataDefaults()
|
|
{
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertSame('E', $data['AccountType']);
|
|
$this->assertSame(0, $data['ApplyAVSCV2']);
|
|
$this->assertSame(0, $data['Apply3DSecure']);
|
|
$this->assertSame(0, $data['CreateToken']);
|
|
}
|
|
|
|
public function testGetData()
|
|
{
|
|
$this->request->setAccountType('M');
|
|
$this->request->setApplyAVSCV2(2);
|
|
$this->request->setApply3DSecure(3);
|
|
$this->request->setDescription('food');
|
|
$this->request->setClientIp('127.0.0.1');
|
|
$this->request->setReferrerId('3F7A4119-8671-464F-A091-9E59EB47B80C');
|
|
$this->request->setVendorData('Vendor secret codes');
|
|
$this->request->setCardholderName('Mr E User');
|
|
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertSame('M', $data['AccountType']);
|
|
$this->assertSame('food', $data['Description']);
|
|
$this->assertSame('12.00', $data['Amount']);
|
|
$this->assertSame('GBP', $data['Currency']);
|
|
$this->assertSame('123', $data['VendorTxCode']);
|
|
$this->assertSame('127.0.0.1', $data['ClientIPAddress']);
|
|
$this->assertSame(2, $data['ApplyAVSCV2']);
|
|
$this->assertSame(3, $data['Apply3DSecure']);
|
|
$this->assertSame('3F7A4119-8671-464F-A091-9E59EB47B80C', $data['ReferrerID']);
|
|
$this->assertSame('Vendor secret codes', $data['VendorData']);
|
|
$this->assertSame('Mr E User', $data['CardHolder']);
|
|
}
|
|
|
|
public function testNoBasket()
|
|
{
|
|
// First with no basket set at all.
|
|
$data = $this->request->getData();
|
|
$this->assertArrayNotHasKey('BasketXML', $data);
|
|
|
|
// Then with a basket containing no items.
|
|
$items = new \Omnipay\Common\ItemBag(array());
|
|
$this->request->setItems($items);
|
|
$data = $this->request->getData();
|
|
$this->assertArrayNotHasKey('BasketXML', $data);
|
|
}
|
|
|
|
public function testBasket()
|
|
{
|
|
$items = new \Omnipay\Common\ItemBag(array(
|
|
new \Omnipay\Common\Item(array(
|
|
'name' => 'Name',
|
|
'description' => 'Description',
|
|
'quantity' => 1,
|
|
'price' => 1.23,
|
|
))
|
|
));
|
|
|
|
$basketXml = '<basket><item>'
|
|
. '<description>Name</description><quantity>1</quantity>'
|
|
. '<unitNetAmount>1.23</unitNetAmount><unitTaxAmount>0.00</unitTaxAmount>'
|
|
. '<unitGrossAmount>1.23</unitGrossAmount><totalGrossAmount>1.23</totalGrossAmount>'
|
|
. '</item></basket>';
|
|
|
|
$this->request->setItems($items);
|
|
|
|
$data = $this->request->getData();
|
|
|
|
// The element does exist, and must contain the basket XML, with optional XML header and
|
|
// trailing newlines.
|
|
$this->assertArrayHasKey('BasketXML', $data);
|
|
$this->assertContains($basketXml, $data['BasketXML']);
|
|
}
|
|
|
|
public function testGetDataNoReferrerId()
|
|
{
|
|
// Default value is equivalent to this:
|
|
$this->request->setReferrerId('');
|
|
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertArrayNotHasKey('ReferrerID', $data);
|
|
}
|
|
|
|
public function testFilterClientIp()
|
|
{
|
|
// Valid IPv4 (no filter)
|
|
$this->request->setClientIp('1.2.3.4');
|
|
$this->assertSame($this->request->getClientIp(), '1.2.3.4');
|
|
|
|
// Invalid IPv4 (filtered)
|
|
$this->request->setClientIp('a.b.c.d');
|
|
$this->assertNull($this->request->getClientIp());
|
|
|
|
// Valid IPv6 (filtered)
|
|
$this->request->setClientIp('2001:0db8:85a3:0000:0000:8a2e:0370:7334');
|
|
$this->assertNull($this->request->getClientIp());
|
|
}
|
|
|
|
public function testGetDataCustomerDetails()
|
|
{
|
|
$card = $this->request->getCard();
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertSame($card->getFirstName(), $data['BillingFirstnames']);
|
|
$this->assertSame($card->getLastName(), $data['BillingSurname']);
|
|
$this->assertSame($card->getBillingAddress1(), $data['BillingAddress1']);
|
|
$this->assertSame($card->getBillingAddress2(), $data['BillingAddress2']);
|
|
$this->assertSame($card->getBillingCity(), $data['BillingCity']);
|
|
$this->assertSame($card->getBillingPostcode(), $data['BillingPostCode']);
|
|
$this->assertSame($card->getBillingState(), $data['BillingState']);
|
|
$this->assertSame($card->getBillingCountry(), $data['BillingCountry']);
|
|
$this->assertSame($card->getBillingPhone(), $data['BillingPhone']);
|
|
|
|
$this->assertSame($card->getFirstName(), $data['DeliveryFirstnames']);
|
|
$this->assertSame($card->getLastName(), $data['DeliverySurname']);
|
|
$this->assertSame($card->getShippingAddress1(), $data['DeliveryAddress1']);
|
|
$this->assertSame($card->getShippingAddress2(), $data['DeliveryAddress2']);
|
|
$this->assertSame($card->getShippingCity(), $data['DeliveryCity']);
|
|
$this->assertSame($card->getShippingPostcode(), $data['DeliveryPostCode']);
|
|
$this->assertSame($card->getShippingState(), $data['DeliveryState']);
|
|
$this->assertSame($card->getShippingCountry(), $data['DeliveryCountry']);
|
|
$this->assertSame($card->getShippingPhone(), $data['DeliveryPhone']);
|
|
}
|
|
|
|
public function testGetDataCustomerDetailsIgnoresStateOutsideUS()
|
|
{
|
|
$card = $this->request->getCard();
|
|
$card->setBillingCountry('UK');
|
|
$card->setShippingCountry('NZ');
|
|
|
|
$data = $this->request->getData();
|
|
|
|
// these must be empty string, not null
|
|
// (otherwise Guzzle ignores them, and SagePay throws a fit)
|
|
$this->assertSame('', $data['BillingState']);
|
|
$this->assertSame('', $data['DeliveryState']);
|
|
}
|
|
|
|
public function testGetDataVisa()
|
|
{
|
|
$this->request->getCard()->setNumber('4929000000006');
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertSame('visa', $data['CardType']);
|
|
}
|
|
|
|
public function testGetDataMastercard()
|
|
{
|
|
$this->request->getCard()->setNumber('5404000000000001');
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertSame('mc', $data['CardType']);
|
|
}
|
|
|
|
public function testGetDataDinersClub()
|
|
{
|
|
$this->request->getCard()->setNumber('30569309025904');
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertSame('dc', $data['CardType']);
|
|
}
|
|
|
|
public function testGetDataNullBillingAddress2()
|
|
{
|
|
$card = $this->request->getCard();
|
|
|
|
// This emulates not setting the billing address 2 at all
|
|
// (it defaults to null).
|
|
$card->setBillingAddress2(null);
|
|
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertNull($data['BillingAddress2']);
|
|
|
|
// This tests that the BillingAddress2 may be left unset,
|
|
// which defaults to null. When it is sent to SagePay, it gets
|
|
// converted to an empty string. I'm not clear how that would be
|
|
// tested.
|
|
}
|
|
|
|
public function testBasketWithNoDiscount()
|
|
{
|
|
$items = new \Omnipay\Common\ItemBag(array(
|
|
new \Omnipay\Common\Item(array(
|
|
'name' => 'Name',
|
|
'description' => 'Description',
|
|
'quantity' => 1,
|
|
'price' => 1.23,
|
|
))
|
|
));
|
|
|
|
$this->request->setItems($items);
|
|
$data = $this->request->getData();
|
|
// The element does exist, and must contain the basket XML, with optional XML header and
|
|
// trailing newlines.
|
|
$this->assertArrayHasKey('BasketXML', $data);
|
|
$this->assertNotContains('<discount>', $data['BasketXML']);
|
|
}
|
|
|
|
public function testMixedBasketWithSpecialChars()
|
|
{
|
|
$items = new \Omnipay\Common\ItemBag(array(
|
|
new \Omnipay\Common\Item(array(
|
|
'name' => "Denisé's Odd & Wierd £name? #12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
|
'description' => 'Description',
|
|
'quantity' => 2,
|
|
'price' => 4.23,
|
|
)),
|
|
array(
|
|
'name' => "Denisé's \"Odd\" & Wierd £discount? #",
|
|
'description' => 'My Offer',
|
|
'quantity' => 2,
|
|
'price' => -0.10,
|
|
),
|
|
array(
|
|
// 101 character name
|
|
'name' => '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901',
|
|
'description' => 'My 2nd Offer',
|
|
'quantity' => 1,
|
|
'price' => -1.60,
|
|
)
|
|
));
|
|
|
|
// Names/descriptions should be max 100 characters in length, once invalid characters have been removed.
|
|
$expected = '<basket><item>'
|
|
. '<description>Denis\'s Odd & Wierd name 123456789012345678901234567890123456789012345678901234567890123456789012345</description><quantity>2</quantity>'
|
|
. '<unitNetAmount>4.23</unitNetAmount><unitTaxAmount>0.00</unitTaxAmount>'
|
|
. '<unitGrossAmount>4.23</unitGrossAmount><totalGrossAmount>8.46</totalGrossAmount>'
|
|
. '</item><discounts>'
|
|
. '<discount><fixed>0.2</fixed><description>Denis\'s "Odd" Wierd discount? #</description></discount>'
|
|
. '<discount><fixed>1.6</fixed><description>1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890</description></discount>'
|
|
. '</discounts></basket>';
|
|
|
|
$this->request->setItems($items);
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertArrayHasKey('BasketXML', $data);
|
|
$this->assertContains($expected, $data['BasketXML'], 'Basket XML does not match the expected output');
|
|
}
|
|
|
|
public function testCreateTokenCanBeSetInRequest()
|
|
{
|
|
$this->request->setCreateToken(true);
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertSame(1, $data['CreateToken']);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider tokenSetterProvider
|
|
*/
|
|
public function testCreateTokenCanOnlyBeOneOrZeroInRequest($parameter, $expectation)
|
|
{
|
|
$this->request->setCreateToken($parameter);
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertSame($expectation, $data['CreateToken']);
|
|
}
|
|
|
|
public function testExistingTokenCanBeSet()
|
|
{
|
|
$token = '{ABCDEF}';
|
|
$this->request->setToken($token);
|
|
|
|
$data = $this->request->getData();
|
|
$this->assertSame($token, $data['Token']);
|
|
}
|
|
|
|
public function testExistingTokenCannotBeSetIfCreateTokenIsTrue()
|
|
{
|
|
$this->request->setCreateToken(true);
|
|
$this->request->setToken('{ABCDEF}');
|
|
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertArrayNotHasKey('Token', $data);
|
|
$this->assertSame(1, $data['CreateToken']);
|
|
}
|
|
|
|
public function testStoreTokenCanOnlyBeSetIfExistingTokenIsSetInRequest()
|
|
{
|
|
$this->request->setToken('{ABCDEF}');
|
|
$this->request->setStoreToken(true);
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertSame(1, $data['StoreToken']);
|
|
}
|
|
|
|
public function testStoreTokenIsUnsetIfThereIsNoExistingTokenSetInRequest()
|
|
{
|
|
$this->request->setStoreToken(true);
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertArrayNotHasKey('StoreToken', $data);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider tokenSetterProvider
|
|
*/
|
|
public function testStoreTokenCanOnlyBeOneOrZeroIfSetInRequest($parameter, $expectation)
|
|
{
|
|
$this->request->setToken('{ABCDEF}');
|
|
$this->request->setStoreToken($parameter);
|
|
$data = $this->request->getData();
|
|
|
|
$this->assertSame($expectation, $data['StoreToken']);
|
|
}
|
|
|
|
public function tokenSetterProvider()
|
|
{
|
|
return array(
|
|
array(1, 1),
|
|
array('1', 1),
|
|
array(true, 1),
|
|
array('some string', 1),
|
|
array(array('something'), 1),
|
|
array(0, 0),
|
|
array('0', 0),
|
|
array(false, 0),
|
|
array('', 0),
|
|
array(null, 0),
|
|
array(array(), 0)
|
|
);
|
|
}
|
|
}
|