Passed
Push — master ( c47bc5...6702e4 )
by Anatoly
02:20
created

RouterTest::testAddMiddleware()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Sunrise\Http\Router\Tests;
4
5
use Fig\Http\Message\RequestMethodInterface;
6
use PHPUnit\Framework\TestCase;
7
use Psr\Http\Server\RequestHandlerInterface;
8
use Sunrise\Http\Message\ResponseFactory;
9
use Sunrise\Http\Router\Exception\HttpExceptionInterface;
10
use Sunrise\Http\Router\Exception\MethodNotAllowedException;
11
use Sunrise\Http\Router\Exception\RouteNotFoundException;
12
use Sunrise\Http\Router\RouteCollection;
13
use Sunrise\Http\Router\Router;
14
use Sunrise\Http\Router\RouterInterface;
15
use Sunrise\Http\ServerRequest\ServerRequestFactory;
16
17
// fake middlewares
18
use Sunrise\Http\Router\Tests\Middleware\FooMiddlewareTest;
19
use Sunrise\Http\Router\Tests\Middleware\BarMiddlewareTest;
20
use Sunrise\Http\Router\Tests\Middleware\BazMiddlewareTest;
21
use Sunrise\Http\Router\Tests\Middleware\QuxMiddlewareTest;
22
23
class RouterTest extends TestCase
24
{
25
	public function testConstructor()
26
	{
27
		$routes = new RouteCollection();
28
		$router = new Router($routes);
29
30
		$this->assertInstanceOf(RouterInterface::class, $router);
31
		$this->assertInstanceOf(RequestHandlerInterface::class, $router);
32
	}
33
34
	public function testGetMiddlewareStack()
35
	{
36
		$routes = new RouteCollection();
37
		$router = new Router($routes);
38
39
		$this->assertEquals([], $router->getMiddlewareStack());
40
	}
41
42
	public function testAddMiddleware()
43
	{
44
		$foo = new FooMiddlewareTest();
45
46
		$routes = new RouteCollection();
47
		$router = new Router($routes);
48
49
		$this->assertInstanceOf(RouterInterface::class, $router->addMiddleware($foo));
50
51
		$this->assertEquals([$foo], $router->getMiddlewareStack());
52
	}
53
54
	public function testAddSeveralMiddlewares()
55
	{
56
		$foo = new FooMiddlewareTest();
57
		$bar = new BarMiddlewareTest();
58
59
		$routes = new RouteCollection();
60
		$router = new Router($routes);
61
62
		$router->addMiddleware($foo);
63
		$router->addMiddleware($bar);
64
65
		$this->assertEquals([
66
			$foo,
67
			$bar,
68
		], $router->getMiddlewareStack());
69
	}
70
71
	public function testMatch()
72
	{
73
		$request = (new ServerRequestFactory)
74
		->createServerRequest('GET', '/');
75
76
		$routes = new RouteCollection();
77
		$routes->get('foo', '/foo');
78
		$routes->get('bar', '/bar');
79
		$routes->get('baz', '/baz');
80
		$router = new Router($routes);
81
82
		$expected = $routes->get('home', '/');
83
		$actual = $router->match($request);
84
85
		$this->assertEquals($expected->getId(), $actual->getId());
86
	}
87
88
	public function testMatchSimple404()
89
	{
90
		$request = (new ServerRequestFactory)
91
		->createServerRequest('GET', '/');
92
93
		$routes = new RouteCollection();
94
		$routes->get('foo', '/foo');
95
		$routes->get('bar', '/bar');
96
		$routes->get('baz', '/baz');
97
		$router = new Router($routes);
98
99
		$this->expectException(RouteNotFoundException::class);
100
101
		$router->match($request);
102
	}
103
104
	public function testMatchSimple405()
105
	{
106
		$request = (new ServerRequestFactory)
107
		->createServerRequest('GET', '/foo');
108
109
		$routes = new RouteCollection();
110
		$routes->post('foo', '/foo');
111
		$routes->patch('foo', '/foo');
112
		$routes->delete('foo', '/foo');
113
		$router = new Router($routes);
114
115
		$this->expectException(MethodNotAllowedException::class);
116
117
		try
118
		{
119
			$router->match($request);
120
		}
121
		catch (MethodNotAllowedException $e)
122
		{
123
			$this->assertEquals(['POST', 'PATCH', 'DELETE'], $e->getAllowedMethods());
124
125
			throw $e;
126
		}
127
	}
128
129
	public function testMatchAdvanced()
130
	{
131
		$routes = new RouteCollection();
132
133
		$static   = $routes->get('static', '/foo');
134
		$dynamic  = $routes->get('dynamic', '/bar/{p}');
135
		$digit    = $routes->get('digit', '/baz/{p}')->addPattern('p', '\d+');
136
		$word     = $routes->get('word', '/qux/{p}')->addPattern('p', '\w+');
137
		$asterisk = $routes->get('asterisk', '{p}')->addPattern('p', '.*?');
138
139
		$router = new Router($routes);
140
141
		$route = $router->match((new ServerRequestFactory)->createServerRequest('GET', '/foo'));
142
		$this->assertEquals($static->getId(), $route->getId());
143
144
		$route = $router->match((new ServerRequestFactory)->createServerRequest('GET', '/bar/123'));
145
		$this->assertEquals($dynamic->getId(), $route->getId());
146
		$this->assertArraySubset(['p' => '123'], $route->getAttributes('p'));
0 ignored issues
show
Unused Code introduced by
The call to Sunrise\Http\Router\Rout...erface::getAttributes() has too many arguments starting with 'p'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

146
		$this->assertArraySubset(['p' => '123'], $route->/** @scrutinizer ignore-call */ getAttributes('p'));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
147
148
		$route = $router->match((new ServerRequestFactory)->createServerRequest('GET', '/bar/qwerty'));
149
		$this->assertEquals($dynamic->getId(), $route->getId());
150
		$this->assertArraySubset(['p' => 'qwerty'], $route->getAttributes('p'));
151
152
		$route = $router->match((new ServerRequestFactory)->createServerRequest('GET', '/baz/123'));
153
		$this->assertEquals($digit->getId(), $route->getId());
154
		$this->assertArraySubset(['p' => '123'], $route->getAttributes('p'));
155
156
		$route = $router->match((new ServerRequestFactory)->createServerRequest('GET', '/qux/qwerty'));
157
		$this->assertEquals($word->getId(), $route->getId());
158
		$this->assertArraySubset(['p' => 'qwerty'], $route->getAttributes('p'));
159
160
		$route = $router->match((new ServerRequestFactory)->createServerRequest('GET', '/123/qwerty'));
161
		$this->assertEquals($asterisk->getId(), $route->getId());
162
		$this->assertArraySubset(['p' => '/123/qwerty'], $route->getAttributes('p'));
163
164
		$route = $router->match((new ServerRequestFactory)->createServerRequest('GET', ''));
165
		$this->assertEquals($asterisk->getId(), $route->getId());
166
		$this->assertArraySubset(['p' => ''], $route->getAttributes('p'));
167
	}
168
169
	public function testHandle()
170
	{
171
		$routes = new RouteCollection();
172
173
		$routes->get('home', '/')
174
		->addMiddleware(new BazMiddlewareTest())
175
		->addMiddleware(new QuxMiddlewareTest());
176
177
		$router = new Router($routes);
178
		$router->addMiddleware(new FooMiddlewareTest());
179
		$router->addMiddleware(new BarMiddlewareTest());
180
181
		$request = (new ServerRequestFactory)
182
		->createServerRequest('GET', '/');
183
184
		$response = $router->handle($request);
185
186
		$this->assertEquals([
187
			'qux',
188
			'baz',
189
			'bar',
190
			'foo',
191
		], $response->getHeader('x-middleware'));
192
	}
193
194
	public function testExceptions()
195
	{
196
		$request = (new ServerRequestFactory)
197
		->createServerRequest('GET', '/');
198
199
		$routeNotFoundException = new RouteNotFoundException($request);
200
		$this->assertInstanceOf(HttpExceptionInterface::class, $routeNotFoundException);
201
		$this->assertInstanceOf(\RuntimeException::class, $routeNotFoundException);
202
203
		$methodNotAllowedException = new MethodNotAllowedException($request, ['HEAD', 'GET']);
204
		$this->assertInstanceOf(HttpExceptionInterface::class, $methodNotAllowedException);
205
		$this->assertInstanceOf(\RuntimeException::class, $methodNotAllowedException);
206
		$this->assertEquals(['HEAD', 'GET'], $methodNotAllowedException->getAllowedMethods());
207
	}
208
}
209