Completed
Push — master ( d9b0e4...7d3622 )
by Florent
11:03
created

FeatureContext::iWantToVerifyIfIsGranted()   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
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2014-2015 Spomky-Labs
7
 *
8
 * This software may be modified and distributed under the terms
9
 * of the MIT license.  See the LICENSE file for details.
10
 */
11
12
namespace SpomkyLabs\TestRoleHierarchyBundle\Features\Context;
13
14
use Behat\Behat\Context\SnippetAcceptingContext;
15
use Behat\MinkExtension\Context\MinkContext;
16
use Behat\Symfony2Extension\Context\KernelDictionary;
17
use Symfony\Component\BrowserKit\Cookie;
18
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
19
20
/**
21
 * Behat context class.
22
 */
23
class FeatureContext extends MinkContext implements SnippetAcceptingContext
24
{
25
    use KernelDictionary;
26
27
    /**
28
     * @var bool
29
     */
30
    private $result;
31
32
    /**
33
     * @Given I am logged in as :username
34
     */
35
    public function iAmAnLoggedInAs($username)
36
    {
37
        $client = $this->getSession()->getDriver()->getClient();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Behat\Mink\Driver\DriverInterface as the method getClient() does only exist in the following implementations of said interface: Behat\Mink\Driver\BrowserKitDriver, Behat\Symfony2Extension\Driver\KernelDriver.

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...
38
39
        $session = $client->getContainer()->get('session');
40
41
        $user = $this->getContainer()->get('test_bundle.user_manager')->getUser($username);
42
43
        $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
44
        $session->set('_security_main', serialize($token));
45
        $session->save();
46
47
        $cookie = new Cookie($session->getName(), $session->getId());
48
        $client->getCookieJar()->set($cookie);
49
    }
50
51
    /**
52
     * @Given I am on the page :uri
53
     */
54
    public function iAmOnThePage($uri)
55
    {
56
        $client = $this->getSession()->getDriver()->getClient();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Behat\Mink\Driver\DriverInterface as the method getClient() does only exist in the following implementations of said interface: Behat\Mink\Driver\BrowserKitDriver, Behat\Symfony2Extension\Driver\KernelDriver.

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...
57
        $client->request('GET', $uri);
58
    }
59
60
    /**
61
     * @When I want to verify if I am granted :grant
62
     */
63
    public function iWantToVerifyIfIsGranted($grant)
64
    {
65
        $this->result = $this->getContainer()->get('security.authorization_checker')->isGranted($grant);
66
    }
67
68
    /**
69
     * @Then I should get true
70
     */
71
    public function iShouldGetTrue()
72
    {
73
        if (true !== $this->result) {
74
            throw new \Exception('I did not get true.');
75
        }
76
    }
77
78
    /**
79
     * @Then I should get false
80
     */
81
    public function iShouldGetFalse()
82
    {
83
        if (false !== $this->result) {
84
            throw new \Exception('I did not get false.');
85
        }
86
    }
87
}
88