"""Tests for router loader.""" import sys from pathlib import Path import pytest from fastapi import APIRouter from fastapi_route_loader.loader import RouterLoader class TestRouterLoader: """Test router loader functionality.""" def test_is_router_with_api_router(self): router = APIRouter() assert RouterLoader._is_router(router) is True def test_is_router_with_non_router(self): assert RouterLoader._is_router("not a router") is False assert RouterLoader._is_router(123) is False assert RouterLoader._is_router(None) is False def test_get_module_path_without_package(self): base_path = Path("/app/routers") file_path = Path("/app/routers/users/api.py") module_path = RouterLoader._get_module_path(file_path, base_path, None) assert module_path == "users.api" def test_get_module_path_with_package(self): base_path = Path("/app/routers") file_path = Path("/app/routers/users/api.py") module_path = RouterLoader._get_module_path(file_path, base_path, "myapp") assert module_path == "myapp.users.api" def test_get_module_path_single_file(self): base_path = Path("/app/routers") file_path = Path("/app/routers/api.py") module_path = RouterLoader._get_module_path(file_path, base_path, None) assert module_path == "api" def test_load_from_module_success(self, tmp_path): module_content = ''' from fastapi import APIRouter router = APIRouter() other_router = APIRouter() not_a_router = "test" ''' module_file = tmp_path / "test_module.py" module_file.write_text(module_content) sys.path.insert(0, str(tmp_path)) try: routers = RouterLoader.load_from_module("test_module") assert "router" in routers assert "other_router" in routers assert "not_a_router" not in routers assert isinstance(routers["router"], APIRouter) finally: sys.path.remove(str(tmp_path)) if "test_module" in sys.modules: del sys.modules["test_module"] def test_load_from_module_import_error(self): with pytest.raises(ImportError, match="Failed to import module"): RouterLoader.load_from_module("nonexistent_module_xyz") def test_load_from_directory_success(self, tmp_path): routers_dir = tmp_path / "routers" routers_dir.mkdir() (routers_dir / "__init__.py").write_text("") (routers_dir / "users.py").write_text( "from fastapi import APIRouter\nuser_router = APIRouter()" ) (routers_dir / "posts.py").write_text( "from fastapi import APIRouter\npost_router = APIRouter()" ) (routers_dir / "_private.py").write_text( "from fastapi import APIRouter\nprivate_router = APIRouter()" ) sys.path.insert(0, str(tmp_path)) try: routers = RouterLoader.load_from_directory(routers_dir, "routers") assert "users.user_router" in routers assert "posts.post_router" in routers assert "private.private_router" not in routers finally: sys.path.remove(str(tmp_path)) for mod in list(sys.modules.keys()): if mod.startswith("routers"): del sys.modules[mod] def test_load_from_directory_not_found(self): with pytest.raises(FileNotFoundError, match="Directory not found"): RouterLoader.load_from_directory("/nonexistent/path") def test_load_from_directory_not_a_directory(self, tmp_path): file_path = tmp_path / "not_a_dir.txt" file_path.write_text("test") with pytest.raises(NotADirectoryError, match="Not a directory"): RouterLoader.load_from_directory(file_path) def test_load_from_directory_nested_structure(self, tmp_path): routers_dir = tmp_path / "routers" routers_dir.mkdir() api_dir = routers_dir / "api" api_dir.mkdir() v1_dir = api_dir / "v1" v1_dir.mkdir() (routers_dir / "__init__.py").write_text("") (api_dir / "__init__.py").write_text("") (v1_dir / "__init__.py").write_text("") (v1_dir / "users.py").write_text( "from fastapi import APIRouter\nusers_router = APIRouter()" ) sys.path.insert(0, str(tmp_path)) try: routers = RouterLoader.load_from_directory(routers_dir, "routers") assert "users.users_router" in routers finally: sys.path.remove(str(tmp_path)) for mod in list(sys.modules.keys()): if mod.startswith("routers"): del sys.modules[mod] def test_load_from_directory_with_import_errors(self, tmp_path): routers_dir = tmp_path / "routers" routers_dir.mkdir() (routers_dir / "__init__.py").write_text("") (routers_dir / "good.py").write_text( "from fastapi import APIRouter\ngood_router = APIRouter()" ) (routers_dir / "bad.py").write_text( "import nonexistent_module\nfrom fastapi import APIRouter\nbad_router = APIRouter()" ) sys.path.insert(0, str(tmp_path)) try: routers = RouterLoader.load_from_directory(routers_dir, "routers") assert "good.good_router" in routers assert "bad.bad_router" not in routers finally: sys.path.remove(str(tmp_path)) for mod in list(sys.modules.keys()): if mod.startswith("routers"): del sys.modules[mod] def test_load_from_directory_empty(self, tmp_path): routers_dir = tmp_path / "empty_routers" routers_dir.mkdir() routers = RouterLoader.load_from_directory(routers_dir) assert routers == {}