Completed
Push — master ( e69772...1b92c1 )
by Arnold
01:43
created

SessionsAuth::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
namespace Jasny\Auth;
4
5
use Jasny\Auth;
6
use PHPUnit_Framework_TestCase as TestCase;
7
use PHPUnit_Framework_MockObject_MockObject as MockObject;
8
9
/**
10
 * @covers Jasny\Auth\Sessions
11
 */
12
class SessionsAuth extends TestCase
13
{
14
    /**
15
     * @var Auth\Sessions|MockObject 
16
     */
17
    protected $auth;
18
    
19
    /**
20
     * @var string
21
     */
22
    protected $sessionModule;
23
24
    protected function mockSessionHandling()
25
    {
26
        // Mock sessions
27
        session_cache_limiter('');
28
        ini_set('session.use_cookies', 0);
29
        ini_set('session.use_only_cookies', 0);
30
        
31
        $this->sessionModule = session_module_name();
32
        session_set_save_handler($this->createMock(\SessionHandlerInterface::class));
33
        
34
        session_start();
35
    }
36
    
37
    protected function restoreSessionHandling()
38
    {
39
        session_abort();
40
        session_module_name($this->sessionModule);
41
    }
42
    
43
    public function setUp()
44
    {
45
        $this->auth = $this->getMockForTrait(Auth\Sessions::class);
46
        $this->mockSessionHandling();
47
    }
48
    
49
    public function tearDown()
50
    {
51
        $this->restoreSessionHandling();
52
    }
53
    
54
    
55
    /**
56
     * Call a protected method
57
     * 
58
     * @param object $object
59
     * @param string $method
60
     * @param array  $args
61
     * @return mixed
62
     */
63
    protected function callProtectedMethod($object, $method, array $args = [])
64
    {
65
        $refl = new \ReflectionMethod(get_class($object), $method);
66
        $refl->setAccessible(true);
67
        
68
        return $refl->invokeArgs($object, $args);
69
    }
70
    
71
    
72
    public function testGetCurrentUserIdWithUser()
0 ignored issues
show
Coding Style introduced by
testGetCurrentUserIdWithUser uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
73
    {
74
        $_SESSION['auth_uid'] = 123;
75
        
76
        $id = $this->callProtectedMethod($this->auth, 'getCurrentUserId');
0 ignored issues
show
Bug introduced by
It seems like $this->auth can also be of type object<Jasny\Auth\Sessions>; however, Jasny\Auth\SessionsAuth::callProtectedMethod() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
77
        $this->assertEquals(123, $id);
78
    }
79
    
80
    public function testGetCurrentUserIdWithoutUser()
81
    {
82
        $id = $this->callProtectedMethod($this->auth, 'getCurrentUserId');
0 ignored issues
show
Bug introduced by
It seems like $this->auth can also be of type object<Jasny\Auth\Sessions>; however, Jasny\Auth\SessionsAuth::callProtectedMethod() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
83
        $this->assertNull($id);
84
    }
85
    
86
    
87
    public function testPersistCurrentUserWithUser()
0 ignored issues
show
Coding Style introduced by
testPersistCurrentUserWithUser uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
88
    {
89
        $_SESSION['foo'] = 'bar';
90
        
91
        $user = $this->createMock(Auth\User::class);
92
        $user->method('getId')->willReturn(123);
93
        
94
        $this->auth->expects($this->once())->method('user')->willReturn($user);
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Jasny\Auth\Sessions.

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...
95
        
96
        $this->callProtectedMethod($this->auth, 'persistCurrentUser');
0 ignored issues
show
Bug introduced by
It seems like $this->auth can also be of type object<Jasny\Auth\Sessions>; however, Jasny\Auth\SessionsAuth::callProtectedMethod() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
97
        
98
        $this->assertEquals(['foo' => 'bar', 'auth_uid' => 123], $_SESSION);
99
    }
100
    
101
    public function testPersistCurrentUserWithoutUser()
0 ignored issues
show
Coding Style introduced by
testPersistCurrentUserWithoutUser uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
102
    {
103
        $_SESSION['auth_uid'] = 123;
104
        $_SESSION['foo'] = 'bar';
105
        
106
        $this->auth->expects($this->once())->method('user')->willReturn(null);
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Jasny\Auth\Sessions.

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...
107
        
108
        $this->callProtectedMethod($this->auth, 'persistCurrentUser');
0 ignored issues
show
Bug introduced by
It seems like $this->auth can also be of type object<Jasny\Auth\Sessions>; however, Jasny\Auth\SessionsAuth::callProtectedMethod() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
109
        
110
        $this->assertEquals(['foo' => 'bar'], $_SESSION);
111
    }
112
}
113