1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Copyright (c) 2013-2014 eBay Enterprise, Inc. |
4
|
|
|
* |
5
|
|
|
* NOTICE OF LICENSE |
6
|
|
|
* |
7
|
|
|
* This source file is subject to the Open Software License (OSL 3.0) |
8
|
|
|
* that is bundled with this package in the file LICENSE.md. |
9
|
|
|
* It is also available through the world-wide-web at this URL: |
10
|
|
|
* http://opensource.org/licenses/osl-3.0.php |
11
|
|
|
* |
12
|
|
|
* @copyright Copyright (c) 2013-2014 eBay Enterprise, Inc. (http://www.ebayenterprise.com/) |
13
|
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
14
|
|
|
*/ |
15
|
|
|
|
16
|
|
|
use eBayEnterprise\RetailOrderManagement\Api; |
17
|
|
|
use eBayEnterprise\RetailOrderManagement\Payload; |
18
|
|
|
use eBayEnterprise\RetailOrderManagement\Payload\PayloadMap; |
19
|
|
|
use eBayEnterprise\RetailOrderManagement\Payload\ValidatorIterator; |
20
|
|
|
use Psr\Log\NullLogger; |
21
|
|
|
|
22
|
|
|
class EbayEnterprise_PayPal_Test_Model_Express_ApiTest extends EbayEnterprise_Eb2cCore_Test_Base |
23
|
|
|
{ |
24
|
|
|
const BIDIRECTIONAL_API = '\eBayEnterprise\RetailOrderManagement\Api\IBidirectionalApi'; |
25
|
|
|
const SETEXPRESS_REQUEST_PAYLOAD = |
26
|
|
|
'\eBayEnterprise\RetailOrderManagement\Payload\Payment\IPayPalSetExpressCheckoutRequest'; |
27
|
|
|
const SETEXPRESS_REPLY_PAYLOAD = |
28
|
|
|
'\eBayEnterprise\RetailOrderManagement\Payload\Payment\IPayPalSetExpressCheckoutReply'; |
29
|
|
|
const GETEXPRESS_REQUEST_PAYLOAD = |
30
|
|
|
'\eBayEnterprise\RetailOrderManagement\Payload\Payment\IPayPalGetExpressCheckoutRequest'; |
31
|
|
|
const GETEXPRESS_REPLY_PAYLOAD = |
32
|
|
|
'\eBayEnterprise\RetailOrderManagement\Payload\Payment\IPayPalGetExpressCheckoutReply'; |
33
|
|
|
const DOEXPRESS_REQUEST_PAYLOAD = |
34
|
|
|
'\eBayEnterprise\RetailOrderManagement\Payload\Payment\IPayPalDoExpressCheckoutRequest'; |
35
|
|
|
const DOEXPRESS_REPLY_PAYLOAD = |
36
|
|
|
'\eBayEnterprise\RetailOrderManagement\Payload\Payment\IPayPalDoExpressCheckoutReply'; |
37
|
|
|
const DOAUTH_REQUEST_PAYLOAD = |
38
|
|
|
'\eBayEnterprise\RetailOrderManagement\Payload\Payment\IPayPalDoAuthorizationRequest'; |
39
|
|
|
const DOAUTH_REPLY_PAYLOAD = '\eBayEnterprise\RetailOrderManagement\Payload\Payment\IPayPalDoAuthorizationReply'; |
40
|
|
|
const DOVOID_REQUEST_PAYLOAD = '\eBayEnterprise\RetailOrderManagement\Payload\Payment\IPayPalDoVoidRequest'; |
41
|
|
|
const DOVOID_REPLY_PAYLOAD = '\eBayEnterprise\RetailOrderManagement\Payload\Payment\IPayPalDoVoidReply'; |
42
|
|
|
const LINE_ITEM_ITERABLE = '\eBayEnterprise\RetailOrderManagement\Payload\Payment\LineItemIterable'; |
43
|
|
|
const LINE_ITEM = '\eBayEnterprise\RetailOrderManagement\Payload\Payment\ILineItem'; |
44
|
|
|
|
45
|
|
|
protected $sdk; |
46
|
|
|
protected $coreHelper; |
47
|
|
|
protected $helper; |
48
|
|
|
protected $checkoutSession; |
49
|
|
|
protected $getSdkApiMap; |
50
|
|
|
protected $cancelUrl = 'cancel url'; |
51
|
|
|
protected $returnUrl = 'return url'; |
52
|
|
|
protected $token = 'token'; |
53
|
|
|
protected $orderId = 'order id'; |
54
|
|
|
protected $currencyCode = 'USD'; |
55
|
|
|
protected $lineItemStub; |
56
|
|
|
protected $lineItemIterableStub; |
57
|
|
|
protected $payerId = 'payer id'; |
58
|
|
|
protected $pickUpStoreId = 'pick up stroe id'; |
59
|
|
|
|
60
|
|
|
public function setUp() |
61
|
|
|
{ |
62
|
|
|
parent::setUp(); |
63
|
|
|
|
64
|
|
|
// suppressing the real session from starting |
65
|
|
|
$session = $this->getModelMockBuilder('core/session') |
66
|
|
|
->disableOriginalConstructor() |
67
|
|
|
->setMethods(null) |
68
|
|
|
->getMock(); |
69
|
|
|
$this->replaceByMock('singleton', 'core/session', $session); |
70
|
|
|
|
71
|
|
|
// disable _construct to prevent excessive stubs |
72
|
|
|
$this->coreUrl = $this->getModelMock( |
|
|
|
|
73
|
|
|
'core/url', |
74
|
|
|
['_construct', 'getUrl'] |
75
|
|
|
); |
76
|
|
|
$this->coreUrl->expects($this->any()) |
77
|
|
|
->method('getUrl')->will( |
78
|
|
|
$this->returnValueMap( |
79
|
|
|
[ |
80
|
|
|
['ebayenterprise_paypal_express/checkout/return', [], 'the.return.url'], |
81
|
|
|
['ebayenterprise_paypal_express/checkout/cancel', [], 'the.cancel.url'], |
82
|
|
|
] |
83
|
|
|
) |
84
|
|
|
); |
85
|
|
|
// stub sdk |
86
|
|
|
$this->sdk = $this->getMock(self::BIDIRECTIONAL_API); |
87
|
|
|
$this->sdk->expects($this->any()) |
88
|
|
|
->method('setRequestBody') |
89
|
|
|
->will($this->returnSelf()); |
90
|
|
|
$this->sdk->expects($this->any()) |
91
|
|
|
->method('send')->will($this->returnSelf()); |
92
|
|
|
$this->getSdkApiMap = [ |
93
|
|
|
['payments', 'paypal/setExpress', [], null, $this->sdk], |
94
|
|
|
['payments', 'paypal/getExpress', [], null, $this->sdk], |
95
|
|
|
['payments', 'paypal/doExpress', [], null, $this->sdk], |
96
|
|
|
['payments', 'paypal/doAuth', [], null, $this->sdk], |
97
|
|
|
['payments', 'paypal/void', [], null, $this->sdk], |
98
|
|
|
]; |
99
|
|
|
$this->lineItemStub = $this->getMock(self::LINE_ITEM); |
100
|
|
|
$this->stubAcceptStrReturnSelf( |
101
|
|
|
['setName', 'setCurrencyCode'], |
102
|
|
|
$this->lineItemStub |
103
|
|
|
); |
104
|
|
|
$this->lineItemStub->expects($this->any()) |
105
|
|
|
->method('setUnitAmount') |
106
|
|
|
->with($this->isNumeric()) |
107
|
|
|
->will($this->returnSelf()); |
108
|
|
|
// sequence number can be set to any scalar |
109
|
|
|
$this->lineItemStub->expects($this->any()) |
110
|
|
|
->method('setSequenceNumber') |
111
|
|
|
->with($this->isScalar()) |
112
|
|
|
->will($this->returnSelf()); |
113
|
|
|
$this->lineItemStub->expects($this->any()) |
114
|
|
|
->method('setQuantity') |
115
|
|
|
->with($this->isType('int')) |
116
|
|
|
->will($this->returnSelf()); |
117
|
|
|
|
118
|
|
|
$validatorIterator = new ValidatorIterator([$this->getMock( |
119
|
|
|
'\eBayEnterprise\RetailOrderManagement\Payload\IValidator' |
120
|
|
|
)]); |
121
|
|
|
$stubSchemaValidator = $this->getMock('\eBayEnterprise\RetailOrderManagement\Payload\ISchemaValidator'); |
122
|
|
|
$payloadMap = new PayloadMap(); |
123
|
|
|
$logger = new NullLogger(); |
124
|
|
|
|
125
|
|
|
$this->lineItemIterableStub = $this->getMockBuilder(self::LINE_ITEM_ITERABLE) |
126
|
|
|
->setConstructorArgs([$validatorIterator, $stubSchemaValidator, $payloadMap, $logger]) |
127
|
|
|
->setMethods(['getEmptyLineItem']) |
128
|
|
|
->getMock(); |
129
|
|
|
$this->lineItemIterableStub->expects($this->any()) |
130
|
|
|
->method('getEmptyLineItem') |
131
|
|
|
->will($this->returnValue($this->lineItemStub)); |
132
|
|
|
// stub helpers |
133
|
|
|
$this->coreHelper = $this->getHelperMock( |
134
|
|
|
'eb2ccore/data', |
135
|
|
|
['getSdkApi'] |
136
|
|
|
); |
137
|
|
|
$this->coreHelper->expects($this->any()) |
138
|
|
|
->method('getSdkApi')->will( |
139
|
|
|
$this->returnValueMap($this->getSdkApiMap) |
140
|
|
|
); |
141
|
|
|
$this->helper = $this->getHelperMock( |
142
|
|
|
'ebayenterprise_paypal/data', |
143
|
|
|
['getConfigModel', '__'] |
144
|
|
|
); |
145
|
|
|
$this->helper->expects($this->any())->method('__')->will( |
146
|
|
|
$this->returnArgument(0) |
147
|
|
|
); |
148
|
|
|
// stub a quote |
149
|
|
|
$strMethods = ['getCity', 'getRegionCode', 'getCountryId', 'getPostCode']; |
150
|
|
|
$this->quoteShipAddress = $this->getModelMock( |
|
|
|
|
151
|
|
|
'sales/quote_address', |
152
|
|
|
$strMethods + ['getStreet', 'getId'] |
153
|
|
|
); |
154
|
|
|
foreach ($strMethods as $setter) { |
155
|
|
|
$this->quoteShipAddress->expects($this->any()) |
156
|
|
|
->method($setter) |
157
|
|
|
->will($this->returnValue('a string value')); |
158
|
|
|
} |
159
|
|
|
$this->quoteShipAddress->expects($this->any()) |
160
|
|
|
->method('getStreet') |
161
|
|
|
->will($this->returnValue(['line 1', 'line 2'])); |
162
|
|
|
$this->quoteShipAddress->expects($this->any()) |
163
|
|
|
->method('getId') |
164
|
|
|
->will($this->returnValue(1)); |
165
|
|
|
$this->quote = $this->getModelMock( |
|
|
|
|
166
|
|
|
'sales/quote', |
167
|
|
|
['reserveOrderId', 'getReservedOrderId', 'getAllItems', 'getTotals', 'getShippingAddress'] |
168
|
|
|
); |
169
|
|
|
$this->quote->expects($this->any()) |
170
|
|
|
->method('reserveOrderId')->will($this->returnSelf()); |
171
|
|
|
$this->quote->expects($this->any()) |
172
|
|
|
->method('getTotals')->will( |
173
|
|
|
$this->returnValue( |
174
|
|
|
[ |
175
|
|
|
'grand_total' => new Varien_Object(['value' => 100]), |
176
|
|
|
'shipping' => new Varien_Object(['value' => 5.95]), |
177
|
|
|
'ebayenterprise_tax' => new Varien_Object(['value' => 2.50]), |
178
|
|
|
'discount' => new Varien_Object(['value' => 100]), |
179
|
|
|
] |
180
|
|
|
) |
181
|
|
|
); |
182
|
|
|
$this->quote->expects($this->any()) |
183
|
|
|
->method('getReservedOrderId')->will($this->returnValue('orderid')); |
184
|
|
|
$this->quote->expects($this->any()) |
185
|
|
|
->method('getAllItems')->will( |
186
|
|
|
$this->returnValue($this->stubQuoteItems()) |
187
|
|
|
); |
188
|
|
|
$this->quote->expects($this->any()) |
189
|
|
|
->method('getShippingAddress') |
190
|
|
|
->will($this->returnValue($this->quoteShipAddress)); |
191
|
|
|
$this->quote->setData(['quote_currency_code' => 'USD']); |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* inject the given config into the core helper |
196
|
|
|
* @param array $config |
197
|
|
|
*/ |
198
|
|
|
protected function injectConfig(array $config) |
199
|
|
|
{ |
200
|
|
|
$config = $this->buildCoreConfigRegistry(array_merge(['transferLines' => true], $config)); |
201
|
|
|
$this->helper->expects($this->any()) |
202
|
|
|
->method('getConfigModel')->will($this->returnValue($config)); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* mock the request and reply for the setExpressCheckout |
207
|
|
|
* @param bool $successful true if the reply should report success |
208
|
|
|
* @return IPayload[] (stub) |
209
|
|
|
*/ |
210
|
|
|
protected function mockSetExpressPayloads($successful) |
211
|
|
|
{ |
212
|
|
|
$request = $this->getMock(self::SETEXPRESS_REQUEST_PAYLOAD); |
213
|
|
|
$this->stubAcceptStrReturnSelf( |
214
|
|
|
['setOrderId', 'setReturnUrl', 'setCancelUrl', 'setLocaleCode', 'setCurrencyCode'], |
215
|
|
|
$request |
216
|
|
|
); |
217
|
|
|
$request->expects($this->once()) |
218
|
|
|
->method('setAmount') |
219
|
|
|
->with($this->isNumeric()) |
220
|
|
|
->will($this->returnSelf()); |
221
|
|
|
$request->expects($this->exactly(2)) |
222
|
|
|
->method('getLineItems') |
223
|
|
|
->will($this->returnValue($this->lineItemIterableStub)); |
224
|
|
|
|
225
|
|
|
$reply = $this->getMock(self::SETEXPRESS_REPLY_PAYLOAD); |
226
|
|
|
$reply->expects($this->any()) |
227
|
|
|
->method('isSuccess') |
228
|
|
|
->will($this->returnValue($successful)); |
229
|
|
|
$reply->expects($this->any()) |
230
|
|
|
->method('getToken') |
231
|
|
|
->will($this->returnValue('token')); |
232
|
|
|
|
233
|
|
|
return [$request, $reply]; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* verify |
238
|
|
|
* - a request payload is acquired and sent to get a response body. |
239
|
|
|
* - the expected array structure is returned |
240
|
|
|
* - for a failure response to a successful request, |
241
|
|
|
* throw EbayEnterprise_PayPal_Exception with a translated message. |
242
|
|
|
* @loadExpectation messageReplies |
243
|
|
|
* @dataProvider provideTrueFalse |
244
|
|
|
*/ |
245
|
|
View Code Duplication |
public function testSetExpressCheckout($isSuccessful) |
|
|
|
|
246
|
|
|
{ |
247
|
|
|
$this->injectConfig([ |
248
|
|
|
'apiOperationSetExpressCheckout' => 'paypal/setExpress', |
249
|
|
|
'apiService' => 'payments', |
250
|
|
|
]); |
251
|
|
|
list($request, $reply) = $this->mockSetExpressPayloads($isSuccessful); |
252
|
|
|
$this->sdk->expects($this->any()) |
253
|
|
|
->method('getRequestBody') |
254
|
|
|
->will($this->returnValue($request)); |
255
|
|
|
// test setExpressCheckout |
256
|
|
|
$api = $this->getModelMock( |
257
|
|
|
'ebayenterprise_paypal/express_api', |
258
|
|
|
['sendRequest'] |
259
|
|
|
); |
260
|
|
|
$api->expects($this->any()) |
261
|
|
|
->method('sendRequest') |
262
|
|
|
->will($this->returnValue($reply)); |
263
|
|
|
EcomDev_Utils_Reflection::setRestrictedPropertyValues( |
264
|
|
|
$api, |
265
|
|
|
['helper' => $this->helper, 'coreHelper' => $this->coreHelper] |
266
|
|
|
); |
267
|
|
|
if (!$isSuccessful) { |
268
|
|
|
$message |
269
|
|
|
= EbayEnterprise_PayPal_Model_Express_Api::EBAYENTERPRISE_PAYPAL_API_FAILED; |
270
|
|
|
$this->setExpectedException('EbayEnterprise_PayPal_Exception', $message); |
271
|
|
|
} |
272
|
|
|
$result = $api->setExpressCheckout($this->cancelUrl, $this->returnUrl, $this->quote); |
273
|
|
|
$this->assertEquals($this->expected('setExpress')->getData(), $result); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
/** |
277
|
|
|
* setup payloads for getExpressCheckout |
278
|
|
|
* @param bool $success |
279
|
|
|
*/ |
280
|
|
|
protected function mockGetExpressPayoads($success) |
281
|
|
|
{ |
282
|
|
|
// mock the request |
283
|
|
|
$request = $this->getMock(self::GETEXPRESS_REQUEST_PAYLOAD); |
284
|
|
|
$this->stubAcceptStrReturnSelf( |
285
|
|
|
['setOrderId', 'setToken', 'setCurrencyCode'], |
286
|
|
|
$request |
287
|
|
|
); |
288
|
|
|
$request->expects($this->any()) |
289
|
|
|
->method('getBillingAddressStatus') |
290
|
|
|
->will($this->returnValue(null)); |
291
|
|
|
$request->expects($this->any()) |
292
|
|
|
->method('getShipToAddressStatus') |
293
|
|
|
->will($this->returnValue(null)); |
294
|
|
|
|
295
|
|
|
// mock the reply |
296
|
|
|
$reply = $this->getMock(self::GETEXPRESS_REPLY_PAYLOAD); |
297
|
|
|
$reply->expects($this->any()) |
298
|
|
|
->method('isSuccess') |
299
|
|
|
->will($this->returnValue($success)); |
300
|
|
|
return [$request, $reply]; |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
/** |
304
|
|
|
* verify |
305
|
|
|
* - get express payload is filled out |
306
|
|
|
* - the expected array structure is returned |
307
|
|
|
* - when the request was unsuccessful throw EbayEnterprise_PayPal_Exception |
308
|
|
|
* @loadExpectation messageReplies |
309
|
|
|
* @dataProvider provideTrueFalse |
310
|
|
|
*/ |
311
|
|
View Code Duplication |
public function testGetExpressCheckout($isSuccessful) |
|
|
|
|
312
|
|
|
{ |
313
|
|
|
$this->injectConfig( |
314
|
|
|
[ |
315
|
|
|
'apiOperationGetExpressCheckout' => 'paypal/getExpress', |
316
|
|
|
'apiService' => 'payments', |
317
|
|
|
] |
318
|
|
|
); |
319
|
|
|
list($request, $reply) = $this->mockGetExpressPayoads($isSuccessful); |
320
|
|
|
$this->sdk->expects($this->any()) |
321
|
|
|
->method('getRequestBody') |
322
|
|
|
->will($this->returnValue($request)); |
323
|
|
|
// test setExpressCheckout |
324
|
|
|
$api = $this->getModelMock('ebayenterprise_paypal/express_api', ['sendRequest']); |
325
|
|
|
$api->expects($this->any()) |
326
|
|
|
->method('sendRequest') |
327
|
|
|
->will($this->returnValue($reply)); |
328
|
|
|
EcomDev_Utils_Reflection::setRestrictedPropertyValues( |
329
|
|
|
$api, |
330
|
|
|
['helper' => $this->helper, 'coreHelper' => $this->coreHelper] |
331
|
|
|
); |
332
|
|
|
if (!$isSuccessful) { |
333
|
|
|
$message |
334
|
|
|
= EbayEnterprise_PayPal_Model_Express_Api::EBAYENTERPRISE_PAYPAL_API_FAILED; |
335
|
|
|
$this->setExpectedException('EbayEnterprise_PayPal_Exception', $message); |
336
|
|
|
} |
337
|
|
|
$result = $api->getExpressCheckout($this->orderId, $this->token, $this->currencyCode); |
338
|
|
|
$this->assertEquals($this->expected('getExpress')->getData(), $result); |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
/** |
342
|
|
|
* verify |
343
|
|
|
* - the given sdk object is used to send the request |
344
|
|
|
* - verify the reply is returned |
345
|
|
|
*/ |
346
|
|
|
public function testSendRequest() |
347
|
|
|
{ |
348
|
|
|
$requestPayload = $this->getMock('\eBayEnterprise\RetailOrderManagement\Payload\IPayload'); |
349
|
|
|
$requestPayload->expects($this->any()) |
350
|
|
|
->method('serialize') |
351
|
|
|
->will($this->returnValue('serialized request')); |
352
|
|
|
$replyPayload = $this->getMock('\eBayEnterprise\RetailOrderManagement\Payload\IPayload'); |
353
|
|
|
$replyPayload->expects($this->any()) |
354
|
|
|
->method('serialize') |
355
|
|
|
->will($this->returnValue('serialized reply')); |
356
|
|
|
$this->sdk->expects($this->any()) |
357
|
|
|
->method('getRequestBody') |
358
|
|
|
->will($this->returnValue($requestPayload)); |
359
|
|
|
$this->sdk->expects($this->any()) |
360
|
|
|
->method('getResponseBody') |
361
|
|
|
->will($this->returnValue($replyPayload)); |
362
|
|
|
$api = Mage::getModel('ebayenterprise_paypal/express_api'); |
363
|
|
|
$this->assertSame( |
364
|
|
|
$replyPayload, |
365
|
|
|
EcomDev_Utils_Reflection::invokeRestrictedMethod($api, 'sendRequest', [$this->sdk]) |
366
|
|
|
); |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
/** |
370
|
|
|
* provide sdk exceptions to throw |
371
|
|
|
* @return array |
|
|
|
|
372
|
|
|
*/ |
373
|
|
View Code Duplication |
public function provideSdkExceptions() |
|
|
|
|
374
|
|
|
{ |
375
|
|
|
$invalidPayload = '\eBayEnterprise\RetailOrderManagement\Payload\Exception\InvalidPayload'; |
376
|
|
|
$networkError = '\eBayEnterprise\RetailOrderManagement\Api\Exception\NetworkError'; |
377
|
|
|
$unsupportedOperation = '\eBayEnterprise\RetailOrderManagement\Api\Exception\UnsupportedOperation'; |
378
|
|
|
$unsupportedHttpAction = '\eBayEnterprise\RetailOrderManagement\Api\Exception\UnsupportedHttpAction'; |
379
|
|
|
$baseException = 'Exception'; |
380
|
|
|
$paypalException = 'EbayEnterprise_PayPal_Exception'; |
381
|
|
|
return [ |
382
|
|
|
[$invalidPayload, $paypalException], |
383
|
|
|
[$networkError, $paypalException], |
384
|
|
|
[$unsupportedOperation, $unsupportedOperation], |
385
|
|
|
[$unsupportedHttpAction, $unsupportedHttpAction], |
386
|
|
|
[$baseException, $baseException], |
387
|
|
|
]; |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
/** |
391
|
|
|
* GIVEN An <sdk> that will thrown an <exception> of <exceptionType> when making a request. |
392
|
|
|
* WHEN A request is made. |
393
|
|
|
* THEN The <exception> will be caught. |
394
|
|
|
* AND An exception of <expectedExceptionType> will be thrown. |
395
|
|
|
* |
396
|
|
|
* @param string |
397
|
|
|
* @param string |
398
|
|
|
* @dataProvider provideSdkExceptions |
399
|
|
|
*/ |
400
|
|
|
public function testSendRequestWithSdkException($exceptionType, $expectedExceptionType) |
401
|
|
|
{ |
402
|
|
|
// Mock log context to prevent session interactions while getting log meta data. |
403
|
|
|
$logContext = $this->getHelperMock('ebayenterprise_magelog/context', ['getMetaData']); |
404
|
|
|
$logContext->method('getMetaData')->will($this->returnValue([])); |
405
|
|
|
|
406
|
|
|
$exception = new $exceptionType(__METHOD__ . ': Test Exception'); |
407
|
|
|
|
408
|
|
|
// Set the SDK API up to throw an exception. |
409
|
|
|
$this->sdk->expects($this->any()) |
410
|
|
|
->method('send') |
411
|
|
|
->will($this->throwException($exception)); |
412
|
|
|
|
413
|
|
|
$api = Mage::getModel('ebayenterprise_paypal/express_api', ['log_context' => $logContext]); |
414
|
|
|
|
415
|
|
|
$this->setExpectedException($expectedExceptionType); |
416
|
|
|
|
417
|
|
|
EcomDev_Utils_Reflection::invokeRestrictedMethod($api, 'sendRequest', [$this->sdk]); |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
/** |
421
|
|
|
* mock the request and reply for the doExpressCheckout |
422
|
|
|
* @param bool $successful true if the reply should report success |
423
|
|
|
* @return IPayload[] (stub) |
424
|
|
|
*/ |
425
|
|
|
protected function mockDoExpressPayloads($successful) |
426
|
|
|
{ |
427
|
|
|
$request = $this->getMock(self::DOEXPRESS_REQUEST_PAYLOAD); |
428
|
|
|
$this->stubAcceptStrReturnSelf( |
429
|
|
|
['setRequestId', 'setOrderId', 'setToken', 'setPayerId', 'setCurrencyCode'], |
430
|
|
|
$request |
431
|
|
|
); |
432
|
|
|
$request->expects($this->exactly(2)) |
433
|
|
|
->method('getLineItems') |
434
|
|
|
->will($this->returnValue($this->lineItemIterableStub)); |
435
|
|
|
$request->expects($this->once()) |
436
|
|
|
->method('setAmount') |
437
|
|
|
->with($this->isNumeric()) |
438
|
|
|
->will($this->returnSelf()); |
439
|
|
|
|
440
|
|
|
$reply = $this->getMock(self::DOEXPRESS_REPLY_PAYLOAD); |
441
|
|
|
$reply->expects($this->any()) |
442
|
|
|
->method('isSuccess') |
443
|
|
|
->will($this->returnValue($successful)); |
444
|
|
|
return [$request, $reply]; |
445
|
|
|
} |
446
|
|
|
|
447
|
|
|
/** |
448
|
|
|
* provide inputs for the case where: |
449
|
|
|
* - the request was succesful and does or does not have a pickup id |
450
|
|
|
* - the request was not successful |
451
|
|
|
* @return array |
|
|
|
|
452
|
|
|
*/ |
453
|
|
|
public function provideForDoExpressCheckout() |
454
|
|
|
{ |
455
|
|
|
return [ |
456
|
|
|
[true, 'pickup id'], |
457
|
|
|
[true, null], |
458
|
|
|
[false, 'pickup id'], |
459
|
|
|
]; |
460
|
|
|
} |
461
|
|
|
|
462
|
|
|
/** |
463
|
|
|
* verify |
464
|
|
|
* - the expected array structure is returned |
465
|
|
|
* @param bool $isSuccessful |
466
|
|
|
* @dataProvider provideForDoExpressCheckout |
467
|
|
|
* @loadExpectation messageReplies |
468
|
|
|
*/ |
469
|
|
|
public function testDoExpressCheckout($isSuccessful, $pickUpStoreId) |
470
|
|
|
{ |
471
|
|
|
$this->injectConfig( |
472
|
|
|
[ |
473
|
|
|
'apiOperationDoExpressCheckout' => 'paypal/doExpress', |
474
|
|
|
'apiService' => 'payments', |
475
|
|
|
] |
476
|
|
|
); |
477
|
|
|
list($request, $reply) = $this->mockDoExpressPayloads($isSuccessful); |
478
|
|
|
if ($pickUpStoreId) { |
479
|
|
|
$request->expects($this->once()) |
480
|
|
|
->method('setPickUpStoreId') |
481
|
|
|
->with($this->isType('string')) |
482
|
|
|
->will($this->returnSelf()); |
483
|
|
|
} |
484
|
|
|
$this->sdk->expects($this->any()) |
485
|
|
|
->method('getRequestBody') |
486
|
|
|
->will($this->returnValue($request)); |
487
|
|
|
// test setExpressCheckout |
488
|
|
|
$api = $this->getModelMock('ebayenterprise_paypal/express_api', ['sendRequest']); |
489
|
|
|
$api->expects($this->any()) |
490
|
|
|
->method('sendRequest') |
491
|
|
|
->will($this->returnValue($reply)); |
492
|
|
|
EcomDev_Utils_Reflection::setRestrictedPropertyValues( |
493
|
|
|
$api, |
494
|
|
|
['helper' => $this->helper, 'coreHelper' => $this->coreHelper] |
495
|
|
|
); |
496
|
|
|
if (!$isSuccessful) { |
497
|
|
|
$message |
498
|
|
|
= EbayEnterprise_PayPal_Model_Express_Api::EBAYENTERPRISE_PAYPAL_API_FAILED; |
499
|
|
|
$this->setExpectedException('EbayEnterprise_PayPal_Exception', $message); |
500
|
|
|
} |
501
|
|
|
$result = $api->doExpressCheckout($this->quote, $this->token, $this->payerId, $pickUpStoreId); |
502
|
|
|
$this->assertEquals($this->expected('doExpress')->getData(), $result); |
503
|
|
|
} |
504
|
|
|
|
505
|
|
|
/** |
506
|
|
|
* stub items for the tests. |
507
|
|
|
* @return Mage_Sale_Model_Quote_Item[] |
|
|
|
|
508
|
|
|
*/ |
509
|
|
|
protected function stubQuoteItems() |
510
|
|
|
{ |
511
|
|
|
$methods = [ |
512
|
|
|
'getHasChildren', 'isChildrenCalculated', 'getChildren', 'getProduct', |
513
|
|
|
'getId', 'getQuoteItem', 'getQty', 'getPrice', 'getName', |
514
|
|
|
]; |
515
|
|
|
// item mocks |
516
|
|
|
$item = $this->getModelMock('sales/quote_item', $methods); |
517
|
|
|
$parent = $this->getModelMock('sales/quote_item', $methods); |
518
|
|
|
$child = $this->getModelMock('sales/quote_item', $methods); |
519
|
|
|
|
520
|
|
|
$parent->expects($this->any()) |
521
|
|
|
->method('getHasChildren') |
522
|
|
|
->will($this->returnValue(true)); |
523
|
|
|
$parent->expects($this->any()) |
524
|
|
|
->method('isChildrenCalculated') |
525
|
|
|
->will($this->returnValue(true)); |
526
|
|
|
$parent->expects($this->any()) |
527
|
|
|
->method('getChildren') |
528
|
|
|
->will($this->returnValue([$child])); |
529
|
|
|
|
530
|
|
|
$stubs = [$item, $child, $parent]; |
531
|
|
|
foreach ($stubs as $stub) { |
532
|
|
|
$stub->expects($this->any()) |
533
|
|
|
->method('getProduct') |
534
|
|
|
->will($this->returnSelf()); |
535
|
|
|
$stub->expects($this->any()) |
536
|
|
|
->method('getId') |
537
|
|
|
->will($this->returnValue(key($stubs))); |
538
|
|
|
$stub->expects($this->any()) |
539
|
|
|
->method('getQuoteItem') |
540
|
|
|
->will($this->returnSelf()); |
541
|
|
|
$stub->expects($this->any()) |
542
|
|
|
->method('getQty') |
543
|
|
|
->will($this->returnValue(1)); |
544
|
|
|
$stub->expects($this->any()) |
545
|
|
|
->method('getPrice') |
546
|
|
|
->will($this->returnValue(1)); |
547
|
|
|
} |
548
|
|
|
|
549
|
|
|
$item->expects($this->any()) |
550
|
|
|
->method('getName') |
551
|
|
|
->will($this->returnValue('item')); |
552
|
|
|
$parent->expects($this->any()) |
553
|
|
|
->method('getName') |
554
|
|
|
->will($this->returnValue('parent')); |
555
|
|
|
$child->expects($this->any()) |
556
|
|
|
->method('getName') |
557
|
|
|
->will($this->returnValue('child')); |
558
|
|
|
|
559
|
|
|
return [$item, $parent]; |
560
|
|
|
} |
561
|
|
|
|
562
|
|
|
/** |
563
|
|
|
* creat a constraint to assert an argument has a numeric value |
564
|
|
|
* @return PHPUnit_Framework_Constraint |
|
|
|
|
565
|
|
|
*/ |
566
|
|
|
protected function isNumeric() |
567
|
|
|
{ |
568
|
|
|
return $this->callback( |
569
|
|
|
function ($val) { |
570
|
|
|
|
571
|
|
|
return is_numeric($val); |
572
|
|
|
} |
573
|
|
|
); |
574
|
|
|
} |
575
|
|
|
|
576
|
|
|
/** |
577
|
|
|
* mock the request and reply for the doAuthorization message |
578
|
|
|
* @param bool $successful true if the reply should report success |
579
|
|
|
* @return IPayload[] (stub) |
580
|
|
|
*/ |
581
|
|
|
protected function mockDoAuthorizationPayloads($successful) |
582
|
|
|
{ |
583
|
|
|
$request = $this->getMock(self::DOAUTH_REQUEST_PAYLOAD); |
584
|
|
|
$this->stubAcceptStrReturnSelf( |
585
|
|
|
['setRequestId', 'setOrderId', 'setCurrencyCode'], |
586
|
|
|
$request |
587
|
|
|
); |
588
|
|
|
$request->expects($this->once()) |
589
|
|
|
->method('setAmount') |
590
|
|
|
->with($this->isNumeric()) |
591
|
|
|
->will($this->returnSelf()); |
592
|
|
|
|
593
|
|
|
$reply = $this->getMock(self::DOAUTH_REPLY_PAYLOAD); |
594
|
|
|
$reply->expects($this->any()) |
595
|
|
|
->method('isSuccess') |
596
|
|
|
->will($this->returnValue($successful)); |
597
|
|
|
return [$request, $reply]; |
598
|
|
|
} |
599
|
|
|
|
600
|
|
|
/** |
601
|
|
|
* verify |
602
|
|
|
* - the request paylad is setup with the correct type of data |
603
|
|
|
* - the resulting array is in the expected structure |
604
|
|
|
* - the is_authorized field is true if the message succeeded; false otherwise |
605
|
|
|
* - throws an EbayEnterprise_PayPal_Exception when the message fails |
606
|
|
|
* @loadExpectation messageReplies |
607
|
|
|
* @dataProvider provideTrueFalse |
608
|
|
|
*/ |
609
|
|
|
public function testDoAuthorization($isSuccessful) |
610
|
|
|
{ |
611
|
|
|
$this->injectConfig( |
612
|
|
|
[ |
613
|
|
|
'apiOperationDoAuthorization' => 'paypal/doAuth', |
614
|
|
|
'apiService' => 'payments', |
615
|
|
|
] |
616
|
|
|
); |
617
|
|
|
list($request, $reply) = $this->mockDoAuthorizationPayloads($isSuccessful); |
618
|
|
|
$this->sdk->expects($this->any()) |
619
|
|
|
->method('getRequestBody') |
620
|
|
|
->will($this->returnValue($request)); |
621
|
|
|
// test setExpressCheckout |
622
|
|
|
$api = $this->getModelMock('ebayenterprise_paypal/express_api', ['sendRequest']); |
623
|
|
|
$api->expects($this->any()) |
624
|
|
|
->method('sendRequest') |
625
|
|
|
->will($this->returnValue($reply)); |
626
|
|
|
EcomDev_Utils_Reflection::setRestrictedPropertyValues( |
627
|
|
|
$api, |
628
|
|
|
['helper' => $this->helper, 'coreHelper' => $this->coreHelper] |
629
|
|
|
); |
630
|
|
|
if (!$isSuccessful) { |
631
|
|
|
$message |
632
|
|
|
= EbayEnterprise_PayPal_Model_Express_Api::EBAYENTERPRISE_PAYPAL_API_FAILED; |
633
|
|
|
$this->setExpectedException('EbayEnterprise_PayPal_Exception', $message); |
634
|
|
|
} |
635
|
|
|
$result = $api->doAuthorization($this->quote); |
636
|
|
|
$expectation = 'doAuth/' . ($isSuccessful ? 'success' : 'failure'); |
637
|
|
|
$this->assertEquals($this->expected($expectation)->getData(), $result); |
638
|
|
|
} |
639
|
|
|
|
640
|
|
|
/** |
641
|
|
|
* mock the request and reply for the doVoid message |
642
|
|
|
* @param bool $successful true if the reply should report success |
643
|
|
|
* @return IPayload[] (stub) |
644
|
|
|
*/ |
645
|
|
|
protected function mockDoVoidPayloads($successful) |
646
|
|
|
{ |
647
|
|
|
$request = $this->getMock(self::DOVOID_REQUEST_PAYLOAD); |
648
|
|
|
$request->expects($this->once()) |
649
|
|
|
->method('setRequestId') |
650
|
|
|
->with($this->isType('string')) |
651
|
|
|
->will($this->returnSelf()); |
652
|
|
|
$request->expects($this->once()) |
653
|
|
|
->method('setOrderId') |
654
|
|
|
->with($this->isType('string')) |
655
|
|
|
->will($this->returnSelf()); |
656
|
|
|
|
657
|
|
|
$reply = $this->getMock(self::DOVOID_REPLY_PAYLOAD); |
658
|
|
|
$reply->expects($this->any()) |
659
|
|
|
->method('isSuccess') |
660
|
|
|
->will($this->returnValue($successful)); |
661
|
|
|
return [$request, $reply]; |
662
|
|
|
} |
663
|
|
|
|
664
|
|
|
/** |
665
|
|
|
* verify |
666
|
|
|
* - the request paylad is setup with the correct type of data |
667
|
|
|
* - the resulting array is in the expected structure |
668
|
|
|
* - the is_voided field is true if the message succeeded; false otherwise |
669
|
|
|
* - throws an EbayEnterprise_PayPal_Exception when the message fails |
670
|
|
|
* @loadExpectation messageReplies |
671
|
|
|
* @dataProvider provideTrueFalse |
672
|
|
|
*/ |
673
|
|
|
public function testDoVoid($isSuccessful) |
674
|
|
|
{ |
675
|
|
|
$order = $this->getModelMock('sales/order', ['getIncrementId']); |
676
|
|
|
$order->expects($this->any()) |
677
|
|
|
->method('getIncrementId') |
678
|
|
|
->will($this->returnValue($this->orderId)); |
679
|
|
|
|
680
|
|
|
$this->injectConfig(['apiOperationDoVoid' => 'paypal/void', 'apiService' => 'payments']); |
681
|
|
|
list($request, $reply) = $this->mockDoVoidPayloads($isSuccessful); |
682
|
|
|
$this->sdk->expects($this->any()) |
683
|
|
|
->method('getRequestBody') |
684
|
|
|
->will($this->returnValue($request)); |
685
|
|
|
// test setExpressCheckout |
686
|
|
|
$api = $this->getModelMock('ebayenterprise_paypal/express_api', ['sendRequest']); |
687
|
|
|
$api->expects($this->any()) |
688
|
|
|
->method('sendRequest') |
689
|
|
|
->will($this->returnValue($reply)); |
690
|
|
|
EcomDev_Utils_Reflection::setRestrictedPropertyValues( |
691
|
|
|
$api, |
692
|
|
|
['helper' => $this->helper, 'coreHelper' => $this->coreHelper] |
693
|
|
|
); |
694
|
|
|
if (!$isSuccessful) { |
695
|
|
|
$message |
696
|
|
|
= EbayEnterprise_PayPal_Model_Express_Api::EBAYENTERPRISE_PAYPAL_API_FAILED; |
697
|
|
|
$this->setExpectedException('EbayEnterprise_PayPal_Exception', $message); |
698
|
|
|
} |
699
|
|
|
$result = $api->doVoidOrder($order); |
700
|
|
|
$expectation = 'void/' . ($isSuccessful ? 'success' : 'failure'); |
701
|
|
|
$this->assertEquals($this->expected($expectation)->getData(), $result); |
702
|
|
|
} |
703
|
|
|
|
704
|
|
|
/** |
705
|
|
|
* use to assert an argument is a scalar |
706
|
|
|
* @return PHPUnit_Framework_Constraint |
|
|
|
|
707
|
|
|
*/ |
708
|
|
|
protected function isScalar() |
709
|
|
|
{ |
710
|
|
|
return $this->callback( |
711
|
|
|
function ($val) { |
712
|
|
|
|
713
|
|
|
return is_scalar($val); |
714
|
|
|
} |
715
|
|
|
); |
716
|
|
|
} |
717
|
|
|
|
718
|
|
|
/** |
719
|
|
|
* stub the specified methods on the mock to expect a |
720
|
|
|
* string argument and return itself |
721
|
|
|
* @param array $methods |
722
|
|
|
* @param object $stub |
723
|
|
|
* @return object |
724
|
|
|
*/ |
725
|
|
|
protected function stubAcceptStrReturnSelf(array $methods, $stub) |
726
|
|
|
{ |
727
|
|
|
foreach ($methods as $method) { |
728
|
|
|
$stub->expects($this->any()) |
729
|
|
|
->method($method) |
730
|
|
|
->with($this->isType('string')) |
731
|
|
|
->will($this->returnSelf()); |
732
|
|
|
} |
733
|
|
|
return $stub; |
734
|
|
|
} |
735
|
|
|
|
736
|
|
|
/** |
737
|
|
|
* ensure the tax amount gets added |
738
|
|
|
* |
739
|
|
|
*/ |
740
|
|
|
public function testAddLineItems() |
741
|
|
|
{ |
742
|
|
|
$iterable = $this->getMockBuilder('\eBayEnterprise\RetailOrderManagement\Payload\Payment\ILineItemIterable') |
743
|
|
|
->getMockForAbstractClass(); |
744
|
|
|
$request = $this->getMockBuilder(self::SETEXPRESS_REQUEST_PAYLOAD) |
745
|
|
|
->getMockForAbstractClass(); |
746
|
|
|
$api = $this->getModelMockBuilder('ebayenterprise_paypal/express_api') |
747
|
|
|
->setConstructorArgs([['core_helper' => $this->coreHelper]]) |
748
|
|
|
->setMethods(['processLineItems', 'processNegativeLineItems', 'canIncludeLineItems']) |
749
|
|
|
->getMock(); |
750
|
|
|
|
751
|
|
|
$api->expects($this->once()) |
752
|
|
|
->method('processLineItems') |
753
|
|
|
->will($this->returnSelf()); |
754
|
|
|
$api->expects($this->once()) |
755
|
|
|
->method('processNegativeLineItems') |
756
|
|
|
->will($this->returnSelf()); |
757
|
|
|
$api->expects($this->once()) |
758
|
|
|
->method('canIncludeLineItems') |
759
|
|
|
->will($this->returnValue(true)); |
760
|
|
|
|
761
|
|
|
$request->expects($this->atLeastOnce()) |
762
|
|
|
->method('getLineItems') |
763
|
|
|
->will($this->returnValue($iterable)); |
764
|
|
|
|
765
|
|
|
$request->expects($this->once()) |
766
|
|
|
->method('setTaxTotal') |
767
|
|
|
->with($this->identicalTo(2.50)) |
768
|
|
|
->will($this->returnSelf()); |
769
|
|
|
$request->expects($this->once()) |
770
|
|
|
->method('setShippingTotal') |
771
|
|
|
->will($this->returnSelf()); |
772
|
|
|
$request->expects($this->once()) |
773
|
|
|
->method('setCurrencyCode') |
774
|
|
|
->will($this->returnSelf()); |
775
|
|
|
EcomDev_Utils_Reflection::invokeRestrictedMethod($api, 'addLineItems', [$this->quote, $request]); |
776
|
|
|
} |
777
|
|
|
|
778
|
|
|
/** |
779
|
|
|
* verify line items are created from |
780
|
|
|
* |
781
|
|
|
*/ |
782
|
|
|
public function testProcessLineItems() |
783
|
|
|
{ |
784
|
|
|
$item = $this->getModelMockBuilder('sales/quote_item_abstract') |
785
|
|
|
->getMockForAbstractClass(); |
786
|
|
|
$quote = $this->getModelMockBuilder('sales/quote') |
787
|
|
|
->disableOriginalConstructor() |
788
|
|
|
->setMethods(['getAllItems', 'getQuoteCurrencyCode']) |
789
|
|
|
->getMock(); |
790
|
|
|
$lineItems = $this->getMockBuilder( |
791
|
|
|
'\eBayEnterprise\RetailOrderManagement\Payload\Payment\ILineItemIterable' |
792
|
|
|
) |
793
|
|
|
->getMockForAbstractClass(); |
794
|
|
|
$selectionHelper = $this->getHelperMock( |
795
|
|
|
'ebayenterprise_paypal/item_selection', |
796
|
|
|
['selectFrom'] |
797
|
|
|
); |
798
|
|
|
$currencyCode = 'USD'; |
799
|
|
|
|
800
|
|
|
$quote->expects($this->once()) |
801
|
|
|
->method('getAllItems') |
802
|
|
|
->will($this->returnValue([$item])); |
803
|
|
|
$quote->expects($this->once()) |
804
|
|
|
->method('getQuoteCurrencyCode') |
805
|
|
|
->will($this->returnValue($currencyCode)); |
806
|
|
|
$selectionHelper->expects($this->once()) |
807
|
|
|
->method('selectFrom') |
808
|
|
|
->with($this->equalTo([$item])) |
809
|
|
|
->will($this->returnArgument(0)); |
810
|
|
|
|
811
|
|
|
$api = $this->getModelMockBuilder('ebayenterprise_paypal/express_api') |
812
|
|
|
->setConstructorArgs([['selection_helper' => $selectionHelper]]) |
813
|
|
|
->setMethods(['createLineItem']) |
814
|
|
|
->getMock(); |
815
|
|
|
$api->expects($this->once()) |
816
|
|
|
->method('createLineItem') |
817
|
|
|
->with( |
818
|
|
|
$this->identicalTo($item), |
819
|
|
|
$this->identicalTo($lineItems), |
820
|
|
|
$this->identicalTo($currencyCode) |
821
|
|
|
); |
822
|
|
|
EcomDev_Utils_Reflection::invokeRestrictedMethod( |
823
|
|
|
$api, |
824
|
|
|
'processLineItems', |
825
|
|
|
[$quote, $lineItems] |
826
|
|
|
); |
827
|
|
|
} |
828
|
|
|
} |
829
|
|
|
|
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: