Passed
Push — master ( 4ee10f...74775e )
by Aimeos
04:12
created

PayPalExpressTest::testCheckConfigBE()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 13
c 1
b 0
f 0
dl 0
loc 18
rs 9.8333
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2012
6
 * @copyright Aimeos (aimeos.org), 2015-2022
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() : void
23
	{
24
		\Aimeos\MShop::cache( true );
25
26
		$this->context = \TestHelper::context();
27
		$serviceManager = \Aimeos\MShop::create( $this->context, 'service' );
28
29
		$search = $serviceManager->filter()->add( ['service.code' => 'paypalexpress'] );
30
		$this->serviceItem = $serviceManager->search( $search )->first( new \RuntimeException( 'No service item available' ) );
31
32
		$this->object = $this->getMockBuilder( \Aimeos\MShop\Service\Provider\Payment\PayPalExpress::class )
33
			->setConstructorArgs( [$this->context, $this->serviceItem] )
34
			->setMethods( ['send'] )
35
			->getMock();
36
37
38
		$orderManager = \Aimeos\MShop::create( $this->context, 'order' );
39
40
		$search = $orderManager->filter()->add( [
41
			'order.channel' => 'web',
42
			'order.statuspayment' => \Aimeos\MShop\Order\Item\Base::PAY_AUTHORIZED
43
		] );
44
		$ref = ['order/base', 'order/base/address', 'order/base/coupon', 'order/base/product', 'order/base/service'];
45
		$this->order = $orderManager->search( $search, $ref )->first( new \RuntimeException( 'No order found' ) );
46
47
		$attr = \Aimeos\MShop::create( $this->context, 'order/base/service' )->createAttributeItem();
48
		$attr->setType( 'payment/paypal' )->setCode( 'TRANSACTIONID' )->setValue( '111111111' );
49
		$this->order->getBaseItem()->getService( 'payment', 0 )->setAttributeItem( $attr );
50
51
52
		$this->orderMock = $this->getMockBuilder( \Aimeos\MShop\Order\Manager\Standard::class )
53
			->setConstructorArgs( array( $this->context ) )
54
			->setMethods( array( 'save' ) )
55
			->getMock();
56
57
		$this->orderMock->expects( $this->any() )->method( 'save' )->will( $this->returnArgument( 0 ) );
58
59
		\Aimeos\MShop::inject( \Aimeos\MShop\Order\Manager\Standard::class, $this->orderMock );
60
	}
61
62
63
	protected function tearDown() : void
64
	{
65
		\Aimeos\MShop::cache( false );
66
		unset( $this->object, $this->serviceItem, $this->order );
67
	}
68
69
70
	public function testGetConfigBE()
71
	{
72
		$result = $this->object->getConfigBE();
73
74
		$this->assertEquals( 16, count( $result ) );
75
76
		foreach( $result as $key => $item ) {
77
			$this->assertInstanceOf( 'Aimeos\Base\Criteria\Attribute\Iface', $item );
78
		}
79
	}
80
81
82
	public function testCheckConfigBE()
83
	{
84
		$attributes = array(
85
			'paypalexpress.ApiUsername' => 'user',
86
			'paypalexpress.AccountEmail' => '[email protected]',
87
			'paypalexpress.ApiPassword' => 'pw',
88
			'paypalexpress.ApiSignature' => '1df23eh67',
89
			'payment.url-cancel' => 'http://cancelUrl',
90
			'payment.url-success' => 'http://returnUrl'
91
		);
92
93
		$result = $this->object->checkConfigBE( $attributes );
94
95
		$this->assertEquals( 16, count( $result ) );
96
		$this->assertEquals( null, $result['paypalexpress.ApiUsername'] );
97
		$this->assertEquals( null, $result['paypalexpress.AccountEmail'] );
98
		$this->assertEquals( null, $result['paypalexpress.ApiPassword'] );
99
		$this->assertEquals( null, $result['paypalexpress.ApiSignature'] );
100
	}
101
102
103
	public function testIsImplemented()
104
	{
105
		$this->assertTrue( $this->object->isImplemented( \Aimeos\MShop\Service\Provider\Payment\Base::FEAT_CANCEL ) );
106
		$this->assertTrue( $this->object->isImplemented( \Aimeos\MShop\Service\Provider\Payment\Base::FEAT_CAPTURE ) );
107
		$this->assertTrue( $this->object->isImplemented( \Aimeos\MShop\Service\Provider\Payment\Base::FEAT_QUERY ) );
108
		$this->assertTrue( $this->object->isImplemented( \Aimeos\MShop\Service\Provider\Payment\Base::FEAT_REFUND ) );
109
110
		$this->assertFalse( $this->object->isImplemented( -1 ) );
111
	}
112
113
114
	public function testProcess()
115
	{
116
		$this->object->expects( $this->once() )->method( 'send' )->will(
117
			$this->returnValue( '&ACK=Success&VERSION=87.0&BUILD=3136725&CORRELATIONID=1234567890&TOKEN=UT-99999999' )
118
		);
119
120
		$helperForm = $this->object->process( $this->order );
121
122
		$this->assertInstanceOf( \Aimeos\MShop\Common\Helper\Form\Iface::class, $helperForm );
123
		$this->assertEquals( 'https://www.sandbox.paypal.com/webscr&cmd=_express-checkout&useraction=commit&token=UT-99999999', $helperForm->getUrl() );
124
		$this->assertEquals( 'POST', $helperForm->getMethod() );
125
		$this->assertEquals( [], $helperForm->getValues() );
126
127
		$attrs = [];
128
		foreach( $this->order->getBaseItem()->getService( 'payment', 0 )->getAttributeItems() as $attrItem ) {
129
			$attrs[$attrItem->getCode()] = $attrItem->getValue();
130
		}
131
132
		$this->assertEquals( 'UT-99999999', $attrs['TOKEN'] );
133
		$this->assertEquals( '111111111', $attrs['TRANSACTIONID'] );
134
	}
135
136
137
	public function testUpdateSync()
138
	{
139
		//DoExpressCheckout
140
141
		$params = array(
142
			'token' => 'UT-99999999',
143
			'PayerID' => 'PaypalUnitTestBuyer'
144
		);
145
146
		$request = $this->getMockBuilder( \Psr\Http\Message\ServerRequestInterface::class )->getMock();
147
148
		$request->expects( $this->once() )->method( 'getAttributes' )->will( $this->returnValue( [] ) );
149
		$request->expects( $this->once() )->method( 'getParsedBody' )->will( $this->returnValue( [] ) );
150
		$request->expects( $this->once() )->method( 'getQueryParams' )->will( $this->returnValue( $params ) );
151
152
		$this->object->expects( $this->once() )->method( 'send' )->will(
153
			$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() )
154
		);
155
156
		$result = $this->object->updateSync( $request, $this->order );
157
158
		$this->assertInstanceOf( \Aimeos\MShop\Order\Item\Iface::class, $result );
159
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_AUTHORIZED, $result->getStatusPayment() );
160
	}
161
162
163
	public function testUpdatePush()
164
	{
165
		//IPN Call
166
		$orderManager = \Aimeos\MShop::create( $this->context, 'order' );
167
		$orderBaseManager = $orderManager->getSubManager( 'base' );
168
169
		$price = $orderBaseManager->get( $this->order->getBaseId() )->getPrice();
170
		$amount = $price->getValue() + $price->getCosts();
171
172
		$params = array(
173
			'residence_country' => 'US',
174
			'receiver_email' => '[email protected]',
175
			'address_city' => 'San+Jose',
176
			'first_name' => 'John',
177
			'payment_status' => 'Completed',
178
			'invoice' => $this->order->getId(),
179
			'txn_id' => '111111111',
180
			'payment_amount' => $amount
181
		);
182
		$testData = array(
0 ignored issues
show
Unused Code introduced by
The assignment to $testData is dead and can be removed.
Loading history...
183
			'TRANSACTIONID' => '111111111',
184
			'111111110' => 'Pending',
185
			'111111111' => 'Completed'
186
		);
187
188
		$request = $this->getMockBuilder( \Psr\Http\Message\ServerRequestInterface::class )->getMock();
189
		$response = $this->getMockBuilder( \Psr\Http\Message\ResponseInterface::class )->getMock();
190
191
		$request->expects( $this->once() )->method( 'getQueryParams' )->will( $this->returnValue( $params ) );
192
		$response->expects( $this->once() )->method( 'withStatus' )
193
			->will( $this->returnValue( $response ) )
194
			->with( $this->equalTo( 200 ) );
195
196
		$cmpFcn = function( $subject ) {
197
			$attrs = $subject->getBaseItem()->getService( 'payment', 0 )->getAttributeItems();
198
			$attrs = $attrs->col( 'order.base.service.attribute.value', 'order.base.service.attribute.code' );
199
			return $subject->getStatusPayment() === \Aimeos\MShop\Order\Item\Base::PAY_RECEIVED
200
				&& $attrs['TRANSACTIONID'] === '111111111'
201
				&& $attrs['111111111'] === 'Completed';
202
		};
203
204
		$this->orderMock->expects( $this->once() )->method( 'save' )->with( $this->callback( $cmpFcn ) );
205
		$this->object->expects( $this->once() )->method( 'send' )->will( $this->returnValue( 'VERIFIED' ) );
206
207
		$result = $this->object->updatePush( $request, $response );
208
		$this->assertInstanceOf( \Psr\Http\Message\ResponseInterface::class, $result );
209
	}
210
211
212
	public function testRefund()
213
	{
214
		$this->object->expects( $this->once() )->method( 'send' )->will(
215
			$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' )
216
		);
217
218
		$this->object->refund( $this->order );
219
220
		$testData = array(
221
			'TRANSACTIONID' => '111111111',
222
			'REFUNDTRANSACTIONID' => '88888888'
223
		);
224
225
		$attributes = $this->order->getBaseItem()->getService( 'payment', 0 )->getAttributeItems();
226
227
		$attributeList = [];
228
		foreach( $attributes as $attribute ) {
229
			$attributeList[$attribute->getCode()] = $attribute;
230
		}
231
232
		foreach( $testData as $key => $value ) {
233
			$this->assertEquals( $attributeList[$key]->getValue(), $testData[$key] );
234
		}
235
236
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_REFUND, $this->order->getStatusPayment() );
237
	}
238
239
240
	public function testCapture()
241
	{
242
		$this->object->expects( $this->once() )->method( 'send' )->will(
243
			$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' )
244
		);
245
246
		$this->object->capture( $this->order );
247
248
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_RECEIVED, $this->order->getStatusPayment() );
249
	}
250
251
252
	public function testQueryPaymentReceived()
253
	{
254
		$this->object->expects( $this->once() )->method( 'send' )->will(
255
			$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' )
256
		);
257
258
		$this->object->query( $this->order );
259
260
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_RECEIVED, $this->order->getStatusPayment() );
261
	}
262
263
264
	public function testQueryPaymentRefused()
265
	{
266
		$this->object->expects( $this->once() )->method( 'send' )->will(
267
			$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' )
268
		);
269
270
		$this->object->query( $this->order );
271
272
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_REFUSED, $this->order->getStatusPayment() );
273
	}
274
275
276
	public function testCancel()
277
	{
278
		$this->object->expects( $this->once() )->method( 'send' )->will(
279
			$this->returnValue( 'CORRELATIONID=1234567890&ACK=Success&VERSION=87.0&BUILD=3136725' )
280
		);
281
282
		$this->object->cancel( $this->order );
283
284
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_CANCELED, $this->order->getStatusPayment() );
285
	}
286
287
288
	public function testQueryPaymentAuthorized()
289
	{
290
		$this->object->expects( $this->once() )->method( 'send' )->will(
291
			$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' )
292
		);
293
294
		$this->object->query( $this->order );
295
296
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_AUTHORIZED, $this->order->getStatusPayment() );
297
	}
298
299
300
	public function testWrongAuthorization()
301
	{
302
		$this->object->expects( $this->once() )->method( 'send' )->will(
303
			$this->returnValue( '&ACK=Error&VERSION=87.0&BUILD=3136725&CORRELATIONID=1234567890&L_ERRORCODE0=0000&L_SHORTMESSAGE0=wrong authorization test method error' )
304
		);
305
306
		$this->expectException( \Aimeos\MShop\Service\Exception::class );
307
		$this->object->process( $this->order );
308
	}
309
310
311
	public function testSetPaymentStatusNone()
312
	{
313
		$class = new \ReflectionClass( \Aimeos\MShop\Service\Provider\Payment\PayPalExpress::class );
314
		$method = $class->getMethod( 'setStatusPayment' );
315
		$method->setAccessible( true );
316
317
		$method->invokeArgs( $this->object, array( $this->order, [] ) );
318
319
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_AUTHORIZED, $this->order->getStatusPayment() );
320
	}
321
322
323
	public function testSetPaymentPending()
324
	{
325
		$class = new \ReflectionClass( \Aimeos\MShop\Service\Provider\Payment\PayPalExpress::class );
326
		$method = $class->getMethod( 'setStatusPayment' );
327
		$method->setAccessible( true );
328
329
		$method->invokeArgs( $this->object, array( $this->order, array( 'PAYMENTSTATUS' => 'Pending', 'PENDINGREASON' => 'error' ) ) );
330
331
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_PENDING, $this->order->getStatusPayment() );
332
	}
333
334
335
	public function testSetPaymentRefunded()
336
	{
337
		$class = new \ReflectionClass( \Aimeos\MShop\Service\Provider\Payment\PayPalExpress::class );
338
		$method = $class->getMethod( 'setStatusPayment' );
339
		$method->setAccessible( true );
340
341
		$method->invokeArgs( $this->object, array( $this->order, array( 'PAYMENTSTATUS' => 'Refunded' ) ) );
342
343
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_REFUND, $this->order->getStatusPayment() );
344
	}
345
346
347
	public function testSetPaymentCanceled()
348
	{
349
		$class = new \ReflectionClass( \Aimeos\MShop\Service\Provider\Payment\PayPalExpress::class );
350
		$method = $class->getMethod( 'setStatusPayment' );
351
		$method->setAccessible( true );
352
353
		$method->invokeArgs( $this->object, array( $this->order, array( 'PAYMENTSTATUS' => 'Voided' ) ) );
354
355
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_CANCELED, $this->order->getStatusPayment() );
356
	}
357
358
359
	public function testSetPaymentInvalid()
360
	{
361
		$class = new \ReflectionClass( \Aimeos\MShop\Service\Provider\Payment\PayPalExpress::class );
362
		$method = $class->getMethod( 'setStatusPayment' );
363
		$method->setAccessible( true );
364
365
		$method->invokeArgs( $this->object, array( $this->order, array( 'PAYMENTSTATUS' => 'Invalid' ) ) );
366
367
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_AUTHORIZED, $this->order->getStatusPayment() );
368
	}
369
}
370