76 lines
3.0 KiB
Python
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"
|