2026-02-13 21:54:36 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Atlas\Tests\Unit;
|
|
|
|
|
|
2026-02-14 23:27:20 +00:00
|
|
|
use Atlas\Exception\RouteNotFoundException;
|
|
|
|
|
use Atlas\Router\RouteDefinition;
|
2026-02-13 23:26:31 +00:00
|
|
|
use Atlas\Router\Router;
|
2026-02-14 23:27:20 +00:00
|
|
|
use Atlas\Config\Config;
|
2026-02-13 21:54:36 +00:00
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
|
use Psr\Http\Message\ServerRequestInterface;
|
|
|
|
|
use Psr\Http\Message\UriInterface;
|
|
|
|
|
|
|
|
|
|
final class ErrorHandlingTest extends TestCase
|
|
|
|
|
{
|
|
|
|
|
public function testMatchOrFailThrowsExceptionWhenNoRouteFound(): void
|
|
|
|
|
{
|
2026-02-14 23:27:20 +00:00
|
|
|
$config = new Config([
|
2026-02-13 21:54:36 +00:00
|
|
|
'modules_path' => ['/path/to/modules']
|
|
|
|
|
]);
|
|
|
|
|
|
2026-02-14 23:27:20 +00:00
|
|
|
$router = new Router($config);
|
2026-02-13 21:54:36 +00:00
|
|
|
|
|
|
|
|
$uri = $this->createMock(UriInterface::class);
|
|
|
|
|
$uri->method('getPath')->willReturn('/nonexistent');
|
|
|
|
|
$uri->method('getScheme')->willReturn('http');
|
|
|
|
|
$uri->method('getHost')->willReturn('localhost');
|
|
|
|
|
$uri->method('getPort')->willReturn(80);
|
|
|
|
|
|
|
|
|
|
$request = $this->createMock(ServerRequestInterface::class);
|
|
|
|
|
$request->method('getMethod')->willReturn('GET');
|
|
|
|
|
$request->method('getUri')->willReturn($uri);
|
|
|
|
|
|
2026-02-14 23:27:20 +00:00
|
|
|
$this->expectException(RouteNotFoundException::class);
|
2026-02-13 21:54:36 +00:00
|
|
|
|
|
|
|
|
$router->matchOrFail($request);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testMatchReturnsNullWhenNoRouteFound(): void
|
|
|
|
|
{
|
2026-02-14 23:27:20 +00:00
|
|
|
$config = new Config([
|
2026-02-13 21:54:36 +00:00
|
|
|
'modules_path' => ['/path/to/modules']
|
|
|
|
|
]);
|
|
|
|
|
|
2026-02-14 23:27:20 +00:00
|
|
|
$router = new Router($config);
|
2026-02-13 21:54:36 +00:00
|
|
|
|
|
|
|
|
$uri = $this->createMock(UriInterface::class);
|
|
|
|
|
$uri->method('getPath')->willReturn('/nonexistent');
|
|
|
|
|
$uri->method('getScheme')->willReturn('http');
|
|
|
|
|
$uri->method('getHost')->willReturn('localhost');
|
|
|
|
|
$uri->method('getPort')->willReturn(80);
|
|
|
|
|
|
|
|
|
|
$request = $this->createMock(ServerRequestInterface::class);
|
|
|
|
|
$request->method('getMethod')->willReturn('GET');
|
|
|
|
|
$request->method('getUri')->willReturn($uri);
|
|
|
|
|
|
|
|
|
|
$result = $router->match($request);
|
|
|
|
|
|
|
|
|
|
$this->assertNull($result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testRouteChainingWithDifferentHttpMethods(): void
|
|
|
|
|
{
|
2026-02-14 23:27:20 +00:00
|
|
|
$config = new Config([
|
2026-02-13 21:54:36 +00:00
|
|
|
'modules_path' => ['/path/to/modules']
|
|
|
|
|
]);
|
|
|
|
|
|
2026-02-14 23:27:20 +00:00
|
|
|
$router = new Router($config);
|
|
|
|
|
$router->get('/test', 'GetHandler');
|
|
|
|
|
$router->post('/test', 'PostHandler');
|
2026-02-13 21:54:36 +00:00
|
|
|
|
2026-02-14 23:27:20 +00:00
|
|
|
$this->assertCount(2, $router->getRoutes());
|
2026-02-13 21:54:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testMatchUsingRouteDefinition(): void
|
|
|
|
|
{
|
2026-02-14 23:27:20 +00:00
|
|
|
$config = new Config([
|
2026-02-13 21:54:36 +00:00
|
|
|
'modules_path' => ['/path/to/modules']
|
|
|
|
|
]);
|
|
|
|
|
|
2026-02-14 23:27:20 +00:00
|
|
|
$router = new Router($config);
|
2026-02-13 21:54:36 +00:00
|
|
|
|
|
|
|
|
$router->get('/test', 'TestMethod');
|
|
|
|
|
|
2026-02-14 23:27:20 +00:00
|
|
|
$routes = iterator_to_array($router->getRoutes());
|
2026-02-13 21:54:36 +00:00
|
|
|
$this->assertCount(1, $routes);
|
2026-02-14 23:27:20 +00:00
|
|
|
$this->assertInstanceOf(RouteDefinition::class, $routes[0]);
|
2026-02-13 21:54:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testCaseInsensitiveHttpMethodMatching(): void
|
|
|
|
|
{
|
2026-02-14 23:27:20 +00:00
|
|
|
$config = new Config([
|
2026-02-13 21:54:36 +00:00
|
|
|
'modules_path' => ['/path/to/modules']
|
|
|
|
|
]);
|
|
|
|
|
|
2026-02-14 23:27:20 +00:00
|
|
|
$router = new Router($config);
|
2026-02-13 21:54:36 +00:00
|
|
|
|
|
|
|
|
$router->get('/test', 'TestHandler');
|
|
|
|
|
|
|
|
|
|
$uri = $this->createMock(UriInterface::class);
|
|
|
|
|
$uri->method('getPath')->willReturn('/test');
|
|
|
|
|
$uri->method('getScheme')->willReturn('http');
|
|
|
|
|
$uri->method('getHost')->willReturn('localhost');
|
|
|
|
|
$uri->method('getPort')->willReturn(80);
|
|
|
|
|
|
|
|
|
|
$request = $this->createMock(ServerRequestInterface::class);
|
|
|
|
|
$request->method('getMethod')->willReturn('GET');
|
|
|
|
|
$request->method('getUri')->willReturn($uri);
|
|
|
|
|
|
|
|
|
|
$matchedRoute = $router->match($request);
|
|
|
|
|
|
|
|
|
|
$this->assertNotNull($matchedRoute);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testPathNormalizationLeadingSlashes(): void
|
|
|
|
|
{
|
2026-02-14 23:27:20 +00:00
|
|
|
$config = new Config([
|
2026-02-13 21:54:36 +00:00
|
|
|
'modules_path' => ['/path/to/modules']
|
|
|
|
|
]);
|
|
|
|
|
|
2026-02-14 23:27:20 +00:00
|
|
|
$router = new Router($config);
|
2026-02-13 21:54:36 +00:00
|
|
|
|
|
|
|
|
$router->get('/test', 'TestHandler');
|
|
|
|
|
|
|
|
|
|
$uri = $this->createMock(UriInterface::class);
|
|
|
|
|
$uri->method('getPath')->willReturn('/test');
|
|
|
|
|
$uri->method('getScheme')->willReturn('http');
|
|
|
|
|
$uri->method('getHost')->willReturn('localhost');
|
|
|
|
|
$uri->method('getPort')->willReturn(80);
|
|
|
|
|
|
|
|
|
|
$request = $this->createMock(ServerRequestInterface::class);
|
|
|
|
|
$request->method('getMethod')->willReturn('GET');
|
|
|
|
|
$request->method('getUri')->willReturn($uri);
|
|
|
|
|
|
|
|
|
|
$matchedRoute = $router->match($request);
|
|
|
|
|
|
|
|
|
|
$this->assertNotNull($matchedRoute);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testMatchOrFailThrowsExceptionForMultipleRoutes(): void
|
|
|
|
|
{
|
2026-02-14 23:27:20 +00:00
|
|
|
$config = new Config([
|
2026-02-13 21:54:36 +00:00
|
|
|
'modules_path' => ['/path/to/modules']
|
|
|
|
|
]);
|
|
|
|
|
|
2026-02-14 23:27:20 +00:00
|
|
|
$router = new Router($config);
|
2026-02-13 21:54:36 +00:00
|
|
|
|
|
|
|
|
$router->get('/test', 'TestHandler');
|
|
|
|
|
|
|
|
|
|
$uri = $this->createMock(UriInterface::class);
|
|
|
|
|
$uri->method('getPath')->willReturn('/test');
|
|
|
|
|
$uri->method('getScheme')->willReturn('http');
|
|
|
|
|
$uri->method('getHost')->willReturn('localhost');
|
|
|
|
|
$uri->method('getPort')->willReturn(80);
|
|
|
|
|
|
|
|
|
|
$request = $this->createMock(ServerRequestInterface::class);
|
|
|
|
|
$request->method('getMethod')->willReturn('GET');
|
|
|
|
|
$request->method('getUri')->willReturn($uri);
|
|
|
|
|
|
|
|
|
|
$matchedRoute = $router->matchOrFail($request);
|
|
|
|
|
|
2026-02-14 23:27:20 +00:00
|
|
|
$this->assertInstanceOf(RouteDefinition::class, $matchedRoute);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testModuleThrowsExceptionWhenModulesPathIsMissing(): void
|
|
|
|
|
{
|
|
|
|
|
$config = new Config([]);
|
|
|
|
|
$router = new Router($config);
|
|
|
|
|
|
|
|
|
|
$this->expectException(\Atlas\Exception\MissingConfigurationException::class);
|
|
|
|
|
$router->module('User');
|
2026-02-13 21:54:36 +00:00
|
|
|
}
|
|
|
|
|
}
|