Issues (3877)

Zed/Payment/Business/Facade/PaymentFacadeTest.php (5 issues)

1
<?php
2
3
/**
4
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace SprykerTest\Zed\Payment\Business\Facade;
9
10
use Codeception\Test\Unit;
11
use DateTime;
12
use DateTimeZone;
13
use Generated\Shared\DataBuilder\CheckoutResponseBuilder;
14
use Generated\Shared\DataBuilder\PaymentMethodBuilder;
15
use Generated\Shared\DataBuilder\PaymentProviderBuilder;
16
use Generated\Shared\DataBuilder\QuoteBuilder;
17
use Generated\Shared\DataBuilder\StoreRelationBuilder;
18
use Generated\Shared\Transfer\AddPaymentMethodTransfer;
19
use Generated\Shared\Transfer\CheckoutResponseTransfer;
20
use Generated\Shared\Transfer\DeletePaymentMethodTransfer;
21
use Generated\Shared\Transfer\MessageAttributesTransfer;
22
use Generated\Shared\Transfer\PaymentAuthorizeRequestTransfer;
23
use Generated\Shared\Transfer\PaymentAuthorizeResponseTransfer;
24
use Generated\Shared\Transfer\PaymentMethodsTransfer;
25
use Generated\Shared\Transfer\PaymentMethodTransfer;
26
use Generated\Shared\Transfer\PaymentProviderTransfer;
27
use Generated\Shared\Transfer\PaymentTransfer;
28
use Generated\Shared\Transfer\QuoteTransfer;
29
use Generated\Shared\Transfer\StoreRelationTransfer;
30
use Generated\Shared\Transfer\StoreTransfer;
31
use Orm\Zed\Payment\Persistence\SpyPaymentMethodQuery;
32
use Orm\Zed\Payment\Persistence\SpyPaymentMethodStoreQuery;
33
use Ramsey\Uuid\Uuid;
34
use Spryker\Client\Payment\PaymentClientInterface;
35
use Spryker\Zed\Kernel\Container;
36
use Spryker\Zed\Payment\Business\Method\PaymentMethodReader;
37
use Spryker\Zed\Payment\Business\PaymentBusinessFactory;
38
use Spryker\Zed\Payment\Business\PaymentFacade;
39
use Spryker\Zed\Payment\PaymentConfig;
40
use Spryker\Zed\Payment\PaymentDependencyProvider;
41
use SprykerTest\Zed\Payment\PaymentBusinessTester;
42
43
/**
44
 * Auto-generated group annotations
45
 *
46
 * @group SprykerTest
47
 * @group Zed
48
 * @group Payment
49
 * @group Business
50
 * @group Facade
51
 * @group Facade
52
 * @group PaymentFacadeTest
53
 * Add your own group annotations below this line
54
 */
55
class PaymentFacadeTest extends Unit
56
{
57
    /**
58
     * @var string
59
     */
60
    protected const STORE_REFERENCE = 'dev-DE';
61
62
    /**
63
     * @var string
64
     */
65
    protected const STORE_NAME = 'DE';
66
67
    /**
68
     * @var string
69
     */
70
    protected const CHECKOUT_REDIRECT_URL = 'checkout-redirect-url';
71
72
    /**
73
     * @var string
74
     */
75
    protected const PAYMENT_AUTHORIZATION_ENDPOINT = 'http://localhost/authorize';
76
77
    /**
78
     * @var string
79
     */
80
    protected const PAYMENT_AUTHORIZATION_REDIRECT = 'http://localhost/redirect';
81
82
    /**
83
     * @var \SprykerTest\Zed\Payment\PaymentBusinessTester
84
     */
85
    protected PaymentBusinessTester $tester;
86
87
    /**
88
     * @var \Spryker\Zed\Payment\Business\PaymentFacadeInterface|\Spryker\Zed\Kernel\Business\AbstractFacade
89
     */
90
    protected $paymentFacade;
91
92
    /**
93
     * @return void
94
     */
95
    protected function setUp(): void
96
    {
97
        parent::setUp();
98
99
        $this->tester->ensurePaymentProviderTableIsEmpty();
100
101
        $this->paymentFacade = $this->tester->getFacade();
102
        $configMock = $this->createMock(PaymentConfig::class);
103
        $configMock->method('getPaymentStatemachineMappings')->willReturn([]);
104
        $paymentBusinessFactory = new PaymentBusinessFactory();
105
        $paymentBusinessFactory->setConfig($configMock);
106
        $this->paymentFacade->setFactory($paymentBusinessFactory);
0 ignored issues
show
The method setFactory() does not exist on Spryker\Zed\Payment\Busi...\PaymentFacadeInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Spryker\Zed\Payment\Busi...\PaymentFacadeInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

106
        $this->paymentFacade->/** @scrutinizer ignore-call */ 
107
                              setFactory($paymentBusinessFactory);
Loading history...
107
108
        $this->tester->setStoreReferenceData([
109
            'DE' => 'dev-DE',
110
            'AT' => 'dev-AT',
111
        ]);
112
    }
113
114
    /**
115
     * @return void
116
     */
117
    protected function tearDown(): void
118
    {
119
        parent::tearDown();
120
121
        $this->tester->ensurePaymentProviderTableIsEmpty();
122
    }
123
124
    /**
125
     * @return void
126
     */
127
    public function testFindPaymentMethodByIdShouldFindPaymentMethod(): void
128
    {
129
        // Arrange
130
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
131
        $paymentMethodTransfer = $this->tester->havePaymentMethod([
132
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
133
        ]);
134
135
        // Act
136
        $paymentMethodResponseTransfer = $this->paymentFacade->findPaymentMethodById($paymentMethodTransfer->getIdPaymentMethod());
0 ignored issues
show
The method findPaymentMethodById() does not exist on Spryker\Zed\Kernel\Business\AbstractFacade. It seems like you code against a sub-type of Spryker\Zed\Kernel\Business\AbstractFacade such as Spryker\Zed\Payment\Business\PaymentFacade. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

136
        /** @scrutinizer ignore-call */ 
137
        $paymentMethodResponseTransfer = $this->paymentFacade->findPaymentMethodById($paymentMethodTransfer->getIdPaymentMethod());
Loading history...
137
138
        // Assert
139
        $this->assertTrue($paymentMethodResponseTransfer->getIsSuccessful(), 'Payment method should be found');
140
        $this->assertNotNull($paymentMethodResponseTransfer->getPaymentMethod(), 'Payment method should not be empty');
141
    }
142
143
    /**
144
     * @return void
145
     */
146
    public function testFindPaymentMethodByIdWithNotExistingIdShouldNotFindPaymentMethod(): void
147
    {
148
        // Act
149
        $paymentMethodResponseTransfer = $this->paymentFacade->findPaymentMethodById(1);
150
151
        // Assert
152
        $this->assertFalse($paymentMethodResponseTransfer->getIsSuccessful(), 'Payment method should not be found');
153
    }
154
155
    /**
156
     * @return void
157
     */
158
    public function testUpdatePaymentMethodShouldUpdatePaymentMethodWithStoreRelation(): void
159
    {
160
        // Arrange
161
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
162
        $paymentMethodTransfer = $this->tester->havePaymentMethod([
163
            PaymentMethodTransfer::PAYMENT_METHOD_KEY => 'test',
164
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
165
        ]);
166
        $storeTransfer = $this->tester->haveStore([
167
            StoreTransfer::NAME => 'DE',
168
        ]);
169
        $storeRelationTransfer = (new StoreRelationBuilder())->seed([
170
            StoreRelationTransfer::ID_ENTITY => $paymentMethodTransfer->getIdPaymentMethod(),
171
            StoreRelationTransfer::ID_STORES => [
172
                $storeTransfer->getIdStore(),
173
            ],
174
            StoreRelationTransfer::STORES => [
175
                $storeTransfer,
176
            ],
177
        ])->build();
178
        $paymentMethodTransfer->setStoreRelation($storeRelationTransfer);
179
        $paymentMethodTransfer->setPaymentMethodKey('test1');
180
181
        // Act
182
        $this->paymentFacade->updatePaymentMethod($paymentMethodTransfer);
0 ignored issues
show
The method updatePaymentMethod() does not exist on Spryker\Zed\Kernel\Business\AbstractFacade. It seems like you code against a sub-type of Spryker\Zed\Kernel\Business\AbstractFacade such as Spryker\Zed\Payment\Business\PaymentFacade. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

182
        $this->paymentFacade->/** @scrutinizer ignore-call */ 
183
                              updatePaymentMethod($paymentMethodTransfer);
Loading history...
183
184
        // Assert
185
        $resultPaymentMethodEntity = SpyPaymentMethodQuery::create()
186
            ->filterByIdPaymentMethod($paymentMethodTransfer->getIdPaymentMethod())
187
            ->findOne();
188
        $storeRelationExist = SpyPaymentMethodStoreQuery::create()
189
            ->filterByFkPaymentMethod($paymentMethodTransfer->getIdPaymentMethod())
190
            ->exists();
191
        $this->assertSame(
192
            'test1',
193
            $resultPaymentMethodEntity->getPaymentMethodKey(),
194
            'Payment method name should match to the expected value',
195
        );
196
        $this->assertTrue($storeRelationExist, 'Payment method store relation should exists');
197
    }
198
199
    /**
200
     * @return void
201
     */
202
    public function testGetAvailablePaymentMethodsShouldReturnActivePaymentMethod(): void
203
    {
204
        // Arrange
205
        $paymentProviderTransfer = $this->tester->havePaymentProvider([
206
            PaymentProviderTransfer::PAYMENT_PROVIDER_KEY => 'dummyPayment',
207
        ]);
208
        $storeTransfer = $this->tester->haveStore([
209
            StoreTransfer::NAME => 'DE',
210
        ]);
211
        $storeRelationTransfer = (new StoreRelationBuilder())->seed([
212
            StoreRelationTransfer::ID_STORES => [
213
                $storeTransfer->getIdStore(),
214
            ],
215
            StoreRelationTransfer::STORES => [
216
                $storeTransfer,
217
            ],
218
        ])->build();
219
        $this->tester->havePaymentMethod([
220
            PaymentMethodTransfer::IS_ACTIVE => true,
221
            PaymentMethodTransfer::PAYMENT_METHOD_KEY => 'dummyPaymentInvoice',
222
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
223
            PaymentMethodTransfer::STORE_RELATION => $storeRelationTransfer,
224
        ]);
225
        $this->tester->havePaymentMethod([
226
            PaymentMethodTransfer::IS_ACTIVE => false,
227
            PaymentMethodTransfer::PAYMENT_METHOD_KEY => 'dummyPaymentCreditCard',
228
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
229
        ]);
230
        $quoteTransfer = (new QuoteBuilder())->withStore([
231
            StoreTransfer::NAME => $storeTransfer->getName(),
232
        ])->build();
233
234
        // Act
235
        $paymentMethodsTransfer = $this->paymentFacade->getAvailableMethods($quoteTransfer);
0 ignored issues
show
The method getAvailableMethods() does not exist on Spryker\Zed\Kernel\Business\AbstractFacade. It seems like you code against a sub-type of Spryker\Zed\Kernel\Business\AbstractFacade such as Spryker\Zed\Payment\Business\PaymentFacade. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

235
        /** @scrutinizer ignore-call */ 
236
        $paymentMethodsTransfer = $this->paymentFacade->getAvailableMethods($quoteTransfer);
Loading history...
236
237
        // Assert
238
        $this->assertCount(
239
            1,
240
            $paymentMethodsTransfer->getMethods(),
241
            'Amount of found payment method does not match to the expected value',
242
        );
243
    }
244
245
    /**
246
     * @return void
247
     */
248
    public function testGetAvailablePaymentMethodsShouldCollectPersistentAndInfrastructuralPaymentMethods(): void
249
    {
250
        $paymentProviderTransfer = $this->tester->havePaymentProvider([
251
            PaymentProviderTransfer::PAYMENT_PROVIDER_KEY => 'dummyPayment',
252
        ]);
253
        $storeTransfer = $this->tester->haveStore([
254
            StoreTransfer::NAME => 'DE',
255
        ]);
256
        $storeRelationTransfer = (new StoreRelationBuilder())->seed([
257
            StoreRelationTransfer::ID_STORES => [
258
                $storeTransfer->getIdStore(),
259
            ],
260
            StoreRelationTransfer::STORES => [
261
                $storeTransfer,
262
            ],
263
        ])->build();
264
        $this->tester->havePaymentMethod([
265
            PaymentMethodTransfer::IS_ACTIVE => true,
266
            PaymentMethodTransfer::PAYMENT_METHOD_KEY => 'dummyPaymentInvoice',
267
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
268
            PaymentMethodTransfer::STORE_RELATION => $storeRelationTransfer,
269
        ]);
270
        $this->tester->havePaymentMethod([
271
            PaymentMethodTransfer::IS_ACTIVE => false,
272
            PaymentMethodTransfer::PAYMENT_METHOD_KEY => 'dummyPaymentCreditCard',
273
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
274
            PaymentMethodTransfer::STORE_RELATION => $storeRelationTransfer,
275
        ]);
276
        $this->tester->havePaymentMethod([
277
            PaymentMethodTransfer::IS_ACTIVE => true,
278
            PaymentMethodTransfer::PAYMENT_METHOD_KEY => 'dummyPaymentTest',
279
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
280
            PaymentMethodTransfer::STORE_RELATION => null,
281
        ]);
282
        $configMock = $this->createMock(PaymentConfig::class);
283
        $configMock->method('getPaymentStatemachineMappings')->willReturn([
284
            'dummyPaymentInvoice' => 'statemachine1',
285
            'dummyPaymentCreditCard' => 'statemachine2',
286
            'dummyPaymentTest' => 'statemachine3',
287
            'not_in_db' => 'statemachine4',
288
        ]);
289
290
        $factory = new PaymentBusinessFactory();
291
        $factory->setConfig($configMock);
292
        $this->paymentFacade->setFactory($factory);
293
        $quoteTransfer = (new QuoteBuilder())->withStore([
294
            StoreTransfer::NAME => $storeTransfer->getName(),
295
        ])->build();
296
297
        // Act
298
        $paymentMethodsTransfer = $this->paymentFacade->getAvailableMethods($quoteTransfer);
299
300
        $this->assertCount(
301
            2,
302
            $paymentMethodsTransfer->getMethods(),
303
            'Amount of found payment method does not match to the expected value',
304
        );
305
    }
306
307
    /**
308
     * @return void
309
     */
310
    public function testGetAvailablePaymentProvidersForStoreShouldReturnActivePaymentProviderForGivenStore(): void
311
    {
312
        // Arrange
313
        $storeTransfer = $this->tester->haveStore([
314
            StoreTransfer::NAME => 'DE',
315
        ]);
316
        $storeRelationTransfer = (new StoreRelationBuilder())->seed([
317
            StoreRelationTransfer::ID_STORES => [$storeTransfer->getIdStore()],
318
        ])->build();
319
        $paymentProviderOne = $this->tester->havePaymentProvider();
320
        $paymentProviderTwo = $this->tester->havePaymentProvider();
321
        $this->tester->havePaymentMethod([
322
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderOne->getIdPaymentProvider(),
323
            PaymentMethodTransfer::IS_ACTIVE => true,
324
            PaymentMethodTransfer::STORE_RELATION => $storeRelationTransfer,
325
            PaymentMethodTransfer::NAME => 'test1',
326
        ]);
327
        $this->tester->havePaymentMethod([
328
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderOne->getIdPaymentProvider(),
329
            PaymentMethodTransfer::IS_ACTIVE => false,
330
            PaymentMethodTransfer::STORE_RELATION => $storeRelationTransfer,
331
            PaymentMethodTransfer::NAME => 'test2',
332
        ]);
333
        $this->tester->havePaymentMethod([
334
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderOne->getIdPaymentProvider(),
335
            PaymentMethodTransfer::IS_ACTIVE => true,
336
            PaymentMethodTransfer::STORE_RELATION => null,
337
            PaymentMethodTransfer::NAME => 'test3',
338
        ]);
339
        $this->tester->havePaymentMethod([
340
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTwo->getIdPaymentProvider(),
341
            PaymentMethodTransfer::IS_ACTIVE => true,
342
            PaymentMethodTransfer::NAME => 'test4',
343
        ]);
344
345
        // Act
346
        $paymentProviderCollectionTransfer = $this->paymentFacade->getAvailablePaymentProvidersForStore('DE');
0 ignored issues
show
The method getAvailablePaymentProvidersForStore() does not exist on Spryker\Zed\Kernel\Business\AbstractFacade. It seems like you code against a sub-type of Spryker\Zed\Kernel\Business\AbstractFacade such as Spryker\Zed\Payment\Business\PaymentFacade. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

346
        /** @scrutinizer ignore-call */ 
347
        $paymentProviderCollectionTransfer = $this->paymentFacade->getAvailablePaymentProvidersForStore('DE');
Loading history...
347
348
        // Assert
349
        $this->assertCount(
350
            1,
351
            $paymentProviderCollectionTransfer->getPaymentProviders(),
352
            'Amount of payment providers does not match the expected value',
353
        );
354
        $paymentMethods = $paymentProviderCollectionTransfer->getPaymentProviders()[0]->getPaymentMethods();
355
        $this->assertCount(
356
            1,
357
            $paymentMethods,
358
            'Amount of payment methods does not match the expected value',
359
        );
360
    }
361
362
    /**
363
     * @return void
364
     */
365
    public function testIsQuotePaymentMethodValidShouldReturnTrueIfPaymentExists(): void
366
    {
367
        // Arrange
368
        $quoteTransfer = (new QuoteBuilder())
369
            ->withPayment(['payment_selection' => 'dummyPaymentInvoice'])
370
            ->build();
371
        $checkoutResponseTransfer = (new CheckoutResponseBuilder())->build();
372
        $this->mockPaymentMethodReader();
373
374
        // Act
375
        $isPaymentMethodExists = $this->paymentFacade->isQuotePaymentMethodValid($quoteTransfer, $checkoutResponseTransfer);
376
377
        // Assert
378
        $this->assertTrue($isPaymentMethodExists);
379
    }
380
381
    /**
382
     * @return void
383
     */
384
    public function testIsQuotePaymentMethodValidShouldReturnFalseIfPaymentNotExists(): void
385
    {
386
        // Arrange
387
        $quoteTransfer = (new QuoteBuilder())
388
            ->withPayment(['payment_selection' => 'NotExists'])
389
            ->build();
390
        $checkoutResponseTransfer = (new CheckoutResponseBuilder())->build();
391
        $this->mockPaymentMethodReader();
392
393
        // Act
394
        $isPaymentMethodExists = $this->paymentFacade->isQuotePaymentMethodValid($quoteTransfer, $checkoutResponseTransfer);
395
396
        // Assert
397
        $this->assertFalse($isPaymentMethodExists);
398
    }
399
400
    /**
401
     * @return void
402
     */
403
    public function testCreatePaymentProvider(): void
404
    {
405
        // Arrange
406
        $paymentProviderTransfer = (new PaymentProviderBuilder())->build();
407
        $storeTransfer = $this->tester->haveStore([
408
            StoreTransfer::NAME => 'DE',
409
        ]);
410
411
        $paymentMethodTransfer = (new PaymentMethodBuilder())->build();
412
        $storeRelationTransfer = (new StoreRelationBuilder())->seed([
413
            StoreRelationTransfer::ID_ENTITY => $paymentMethodTransfer->getIdPaymentMethod(),
414
            StoreRelationTransfer::ID_STORES => [
415
                $storeTransfer->getIdStore(),
416
            ],
417
            StoreRelationTransfer::STORES => [
418
                $storeTransfer,
419
            ],
420
        ])->build();
421
        $paymentMethodTransfer->setStoreRelation($storeRelationTransfer);
422
        $paymentProviderTransfer->addPaymentMethod($paymentMethodTransfer);
423
424
        // Act
425
        $paymentProviderResponseTransfer = $this->paymentFacade->createPaymentProvider($paymentProviderTransfer);
426
427
        // Assert
428
        $this->assertTrue($paymentProviderResponseTransfer->getIsSuccessful());
429
        $this->assertNotEmpty($paymentProviderResponseTransfer->getPaymentProvider()->getIdPaymentProvider());
430
    }
431
432
    /**
433
     * @return void
434
     */
435
    public function testCreatePaymentMethod(): void
436
    {
437
        // Arrange
438
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
439
        $storeTransfer = $this->tester->haveStore([
440
            StoreTransfer::NAME => 'DE',
441
        ]);
442
443
        $paymentMethodTransfer = (new PaymentMethodBuilder())
444
            ->seed([PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider()])
445
            ->build();
446
        $storeRelationTransfer = (new StoreRelationBuilder())->seed([
447
            StoreRelationTransfer::ID_ENTITY => $paymentMethodTransfer->getIdPaymentMethod(),
448
            StoreRelationTransfer::ID_STORES => [
449
                $storeTransfer->getIdStore(),
450
            ],
451
            StoreRelationTransfer::STORES => [
452
                $storeTransfer,
453
            ],
454
        ])->build();
455
        $paymentMethodTransfer->setStoreRelation($storeRelationTransfer);
456
457
        // Act
458
        $paymentMethodResponseTransfer = $this->paymentFacade->createPaymentMethod($paymentMethodTransfer);
459
460
        // Assert
461
        $this->assertTrue($paymentMethodResponseTransfer->getIsSuccessful());
462
        $this->assertNotEmpty($paymentMethodResponseTransfer->getPaymentMethod()->getIdPaymentMethod());
463
    }
464
465
    /**
466
     * @return void
467
     */
468
    public function testDeactivatePaymentMethod(): void
469
    {
470
        // Arrange
471
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
472
        $storeTransfer = $this->tester->haveStore([
473
            StoreTransfer::NAME => 'DE',
474
        ]);
475
        $storeRelationTransfer = (new StoreRelationBuilder())->seed([
476
            StoreRelationTransfer::ID_STORES => [
477
                $storeTransfer->getIdStore(),
478
            ],
479
            StoreRelationTransfer::STORES => [
480
                $storeTransfer,
481
            ],
482
        ])->build();
483
484
        $paymentMethodTransfer = $this->tester->havePaymentMethod([
485
            PaymentMethodTransfer::IS_ACTIVE => true,
486
            PaymentMethodTransfer::PAYMENT_METHOD_KEY => rand(),
487
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
488
            PaymentMethodTransfer::STORE_RELATION => $storeRelationTransfer,
489
        ]);
490
491
        // Act
492
        $paymentMethodResponseTransfer = $this->paymentFacade->deactivatePaymentMethod($paymentMethodTransfer);
493
494
        // Assert
495
        $this->assertTrue($paymentMethodResponseTransfer->getIsSuccessful());
496
        $this->assertFalse($paymentMethodResponseTransfer->getPaymentMethod()->getIsActive());
497
    }
498
499
    /**
500
     * @return void
501
     */
502
    public function testActivatePaymentMethod(): void
503
    {
504
        // Arrange
505
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
506
        $storeTransfer = $this->tester->haveStore([
507
            StoreTransfer::NAME => 'DE',
508
        ]);
509
        $storeRelationTransfer = (new StoreRelationBuilder())->seed([
510
            StoreRelationTransfer::ID_STORES => [
511
                $storeTransfer->getIdStore(),
512
            ],
513
            StoreRelationTransfer::STORES => [
514
                $storeTransfer,
515
            ],
516
        ])->build();
517
518
        $paymentMethodTransfer = $this->tester->havePaymentMethod([
519
            PaymentMethodTransfer::IS_ACTIVE => false,
520
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
521
            PaymentMethodTransfer::PAYMENT_METHOD_KEY => rand(),
522
            PaymentMethodTransfer::STORE_RELATION => $storeRelationTransfer,
523
        ]);
524
525
        // Act
526
        $paymentMethodResponseTransfer = $this->paymentFacade->activatePaymentMethod($paymentMethodTransfer);
527
528
        // Assert
529
        $this->assertTrue($paymentMethodResponseTransfer->getIsSuccessful());
530
        $this->assertTrue($paymentMethodResponseTransfer->getPaymentMethod()->getIsActive());
531
    }
532
533
    /**
534
     * @return void
535
     */
536
    public function testForeignPaymentAuthorizerReceivesCorrectResponseAndUsingItAddsRedirectUrlWithCorrectData(): void
537
    {
538
        // Arrange
539
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
540
        $paymentMethodTransfer = $this->tester->havePaymentMethod([
541
            PaymentMethodTransfer::IS_HIDDEN => false,
542
            PaymentMethodTransfer::PAYMENT_AUTHORIZATION_ENDPOINT => static::PAYMENT_AUTHORIZATION_ENDPOINT,
543
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
544
        ]);
545
546
        $paymentTransfer = (new PaymentTransfer())->setPaymentSelection(
547
            sprintf('%s[%s]', PaymentTransfer::FOREIGN_PAYMENTS, $paymentMethodTransfer->getPaymentMethodKey()),
548
        );
549
550
        $quoteTransfer = $this->buildQuoteTransfer();
551
        $quoteTransfer->setPayment($paymentTransfer);
552
        $checkoutResponseTransfer = $this->buildCheckoutResponseTransfer();
553
554
        $paymentClientMock = $this->getMockBuilder(PaymentClientInterface::class)->getMock();
555
556
        $paymentClientMock->expects($this->once())
557
            ->method('authorizeForeignPayment')
558
            ->with($this->callback(function (PaymentAuthorizeRequestTransfer $paymentAuthorizeRequestTransfer) {
559
                return $paymentAuthorizeRequestTransfer->getRequestUrl() === static::PAYMENT_AUTHORIZATION_ENDPOINT;
560
            }))
561
            ->willReturn(
562
                (new PaymentAuthorizeResponseTransfer())
563
                    ->setIsSuccessful(true)
564
                    ->setRedirectUrl(static::PAYMENT_AUTHORIZATION_REDIRECT),
565
            );
566
567
        $this->tester->setDependency(PaymentDependencyProvider::CLIENT_PAYMENT, $paymentClientMock);
568
569
        // Act
570
        $this->tester->getFacade()->initForeignPaymentForCheckoutProcess($quoteTransfer, $checkoutResponseTransfer);
571
572
        // Assert
573
        $this->assertTrue($checkoutResponseTransfer->getIsExternalRedirect());
574
        $this->assertSame(static::PAYMENT_AUTHORIZATION_REDIRECT, $checkoutResponseTransfer->getRedirectUrl());
575
    }
576
577
    /**
578
     * @return void
579
     */
580
    public function testForeignPaymentAuthorizerForwardsAdditionPaymentDataToThePaymentServiceProviderApp(): void
581
    {
582
        // Arrange
583
        $this->tester->setStoreReferenceData([static::STORE_NAME => static::STORE_REFERENCE]);
584
585
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
586
        $paymentMethodTransfer = $this->tester->havePaymentMethod([
587
            PaymentMethodTransfer::IS_HIDDEN => false,
588
            PaymentMethodTransfer::PAYMENT_AUTHORIZATION_ENDPOINT => static::PAYMENT_AUTHORIZATION_ENDPOINT,
589
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
590
        ]);
591
592
        $paymentTransfer = (new PaymentTransfer())->setPaymentSelection(
593
            sprintf('%s[%s]', PaymentTransfer::FOREIGN_PAYMENTS, $paymentMethodTransfer->getPaymentMethodKey()),
594
        );
595
596
        $additionalPaymentData = [
597
            'internalId' => Uuid::uuid4()->toString(),
598
            'externalId' => Uuid::uuid4()->toString(),
599
        ];
600
601
        $paymentTransfer->setAdditionalPaymentData($additionalPaymentData);
602
603
        $quoteTransfer = $this->buildQuoteTransfer();
604
        $quoteTransfer->setPayment($paymentTransfer);
605
        $checkoutResponseTransfer = $this->buildCheckoutResponseTransfer();
606
607
        $paymentClientMock = $this->getMockBuilder(PaymentClientInterface::class)->getMock();
608
609
        $forwardedAdditionPaymentData = [];
610
611
        $paymentClientMock->expects($this->once())
612
            ->method('authorizeForeignPayment')
613
            ->with($this->callback(function (PaymentAuthorizeRequestTransfer $paymentAuthorizeRequestTransfer) use (&$forwardedAdditionPaymentData) {
614
                // This is what would be sent, we want to compare later.
615
                $forwardedAdditionPaymentData = $paymentAuthorizeRequestTransfer->getPostData()['orderData'][PaymentTransfer::ADDITIONAL_PAYMENT_DATA];
616
617
                return $paymentAuthorizeRequestTransfer->getRequestUrl() === static::PAYMENT_AUTHORIZATION_ENDPOINT;
618
            }))
619
            ->willReturn(
620
                (new PaymentAuthorizeResponseTransfer())
621
                    ->setIsSuccessful(true)
622
                    ->setRedirectUrl(static::PAYMENT_AUTHORIZATION_REDIRECT),
623
            );
624
625
        $this->tester->setDependency(PaymentDependencyProvider::CLIENT_PAYMENT, $paymentClientMock);
626
627
        // Act
628
        $this->tester->getFacade()->initForeignPaymentForCheckoutProcess($quoteTransfer, $checkoutResponseTransfer);
629
630
        // Assert
631
        $this->assertSame($forwardedAdditionPaymentData, $additionalPaymentData);
632
    }
633
634
    /**
635
     * @return void
636
     */
637
    public function testForeignPaymentAuthorizerDoesNothingWithIncorrectData(): void
638
    {
639
        // Arrange
640
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
641
        $paymentMethodTransfer = $this->tester->havePaymentMethod([
642
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
643
        ]);
644
645
        $initialQuoteTransfer = $this->buildQuoteTransfer();
646
        $initialQuoteTransfer->setPayment(
647
            (new PaymentTransfer())->setPaymentSelection($paymentMethodTransfer->getPaymentMethodKey()),
648
        );
649
        $initialCheckoutResponseTransfer = $this->buildCheckoutResponseTransfer();
650
651
        $quoteTransfer = clone $initialQuoteTransfer;
652
        $checkoutResponseTransfer = clone $initialCheckoutResponseTransfer;
653
654
        // Act
655
        $this->tester->getFacade()->initForeignPaymentForCheckoutProcess($quoteTransfer, $checkoutResponseTransfer);
656
657
        // Assert
658
        $this->assertEquals($initialQuoteTransfer->toArray(), $quoteTransfer->toArray());
659
        $this->assertEquals($initialCheckoutResponseTransfer->toArray(), $checkoutResponseTransfer->toArray());
660
    }
661
662
    /**
663
     * @return void
664
     */
665
    public function testInitForeignPaymentForCheckoutProcessReturnsRedirectToRelativePaymentPageFromConfig(): void
666
    {
667
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
668
        $paymentMethodTransfer = $this->tester->havePaymentMethod([
669
            PaymentMethodTransfer::IS_HIDDEN => false,
670
            PaymentMethodTransfer::PAYMENT_AUTHORIZATION_ENDPOINT => static::PAYMENT_AUTHORIZATION_ENDPOINT,
671
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
672
        ]);
673
674
        $paymentTransfer = (new PaymentTransfer())->setPaymentSelection(
675
            sprintf('%s[%s]', PaymentTransfer::FOREIGN_PAYMENTS, $paymentMethodTransfer->getPaymentMethodKey()),
676
        );
677
678
        $quoteTransfer = $this->buildQuoteTransfer();
679
        $quoteTransfer->setPayment($paymentTransfer);
680
        $checkoutResponseTransfer = $this->buildCheckoutResponseTransfer();
681
682
        $paymentClientMock = $this->getMockBuilder(PaymentClientInterface::class)->getMock();
683
684
        $paymentClientMock->expects($this->once())
685
            ->method('authorizeForeignPayment')
686
            ->with($this->callback(function (PaymentAuthorizeRequestTransfer $paymentAuthorizeRequestTransfer) {
687
                return $paymentAuthorizeRequestTransfer->getRequestUrl() === static::PAYMENT_AUTHORIZATION_ENDPOINT;
688
            }))
689
            ->willReturn(
690
                (new PaymentAuthorizeResponseTransfer())
691
                    ->setIsSuccessful(true)
692
                    ->setRedirectUrl(static::PAYMENT_AUTHORIZATION_REDIRECT),
693
            );
694
695
        $this->tester->setDependency(PaymentDependencyProvider::CLIENT_PAYMENT, $paymentClientMock);
696
697
        $this->tester->mockConfigMethod('getStoreFrontPaymentPage', '/my-custom-payment-page');
698
699
        // Act
700
        $this->tester->getFacade()->initForeignPaymentForCheckoutProcess($quoteTransfer, $checkoutResponseTransfer);
701
702
        // Assert
703
        $this->assertTrue($checkoutResponseTransfer->getIsExternalRedirect());
704
        $this->assertSame(
705
            '/my-custom-payment-page?' . http_build_query(['url' => base64_encode(static::PAYMENT_AUTHORIZATION_REDIRECT)]),
706
            $checkoutResponseTransfer->getRedirectUrl(),
707
        );
708
    }
709
710
    /**
711
     * @return void
712
     */
713
    public function testInitForeignPaymentForCheckoutProcessReturnsRedirectToAbsolutePaymentPageOnAnotherDomainFromConfig(): void
714
    {
715
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
716
        $paymentMethodTransfer = $this->tester->havePaymentMethod([
717
            PaymentMethodTransfer::IS_HIDDEN => false,
718
            PaymentMethodTransfer::PAYMENT_AUTHORIZATION_ENDPOINT => static::PAYMENT_AUTHORIZATION_ENDPOINT,
719
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
720
        ]);
721
722
        $paymentTransfer = (new PaymentTransfer())->setPaymentSelection(
723
            sprintf('%s[%s]', PaymentTransfer::FOREIGN_PAYMENTS, $paymentMethodTransfer->getPaymentMethodKey()),
724
        );
725
726
        $quoteTransfer = $this->buildQuoteTransfer();
727
        $quoteTransfer->setPayment($paymentTransfer);
728
        $checkoutResponseTransfer = $this->buildCheckoutResponseTransfer();
729
730
        $paymentClientMock = $this->getMockBuilder(PaymentClientInterface::class)->getMock();
731
732
        $paymentClientMock->expects($this->once())
733
            ->method('authorizeForeignPayment')
734
            ->with($this->callback(function (PaymentAuthorizeRequestTransfer $paymentAuthorizeRequestTransfer) {
735
                return $paymentAuthorizeRequestTransfer->getRequestUrl() === static::PAYMENT_AUTHORIZATION_ENDPOINT;
736
            }))
737
            ->willReturn(
738
                (new PaymentAuthorizeResponseTransfer())
739
                    ->setIsSuccessful(true)
740
                    ->setRedirectUrl(static::PAYMENT_AUTHORIZATION_REDIRECT),
741
            );
742
743
        $this->tester->setDependency(PaymentDependencyProvider::CLIENT_PAYMENT, $paymentClientMock);
744
        $this->tester->mockConfigMethod('getStoreFrontPaymentPage', 'https://my-custom-domain.com/payment?some=param');
745
746
        // Act
747
        $this->tester->getFacade()->initForeignPaymentForCheckoutProcess($quoteTransfer, $checkoutResponseTransfer);
748
749
        // Assert
750
        $this->assertTrue($checkoutResponseTransfer->getIsExternalRedirect());
751
        $this->assertSame(
752
            'https://my-custom-domain.com/payment?some=param&' . http_build_query(['url' => base64_encode(static::PAYMENT_AUTHORIZATION_REDIRECT)]),
753
            $checkoutResponseTransfer->getRedirectUrl(),
754
        );
755
    }
756
757
    /**
758
     * @return void
759
     */
760
    public function testEnablePaymentMethodReturnsSavedPaymentMethodTransferWithCorrectData(): void
761
    {
762
        // Arrange
763
        $this->tester->setStoreReferenceData([static::STORE_NAME => static::STORE_REFERENCE]);
764
765
        $addPaymentMethodTransfer = $this->tester->haveAddPaymentMethodTransfer([
766
            AddPaymentMethodTransfer::NAME => 'name-1',
767
            AddPaymentMethodTransfer::PROVIDER_NAME => 'provider-name-1',
768
            AddPaymentMethodTransfer::PAYMENT_AUTHORIZATION_ENDPOINT => 'redirect-url',
769
        ], [
770
            MessageAttributesTransfer::STORE_REFERENCE => static::STORE_REFERENCE,
771
        ]);
772
773
        // Act
774
        $createdPaymentMethodTransfer = $this->tester->getFacade()
775
            ->enableForeignPaymentMethod($addPaymentMethodTransfer);
776
777
        $createdAddPaymentMethodTransfer = $this->tester->mapPaymentMethodTransferToAddPaymentMethodTransfer(
778
            $createdPaymentMethodTransfer,
779
            new AddPaymentMethodTransfer(),
780
        );
781
782
        // Assert
783
        $this->assertNotNull($createdPaymentMethodTransfer->getIdPaymentMethod());
784
        $this->assertNotNull($createdPaymentMethodTransfer->getIdPaymentProvider());
785
        $this->assertFalse($createdPaymentMethodTransfer->getIsHidden());
786
787
        $this->assertSame($addPaymentMethodTransfer->getName(), $createdAddPaymentMethodTransfer->getName());
788
        $this->assertSame($addPaymentMethodTransfer->getProviderName(), $createdAddPaymentMethodTransfer->getProviderName());
789
        $this->assertSame($addPaymentMethodTransfer->getPaymentAuthorizationEndpoint(), $createdAddPaymentMethodTransfer->getPaymentAuthorizationEndpoint());
790
    }
791
792
    /**
793
     * @return void
794
     */
795
    public function testAddPaymentMethodReturnsSavedPaymentMethodTransferWithCorrectData(): void
796
    {
797
        // Arrange
798
        $addPaymentMethodTransfer = $this->tester->haveAddPaymentMethodTransfer(
799
            [
800
                AddPaymentMethodTransfer::NAME => 'name-1',
801
                AddPaymentMethodTransfer::PROVIDER_NAME => 'provider-name-1',
802
                AddPaymentMethodTransfer::PAYMENT_AUTHORIZATION_ENDPOINT => 'redirect-url',
803
            ],
804
            [],
805
        );
806
807
        // Act
808
        $createdPaymentMethodTransfer = $this->tester->getFacade()
809
            ->addPaymentMethod($addPaymentMethodTransfer);
810
811
        $createdAddPaymentMethodTransfer = $this->tester->mapPaymentMethodTransferToAddPaymentMethodTransfer(
812
            $createdPaymentMethodTransfer,
813
            new AddPaymentMethodTransfer(),
814
        );
815
816
        // Assert
817
        $this->assertNotNull($createdPaymentMethodTransfer->getIdPaymentMethod());
818
        $this->assertNotNull($createdPaymentMethodTransfer->getIdPaymentProvider());
819
        $this->assertFalse($createdPaymentMethodTransfer->getIsHidden());
820
821
        $this->assertSame($addPaymentMethodTransfer->getName(), $createdAddPaymentMethodTransfer->getName());
822
        $this->assertSame($addPaymentMethodTransfer->getProviderName(), $createdAddPaymentMethodTransfer->getProviderName());
823
        $this->assertSame($addPaymentMethodTransfer->getPaymentAuthorizationEndpoint(), $createdAddPaymentMethodTransfer->getPaymentAuthorizationEndpoint());
824
    }
825
826
    /**
827
     * Reflecting an Update of a PaymentMethod.
828
     *
829
     * @return void
830
     */
831
    public function testGivenThePaymentMethodAlreadyExistsAndIsActiveWhenTheAddPaymentMethodMessageIsHandledThenThePaymentMethodIsUpdatedAndIsStillActive(): void
832
    {
833
        // Arrange
834
        $paymentMethodName = 'MethodName' . Uuid::uuid4()->toString();
835
        $paymentProviderKey = 'ProviderKey' . Uuid::uuid4()->toString();
836
837
        $paymentProviderTransfer = $this->tester->havePaymentProvider([PaymentProviderTransfer::PAYMENT_PROVIDER_KEY => $paymentProviderKey]);
838
839
        $this->tester->havePaymentMethod([
840
            PaymentMethodTransfer::IS_ACTIVE => true,
841
            PaymentMethodTransfer::PAYMENT_METHOD_KEY => (new PaymentFacade())->generatePaymentMethodKey($paymentProviderKey, $paymentMethodName),
842
            PaymentMethodTransfer::NAME => $paymentMethodName,
843
            PaymentMethodTransfer::PAYMENT_PROVIDER => $paymentProviderTransfer,
844
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
845
            PaymentMethodTransfer::IS_FOREIGN => true,
846
        ]);
847
848
        $addPaymentMethodTransfer = $this->tester->haveAddPaymentMethodTransfer(
849
            [
850
                AddPaymentMethodTransfer::NAME => $paymentMethodName,
851
                AddPaymentMethodTransfer::PROVIDER_NAME => $paymentProviderKey,
852
                AddPaymentMethodTransfer::PAYMENT_AUTHORIZATION_ENDPOINT => 'redirect-url',
853
            ],
854
        );
855
856
        // Act
857
        $createdPaymentMethodTransfer = $this->tester->getFacade()->addPaymentMethod($addPaymentMethodTransfer);
858
859
        // Assert
860
        $this->assertNotNull($createdPaymentMethodTransfer->getIdPaymentMethod());
861
        $this->assertNotNull($createdPaymentMethodTransfer->getIdPaymentProvider());
862
        $this->assertFalse($createdPaymentMethodTransfer->getIsHidden(), 'Expected that the payment method is visible but it is hidden');
863
        $this->assertTrue($createdPaymentMethodTransfer->getIsActive(), 'Expected that the payment method is active but it is inactive');
864
    }
865
866
    /**
867
     * Reflecting an Update of a PaymentMethod.
868
     *
869
     * @return void
870
     */
871
    public function testGivenThePaymentMethodAlreadyExistsAndIsInactiveWhenTheAddPaymentMethodMessageIsHandledThenThePaymentMethodIsUpdatedAndIsStillInctive(): void
872
    {
873
        // Arrange
874
        $paymentMethodName = 'MethodName' . Uuid::uuid4()->toString();
875
        $paymentProviderKey = 'ProviderKey' . Uuid::uuid4()->toString();
876
877
        $paymentProviderTransfer = $this->tester->havePaymentProvider([PaymentProviderTransfer::PAYMENT_PROVIDER_KEY => $paymentProviderKey]);
878
879
        $this->tester->havePaymentMethod([
880
            PaymentMethodTransfer::IS_ACTIVE => false,
881
            PaymentMethodTransfer::PAYMENT_METHOD_KEY => (new PaymentFacade())->generatePaymentMethodKey($paymentProviderKey, $paymentMethodName),
882
            PaymentMethodTransfer::NAME => $paymentMethodName,
883
            PaymentMethodTransfer::PAYMENT_PROVIDER => $paymentProviderTransfer,
884
            PaymentMethodTransfer::ID_PAYMENT_PROVIDER => $paymentProviderTransfer->getIdPaymentProvider(),
885
            PaymentMethodTransfer::IS_FOREIGN => true,
886
        ]);
887
888
        $addPaymentMethodTransfer = $this->tester->haveAddPaymentMethodTransfer(
889
            [
890
                AddPaymentMethodTransfer::NAME => $paymentMethodName,
891
                AddPaymentMethodTransfer::PROVIDER_NAME => $paymentProviderKey,
892
                AddPaymentMethodTransfer::PAYMENT_AUTHORIZATION_ENDPOINT => 'redirect-url',
893
            ],
894
        );
895
896
        // Act
897
        $createdPaymentMethodTransfer = $this->tester->getFacade()->addPaymentMethod($addPaymentMethodTransfer);
898
899
        // Assert
900
        $this->assertNotNull($createdPaymentMethodTransfer->getIdPaymentMethod());
901
        $this->assertNotNull($createdPaymentMethodTransfer->getIdPaymentProvider());
902
        $this->assertFalse($createdPaymentMethodTransfer->getIsHidden(), 'Expected that the payment method is visible but it is hidden');
903
        $this->assertFalse($createdPaymentMethodTransfer->getIsActive(), 'Expected that the payment method is inactive but it is active');
904
    }
905
906
    /**
907
     * @return void
908
     */
909
    public function testDisableForeignPaymentMethodSetsPaymentMethodIsDeletedFlagToTrueWithCorrectData(): void
910
    {
911
        // Arrange
912
        $storeTransfer = $this->tester->getStoreTransfer([
913
            StoreTransfer::STORE_REFERENCE => static::STORE_REFERENCE,
914
        ]);
915
        $this->tester->setStoreReferenceData([static::STORE_NAME => static::STORE_REFERENCE]);
916
917
        $addPaymentMethodTransfer = $this->tester->haveAddPaymentMethodTransfer([
918
            AddPaymentMethodTransfer::NAME => 'name-2',
919
            AddPaymentMethodTransfer::PROVIDER_NAME => 'provider-name-2',
920
            AddPaymentMethodTransfer::PAYMENT_AUTHORIZATION_ENDPOINT => 'redirect-url',
921
        ], [
922
            MessageAttributesTransfer::STORE_REFERENCE => static::STORE_REFERENCE,
923
        ]);
924
925
        // Act
926
        $paymentMethodTransfer = $this->tester->getFacade()
927
            ->enableForeignPaymentMethod($addPaymentMethodTransfer);
928
929
        $deletePaymentMethodTransfer = $this->tester->mapPaymentMethodTransferToDeletePaymentMethodTransfer(
930
            $paymentMethodTransfer,
931
            (new DeletePaymentMethodTransfer())
932
                ->setMessageAttributes($addPaymentMethodTransfer->getMessageAttributes()),
933
        );
934
        $this->tester->getFacade()->disableForeignPaymentMethod($deletePaymentMethodTransfer);
935
936
        $filterPaymentMethodTransfer = (new PaymentMethodTransfer())
937
            ->setIdPaymentMethod($paymentMethodTransfer->getIdPaymentMethod());
938
        $updatedPaymentMethodTransfer = $this->tester->findPaymentMethod($filterPaymentMethodTransfer);
939
940
        // Assert
941
        $this->assertSame($paymentMethodTransfer->getIdPaymentMethod(), $updatedPaymentMethodTransfer->getIdPaymentMethod());
942
        $this->assertTrue($updatedPaymentMethodTransfer->getIsHidden());
943
    }
944
945
    /**
946
     * @return void
947
     */
948
    public function testDeletePaymentMethodSetsPaymentMethodIsDeletedFlagToTrueWithCorrectData(): void
949
    {
950
        // Arrange
951
        $addPaymentMethodTransfer = $this->tester->haveAddPaymentMethodTransfer(
952
            [
953
                AddPaymentMethodTransfer::NAME => 'name-2',
954
                AddPaymentMethodTransfer::PROVIDER_NAME => 'provider-name-2',
955
                AddPaymentMethodTransfer::PAYMENT_AUTHORIZATION_ENDPOINT => 'redirect-url',
956
            ],
957
            [],
958
        );
959
960
        // Act
961
        $paymentMethodTransfer = $this->tester->getFacade()
962
            ->addPaymentMethod($addPaymentMethodTransfer);
963
964
        $deletePaymentMethodTransfer = $this->tester->mapPaymentMethodTransferToDeletePaymentMethodTransfer(
965
            $paymentMethodTransfer,
966
            (new DeletePaymentMethodTransfer())
967
                ->setMessageAttributes($addPaymentMethodTransfer->getMessageAttributes()),
968
        );
969
        $this->tester->getFacade()->deletePaymentMethod($deletePaymentMethodTransfer);
970
971
        $filterPaymentMethodTransfer = (new PaymentMethodTransfer())
972
            ->setIdPaymentMethod($paymentMethodTransfer->getIdPaymentMethod());
973
        $updatedPaymentMethodTransfer = $this->tester->findPaymentMethod($filterPaymentMethodTransfer);
974
975
        // Assert
976
        $this->assertSame($paymentMethodTransfer->getIdPaymentMethod(), $updatedPaymentMethodTransfer->getIdPaymentMethod());
977
        $this->assertTrue($updatedPaymentMethodTransfer->getIsHidden());
978
    }
979
980
    /**
981
     * When the `disableForeignPaymentMethod()` method is called and the Payment Method doesn't exist yet
982
     * (disable message arrived before add message), it must be created and stored with `is_hidden=true` (soft deletion)
983
     * so the add message can be handled without adding it after it got removed (Payment method gets updated and stays as soft deleted).
984
     *
985
     * @return void
986
     */
987
    public function testDisablePaymentMethodMessageCreatesPaymentMethodAndMarkItAsDeletedWhenThePaymentMethodDoesNotExistsBeforeTheDeleteMessageArrives(): void
988
    {
989
        // Arrange
990
        $deletePaymentMethodMessage = $this->tester->haveDeletePaymentMethodTransferWithoutTimestamp();
991
992
        // Act
993
        $this->tester->getFacade()->disableForeignPaymentMethod($deletePaymentMethodMessage);
994
995
        // Assert
996
        $this->tester->assertDisabledPaymentMethodWasCreatedWithSoftDeletion(
997
            $deletePaymentMethodMessage,
998
        );
999
    }
1000
1001
    /**
1002
     * When the `deletePaymentMethod()` method is called and the Payment Method doesn't exist yet
1003
     * (disable message arrived before add message), it must be created and stored with `is_hidden=true` (soft deletion)
1004
     * so the add message can be handled without adding it after it got removed (Payment method gets updated and stays as soft deleted).
1005
     *
1006
     * @return void
1007
     */
1008
    public function testDeletePaymentMethodMessageCreatesPaymentMethodAndMarkItAsDeletedWhenThePaymentMethodDoesNotExistsBeforeTheDeleteMessageArrives(): void
1009
    {
1010
        // Arrange
1011
        $deletePaymentMethodMessage = $this->tester->haveDeletePaymentMethodTransferWithoutTimestamp();
1012
1013
        // Act
1014
        $this->tester->getFacade()->deletePaymentMethod($deletePaymentMethodMessage);
1015
1016
        // Assert
1017
        $this->tester->assertDisabledPaymentMethodWasCreatedWithSoftDeletion(
1018
            $deletePaymentMethodMessage,
1019
            false,
1020
        );
1021
    }
1022
1023
    /**
1024
     * If the `AddPaymentMethodTransfer` comes from a message when `enableForeignPaymentMethod()` is called
1025
     * it must compare its timestamp with the last message timestamp stored on the existing payment method record.
1026
     * If the last message timestamp stored on the existing payment method record is newer the method must not do any change.
1027
     *
1028
     * @return void
1029
     */
1030
    public function testAddPaymentMethodMessageShouldNotChangeDeletedStateOfPaymentMethodWhenDeletePaymentMethodMessageWasSentAfterAddPaymentMethodMessage(): void
1031
    {
1032
        // Arrange
1033
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1034
        $addPaymentMethodMessage = $this->tester->haveAddPaymentMethodTransferWithTimestamp(
1035
            $paymentProviderTransfer,
1036
            $this->generateNowTimestamp(),
1037
        );
1038
        $disabledPaymentMethod = $this->tester->createDisabledPaymentMethodWithTimestampOnDatabase(
1039
            $paymentProviderTransfer,
1040
            $this->generateNowTimestamp(),
1041
        );
1042
1043
        // Act
1044
        $this->tester->getFacade()->enableForeignPaymentMethod($addPaymentMethodMessage);
1045
1046
        // Assert
1047
        $this->tester->assertDisabledPaymentMethodDidNotChange($disabledPaymentMethod);
1048
    }
1049
1050
    /**
1051
     * If the `AddPaymentMethodTransfer` comes from a message when `enableForeignPaymentMethod()` is called
1052
     * it must compare its timestamp with the last message timestamp stored on the existing payment method record.
1053
     * If the last message timestamp stored on the existing payment method record is newer the method must not do any change.
1054
     *
1055
     * @return void
1056
     */
1057
    public function testAddPaymentMethodMessageShouldNotChangeStateOfPaymentMethodWhenDeletePaymentMethodMessageWasSentAfterAddPaymentMethodMessage(): void
1058
    {
1059
        // Arrange
1060
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1061
        $addPaymentMethodMessage = $this->tester->haveAddPaymentMethodTransferWithTimestamp(
1062
            $paymentProviderTransfer,
1063
            $this->generateNowTimestamp(),
1064
        );
1065
        $disabledPaymentMethod = $this->tester->createDisabledPaymentMethodWithTimestampOnDatabase(
1066
            $paymentProviderTransfer,
1067
            $this->generateNowTimestamp(),
1068
        );
1069
1070
        // Act
1071
        $this->tester->getFacade()->addPaymentMethod($addPaymentMethodMessage);
1072
1073
        // Assert
1074
        $this->tester->assertDisabledPaymentMethodDidNotChange($disabledPaymentMethod);
1075
    }
1076
1077
    /**
1078
     * If the last message timestamp is null when `enableForeignPaymentMethod()` is called it should always
1079
     * proceed with the change and update the timestamp.
1080
     *
1081
     * @return void
1082
     */
1083
    public function testEnableForeignPaymentMethodShouldChangeDeletedStateOfPaymentMethodWhenPaymentMethodsLastMessageTimestampIsNull(): void
1084
    {
1085
        // Arrange
1086
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1087
        $addPaymentMethodMessage = $this->tester->haveAddPaymentMethodTransferWithTimestamp(
1088
            $paymentProviderTransfer,
1089
            $this->generateNowTimestamp(),
1090
        );
1091
        $disabledPaymentMethod = $this->tester->createDisabledPaymentMethodWithoutTimestampOnDatabase($paymentProviderTransfer);
1092
1093
        // Act
1094
        $this->tester->getFacade()->enableForeignPaymentMethod($addPaymentMethodMessage);
1095
1096
        // Assert
1097
        $this->tester->assertDisabledPaymentMethodWasEnabledAndTimestampChanged(
1098
            $disabledPaymentMethod,
1099
            $addPaymentMethodMessage,
1100
        );
1101
    }
1102
1103
    /**
1104
     * If the last message timestamp is null when `addPaymentMethod()` is called it should always
1105
     * proceed with the change and update the timestamp.
1106
     *
1107
     * @return void
1108
     */
1109
    public function testAddPaymentMethodShouldChangeDeletedStateOfPaymentMethodWhenPaymentMethodsLastMessageTimestampIsNull(): void
1110
    {
1111
        // Arrange
1112
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1113
        $addPaymentMethodMessage = $this->tester->haveAddPaymentMethodTransferWithTimestamp(
1114
            $paymentProviderTransfer,
1115
            $this->generateNowTimestamp(),
1116
        );
1117
        $disabledPaymentMethod = $this->tester->createDisabledPaymentMethodWithoutTimestampOnDatabase(
1118
            $paymentProviderTransfer,
1119
            false,
1120
        );
1121
1122
        // Act
1123
        $this->tester->getFacade()->addPaymentMethod($addPaymentMethodMessage);
1124
1125
        // Assert
1126
        $this->tester->assertDisabledPaymentMethodWasEnabledAndTimestampChanged(
1127
            $disabledPaymentMethod,
1128
            $addPaymentMethodMessage,
1129
        );
1130
    }
1131
1132
    /**
1133
     * If `AddPaymentMethodTransfer` doesn't come from a message it likely will not have a timestamp and this can not
1134
     * avoid the process to keep on running and the change must happen, and the timestamp must be updated.
1135
     *
1136
     * @return void
1137
     */
1138
    public function testEnabledForeignPaymentMethodShouldChangeDeletedStateOfPaymentMethodWhenAddPaymentMethodTransferDoNotComeFromAMessageAndItsTimestampIsNull(): void
1139
    {
1140
        // Arrange
1141
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1142
        $addPaymentMethodMessage = $this->tester->haveAddPaymentMethodTransferWithoutTimestamp($paymentProviderTransfer);
1143
        $disabledPaymentMethod = $this->tester->createDisabledPaymentMethodWithTimestampOnDatabase(
1144
            $paymentProviderTransfer,
1145
            $this->generateNowTimestamp(),
1146
        );
1147
1148
        // Act
1149
        $this->tester->getFacade()->enableForeignPaymentMethod($addPaymentMethodMessage);
1150
1151
        // Assert
1152
        $this->tester->assertDisabledPaymentMethodWasEnabledAndTimestampWasUpdated(
1153
            $disabledPaymentMethod,
1154
        );
1155
    }
1156
1157
    /**
1158
     * If `AddPaymentMethodTransfer` doesn't come from a message it likely will not have a timestamp and this can not
1159
     * avoid the process to keep on running and the change must happen, and the timestamp must be updated.
1160
     *
1161
     * @return void
1162
     */
1163
    public function testEnabledForeignPaymentMethodShouldModifyStateOfPaymentMethodWhenAddPaymentMethodTransferDoNotComeFromAMessageAndItsTimestampIsNull(): void
1164
    {
1165
        // Arrange
1166
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1167
        $addPaymentMethodMessage = $this->tester->haveAddPaymentMethodTransferWithoutTimestamp($paymentProviderTransfer);
1168
        $disabledPaymentMethod = $this->tester->createDisabledPaymentMethodWithTimestampOnDatabase(
1169
            $paymentProviderTransfer,
1170
            $this->generateNowTimestamp(),
1171
            false,
1172
        );
1173
1174
        // Act
1175
        $this->tester->getFacade()->addPaymentMethod($addPaymentMethodMessage);
1176
1177
        // Assert
1178
        $this->tester->assertDisabledPaymentMethodWasEnabledAndTimestampWasUpdated(
1179
            $disabledPaymentMethod,
1180
        );
1181
    }
1182
1183
    /**
1184
     * If the `DeletePaymentMethodTransfer` comes from a message when `disableForeignPaymentMethod()` is called
1185
     * it must compare its timestamp with the last message timestamp stored on the existing payment method record.
1186
     * If the last message timestamp stored on the existing payment method record is newer the method must not do any change.
1187
     *
1188
     * @return void
1189
     */
1190
    public function testDisableForeignPaymentMethodShouldNotChangeEnabledStateOfPaymentMethodIfLastMessageTimestampIsOlderThanDeletePaymentMethodTransferTimestamp(): void
1191
    {
1192
        // Arrange
1193
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1194
        $deletePaymentMethodMessage = $this->tester->haveDeletePaymentMethodTransferWithTimestamp(
1195
            $paymentProviderTransfer,
1196
            $this->generateNowTimestamp(),
1197
        );
1198
        $enabledPaymentMethod = $this->tester->createEnabledPaymentMethodWithTimestampOnDatabase(
1199
            $paymentProviderTransfer,
1200
            $this->generateNowTimestamp(),
1201
        );
1202
1203
        // Act
1204
        $this->tester->getFacade()->disableForeignPaymentMethod($deletePaymentMethodMessage);
1205
1206
        // Assert
1207
        $this->tester->assertEnabledPaymentMethodDidNotChange($enabledPaymentMethod);
1208
    }
1209
1210
    /**
1211
     * If the `DeletePaymentMethodTransfer` comes from a message when `deletePaymentMethod()` is called
1212
     * it must compare its timestamp with the last message timestamp stored on the existing payment method record.
1213
     * If the last message timestamp stored on the existing payment method record is newer the method must not do any change.
1214
     *
1215
     * @return void
1216
     */
1217
    public function testDeletePaymentMethodShouldNotChangeEnabledStateOfPaymentMethodIfLastMessageTimestampIsOlderThanDeletePaymentMethodTransferTimestamp(): void
1218
    {
1219
        // Arrange
1220
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1221
        $deletePaymentMethodMessage = $this->tester->haveDeletePaymentMethodTransferWithTimestamp(
1222
            $paymentProviderTransfer,
1223
            $this->generateNowTimestamp(),
1224
        );
1225
        $enabledPaymentMethod = $this->tester->createEnabledPaymentMethodWithTimestampOnDatabase(
1226
            $paymentProviderTransfer,
1227
            $this->generateNowTimestamp(),
1228
            false,
1229
        );
1230
1231
        // Act
1232
        $this->tester->getFacade()->deletePaymentMethod($deletePaymentMethodMessage);
1233
1234
        // Assert
1235
        $this->tester->assertEnabledPaymentMethodDidNotChange($enabledPaymentMethod);
1236
    }
1237
1238
    /**
1239
     * If the last message timestamp is null when `disableForeignPaymentMethod()` is called it should always
1240
     * proceed with the change and update the timestamp.
1241
     *
1242
     * @return void
1243
     */
1244
    public function testDisableForeignPaymentMethodShouldChangeEnabledStateOfPaymentMethodWhenPaymentMethodsLastMessageTimestampIsNull(): void
1245
    {
1246
        // Arrange
1247
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1248
        $deletePaymentMethodMessage = $this->tester->haveDeletePaymentMethodTransferWithTimestamp(
1249
            $paymentProviderTransfer,
1250
            $this->generateNowTimestamp(),
1251
        );
1252
        $enabledPaymentMethod = $this->tester->createEnabledPaymentMethodWithoutTimestampOnDatabase($paymentProviderTransfer);
1253
1254
        // Act
1255
        $this->tester->getFacade()->disableForeignPaymentMethod($deletePaymentMethodMessage);
1256
1257
        // Assert
1258
        $this->tester->assertEnabledPaymentMethodWasDisabledAndTimestampChanged(
1259
            $enabledPaymentMethod,
1260
            $deletePaymentMethodMessage,
1261
        );
1262
    }
1263
1264
    /**
1265
     * If the last message timestamp is null when `deletePaymentMethod()` is called it should always
1266
     * proceed with the change and update the timestamp.
1267
     *
1268
     * @return void
1269
     */
1270
    public function testDeletePaymentMethodShouldChangeEnabledStateOfPaymentMethodWhenPaymentMethodsLastMessageTimestampIsNull(): void
1271
    {
1272
        // Arrange
1273
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1274
        $deletePaymentMethodMessage = $this->tester->haveDeletePaymentMethodTransferWithTimestamp(
1275
            $paymentProviderTransfer,
1276
            $this->generateNowTimestamp(),
1277
        );
1278
        $enabledPaymentMethod = $this->tester->createEnabledPaymentMethodWithoutTimestampOnDatabase(
1279
            $paymentProviderTransfer,
1280
            false,
1281
        );
1282
1283
        // Act
1284
        $this->tester->getFacade()->deletePaymentMethod($deletePaymentMethodMessage);
1285
1286
        // Assert
1287
        $this->tester->assertEnabledPaymentMethodWasDisabledAndTimestampChanged(
1288
            $enabledPaymentMethod,
1289
            $deletePaymentMethodMessage,
1290
        );
1291
    }
1292
1293
    /**
1294
     * If `DeletePaymentMethodTransfer` doesn't come from a message it likely will not have a timestamp and this can not
1295
     * avoid the process to keep up running and the change must happen, and the timestamp must be updated.
1296
     *
1297
     * @return void
1298
     */
1299
    public function testDisableForeignPaymentMethodShouldChangeEnabledStateOfPaymentMethodWhenDeletePaymentMethodTransferDoNotComeFromAMessageAndItsTimestampIsNull(): void
1300
    {
1301
        // Arrange
1302
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1303
        $deletePaymentMethodMessage = $this->tester->haveDeletePaymentMethodTransferWithoutTimestamp($paymentProviderTransfer);
1304
        $enabledPaymentMethod = $this->tester->createEnabledPaymentMethodWithTimestampOnDatabase(
1305
            $paymentProviderTransfer,
1306
            $this->generateNowTimestamp(),
1307
        );
1308
1309
        // Act
1310
        $this->tester->getFacade()->disableForeignPaymentMethod($deletePaymentMethodMessage);
1311
1312
        // Assert
1313
        $this->tester->assertEnabledPaymentMethodWasDisabledAndTimestampWasUpdated(
1314
            $enabledPaymentMethod,
1315
            $deletePaymentMethodMessage,
1316
        );
1317
    }
1318
1319
    /**
1320
     * If `DeletePaymentMethodTransfer` doesn't come from a message it likely will not have a timestamp and this can not
1321
     * avoid the process to keep up running and the change must happen, and the timestamp must be updated.
1322
     *
1323
     * @return void
1324
     */
1325
    public function testDeletePaymentMethodShouldChangeEnabledStateOfPaymentMethodWhenDeletePaymentMethodTransferDoNotComeFromAMessageAndItsTimestampIsNull(): void
1326
    {
1327
        // Arrange
1328
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1329
        $deletePaymentMethodMessage = $this->tester->haveDeletePaymentMethodTransferWithoutTimestamp($paymentProviderTransfer);
1330
        $enabledPaymentMethod = $this->tester->createEnabledPaymentMethodWithTimestampOnDatabase(
1331
            $paymentProviderTransfer,
1332
            $this->generateNowTimestamp(),
1333
            false,
1334
        );
1335
1336
        // Act
1337
        $this->tester->getFacade()->deletePaymentMethod($deletePaymentMethodMessage);
1338
1339
        // Assert
1340
        $this->tester->assertEnabledPaymentMethodWasDisabledAndTimestampWasUpdated(
1341
            $enabledPaymentMethod,
1342
            $deletePaymentMethodMessage,
1343
        );
1344
    }
1345
1346
    /**
1347
     * Tests if a new Payment Method will be created and the Payment Method that already
1348
     * exists will not be modified when PaymentMethodUpdater::disableForeignPaymentMethod() is called.
1349
     *
1350
     * This bug was reported on https://spryker.atlassian.net/browse/PBC-1674.
1351
     *
1352
     * @return void
1353
     */
1354
    public function testEnableForeignPaymentMethodMustChangeTheRightPaymentMethodWhenThereIsMoreThanOneMethodStored(): void
1355
    {
1356
        // Arrange
1357
        $existentPaymentMethod = $this->tester->createEnabledPaymentMethodWithoutTimestampOnDatabase(
1358
            $this->tester->havePaymentProvider(),
1359
        );
1360
1361
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1362
        $deletePaymentMethodMessage = $this->tester->haveDeletePaymentMethodTransferWithTimestamp(
1363
            $paymentProviderTransfer,
1364
            $this->generateNowTimestamp(),
1365
        );
1366
1367
        // Act
1368
        $this->tester->getFacade()->disableForeignPaymentMethod($deletePaymentMethodMessage);
1369
1370
        // Assert
1371
        $this->tester->assertRightPaymentMethodWasUpdated(
1372
            $existentPaymentMethod,
1373
            $deletePaymentMethodMessage->getProviderName(),
1374
        );
1375
    }
1376
1377
    /**
1378
     * Tests if a new Payment Method will be created and the Payment Method that already
1379
     * exists will not be modified when PaymentMethodUpdater::deletePaymentMethod() is called.
1380
     *
1381
     * This bug was reported on https://spryker.atlassian.net/browse/PBC-1674.
1382
     *
1383
     * @return void
1384
     */
1385
    public function testDeletePaymentMethodMustChangeTheRightPaymentMethodWhenThereIsMoreThanOneMethodStored(): void
1386
    {
1387
        // Arrange
1388
        $existentPaymentMethod = $this->tester->createEnabledPaymentMethodWithoutTimestampOnDatabase(
1389
            $this->tester->havePaymentProvider(),
1390
            false,
1391
        );
1392
1393
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1394
        $deletePaymentMethodMessage = $this->tester->haveDeletePaymentMethodTransferWithTimestamp(
1395
            $paymentProviderTransfer,
1396
            $this->generateNowTimestamp(),
1397
        );
1398
1399
        // Act
1400
        $this->tester->getFacade()->deletePaymentMethod($deletePaymentMethodMessage);
1401
1402
        // Assert
1403
        $this->tester->assertRightPaymentMethodWasUpdated(
1404
            $existentPaymentMethod,
1405
            $deletePaymentMethodMessage->getProviderName(),
1406
            false,
1407
        );
1408
    }
1409
1410
    /**
1411
     * Tests if a new Payment Method will be created and the Payment Method that already
1412
     * exists will not be modified when PaymentMethodUpdater::enableForeignPaymentMethod() is called.
1413
     *
1414
     * This bug was reported on https://spryker.atlassian.net/browse/PBC-1674.
1415
     *
1416
     * @return void
1417
     */
1418
    public function testDisableForeignPaymentMethodMustChangeTheRightPaymentMethodWhenThereIsMoreThanOneMethodStored(): void
1419
    {
1420
        // Arrange
1421
        $existentPaymentMethod = $this->tester->createDisabledPaymentMethodWithoutTimestampOnDatabase(
1422
            $this->tester->havePaymentProvider(),
1423
        );
1424
1425
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1426
        $addPaymentMethodMessage = $this->tester->haveAddPaymentMethodTransferWithTimestamp(
1427
            $paymentProviderTransfer,
1428
            $this->generateNowTimestamp(),
1429
        );
1430
1431
        // Act
1432
        $this->tester->getFacade()->enableForeignPaymentMethod($addPaymentMethodMessage);
1433
1434
        // Assert
1435
        $this->tester->assertRightPaymentMethodWasUpdated(
1436
            $existentPaymentMethod,
1437
            $addPaymentMethodMessage->getProviderName(),
1438
        );
1439
    }
1440
1441
    /**
1442
     * Tests if a new Payment Method will be created and the Payment Method that already
1443
     * exists will not be modified when PaymentMethodUpdater::addPaymentMethod() is called.
1444
     *
1445
     * This bug was reported on https://spryker.atlassian.net/browse/PBC-1674.
1446
     *
1447
     * @return void
1448
     */
1449
    public function testDisableForeignPaymentMethodMustModifyTheRightPaymentMethodWhenThereIsMoreThanOneMethodStored(): void
1450
    {
1451
        // Arrange
1452
        $existentPaymentMethod = $this->tester->createDisabledPaymentMethodWithoutTimestampOnDatabase(
1453
            $this->tester->havePaymentProvider(),
1454
            false,
1455
        );
1456
1457
        $paymentProviderTransfer = $this->tester->havePaymentProvider();
1458
        $addPaymentMethodMessage = $this->tester->haveAddPaymentMethodTransferWithTimestamp(
1459
            $paymentProviderTransfer,
1460
            $this->generateNowTimestamp(),
1461
        );
1462
1463
        // Act
1464
        $this->tester->getFacade()->addPaymentMethod($addPaymentMethodMessage);
1465
1466
        // Assert
1467
        $this->tester->assertRightPaymentMethodWasUpdated(
1468
            $existentPaymentMethod,
1469
            $addPaymentMethodMessage->getProviderName(),
1470
            false,
1471
        );
1472
    }
1473
1474
    /**
1475
     * @return \Generated\Shared\Transfer\CheckoutResponseTransfer
1476
     */
1477
    protected function buildCheckoutResponseTransfer(): CheckoutResponseTransfer
1478
    {
1479
        return (new CheckoutResponseBuilder())
1480
            ->withSaveOrder()
1481
            ->build();
1482
    }
1483
1484
    /**
1485
     * @return \Generated\Shared\Transfer\QuoteTransfer
1486
     */
1487
    protected function buildQuoteTransfer(): QuoteTransfer
1488
    {
1489
        return (new QuoteBuilder())
1490
            ->withItem()
1491
            ->withStore([
1492
                'name' => static::STORE_NAME,
1493
            ])
1494
            ->withCustomer()
1495
            ->withTotals()
1496
            ->withCurrency()
1497
            ->withBillingAddress()
1498
            ->withShippingAddress()
1499
            ->build();
1500
    }
1501
1502
    /**
1503
     * @return void
1504
     */
1505
    protected function mockPaymentMethodReader(): void
1506
    {
1507
        $paymentMethodReaderMock = $this->getMockBuilder(PaymentMethodReader::class)
1508
            ->onlyMethods(['getAvailableMethods'])
1509
            ->disableOriginalConstructor()
1510
            ->getMock();
1511
        $paymentMethodReaderMock->method('getAvailableMethods')->willReturn(
1512
            (new PaymentMethodsTransfer())
1513
                ->addMethod(
1514
                    (new PaymentMethodTransfer())->setMethodName('dummyPaymentInvoice')
1515
                        ->setPaymentMethodKey('dummyPaymentInvoice'),
1516
                ),
1517
        );
1518
1519
        $container = new Container();
1520
        /** @var \Spryker\Zed\Payment\Business\PaymentBusinessFactory $paymentBusinessFactoryMock */
1521
        $paymentBusinessFactoryMock = $this->getMockBuilder(PaymentBusinessFactory::class)
1522
            ->onlyMethods(['createPaymentMethodReader', 'getPaymentService'])
1523
            ->getMock();
1524
        $paymentBusinessFactoryMock->method('createPaymentMethodReader')
1525
            ->willReturn($paymentMethodReaderMock);
1526
        $paymentBusinessFactoryMock->method('getPaymentService')
1527
            ->willReturn($container->getLocator()->payment()->service());
1528
1529
        $this->paymentFacade->setFactory($paymentBusinessFactoryMock);
1530
    }
1531
1532
    /**
1533
     * @return string
1534
     */
1535
    protected function generateNowTimestamp(): string
1536
    {
1537
        return (new DateTime('now', new DateTimeZone('UTC')))->format('Y-m-d\TH:i:s.u');
1538
    }
1539
1540
    /**
1541
     * @return void
1542
     */
1543
    public function testGeneratePaymentMethodKeyReturnsPaymentMethodKeyForGivenProviderAndMethod(): void
1544
    {
1545
        // Arrange, Act, Assert
1546
        $this->assertSame('foo-bar-baz', $this->paymentFacade->generatePaymentMethodKey('foo', 'bar baz'));
1547
    }
1548
}
1549