Completed
Push — master ( 0f478c...b73fd3 )
by Kamil
14:27 queued 08:29
created

shouldHaveCountriesToChooseFrom()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
cc 1
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
declare(strict_types=1);
13
14
namespace Sylius\Behat\Context\Ui\Shop\Checkout;
15
16
use Behat\Behat\Context\Context;
17
use Sylius\Behat\Page\Shop\Checkout\AddressPageInterface;
18
use Sylius\Behat\Page\Shop\Checkout\SelectShippingPageInterface;
19
use Sylius\Behat\Service\SharedStorageInterface;
20
use Sylius\Component\Addressing\Comparator\AddressComparatorInterface;
21
use Sylius\Component\Addressing\Model\CountryInterface;
22
use Sylius\Component\Core\Model\AddressInterface;
23
use Sylius\Component\Resource\Factory\FactoryInterface;
24
use Webmozart\Assert\Assert;
25
26
final class CheckoutAddressingContext implements Context
27
{
28
    /** @var SharedStorageInterface */
29
    private $sharedStorage;
30
31
    /** @var AddressPageInterface */
32
    private $addressPage;
33
34
    /** @var FactoryInterface */
35
    private $addressFactory;
36
37
    /** @var AddressComparatorInterface */
38
    private $addressComparator;
39
40
    /** @var SelectShippingPageInterface */
41
    private $selectShippingPage;
42
43
    public function __construct(
44
        SharedStorageInterface $sharedStorage,
45
        AddressPageInterface $addressPage,
46
        FactoryInterface $addressFactory,
47
        AddressComparatorInterface $addressComparator,
48
        SelectShippingPageInterface $selectShippingPage
49
    ) {
50
        $this->sharedStorage = $sharedStorage;
51
        $this->addressPage = $addressPage;
52
        $this->addressFactory = $addressFactory;
53
        $this->addressComparator = $addressComparator;
54
        $this->selectShippingPage = $selectShippingPage;
55
    }
56
57
    /**
58
     * @Given I am at the checkout addressing step
59
     * @When I go to the checkout addressing step
60
     * @When I go back to addressing step of the checkout
61
     */
62
    public function iAmAtTheCheckoutAddressingStep(): void
63
    {
64
        $this->addressPage->open();
65
    }
66
67
    /**
68
     * @Given /^I have completed addressing step with email "([^"]+)" and ("[^"]+" based billing address)$/
69
     * @When /^I complete addressing step with email "([^"]+)" and ("[^"]+" based billing address)$/
70
     */
71
    public function iCompleteAddressingStepWithEmail(string $email, AddressInterface $address): void
72
    {
73
        $this->addressPage->open();
74
        $this->iSpecifyTheEmail($email);
75
        $this->iSpecifyTheBillingAddressAs($address);
76
        $this->iCompleteTheAddressingStep();
77
    }
78
79
    /**
80
     * @When /^I complete addressing step with ("[^"]+" based billing address)$/
81
     */
82
    public function iCompleteAddressingStepWithBasedBillingAddress(AddressInterface $address): void
83
    {
84
        $this->addressPage->open();
85
        $this->iSpecifyTheBillingAddressAs($address);
86
        $this->iCompleteTheAddressingStep();
87
    }
88
89
    /**
90
     * @When I specify the province name manually as :provinceName for shipping address
91
     */
92
    public function iSpecifyTheProvinceNameManuallyAsForShippingAddress($provinceName)
93
    {
94
        $this->addressPage->specifyShippingAddressProvince($provinceName);
95
    }
96
97
    /**
98
     * @When I specify the province name manually as :provinceName for billing address
99
     */
100
    public function iSpecifyTheProvinceNameManuallyAsForBillingAddress($provinceName)
101
    {
102
        $this->addressPage->specifyBillingAddressProvince($provinceName);
103
    }
104
105
    /**
106
     * @When I try to open checkout addressing page
107
     */
108
    public function iTryToOpenCheckoutAddressingPage()
109
    {
110
        $this->addressPage->tryToOpen();
111
    }
112
113
    /**
114
     * @When /^I choose ("[^"]+" street) for shipping address$/
115
     */
116
    public function iChooseForShippingAddress(AddressInterface $address)
117
    {
118
        $this->addressPage->chooseDifferentShippingAddress();
119
        $this->addressPage->selectShippingAddressFromAddressBook($address);
120
    }
121
122
    /**
123
     * @When /^I choose ("[^"]+" street) for billing address$/
124
     */
125
    public function iChooseForBillingAddress(AddressInterface $address)
126
    {
127
        $this->addressPage->selectBillingAddressFromAddressBook($address);
128
    }
129
130
    /**
131
     * @When /^I specify the shipping (address as "[^"]+", "[^"]+", "[^"]+", "[^"]+" for "[^"]+")$/
132
     * @When /^I specify the shipping (address for "[^"]+" from "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+")$/
133
     * @When /^I (do not specify any shipping address) information$/
134
     * @When /^I change the shipping (address to "[^"]+", "[^"]+", "[^"]+", "[^"]+" for "[^"]+")$/
135
     */
136
    public function iSpecifyTheShippingAddressAs(AddressInterface $address)
137
    {
138
        $this->addressPage->chooseDifferentShippingAddress();
139
140
        $key = sprintf(
141
            'shipping_address_%s_%s',
142
            strtolower((string) $address->getFirstName()),
143
            strtolower((string) $address->getLastName())
144
        );
145
        $this->sharedStorage->set($key, $address);
146
147
        $this->addressPage->specifyShippingAddress($address);
148
    }
149
150
    /**
151
     * @When I specify shipping country province as :province
152
     */
153
    public function iSpecifyShippingCountryProvinceAs($province)
154
    {
155
        $this->addressPage->selectShippingAddressProvince($province);
156
    }
157
158
    /**
159
     * @When I specify billing country province as :province
160
     */
161
    public function iSpecifyBillingCountryProvinceAs($province)
162
    {
163
        $this->addressPage->selectBillingAddressProvince($province);
164
    }
165
166
    /**
167
     * @When /^I specify the billing (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
168
     * @When /^I specify the billing (address for "([^"]+)" from "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)")$/
169
     * @When /^I (do not specify any billing address) information$/
170
     */
171
    public function iSpecifyTheBillingAddressAs(AddressInterface $address)
172
    {
173
        $key = sprintf(
174
            'billing_address_%s_%s',
175
            strtolower((string) $address->getFirstName()),
176
            strtolower((string) $address->getLastName())
177
        );
178
        $this->sharedStorage->set($key, $address);
179
180
        $this->addressPage->specifyBillingAddress($address);
181
    }
182
183
    /**
184
     * @When /^I specified the billing (address as "[^"]+", "[^"]+", "[^"]+", "[^"]+" for "[^"]+")$/
185
     */
186
    public function iSpecifiedTheBillingAddress(AddressInterface $address = null)
187
    {
188
        if (null === $address) {
189
            $address = $this->createDefaultAddress();
190
        }
191
192
        $this->addressPage->open();
193
        $this->iSpecifyTheBillingAddressAs($address);
194
195
        $key = sprintf('shipping_address_%s_%s', strtolower((string) $address->getFirstName()), strtolower((string) $address->getLastName()));
196
        $this->sharedStorage->set($key, $address);
197
198
        $this->iCompleteTheAddressingStep();
199
    }
200
201
    /**
202
     * @When I specify the email as :email
203
     * @When I do not specify the email
204
     */
205
    public function iSpecifyTheEmail($email = null)
206
    {
207
        $this->addressPage->specifyEmail($email);
208
    }
209
210
    /**
211
     * @When I specify the first and last name as :fullName for billing address
212
     */
213
    public function iSpecifyTheStreetAsForBillingAddress(string $fullName): void
214
    {
215
        $this->addressPage->specifyBillingAddressFullName($fullName);
216
    }
217
218
    /**
219
     * @When I complete the addressing step
220
     * @When I try to complete the addressing step
221
     */
222
    public function iCompleteTheAddressingStep()
223
    {
224
        $this->addressPage->nextStep();
225
    }
226
227
    /**
228
     * @When I go back to store
229
     */
230
    public function iGoBackToStore()
231
    {
232
        $this->addressPage->backToStore();
233
    }
234
235
    /**
236
     * @When /^I proceed selecting ("[^"]+" as billing country)$/
237
     */
238
    public function iProceedSelectingBillingCountry(
239
        CountryInterface $shippingCountry = null,
240
        string $localeCode = 'en_US',
241
        ?string $email = null
242
    ) {
243
        $this->addressPage->open(['_locale' => $localeCode]);
244
        $shippingAddress = $this->createDefaultAddress();
245
        if (null !== $shippingCountry) {
246
            $shippingAddress->setCountryCode($shippingCountry->getCode());
247
        }
248
        if (null !== $email) {
249
            $this->addressPage->specifyEmail($email);
250
        }
251
        $this->addressPage->specifyBillingAddress($shippingAddress);
252
        $this->addressPage->nextStep();
253
    }
254
255
    /**
256
     * @When /^I proceed as guest "([^"]*)" with ("[^"]+" as billing country)$/
257
     */
258
    public function iProceedLoggingAsGuestWithAsBillingCountry(
259
        string $email,
260
        CountryInterface $shippingCountry = null
261
    ): void {
262
        $this->addressPage->open();
263
        $this->addressPage->specifyEmail($email);
264
        $shippingAddress = $this->createDefaultAddress();
265
        if (null !== $shippingCountry) {
266
            $shippingAddress->setCountryCode($shippingCountry->getCode());
267
        }
268
269
        $this->addressPage->specifyBillingAddress($shippingAddress);
270
        $this->addressPage->nextStep();
271
    }
272
273
    /**
274
     * @When I specify the password as :password
275
     */
276
    public function iSpecifyThePasswordAs($password)
277
    {
278
        $this->addressPage->specifyPassword($password);
279
    }
280
281
    /**
282
     * @When I sign in
283
     */
284
    public function iSignIn()
285
    {
286
        $this->addressPage->signIn();
287
    }
288
289
    /**
290
     * @Then I should have :countryName selected as country
291
     */
292
    public function iShouldHaveSelectedAsCountry($countryName)
293
    {
294
        Assert::same($this->addressPage->getShippingAddressCountry(), $countryName);
295
    }
296
297
    /**
298
     * @Then I should have no country selected
299
     */
300
    public function iShouldHaveNoCountrySelected()
301
    {
302
        Assert::same($this->addressPage->getShippingAddressCountry(), 'Select');
303
    }
304
305
    /**
306
     * @Then I should be able to log in
307
     */
308
    public function iShouldBeAbleToLogIn()
309
    {
310
        Assert::true($this->addressPage->canSignIn());
311
    }
312
313
    /**
314
     * @Then the login form should no longer be accessible
315
     */
316
    public function theLoginFormShouldNoLongerBeAccessible()
317
    {
318
        Assert::false($this->addressPage->canSignIn());
319
    }
320
321
    /**
322
     * @Then I should be notified about bad credentials
323
     */
324
    public function iShouldBeNotifiedAboutBadCredentials()
325
    {
326
        Assert::true($this->addressPage->checkInvalidCredentialsValidation());
327
    }
328
329
    /**
330
     * @Then I should be redirected to the addressing step
331
     * @Then I should be on the checkout addressing step
332
     */
333
    public function iShouldBeRedirectedToTheAddressingStep()
334
    {
335
        $this->addressPage->verify();
336
    }
337
338
    /**
339
     * @Then I should be able to go to the shipping step again
340
     */
341
    public function iShouldBeAbleToGoToTheShippingStepAgain()
342
    {
343
        $this->addressPage->nextStep();
344
345
        $this->selectShippingPage->verify();
346
    }
347
348
    /**
349
     * @Then I should not be able to specify province name manually for shipping address
350
     */
351
    public function iShouldNotBeAbleToSpecifyProvinceNameManuallyForShippingAddress()
352
    {
353
        Assert::false($this->addressPage->hasShippingAddressInput());
354
    }
355
356
    /**
357
     * @Then I should not be able to specify province name manually for billing address
358
     */
359
    public function iShouldNotBeAbleToSpecifyProvinceNameManuallyForBillingAddress()
360
    {
361
        Assert::false($this->addressPage->hasBillingAddressInput());
362
    }
363
364
    /**
365
     * @Then /^(address "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+") should be filled as shipping address$/
366
     */
367
    public function addressShouldBeFilledAsShippingAddress(AddressInterface $address)
368
    {
369
        Assert::true($this->addressComparator->equal($address, $this->addressPage->getPreFilledShippingAddress()));
370
    }
371
372
    /**
373
     * @Then /^(address "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+") should be filled as billing address$/
374
     */
375
    public function addressShouldBeFilledAsBillingAddress(AddressInterface $address)
376
    {
377
        Assert::true($this->addressComparator->equal($address, $this->addressPage->getPreFilledBillingAddress()));
378
    }
379
380
    /**
381
     * @Then /^I should(?:| also) be notified that the "([^"]+)" and the "([^"]+)" in (shipping|billing) details are required$/
382
     */
383
    public function iShouldBeNotifiedThatTheAndTheInShippingDetailsAreRequired($firstElement, $secondElement, $type)
384
    {
385
        $this->assertElementValidationMessage($type, $firstElement, sprintf('Please enter %s.', $firstElement));
386
        $this->assertElementValidationMessage($type, $secondElement, sprintf('Please enter %s.', $secondElement));
387
    }
388
389
    /**
390
     * @Then I should have only :firstCountry country available to choose from
391
     * @Then I should have both :firstCountry and :secondCountry countries available to choose from
392
     */
393
    public function shouldHaveCountriesToChooseFrom(string ...$countries): void
394
    {
395
        $availableShippingCountries = $this->addressPage->getAvailableShippingCountries();
396
        $availableBillingCountries = $this->addressPage->getAvailableBillingCountries();
397
398
        sort($countries);
399
        sort($availableShippingCountries);
400
        sort($availableBillingCountries);
401
402
        Assert::same($availableShippingCountries, $countries);
403
        Assert::same($availableBillingCountries, $countries);
404
    }
405
406
    /**
407
     * @return AddressInterface
408
     */
409
    private function createDefaultAddress()
410
    {
411
        /** @var AddressInterface $address */
412
        $address = $this->addressFactory->createNew();
413
        $address->setFirstName('John');
414
        $address->setLastName('Doe');
415
        $address->setCountryCode('US');
416
        $address->setCity('North Bridget');
417
        $address->setPostcode('93-554');
418
        $address->setStreet('0635 Myron Hollow Apt. 711');
419
        $address->setPhoneNumber('321123456');
420
421
        return $address;
422
    }
423
424
    /**
425
     * @param string $type
426
     * @param string $element
427
     * @param string $expectedMessage
428
     *
429
     * @throws \InvalidArgumentException
430
     */
431
    private function assertElementValidationMessage($type, $element, $expectedMessage)
432
    {
433
        $element = sprintf('%s_%s', $type, str_replace(' ', '_', $element));
434
        Assert::true($this->addressPage->checkValidationMessageFor($element, $expectedMessage));
435
    }
436
}
437