Completed
Push — master ( 4c7b9c...e919dc )
by Kamil
21:11
created

CheckoutContext::iChangeShippingMethod()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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