Passed
Push — master ( aac959...f67e8c )
by Anatoly
01:26
created

anonymous//tests/RouterTest.php$2   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 5
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
wmc 1
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\Message\ResponseInterface;
8
use Psr\Http\Message\ServerRequestInterface;
9
use Psr\Http\Server\MiddlewareInterface;
10
use Psr\Http\Server\RequestHandlerInterface;
11
use Sunrise\Http\Message\ResponseFactory;
12
use Sunrise\Http\Router\Exception\BadRequestException;
13
use Sunrise\Http\Router\Exception\HttpException;
14
use Sunrise\Http\Router\Exception\HttpExceptionInterface;
15
use Sunrise\Http\Router\Exception\MethodNotAllowedException;
16
use Sunrise\Http\Router\Exception\PageNotFoundException;
17
use Sunrise\Http\Router\RouteInterface;
18
use Sunrise\Http\Router\RouteCollection;
19
use Sunrise\Http\Router\Router;
20
use Sunrise\Http\Router\RouterInterface;
21
use Sunrise\Http\ServerRequest\ServerRequestFactory;
22
23
class RouterTest extends TestCase
24
{
25
	use HelpersInjectTest;
26
27
	public function testConstructor()
28
	{
29
		$router = new Router();
30
31
		$this->assertInstanceOf(RouterInterface::class, $router);
32
		$this->assertInstanceOf(RequestHandlerInterface::class, $router);
33
		$this->assertInstanceOf(RouteCollection::class, $router);
34
	}
35
36
	public function testMatch()
37
	{
38
		$router = new Router();
39
40
		$router->get('home', '/', $this->getRouteActionFoo());
41
42
		$request = (new ServerRequestFactory)
43
		->createServerRequest('GET', '/');
44
45
		$route = $router->match($request);
46
47
		$this->assertEquals('home', $route->getId());
48
	}
49
50
	public function testMatchPageNotFoundException()
51
	{
52
		$this->expectException(PageNotFoundException::class);
53
54
		$router = new Router();
55
56
		$router->get('home', '/', $this->getRouteActionFoo());
57
58
		$request = (new ServerRequestFactory)
59
		->createServerRequest('GET', '/404');
60
61
		$router->match($request);
62
	}
63
64
	public function testMatchMethodNotAllowedException()
65
	{
66
		$this->expectException(MethodNotAllowedException::class);
67
68
		$router = new Router();
69
70
		$router->safe('home', '/', $this->getRouteActionFoo());
71
72
		$request = (new ServerRequestFactory)
73
		->createServerRequest('POST', '/');
74
75
		try
76
		{
77
			$router->match($request);
78
		}
79
		catch (MethodNotAllowedException $e)
80
		{
81
			$allowedMethods[] = RequestMethodInterface::METHOD_HEAD;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$allowedMethods was never initialized. Although not strictly required by PHP, it is generally a good practice to add $allowedMethods = array(); before regardless.
Loading history...
82
			$allowedMethods[] = RequestMethodInterface::METHOD_GET;
83
84
			$this->assertEquals($allowedMethods, $e->getAllowedMethods());
85
86
			throw $e;
87
		}
88
		catch (\Throwable $e)
89
		{
90
			throw $e;
91
		}
92
	}
93
94
	public function testMatchWithRouteAttributes()
95
	{
96
		$router = new Router();
97
98
		$router->patch('post.update', '/post/{id}', $this->getRouteActionFoo());
99
100
		$request = (new ServerRequestFactory)
101
		->createServerRequest('PATCH', '/post/100');
102
103
		$route = $router->match($request);
104
105
		$this->assertEquals('post.update', $route->getId());
106
		$this->assertArraySubset(['id' => '100'], $route->getAttributes());
107
	}
108
109
	public function testMatchWithSeveralRouteAttributes()
110
	{
111
		$router = new Router();
112
113
		$router->patch('post.update', '/post/{section}/{post}', $this->getRouteActionFoo());
114
115
		$request = (new ServerRequestFactory)
116
		->createServerRequest('PATCH', '/post/100/200');
117
118
		$route = $router->match($request);
119
120
		$this->assertEquals('post.update', $route->getId());
121
		$this->assertArraySubset([
122
			'section' => '100',
123
			'post' => '200',
124
		], $route->getAttributes());
125
	}
126
127
	public function testMatchWithRoutePatterns()
128
	{
129
		$router = new Router();
130
131
		$route = $router->patch('menu.item.move', '/menu/item/{id}/{direction}', $this->getRouteActionFoo());
132
		$route->pattern('id', '\d+');
133
		$route->pattern('direction', 'up|down');
134
135
		$route = $router->match((new ServerRequestFactory)
136
		->createServerRequest('PATCH', '/menu/item/100/up'));
137
138
		$this->assertEquals('menu.item.move', $route->getId());
139
		$this->assertArraySubset([
140
			'id' => '100',
141
			'direction' => 'up',
142
		], $route->getAttributes());
143
144
		$route = $router->match((new ServerRequestFactory)
145
		->createServerRequest('PATCH', '/menu/item/100/down'));
146
147
		$this->assertEquals('menu.item.move', $route->getId());
148
		$this->assertArraySubset([
149
			'id' => '100',
150
			'direction' => 'down',
151
		], $route->getAttributes());
152
	}
153
154
	public function testMatchPageNotFoundExceptionDueInvalidAttributes()
155
	{
156
		$this->expectException(PageNotFoundException::class);
157
158
		$router = new Router();
159
160
		$route = $router->delete('post.delete', '/post/{id}', $this->getRouteActionFoo());
161
		$route->pattern('id', '\d+');
162
163
		$request = (new ServerRequestFactory)
164
		->createServerRequest('DELETE', '/post/a');
165
166
		$router->match($request);
167
	}
168
169
	public function testHandle()
170
	{
171
		$router = new Router();
172
		$router->middleware($this->getMiddlewareFoo());
173
		$router->middleware($this->getMiddlewareBar());
174
175
		$route = $router->get('home', '/', $this->getRouteActionFoo());
176
		$route->middleware($this->getMiddlewareBaz());
177
		$route->middleware($this->getMiddlewareQux());
178
179
		$request = (new ServerRequestFactory)
180
		->createServerRequest('GET', '/');
181
182
		$response = $router->handle($request);
183
184
		$this->assertEquals([
185
			'route-foo',
186
			'middleware-qux',
187
			'middleware-baz',
188
			'middleware-bar',
189
			'middleware-foo',
190
		], $response->getHeader('x-queue'));
191
	}
192
193
	public function testExceptions()
194
	{
195
		$request = (new ServerRequestFactory)
196
		->createServerRequest('GET', '/');
197
198
		$response = (new ResponseFactory)
199
		->createResponse(200);
200
201
		$httpException = new HttpException($request, $response);
202
		$this->assertInstanceOf(\RuntimeException::class, $httpException);
203
		$this->assertInstanceOf(HttpExceptionInterface::class, $httpException);
204
		$this->assertEquals($request, $httpException->getRequest());
205
		$this->assertEquals($response, $httpException->getResponse());
206
207
		$badRequestException = new BadRequestException($request);
208
		$this->assertInstanceOf(HttpException::class, $badRequestException);
209
		$this->assertEquals(400, $badRequestException->getResponse()->getStatusCode());
210
211
		$pageNotFoundException = new PageNotFoundException($request);
212
		$this->assertInstanceOf(HttpException::class, $pageNotFoundException);
213
		$this->assertEquals(404, $pageNotFoundException->getResponse()->getStatusCode());
214
215
		$methodNotAllowedException = new MethodNotAllowedException($request, ['HEAD', 'GET']);
216
		$this->assertInstanceOf(HttpException::class, $methodNotAllowedException);
217
		$this->assertEquals(['HEAD', 'GET'], $methodNotAllowedException->getAllowedMethods());
218
		$this->assertEquals(405, $methodNotAllowedException->getResponse()->getStatusCode());
219
	}
220
}
221