summaryrefslogtreecommitdiffstats
path: root/tests/Router/Runner/PhpScriptTest.php
blob: 658998be7fb41a3214b1722ae6a7263adc2e0d0f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php

namespace Jasny\Router;

use Jasny\Router\Route;
use Jasny\Router\Runner;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;

/**
 * @covers Jasny\Router\Runner\PhpScript
 */
class PhpScriptTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var vfsStreamDirectory
     */
    protected $root;
    
    public function setUp()
    {
        $this->root = vfsStream::setup('root');
        $this->root->addChild(vfsStream::newFile('true.php')->setContent('<?php ?>'));
        $this->root->addChild(vfsStream::newFile('foo.php')->setContent('<?php return "foo"; ?>'));
    }

    public function testInvoke()
    {
        $request = $this->createMock(ServerRequestInterface::class);
        $response = $this->createMock(ResponseInterface::class);
        $finalResponse = $this->createMock(ResponseInterface::class);

        $route = $this->createMock(Route::class);
        $route->file = vfsStream::url('root/foo.php');
        
        $request->expects($this->once())->method('getAttribute')->with('route')->willReturn($route);
        
        $runner = $this->getMockBuilder(Runner\PhpScript::class)->setMethods(['includeScript'])->getMock();
        $runner->expects($this->once())->method('includeScript')
            ->with(vfsStream::url('root/foo.php'), $request, $response)
            ->willReturn($finalResponse);

        $result = $runner($request, $response);
        
        $this->assertSame($finalResponse, $result);
    }
    
    public function phpScriptProvider()
    {
        $routeTrue = $this->createMock(Route::class);
        $routeTrue->file = vfsStream::url('root/true.php');
        
        $routeFoo = $this->createMock(Route::class);
        $routeFoo->file = vfsStream::url('root/foo.php');
        
        return [
            [$routeTrue, 1],
            [$routeFoo, 'foo']
        ];
    }
    
    /**
     * @dataProvider phpScriptProvider
     * 
     * @param Route $route
     * @param mixed $expected
     */
    public function testInvokeIncludeScript($route, $expected)
    {
        $request = $this->createMock(ServerRequestInterface::class);
        $response = $this->createMock(ResponseInterface::class);
        $request->expects($this->once())->method('getAttribute')->with($this->equalTo('route'))->will($this->returnValue($route));

        $runner = new Runner\PhpScript($route);
        
        if ($expected === 1) {
            $expected = $response;
        }
        
        $result = $runner->run($request, $response);
        
        $this->assertSame($expected, $result);
    }

    /**
     * @expectedException \RuntimeException
     * @expectedExceptionMessage Failed to route using 'vfs://root/bar.php': File doesn't exist
     */
    public function testInvokeWithNonExistingFile()
    {
        $request = $this->createMock(ServerRequestInterface::class);
        $response = $this->createMock(ResponseInterface::class);

        $route = $this->createMock(Route::class);
        $route->file = vfsStream::url('root/bar.php');
        
        $request->expects($this->once())->method('getAttribute')->with('route')->willReturn($route);
        
        $runner = $this->getMockBuilder(Runner\PhpScript::class)->setMethods(['includeScript'])->getMock();
        $runner->expects($this->never())->method('includeScript');

        $runner($request, $response);
    }

    /**
     * @expectedException \RuntimeException
     * @expectedExceptionMessage Won't route to 'vfs://root/../bar.php': '~', '..' are not allowed in filename
     */
    public function testInvokeWithIlligalFilename()
    {
        $request = $this->createMock(ServerRequestInterface::class);
        $response = $this->createMock(ResponseInterface::class);

        $route = $this->createMock(Route::class);
        $route->file = vfsStream::url('root/../bar.php');
        
        $request->expects($this->once())->method('getAttribute')->with('route')->willReturn($route);
        
        $runner = $this->getMockBuilder(Runner\PhpScript::class)->setMethods(['includeScript'])->getMock();
        $runner->expects($this->never())->method('includeScript');

        $runner($request, $response);
    }
    
}