81 lines
2.8 KiB
PHP
81 lines
2.8 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace MintyPHP\Tests\Support\Helpers;
|
||
|
|
|
||
|
|
use MintyPHP\App\AppContainer;
|
||
|
|
use MintyPHP\App\Module\ModuleRegistry;
|
||
|
|
use MintyPHP\Tests\Support\AppContainerIsolationTrait;
|
||
|
|
use PHPUnit\Framework\TestCase;
|
||
|
|
|
||
|
|
class EndpointUrlTest extends TestCase
|
||
|
|
{
|
||
|
|
use AppContainerIsolationTrait;
|
||
|
|
|
||
|
|
protected function tearDown(): void
|
||
|
|
{
|
||
|
|
$this->restoreAppContainer();
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testResolvesSourcePathToTarget(): void
|
||
|
|
{
|
||
|
|
$this->installRegistryWithRoutes([
|
||
|
|
['path' => 'admin/system-audit/export', 'target' => 'audit/system-audit/export', 'module_id' => 'audit'],
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertStringEndsWith('audit/system-audit/export', endpointUrl('admin/system-audit/export'));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testIdempotentWhenPathEqualsTarget(): void
|
||
|
|
{
|
||
|
|
$this->installRegistryWithRoutes([
|
||
|
|
['path' => 'helpdesk/domains/export', 'target' => 'helpdesk/domains/export', 'module_id' => 'helpdesk'],
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertStringEndsWith('helpdesk/domains/export', endpointUrl('helpdesk/domains/export'));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testFallsThroughToLurlForUnregisteredPath(): void
|
||
|
|
{
|
||
|
|
$this->installRegistryWithRoutes([]);
|
||
|
|
|
||
|
|
$this->assertSame(lurl('admin/users/export'), endpointUrl('admin/users/export'));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testIgnoresLeadingSlash(): void
|
||
|
|
{
|
||
|
|
$this->installRegistryWithRoutes([
|
||
|
|
['path' => 'admin/system-audit/export', 'target' => 'audit/system-audit/export', 'module_id' => 'audit'],
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertSame(
|
||
|
|
endpointUrl('admin/system-audit/export'),
|
||
|
|
endpointUrl('/admin/system-audit/export')
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testDegradesGracefullyWhenRegistryMissing(): void
|
||
|
|
{
|
||
|
|
$this->pushAppContainer(new AppContainer());
|
||
|
|
|
||
|
|
// No ModuleRegistry registered — endpointUrl() must fall back, not throw.
|
||
|
|
$this->assertSame(lurl('some/path'), endpointUrl('some/path'));
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param list<array{path: string, target: string, module_id?: string}> $routes
|
||
|
|
*/
|
||
|
|
private function installRegistryWithRoutes(array $routes): void
|
||
|
|
{
|
||
|
|
// ModuleRegistry is final and has no public constructor — build via
|
||
|
|
// reflection and write the merged-routes field directly. Only used
|
||
|
|
// by endpointUrl() via getRoutes(), so that is all we need to stage.
|
||
|
|
$registry = (new \ReflectionClass(ModuleRegistry::class))->newInstanceWithoutConstructor();
|
||
|
|
$routesProp = (new \ReflectionClass(ModuleRegistry::class))->getProperty('mergedRoutes');
|
||
|
|
$routesProp->setValue($registry, $routes);
|
||
|
|
|
||
|
|
$container = new AppContainer();
|
||
|
|
$container->set(ModuleRegistry::class, static fn (): ModuleRegistry => $registry);
|
||
|
|
$this->pushAppContainer($container);
|
||
|
|
}
|
||
|
|
}
|