Completed
Push — master ( a1560f...1d26b8 )
by Kamil
17s
created

CheckoutContext::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 31
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 2
Metric Value
c 3
b 0
f 2
dl 0
loc 31
rs 8.8571
cc 1
eloc 29
nc 1
nop 14

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Behat\Context\Ui;
13
14
use Behat\Behat\Context\Context;
15
use Sylius\Behat\Page\Shop\Checkout\AddressingPageInterface;
16
use Sylius\Behat\Page\Shop\Checkout\PaymentPageInterface;
17
use Sylius\Behat\Page\Shop\Checkout\ShippingPageInterface;
18
use Sylius\Behat\Page\Shop\Checkout\SummaryPageInterface;
19
use Sylius\Behat\Page\Shop\Order\OrderPaymentsPageInterface;
20
use Sylius\Behat\Page\Shop\Checkout\AddressingStepInterface;
21
use Sylius\Behat\Page\Shop\Checkout\FinalizeStepInterface;
22
use Sylius\Behat\Page\Shop\Checkout\PaymentStepInterface;
23
use Sylius\Behat\Page\Shop\Checkout\SecurityStepInterface;
24
use Sylius\Behat\Page\Shop\Checkout\ShippingStepInterface;
25
use Sylius\Behat\Page\Shop\Checkout\ThankYouPageInterface;
26
use Sylius\Component\Core\Formatter\StringInflector;
27
use Sylius\Behat\Service\SecurityServiceInterface;
28
use Sylius\Component\Core\Model\AddressInterface;
29
use Sylius\Component\Core\Model\OrderInterface;
30
use Sylius\Component\Core\Model\ProductInterface;
31
use Sylius\Component\Core\Model\UserInterface;
32
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
33
use Sylius\Component\Order\Repository\OrderRepositoryInterface;
34
use Sylius\Component\Payment\Model\PaymentInterface;
35
use Webmozart\Assert\Assert;
36
37
/**
38
 * @author Arkadiusz Krakowiak <[email protected]>
39
 */
40
final class CheckoutContext implements Context
41
{
42
    /**
43
     * @var SharedStorageInterface
44
     */
45
    private $sharedStorage;
46
47
    /**
48
     * @var SecurityStepInterface
49
     */
50
    private $checkoutSecurityStep;
51
52
    /**
53
     * @var AddressingStepInterface
54
     */
55
    private $checkoutAddressingStep;
56
57
    /**
58
     * @var AddressingPageInterface
59
     */
60
    private $addressingPage;
61
62
    /**
63
     * @var ShippingStepInterface
64
     */
65
    private $checkoutShippingStep;
66
67
    /**
68
     * @var PaymentStepInterface
69
     */
70
    private $checkoutPaymentStep;
71
72
    /**
73
     * @var PaymentPageInterface
74
     */
75
    private $paymentPage;
76
77
    /**
78
     * @var FinalizeStepInterface
79
     */
80
    private $checkoutFinalizeStep;
81
82
    /**
83
     * @var ThankYouPageInterface
84
     */
85
    private $checkoutThankYouPage;
86
87
    /**
88
     * @var OrderPaymentsPageInterface
89
     */
90
    private $orderPaymentsPage;
91
92
    /**
93
     * @var ShippingPageInterface
94
     */
95
    private $shippingPage;
96
97
    /**
98
     * @var SummaryPageInterface
99
     */
100
    private $summaryPage;
101
102
    /**
103
     * @var OrderRepositoryInterface
104
     */
105
    private $orderRepository;
106
107
    /**
108
     * @var SecurityServiceInterface
109
     */
110
    private $securityService;
111
112
    /**
113
     * @param SharedStorageInterface $sharedStorage
114
     * @param SecurityStepInterface $checkoutSecurityStep
115
     * @param AddressingStepInterface $checkoutAddressingStep
116
     * @param AddressingPageInterface $addressingPage
117
     * @param ShippingStepInterface $checkoutShippingStep
118
     * @param ShippingPageInterface $shippingPage
119
     * @param PaymentStepInterface $checkoutPaymentStep
120
     * @param PaymentPageInterface $paymentPage
121
     * @param SummaryPageInterface $summaryPage
122
     * @param FinalizeStepInterface $checkoutFinalizeStep
123
     * @param ThankYouPageInterface $checkoutThankYouPage
124
     * @param OrderPaymentsPageInterface $orderPaymentsPage
125
     * @param OrderRepositoryInterface $orderRepository
126
     * @param SecurityServiceInterface $securityService
127
     */
128
    public function __construct(
129
        SharedStorageInterface $sharedStorage,
130
        SecurityStepInterface $checkoutSecurityStep,
131
        AddressingStepInterface $checkoutAddressingStep,
132
        AddressingPageInterface $addressingPage,
133
        ShippingStepInterface $checkoutShippingStep,
134
        ShippingPageInterface $shippingPage,
135
        PaymentStepInterface $checkoutPaymentStep,
136
        PaymentPageInterface $paymentPage,
137
        SummaryPageInterface $summaryPage,
138
        FinalizeStepInterface $checkoutFinalizeStep,
139
        ThankYouPageInterface $checkoutThankYouPage,
140
        OrderPaymentsPageInterface $orderPaymentsPage,
141
        OrderRepositoryInterface $orderRepository,
142
        SecurityServiceInterface $securityService
143
    ) {
144
        $this->sharedStorage = $sharedStorage;
145
        $this->checkoutSecurityStep = $checkoutSecurityStep;
146
        $this->checkoutAddressingStep = $checkoutAddressingStep;
147
        $this->addressingPage = $addressingPage;
148
        $this->checkoutShippingStep = $checkoutShippingStep;
149
        $this->shippingPage = $shippingPage;
150
        $this->checkoutPaymentStep = $checkoutPaymentStep;
151
        $this->paymentPage = $paymentPage;
152
        $this->summaryPage = $summaryPage;
153
        $this->checkoutFinalizeStep = $checkoutFinalizeStep;
154
        $this->checkoutThankYouPage = $checkoutThankYouPage;
155
        $this->orderPaymentsPage = $orderPaymentsPage;
156
        $this->orderRepository = $orderRepository;
157
        $this->securityService = $securityService;
158
    }
159
160
    /**
161
     * @Given /^I proceed without selecting shipping address$/
162
     */
163
    public function iProceedWithoutSelectingShippingAddress()
164
    {
165
        $this->checkoutAddressingStep->open();
166
        $this->checkoutAddressingStep->continueCheckout();
167
    }
168
169
    /**
170
     * @Given I am at the checkout addressing step
171
     */
172
    public function iAmAtTheCheckoutAddressingStep()
173
    {
174
        $this->addressingPage->open();
175
    }
176
177
    /**
178
     * @Given /^(this user) bought this product$/
179
     */
180
    public function thisUserBought(UserInterface $user)
181
    {
182
        $this->securityService->performActionAs($user, function () {
183
            $this->iProceedSelectingOfflinePaymentMethod();
184
            $this->iConfirmMyOrder();
185
        });
186
    }
187
188
    /**
189
     * @When /^I specify the shipping (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
190
     * @When /^I (do not specify any shipping address) information$/
191
     */
192
    public function iSpecifyTheShippingAddressAs(AddressInterface $address)
193
    {
194
        $key = sprintf(
195
            'shipping_address_%s_%s',
196
            strtolower($address->getFirstName()),
197
            strtolower($address->getLastName())
198
        );
199
        $this->sharedStorage->set($key, $address);
200
201
        $this->addressingPage->specifyShippingAddress($address);
202
    }
203
204
    /**
205
     * @When /^I specify the billing (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
206
     * @When /^I (do not specify any billing address) information$/
207
     */
208
    public function iSpecifyTheBillingAddressAs(AddressInterface $address)
209
    {
210
        $this->iChooseTheDifferentBillingAddress();
211
        $key = sprintf(
212
            'billing_address_%s_%s',
213
            strtolower($address->getFirstName()),
214
            strtolower($address->getLastName())
215
        );
216
        $this->sharedStorage->set($key, $address);
217
218
        $this->addressingPage->specifyBillingAddress($address);
219
    }
220
221
    /**
222
     * @When /^I specified the shipping (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
223
     */
224
    public function iSpecifiedTheShippingAddress(AddressInterface $address)
225
    {
226
        $this->addressingPage->open();
227
        $this->iSpecifyTheShippingAddressAs($address);
228
229
        $key = sprintf('billing_address_%s_%s', strtolower($address->getFirstName()), strtolower($address->getLastName()));
230
        $this->sharedStorage->set($key, $address);
231
232
        $this->iCompleteTheAddressingStep();
233
    }
234
235
    /**
236
     * @When I choose the different billing address
237
     */
238
    public function iChooseTheDifferentBillingAddress()
239
    {
240
        $this->addressingPage->chooseDifferentBillingAddress();
241
    }
242
243
    /**
244
     * @When I specify the email as :email
245
     * @When I do not specify the email
246
     */
247
    public function iSpecifyTheEmail($email = null)
248
    {
249
        $this->addressingPage->specifyEmail($email);
250
    }
251
252
    /**
253
     * @When I select :shippingMethod shipping method
254
     */
255
    public function iSelectShippingMethod($shippingMethod)
256
    {
257
        $this->shippingPage->selectShippingMethod($shippingMethod);
258
    }
259
260
    /**
261
     * @Then I should not be able to select :shippingMethod shipping method
262
     */
263
    public function iShouldNotBeAbleToSelectShippingMethod($shippingMethod)
264
    {
265
        Assert::false(
266
            $this->shippingPage->hasShippingMethod($shippingMethod),
267
            sprintf('Shipping method "%s" should not be available but it does.', $shippingMethod)
268
        );
269
    }
270
271
    /**
272
     * @When I complete the addressing step
273
     * @When I try to complete the addressing step
274
     */
275
    public function iCompleteTheAddressingStep()
276
    {
277
        $this->addressingPage->nextStep();
278
    }
279
280
    /**
281
     * @When I complete the shipping step
282
     */
283
    public function iCompleteTheShippingStep()
284
    {
285
        $this->shippingPage->nextStep();
286
    }
287
288
    /**
289
     * @When /^I proceed selecting "([^"]*)" as shipping country$/
290
     */
291
    public function iProceedSelectingShippingCountry($shippingCountry)
292
    {
293
        $this->checkoutAddressingStep->open();
294
        $this->checkoutAddressingStep->fillAddressingDetails([
295
            'firstName' => 'John',
296
            'lastName' => 'Doe',
297
            'country' => $shippingCountry ?: 'France',
298
            'street' => '0635 Myron Hollow Apt. 711',
299
            'city' => 'North Bridget',
300
            'postcode' => '93-554',
301
            'phoneNumber' => '321123456',
302
        ]);
303
        $this->checkoutAddressingStep->continueCheckout();
304
    }
305
306
    /**
307
     * @When /^I proceed selecting "([^"]*)" as shipping country with "([^"]*)" method$/
308
     */
309
    public function iProceedSelectingShippingCountryAndShippingMethod($shippingCountry, $shippingMethodName)
310
    {
311
        $this->iProceedSelectingShippingCountry($shippingCountry);
312
313
        $this->checkoutShippingStep->selectShippingMethod($shippingMethodName ?: 'Free');
314
        $this->checkoutShippingStep->continueCheckout();
315
    }
316
317
    /**
318
     * @When /^I proceed selecting "([^"]+)" shipping method$/
319
     * @Given /^I chose "([^"]*)" shipping method$/
320
     */
321
    public function iProceedSelectingShippingMethod($shippingMethodName)
322
    {
323
        $this->iProceedSelectingShippingCountryAndShippingMethod(null, $shippingMethodName);
324
    }
325
326
    /**
327
     * @When /^I choose "([^"]*)" payment method$/
328
     */
329
    public function iChoosePaymentMethod($paymentMethodName)
330
    {
331
        $this->checkoutPaymentStep->verify([]);
332
        $this->checkoutPaymentStep->selectPaymentMethod($paymentMethodName ?: 'Offline');
333
        $this->checkoutPaymentStep->continueCheckout();
334
    }
335
336
    /**
337
     * @When /^I proceed selecting "([^"]*)" as shipping country with "([^"]*)" payment method$/
338
     */
339
    public function iProceedSelectingShippingCountryAndPaymentMethod($shippingCountry, $paymentMethodName)
340
    {
341
        $this->iProceedSelectingShippingCountryAndShippingMethod($shippingCountry, null);
342
343
        $this->iChoosePaymentMethod($paymentMethodName);
344
    }
345
346
    /**
347
     * @When I proceed selecting :paymentMethodName payment method
348
     */
349
    public function iProceedSelectingOfflinePaymentMethod($paymentMethodName = 'Offline')
350
    {
351
        $this->iProceedSelectingShippingCountryAndPaymentMethod(null, $paymentMethodName);
352
    }
353
354
    /**
355
     * @When /^I change shipping method to "([^"]*)"$/
356
     */
357
    public function iChangeShippingMethod($shippingMethodName)
358
    {
359
        $this->checkoutShippingStep->open();
360
        $this->checkoutShippingStep->selectShippingMethod($shippingMethodName);
361
        $this->checkoutShippingStep->continueCheckout();
362
    }
363
364
    /**
365
     * @Given /^I proceed logging as "([^"]*)" with "([^"]*)" password$/
366
     */
367
    public function iProceedLoggingAs($login, $password)
368
    {
369
        $this->checkoutSecurityStep->open();
370
        $this->checkoutSecurityStep->logInAsExistingUser($login, $password);
371
372
        $this->checkoutAddressingStep->continueCheckout();
373
    }
374
375
    /**
376
     * @When /^I proceed as guest "([^"]*)" with "([^"]*)" as shipping country$/
377
     */
378
    public function iProceedLoggingAsGuestWithAsShippingCountry($email, $shippingCountry)
379
    {
380
        $this->checkoutSecurityStep->open();
381
        $this->checkoutSecurityStep->proceedAsGuest($email);
382
383
        $this->iProceedSelectingShippingCountry($shippingCountry);
384
    }
385
386
    /**
387
     * @When I confirm my order
388
     */
389
    public function iConfirmMyOrder()
390
    {
391
        $this->checkoutFinalizeStep->confirmOrder();
392
    }
393
394
    /**
395
     * @When I specify the password as :password
396
     */
397
    public function iSpecifyThePasswordAs($password)
398
    {
399
        $this->addressingPage->specifyPassword($password);
400
    }
401
402
    /**
403
     * @When I sign in
404
     */
405
    public function iSignIn()
406
    {
407
        $this->addressingPage->signIn();
408
    }
409
410
    /**
411
     * @Then I should see the thank you page
412
     */
413
    public function iShouldSeeTheThankYouPage()
414
    {
415
        /** @var UserInterface $user */
416
        $user = $this->sharedStorage->get('user');
417
        $customer = $user->getCustomer();
418
419
        expect($this->checkoutThankYouPage->hasThankYouMessageFor($customer->getFullName()))->toBe(true);
420
    }
421
422
    /**
423
     * @Then I should be redirected back to the thank you page
424
     */
425
    public function iShouldBeRedirectedBackToTheThankYouPage()
426
    {
427
        $this->checkoutThankYouPage->waitForResponse(5);
428
429
        expect($this->checkoutThankYouPage->isOpen())->toBe(true);
430
    }
431
432
    /**
433
     * @Then I should be redirected back to the order payment page
434
     */
435
    public function iShouldBeRedirectedBackToTheOrderPaymentPage()
436
    {
437
        $this->orderPaymentsPage->waitForResponse(5, ['number' => $this->getLastOrder()->getNumber()]);
438
439
        expect($this->orderPaymentsPage->isOpen(['number' => $this->getLastOrder()->getNumber()]))->toBe(true);
440
    }
441
442
    /**
443
     * @Then I should be on the checkout shipping step
444
     */
445
    public function iShouldBeOnTheCheckoutShippingStep()
446
    {
447
        Assert::true(
448
            $this->shippingPage->isOpen(),
449
            'Checkout shipping page should be opened, but it is not.'
450
        );
451
    }
452
453
    /**
454
     * @Then I should be on the checkout summary step
455
     */
456
    public function iShouldBeOnTheCheckoutSummaryStep()
457
    {
458
        Assert::true(
459
            $this->summaryPage->isOpen(),
460
            'Checkout summary page should be opened, but it is not.'
461
        );
462
    }
463
464
    /**
465
     * @Then I should see two cancelled payments and new one ready to be paid
466
     */
467
    public function iShouldSeeTwoCancelledPaymentsAndNewOneReadyToBePaid()
468
    {
469
        expect($this->orderPaymentsPage->countPaymentWithSpecificState(PaymentInterface::STATE_CANCELLED))->toBe(2);
470
        expect($this->orderPaymentsPage->countPaymentWithSpecificState(PaymentInterface::STATE_NEW))->toBe(1);
471
    }
472
473
    /**
474
     * @Then /^I should(?:| also) be notified that the "([^"]+)" and the "([^"]+)" in (shipping|billing) details are required$/
475
     */
476
    public function iShouldBeNotifiedThatTheAndTheInShippingDetailsAreRequired($firstElement, $secondElement, $type)
477
    {
478
        $this->assertElementValidationMessage($type, $firstElement, sprintf('Please enter %s.', $firstElement));
479
        $this->assertElementValidationMessage($type, $secondElement, sprintf('Please enter %s.', $secondElement));
480
    }
481
482
    /**
483
     * @Then I should be informed that my order cannot be shipped to this address
484
     */
485
    public function iShouldBeInformedThatMyOrderCannotBeShippedToThisAddress()
486
    {
487
        Assert::true(
488
            $this->shippingPage->hasNoShippingMethodsMessage(),
489
            'Shipping page should have no shipping methods message but it does not.'
490
        );
491
    }
492
493
    /**
494
     * @Then I should be able to log in
495
     */
496
    public function iShouldBeAbleToLogIn()
497
    {
498
        Assert::true(
499
            $this->addressingPage->canSignIn(),
500
            'I should be able to login, but I am not.'
501
        );
502
    }
503
504
    /**
505
     * @Then the login form should no longer be accessible
506
     */
507
    public function theLoginFormShouldNoLongerBeAccessible()
508
    {
509
        Assert::false(
510
            $this->addressingPage->canSignIn(),
511
            'I should not be able to login, but I am.'
512
        );
513
    }
514
515
    /**
516
     * @Then I should be notified about bad credentials
517
     */
518
    public function iShouldBeNotifiedAboutBadCredentials()
519
    {
520
        Assert::true(
521
            $this->addressingPage->checkInvalidCredentialsValidation(),
522
            'I should see validation error, but I do not.'
523
        );
524
    }
525
526
    /**
527
     * @Then my order's shipping address should be to :fullName
528
     */
529
    public function iShouldSeeThisShippingAddressAsShippingAddress($fullName)
530
    {
531
        $address = $this->sharedStorage->get('shipping_address_'.StringInflector::nameToLowercaseCode($fullName));
532
        Assert::true(
533
            $this->summaryPage->hasShippingAddress($address),
534
            'Shipping address is improper.'
535
        );
536
    }
537
538
    /**
539
     * @Then my order's billing address should be to :fullName
540
     */
541
    public function iShouldSeeThisBillingAddressAsBillingAddress($fullName)
542
    {
543
        $address = $this->sharedStorage->get('billing_address_'.StringInflector::nameToLowercaseCode($fullName));
544
        Assert::true(
545
            $this->summaryPage->hasBillingAddress($address),
546
            'Billing address is improper.'
547
        );
548
    }
549
550
    /**
551
     * @Then address to :fullName should be used for both shipping and billing of my order`
552
     */
553
    public function iShouldSeeThisShippingAddressAsShippingAndBillingAddress($fullName)
554
    {
555
        $this->iShouldSeeThisShippingAddressAsShippingAddress($fullName);
556
        $this->iShouldSeeThisBillingAddressAsBillingAddress($fullName);
557
    }
558
559
    /**
560
     * @Given I am at the checkout payment step
561
     */
562
    public function iAmAtTheCheckoutPaymentStep()
563
    {
564
        $this->paymentPage->open();
565
    }
566
567
    /**
568
     * @When I complete the payment step
569
     */
570
    public function iCompleteThePaymentStep()
571
    {
572
        $this->paymentPage->nextStep();
573
    }
574
575
    /**
576
     * @When I select :paymentMethodName payment method
577
     */
578
    public function iSelectPaymentMethod($paymentMethodName)
579
    {
580
        $this->paymentPage->selectPaymentMethod($paymentMethodName);
581
    }
582
583
    /**
584
     * @Then I should not be able to select :paymentMethodName payment method
585
     */
586
    public function iShouldNotBeAbleToSelectPaymentMethod($paymentMethodName)
587
    {
588
        Assert::false(
589
            $this->paymentPage->hasPaymentMethod($paymentMethodName),
590
            sprintf('Payment method "%s" should not be available but it does.', $paymentMethodName)
591
        );
592
    }
593
594
    /**
595
     * @When I proceed order with :shippingMethod shipping method and :paymentMethod payment
596
     */
597
    public function iProceedOrderWithShippingMethodAndPayment($shippingMethod, $paymentMethod)
598
    {
599
        $this->iSelectShippingMethod($shippingMethod);
600
        $this->iCompleteTheShippingStep();
601
        $this->iSelectPaymentMethod($paymentMethod);
602
        $this->iCompleteThePaymentStep();
603
    }
604
605
    /**
606
     * @Given I should have :quantity :productName products in the cart
607
     */
608
    public function iShouldHaveProductsInTheCart($quantity, $productName)
609
    {
610
        Assert::true(
611
            $this->summaryPage->hasItemWithProductAndQuantity($productName, $quantity),
612
            sprintf('There is no "%s" with quantity %s on order summary page, but it should.', $productName, $quantity)
613
        );
614
    }
615
616
    /**
617
     * @Then /^the ("[^"]+" product) should have unit price discounted by ("\$\d+")$/
618
     */
619
    public function theShouldHaveUnitPriceDiscountedFor(ProductInterface $product, $amount)
620
    {
621
        Assert::true(
622
            $this->summaryPage->hasProductDiscountedUnitPriceBy($product, $amount),
623
            sprintf('Product %s should have discounted price by %s, but it does not have.', $product->getName(), $amount)
624
        );
625
    }
626
627
    /**
628
     * @Then /^my order total should be ("\$\d+")$/
629
     */
630
    public function myOrderTotalShouldBe($total)
631
    {
632
        Assert::true(
633
            $this->summaryPage->hasOrderTotal($total),
634
            sprintf('Order total should have %s total, but it does not have.', $total)
635
        );
636
    }
637
638
    /**
639
     * @param string $type
640
     * @param string $element
641
     * @param string $expectedMessage
642
     *
643
     * @throws \InvalidArgumentException
644
     */
645
    private function assertElementValidationMessage($type, $element, $expectedMessage)
646
    {
647
        $element = sprintf('%s_%s', $type, implode('_', explode(' ', $element)));
648
        Assert::true(
649
            $this->addressingPage->checkValidationMessageFor($element, $expectedMessage),
650
            sprintf('The %s should be required.', $element)
651
        );
652
    }
653
654
    /**
655
     * @return OrderInterface
656
     *
657
     * @throws \RuntimeException
658
     */
659
    private function getLastOrder()
660
    {
661
        $customer = $this->sharedStorage->get('user')->getCustomer();
662
        $orders = $this->orderRepository->findByCustomer($customer);
0 ignored issues
show
Bug introduced by
The method findByCustomer() does not exist on Sylius\Component\Order\R...rderRepositoryInterface. Did you maybe mean findBy()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
663
        $lastOrder = end($orders);
664
665
        if (false === $lastOrder) {
666
            throw new \RuntimeException(sprintf('There is no last order for %s', $customer->getFullName()));
667
        }
668
669
        return $lastOrder;
670
    }
671
}
672