Completed
Push — master ( b42639...616c5a )
by Paweł
24:03 queued 09:34
created

CheckoutContext::iShouldHaveProductsInTheCart()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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