Skip to content

Commit a6750c2

Browse files
committed
test for redirect
1 parent f320907 commit a6750c2

1 file changed

Lines changed: 169 additions & 0 deletions

File tree

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace LightTest\Unit\App;
6+
7+
use Laminas\Diactoros\Response\RedirectResponse;
8+
use Light\App\Handler\GetFeedViewHandler;
9+
use Light\App\Handler\GetIndexViewHandler;
10+
use Light\App\Handler\GetMarkdownArticleHandler;
11+
use Light\App\Handler\GetPackagesViewHandler;
12+
use Light\App\Handler\GetSitemapViewHandler;
13+
use Light\App\RoutesDelegator;
14+
use LightTest\Unit\UnitTest;
15+
use Mezzio\Application;
16+
use Mezzio\Router\Route;
17+
use PHPUnit\Framework\MockObject\Exception;
18+
use Psr\Container\ContainerExceptionInterface;
19+
use Psr\Container\ContainerInterface;
20+
use Psr\Container\NotFoundExceptionInterface;
21+
use Psr\Http\Message\ServerRequestInterface;
22+
use Psr\Http\Message\UriInterface;
23+
24+
use function sprintf;
25+
26+
class RoutesDelegatorTest extends UnitTest
27+
{
28+
/** @var array<string, array{handler: mixed, name: string|null}> */
29+
private array $registeredRoutes = [];
30+
31+
/**
32+
* @throws ContainerExceptionInterface
33+
* @throws Exception
34+
* @throws NotFoundExceptionInterface
35+
*/
36+
public function testWillRegisterAllRoutes(): void
37+
{
38+
$container = $this->createStub(ContainerInterface::class);
39+
$app = $this->createStub(Application::class);
40+
41+
$app->method('get')->willReturnCallback(function (string $uri, mixed $handler, ?string $name = null) {
42+
$this->registeredRoutes[$uri] = ['handler' => $handler, 'name' => $name];
43+
44+
return $this->createStub(Route::class);
45+
});
46+
47+
$application = (new RoutesDelegator())($container, '', fn () => $app);
48+
49+
$this->assertSame($app, $application);
50+
51+
$this->assertSame([GetIndexViewHandler::class], $this->registeredRoutes['/']['handler']);
52+
$this->assertSame('app::index', $this->registeredRoutes['/']['name']);
53+
54+
$this->assertSame([GetFeedViewHandler::class], $this->registeredRoutes['/feed/']['handler']);
55+
$this->assertSame('app::feed', $this->registeredRoutes['/feed/']['name']);
56+
57+
$this->assertSame([GetSitemapViewHandler::class], $this->registeredRoutes['/sitemap/']['handler']);
58+
$this->assertSame('app::sitemap', $this->registeredRoutes['/sitemap/']['name']);
59+
60+
$this->assertSame(
61+
[GetMarkdownArticleHandler::class],
62+
$this->registeredRoutes['/{categorySlug}/{slug}.md']['handler']
63+
);
64+
$this->assertSame('app::markdown-article', $this->registeredRoutes['/{categorySlug}/{slug}.md']['name']);
65+
66+
$this->assertSame(
67+
[GetPackagesViewHandler::class],
68+
$this->registeredRoutes['/dotkernel-packages-oss-lifecycle/']['handler']
69+
);
70+
$this->assertSame(
71+
GetPackagesViewHandler::TEMPLATE,
72+
$this->registeredRoutes['/dotkernel-packages-oss-lifecycle/']['name']
73+
);
74+
75+
$this->assertArrayHasKey('/{wpPath:wp-.*}', $this->registeredRoutes);
76+
$this->assertArrayHasKey('/{first}', $this->registeredRoutes);
77+
$this->assertArrayHasKey('/{first}/{second}', $this->registeredRoutes);
78+
}
79+
80+
/**
81+
* @throws ContainerExceptionInterface
82+
* @throws Exception
83+
* @throws NotFoundExceptionInterface
84+
*/
85+
public function testWpPrefixedPathRouteRedirectsToHomepage(): void
86+
{
87+
$handler = $this->captureRouteHandler('/{wpPath:wp-.*}');
88+
89+
$response = $handler();
90+
91+
$this->assertInstanceOf(RedirectResponse::class, $response);
92+
$this->assertSame(301, $response->getStatusCode());
93+
$this->assertSame('/', $response->getHeaderLine('Location'));
94+
}
95+
96+
/**
97+
* @throws ContainerExceptionInterface
98+
* @throws Exception
99+
* @throws NotFoundExceptionInterface
100+
*/
101+
public function testFirstSegmentCatchAllAppendsTrailingSlash(): void
102+
{
103+
$handler = $this->captureRouteHandler('/{first}');
104+
$request = $this->createRequestForUri('/some-page');
105+
106+
$response = $handler($request);
107+
108+
$this->assertInstanceOf(RedirectResponse::class, $response);
109+
$this->assertSame(301, $response->getStatusCode());
110+
$this->assertSame('/some-page/', $response->getHeaderLine('Location'));
111+
}
112+
113+
/**
114+
* @throws ContainerExceptionInterface
115+
* @throws Exception
116+
* @throws NotFoundExceptionInterface
117+
*/
118+
public function testTwoSegmentCatchAllAppendsTrailingSlash(): void
119+
{
120+
$handler = $this->captureRouteHandler('/{first}/{second}');
121+
$request = $this->createRequestForUri('/some-category/some-slug');
122+
123+
$response = $handler($request);
124+
125+
$this->assertInstanceOf(RedirectResponse::class, $response);
126+
$this->assertSame(301, $response->getStatusCode());
127+
$this->assertSame('/some-category/some-slug/', $response->getHeaderLine('Location'));
128+
}
129+
130+
/**
131+
* @throws Exception
132+
*/
133+
private function createRequestForUri(string $uri): ServerRequestInterface
134+
{
135+
$uriStub = $this->createStub(UriInterface::class);
136+
$uriStub->method('__toString')->willReturn($uri);
137+
138+
$request = $this->createStub(ServerRequestInterface::class);
139+
$request->method('getUri')->willReturn($uriStub);
140+
141+
return $request;
142+
}
143+
144+
/**
145+
* @throws ContainerExceptionInterface
146+
* @throws Exception
147+
* @throws NotFoundExceptionInterface
148+
*/
149+
private function captureRouteHandler(string $routeUri): callable
150+
{
151+
$container = $this->createStub(ContainerInterface::class);
152+
$app = $this->createStub(Application::class);
153+
$captured = null;
154+
155+
$app->method('get')->willReturnCallback(function (...$args) use ($routeUri, &$captured) {
156+
if ($args[0] === $routeUri) {
157+
$captured = $args[1];
158+
}
159+
160+
return $this->createStub(Route::class);
161+
});
162+
163+
(new RoutesDelegator())($container, '', fn () => $app);
164+
165+
$this->assertIsCallable($captured, sprintf('No callable handler was registered for route "%s".', $routeUri));
166+
167+
return $captured;
168+
}
169+
}

0 commit comments

Comments
 (0)