Files
Edu/services/ai/tests/test_permission.py
2026-07-10 18:57:39 +08:00

76 lines
3.0 KiB
Python

"""权限校验守卫测试."""
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"