Completed
Push — master ( b31cd6...60f5be )
by Kamil
43:45
created

CheckoutContext::iConfirmMyOrder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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