ControllerTraitTest::testTransfer()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
1
<?php
2
namespace FwlibTest\Web;
3
4
use Fwlib\Web\ControllerTrait;
5
use Fwlib\Web\Request;
6
use FwlibTest\Aide\ObjectMockBuilder\FwlibWebRequestTrait;
7
use Fwolf\Wrapper\PHPUnit\PHPUnitTestCase;
8
use PHPUnit_Framework_MockObject_MockObject as MockObject;
9
10
/**
11
 * @copyright   Copyright 2013-2015 Fwolf
12
 * @license     http://www.gnu.org/licenses/lgpl.html LGPL-3.0+
13
 */
14
class ControllerTraitTest extends PHPUnitTestCase
15
{
16
    use FwlibWebRequestTrait;
17
18
19
    /**
20
     * @var string
21
     */
22
    public static $controllerClass;
23
24
    /**
25
     * @var string
26
     */
27
    public static $viewClass;
28
29
30
    /**
31
     * @return  MockObject|ControllerTrait
32
     */
33
    protected function buildMock()
34
    {
35
        $controller = $this->getMockBuilder(ControllerTrait::class)
36
            ->setMethods([
37
                'createController',
38
                'createView',
39
                'getControllerClass',
40
                'getViewClass',
41
            ])
42
            ->getMockForTrait();
43
44
        $controller->expects($this->any())
45
            ->method('getViewClass')
46
            ->will($this->returnCallback(function () {
47
                return ControllerTraitTest::$viewClass;
48
            }));
49
50
        $controller->expects($this->any())
51
            ->method('getControllerClass')
52
            ->will($this->returnCallback(function () {
53
                return ControllerTraitTest::$controllerClass;
54
            }));
55
56
57
        // Mock a controller/view instance for output
58
        $mock = $this->getMock('stdClass', ['getOutput', 'setAction']);
59
        $mock->expects($this->any())
60
            ->method('setAction')
61
            ->will($this->returnSelf());
62
        $mock->expects($this->any())
63
            ->method('getOutput')
64
            ->will($this->returnValue('Dummy Output'));
65
66
        // Attach this mock
67
        $controller->expects($this->any())
68
            ->method('createController')
69
            ->will($this->returnValue($mock));
70
        $controller->expects($this->any())
71
            ->method('createView')
72
            ->will($this->returnValue($mock));
73
74
        /** @noinspection PhpUndefinedFieldInspection */
75
        $controller->module = '';
0 ignored issues
show
Bug introduced by
Accessing module on the interface PHPUnit_Framework_MockObject_MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
76
        /** @noinspection PhpUndefinedFieldInspection */
77
        $controller->defaultModule = '';
0 ignored issues
show
Bug introduced by
Accessing defaultModule on the interface PHPUnit_Framework_MockObject_MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
78
79
        return $controller;
80
    }
81
82
83
    /**
84
     * Build a mock, implements abstract method only
85
     *
86
     * @return  MockObject|ControllerTrait
87
     */
88
    protected function buildMockBasis()
89
    {
90
        $controller = $this->getMockBuilder(ControllerTrait::class)
91
            ->setMethods(['getViewClass'])
92
            ->getMockForTrait();
93
94
        $controller->expects($this->any())
95
            ->method('getViewClass')
96
            ->will($this->returnCallback(function () {
97
                return ControllerTraitTest::$viewClass;
98
            }));
99
100
        /** @var ControllerTrait $controller */
101
        $controller->setRequest($this->buildRequestMock());
102
103
        $controller->module = '';
104
        $controller->defaultModule = '';
105
106
        return $controller;
107
    }
108
109
110
    /**
111
     * Build a mock, with getControllerClass() method
112
     *
113
     * @return  MockObject|ControllerTrait
114
     */
115
    protected function buildMockWithGetControllerClass()
116
    {
117
        $controller = $this->getMockBuilder(ControllerTrait::class)
118
            ->setMethods(['getControllerClass', 'getViewClass'])
119
            ->getMockForTrait();
120
121
        $controller->expects($this->any())
122
            ->method('getControllerClass')
123
            ->will($this->returnCallback(function () {
124
                return ControllerTraitTest::$controllerClass;
125
            }));
126
127
        $controller->expects($this->any())
128
            ->method('getViewClass')
129
            ->will($this->returnCallback(function () {
130
                return ControllerTraitTest::$viewClass;
131
            }));
132
133
        /** @var ControllerTrait $controller */
134
        $controller->setRequest($this->buildRequestMock());
135
136
        $controller->module = '';
137
        $controller->defaultModule = '';
138
139
        return $controller;
140
    }
141
142
143
    public function testDisplay()
144
    {
145
        $controller = $this->buildMock();
146
147
        $this->getAction = 'test-action';
148
        // Need a dummy view class name, empty will throw exception
149
        self::$viewClass = 'Dummy';
150
151
        $output = $controller->getOutput();
0 ignored issues
show
Bug introduced by
The method getOutput does only exist in Fwlib\Web\ControllerTrait, but not in PHPUnit_Framework_MockObject_MockObject.

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...
152
        $this->assertEquals('Dummy Output', $output);
153
154
        // Action can be empty, need View allow output without action.
155
        $this->getAction = '';
156
        $output = $controller->getOutput();
157
        $this->assertEquals('Dummy Output', $output);
158
    }
159
160
161
    public function testDisplayWithActualView()
162
    {
163
        $controller = $this->buildMockWithGetControllerClass();
164
        self::$viewClass = ControllerAndViewDummy::class;
165
166
        $output = $controller->getOutput();
0 ignored issues
show
Bug introduced by
The method getOutput does only exist in Fwlib\Web\ControllerTrait, but not in PHPUnit_Framework_MockObject_MockObject.

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...
167
        $this->assertEquals('Output from dummy', $output);
168
    }
169
170
171
    public function testDisplayWithEmptyViewClass()
172
    {
173
        $controller = $this->buildMock();
174
175
        $this->getAction = 'test-action';
176
        self::$viewClass = '';
177
178
        $output = $controller->getOutput();
0 ignored issues
show
Bug introduced by
The method getOutput does only exist in Fwlib\Web\ControllerTrait, but not in PHPUnit_Framework_MockObject_MockObject.

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...
179
        $this->assertStringStartsWith('Error: View for action', $output);
180
    }
181
182
183
    public function testGetRequestModule()
184
    {
185
        $controller = $this->buildMock();
186
        $request = $controller->getRequest();
0 ignored issues
show
Bug introduced by
The method getRequest does only exist in Fwlib\Web\ControllerTrait, but not in PHPUnit_Framework_MockObject_MockObject.

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...
187
188
        $request->setModule('');
189
        $this->reflectionSet($controller, 'defaultModule', 'fooModule');
190
191
        $this->assertEquals(
192
            'fooModule',
193
            $this->reflectionCall($controller, 'getRequestModule')
194
        );
195
        /** @var Request $request */
196
        $this->assertEquals('fooModule', $request->getModule());
197
    }
198
199
200
    public function testTransfer()
201
    {
202
        $controller = $this->buildMock();
203
204
        $this->getModule = 'testModule';
205
        // Need a dummy view class name, or will throw exception
206
        self::$controllerClass = 'Dummy';
207
208
        $output = $controller->getOutput();
0 ignored issues
show
Bug introduced by
The method getOutput does only exist in Fwlib\Web\ControllerTrait, but not in PHPUnit_Framework_MockObject_MockObject.

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...
209
        $this->assertEquals('Dummy Output', $output);
210
    }
211
212
213
    public function testTransferWithActualController()
214
    {
215
        $this->getModule = 'testModule';
216
        $controller = $this->buildMockWithGetControllerClass();
217
218
        self::$controllerClass = ControllerAndViewDummy::class;
219
220
        $output = $controller->getOutput();
0 ignored issues
show
Bug introduced by
The method getOutput does only exist in Fwlib\Web\ControllerTrait, but not in PHPUnit_Framework_MockObject_MockObject.

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...
221
        $this->assertEquals('Output from dummy', $output);
222
    }
223
224
225
    public function testTransferWithEmptyControllerClass()
226
    {
227
        $this->getModule = 'testModule';
228
        $controller = $this->buildMockBasis();
229
230
        $output = $controller->getOutput();
0 ignored issues
show
Bug introduced by
The method getOutput does only exist in Fwlib\Web\ControllerTrait, but not in PHPUnit_Framework_MockObject_MockObject.

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...
231
        $this->assertStringStartsWith('Error: Controller for module', $output);
232
    }
233
}
234