Passed
Push — master ( 29d5f6...586595 )
by Aimeos
04:48
created

Service/Provider/Payment/PayPalExpressTest.php (1 issue)

Severity
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2012
6
 * @copyright Aimeos (aimeos.org), 2015-2018
7
 */
8
9
10
namespace Aimeos\MShop\Service\Provider\Payment;
11
12
13
class PayPalExpressTest extends \PHPUnit\Framework\TestCase
14
{
15
	private $context;
16
	private $object;
17
	private $serviceItem;
18
	private $orderMock;
19
	private $order;
20
21
22
	protected function setUp()
23
	{
24
		$this->context = \TestHelperMShop::getContext();
25
		$serviceManager = \Aimeos\MShop\Service\Manager\Factory::createManager( $this->context );
26
27
		$search = $serviceManager->createSearch();
28
		$search->setConditions( $search->compare( '==', 'service.code', 'paypalexpress' ) );
29
30
		$serviceItems = $serviceManager->searchItems( $search );
31
32
		if( ( $this->serviceItem = reset( $serviceItems ) ) === false ) {
33
			throw new \RuntimeException( 'No paypalexpress service item available' );
34
		}
35
36
		$this->object = $this->getMockBuilder( '\Aimeos\MShop\Service\Provider\Payment\PayPalExpress' )
37
			->setConstructorArgs( [$this->context, $this->serviceItem] )
38
			->setMethods( ['send'] )
39
			->getMock();
40
41
42
		$orderManager = \Aimeos\MShop\Order\Manager\Factory::createManager( $this->context );
43
44
		$search = $orderManager->createSearch();
45
		$expr = array(
46
			$search->compare( '==', 'order.type', \Aimeos\MShop\Order\Item\Base::TYPE_WEB ),
47
			$search->compare( '==', 'order.statuspayment', \Aimeos\MShop\Order\Item\Base::PAY_AUTHORIZED )
48
		);
49
		$search->setConditions( $search->combine( '&&', $expr ) );
50
		$orderItems = $orderManager->searchItems( $search );
51
52
		if( ( $this->order = reset( $orderItems ) ) === false ) {
53
			throw new \RuntimeException( sprintf( 'No Order found with statuspayment "%1$s" and type "%2$s"', \Aimeos\MShop\Order\Item\Base::PAY_AUTHORIZED, \Aimeos\MShop\Order\Item\Base::TYPE_WEB ) );
54
		}
55
56
57
		$this->orderMock = $this->getMockBuilder( '\\Aimeos\\MShop\\Order\\Manager\\Standard' )
58
			->setConstructorArgs( array( $this->context ) )
59
			->setMethods( array( 'saveItem' ) )
60
			->getMock();
61
62
		$this->context->getConfig()->set( 'mshop/order/manager/name', 'MockPayPal' );
63
		\Aimeos\MShop\Order\Manager\Factory::injectManager( '\\Aimeos\\MShop\\Order\\Manager\\MockPayPal', $this->orderMock );
64
	}
65
66
67
	protected function tearDown()
68
	{
69
		unset( $this->object );
70
		unset( $this->serviceItem );
71
		unset( $this->order );
72
	}
73
74
75
	public function testGetConfigBE()
76
	{
77
		$result = $this->object->getConfigBE();
78
79
		$this->assertEquals( 15, count( $result ) );
80
81
		foreach( $result as $key => $item ) {
82
			$this->assertInstanceOf( 'Aimeos\MW\Criteria\Attribute\Iface', $item );
83
		}
84
	}
85
86
87
	public function testCheckConfigBE()
88
	{
89
		$attributes = array(
90
			'paypalexpress.ApiUsername' => 'user',
91
			'paypalexpress.AccountEmail' => '[email protected]',
92
			'paypalexpress.ApiPassword' => 'pw',
93
			'paypalexpress.ApiSignature' => '1df23eh67',
94
			'payment.url-cancel' => 'http://cancelUrl',
95
			'payment.url-success' => 'http://returnUrl'
96
		);
97
98
		$result = $this->object->checkConfigBE( $attributes );
99
100
		$this->assertEquals( 15, count( $result ) );
101
		$this->assertEquals( null, $result['paypalexpress.ApiUsername'] );
102
		$this->assertEquals( null, $result['paypalexpress.AccountEmail'] );
103
		$this->assertEquals( null, $result['paypalexpress.ApiPassword'] );
104
		$this->assertEquals( null, $result['paypalexpress.ApiSignature'] );
105
	}
106
107
	public function testIsImplemented()
108
	{
109
		$this->assertTrue( $this->object->isImplemented( \Aimeos\MShop\Service\Provider\Payment\Base::FEAT_CANCEL ) );
110
		$this->assertTrue( $this->object->isImplemented( \Aimeos\MShop\Service\Provider\Payment\Base::FEAT_CAPTURE ) );
111
		$this->assertTrue( $this->object->isImplemented( \Aimeos\MShop\Service\Provider\Payment\Base::FEAT_QUERY ) );
112
		$this->assertTrue( $this->object->isImplemented( \Aimeos\MShop\Service\Provider\Payment\Base::FEAT_REFUND ) );
113
114
		$this->assertFalse( $this->object->isImplemented( -1 ) );
115
	}
116
117
118
	public function testProcess()
119
	{
120
		$this->object->expects( $this->once() )->method( 'send' )->will(
121
			$this->returnValue( '&ACK=Success&VERSION=87.0&BUILD=3136725&CORRELATIONID=1234567890&TOKEN=UT-99999999' )
122
		);
123
124
		$helperForm = $this->object->process( $this->order );
125
126
		$orderManager = \Aimeos\MShop\Order\Manager\Factory::createManager( $this->context );
127
		$orderBaseManager = $orderManager->getSubManager( 'base' );
128
129
		$refOrderBase = $orderBaseManager->load( $this->order->getBaseId() );
130
131
		$attributes = $refOrderBase->getService( 'payment', 'paypalexpress' )->getAttributeItems();
132
133
		$attributeList = [];
134
		foreach( $attributes as $attribute ) {
135
			$attributeList[$attribute->getCode()] = $attribute;
136
		}
137
138
		$this->assertInstanceOf( '\\Aimeos\\MShop\\Common\\Item\\Helper\\Form\\Iface', $helperForm );
139
		$this->assertEquals( 'https://www.sandbox.paypal.com/webscr&cmd=_express-checkout&useraction=commit&token=UT-99999999', $helperForm->getUrl() );
140
		$this->assertEquals( 'POST', $helperForm->getMethod() );
141
		$this->assertEquals( [], $helperForm->getValues() );
142
143
		$testData = array(
144
			'TOKEN' => 'UT-99999999'
145
		);
146
147
		foreach( $testData as $key => $value ) {
148
			$this->assertEquals( $attributeList[$key]->getValue(), $testData[$key] );
149
		}
150
	}
151
152
153
	public function testUpdateSync()
154
	{
155
		//DoExpressCheckout
156
157
		$params = array(
158
			'token' => 'UT-99999999',
159
			'PayerID' => 'PaypalUnitTestBuyer'
160
		);
161
162
		$request = $this->getMockBuilder( '\Psr\Http\Message\ServerRequestInterface' )->getMock();
163
164
		$request->expects( $this->once() )->method( 'getAttributes' )->will( $this->returnValue( [] ) );
165
		$request->expects( $this->once() )->method( 'getParsedBody' )->will( $this->returnValue( [] ) );
166
		$request->expects( $this->once() )->method( 'getQueryParams' )->will( $this->returnValue( $params ) );
167
168
		$this->object->expects( $this->once() )->method( 'send' )->will(
169
			$this->returnValue( '&TOKEN=UT-99999999&CORRELATIONID=1234567890&ACK=Success&VERSION=87.0&BUILD=3136725&PAYERID=PaypalUnitTestBuyer&TRANSACTIONID=111111110&PAYMENTSTATUS=Pending&PENDINGREASON=authorization&INVNUM=' . $this->order->getId() )
170
		);
171
172
		$result = $this->object->updateSync( $request, $this->order );
173
174
		$this->assertInstanceOf( '\\Aimeos\\MShop\\Order\\Item\\Iface', $result );
175
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_AUTHORIZED, $result->getPaymentStatus() );
176
	}
177
178
179
	public function testUpdatePush()
180
	{
181
		//IPN Call
182
		$orderManager = \Aimeos\MShop\Order\Manager\Factory::createManager( $this->context );
183
		$orderBaseManager = $orderManager->getSubManager( 'base' );
184
185
		$price = $orderBaseManager->getItem( $this->order->getBaseId() )->getPrice();
186
		$amount = $price->getValue() + $price->getCosts();
187
188
		$params = array(
189
			'residence_country' => 'US',
190
			'receiver_email' => '[email protected]',
191
			'address_city' => 'San+Jose',
192
			'first_name' => 'John',
193
			'payment_status' => 'Completed',
194
			'invoice' => $this->order->getId(),
195
			'txn_id' => '111111111',
196
			'payment_amount' => $amount
197
		);
198
		$testData = array(
199
			'TRANSACTIONID' => '111111111',
200
			'111111110' => 'Pending',
201
			'111111111' => 'Completed'
202
		);
203
204
		$request = $this->getMockBuilder( '\Psr\Http\Message\ServerRequestInterface' )->getMock();
205
		$response = $this->getMockBuilder( '\Psr\Http\Message\ResponseInterface' )->getMock();
206
207
		$request->expects( $this->once() )->method( 'getQueryParams' )->will( $this->returnValue( $params ) );
208
		$response->expects( $this->once() )->method( 'withStatus' )
209
			->will( $this->returnValue( $response ) )
210
			->with( $this->equalTo( 200 ) );
211
212
		$cmpFcn = function( $subject ) {
213
			return $subject->getPaymentStatus() === \Aimeos\MShop\Order\Item\Base::PAY_RECEIVED;
214
		};
215
216
		$this->orderMock->expects( $this->once() )->method( 'saveItem' )->with( $this->callback( $cmpFcn ) );
217
		$this->object->expects( $this->once() )->method( 'send' )->will( $this->returnValue( 'VERIFIED' ) );
218
219
		$result = $this->object->updatePush( $request, $response );
220
		$this->assertInstanceOf( '\Psr\Http\Message\ResponseInterface', $result );
221
222
		$refOrderBase = $orderBaseManager->load( $this->order->getBaseId(), \Aimeos\MShop\Order\Item\Base\Base::PARTS_SERVICE );
223
		$attributes = $refOrderBase->getService( 'payment', 'paypalexpress' )->getAttributeItems();
224
		$attrManager = $orderBaseManager->getSubManager( 'service' )->getSubManager( 'attribute' );
225
226
		$attributeList = [];
227
		foreach( $attributes as $attribute ) {
228
			//remove attr where txn ids as keys, because next test with same txn id would fail
229
			if( $attribute->getCode() === '111111110' || $attribute->getCode() === '111111111' ) {
230
				$attrManager->deleteItem( $attribute->getId() );
231
			}
232
233
			$attributeList[$attribute->getCode()] = $attribute;
234
		}
235
236
		foreach( $testData as $key => $value ) {
237
			$this->assertEquals( $attributeList[$key]->getValue(), $testData[$key] );
238
		}
239
	}
240
241
242
	public function testRefund()
243
	{
244
		$this->object->expects( $this->once() )->method( 'send' )->will(
245
			$this->returnValue( 'REFUNDTRANSACTIONID=88888888&FEEREFUNDAMT=2.00&TOTALREFUNDAMT=24.00&CURRENCYCODE=EUR&REFUNDSTATUS=delayed&PENDINGREASON=echeck&CORRELATIONID=1234567890&ACK=Success&VERSION=87.0&BUILD=3136725' )
246
		);
247
248
		$this->object->refund( $this->order );
249
250
		$testData = array(
251
			'TOKEN' => 'UT-99999999',
252
			'TRANSACTIONID' => '111111111',
253
			'REFUNDTRANSACTIONID' => '88888888'
254
		);
255
256
		$orderManager = \Aimeos\MShop\Order\Manager\Factory::createManager( $this->context );
257
		$orderBaseManager = $orderManager->getSubManager( 'base' );
258
259
		$refOrderBase = $orderBaseManager->load( $this->order->getBaseId() );
260
		$attributes = $refOrderBase->getService( 'payment', 'paypalexpress' )->getAttributeItems();
261
262
		$attributeList = [];
263
		foreach( $attributes as $attribute ) {
264
			$attributeList[$attribute->getCode()] = $attribute;
265
		}
266
267
		foreach( $testData as $key => $value ) {
268
			$this->assertEquals( $attributeList[$key]->getValue(), $testData[$key] );
269
		}
270
271
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_REFUND, $this->order->getPaymentStatus() );
272
	}
273
274
275
	public function testCapture()
276
	{
277
		$orderManager = \Aimeos\MShop\Order\Manager\Factory::createManager( $this->context );
278
		$orderBaseManager = $orderManager->getSubManager( 'base' );
279
		$baseItem = $orderBaseManager->getItem( $this->order->getBaseId() );
0 ignored issues
show
The assignment to $baseItem is dead and can be removed.
Loading history...
280
281
		$this->object->expects( $this->once() )->method( 'send' )->will(
282
			$this->returnValue( 'AUTHORIZATIONID=112233&TRANSACTIONID=111111111&PARENTTRANSACTIONID=12212AD&TRANSACTIONTYPE=express-checkout&AMT=22.30&FEEAMT=3.33&PAYMENTSTATUS=Completed&PENDINGREASON=None&CORRELATIONID=1234567890&ACK=Success&VERSION=87.0&BUILD=3136725' )
283
		);
284
285
		$this->object->capture( $this->order );
286
287
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_RECEIVED, $this->order->getPaymentStatus() );
288
	}
289
290
291
	public function testQueryPaymentReceived()
292
	{
293
		$this->object->expects( $this->once() )->method( 'send' )->will(
294
			$this->returnValue( 'SHIPPINGCALCULATIONMODE=Callback&INSURANCEOPTIONSELECTED=false&RECEIVERID=unit_1340199666_biz_api1.yahoo.de&PAYERID=unittest&PAYERSTATUS=verified&COUNTRYCODE=DE&FIRSTNAME=Unit&LASTNAME=Test&SHIPTOSTREET=Unitteststr. 11&TRANSACTIONID=111111111&PARENTTRANSACTIONID=111111111&TRANSACTIONTYPE=express-checkout&AMT=22.50CURRENCYCODE=EUR&FEEAMT=4.44&PAYMENTSTATUS=Completed&PENDINGREASON=None&INVNUM=34&CORRELATIONID=1f4b8e2c86ead&ACK=Success&VERSION=87.0&BUILD=3136725' )
295
		);
296
297
		$this->object->query( $this->order );
298
299
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_RECEIVED, $this->order->getPaymentStatus() );
300
	}
301
302
303
	public function testQueryPaymentRefused()
304
	{
305
		$this->object->expects( $this->once() )->method( 'send' )->will(
306
			$this->returnValue( 'SHIPPINGCALCULATIONMODE=Callback&INSURANCEOPTIONSELECTED=false&RECEIVERID=unit_1340199666_biz_api1.yahoo.de&PAYERID=unittest&PAYERSTATUS=verified&COUNTRYCODE=DE&FIRSTNAME=Unit&LASTNAME=Test&SHIPTOSTREET=Unitteststr. 11&TRANSACTIONID=111111111&PARENTTRANSACTIONID=111111111&TRANSACTIONTYPE=express-checkout&AMT=22.50CURRENCYCODE=EUR&FEEAMT=4.44&PAYMENTSTATUS=Expired&PENDINGREASON=None&INVNUM=34&CORRELATIONID=1f4b8e2c86ead&ACK=Success&VERSION=87.0&BUILD=3136725' )
307
		);
308
309
		$this->object->query( $this->order );
310
311
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_REFUSED, $this->order->getPaymentStatus() );
312
	}
313
314
315
	public function testCancel()
316
	{
317
		$this->object->expects( $this->once() )->method( 'send' )->will(
318
			$this->returnValue( 'CORRELATIONID=1234567890&ACK=Success&VERSION=87.0&BUILD=3136725' )
319
		);
320
321
		$this->object->cancel( $this->order );
322
323
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_CANCELED, $this->order->getPaymentStatus() );
324
	}
325
326
327
	public function testQueryPaymentAuthorized()
328
	{
329
		$this->object->expects( $this->once() )->method( 'send' )->will(
330
			$this->returnValue( 'SHIPPINGCALCULATIONMODE=Callback&INSURANCEOPTIONSELECTED=false&RECEIVERID=unit_1340199666_biz_api1.yahoo.de&PAYERID=unittest&PAYERSTATUS=verified&COUNTRYCODE=DE&FIRSTNAME=Unit&LASTNAME=Test&SHIPTOSTREET=Unitteststr. 11&TRANSACTIONID=111111111&PARENTTRANSACTIONID=111111111&TRANSACTIONTYPE=express-checkout&AMT=22.50CURRENCYCODE=EUR&FEEAMT=4.44&PAYMENTSTATUS=Pending&PENDINGREASON=authorization&INVNUM=34&CORRELATIONID=1234567890&ACK=Success&VERSION=87.0&BUILD=3136725' )
331
		);
332
333
		$this->object->query( $this->order );
334
335
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_AUTHORIZED, $this->order->getPaymentStatus() );
336
	}
337
338
339
	public function testWrongAuthorization()
340
	{
341
		$this->object->expects( $this->once() )->method( 'send' )->will(
342
			$this->returnValue( '&ACK=Error&VERSION=87.0&BUILD=3136725&CORRELATIONID=1234567890&L_ERRORCODE0=0000&L_SHORTMESSAGE0=wrong authorization test method error' )
343
		);
344
345
		$this->setExpectedException( '\\Aimeos\\MShop\\Service\\Exception' );
346
		$this->object->process( $this->order );
347
	}
348
349
350
	public function testSetPaymentStatusNone()
351
	{
352
		$class = new \ReflectionClass( '\Aimeos\MShop\Service\Provider\Payment\PayPalExpress' );
353
		$method = $class->getMethod( 'setPaymentStatus' );
354
		$method->setAccessible( true );
355
356
		$method->invokeArgs( $this->object, array( $this->order, [] ) );
357
358
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_AUTHORIZED, $this->order->getPaymentStatus() );
359
	}
360
361
362
	public function testSetPaymentPending()
363
	{
364
		$class = new \ReflectionClass( '\Aimeos\MShop\Service\Provider\Payment\PayPalExpress' );
365
		$method = $class->getMethod( 'setPaymentStatus' );
366
		$method->setAccessible( true );
367
368
		$method->invokeArgs( $this->object, array( $this->order, array( 'PAYMENTSTATUS' => 'Pending', 'PENDINGREASON' => 'error' ) ) );
369
370
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_PENDING, $this->order->getPaymentStatus() );
371
	}
372
373
374
	public function testSetPaymentRefunded()
375
	{
376
		$class = new \ReflectionClass( '\Aimeos\MShop\Service\Provider\Payment\PayPalExpress' );
377
		$method = $class->getMethod( 'setPaymentStatus' );
378
		$method->setAccessible( true );
379
380
		$method->invokeArgs( $this->object, array( $this->order, array( 'PAYMENTSTATUS' => 'Refunded' ) ) );
381
382
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_REFUND, $this->order->getPaymentStatus() );
383
	}
384
385
386
	public function testSetPaymentCanceled()
387
	{
388
		$class = new \ReflectionClass( '\Aimeos\MShop\Service\Provider\Payment\PayPalExpress' );
389
		$method = $class->getMethod( 'setPaymentStatus' );
390
		$method->setAccessible( true );
391
392
		$method->invokeArgs( $this->object, array( $this->order, array( 'PAYMENTSTATUS' => 'Voided' ) ) );
393
394
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_CANCELED, $this->order->getPaymentStatus() );
395
	}
396
397
398
	public function testSetPaymentInvalid()
399
	{
400
		$class = new \ReflectionClass( '\Aimeos\MShop\Service\Provider\Payment\PayPalExpress' );
401
		$method = $class->getMethod( 'setPaymentStatus' );
402
		$method->setAccessible( true );
403
404
		$method->invokeArgs( $this->object, array( $this->order, array( 'PAYMENTSTATUS' => 'Invalid' ) ) );
405
406
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_AUTHORIZED, $this->order->getPaymentStatus() );
407
	}
408
}
409