Completed
Push — symfony3-fqcn-sylius ( 26083b...02605f )
by Kamil
20:07
created

CheckoutContext::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 25
nc 1
nop 12

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\AddressPageInterface;
16
use Sylius\Behat\Page\Shop\Checkout\CompletePageInterface;
17
use Sylius\Behat\Page\Shop\Checkout\SelectPaymentPageInterface;
18
use Sylius\Behat\Page\Shop\Checkout\SelectShippingPageInterface;
19
use Sylius\Behat\Page\Shop\HomePageInterface;
20
use Sylius\Behat\Page\Shop\Order\ShowPageInterface;
21
use Sylius\Behat\Page\Shop\Order\ThankYouPageInterface;
22
use Sylius\Behat\Page\SymfonyPageInterface;
23
use Sylius\Behat\Page\UnexpectedPageException;
24
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
25
use Sylius\Behat\Service\SharedStorageInterface;
26
use Sylius\Component\Addressing\Comparator\AddressComparatorInterface;
27
use Sylius\Component\Addressing\Model\CountryInterface;
28
use Sylius\Component\Core\Formatter\StringInflector;
29
use Sylius\Component\Core\Model\AddressInterface;
30
use Sylius\Component\Core\Model\OrderInterface;
31
use Sylius\Component\Core\Model\ProductInterface;
32
use Sylius\Component\Core\Model\ShippingMethodInterface;
33
use Sylius\Component\Order\Repository\OrderRepositoryInterface;
34
use Sylius\Component\Payment\Model\PaymentMethodInterface;
35
use Sylius\Component\Resource\Factory\FactoryInterface;
36
use Webmozart\Assert\Assert;
37
38
/**
39
 * @author Arkadiusz Krakowiak <[email protected]>
40
 */
41
final class CheckoutContext implements Context
42
{
43
    /**
44
     * @var SharedStorageInterface
45
     */
46
    private $sharedStorage;
47
48
    /**
49
     * @var HomePageInterface
50
     */
51
    private $homePage;
52
53
    /**
54
     * @var AddressPageInterface
55
     */
56
    private $addressPage;
57
58
    /**
59
     * @var SelectPaymentPageInterface
60
     */
61
    private $selectPaymentPage;
62
63
    /**
64
     * @var ThankYouPageInterface
65
     */
66
    private $thankYouPage;
67
68
    /**
69
     * @var SelectShippingPageInterface
70
     */
71
    private $selectShippingPage;
72
73
    /**
74
     * @var CompletePageInterface
75
     */
76
    private $completePage;
77
78
    /**
79
     * @var ShowPageInterface
80
     */
81
    private $orderDetails;
82
83
    /**
84
     * @var OrderRepositoryInterface
85
     */
86
    private $orderRepository;
87
88
    /**
89
     * @var FactoryInterface
90
     */
91
    private $addressFactory;
92
93
    /**
94
     * @var CurrentPageResolverInterface
95
     */
96
    private $currentPageResolver;
97
98
    /**
99
     * @var AddressComparatorInterface
100
     */
101
    private $addressComparator;
102
103
    /**
104
     * @param SharedStorageInterface $sharedStorage
105
     * @param HomePageInterface $homePage
106
     * @param AddressPageInterface $addressPage
107
     * @param SelectPaymentPageInterface $selectPaymentPage
108
     * @param ThankYouPageInterface $thankYouPage
109
     * @param SelectShippingPageInterface $selectShippingPage
110
     * @param CompletePageInterface $completePage
111
     * @param ShowPageInterface $orderDetails
112
     * @param OrderRepositoryInterface $orderRepository
113
     * @param FactoryInterface $addressFactory
114
     * @param CurrentPageResolverInterface $currentPageResolver
115
     * @param AddressComparatorInterface $addressComparator
116
     */
117
    public function __construct(
118
        SharedStorageInterface $sharedStorage,
119
        HomePageInterface $homePage,
120
        AddressPageInterface $addressPage,
121
        SelectPaymentPageInterface $selectPaymentPage,
122
        ThankYouPageInterface $thankYouPage,
123
        SelectShippingPageInterface $selectShippingPage,
124
        CompletePageInterface $completePage,
125
        ShowPageInterface $orderDetails,
126
        OrderRepositoryInterface $orderRepository,
127
        FactoryInterface $addressFactory,
128
        CurrentPageResolverInterface $currentPageResolver,
129
        AddressComparatorInterface $addressComparator
130
    ) {
131
        $this->sharedStorage = $sharedStorage;
132
        $this->homePage = $homePage;
133
        $this->addressPage = $addressPage;
134
        $this->selectPaymentPage = $selectPaymentPage;
135
        $this->thankYouPage = $thankYouPage;
136
        $this->selectShippingPage = $selectShippingPage;
137
        $this->completePage = $completePage;
138
        $this->orderDetails = $orderDetails;
139
        $this->orderRepository = $orderRepository;
140
        $this->addressFactory = $addressFactory;
141
        $this->currentPageResolver = $currentPageResolver;
142
        $this->addressComparator = $addressComparator;
143
    }
144
145
    /**
146
     * @Given I was at the checkout summary step
147
     */
148
    public function iWasAtTheCheckoutSummaryStep()
149
    {
150
        $this->iSpecifiedTheShippingAddress($this->createDefaultAddress());
151
        $this->iProceedOrderWithShippingMethodAndPayment('Free', 'Offline');
152
    }
153
154
    /**
155
     * @Given /^I proceed without selecting shipping address$/
156
     */
157
    public function iProceedWithoutSelectingShippingAddress()
158
    {
159
        $this->addressPage->open();
160
        $this->addressPage->nextStep();
161
    }
162
163
    /**
164
     * @Given I have proceeded selecting :shippingMethodName shipping method
165
     */
166
    public function iHaveProceededSelectingShippingMethod($shippingMethodName)
167
    {
168
        $this->iSelectShippingMethod($shippingMethodName);
169
        $this->selectShippingPage->nextStep();
170
    }
171
172
    /**
173
     * @Given I am at the checkout addressing step
174
     * @When I go back to addressing step of the checkout
175
     */
176
    public function iAmAtTheCheckoutAddressingStep()
177
    {
178
        $this->addressPage->open();
179
    }
180
181
    /**
182
     * @When I try to open checkout addressing page
183
     */
184
    public function iTryToOpenCheckoutAddressingPage()
185
    {
186
        $this->addressPage->tryToOpen();
187
    }
188
189
    /**
190
     * @When I try to open checkout shipping page
191
     */
192
    public function iTryToOpenCheckoutShippingPage()
193
    {
194
        $this->selectShippingPage->tryToOpen();
195
    }
196
197
    /**
198
     * @When I try to open checkout payment page
199
     */
200
    public function iTryToOpenCheckoutPaymentPage()
201
    {
202
        $this->selectPaymentPage->tryToOpen();
203
    }
204
205
    /**
206
     * @When I try to open checkout complete page
207
     */
208
    public function iTryToOpenCheckoutCompletePage()
209
    {
210
        $this->completePage->tryToOpen();
211
    }
212
213
    /**
214
     * @When /^I want to browse order details for (this order)$/
215
     */
216
    public function iWantToBrowseOrderDetailsForThisOrder(OrderInterface $order)
217
    {
218
        $this->orderDetails->open(['tokenValue' => $order->getTokenValue()]);
219
    }
220
221
    /**
222
     * @When /^I choose ("[^"]+" street) for shipping address$/
223
     */
224
    public function iChooseForShippingAddress(AddressInterface $address)
225
    {
226
        $this->addressPage->selectShippingAddressFromAddressBook($address);
227
    }
228
229
    /**
230
     * @When /^I choose ("[^"]+" street) for billing address$/
231
     */
232
    public function iChooseForBillingAddress(AddressInterface $address)
233
    {
234
        $this->addressPage->chooseDifferentBillingAddress();
235
        $this->addressPage->selectBillingAddressFromAddressBook($address);
236
    }
237
238
    /**
239
     * @When /^I specify the shipping (address as "[^"]+", "[^"]+", "[^"]+", "[^"]+" for "[^"]+")$/
240
     * @When /^I specify the shipping (address for "[^"]+" from "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+")$/
241
     * @When /^I (do not specify any shipping address) information$/
242
     * @When /^I change the shipping (address to "[^"]+", "[^"]+", "[^"]+", "[^"]+" for "[^"]+")$/
243
     */
244
    public function iSpecifyTheShippingAddressAs(AddressInterface $address)
245
    {
246
        $key = sprintf(
247
            'shipping_address_%s_%s',
248
            strtolower($address->getFirstName()),
249
            strtolower($address->getLastName())
250
        );
251
        $this->sharedStorage->set($key, $address);
252
253
        $this->addressPage->specifyShippingAddress($address);
254
    }
255
256
    /**
257
     * @When I specify shipping country province as :province
258
     */
259
    public function iSpecifyShippingCountryProvinceAs($province)
260
    {
261
        $this->addressPage->selectShippingAddressProvince($province);
262
    }
263
264
    /**
265
     * @When I specify billing country province as :province
266
     */
267
    public function iSpecifyBillingCountryProvinceAs($province)
268
    {
269
        $this->addressPage->selectBillingAddressProvince($province);
270
    }
271
272
    /**
273
     * @When /^I specify the billing (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
274
     * @When /^I specify the billing (address for "([^"]+)" from "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)")$/
275
     * @When /^I (do not specify any billing address) information$/
276
     */
277
    public function iSpecifyTheBillingAddressAs(AddressInterface $address)
278
    {
279
        $this->iChooseTheDifferentBillingAddress();
280
        $key = sprintf(
281
            'billing_address_%s_%s',
282
            strtolower($address->getFirstName()),
283
            strtolower($address->getLastName())
284
        );
285
        $this->sharedStorage->set($key, $address);
286
287
        $this->addressPage->specifyBillingAddress($address);
288
    }
289
290
    /**
291
     * @When /^I specified the shipping (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
292
     */
293
    public function iSpecifiedTheShippingAddress(AddressInterface $address)
294
    {
295
        $this->addressPage->open();
296
        $this->iSpecifyTheShippingAddressAs($address);
297
298
        $key = sprintf('billing_address_%s_%s', strtolower($address->getFirstName()), strtolower($address->getLastName()));
299
        $this->sharedStorage->set($key, $address);
300
301
        $this->iCompleteTheAddressingStep();
302
    }
303
304
    /**
305
     * @When I choose the different billing address
306
     */
307
    public function iChooseTheDifferentBillingAddress()
308
    {
309
        $this->addressPage->chooseDifferentBillingAddress();
310
    }
311
312
    /**
313
     * @When I specify the email as :email
314
     * @When I do not specify the email
315
     */
316
    public function iSpecifyTheEmail($email = null)
317
    {
318
        $this->addressPage->specifyEmail($email);
319
    }
320
321
    /**
322
     * @Given I have selected :shippingMethod shipping method
323
     * @When I select :shippingMethod shipping method
324
     */
325
    public function iSelectShippingMethod($shippingMethod)
326
    {
327
        $this->selectShippingPage->selectShippingMethod($shippingMethod);
328
    }
329
330
    /**
331
     * @Then I should not be able to select :shippingMethodName shipping method
332
     */
333
    public function iShouldNotBeAbleToSelectShippingMethod($shippingMethodName)
334
    {
335
        Assert::false(
336
            in_array($shippingMethodName, $this->selectShippingPage->getShippingMethods(), true),
337
            sprintf('Shipping method "%s" should not be available but it does.', $shippingMethodName)
338
        );
339
    }
340
341
    /**
342
     * @Then I should have :shippingMethodName shipping method available as the first choice
343
     */
344
    public function iShouldHaveShippingMethodAvailableAsFirstChoice($shippingMethodName)
345
    {
346
        $shippingMethods = $this->selectShippingPage->getShippingMethods();
347
        $firstShippingMethod = reset($shippingMethods);
348
349
        Assert::same($shippingMethodName, $firstShippingMethod);
350
    }
351
352
    /**
353
     * @Then I should have :shippingMethodName shipping method available as the last choice
354
     */
355
    public function iShouldHaveShippingMethodAvailableAsLastChoice($shippingMethodName)
356
    {
357
        $shippingMethods = $this->selectShippingPage->getShippingMethods();
358
        $lastShippingMethod = end($shippingMethods);
359
360
        Assert::same($shippingMethodName, $lastShippingMethod);
361
    }
362
363
    /**
364
     * @Then I should have :countryName selected as country
365
     */
366
    public function iShouldHaveSelectedAsCountry($countryName)
367
    {
368
        Assert::eq(
369
            $countryName,
370
            $this->addressPage->getShippingAddressCountry(),
371
            sprintf('Shipping country should be %s but is not.', $countryName)
372
        );
373
    }
374
375
    /**
376
     * @Then I should have no country selected
377
     */
378
    public function iShouldHaveNoCountrySelected()
379
    {
380
        Assert::eq(
381
            'Select',
382
            $this->addressPage->getShippingAddressCountry(),
383
            'Shipping country should not be selected.'
384
        );
385
    }
386
387
    /**
388
     * @When I complete the addressing step
389
     * @When I try to complete the addressing step
390
     */
391
    public function iCompleteTheAddressingStep()
392
    {
393
        $this->addressPage->nextStep();
394
    }
395
396
    /**
397
     * @When I go back to store
398
     */
399
    public function iGoBackToStore()
400
    {
401
        $this->addressPage->backToStore();
402
    }
403
404
    /**
405
     * @When /^I(?:| try to) complete the shipping step$/
406
     */
407
    public function iCompleteTheShippingStep()
408
    {
409
        $this->selectShippingPage->nextStep();
410
    }
411
412
    /**
413
     * @When I decide to change my address
414
     */
415
    public function iDecideToChangeMyAddress()
416
    {
417
        $this->selectShippingPage->changeAddress();
418
    }
419
420
    /**
421
     * @When I decide to change order shipping method
422
     */
423
    public function iDecideToChangeMyShippingMethod()
424
    {
425
        $this->selectPaymentPage->changeShippingMethod();
426
    }
427
428
    /**
429
     * @When I want to browse thank you page
430
     */
431
    public function iWantToBrowseThankYouPageForThisOrder()
432
    {
433
        $this->thankYouPage->open();
434
    }
435
436
    /**
437
     * @When I go to the addressing step
438
     */
439
    public function iGoToTheAddressingStep()
440
    {
441
        if ($this->selectShippingPage->isOpen()) {
442
            $this->selectShippingPage->changeAddressByStepLabel();
443
444
            return;
445
        }
446
447
        if ($this->selectPaymentPage->isOpen()) {
448
            $this->selectPaymentPage->changeAddressByStepLabel();
449
450
            return;
451
        }
452
453
        if ($this->completePage->isOpen()) {
454
            $this->completePage->changeAddress();
455
456
            return;
457
        }
458
459
        throw new UnexpectedPageException('It is impossible to go to addressing step from current page.');
460
    }
461
462
    /**
463
     * @When I go to the shipping step
464
     */
465
    public function iGoToTheShippingStep()
466
    {
467
        if ($this->selectPaymentPage->isOpen()) {
468
            $this->selectPaymentPage->changeShippingMethodByStepLabel();
469
470
            return;
471
        }
472
473
        if ($this->completePage->isOpen()) {
474
            $this->completePage->changeShippingMethod();
475
476
            return;
477
        }
478
479
        throw new UnexpectedPageException('It is impossible to go to shipping step from current page.');
480
    }
481
482
    /**
483
     * @When I decide to change the payment method
484
     */
485
    public function iGoToThePaymentStep()
486
    {
487
        $this->completePage->changePaymentMethod();
488
    }
489
490
    /**
491
     * @When /^I proceed selecting ("[^"]+" as shipping country)$/
492
     */
493
    public function iProceedSelectingShippingCountry(CountryInterface $shippingCountry = null)
494
    {
495
        $this->addressPage->open();
496
        $shippingAddress = $this->createDefaultAddress();
497
        if (null !== $shippingCountry) {
498
            $shippingAddress->setCountryCode($shippingCountry->getCode());
499
        }
500
501
        $this->addressPage->specifyShippingAddress($shippingAddress);
502
        $this->addressPage->nextStep();
503
    }
504
505
    /**
506
     * @When /^I proceed selecting ("[^"]+" as shipping country) with "([^"]+)" method$/
507
     */
508
    public function iProceedSelectingShippingCountryAndShippingMethod(CountryInterface $shippingCountry = null, $shippingMethodName)
0 ignored issues
show
Coding Style introduced by
Parameters which have default values should be placed at the end.

If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway:

// $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
Loading history...
509
    {
510
        $this->iProceedSelectingShippingCountry($shippingCountry);
511
512
        $this->selectShippingPage->selectShippingMethod($shippingMethodName ?: 'Free');
513
        $this->selectShippingPage->nextStep();
514
    }
515
516
    /**
517
     * @When /^I proceed selecting "([^"]+)" shipping method$/
518
     * @Given /^I chose "([^"]*)" shipping method$/
519
     */
520
    public function iProceedSelectingShippingMethod($shippingMethodName)
521
    {
522
        $this->iProceedSelectingShippingCountryAndShippingMethod(null, $shippingMethodName);
523
    }
524
525
    /**
526
     * @When /^I choose "([^"]*)" payment method$/
527
     */
528
    public function iChoosePaymentMethod($paymentMethodName)
529
    {
530
        $this->selectPaymentPage->selectPaymentMethod($paymentMethodName ?: 'Offline');
531
        $this->selectPaymentPage->nextStep();
532
    }
533
534
    /**
535
     * @When I change payment method to :paymentMethodName
536
     */
537
    public function iChangePaymentMethodTo($paymentMethodName)
538
    {
539
        $this->orderDetails->choosePaymentMethod($paymentMethodName);
540
    }
541
542
    /**
543
     * @When /^I proceed selecting "([^"]*)" as shipping country with "([^"]*)" payment method$/
544
     */
545
    public function iProceedSelectingShippingCountryAndPaymentMethod($shippingCountry, $paymentMethodName)
546
    {
547
        $this->iProceedSelectingShippingCountryAndShippingMethod($shippingCountry, null);
548
549
        $this->iChoosePaymentMethod($paymentMethodName);
550
    }
551
552
    /**
553
     * @When I go back to shipping step of the checkout
554
     */
555
    public function iGoBackToShippingStepOfTheCheckout()
556
    {
557
        $this->selectShippingPage->open();
558
    }
559
560
    /**
561
     * @Given I have proceeded selecting :paymentMethodName payment method
562
     * @When /^I (?:proceed|proceeded) selecting "([^"]+)" payment method$/
563
     */
564
    public function iProceedSelectingPaymentMethod($paymentMethodName = 'Offline')
565
    {
566
        $this->iProceedSelectingShippingCountryAndPaymentMethod(null, $paymentMethodName);
567
    }
568
569
    /**
570
     * @When /^I change shipping method to "([^"]*)"$/
571
     */
572
    public function iChangeShippingMethod($shippingMethodName)
573
    {
574
        $this->selectPaymentPage->changeShippingMethod();
575
        $this->selectShippingPage->selectShippingMethod($shippingMethodName);
576
        $this->selectShippingPage->nextStep();
577
    }
578
579
    /**
580
     * @When /^I provide additional note like "([^"]+)"$/
581
     */
582
    public function iProvideAdditionalNotesLike($notes)
583
    {
584
        $this->sharedStorage->set('additional_note', $notes);
585
        $this->completePage->addNotes($notes);
586
    }
587
588
    /**
589
     * @When /^I proceed as guest "([^"]*)" with ("[^"]+" as shipping country)$/
590
     */
591
    public function iProceedLoggingAsGuestWithAsShippingCountry($email, CountryInterface $shippingCountry = null)
592
    {
593
        $this->addressPage->open();
594
        $this->addressPage->specifyEmail($email);
595
        $shippingAddress = $this->createDefaultAddress();
596
        if (null !== $shippingCountry) {
597
            $shippingAddress->setCountryCode($shippingCountry->getCode());
598
        }
599
600
        $this->addressPage->specifyShippingAddress($shippingAddress);
601
        $this->addressPage->nextStep();
602
    }
603
604
    /**
605
     * @When I return to the checkout summary step
606
     */
607
    public function iReturnToTheCheckoutSummaryStep()
608
    {
609
        $this->completePage->open();
610
    }
611
612
    /**
613
     * @When I want to complete checkout
614
     */
615
    public function iWantToCompleteCheckout()
616
    {
617
        $this->completePage->tryToOpen();
618
    }
619
620
    /**
621
     * @Given I have confirmed my order
622
     * @When I confirm my order
623
     */
624
    public function iConfirmMyOrder()
625
    {
626
        $this->completePage->confirmOrder();
627
    }
628
629
    /**
630
     * @When I specify the password as :password
631
     */
632
    public function iSpecifyThePasswordAs($password)
633
    {
634
        $this->addressPage->specifyPassword($password);
635
    }
636
637
    /**
638
     * @When I sign in
639
     */
640
    public function iSignIn()
641
    {
642
        $this->addressPage->signIn();
643
    }
644
645
    /**
646
     * @Then I should see the thank you page
647
     */
648
    public function iShouldSeeTheThankYouPage()
649
    {
650
        Assert::true(
651
            $this->thankYouPage->hasThankYouMessage(),
652
            'I should see thank you message, but I do not.'
653
        );
654
    }
655
656
    /**
657
     * @Then I should not see the thank you page
658
     */
659
    public function iShouldNotSeeTheThankYouPage()
660
    {
661
        Assert::false(
662
            $this->thankYouPage->isOpen(),
663
            'I should not see thank you message, but I do.'
664
        );
665
    }
666
667
    /**
668
     * @Given I should be informed with :paymentMethod payment method instructions
669
     */
670
    public function iShouldBeInformedWithPaymentMethodInstructions(PaymentMethodInterface $paymentMethod)
671
    {
672
        Assert::same(
673
            $this->thankYouPage->getInstructions(),
674
            $paymentMethod->getInstructions()
675
        );
676
    }
677
678
    /**
679
     * @Then /^I should be redirected (?:|back )to the thank you page$/
680
     */
681
    public function iShouldBeRedirectedBackToTheThankYouPage()
682
    {
683
        $this->thankYouPage->waitForResponse(5);
684
685
        Assert::true(
686
            $this->thankYouPage->isOpen(),
687
            'I should be on thank you page, but I am not.'
688
        );
689
    }
690
691
    /**
692
     * @Then I should be on the checkout shipping step
693
     */
694
    public function iShouldBeOnTheCheckoutShippingStep()
695
    {
696
        Assert::true(
697
            $this->selectShippingPage->isOpen(),
698
            'Checkout shipping page should be opened, but it is not.'
699
        );
700
    }
701
702
    /**
703
     * @Then I should be on the checkout payment step
704
     */
705
    public function iShouldBeOnTheCheckoutPaymentStep()
706
    {
707
        Assert::true(
708
            $this->selectPaymentPage->isOpen(),
709
            'Checkout payment page should be opened, but it is not.'
710
        );
711
    }
712
713
    /**
714
     * @Then I should be on the checkout summary step
715
     */
716
    public function iShouldBeOnTheCheckoutSummaryStep()
717
    {
718
        Assert::true(
719
            $this->completePage->isOpen(),
720
            'Checkout summary page should be opened, but it is not.'
721
        );
722
    }
723
724
    /**
725
     * @Then /^I should(?:| also) be notified that the "([^"]+)" and the "([^"]+)" in (shipping|billing) details are required$/
726
     */
727
    public function iShouldBeNotifiedThatTheAndTheInShippingDetailsAreRequired($firstElement, $secondElement, $type)
728
    {
729
        $this->assertElementValidationMessage($type, $firstElement, sprintf('Please enter %s.', $firstElement));
730
        $this->assertElementValidationMessage($type, $secondElement, sprintf('Please enter %s.', $secondElement));
731
    }
732
733
    /**
734
     * @Then I should be informed that my order cannot be shipped to this address
735
     */
736
    public function iShouldBeInformedThatMyOrderCannotBeShippedToThisAddress()
737
    {
738
        Assert::true(
739
            $this->selectShippingPage->hasNoShippingMethodsMessage(),
740
            'Shipping page should have no shipping methods message but it does not.'
741
        );
742
    }
743
744
    /**
745
     * @Then I should be able to log in
746
     */
747
    public function iShouldBeAbleToLogIn()
748
    {
749
        Assert::true(
750
            $this->addressPage->canSignIn(),
751
            'I should be able to login, but I am not.'
752
        );
753
    }
754
755
    /**
756
     * @Then the login form should no longer be accessible
757
     */
758
    public function theLoginFormShouldNoLongerBeAccessible()
759
    {
760
        Assert::false(
761
            $this->addressPage->canSignIn(),
762
            'I should not be able to login, but I am.'
763
        );
764
    }
765
766
    /**
767
     * @Then I should be notified about bad credentials
768
     */
769
    public function iShouldBeNotifiedAboutBadCredentials()
770
    {
771
        Assert::true(
772
            $this->addressPage->checkInvalidCredentialsValidation(),
773
            'I should see validation error, but I do not.'
774
        );
775
    }
776
777
    /**
778
     * @Then my order's shipping address should be to :fullName
779
     */
780
    public function iShouldSeeThisShippingAddressAsShippingAddress($fullName)
781
    {
782
        $address = $this->sharedStorage->get('shipping_address_'.StringInflector::nameToLowercaseCode($fullName));
783
        Assert::true(
784
            $this->completePage->hasShippingAddress($address),
785
            'Shipping address is improper.'
786
        );
787
    }
788
789
    /**
790
     * @Then my order's billing address should be to :fullName
791
     */
792
    public function iShouldSeeThisBillingAddressAsBillingAddress($fullName)
793
    {
794
        $address = $this->sharedStorage->get('billing_address_'.StringInflector::nameToLowercaseCode($fullName));
795
        Assert::true(
796
            $this->completePage->hasBillingAddress($address),
797
            'Billing address is improper.'
798
        );
799
    }
800
801
    /**
802
     * @Then address to :fullName should be used for both shipping and billing of my order
803
     */
804
    public function iShouldSeeThisShippingAddressAsShippingAndBillingAddress($fullName)
805
    {
806
        $this->iShouldSeeThisShippingAddressAsShippingAddress($fullName);
807
        $this->iShouldSeeThisBillingAddressAsBillingAddress($fullName);
808
    }
809
810
    /**
811
     * @Given I am at the checkout payment step
812
     * @When I go back to payment step of the checkout
813
     */
814
    public function iAmAtTheCheckoutPaymentStep()
815
    {
816
        $this->selectPaymentPage->open();
817
    }
818
819
    /**
820
     * @When I complete the payment step
821
     */
822
    public function iCompleteThePaymentStep()
823
    {
824
        $this->selectPaymentPage->nextStep();
825
    }
826
827
    /**
828
     * @When I select :name payment method
829
     */
830
    public function iSelectPaymentMethod($name)
831
    {
832
        $this->selectPaymentPage->selectPaymentMethod($name);
833
    }
834
835
    /**
836
     * @When /^I do not modify anything$/
837
     */
838
    public function iDoNotModifyAnything()
839
    {
840
        // Intentionally left blank to fulfill context expectation
841
    }
842
843
    /**
844
     * @Then I should not be able to select :paymentMethodName payment method
845
     */
846
    public function iShouldNotBeAbleToSelectPaymentMethod($paymentMethodName)
847
    {
848
        Assert::false(
849
            $this->selectPaymentPage->hasPaymentMethod($paymentMethodName),
850
            sprintf('Payment method "%s" should not be available, but it does.', $paymentMethodName)
851
        );
852
    }
853
854
    /**
855
     * @Then I should be able to select :paymentMethodName payment method
856
     */
857
    public function iShouldBeAbleToSelectPaymentMethod($paymentMethodName)
858
    {
859
        Assert::true(
860
            $this->selectPaymentPage->hasPaymentMethod($paymentMethodName),
861
            sprintf('Payment method "%s" should be available, but it does not.', $paymentMethodName)
862
        );
863
    }
864
865
    /**
866
     * @Given I have proceeded order with :shippingMethod shipping method and :paymentMethod payment
867
     * @When I proceed with :shippingMethod shipping method and :paymentMethod payment
868
     */
869
    public function iProceedOrderWithShippingMethodAndPayment($shippingMethod, $paymentMethod)
870
    {
871
        $this->iSelectShippingMethod($shippingMethod);
872
        $this->iCompleteTheShippingStep();
873
        $this->iSelectPaymentMethod($paymentMethod);
874
        $this->iCompleteThePaymentStep();
875
    }
876
877
    /**
878
     * @Given I should have :quantity :productName products in the cart
879
     */
880
    public function iShouldHaveProductsInTheCart($quantity, $productName)
881
    {
882
        Assert::true(
883
            $this->completePage->hasItemWithProductAndQuantity($productName, $quantity),
884
            sprintf('There is no "%s" with quantity %s on order summary page, but it should.', $productName, $quantity)
885
        );
886
    }
887
888
    /**
889
     * @Then my order shipping should be :price
890
     */
891
    public function myOrderShippingShouldBe($price)
892
    {
893
        Assert::true(
894
            $this->completePage->hasShippingTotal($price),
895
            sprintf('The shipping total should be %s, but it is not.',$price)
896
        );
897
    }
898
899
    /**
900
     * @Then /^the ("[^"]+" product) should have unit price discounted by ("\$\d+")$/
901
     */
902
    public function theShouldHaveUnitPriceDiscountedFor(ProductInterface $product, $amount)
903
    {
904
        Assert::true(
905
            $this->completePage->hasProductDiscountedUnitPriceBy($product, $amount),
906
            sprintf('Product %s should have discounted price by %s, but it does not have.', $product->getName(), $amount)
907
        );
908
    }
909
910
    /**
911
     * @Then /^my order total should be ("(?:\£|\$)\d+")$/
912
     */
913
    public function myOrderTotalShouldBe($total)
914
    {
915
        Assert::true(
916
            $this->completePage->hasOrderTotal($total),
917
            sprintf('Order total should have %s total, but it does not have.', $total)
918
        );
919
    }
920
921
    /**
922
     * @Then my order promotion total should be :promotionTotal
923
     */
924
    public function myOrderPromotionTotalShouldBe($promotionTotal)
925
    {
926
        Assert::true(
927
            $this->completePage->hasPromotionTotal($promotionTotal),
928
            sprintf('The total discount should be %s, but it does not.', $promotionTotal)
929
        );
930
    }
931
932
    /**
933
     * @Then :promotionName should be applied to my order
934
     */
935
    public function shouldBeAppliedToMyOrder($promotionName)
936
    {
937
        Assert::true(
938
            $this->completePage->hasPromotion($promotionName),
939
            sprintf('The promotion %s should appear on the page, but it does not.', $promotionName)
940
        );
941
    }
942
943
    /**
944
     * @Given my tax total should be :taxTotal
945
     */
946
    public function myTaxTotalShouldBe($taxTotal)
947
    {
948
        Assert::true(
949
            $this->completePage->hasTaxTotal($taxTotal),
950
            sprintf('The tax total should be %s, but it does not.', $taxTotal)
951
        );
952
    }
953
954
    /**
955
     * @Then my order's shipping method should be :shippingMethod
956
     */
957
    public function myOrderSShippingMethodShouldBe(ShippingMethodInterface $shippingMethod)
958
    {
959
        Assert::true(
960
            $this->completePage->hasShippingMethod($shippingMethod),
961
            sprintf('I should see %s shipping method, but I do not.', $shippingMethod->getName())
962
        );
963
    }
964
965
    /**
966
     * @Then my order's payment method should be :paymentMethod
967
     */
968
    public function myOrderSPaymentMethodShouldBe(PaymentMethodInterface $paymentMethod)
969
    {
970
        Assert::true(
971
            $this->completePage->hasPaymentMethod($paymentMethod),
972
            sprintf('I should see %s payment method, but I do not.', $paymentMethod->getName())
973
        );
974
    }
975
976
    /**
977
     * @Then I should be redirected to the homepage
978
     */
979
    public function iShouldBeRedirectedToTheHomepage()
980
    {
981
        Assert::true(
982
            $this->homePage->isOpen(),
983
            'Shop homepage should be opened, but it is not.'
984
        );
985
    }
986
987
    /**
988
     * @Then I should be redirected to the addressing step
989
     */
990
    public function iShouldBeRedirectedToTheAddressingStep()
991
    {
992
        Assert::true(
993
            $this->addressPage->isOpen(),
994
            'Checkout addressing step should be opened, but it is not.'
995
        );
996
    }
997
998
    /**
999
     * @Given I should be able to go to the shipping step again
1000
     */
1001
    public function iShouldBeAbleToGoToTheShippingStepAgain()
1002
    {
1003
        $this->addressPage->nextStep();
1004
1005
        Assert::true(
1006
            $this->selectShippingPage->isOpen(),
1007
            'Checkout shipping step should be opened, but it is not.'
1008
        );
1009
    }
1010
1011
    /**
1012
     * @Then I should be redirected to the shipping step
1013
     */
1014
    public function iShouldBeRedirectedToTheShippingStep()
1015
    {
1016
        Assert::true(
1017
            $this->selectShippingPage->isOpen(),
1018
            'Checkout shipping step should be opened, but it is not.'
1019
        );
1020
    }
1021
1022
    /**
1023
     * @Then /^I should be able to pay(?| again)$/
1024
     */
1025
    public function iShouldBeAbleToPayAgain()
1026
    {
1027
        Assert::true(
1028
            $this->orderDetails->hasPayAction(),
1029
            'I should be able to pay, but I am not able to.'
1030
        );
1031
    }
1032
1033
    /**
1034
     * @Then I should not be able to pay
1035
     */
1036
    public function iShouldNotBeAbleToPayAgain()
1037
    {
1038
        Assert::false(
1039
            $this->orderDetails->hasPayAction(),
1040
            'I should not be able to pay, but I am able to.'
1041
        );
1042
    }
1043
1044
    /**
1045
     * @Given I should be able to go to the payment step again
1046
     */
1047
    public function iShouldBeAbleToGoToThePaymentStepAgain()
1048
    {
1049
        $this->selectShippingPage->nextStep();
1050
1051
        Assert::true(
1052
            $this->selectPaymentPage->isOpen(),
1053
            'Checkout payment step should be opened, but it is not.'
1054
        );
1055
    }
1056
1057
    /**
1058
     * @Then I should be redirected to the payment step
1059
     */
1060
    public function iShouldBeRedirectedToThePaymentStep()
1061
    {
1062
        Assert::true(
1063
            $this->selectPaymentPage->isOpen(),
1064
            'Checkout payment step should be opened, but it is not.'
1065
        );
1066
    }
1067
1068
    /**
1069
     * @Given I should be able to go to the summary page again
1070
     */
1071
    public function iShouldBeAbleToGoToTheSummaryPageAgain()
1072
    {
1073
        $this->selectPaymentPage->nextStep();
1074
1075
        Assert::true(
1076
            $this->completePage->isOpen(),
1077
            'Checkout summary page should be opened, but it is not.'
1078
        );
1079
    }
1080
1081
    /**
1082
     * @Given I should see shipping method :shippingMethodName with fee :fee
1083
     */
1084
    public function iShouldSeeShippingFee($shippingMethodName, $fee)
1085
    {
1086
        Assert::true(
1087
            $this->selectShippingPage->hasShippingMethodFee($shippingMethodName, $fee),
1088
            sprintf('The shipping fee should be %s, but it does not.', $fee)
1089
        );
1090
    }
1091
1092
    /**
1093
     * @Given /^I have completed addressing step with email "([^"]+)" and ("[^"]+" based shipping address)$/
1094
     * @When /^I complete addressing step with email "([^"]+)" and ("[^"]+" based shipping address)$/
1095
     */
1096
    public function iCompleteAddressingStepWithEmail($email, AddressInterface $address)
1097
    {
1098
        $this->addressPage->open();
1099
        $this->iSpecifyTheEmail($email);
1100
        $this->iSpecifyTheShippingAddressAs($address);
1101
        $this->iCompleteTheAddressingStep();
1102
    }
1103
1104
    /**
1105
     * @Then the subtotal of :item item should be :price
1106
     */
1107
    public function theSubtotalOfItemShouldBe($item, $price)
1108
    {
1109
        $currentPage = $this->resolveCurrentStepPage();
1110
        $actualPrice = $currentPage->getItemSubtotal($item);
1111
1112
        Assert::eq(
1113
            $actualPrice,
1114
            $price,
1115
            sprintf('The %s subtotal should be %s, but is %s', $item, $price, $actualPrice)
1116
        );
1117
    }
1118
1119
    /**
1120
     * @Then the :product product should have unit price :price
1121
     */
1122
    public function theProductShouldHaveUnitPrice(ProductInterface $product, $price)
1123
    {
1124
        Assert::true(
1125
            $this->completePage->hasProductUnitPrice($product, $price),
1126
            sprintf('Product %s should have unit price %s, but it does not have.', $product->getName(), $price)
1127
        );
1128
    }
1129
1130
    /**
1131
     * @Given /^I should be notified that (this product) does not have sufficient stock$/
1132
     */
1133
    public function iShouldBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product)
1134
    {
1135
        Assert::true(
1136
            $this->completePage->hasProductOutOfStockValidationMessage($product),
1137
            sprintf('I should see validation message for %s product', $product->getName())
1138
        );
1139
    }
1140
1141
    /**
1142
     * @Then my order's locale should be :localeName
1143
     */
1144
    public function myOrderSLocaleShouldBe($localeName)
1145
    {
1146
        Assert::true(
1147
            $this->completePage->hasLocale($localeName),
1148
            'Order locale code is improper.'
1149
        );
1150
    }
1151
1152
    /**
1153
     * @Then my order's currency should be :currencyCode
1154
     */
1155
    public function myOrderSCurrencyShouldBe($currencyCode)
1156
    {
1157
        Assert::true(
1158
            $this->completePage->hasCurrency($currencyCode),
1159
            'Order currency code is improper.'
1160
        );
1161
    }
1162
1163
    /**
1164
     * @Then /^I should not be notified that (this product) does not have sufficient stock$/
1165
     */
1166
    public function iShouldNotBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product)
1167
    {
1168
        Assert::false(
1169
            $this->completePage->hasProductOutOfStockValidationMessage($product),
1170
            sprintf('I should see validation message for %s product', $product->getName())
1171
        );
1172
    }
1173
1174
    /**
1175
     * @Then I should be on the checkout addressing step
1176
     */
1177
    public function iShouldBeOnTheCheckoutAddressingStep()
1178
    {
1179
        Assert::true(
1180
            $this->addressPage->isOpen(),
1181
            'Checkout addressing page should be opened, but it is not.'
1182
        );
1183
    }
1184
1185
    /**
1186
     * @When I specify the province name manually as :provinceName for shipping address
1187
     */
1188
    public function iSpecifyTheProvinceNameManuallyAsForShippingAddress($provinceName)
1189
    {
1190
        $this->addressPage->specifyShippingAddressProvince($provinceName);
1191
    }
1192
1193
    /**
1194
     * @When I specify the province name manually as :provinceName for billing address
1195
     */
1196
    public function iSpecifyTheProvinceNameManuallyAsForBillingAddress($provinceName)
1197
    {
1198
        $this->addressPage->specifyBillingAddressProvince($provinceName);
1199
    }
1200
1201
    /**
1202
     * @Then I should not be able to specify province name manually for shipping address
1203
     */
1204
    public function iShouldNotBeAbleToSpecifyProvinceNameManuallyForShippingAddress()
1205
    {
1206
        Assert::false(
1207
            $this->addressPage->hasShippingAddressInput(),
1208
            'I should not be able to specify manually the province for shipping address, but I can.'
1209
        );
1210
    }
1211
1212
    /**
1213
     * @Then I should not be able to specify province name manually for billing address
1214
     */
1215
    public function iShouldNotBeAbleToSpecifyProvinceNameManuallyForBillingAddress()
1216
    {
1217
        Assert::false(
1218
            $this->addressPage->hasBillingAddressInput(),
1219
            'I should not be able to specify manually the province for billing address, but I can.'
1220
        );
1221
    }
1222
1223
    /**
1224
     * @Then I should see :provinceName in the shipping address
1225
     */
1226
    public function iShouldSeeInTheShippingAddress($provinceName)
1227
    {
1228
        Assert::true(
1229
            $this->completePage->hasShippingProvinceName($provinceName),
1230
            sprintf('Cannot find shipping address with province %s', $provinceName)
1231
        );
1232
    }
1233
1234
    /**
1235
     * @Then I should see :provinceName in the billing address
1236
     */
1237
    public function iShouldSeeInTheBillingAddress($provinceName)
1238
    {
1239
        Assert::true(
1240
            $this->completePage->hasBillingProvinceName($provinceName),
1241
            sprintf('Cannot find billing address with province %s', $provinceName)
1242
        );
1243
    }
1244
1245
    /**
1246
     * @When I do not select any shipping method
1247
     */
1248
    public function iDoNotSelectAnyShippingMethod()
1249
    {
1250
        // Intentionally left blank to fulfill context expectation
1251
    }
1252
1253
    /**
1254
     * @Then I should still be on the shipping step
1255
     */
1256
    public function iShouldStillBeOnTheShippingStep()
1257
    {
1258
        Assert::true(
1259
            $this->selectShippingPage->isOpen(),
1260
            'Select shipping page should be open, but it does not.'
1261
        );
1262
    }
1263
1264
    /**
1265
     * @Then I should be notified that the shipping method is required
1266
     */
1267
    public function iShouldBeNotifiedThatTheShippingMethodIsRequired()
1268
    {
1269
        Assert::same(
1270
            $this->selectShippingPage->getValidationMessageForShipment(),
1271
            'Please select shipping method.'
1272
        );
1273
    }
1274
1275
    /**
1276
     * @Then there should be information about no available shipping methods
1277
     * @Then there should be information about no shipping methods available for my shipping address
1278
     */
1279
    public function thereShouldBeInformationAboutNoShippingMethodsAvailableForMyShippingAddress()
1280
    {
1281
        Assert::true(
1282
            $this->selectShippingPage->hasNoAvailableShippingMethodsWarning(),
1283
            'There should be warning about no available shipping methods, but it does not.'
1284
        );
1285
    }
1286
1287
    /**
1288
     * @Then I should not be able to complete the shipping step
1289
     */
1290
    public function iShouldNotBeAbleToCompleteTheShippingStep()
1291
    {
1292
        Assert::true(
1293
            $this->selectShippingPage->isNextStepButtonUnavailable(),
1294
            'The next step button should be disabled, but it does not.'
1295
        );
1296
    }
1297
1298
    /**
1299
     * @When I do not select any payment method
1300
     */
1301
    public function iDoNotSelectAnyPaymentMethod()
1302
    {
1303
        // Intentionally left blank to fulfill context expectation
1304
    }
1305
1306
    /**
1307
     * @Then I should not be able to complete the payment step
1308
     */
1309
    public function iShouldNotBeAbleToCompleteThePaymentStep()
1310
    {
1311
        Assert::true(
1312
            $this->selectPaymentPage->isNextStepButtonUnavailable(),
1313
           'The "next step" button should be disabled.'
1314
        );
1315
    }
1316
1317
    /**
1318
     * @Then there should be information about no payment methods available for my order
1319
     */
1320
    public function thereShouldBeInformationAboutNoPaymentMethodsAvailableForMyOrder()
1321
    {
1322
        Assert::true(
1323
            $this->selectPaymentPage->hasNoAvailablePaymentMethodsWarning(),
1324
            'There should be warning about no available payment methods, but it does not.'
1325
        );
1326
    }
1327
1328
    /**
1329
     * @Then /^(address "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+") should be filled as shipping address$/
1330
     */
1331
    public function addressShouldBeFilledAsShippingAddress(AddressInterface $address)
1332
    {
1333
        Assert::true($this->addressComparator->equal($address, $this->addressPage->getPreFilledShippingAddress()));
1334
    }
1335
1336
    /**
1337
     * @Then /^(address "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+") should be filled as billing address$/
1338
     */
1339
    public function addressShouldBeFilledAsBillingAddress(AddressInterface $address)
1340
    {
1341
        Assert::true($this->addressComparator->equal($address, $this->addressPage->getPreFilledBillingAddress()));
1342
    }
1343
1344
    /**
1345
     * @Then I should have :paymentMethodName payment method available as the first choice
1346
     */
1347
    public function iShouldHavePaymentMethodAvailableAsFirstChoice($paymentMethodName)
1348
    {
1349
        $paymentMethods = $this->selectPaymentPage->getPaymentMethods();
1350
        $firstPaymentMethod = reset($paymentMethods);
1351
1352
        Assert::same($paymentMethodName, $firstPaymentMethod);
1353
    }
1354
1355
    /**
1356
     * @Then I should have :paymentMethodName payment method available as the last choice
1357
     */
1358
    public function iShouldHavePaymentMethodAvailableAsLastChoice($paymentMethodName)
1359
    {
1360
        $paymentMethods = $this->selectPaymentPage->getPaymentMethods();
1361
        $lastPaymentMethod = end($paymentMethods);
1362
1363
        Assert::same($paymentMethodName, $lastPaymentMethod);
1364
    }
1365
1366
    /**
1367
     * @Then I should see :shippingMethodName shipping method
1368
     */
1369
    public function iShouldSeeShippingMethod($shippingMethodName)
1370
    {
1371
        Assert::true(
1372
            $this->selectShippingPage->hasShippingMethod($shippingMethodName),
1373
            sprintf('There should be %s shipping method, but it is not.', $shippingMethodName)
1374
        );
1375
    }
1376
1377
    /**
1378
     * @Then I should not see :shippingMethodName shipping method
1379
     */
1380
    public function iShouldNotSeeShippingMethod($shippingMethodName)
1381
    {
1382
        Assert::false(
1383
            $this->selectShippingPage->hasShippingMethod($shippingMethodName),
1384
            sprintf('There should not be %s shipping method, but it is.', $shippingMethodName)
1385
        );
1386
    }
1387
1388
    /**
1389
     * @return AddressInterface
1390
     */
1391
    private function createDefaultAddress()
1392
    {
1393
        /** @var AddressInterface $address */
1394
        $address = $this->addressFactory->createNew();
1395
        $address->setFirstName('John');
1396
        $address->setLastName('Doe');
1397
        $address->setCountryCode('US');
1398
        $address->setCity('North Bridget');
1399
        $address->setPostcode('93-554');
1400
        $address->setStreet('0635 Myron Hollow Apt. 711');
1401
        $address->setPhoneNumber('321123456');
1402
1403
        return $address;
1404
    }
1405
1406
    /**
1407
     * @param string $type
1408
     * @param string $element
1409
     * @param string $expectedMessage
1410
     *
1411
     * @throws \InvalidArgumentException
1412
     */
1413
    private function assertElementValidationMessage($type, $element, $expectedMessage)
1414
    {
1415
        $element = sprintf('%s_%s', $type, implode('_', explode(' ', $element)));
1416
        Assert::true(
1417
            $this->addressPage->checkValidationMessageFor($element, $expectedMessage),
1418
            sprintf('The %s should be required.', $element)
1419
        );
1420
    }
1421
1422
    /**
1423
     * @return SymfonyPageInterface
1424
     */
1425
    private function resolveCurrentStepPage()
1426
    {
1427
        $possiblePages = [
1428
            $this->addressPage,
1429
            $this->selectPaymentPage,
1430
            $this->selectShippingPage,
1431
        ];
1432
1433
        return $this->currentPageResolver->getCurrentPageWithForm($possiblePages);
1434
    }
1435
}
1436