Completed
Push — missing-product-variant-variab... ( 2e9a80...01bfdb )
by Kamil
22:39
created

BrowsingProductVariantsContext::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 2
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\Page\Admin\ProductVariant\IndexPageInterface;
16
use Sylius\Component\Core\Model\ProductInterface;
17
use Sylius\Component\Core\Model\ProductVariantInterface;
18
use Sylius\Component\Product\Resolver\ProductVariantResolverInterface;
19
use Webmozart\Assert\Assert;
20
21
/**
22
 * @author Kamil Kokot <[email protected]>
23
 */
24
final class BrowsingProductVariantsContext implements Context
25
{
26
    /**
27
     * @var IndexPageInterface
28
     */
29
    private $indexPage;
30
31
    /**
32
     * @var ProductVariantResolverInterface
33
     */
34
    private $defaultProductVariantResolver;
35
36
    /**
37
     * @param IndexPageInterface $indexPage
38
     * @param ProductVariantResolverInterface $defaultProductVariantResolver
39
     */
40
    public function __construct(
41
        IndexPageInterface $indexPage,
42
        ProductVariantResolverInterface $defaultProductVariantResolver
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $defaultProductVariantResolver exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
43
    ) {
44
        $this->indexPage = $indexPage;
45
        $this->defaultProductVariantResolver = $defaultProductVariantResolver;
46
    }
47
48
    /**
49
     * @When I start sorting variants by :field
50
     */
51
    public function iSortProductsBy($field)
52
    {
53
        $this->indexPage->sortBy($field);
54
    }
55
56
    /**
57
     * @Then the :productVariantCode variant of the :product product should appear in the store
58
     */
59
    public function theProductVariantShouldAppearInTheShop($productVariantCode, ProductInterface $product)
60
    {
61
        $this->iWantToViewAllVariantsOfThisProduct($product);
62
63
        Assert::true($this->indexPage->isSingleResourceOnPage(['code' => $productVariantCode]));
64
    }
65
66
    /**
67
     * @Then the :productVariantCode variant of the :product product should not appear in the store
68
     */
69
    public function theProductVariantShouldNotAppearInTheShop($productVariantCode, ProductInterface $product)
70
    {
71
        $this->iWantToViewAllVariantsOfThisProduct($product);
72
73
        Assert::false($this->indexPage->isSingleResourceOnPage(['code' => $productVariantCode]));
74
    }
75
76
    /**
77
     * @Then the :product product should have no variants
78
     */
79
    public function theProductShouldHaveNoVariants(ProductInterface $product)
80
    {
81
        $this->assertNumberOfVariantsOnProductPage($product, 0);
82
    }
83
84
    /**
85
     * @Then the :product product should have only one variant
86
     */
87
    public function theProductShouldHaveOnlyOneVariant(ProductInterface $product)
88
    {
89
        $this->assertNumberOfVariantsOnProductPage($product, 1);
90
    }
91
92
    /**
93
     * @When /^I (?:|want to )view all variants of (this product)$/
94
     * @When /^I view(?:| all) variants of the (product "[^"]+")$/
95
     */
96
    public function iWantToViewAllVariantsOfThisProduct(ProductInterface $product)
97
    {
98
        $this->indexPage->open(['productId' => $product->getId()]);
99
    }
100
101
    /**
102
     * @Then I should see :numberOfProductVariants variants in the list
103
     * @Then I should see :numberOfProductVariants variant in the list
104
     * @Then I should not see any variants in the list
105
     */
106
    public function iShouldSeeProductVariantsInTheList($numberOfProductVariants = 0)
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $numberOfProductVariants exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
107
    {
108
        Assert::same($this->indexPage->countItems(), (int) $numberOfProductVariants);
109
    }
110
111
    /**
112
     * @Then /^(this variant) should not exist in the product catalog$/
113
     */
114
    public function productVariantShouldNotExist(ProductVariantInterface $productVariant)
115
    {
116
        $this->iWantToViewAllVariantsOfThisProduct($productVariant->getProduct());
0 ignored issues
show
Compatibility introduced by
$productVariant->getProduct() of type object<Sylius\Component\...Model\ProductInterface> is not a sub-type of object<Sylius\Component\...Model\ProductInterface>. It seems like you assume a child interface of the interface Sylius\Component\Product\Model\ProductInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
117
118
        Assert::false($this->indexPage->isSingleResourceOnPage(['name' => $productVariant->getName()]));
119
    }
120
121
    /**
122
     * @Then /^(this variant) should still exist in the product catalog$/
123
     */
124
    public function productShouldExistInTheProductCatalog(ProductVariantInterface $productVariant)
125
    {
126
        $this->theProductVariantShouldAppearInTheShop($productVariant->getCode(), $productVariant->getProduct());
0 ignored issues
show
Compatibility introduced by
$productVariant->getProduct() of type object<Sylius\Component\...Model\ProductInterface> is not a sub-type of object<Sylius\Component\...Model\ProductInterface>. It seems like you assume a child interface of the interface Sylius\Component\Product\Model\ProductInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
127
    }
128
129
    /**
130
     * @Then /^the variant "([^"]+)" should have (\d+) items on hand$/
131
     */
132
    public function thisVariantShouldHaveItemsOnHand($productVariantName, $quantity)
133
    {
134
        Assert::true($this->indexPage->isSingleResourceWithSpecificElementOnPage(
135
            ['name' => $productVariantName],
136
            sprintf('td > div.ui.label:contains("%s")', $quantity)
137
        ));
138
    }
139
140
    /**
141
     * @Then /^the "([^"]+)" variant of ("[^"]+" product) should have (\d+) items on hand$/
142
     */
143
    public function theVariantOfProductShouldHaveItemsOnHand($productVariantName, ProductInterface $product, $quantity)
144
    {
145
        $this->indexPage->open(['productId' => $product->getId()]);
146
147
        Assert::true($this->indexPage->isSingleResourceWithSpecificElementOnPage(
148
            ['name' => $productVariantName],
149
            sprintf('td > div.ui.label:contains("%s")', $quantity)
150
        ));
151
    }
152
153
    /**
154
     * @Then /^I should see that the ("([^"]+)" variant) is not tracked$/
155
     */
156
    public function iShouldSeeThatIsNotTracked(ProductVariantInterface $productVariant)
157
    {
158
        Assert::true($this->indexPage->isSingleResourceOnPage([
159
            'name' => $productVariant->getName(),
160
            'inventory' => 'Not tracked',
161
        ]));
162
    }
163
164
    /**
165
     * @Then /^I should see that the ("[^"]+" variant) has zero on hand quantity$/
166
     */
167
    public function iShouldSeeThatTheVariantHasZeroOnHandQuantity(ProductVariantInterface $productVariant)
168
    {
169
        Assert::true($this->indexPage->isSingleResourceOnPage([
170
            'name' => $productVariant->getName(),
171
            'inventory' => '0 Available on hand',
172
        ]));
173
    }
174
175
    /**
176
     * @Then /^(\d+) units of (this product) should be on hold$/
177
     */
178
    public function unitsOfThisProductShouldBeOnHold($quantity, ProductInterface $product)
179
    {
180
        /** @var ProductVariantInterface $variant */
181
        $variant = $this->defaultProductVariantResolver->getVariant($product);
182
183
        $this->assertOnHoldQuantityOfVariant($quantity, $variant);
184
    }
185
186
    /**
187
     * @Then /^(\d+) units of (this product) should be on hand$/
188
     */
189
    public function unitsOfThisProductShouldBeOnHand($quantity, ProductInterface $product)
190
    {
191
        /** @var ProductVariantInterface $variant */
192
        $variant = $this->defaultProductVariantResolver->getVariant($product);
193
194
        Assert::same($this->indexPage->getOnHandQuantityFor($variant), (int) $quantity);
195
    }
196
197
    /**
198
     * @Then /^there should be no units of (this product) on hold$/
199
     */
200
    public function thereShouldBeNoUnitsOfThisProductOnHold(ProductInterface $product)
201
    {
202
        /** @var ProductVariantInterface $variant */
203
        $variant = $this->defaultProductVariantResolver->getVariant($product);
204
205
        $this->assertOnHoldQuantityOfVariant(0, $variant);
206
    }
207
208
    /**
209
     * @Then the :variant variant should have :amount items on hold
210
     */
211
    public function thisVariantShouldHaveItemsOnHold(ProductVariantInterface $variant, $amount)
212
    {
213
        $this->assertOnHoldQuantityOfVariant((int) $amount, $variant);
214
    }
215
216
    /**
217
     * @Then the :variant variant of :product product should have :amount items on hold
218
     */
219
    public function theVariantOfProductShouldHaveItemsOnHold(ProductVariantInterface $variant, ProductInterface $product, $amount)
220
    {
221
        $this->indexPage->open(['productId' => $product->getId()]);
222
223
        $this->assertOnHoldQuantityOfVariant((int) $amount, $variant);
224
    }
225
226
    /**
227
     * @Then the first variant in the list should have :field :value
228
     */
229
    public function theFirstVariantInTheListShouldHave($field, $value)
230
    {
231
        Assert::same($this->indexPage->getColumnFields($field)[0], $value);
232
    }
233
234
    /**
235
     * @Then the last variant in the list should have :field :value
236
     */
237
    public function theLastVariantInTheListShouldHave($field, $value)
238
    {
239
        $values = $this->indexPage->getColumnFields($field);
240
241
        Assert::same(end($values), $value);
242
    }
243
244
    /**
245
     * @Then /^(this variant) should have a (\d+) item currently in stock$/
246
     */
247
    public function thisVariantShouldHaveAItemCurrentlyInStock(ProductVariantInterface $productVariant, $amountInStock)
248
    {
249
        $this->indexPage->open(['productId' => $productVariant->getProduct()->getId()]);
250
251
        Assert::same($this->indexPage->getOnHandQuantityFor($productVariant), (int) $amountInStock);
252
    }
253
254
    /**
255
     * @param int $expectedAmount
256
     * @param ProductVariantInterface $variant
257
     *
258
     * @throws \InvalidArgumentException
259
     */
260
    private function assertOnHoldQuantityOfVariant($expectedAmount, $variant)
261
    {
262
        $actualAmount = $this->indexPage->getOnHoldQuantityFor($variant);
263
264
        Assert::same(
265
            $actualAmount,
266
            (int) $expectedAmount,
267
            sprintf(
268
                'Unexpected on hold quantity for "%s" variant. It should be "%s" but is "%s"',
269
                $variant->getName(),
270
                $expectedAmount,
271
                $actualAmount
272
            )
273
        );
274
    }
275
276
    /**
277
     * @param ProductInterface $product
278
     * @param int $amount
279
     */
280
    private function assertNumberOfVariantsOnProductPage(ProductInterface $product, $amount)
281
    {
282
        $this->iWantToViewAllVariantsOfThisProduct($product);
283
284
        Assert::same((int) $this->indexPage->countItems(), $amount, 'Product has %d variants, but should have %d');
285
    }
286
}
287