FeatureContext::iShouldGotAnException()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
use Behat\Behat\Context\Context;
4
use Behat\Behat\Context\SnippetAcceptingContext;
5
use Behat\Gherkin\Node\PyStringNode;
6
use Behat\Gherkin\Node\TableNode;
7
8
use Bee4\Transport\Client;
9
10
/**
11
 * Defines application features from the specific context.
12
 */
13
class FeatureContext implements Context, SnippetAcceptingContext
14
{
15
    private $client;
16
17
    private $request;
18
    private $response;
19
    private $error;
20
21
    /**
22
     * Initializes context.
23
     *
24
     * Every scenario gets its own context instance.
25
     * You can also pass arbitrary arguments to the
26
     * context constructor through behat.yml.
27
     */
28
    public function __construct($rootUrl = "http://localhost")
29
    {
30
        $this->client = new Client($rootUrl);
31
        $this->response = null;
32
        $this->request  = null;
33
    }
34
35
    /**
36
     * @Given I make a :method request to :url with :body
37
     * @Given I make a :method request to :url
38
     */
39
    public function iMadeARequestToTheUrl($method, $url, $body = null)
40
    {
41
        $this->request = $this->client->createRequest($method, $url);
42
        if( isset($body) ) {
43
            $this->request->setBody($body);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Bee4\Transport\Message\Request\AbstractRequest as the method setBody() does only exist in the following sub-classes of Bee4\Transport\Message\Request\AbstractRequest: Bee4\Transport\Message\Request\Ftp\Put, Bee4\Transport\Message\Request\Http\Delete, Bee4\Transport\Message\Request\Http\Post, Bee4\Transport\Message\Request\Http\Put, Bee4\Transport\Message\Request\Ssh\Put. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
44
        }
45
        try {
46
            $this->response = $this->request->send();
47
        } catch( \Exception $error ) {
48
            $this->error = $error;
49
            if (method_exists($this->error, "getResponse")) {
50
                $this->response = $error->getResponse();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Exception as the method getResponse() does only exist in the following sub-classes of Exception: Bee4\Transport\Exception\CurlException. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
51
            }
52
        }
53
    }
54
55
    /**
56
     * @Then I should got a status of :status
57
     */
58
    public function iShouldGotAStatusOf($status)
59
    {
60
        return preg_match('/'.$status.'/', $this->response->getStatus())===1;
61
    }
62
63
    /**
64
     * @Then I should got a status different than :status
65
     */
66
    public function iShouldGotAStatusDifferentThan($status)
67
    {
68
        return preg_match('/'.$status.'/', $this->response->getStatus())!==1;
69
    }
70
71
    /**
72
     * @Then I should have an empty body
73
     * @Then I should have a body of :body
74
     */
75
    public function iShouldHaveABodyLike($body = '')
76
    {
77
        return $this->response->getBody()===$body;
78
    }
79
80
    /**
81
     * @Then I should got an exception :type
82
     */
83
    public function iShouldGotAnException($type)
84
    {
85
        return $this->error instanceof $type;
86
    }
87
}
88