Completed
Push — master ( b55ca8...f3fba8 )
by Kamil
20:16 queued 07:20
created

ManagingProductAttributesContext::iDeleteValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
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
declare(strict_types=1);
13
14
namespace Sylius\Behat\Context\Ui\Admin;
15
16
use Behat\Behat\Context\Context;
17
use Sylius\Behat\Page\Admin\Crud\IndexPageInterface;
18
use Sylius\Behat\Page\Admin\ProductAttribute\CreatePageInterface;
19
use Sylius\Behat\Page\Admin\ProductAttribute\UpdatePageInterface;
20
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
21
use Sylius\Behat\Service\SharedSecurityServiceInterface;
22
use Sylius\Component\Core\Model\AdminUserInterface;
23
use Sylius\Component\Product\Model\ProductAttributeInterface;
24
use Webmozart\Assert\Assert;
25
26
/**
27
 * @author Anna Walasek <[email protected]>
28
 */
29
final class ManagingProductAttributesContext implements Context
30
{
31
    /**
32
     * @var CreatePageInterface
33
     */
34
    private $createPage;
35
36
    /**
37
     * @var IndexPageInterface
38
     */
39
    private $indexPage;
40
41
    /**
42
     * @var UpdatePageInterface
43
     */
44
    private $updatePage;
45
46
    /**
47
     * @var CurrentPageResolverInterface
48
     */
49
    private $currentPageResolver;
50
51
    /**
52
     * @var SharedSecurityServiceInterface
53
     */
54
    private $sharedSecurityService;
55
56
    /**
57
     * @param CreatePageInterface $createPage
58
     * @param IndexPageInterface $indexPage
59
     * @param UpdatePageInterface $updatePage
60
     * @param CurrentPageResolverInterface $currentPageResolver
61
     * @param SharedSecurityServiceInterface $sharedSecurityService
62
     */
63
    public function __construct(
64
        CreatePageInterface $createPage,
65
        IndexPageInterface $indexPage,
66
        UpdatePageInterface $updatePage,
67
        CurrentPageResolverInterface $currentPageResolver,
68
        SharedSecurityServiceInterface $sharedSecurityService
69
    ) {
70
        $this->createPage = $createPage;
71
        $this->indexPage = $indexPage;
72
        $this->updatePage = $updatePage;
73
        $this->currentPageResolver = $currentPageResolver;
74
        $this->sharedSecurityService = $sharedSecurityService;
75
    }
76
77
    /**
78
     * @When I want to create a new :type product attribute
79
     */
80
    public function iWantToCreateANewTextProductAttribute($type)
81
    {
82
        $this->createPage->open(['type' => $type]);
83
    }
84
85
    /**
86
     * @When I specify its code as :code
87
     * @When I do not specify its code
88
     */
89
    public function iSpecifyItsCodeAs($code = null)
90
    {
91
        $this->createPage->specifyCode($code);
92
    }
93
94
    /**
95
     * @When I name it :name in :language
96
     */
97
    public function iSpecifyItsNameAs($name, $language)
98
    {
99
        $this->createPage->nameIt($name, $language);
100
    }
101
102
    /**
103
     * @When I add it
104
     * @When I try to add it
105
     */
106
    public function iAddIt()
107
    {
108
        $this->createPage->create();
109
    }
110
111
    /**
112
     * @When I( also) add value :value
113
     */
114
    public function iAddValue(string $value): void
115
    {
116
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
117
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
118
119
        $currentPage->addAttributeValue($value);
120
    }
121
122
    /**
123
     * @When I delete value :value
124
     */
125
    public function iDeleteValue(string $value): void
126
    {
127
        $this->updatePage->deleteAttributeValue($value);
128
    }
129
130
    /**
131
     * @When I change its value :oldValue to :newValue
132
     */
133
    public function iChangeItsValueTo(string $oldValue, string $newValue): void
134
    {
135
        $this->updatePage->changeAttributeValue($oldValue, $newValue);
136
    }
137
138
    /**
139
     * @Then I should see the product attribute :name in the list
140
     */
141
    public function iShouldSeeTheProductAttributeInTheList($name)
142
    {
143
        $this->indexPage->open();
144
145
        Assert::true($this->indexPage->isSingleResourceOnPage(['name' => $name]));
146
    }
147
148
    /**
149
     * @Then the :type attribute :name should appear in the store
150
     */
151
    public function theAttributeShouldAppearInTheStore($type, $name)
152
    {
153
        $this->indexPage->open();
154
155
        Assert::true($this->indexPage->isSingleResourceWithSpecificElementOnPage(
156
            ['name' => $name],
157
            sprintf('td span.ui.label:contains("%s")', $type)
158
        ));
159
    }
160
161
    /**
162
     * @When /^I want to edit (this product attribute)$/
163
     */
164
    public function iWantToEditThisAttribute(ProductAttributeInterface $productAttribute)
165
    {
166
        $this->updatePage->open(['id' => $productAttribute->getId()]);
167
    }
168
169
    /**
170
     * @When I change its name to :name in :language
171
     */
172
    public function iChangeItNameToIn($name, $language)
173
    {
174
        $this->updatePage->changeName($name, $language);
175
    }
176
177
    /**
178
     * @When I save my changes
179
     * @When I try to save my changes
180
     */
181
    public function iSaveMyChanges()
182
    {
183
        $this->updatePage->saveChanges();
184
    }
185
186
    /**
187
     * @Then the code field should be disabled
188
     */
189
    public function theCodeFieldShouldBeDisabled()
190
    {
191
        Assert::true($this->updatePage->isCodeDisabled());
192
    }
193
194
    /**
195
     * @Then the type field should be disabled
196
     */
197
    public function theTypeFieldShouldBeDisabled()
198
    {
199
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
200
201
        Assert::true($currentPage->isTypeDisabled());
202
    }
203
204
    /**
205
     * @Then I should be notified that product attribute with this code already exists
206
     */
207
    public function iShouldBeNotifiedThatProductAttributeWithThisCodeAlreadyExists()
208
    {
209
        Assert::same($this->updatePage->getValidationMessage('code'), 'This code is already in use.');
210
    }
211
212
    /**
213
     * @Then there should still be only one product attribute with code :code
214
     */
215
    public function thereShouldStillBeOnlyOneProductAttributeWithCode($code)
216
    {
217
        $this->indexPage->open();
218
219
        Assert::true($this->indexPage->isSingleResourceOnPage(['code' => $code]));
220
    }
221
222
    /**
223
     * @When I do not name it
224
     */
225
    public function iDoNotNameIt()
226
    {
227
        // Intentionally left blank to fulfill context expectation
228
    }
229
230
    /**
231
     * @Then I should be notified that :element is required
232
     */
233
    public function iShouldBeNotifiedThatIsRequired($element)
234
    {
235
        $this->assertFieldValidationMessage($element, sprintf('Please enter attribute %s.', $element));
236
    }
237
238
    /**
239
     * @Given the attribute with :elementName :elementValue should not appear in the store
240
     */
241
    public function theAttributeWithCodeShouldNotAppearInTheStore($elementName, $elementValue)
242
    {
243
        $this->indexPage->open();
244
245
        Assert::false($this->indexPage->isSingleResourceOnPage([$elementName => $elementValue]));
246
    }
247
248
    /**
249
     * @When I remove its name from :language translation
250
     */
251
    public function iRemoveItsNameFromTranslation($language)
252
    {
253
        $this->updatePage->changeName('', $language);
254
    }
255
256
    /**
257
     * @When I want to see all product attributes in store
258
     */
259
    public function iWantToSeeAllProductAttributesInStore()
260
    {
261
        $this->indexPage->open();
262
    }
263
264
    /**
265
     * @When /^(the administrator) changes (this product attribute)'s value "([^"]*)" to "([^"]*)"$/
266
     */
267
    public function theAdministratorChangesThisProductAttributesValueTo(
268
        AdminUserInterface $user,
269
        ProductAttributeInterface $productAttribute,
270
        string $oldValue,
271
        string $newValue
272
    ): void {
273
        $this->sharedSecurityService->performActionAsAdminUser(
274
            $user,
275
            function () use ($productAttribute, $oldValue, $newValue) {
276
                $this->iWantToEditThisAttribute($productAttribute);
277
                $this->iChangeItsValueTo($oldValue, $newValue);
278
                $this->iSaveMyChanges();
279
            }
280
        );
281
    }
282
283
    /**
284
     * @When I specify its min length as :min
285
     * @When I specify its min entries value as :min
286
     */
287
    public function iSpecifyItsMinValueAs(int $min): void
288
    {
289
        $this->createPage->specifyMinValue($min);
290
    }
291
292
    /**
293
     * @When I specify its max length as :max
294
     * @When I specify its max entries value as :max
295
     */
296
    public function iSpecifyItsMaxLengthAs(int $max): void
297
    {
298
        $this->createPage->specifyMaxValue($max);
299
    }
300
301
    /**
302
     * @When I check multiple option
303
     */
304
    public function iCheckMultipleOption(): void
305
    {
306
        $this->createPage->checkMultiple();
307
    }
308
309
    /**
310
     * @When I do not check multiple option
311
     */
312
    public function iDoNotCheckMultipleOption(): void
313
    {
314
        // Intentionally left blank to fulfill context expectation
315
    }
316
317
    /**
318
     * @When /^(the administrator) deletes the value "([^"]+)" from (this product attribute)$/
319
     */
320
    public function theAdministratorDeletesTheValueFromThisProductAttribute(
321
        AdminUserInterface $user,
322
        string $value,
323
        ProductAttributeInterface $productAttribute
324
    ): void {
325
        $this->sharedSecurityService->performActionAsAdminUser(
326
            $user,
327
            function () use ($productAttribute, $value) {
328
                $this->iWantToEditThisAttribute($productAttribute);
329
                $this->iDeleteValue($value);
330
                $this->iSaveMyChanges();
331
            }
332
        );
333
    }
334
335
    /**
336
     * @Then /^I should see (\d+) product attributes in the list$/
337
     */
338
    public function iShouldSeeCustomersInTheList($amountOfProductAttributes)
339
    {
340
        Assert::same($this->indexPage->countItems(), (int) $amountOfProductAttributes);
341
    }
342
343
    /**
344
     * @When /^I delete (this product attribute)$/
345
     */
346
    public function iDeleteThisProductAttribute(ProductAttributeInterface $productAttribute)
347
    {
348
        $this->indexPage->open();
349
        $this->indexPage->deleteResourceOnPage(['code' => $productAttribute->getCode(), 'name' => $productAttribute->getName()]);
350
    }
351
352
    /**
353
     * @Then /^(this product attribute) should no longer exist in the registry$/
354
     */
355
    public function thisProductAttributeShouldNoLongerExistInTheRegistry(ProductAttributeInterface $productAttribute)
356
    {
357
        Assert::false($this->indexPage->isSingleResourceOnPage(['code' => $productAttribute->getCode()]));
358
    }
359
360
    /**
361
     * @Then the first product attribute on the list should have name :name
362
     */
363
    public function theFirstProductAttributeOnTheListShouldHave($name)
364
    {
365
        $names = $this->indexPage->getColumnFields('name');
366
367
        Assert::same(reset($names), $name);
368
    }
369
370
    /**
371
     * @Then the last product attribute on the list should have name :name
372
     */
373
    public function theLastProductAttributeOnTheListShouldHave($name)
374
    {
375
        $names = $this->indexPage->getColumnFields('name');
376
377
        Assert::same(end($names), $name);
378
    }
379
380
    /**
381
     * @Then /^(this product attribute) should have value "([^"]*)"/
382
     */
383
    public function theSelectAttributeShouldHaveValue(ProductAttributeInterface $productAttribute, string $value): void
384
    {
385
        $this->iWantToEditThisAttribute($productAttribute);
386
387
        Assert::true($this->updatePage->hasAttributeValue($value));
388
    }
389
390
    /**
391
     * @Then I should be notified that max length must be greater or equal to the min length
392
     */
393
    public function iShouldBeNotifiedThatMaxLengthMustBeGreaterOrEqualToTheMinLength(): void
394
    {
395
        $this->assertValidationMessage(
396
            'Configuration max length must be greater or equal to the min length.'
397
        );
398
    }
399
400
    /**
401
     * @Then I should be notified that max entries value must be greater or equal to the min entries value
402
     */
403
    public function iShouldBeNotifiedThatMaxEntriesValueMustBeGreaterOrEqualToTheMinEntriesValue(): void
404
    {
405
        $this->assertValidationMessage(
406
            'Configuration max entries value must be greater or equal to the min entries value.'
407
        );
408
    }
409
410
    /**
411
     * @Then I should be notified that min entries value must be lower or equal to the number of added choices
412
     */
413
    public function iShouldBeNotifiedThatMinEntriesValueMustBeLowerOrEqualToTheNumberOfAddedChoices(): void
414
    {
415
        $this->assertValidationMessage(
416
            'Configuration min entries value must be lower or equal to the number of added choices.'
417
        );
418
    }
419
420
    /**
421
     * @Then I should be notified that multiple must be true if min or max entries values are specified
422
     */
423
    public function iShouldBeNotifiedThatMultipleMustBeTrueIfMinOrMaxEntriesValuesAreSpecified(): void
424
    {
425
        $this->assertValidationMessage(
426
            'Configuration multiple must be true if min or max entries values are specified.'
427
        );
428
    }
429
430
    /**
431
     * @Then /^(this product attribute) should not have value "([^"]*)"/
432
     */
433
    public function theSelectAttributeShouldNotHaveValue(ProductAttributeInterface $productAttribute, string $value): void
434
    {
435
        $this->iWantToEditThisAttribute($productAttribute);
436
437
        Assert::false($this->updatePage->hasAttributeValue($value));
438
    }
439
440
    /**
441
     * @param string $element
442
     * @param string $expectedMessage
443
     *
444
     * @throws \InvalidArgumentException
445
     */
446
    private function assertFieldValidationMessage(string $element, string $expectedMessage): void
447
    {
448
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
449
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
450
451
        Assert::same($currentPage->getValidationMessage($element), $expectedMessage);
452
    }
453
454
    /**
455
     * @param string $expectedMessage
456
     *
457
     * @throws \InvalidArgumentException
458
     */
459
    private function assertValidationMessage(string $expectedMessage): void
460
    {
461
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
462
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
463
464
        Assert::same($currentPage->getValidationErrors(), $expectedMessage);
0 ignored issues
show
Bug introduced by
The method getValidationErrors does only exist in Sylius\Behat\Page\Admin\...ute\CreatePageInterface, but not in Sylius\Behat\Page\Admin\...ute\UpdatePageInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
465
    }
466
}
467