From a69ca09d3a7ff24005eb3865f8ae7ee8eb5e035d Mon Sep 17 00:00:00 2001 From: Ben Cromwell Date: Sat, 10 Oct 2015 12:04:28 +0100 Subject: [PATCH 1/8] add support for PayPal's Instant Update API shipping costs calculator - it requires you to send PayPal a callback URL - if you send a callback URL, you must also specify its timeout and default shipping options - on line 115 where we check for `if (!empty($shippingOptions))` it arguably should throw an InvalidArgumentException or similar - the rest of the library doesn't do this, so I have left it as is to be consistent with the current behaviour --- src/Message/ExpressAuthorizeRequest.php | 98 +++++++++++++++++++ tests/Message/ExpressAuthorizeRequestTest.php | 73 ++++++++++++++ 2 files changed, 171 insertions(+) diff --git a/src/Message/ExpressAuthorizeRequest.php b/src/Message/ExpressAuthorizeRequest.php index e05f3bf..2a3f23a 100644 --- a/src/Message/ExpressAuthorizeRequest.php +++ b/src/Message/ExpressAuthorizeRequest.php @@ -7,6 +7,73 @@ */ class ExpressAuthorizeRequest extends AbstractRequest { + + const DEFAULT_CALLBACK_TIMEOUT = 5; + + public function setCallback($callback) + { + return $this->setParameter('callback', $callback); + } + + public function getCallback() + { + return $this->getParameter('callback'); + } + + public function setCallbackTimeout($callbackTimeout) + { + return $this->setParameter('callbackTimeout', $callbackTimeout); + } + + public function getCallbackTimeout() + { + return $this->getParameter('callbackTimeout'); + } + + /** + * @param int $index + * @param string $name + * @param float $amount + * @param bool $isDefault + * @param string $label + */ + public function setShippingOption($index, $name, $amount, $isDefault, $label = null) + { + $data['L_SHIPPINGOPTIONNAME' . $index] = $name; + $data['L_SHIPPINGOPTIONAMOUNT' . $index] = number_format($amount, 2); + $data['L_SHIPPINGOPTIONISDEFAULT' . $index] = $isDefault ? '1' : '0'; + + if (!is_null($label)) { + $data['L_SHIPPINGOPTIONLABEL' . $index] = $name; + } + + $currentShippingOptions = $this->getParameter('shippingOptions'); + if (empty($currentShippingOptions)) { + $currentShippingOptions = array(); + } + + $currentShippingOptions[$index] = $data; + + $this->setParameter('shippingOptions', $currentShippingOptions); + } + + /** + * Multi-dimensional array of shipping options, containing: + * - index, name, amount, isDefault, label + * index is 0-based as per PayPal's docs. label is optional + * + * @param array $data + */ + public function setShippingOptions($data) + { + $this->setParameter('shippingOptions', $data); + } + + public function getShippingOptions() + { + return $this->getParameter('shippingOptions'); + } + public function getData() { $this->validate('amount', 'returnUrl', 'cancelUrl'); @@ -34,6 +101,37 @@ public function getData() $data['LOCALECODE'] = $this->getLocaleCode(); $data['CUSTOMERSERVICENUMBER'] = $this->getCustomerServiceNumber(); + $callback = $this->getCallback(); + + if (!empty($callback)) { + $data['CALLBACK'] = $callback; + // callback timeout MUST be included and > 0 + $timeout = $this->getCallbackTimeout(); + + $data['CALLBACKTIMEOUT'] = $timeout > 0 ? $timeout : self::DEFAULT_CALLBACK_TIMEOUT; + + // if you're using a callback you MUST set shipping option(s) + $shippingOptions = $this->getShippingOptions(); + + if (!empty($shippingOptions)) { + foreach ($shippingOptions as $shipping) { + $index = $shipping['index']; + $name = $shipping['name']; + $isDefault = $shipping['isDefault']; + $amount = $shipping['amount']; + $label = isset($shipping['label']) ? $shipping['label'] : ''; + + $data['L_SHIPPINGOPTIONNAME' . $index] = $name; + $data['L_SHIPPINGOPTIONAMOUNT' . $index] = number_format($amount, 2); + $data['L_SHIPPINGOPTIONISDEFAULT' . $index] = $isDefault ? '1' : '0'; + + if (!empty($label)) { + $data['L_SHIPPINGOPTIONLABEL' . $index] = $label; + } + } + } + } + $data['MAXAMT'] = $this->getMaxAmount(); $data['PAYMENTREQUEST_0_TAXAMT'] = $this->getTaxAmount(); $data['PAYMENTREQUEST_0_SHIPPINGAMT'] = $this->getShippingAmount(); diff --git a/tests/Message/ExpressAuthorizeRequestTest.php b/tests/Message/ExpressAuthorizeRequestTest.php index 34d5199..68ac22a 100644 --- a/tests/Message/ExpressAuthorizeRequestTest.php +++ b/tests/Message/ExpressAuthorizeRequestTest.php @@ -215,4 +215,77 @@ public function testMaxAmount() $this->assertSame(321.54, $data['MAXAMT']); } + + public function testDataWithCallback() + { + $baseData = array( + 'amount' => '10.00', + 'currency' => 'AUD', + 'transactionId' => '111', + 'description' => 'Order Description', + 'returnUrl' => 'https://www.example.com/return', + 'cancelUrl' => 'https://www.example.com/cancel', + 'subject' => 'demo@example.com', + 'headerImageUrl' => 'https://www.example.com/header.jpg', + 'allowNote' => 0, + 'addressOverride' => 0, + 'brandName' => 'Dunder Mifflin Paper Company, Incy.', + ); + + // with a default callback timeout + $this->request->initialize(array_merge($baseData, array( + 'callback' => 'https://www.example.com/calculate-shipping', + 'shippingOptions' => array( + array( + 'index' => 0, + 'name' => 'First Class', + 'label' => '1-2 days', + 'amount' => 1.20, + 'isDefault' => true, + ), + array( + 'index' => 1, + 'name' => 'Second Class', + 'label' => '3-5 days', + 'amount' => 0.70, + 'isDefault' => false, + ), + array( + 'index' => 2, + 'name' => 'International', + 'amount' => 3.50, + 'isDefault' => false, + ) + ), + ))); + + $data = $this->request->getData(); + $this->assertSame('https://www.example.com/calculate-shipping', $data['CALLBACK']); + $this->assertSame(ExpressAuthorizeRequest::DEFAULT_CALLBACK_TIMEOUT, $data['CALLBACKTIMEOUT']); + + $this->assertSame('First Class', $data['L_SHIPPINGOPTIONNAME0']); + $this->assertSame('1.20', $data['L_SHIPPINGOPTIONAMOUNT0']); + $this->assertSame('1', $data['L_SHIPPINGOPTIONISDEFAULT0']); + $this->assertSame('1-2 days', $data['L_SHIPPINGOPTIONLABEL0']); + + $this->assertSame('Second Class', $data['L_SHIPPINGOPTIONNAME1']); + $this->assertSame('0.70', $data['L_SHIPPINGOPTIONAMOUNT1']); + $this->assertSame('0', $data['L_SHIPPINGOPTIONISDEFAULT1']); + $this->assertSame('3-5 days', $data['L_SHIPPINGOPTIONLABEL1']); + + $this->assertSame('International', $data['L_SHIPPINGOPTIONNAME2']); + $this->assertSame('3.50', $data['L_SHIPPINGOPTIONAMOUNT2']); + $this->assertSame('0', $data['L_SHIPPINGOPTIONISDEFAULT2']); + + // with a defined callback timeout + $this->request->initialize(array_merge($baseData, array( + 'callback' => 'https://www.example.com/calculate-shipping', + 'callbackTimeout' => 10, + ))); + + $data = $this->request->getData(); + $this->assertSame('https://www.example.com/calculate-shipping', $data['CALLBACK']); + $this->assertSame(10, $data['CALLBACKTIMEOUT']); + } + } From 98d19fc6cd4dcdfbc31b8552d8d3dec8e2754245 Mon Sep 17 00:00:00 2001 From: Ben Cromwell Date: Sat, 10 Oct 2015 12:05:59 +0100 Subject: [PATCH 2/8] add support for PayPal's Instant Update API shipping costs calculator - use the array index for the shipping index instead of having to define it manually --- src/Message/ExpressAuthorizeRequest.php | 3 +-- tests/Message/ExpressAuthorizeRequestTest.php | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Message/ExpressAuthorizeRequest.php b/src/Message/ExpressAuthorizeRequest.php index 2a3f23a..e057af6 100644 --- a/src/Message/ExpressAuthorizeRequest.php +++ b/src/Message/ExpressAuthorizeRequest.php @@ -114,8 +114,7 @@ public function getData() $shippingOptions = $this->getShippingOptions(); if (!empty($shippingOptions)) { - foreach ($shippingOptions as $shipping) { - $index = $shipping['index']; + foreach ($shippingOptions as $index => $shipping) { $name = $shipping['name']; $isDefault = $shipping['isDefault']; $amount = $shipping['amount']; diff --git a/tests/Message/ExpressAuthorizeRequestTest.php b/tests/Message/ExpressAuthorizeRequestTest.php index 68ac22a..7dfb7ed 100644 --- a/tests/Message/ExpressAuthorizeRequestTest.php +++ b/tests/Message/ExpressAuthorizeRequestTest.php @@ -237,21 +237,18 @@ public function testDataWithCallback() 'callback' => 'https://www.example.com/calculate-shipping', 'shippingOptions' => array( array( - 'index' => 0, 'name' => 'First Class', 'label' => '1-2 days', 'amount' => 1.20, 'isDefault' => true, ), array( - 'index' => 1, 'name' => 'Second Class', 'label' => '3-5 days', 'amount' => 0.70, 'isDefault' => false, ), array( - 'index' => 2, 'name' => 'International', 'amount' => 3.50, 'isDefault' => false, From 91a6ca92e5542667925610b94870db7ce51abdaa Mon Sep 17 00:00:00 2001 From: Ben Cromwell Date: Sat, 10 Oct 2015 12:08:53 +0100 Subject: [PATCH 3/8] add support for PayPal's Instant Update API shipping costs calculator - remove defunct method accidentally left in the codebase (superseded underneath by `setShippingOptions`) --- src/Message/ExpressAuthorizeRequest.php | 27 ------------------------- 1 file changed, 27 deletions(-) diff --git a/src/Message/ExpressAuthorizeRequest.php b/src/Message/ExpressAuthorizeRequest.php index e057af6..1830efa 100644 --- a/src/Message/ExpressAuthorizeRequest.php +++ b/src/Message/ExpressAuthorizeRequest.php @@ -30,33 +30,6 @@ public function getCallbackTimeout() return $this->getParameter('callbackTimeout'); } - /** - * @param int $index - * @param string $name - * @param float $amount - * @param bool $isDefault - * @param string $label - */ - public function setShippingOption($index, $name, $amount, $isDefault, $label = null) - { - $data['L_SHIPPINGOPTIONNAME' . $index] = $name; - $data['L_SHIPPINGOPTIONAMOUNT' . $index] = number_format($amount, 2); - $data['L_SHIPPINGOPTIONISDEFAULT' . $index] = $isDefault ? '1' : '0'; - - if (!is_null($label)) { - $data['L_SHIPPINGOPTIONLABEL' . $index] = $name; - } - - $currentShippingOptions = $this->getParameter('shippingOptions'); - if (empty($currentShippingOptions)) { - $currentShippingOptions = array(); - } - - $currentShippingOptions[$index] = $data; - - $this->setParameter('shippingOptions', $currentShippingOptions); - } - /** * Multi-dimensional array of shipping options, containing: * - index, name, amount, isDefault, label From 2dbfb742d8c57345e6e7407c5bb75f39a470b6a0 Mon Sep 17 00:00:00 2001 From: Ben Cromwell Date: Sat, 10 Oct 2015 12:10:03 +0100 Subject: [PATCH 4/8] add support for PayPal's Instant Update API shipping costs calculator - update doc-comment to reflect prior changes --- src/Message/ExpressAuthorizeRequest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Message/ExpressAuthorizeRequest.php b/src/Message/ExpressAuthorizeRequest.php index 1830efa..9483708 100644 --- a/src/Message/ExpressAuthorizeRequest.php +++ b/src/Message/ExpressAuthorizeRequest.php @@ -32,8 +32,7 @@ public function getCallbackTimeout() /** * Multi-dimensional array of shipping options, containing: - * - index, name, amount, isDefault, label - * index is 0-based as per PayPal's docs. label is optional + * name, amount, isDefault, and an optional label * * @param array $data */ From 24d3d87af23f979e23fd27a7ae335263b68978cd Mon Sep 17 00:00:00 2001 From: Ben Cromwell Date: Sat, 10 Oct 2015 12:12:12 +0100 Subject: [PATCH 5/8] adjust use of whitespace to match the rest of the project --- src/Message/ExpressAuthorizeRequest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Message/ExpressAuthorizeRequest.php b/src/Message/ExpressAuthorizeRequest.php index 9483708..8e93a3f 100644 --- a/src/Message/ExpressAuthorizeRequest.php +++ b/src/Message/ExpressAuthorizeRequest.php @@ -76,7 +76,7 @@ public function getData() $callback = $this->getCallback(); if (!empty($callback)) { - $data['CALLBACK'] = $callback; + $data['CALLBACK'] = $callback; // callback timeout MUST be included and > 0 $timeout = $this->getCallbackTimeout(); @@ -87,13 +87,13 @@ public function getData() if (!empty($shippingOptions)) { foreach ($shippingOptions as $index => $shipping) { - $name = $shipping['name']; + $name = $shipping['name']; $isDefault = $shipping['isDefault']; - $amount = $shipping['amount']; - $label = isset($shipping['label']) ? $shipping['label'] : ''; + $amount = $shipping['amount']; + $label = isset($shipping['label']) ? $shipping['label'] : ''; - $data['L_SHIPPINGOPTIONNAME' . $index] = $name; - $data['L_SHIPPINGOPTIONAMOUNT' . $index] = number_format($amount, 2); + $data['L_SHIPPINGOPTIONNAME' . $index] = $name; + $data['L_SHIPPINGOPTIONAMOUNT' . $index] = number_format($amount, 2); $data['L_SHIPPINGOPTIONISDEFAULT' . $index] = $isDefault ? '1' : '0'; if (!empty($label)) { From fb140b228bd13ffb07e5a6050b551584ec934b91 Mon Sep 17 00:00:00 2001 From: Ben Cromwell Date: Tue, 13 Oct 2015 18:00:44 +0100 Subject: [PATCH 6/8] add validation for the callback/shipping configuration - also added some test coverage for the existing validate - toyed with overriding `validate()` instead of adding `validateCallback()` but doing so prevents `func_get_args` from returning anything --- src/Message/ExpressAuthorizeRequest.php | 18 ++++ tests/Message/ExpressAuthorizeRequestTest.php | 100 ++++++++++++++---- 2 files changed, 99 insertions(+), 19 deletions(-) diff --git a/src/Message/ExpressAuthorizeRequest.php b/src/Message/ExpressAuthorizeRequest.php index 8e93a3f..4e19c7b 100644 --- a/src/Message/ExpressAuthorizeRequest.php +++ b/src/Message/ExpressAuthorizeRequest.php @@ -2,6 +2,8 @@ namespace Omnipay\PayPal\Message; +use Omnipay\Common\Exception\InvalidRequestException; + /** * PayPal Express Authorize Request */ @@ -46,9 +48,25 @@ public function getShippingOptions() return $this->getParameter('shippingOptions'); } + protected function validateCallback() + { + $callback = $this->getCallback(); + + if (!empty($callback)) { + $shippingOptions = $this->getShippingOptions(); + + if (empty($shippingOptions)) { + throw new InvalidRequestException( + 'When setting a callback for the Instant Update API you must set shipping options' + ); + } + } + } + public function getData() { $this->validate('amount', 'returnUrl', 'cancelUrl'); + $this->validateCallback(); $data = $this->getBaseData(); $data['METHOD'] = 'SetExpressCheckout'; diff --git a/tests/Message/ExpressAuthorizeRequestTest.php b/tests/Message/ExpressAuthorizeRequestTest.php index 7dfb7ed..a4166c7 100644 --- a/tests/Message/ExpressAuthorizeRequestTest.php +++ b/tests/Message/ExpressAuthorizeRequestTest.php @@ -232,28 +232,30 @@ public function testDataWithCallback() 'brandName' => 'Dunder Mifflin Paper Company, Incy.', ); + $shippingOptions = array( + array( + 'name' => 'First Class', + 'label' => '1-2 days', + 'amount' => 1.20, + 'isDefault' => true, + ), + array( + 'name' => 'Second Class', + 'label' => '3-5 days', + 'amount' => 0.70, + 'isDefault' => false, + ), + array( + 'name' => 'International', + 'amount' => 3.50, + 'isDefault' => false, + ) + ); + // with a default callback timeout $this->request->initialize(array_merge($baseData, array( 'callback' => 'https://www.example.com/calculate-shipping', - 'shippingOptions' => array( - array( - 'name' => 'First Class', - 'label' => '1-2 days', - 'amount' => 1.20, - 'isDefault' => true, - ), - array( - 'name' => 'Second Class', - 'label' => '3-5 days', - 'amount' => 0.70, - 'isDefault' => false, - ), - array( - 'name' => 'International', - 'amount' => 3.50, - 'isDefault' => false, - ) - ), + 'shippingOptions' => $shippingOptions, ))); $data = $this->request->getData(); @@ -278,6 +280,7 @@ public function testDataWithCallback() $this->request->initialize(array_merge($baseData, array( 'callback' => 'https://www.example.com/calculate-shipping', 'callbackTimeout' => 10, + 'shippingOptions' => $shippingOptions, ))); $data = $this->request->getData(); @@ -285,4 +288,63 @@ public function testDataWithCallback() $this->assertSame(10, $data['CALLBACKTIMEOUT']); } + public function testNoAmount() + { + $baseData = array(// nothing here - should cause a certain exception + ); + + $this->request->initialize($baseData); + + $this->setExpectedException( + '\Omnipay\Common\Exception\InvalidRequestException', + 'The amount parameter is required' + ); + + $this->request->getData(); + } + + public function testAmountButNoReturnUrl() + { + $baseData = array( + 'amount' => 10.00, + ); + + $this->request->initialize($baseData); + + $this->setExpectedException( + '\Omnipay\Common\Exception\InvalidRequestException', + 'The returnUrl parameter is required' + ); + + $this->request->getData(); + } + + public function testBadCallbackConfiguration() + { + $baseData = array( + 'amount' => '10.00', + 'currency' => 'AUD', + 'transactionId' => '111', + 'description' => 'Order Description', + 'returnUrl' => 'https://www.example.com/return', + 'cancelUrl' => 'https://www.example.com/cancel', + 'subject' => 'demo@example.com', + 'headerImageUrl' => 'https://www.example.com/header.jpg', + 'allowNote' => 0, + 'addressOverride' => 0, + 'brandName' => 'Dunder Mifflin Paper Company, Incy.', + ); + + $this->request->initialize(array_merge($baseData, array( + 'callback' => 'https://www.example.com/calculate-shipping', + ))); + + // from the docblock on this exception - + // Thrown when a request is invalid or missing required fields. + // callback has been set but no shipping options so expect one of these: + $this->setExpectedException('\Omnipay\Common\Exception\InvalidRequestException'); + + $this->request->getData(); + } + } From 67035b1c8fa47a06c95c9738427b9195dcaae163 Mon Sep 17 00:00:00 2001 From: Ben Cromwell Date: Thu, 12 Nov 2015 20:17:24 +0000 Subject: [PATCH 7/8] encapsulate shipping options within a wrapper class to make the parameters self-documenting/validating --- src/Message/ExpressAuthorizeRequest.php | 38 ++++++---- .../InstantUpdateApi/ShippingOption.php | 72 +++++++++++++++++++ tests/Message/ExpressAuthorizeRequestTest.php | 21 ++---- 3 files changed, 100 insertions(+), 31 deletions(-) create mode 100644 src/Support/InstantUpdateApi/ShippingOption.php diff --git a/src/Message/ExpressAuthorizeRequest.php b/src/Message/ExpressAuthorizeRequest.php index 4e19c7b..fd08b88 100644 --- a/src/Message/ExpressAuthorizeRequest.php +++ b/src/Message/ExpressAuthorizeRequest.php @@ -3,6 +3,7 @@ namespace Omnipay\PayPal\Message; use Omnipay\Common\Exception\InvalidRequestException; +use Omnipay\PayPal\Support\InstantUpdateApi\ShippingOption; /** * PayPal Express Authorize Request @@ -33,16 +34,16 @@ public function getCallbackTimeout() } /** - * Multi-dimensional array of shipping options, containing: - * name, amount, isDefault, and an optional label - * - * @param array $data + * @param ShippingOption[] $data */ public function setShippingOptions($data) { $this->setParameter('shippingOptions', $data); } + /** + * @return ShippingOption[] + */ public function getShippingOptions() { return $this->getParameter('shippingOptions'); @@ -59,6 +60,20 @@ protected function validateCallback() throw new InvalidRequestException( 'When setting a callback for the Instant Update API you must set shipping options' ); + } else { + $hasDefault = false; + foreach ($shippingOptions as $shippingOption) { + if ($shippingOption->isDefault()) { + $hasDefault = true; + continue; + } + } + + if (!$hasDefault) { + throw new InvalidRequestException( + 'One of the supplied shipping options must be set as default' + ); + } } } } @@ -105,17 +120,12 @@ public function getData() if (!empty($shippingOptions)) { foreach ($shippingOptions as $index => $shipping) { - $name = $shipping['name']; - $isDefault = $shipping['isDefault']; - $amount = $shipping['amount']; - $label = isset($shipping['label']) ? $shipping['label'] : ''; - - $data['L_SHIPPINGOPTIONNAME' . $index] = $name; - $data['L_SHIPPINGOPTIONAMOUNT' . $index] = number_format($amount, 2); - $data['L_SHIPPINGOPTIONISDEFAULT' . $index] = $isDefault ? '1' : '0'; + $data['L_SHIPPINGOPTIONNAME' . $index] = $shipping->getName(); + $data['L_SHIPPINGOPTIONAMOUNT' . $index] = number_format($shipping->getAmount(), 2); + $data['L_SHIPPINGOPTIONISDEFAULT' . $index] = $shipping->isDefault() ? '1' : '0'; - if (!empty($label)) { - $data['L_SHIPPINGOPTIONLABEL' . $index] = $label; + if ($shipping->hasLabel()) { + $data['L_SHIPPINGOPTIONLABEL' . $index] = $shipping->getLabel(); } } } diff --git a/src/Support/InstantUpdateApi/ShippingOption.php b/src/Support/InstantUpdateApi/ShippingOption.php new file mode 100644 index 0000000..aba549d --- /dev/null +++ b/src/Support/InstantUpdateApi/ShippingOption.php @@ -0,0 +1,72 @@ +name = $name; + $this->amount = $amount; + $this->isDefault = $isDefault; + $this->label = $label; + } + + /** + * @return bool + */ + public function hasLabel() + { + return !is_null($this->label); + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @return float + */ + public function getAmount() + { + return $this->amount; + } + + /** + * @return boolean + */ + public function isDefault() + { + return $this->isDefault; + } + + /** + * @return string + */ + public function getLabel() + { + return $this->label; + } +} diff --git a/tests/Message/ExpressAuthorizeRequestTest.php b/tests/Message/ExpressAuthorizeRequestTest.php index a4166c7..00a478c 100644 --- a/tests/Message/ExpressAuthorizeRequestTest.php +++ b/tests/Message/ExpressAuthorizeRequestTest.php @@ -3,6 +3,7 @@ namespace Omnipay\PayPal\Message; use Omnipay\Common\CreditCard; +use Omnipay\PayPal\Support\InstantUpdateApi\ShippingOption; use Omnipay\Tests\TestCase; class ExpressAuthorizeRequestTest extends TestCase @@ -233,23 +234,9 @@ public function testDataWithCallback() ); $shippingOptions = array( - array( - 'name' => 'First Class', - 'label' => '1-2 days', - 'amount' => 1.20, - 'isDefault' => true, - ), - array( - 'name' => 'Second Class', - 'label' => '3-5 days', - 'amount' => 0.70, - 'isDefault' => false, - ), - array( - 'name' => 'International', - 'amount' => 3.50, - 'isDefault' => false, - ) + new ShippingOption('First Class', 1.20, true, '1-2 days'), + new ShippingOption('Second Class', 0.70, false, '3-5 days'), + new ShippingOption('International', 3.50), ); // with a default callback timeout From 7e2e44070a0004c3833c97f39aa481db87028b21 Mon Sep 17 00:00:00 2001 From: Ben Cromwell Date: Thu, 12 Nov 2015 20:23:24 +0000 Subject: [PATCH 8/8] add a test to cover shipping option validation where there is no default shipping option supplied --- tests/Message/ExpressAuthorizeRequestTest.php | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/Message/ExpressAuthorizeRequestTest.php b/tests/Message/ExpressAuthorizeRequestTest.php index 00a478c..999a960 100644 --- a/tests/Message/ExpressAuthorizeRequestTest.php +++ b/tests/Message/ExpressAuthorizeRequestTest.php @@ -275,6 +275,42 @@ public function testDataWithCallback() $this->assertSame(10, $data['CALLBACKTIMEOUT']); } + public function testDataWithCallbackAndNoDefaultShippingOption() + { + $baseData = array( + 'amount' => '10.00', + 'currency' => 'AUD', + 'transactionId' => '111', + 'description' => 'Order Description', + 'returnUrl' => 'https://www.example.com/return', + 'cancelUrl' => 'https://www.example.com/cancel', + 'subject' => 'demo@example.com', + 'headerImageUrl' => 'https://www.example.com/header.jpg', + 'allowNote' => 0, + 'addressOverride' => 0, + 'brandName' => 'Dunder Mifflin Paper Company, Incy.', + ); + + $shippingOptions = array( + new ShippingOption('First Class', 1.20, false, '1-2 days'), + new ShippingOption('Second Class', 0.70, false, '3-5 days'), + new ShippingOption('International', 3.50), + ); + + // with a default callback timeout + $this->request->initialize(array_merge($baseData, array( + 'callback' => 'https://www.example.com/calculate-shipping', + 'shippingOptions' => $shippingOptions, + ))); + + $this->setExpectedException( + '\Omnipay\Common\Exception\InvalidRequestException', + 'One of the supplied shipping options must be set as default' + ); + + $this->request->getData(); + } + public function testNoAmount() { $baseData = array(// nothing here - should cause a certain exception