feat: 添加项目规则、环境配置示例及开发文档
This commit is contained in:
227
tests/test_permissions.py
Normal file
227
tests/test_permissions.py
Normal file
@@ -0,0 +1,227 @@
|
||||
"""权限模块测试"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from minenasai.agent.permissions import (
|
||||
ConfirmationStatus,
|
||||
DangerLevel,
|
||||
PermissionManager,
|
||||
ToolPermission,
|
||||
)
|
||||
|
||||
|
||||
class TestDangerLevel:
|
||||
"""DangerLevel 枚举测试"""
|
||||
|
||||
def test_danger_levels(self):
|
||||
"""测试危险等级"""
|
||||
assert DangerLevel.SAFE.value == "safe"
|
||||
assert DangerLevel.CRITICAL.value == "critical"
|
||||
|
||||
|
||||
class TestToolPermission:
|
||||
"""ToolPermission 测试"""
|
||||
|
||||
def test_default_permission(self):
|
||||
"""测试默认权限"""
|
||||
perm = ToolPermission(
|
||||
name="test_tool",
|
||||
danger_level=DangerLevel.SAFE,
|
||||
)
|
||||
|
||||
assert perm.requires_confirmation is False
|
||||
assert perm.rate_limit is None
|
||||
|
||||
|
||||
class TestPermissionManager:
|
||||
"""PermissionManager 测试"""
|
||||
|
||||
def setup_method(self):
|
||||
"""初始化"""
|
||||
self.manager = PermissionManager()
|
||||
|
||||
def test_get_default_permission(self):
|
||||
"""测试获取默认权限"""
|
||||
perm = self.manager.get_permission("read_file")
|
||||
|
||||
assert perm is not None
|
||||
assert perm.danger_level == DangerLevel.SAFE
|
||||
|
||||
def test_register_tool(self):
|
||||
"""测试注册工具权限"""
|
||||
perm = ToolPermission(
|
||||
name="custom_tool",
|
||||
danger_level=DangerLevel.MEDIUM,
|
||||
description="自定义工具",
|
||||
)
|
||||
self.manager.register_tool(perm)
|
||||
|
||||
result = self.manager.get_permission("custom_tool")
|
||||
assert result is not None
|
||||
assert result.danger_level == DangerLevel.MEDIUM
|
||||
|
||||
def test_check_permission_allowed(self):
|
||||
"""测试权限检查 - 允许"""
|
||||
allowed, reason = self.manager.check_permission("read_file")
|
||||
|
||||
assert allowed is True
|
||||
|
||||
def test_check_permission_unknown_tool(self):
|
||||
"""测试权限检查 - 未知工具"""
|
||||
allowed, reason = self.manager.check_permission("unknown_tool")
|
||||
|
||||
assert allowed is False
|
||||
assert "未知工具" in reason
|
||||
|
||||
def test_check_permission_denied_path(self):
|
||||
"""测试权限检查 - 禁止路径"""
|
||||
perm = ToolPermission(
|
||||
name="restricted_read",
|
||||
danger_level=DangerLevel.SAFE,
|
||||
denied_paths=["/etc/", "/root/"],
|
||||
)
|
||||
self.manager.register_tool(perm)
|
||||
|
||||
allowed, reason = self.manager.check_permission(
|
||||
"restricted_read",
|
||||
params={"path": "/etc/passwd"},
|
||||
)
|
||||
|
||||
assert allowed is False
|
||||
assert "禁止访问" in reason
|
||||
|
||||
def test_requires_confirmation_by_level(self):
|
||||
"""测试确认要求 - 按等级"""
|
||||
# HIGH 级别需要确认
|
||||
assert self.manager.requires_confirmation("delete_file") is True
|
||||
|
||||
# SAFE 级别不需要确认
|
||||
assert self.manager.requires_confirmation("read_file") is False
|
||||
|
||||
def test_requires_confirmation_explicit(self):
|
||||
"""测试确认要求 - 显式设置"""
|
||||
perm = ToolPermission(
|
||||
name="explicit_confirm",
|
||||
danger_level=DangerLevel.LOW,
|
||||
requires_confirmation=True,
|
||||
)
|
||||
self.manager.register_tool(perm)
|
||||
|
||||
assert self.manager.requires_confirmation("explicit_confirm") is True
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_confirmation_flow(self):
|
||||
"""测试确认流程"""
|
||||
request = await self.manager.request_confirmation(
|
||||
request_id="req-1",
|
||||
tool_name="delete_file",
|
||||
params={"path": "/test.txt"},
|
||||
)
|
||||
|
||||
assert request.status == ConfirmationStatus.PENDING
|
||||
|
||||
# 批准
|
||||
self.manager.approve_confirmation("req-1")
|
||||
assert request.status == ConfirmationStatus.APPROVED
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_confirmation_deny(self):
|
||||
"""测试拒绝确认"""
|
||||
request = await self.manager.request_confirmation(
|
||||
request_id="req-2",
|
||||
tool_name="delete_file",
|
||||
params={"path": "/test.txt"},
|
||||
)
|
||||
|
||||
self.manager.deny_confirmation("req-2")
|
||||
assert request.status == ConfirmationStatus.DENIED
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_pending_confirmations(self):
|
||||
"""测试获取待处理确认"""
|
||||
await self.manager.request_confirmation(
|
||||
request_id="req-3",
|
||||
tool_name="test",
|
||||
params={},
|
||||
)
|
||||
|
||||
pending = self.manager.get_pending_confirmations()
|
||||
assert len(pending) >= 1
|
||||
|
||||
|
||||
class TestToolRegistry:
|
||||
"""ToolRegistry 测试"""
|
||||
|
||||
def test_import_registry(self):
|
||||
"""测试导入注册中心"""
|
||||
from minenasai.agent import ToolRegistry, get_tool_registry
|
||||
|
||||
registry = get_tool_registry()
|
||||
assert isinstance(registry, ToolRegistry)
|
||||
|
||||
def test_register_builtin_tools(self):
|
||||
"""测试注册内置工具"""
|
||||
from minenasai.agent import get_tool_registry, register_builtin_tools
|
||||
|
||||
registry = get_tool_registry()
|
||||
initial_count = len(registry.list_tools())
|
||||
|
||||
register_builtin_tools()
|
||||
|
||||
# 应该有更多工具
|
||||
new_count = len(registry.list_tools())
|
||||
assert new_count >= initial_count
|
||||
|
||||
def test_tool_decorator(self):
|
||||
"""测试工具装饰器"""
|
||||
from minenasai.agent import tool, get_tool_registry
|
||||
|
||||
@tool(name="decorated_tool", description="装饰器测试")
|
||||
async def decorated_tool(param: str) -> dict:
|
||||
return {"result": param}
|
||||
|
||||
registry = get_tool_registry()
|
||||
tool_obj = registry.get("decorated_tool")
|
||||
|
||||
assert tool_obj is not None
|
||||
assert tool_obj.description == "装饰器测试"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_execute_tool(self):
|
||||
"""测试执行工具"""
|
||||
from minenasai.agent import get_tool_registry, DangerLevel
|
||||
|
||||
registry = get_tool_registry()
|
||||
|
||||
# 注册测试工具
|
||||
async def echo(message: str) -> dict:
|
||||
return {"echo": message}
|
||||
|
||||
registry.register(
|
||||
name="echo",
|
||||
description="回显消息",
|
||||
func=echo,
|
||||
parameters={
|
||||
"type": "object",
|
||||
"properties": {"message": {"type": "string"}},
|
||||
"required": ["message"],
|
||||
},
|
||||
danger_level=DangerLevel.SAFE,
|
||||
)
|
||||
|
||||
result = await registry.execute("echo", {"message": "hello"})
|
||||
|
||||
assert result["success"] is True
|
||||
assert result["result"]["echo"] == "hello"
|
||||
|
||||
def test_get_stats(self):
|
||||
"""测试获取统计"""
|
||||
from minenasai.agent import get_tool_registry
|
||||
|
||||
registry = get_tool_registry()
|
||||
stats = registry.get_stats()
|
||||
|
||||
assert "total_tools" in stats
|
||||
assert "categories" in stats
|
||||
Reference in New Issue
Block a user