ForcePilot/backend/test/unit/channels/contract/dtos/test_session.py
Kris 002e6a356b chore: 批量整理代码变更,修复多类细节问题
1.  清理测试文件中未使用的导入与冗余代码
2.  修复审计日志与批量操作的空值约束,统一填充"global"作为默认渠道
3.  调整批量消息撤回的响应语义,对齐其他端点的部分成功契约
4.  修复访问规则批量克隆的唯一约束问题,新增后缀自动处理逻辑
5.  替换anyio为asyncio并行调用,修正时间UTC导入路径
6.  优化前端外部系统概览页的刷新状态提示与缓存逻辑
7.  修复测试用例中的断言与请求方式问题,适配httpx删除请求特性
8.  重构后端路由的依赖注入,移除冗余的数据库会话依赖
9.  调整测试用例的权限校验逻辑,修正强制登出的权限判断
10. 修复语义分块测试的numpy依赖问题,清理冗余导入
2026-07-13 20:48:29 +08:00

204 lines
5.5 KiB
Python

"""session.py DTO 单元测试。
覆盖 ``ChannelSessionId`` / ``PeerId`` / ``ChatType`` / ``SessionOwner`` /
``OwnerTransferCmd`` / ``TemporarySessionPattern`` / ``CloseSessionCmd`` /
``SessionMessageItem`` / ``SessionStatsResult`` / ``BatchCloseSessionsCmd`` /
``BatchCloseResult`` 的字段赋值、默认值、不可变语义与 ``__post_init__``
校验逻辑。
"""
from __future__ import annotations
from datetime import datetime
import pytest
from yuxi.channels.contract.dtos.common import Operator, OperatorRole
from yuxi.channels.contract.dtos.session import (
BatchCloseSessionsCmd,
ChannelSessionId,
ChatType,
CloseSessionCmd,
OwnerTransferCmd,
PeerId,
SessionOwner,
SessionStatsResult,
)
from yuxi.channels.contract.errors import ValidationError
pytestmark = pytest.mark.unit
def _make_operator() -> Operator:
return Operator(user_id="admin-1", role=OperatorRole.ADMIN_USER)
@pytest.mark.unit
class TestChannelSessionId:
"""渠道会话 ID DTO 测试。"""
def test_value_is_assigned(self):
# Act
sid = ChannelSessionId(value="session-001")
# Assert
assert sid.value == "session-001"
@pytest.mark.unit
class TestPeerId:
"""对端 ID DTO 测试。"""
def test_value_is_assigned(self):
# Act
pid = PeerId(value="peer-001")
# Assert
assert pid.value == "peer-001"
@pytest.mark.unit
class TestChatType:
"""会话类型枚举测试。"""
def test_str_values(self):
assert ChatType.P2P == "p2p"
assert ChatType.GROUP == "group"
assert ChatType.KF == "kf"
@pytest.mark.unit
class TestSessionOwner:
"""会话所有者 DTO 测试。"""
def test_fields_are_assigned(self):
# Act
owner = SessionOwner(
conversation_id="conv-1",
owner_peer_id="peer-1",
created_at=datetime(2024, 1, 1),
)
# Assert
assert owner.owner_peer_id == "peer-1"
@pytest.mark.unit
class TestOwnerTransferCmd:
"""所有者转移命令 DTO 测试。"""
def test_valid_construction(self):
# Act
cmd = OwnerTransferCmd(
session_id="sess-1",
new_owner_id="peer-2",
operator=_make_operator(),
)
# Assert
assert cmd.new_owner_id == "peer-2"
def test_empty_session_id_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
OwnerTransferCmd(
session_id="",
new_owner_id="peer-2",
operator=_make_operator(),
)
assert exc_info.value.field == "session_id"
def test_empty_new_owner_id_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
OwnerTransferCmd(
session_id="sess-1",
new_owner_id="",
operator=_make_operator(),
)
assert exc_info.value.field == "new_owner_id"
@pytest.mark.unit
class TestCloseSessionCmd:
"""关闭会话命令 DTO 测试。"""
def test_valid_construction(self):
# Act
cmd = CloseSessionCmd(
session_id="sess-1",
operator=_make_operator(),
)
# Assert
assert cmd.reason is None
def test_empty_session_id_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
CloseSessionCmd(session_id="", operator=_make_operator())
assert exc_info.value.field == "session_id"
@pytest.mark.unit
class TestBatchCloseSessionsCmd:
"""批量关闭会话命令 DTO 测试。"""
def test_valid_with_session_ids(self):
# Act
cmd = BatchCloseSessionsCmd(
operator=_make_operator(),
session_ids=("s1", "s2"),
)
# Assert
assert cmd.max_count == 100
assert cmd.filter is None
def test_valid_with_filter(self):
# Act
cmd = BatchCloseSessionsCmd(
operator=_make_operator(),
filter={"channel_type": "wechat"},
)
# Assert
assert cmd.session_ids == ()
def test_both_empty_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
BatchCloseSessionsCmd(operator=_make_operator())
assert exc_info.value.field == "session_ids"
def test_max_count_below_min_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
BatchCloseSessionsCmd(
operator=_make_operator(),
session_ids=("s1",),
max_count=0,
)
assert exc_info.value.field == "max_count"
def test_max_count_above_max_raises(self):
# Act / Assert
with pytest.raises(ValidationError) as exc_info:
BatchCloseSessionsCmd(
operator=_make_operator(),
session_ids=("s1",),
max_count=1001,
)
assert exc_info.value.field == "max_count"
@pytest.mark.unit
class TestSessionStatsResult:
"""会话统计结果 DTO 测试。"""
def test_fields_are_assigned_with_defaults(self):
# Act
result = SessionStatsResult(
message_count=10,
user_message_count=5,
assistant_message_count=5,
started_at=datetime(2024, 1, 1),
last_activity_at=datetime(2024, 1, 2),
duration_seconds=86400,
)
# Assert
assert result.first_response_seconds is None
assert result.avg_response_seconds is None