Completed
Push — master ( 60b5cc...359431 )
by Michał
458:10 queued 444:50
created

ProductContext::iShouldSeeItIsOutOfStock()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 0
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\Shop;
13
14
use Behat\Behat\Context\Context;
15
use Sylius\Behat\Page\Shop\Product\ShowPageInterface;
16
use Sylius\Behat\Page\SymfonyPageInterface;
17
use Sylius\Component\Core\Model\ProductInterface;
18
use Sylius\Component\Core\Model\TaxonInterface;
19
use Webmozart\Assert\Assert;
20
21
/**
22
 * @author Kamil Kokot <[email protected]>
23
 * @author Magdalena Banasiak <[email protected]>
24
 * @author Anna Walasek <[email protected]>
25
 */
26
final class ProductContext implements Context
27
{
28
    /**
29
     * @var ShowPageInterface
30
     */
31
    private $showPage;
32
33
    /**
34
     * @var SymfonyPageInterface
35
     */
36
    private $taxonShowPage;
37
38
    /**
39
     * @param ShowPageInterface $showPage
40
     * @param SymfonyPageInterface $taxonShowPage
41
     */
42
    public function __construct(
43
        ShowPageInterface $showPage,
44
        SymfonyPageInterface $taxonShowPage
45
    ) {
46
        $this->showPage = $showPage;
47
        $this->taxonShowPage = $taxonShowPage;
48
    }
49
50
    /**
51
     * @Then I should be able to access product :product
52
     */
53
    public function iShouldBeAbleToAccessProduct(ProductInterface $product)
54
    {
55
        $this->showPage->tryToOpen(['slug' => $product->getSlug()]);
56
57
        Assert::true(
58
            $this->showPage->isOpen(['slug' => $product->getSlug()]),
59
            'Product show page should be open, but it does not.'
60
        );
61
    }
62
63
    /**
64
     * @Then I should not be able to access product :product
65
     */
66
    public function iShouldNotBeAbleToAccessProduct(ProductInterface $product)
67
    {
68
        $this->showPage->tryToOpen(['slug' => $product->getSlug()]);
69
70
        Assert::false(
71
            $this->showPage->isOpen(['slug' => $product->getSlug()]),
72
            'Product show page should not be open, but it does.'
73
        );
74
    }
75
76
    /**
77
     * @When /^I check (this product)'s details/
78
     */
79
    public function iOpenProductPage(ProductInterface $product)
80
    {
81
        $this->showPage->open(['slug' => $product->getSlug()]);
82
    }
83
84
    /**
85
     * @Given I should see the product name :name
86
     */
87
    public function iShouldSeeProductName($name)
88
    {
89
        Assert::same(
90
            $name,
91
            $this->showPage->getName(),
92
            'Product should have name %2$s, but it has %s'
93
        );
94
    }
95
96
    /**
97
     * @When I open page :url
98
     */
99
    public function iOpenPage($url)
100
    {
101
        $this->showPage->visit($url);
102
    }
103
104
    /**
105
     * @Then I should be on :product product detailed page
106
     */
107
    public function iShouldBeOnProductDetailedPage(ProductInterface $product)
108
    {
109
        Assert::true(
110
            $this->showPage->isOpen(['slug' => $product->getSlug()]),
111
            sprintf('Product %s show page should be open, but it does not.', $product->getName())
112
        );
113
    }
114
115
    /**
116
     * @Then I should see the product attribute :attributeName with value :AttributeValue
117
     */
118
    public function iShouldSeeTheProductAttributeWithValue($attributeName, $AttributeValue)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $AttributeValue is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style Naming introduced by
The variable $AttributeValue is not named in camelCase.

This check marks variable names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
119
    {
120
        Assert::true(
121
            $this->showPage->hasAttributeWithValue($attributeName, $AttributeValue),
122
            sprintf('Product should have attribute %s with value %s, but it does not.', $attributeName, $AttributeValue)
123
        );
124
    }
125
    
126
    /**
127
     * @When /^I browse products from (taxon "([^"]+)")$/
128
     */
129
    public function iCheckListOfProductsForTaxon(TaxonInterface $taxon)
130
    {
131
        $this->taxonShowPage->open(['permalink' => $taxon->getPermalink()]);
132
    }
133
134
    /**
135
     * @Then I should see the product :productName
136
     */
137
    public function iShouldSeeProduct($productName)
138
    {
139
        Assert::true(
140
            $this->taxonShowPage->isProductInList($productName),
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Sylius\Behat\Page\SymfonyPageInterface as the method isProductInList() does only exist in the following implementations of said interface: Sylius\Behat\Page\Shop\Taxon\ShowPage.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
141
            sprintf("The product %s should appear on page, but it does not.", $productName)
142
        );
143
    }
144
145
    /**
146
     * @Then I should not see the product :productName
147
     */
148
    public function iShouldNotSeeProduct($productName)
149
    {
150
        Assert::false(
151
            $this->taxonShowPage->isProductInList($productName),
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Sylius\Behat\Page\SymfonyPageInterface as the method isProductInList() does only exist in the following implementations of said interface: Sylius\Behat\Page\Shop\Taxon\ShowPage.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
152
            sprintf("The product %s should not appear on page, but it does.", $productName)
153
        );
154
    }
155
156
    /**
157
     * @Then I should see empty list of products
158
     */
159
    public function iShouldSeeEmptyListOfProducts()
160
    {
161
        Assert::true(
162
            $this->taxonShowPage->isEmpty(),
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Sylius\Behat\Page\SymfonyPageInterface as the method isEmpty() does only exist in the following implementations of said interface: Sylius\Behat\Page\Shop\Cart\SummaryPage, Sylius\Behat\Page\Shop\Taxon\ShowPage.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
163
            'There should appear information about empty list of products, but it does not.'
164
        );
165
    }
166
167
    /**
168
     * @Then I should see that it is out of stock
169
     */
170
    public function iShouldSeeItIsOutOfStock()
171
    {
172
        Assert::true(
173
            $this->showPage->isOutOfStock(),
174
            'Out of stock label should be visible.'
175
        );
176
    }
177
178
    /**
179
     * @Then I should be unable to add it to the cart
180
     */
181
    public function iShouldBeUnableToAddItToTheCart()
182
    {
183
        Assert::false(
184
            $this->showPage->hasAddToCartButton(),
185
            'Add to cart button should not be visible.'
186
        );
187
    }
188
}
189