diff --git a/tests/Integration/ModuleDiscoveryTest.php b/tests/Integration/ModuleDiscoveryTest.php new file mode 100644 index 0000000..b34bcab --- /dev/null +++ b/tests/Integration/ModuleDiscoveryTest.php @@ -0,0 +1,110 @@ +tempDir = sys_get_temp_dir() . '/atlas_module_test_' . uniqid(); + mkdir($this->tempDir); + } + + protected function tearDown(): void + { + $this->removeDirectory($this->tempDir); + } + + private function removeDirectory(string $path): void + { + if (!is_dir($path)) return; + $files = array_diff(scandir($path), ['.', '..']); + foreach ($files as $file) { + (is_dir("$path/$file")) ? $this->removeDirectory("$path/$file") : unlink("$path/$file"); + } + rmdir($path); + } + + private function createModule(string $name, string $content): void + { + mkdir($this->tempDir . '/' . $name, 0777, true); + file_put_contents($this->tempDir . '/' . $name . '/routes.php', $content); + } + + public function testModuleDiscoveryWithPrefix(): void + { + $routesContent = ' "GET", "path" => "/index", "handler" => "UserHandler"]];'; + $this->createModule('User', $routesContent); + + $config = new Config(['modules_path' => $this->tempDir]); + $router = new Router($config); + $router->module('User', '/user'); + + $routes = iterator_to_array($router->getRoutes()); + $this->assertCount(1, $routes); + $this->assertSame('/user/index', $routes[0]->getPath()); + $this->assertSame('User', $routes[0]->getModule()); + } + + public function testModuleInheritanceOfMiddlewareAndValidation(): void + { + $routesContent = ' "POST", + "path" => "/save", + "handler" => "SaveHandler", + "middleware" => ["module_mid"], + "validation" => ["id" => "numeric"] + ] + ];'; + $this->createModule('Admin', $routesContent); + + $config = new Config(['modules_path' => $this->tempDir]); + $router = new Router($config); + + // Group at router level + $router->group(['middleware' => ['global_mid']])->module('Admin', '/admin'); + + $routes = iterator_to_array($router->getRoutes()); + $this->assertCount(1, $routes); + $route = $routes[0]; + + $this->assertSame('/admin/save', $route->getPath()); + $this->assertContains('global_mid', $route->getMiddleware()); + $this->assertContains('module_mid', $route->getMiddleware()); + $this->assertArrayHasKey('id', $route->getValidation()); + $this->assertSame('numeric', $route->getValidation()['id'][0]); + $this->assertSame('Admin', $route->getModule()); + } + + public function testOverlappingModuleRoutes(): void + { + // Conflict resolution: first registered wins or both stay? + // Typically, router matches sequentially, so first registered wins. + + $userRoutes = ' "GET", "path" => "/profile", "handler" => "UserHandler"]];'; + $this->createModule('User', $userRoutes); + + $adminRoutes = ' "GET", "path" => "/profile", "handler" => "AdminHandler"]];'; + $this->createModule('Admin', $adminRoutes); + + $config = new Config(['modules_path' => $this->tempDir]); + $router = new Router($config); + + $router->module('User', '/common'); + $router->module('Admin', '/common'); + + $routes = iterator_to_array($router->getRoutes()); + $this->assertCount(2, $routes); + $this->assertSame('/common/profile', $routes[0]->getPath()); + $this->assertSame('UserHandler', $routes[0]->getHandler()); + $this->assertSame('/common/profile', $routes[1]->getPath()); + $this->assertSame('AdminHandler', $routes[1]->getHandler()); + } +}