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

CheckoutContext::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 2
Metric Value
dl 0
loc 27
rs 8.8571
c 3
b 1
f 2
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\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