"""权限模板服务单元测试""" from __future__ import annotations import uuid import pytest from app.models.permission_template import PermissionTemplate, TemplateType from app.schemas.permission_template import PermissionTemplateCreate, PermissionTemplateUpdate from app.services.permission_template_service import PermissionTemplateService SAMPLE_PERMISSIONS = { "PM": { "subjects:create": True, "subjects:read": True, "subjects:update": True, "subjects:delete": False, }, "CRA": { "subjects:create": False, "subjects:read": True, "subjects:update": False, "subjects:delete": False, }, } @pytest.fixture def user_id() -> uuid.UUID: return uuid.uuid4() # --------------------------------------------------------------------------- # 创建模板 # --------------------------------------------------------------------------- @pytest.mark.asyncio async def test_create_template_success(db_session, user_id): payload = PermissionTemplateCreate( name="测试模板", description="用于测试", template_type=TemplateType.CUSTOM, permissions=SAMPLE_PERMISSIONS, ) template = await PermissionTemplateService.create_template(db_session, payload, user_id) assert template.id is not None assert template.name == "测试模板" assert template.is_system is False assert template.template_type == TemplateType.CUSTOM assert template.permissions == SAMPLE_PERMISSIONS @pytest.mark.asyncio async def test_create_template_creates_version_1(db_session, user_id): payload = PermissionTemplateCreate( name="版本测试", template_type=TemplateType.CUSTOM, permissions=SAMPLE_PERMISSIONS, ) template = await PermissionTemplateService.create_template(db_session, payload, user_id) await db_session.refresh(template, ["versions"]) assert len(template.versions) == 1 assert template.versions[0].version == 1 assert template.versions[0].change_log == "初始版本" @pytest.mark.asyncio async def test_create_template_invalid_endpoint_key(db_session, user_id): payload = PermissionTemplateCreate( name="无效模板", template_type=TemplateType.CUSTOM, permissions={"PM": {"nonexistent:action": True}}, ) with pytest.raises(ValueError, match="权限操作 nonexistent:action 不存在"): await PermissionTemplateService.create_template(db_session, payload, user_id) @pytest.mark.asyncio async def test_create_template_invalid_permission_value(db_session, user_id): payload = PermissionTemplateCreate( name="无效值模板", template_type=TemplateType.CUSTOM, permissions={"PM": {"subjects:read": "yes"}}, # type: ignore ) with pytest.raises(ValueError, match="必须是布尔类型"): await PermissionTemplateService.create_template(db_session, payload, user_id) # --------------------------------------------------------------------------- # 获取模板 # --------------------------------------------------------------------------- @pytest.mark.asyncio async def test_get_template_exists(db_session, user_id): payload = PermissionTemplateCreate( name="获取测试", template_type=TemplateType.ROLE, permissions=SAMPLE_PERMISSIONS, ) created = await PermissionTemplateService.create_template(db_session, payload, user_id) fetched = await PermissionTemplateService.get_template(db_session, created.id) assert fetched is not None assert fetched.id == created.id assert fetched.name == "获取测试" @pytest.mark.asyncio async def test_get_template_not_found(db_session): result = await PermissionTemplateService.get_template(db_session, uuid.uuid4()) assert result is None # --------------------------------------------------------------------------- # 列表模板 # --------------------------------------------------------------------------- @pytest.mark.asyncio async def test_list_templates_filter_by_type(db_session, user_id): await PermissionTemplateService.create_template( db_session, PermissionTemplateCreate(name="角色模板", template_type=TemplateType.ROLE, permissions=SAMPLE_PERMISSIONS), user_id, ) await PermissionTemplateService.create_template( db_session, PermissionTemplateCreate(name="场景模板", template_type=TemplateType.SCENARIO, permissions=SAMPLE_PERMISSIONS), user_id, ) role_templates = await PermissionTemplateService.list_templates(db_session, template_type=TemplateType.ROLE) assert all(t.template_type == TemplateType.ROLE for t in role_templates) assert len(role_templates) >= 1 # --------------------------------------------------------------------------- # 更新模板 # --------------------------------------------------------------------------- @pytest.mark.asyncio async def test_update_template_name(db_session, user_id): created = await PermissionTemplateService.create_template( db_session, PermissionTemplateCreate(name="旧名称", template_type=TemplateType.CUSTOM, permissions=SAMPLE_PERMISSIONS), user_id, ) updated = await PermissionTemplateService.update_template( db_session, created.id, PermissionTemplateUpdate(name="新名称") ) assert updated.name == "新名称" @pytest.mark.asyncio async def test_update_template_permissions_creates_new_version(db_session, user_id): created = await PermissionTemplateService.create_template( db_session, PermissionTemplateCreate(name="版本测试2", template_type=TemplateType.CUSTOM, permissions=SAMPLE_PERMISSIONS), user_id, ) new_perms = {"PM": {"subjects:read": True}} await PermissionTemplateService.update_template( db_session, created.id, PermissionTemplateUpdate(permissions=new_perms) ) updated = await PermissionTemplateService.get_template(db_session, created.id) await db_session.refresh(updated, ["versions"]) assert len(updated.versions) == 2 assert updated.versions[-1].version == 2 assert updated.permissions == new_perms @pytest.mark.asyncio async def test_update_system_template_raises(db_session): system_template = PermissionTemplate( name="系统模板", template_type=TemplateType.ROLE, is_system=True, permissions=SAMPLE_PERMISSIONS, ) db_session.add(system_template) await db_session.commit() await db_session.refresh(system_template) with pytest.raises(ValueError, match="不允许修改系统预设模板"): await PermissionTemplateService.update_template( db_session, system_template.id, PermissionTemplateUpdate(name="改名") ) # --------------------------------------------------------------------------- # 删除模板 # --------------------------------------------------------------------------- @pytest.mark.asyncio async def test_delete_template_success(db_session, user_id): created = await PermissionTemplateService.create_template( db_session, PermissionTemplateCreate(name="待删除", template_type=TemplateType.CUSTOM, permissions=SAMPLE_PERMISSIONS), user_id, ) await PermissionTemplateService.delete_template(db_session, created.id) assert await PermissionTemplateService.get_template(db_session, created.id) is None @pytest.mark.asyncio async def test_delete_system_template_raises(db_session): system_template = PermissionTemplate( name="系统模板2", template_type=TemplateType.ROLE, is_system=True, permissions=SAMPLE_PERMISSIONS, ) db_session.add(system_template) await db_session.commit() await db_session.refresh(system_template) with pytest.raises(ValueError, match="不允许删除系统预设模板"): await PermissionTemplateService.delete_template(db_session, system_template.id) @pytest.mark.asyncio async def test_delete_nonexistent_template_raises(db_session): with pytest.raises(ValueError, match="不存在"): await PermissionTemplateService.delete_template(db_session, uuid.uuid4())