Completed
Push — master ( 61c842...2ec63c )
by Paweł
293:00 queued 278:23
created

thisProductPriceShouldBeEqualTo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
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\Admin;
13
14
use Behat\Behat\Context\Context;
15
use Sylius\Behat\NotificationType;
16
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface;
17
use Sylius\Behat\Page\Admin\Crud\IndexPageInterface;
18
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface;
19
use Sylius\Behat\Page\Admin\Product\CreateConfigurableProductPageInterface;
20
use Sylius\Behat\Page\Admin\Product\CreateSimpleProductPageInterface;
21
use Sylius\Behat\Page\Admin\Product\UpdateConfigurableProductPageInterface;
22
use Sylius\Behat\Page\Admin\Product\UpdateSimpleProductPageInterface;
23
use Sylius\Behat\Service\NotificationCheckerInterface;
24
use Sylius\Behat\Service\Resolver\CurrentProductPageResolverInterface;
25
use Sylius\Component\Core\Model\ProductInterface;
26
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
27
use Webmozart\Assert\Assert;
28
29
/**
30
 * @author Kamil Kokot <[email protected]>
31
 * @author Magdalena Banasiak <[email protected]>
32
 * @author Łukasz Chruściel <[email protected]>
33
 */
34
final class ManagingProductsContext implements Context
35
{
36
    /**
37
     * @var SharedStorageInterface
38
     */
39
    private $sharedStorage;
40
41
    /**x
42
     * @var CreateSimpleProductPageInterface
43
     */
44
    private $createSimpleProductPage;
45
46
    /**
47
     * @var CreateConfigurableProductPageInterface
48
     */
49
    private $createConfigurableProductPage;
50
51
    /**
52
     * @var IndexPageInterface
53
     */
54
    private $indexPage;
55
56
    /**
57
     * @var UpdateSimpleProductPageInterface
58
     */
59
    private $updateSimpleProductPage;
60
61
    /**
62
     * @var UpdateConfigurableProductPageInterface
63
     */
64
    private $updateConfigurableProductPage;
65
66
    /**
67
     * @var CurrentProductPageResolverInterface
68
     */
69
    private $currentPageResolver;
70
71
    /**
72
     * @var NotificationCheckerInterface
73
     */
74
    private $notificationChecker;
75
76
    /**
77
     * @param SharedStorageInterface $sharedStorage
78
     * @param CreateSimpleProductPageInterface $createSimpleProductPage
79
     * @param CreateConfigurableProductPageInterface $createConfigurableProductPage
80
     * @param IndexPageInterface $indexPage
81
     * @param UpdateSimpleProductPageInterface $updateSimpleProductPage
82
     * @param UpdateConfigurableProductPageInterface $updateConfigurableProductPage
83
     * @param CurrentProductPageResolverInterface $currentPageResolver
84
     * @param NotificationCheckerInterface $notificationChecker
85
     */
86
    public function __construct(
87
        SharedStorageInterface $sharedStorage,
88
        CreateSimpleProductPageInterface $createSimpleProductPage,
89
        CreateConfigurableProductPageInterface $createConfigurableProductPage,
90
        IndexPageInterface $indexPage,
91
        UpdateSimpleProductPageInterface $updateSimpleProductPage,
92
        UpdateConfigurableProductPageInterface $updateConfigurableProductPage,
93
        CurrentProductPageResolverInterface $currentPageResolver,
94
        NotificationCheckerInterface $notificationChecker
95
    ) {
96
        $this->sharedStorage = $sharedStorage;
97
        $this->createSimpleProductPage = $createSimpleProductPage;
98
        $this->createConfigurableProductPage = $createConfigurableProductPage;
99
        $this->indexPage = $indexPage;
100
        $this->updateSimpleProductPage = $updateSimpleProductPage;
101
        $this->updateConfigurableProductPage = $updateConfigurableProductPage;
102
        $this->currentPageResolver = $currentPageResolver;
103
        $this->notificationChecker = $notificationChecker;
104
    }
105
106
    /**
107
     * @Given I want to create a new simple product
108
     */
109
    public function iWantToCreateANewSimpleProduct()
110
    {
111
        $this->createSimpleProductPage->open();
112
    }
113
114
    /**
115
     * @Given I want to create a new configurable product
116
     */
117
    public function iWantToCreateANewConfigurableProduct()
118
    {
119
        $this->createConfigurableProductPage->open();
120
    }
121
122
    /**
123
     * @When I specify its code as :code
124
     * @When I do not specify its code
125
     */
126
    public function iSpecifyItsCodeAs($code = null)
127
    {
128
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
129
            $this->createSimpleProductPage,
130
            $this->createConfigurableProductPage,
131
        ]);
132
133
        $currentPage->specifyCode($code);
134
    }
135
136
    /**
137
     * @When I name it :name in :language
138
     */
139
    public function iNameItIn($name, $language)
140
    {
141
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
142
            $this->createSimpleProductPage,
143
            $this->createConfigurableProductPage,
144
        ]);
145
146
        $currentPage->nameItIn($name, $language);
147
    }
148
149
    /**
150
     * @When I rename it to :name in :language
151
     */
152
    public function iRenameItToIn($name, $language)
153
    {
154
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
155
            $this->updateSimpleProductPage,
156
            $this->updateConfigurableProductPage,
157
        ], $this->sharedStorage->get('product'));
158
159
        $currentPage->nameItIn($name, $language);
160
    }
161
162
    /**
163
     * @When I add it
164
     * @When I try to add it
165
     */
166
    public function iAddIt()
167
    {
168
        /** @var CreatePageInterface $currentPage */
169
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
170
            $this->createSimpleProductPage,
171
            $this->createConfigurableProductPage,
172
        ]);
173
174
        Assert::isInstanceOf($currentPage, CreatePageInterface::class);
175
176
        $currentPage->create();
177
    }
178
179
    /**
180
     * @When /^I specify its price to ("(?:€|£|\$)[^"]+")$/
181
     */
182
    public function iSpecifyItsPriceTo($price)
183
    {
184
        $this->createSimpleProductPage->specifyPrice($price);
185
    }
186
187
    /**
188
     * @Given the product :productName should appear in the shop
189
     * @Given the product :productName should be in the shop
190
     * @Given this product should still be named :productName
191
     */
192
    public function theProductShouldAppearInTheShop($productName)
193
    {
194
        $this->iWantToBrowseProducts();
195
196
        Assert::true(
197
            $this->indexPage->isSingleResourceOnPage(['name' => $productName]),
198
            sprintf('The product with name %s has not been found.', $productName)
199
        );
200
    }
201
202
    /**
203
     * @When I want to browse products
204
     */
205
    public function iWantToBrowseProducts()
206
    {
207
        $this->indexPage->open();
208
    }
209
210
    /**
211
     * @Then I should see :numberOfProducts products in the list
212
     */
213
    public function iShouldSeeProductsInTheList($numberOfProducts)
214
    {
215
        $foundRows = $this->indexPage->countItems();
216
217
        Assert::eq(
218
            $numberOfProducts,
219
            $foundRows,
220
            '%s rows with products should appear on page, %s rows has been found'
221
        );
222
    }
223
224
    /**
225
     * @When I delete the :product product
226
     * @When I try to delete the :product product
227
     */
228
    public function iDeleteProduct(ProductInterface $product)
229
    {
230
        $this->sharedStorage->set('product', $product);
231
232
        $this->iWantToBrowseProducts();
233
        $this->indexPage->deleteResourceOnPage(['name' => $product->getName()]);
234
    }
235
236
    /**
237
     * @Then /^(this product) should not exist in the product catalog$/
238
     */
239
    public function productShouldNotExist(ProductInterface $product)
240
    {
241
        $this->iWantToBrowseProducts();
242
243
        Assert::false(
244
            $this->indexPage->isSingleResourceOnPage(['code' => $product->getCode()]),
245
            sprintf('Product with code %s exists but should not.', $product->getCode())
246
        );
247
    }
248
249
    /**
250
     * @Then I should be notified that this product is in use and cannot be deleted
251
     */
252
    public function iShouldBeNotifiedOfFailure()
253
    {
254
        $this->notificationChecker->checkNotification(
255
            "Cannot delete, the product is in use.",
256
            NotificationType::failure()
257
        );
258
    }
259
260
    /**
261
     * @Then /^(this product) should still exist in the product catalog$/
262
     */
263
    public function productShouldExistInTheProductCatalog(ProductInterface $product)
264
    {
265
        $this->theProductShouldAppearInTheShop($product->getName());
266
    }
267
268
    /**
269
     * @When I want to modify the :product product
270
     * @When /^I want to modify (this product)$/
271
     */
272
    public function iWantToModifyAProduct(ProductInterface $product)
273
    {
274
        $this->sharedStorage->set('product', $product);
275
276
        if ($product->isSimple()) {
277
            $this->updateSimpleProductPage->open(['id' => $product->getId()]);
278
            return;
279
        }
280
281
        $this->updateConfigurableProductPage->open(['id' => $product->getId()]);
282
    }
283
284
    /**
285
     * @Then the code field should be disabled
286
     */
287
    public function theCodeFieldShouldBeDisabled()
288
    {
289
        /** @var UpdatePageInterface $currentPage */
290
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
291
            $this->updateSimpleProductPage,
292
            $this->updateConfigurableProductPage,
293
        ], $this->sharedStorage->get('product'));
294
295
        Assert::true(
296
            $currentPage->isCodeDisabled(),
297
            'Code should be immutable, but it does not.'
298
        );
299
    }
300
301
    /**
302
     * @Then /^this product price should be "(?:€|£|\$)([^"]+)"$/
303
     */
304
    public function thisProductPriceShouldBeEqualTo($price)
305
    {
306
        $this->assertElementValue('price', $price);
307
    }
308
309
    /**
310
     * @Then this product name should be :name
311
     */
312
    public function thisProductElementShouldBe($name)
313
    {
314
        $this->assertElementValue('name', $name);
315
    }
316
317
    /**
318
     * @Then /^I should be notified that (code|name) is required$/
319
     */
320
    public function iShouldBeNotifiedThatIsRequired($element)
321
    {
322
        $this->assertValidationMessage($element, sprintf('Please enter product %s.', $element));
323
    }
324
325
    /**
326
     * @Then I should be notified that price is required
327
     */
328
    public function iShouldBeNotifiedThatPriceIsRequired()
329
    {
330
        $this->assertValidationMessage('price', 'Please enter the price.');
331
    }
332
333
    /**
334
     * @When I save my changes
335
     * @When I try to save my changes
336
     */
337
    public function iSaveMyChanges()
338
    {
339
        /** @var UpdatePageInterface $currentPage */
340
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
341
            $this->updateSimpleProductPage,
342
            $this->updateConfigurableProductPage,
343
        ], $this->sharedStorage->get('product'));
344
345
        Assert::isInstanceOf($currentPage, UpdatePageInterface::class);
346
347
        $currentPage->saveChanges();
348
    }
349
350
    /**
351
     * @When /^I change its price to "(?:€|£|\$)([^"]+)"$/
352
     */
353
    public function iChangeItsPriceTo($price)
354
    {
355
        $this->updateSimpleProductPage->specifyPrice($price);
356
    }
357
358
    /**
359
     * @Given I add the :optionName option to it
360
     */
361
    public function iAddTheOptionToIt($optionName)
362
    {
363
        $this->createConfigurableProductPage->selectOption($optionName);
364
    }
365
366
    /**
367
     * @Given product with :element :value should not be added
368
     */
369
    public function productWithNameShouldNotBeAdded($element, $value)
370
    {
371
        $this->iWantToBrowseProducts();
372
373
        Assert::false(
374
            $this->indexPage->isSingleResourceOnPage([$element => $value]),
375
            sprintf('Product with %s %s was created, but it should not.', $element, $value)
376
        );
377
    }
378
379
    /**
380
     * @When I remove its name from :language translation
381
     */
382
    public function iRemoveItsNameFromTranslation($language)
383
    {
384
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
385
            $this->updateSimpleProductPage,
386
            $this->updateConfigurableProductPage,
387
        ], $this->sharedStorage->get('product'));
388
389
        $currentPage->nameItIn('', $language);
390
    }
391
392
    /**
393
     * @Then /^this product should have (?:a|an) "([^"]+)" option$/
394
     */
395
    public function thisProductShouldHaveOption($productOption)
396
    {
397
        $this->updateConfigurableProductPage->isProductOptionChosen($productOption);
398
    }
399
400
    /**
401
     * @Then the option field should be disabled
402
     */
403
    public function theOptionFieldShouldBeDisabled()
404
    {
405
        Assert::true(
406
            $this->updateConfigurableProductPage->isCodeDisabled(),
407
            'Option should be immutable, but it does not.'
408
        );
409
    }
410
411
    /**
412
     * @param string $element
413
     * @param string $value
414
     */
415
    private function assertElementValue($element, $value)
416
    {
417
        /** @var UpdatePageInterface $currentPage */
418
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
419
            $this->updateSimpleProductPage,
420
            $this->updateConfigurableProductPage,
421
        ], $this->sharedStorage->get('product'));
422
423
        Assert::isInstanceOf($currentPage, UpdatePageInterface::class);
424
425
        Assert::true(
426
            $currentPage->hasResourceValues(
427
                [$element => $value]
428
            ),
429
            sprintf('Product should have %s with %s value.', $element, $value)
430
        );
431
    }
432
433
    /**
434
     * @param string $element
435
     * @param string $message
436
     */
437
    private function assertValidationMessage($element, $message)
438
    {
439
        $product = $this->sharedStorage->has('product') ? $this->sharedStorage->get('product') : null;
440
441
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
442
            $this->createSimpleProductPage,
443
            $this->createConfigurableProductPage,
444
            $this->updateSimpleProductPage,
445
            $this->updateConfigurableProductPage,
446
        ], $product);
447
448
        Assert::true(
449
            $currentPage->checkValidationMessageFor($element, $message),
450
            sprintf('Product %s should be required.', $element)
451
        );
452
    }
453
}
454