from __future__ import annotations import pytest from iti.applications import create_app from iti.applications.common.enums import MenuTypeEnum from iti.applications.extensions import db from iti.applications.models import Role, SysMenu from iti.modules import ModuleMenuSeed, ModulePermission, get_module_registry from iti.modules.registry import ModuleRegistry from iti.seeds.system import seed_system_data class RecordingModule: name = "recording" def __init__(self) -> None: self.calls: list[str] = [] def init_app(self, app) -> None: self.calls.append("init_app") def register_commands(self, app) -> None: self.calls.append("register_commands") def register_routes(self, app) -> None: self.calls.append("register_routes") def register_permissions(self, app) -> None: self.calls.append("register_permissions") get_module_registry(app).register_permission( ModulePermission(code="recording:list", name="录制列表") ) def register_menu_seed(self, app) -> None: self.calls.append("register_menu_seed") get_module_registry(app).register_menu_seed( ModuleMenuSeed( id="recording-menu", name="Recording", type=MenuTypeEnum.MENU.value, path="/recording", component="/recording/list", auth_code="recording:list", meta={"title": "录制模块"}, sort=200, ) ) def test_module_registry_rejects_duplicate_names(): registry = ModuleRegistry() registry.register(RecordingModule()) with pytest.raises(ValueError, match="module already registered"): registry.register(RecordingModule()) def test_create_app_runs_module_phases_and_collects_metadata(): module = RecordingModule() imported: list[str] = [] app = create_app( "test", modules=[module], config_mapping={"test": "iti.config.TestConfig"}, model_imports=[lambda: imported.append("models")], ) registry = get_module_registry(app) assert module.calls == [ "init_app", "register_commands", "register_routes", "register_permissions", "register_menu_seed", ] assert imported == ["models"] assert registry.list_permissions()[0].code == "recording:list" assert registry.list_menu_seeds()[0].id == "recording-menu" def test_module_menu_seed_is_written_by_system_seed(): module = RecordingModule() app = create_app("test", modules=[module]) with app.app_context(): db.create_all() summary = seed_system_data(get_module_registry(app)) menu = db.session.get(SysMenu, "recording-menu") role = db.session.scalar(db.select(Role).filter_by(code="ADMIN")) assert summary["module_menus"]["created"] == 1 assert summary["module_role_menus"]["created"] == 1 assert menu is not None assert menu.auth_code == "recording:list" assert role is not None assert "recording-menu" in {item.id for item in role.menus} db.session.remove() db.drop_all()