"""权限校验守卫测试.""" import pytest from src.ai.errors import AIError, ErrorCode from src.ai.middleware.auth import UserContext from src.ai.middleware.permission import ( PERMISSION_AI_CHAT, PERMISSION_AI_LESSON_CONFIRM, PERMISSION_AI_LESSON_GENERATE, PERMISSION_AI_QUESTION_GENERATE, PermissionGuard, ) class TestPermissionGuard: """PermissionGuard 测试.""" def test_dev_mode_skips_check(self) -> None: """dev_mode=true 跳过校验.""" guard = PermissionGuard(dev_mode=True) ctx = UserContext() # 未认证 # 不抛异常即通过 guard.check(ctx, PERMISSION_AI_CHAT) def test_unauthenticated_raises(self) -> None: """未认证用户抛 AI_UNAUTHORIZED.""" guard = PermissionGuard(dev_mode=False) ctx = UserContext() with pytest.raises(AIError) as exc_info: guard.check(ctx, PERMISSION_AI_CHAT) assert exc_info.value.code == ErrorCode.AI_UNAUTHORIZED def test_teacher_has_all_permissions(self) -> None: """teacher 角色拥有全部权限.""" guard = PermissionGuard(dev_mode=False) ctx = UserContext(user_id="u-1", role="teacher") guard.check(ctx, PERMISSION_AI_CHAT) guard.check(ctx, PERMISSION_AI_QUESTION_GENERATE) guard.check(ctx, PERMISSION_AI_LESSON_GENERATE) guard.check(ctx, PERMISSION_AI_LESSON_CONFIRM) def test_student_only_chat(self) -> None: """student 角色仅有 chat 权限.""" guard = PermissionGuard(dev_mode=False) ctx = UserContext(user_id="u-1", role="student") guard.check(ctx, PERMISSION_AI_CHAT) with pytest.raises(AIError) as exc_info: guard.check(ctx, PERMISSION_AI_QUESTION_GENERATE) assert exc_info.value.code == ErrorCode.AI_FORBIDDEN def test_unknown_role_defaults_student(self) -> None: """未知角色降级为 student 权限.""" guard = PermissionGuard(dev_mode=False) ctx = UserContext(user_id="u-1", role="guest") guard.check(ctx, PERMISSION_AI_CHAT) with pytest.raises(AIError): guard.check(ctx, PERMISSION_AI_LESSON_GENERATE) def test_empty_role_defaults_student(self) -> None: """空角色降级为 student.""" guard = PermissionGuard(dev_mode=False) ctx = UserContext(user_id="u-1", role="") guard.check(ctx, PERMISSION_AI_CHAT) with pytest.raises(AIError): guard.check(ctx, PERMISSION_AI_QUESTION_GENERATE) def test_forbidden_includes_details(self) -> None: """权限拒绝 details 含 required_permission + role.""" guard = PermissionGuard(dev_mode=False) ctx = UserContext(user_id="u-1", role="student") with pytest.raises(AIError) as exc_info: guard.check(ctx, PERMISSION_AI_LESSON_CONFIRM) assert exc_info.value.details["required_permission"] == PERMISSION_AI_LESSON_CONFIRM assert exc_info.value.details["role"] == "student"