feat: 重构 Reminder Notification 系统并更新应用包名
This commit is contained in:
@@ -4,7 +4,7 @@ import json
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime, timezone
|
||||
from types import SimpleNamespace
|
||||
from typing import Any
|
||||
from typing import Any, cast
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
import pytest
|
||||
@@ -27,6 +27,7 @@ class _FakeService:
|
||||
created_request: Any = None
|
||||
created_id: str = field(default_factory=lambda: str(uuid4()))
|
||||
list_calls: list[dict[str, Any]] = field(default_factory=list)
|
||||
range_calls: list[dict[str, Any]] = field(default_factory=list)
|
||||
deleted_ids: list[str] = field(default_factory=list)
|
||||
|
||||
async def list_paginated(
|
||||
@@ -47,6 +48,29 @@ class _FakeService:
|
||||
)
|
||||
return [item], 1
|
||||
|
||||
async def list_by_date_range(self, request: Any):
|
||||
self.range_calls.append(
|
||||
{
|
||||
"start_at": request.start_at,
|
||||
"end_at": request.end_at,
|
||||
}
|
||||
)
|
||||
return [
|
||||
SimpleNamespace(
|
||||
id=UUID(self.created_id),
|
||||
owner_id=uuid4(),
|
||||
title="会议",
|
||||
description="今天下午五点的会议",
|
||||
start_at=datetime(2026, 3, 17, 9, 0, tzinfo=timezone.utc),
|
||||
end_at=datetime(2026, 3, 17, 9, 30, tzinfo=timezone.utc),
|
||||
timezone="Asia/Shanghai",
|
||||
status="active",
|
||||
source_type="manual",
|
||||
metadata=None,
|
||||
subscribers=[],
|
||||
)
|
||||
]
|
||||
|
||||
async def create_agent_generated(self, request):
|
||||
self.created_request = request
|
||||
return SimpleNamespace(
|
||||
@@ -235,22 +259,48 @@ async def test_calendar_read_returns_structured_result_with_ids(
|
||||
)
|
||||
|
||||
result = await calendar_module.calendar_read(
|
||||
query="会议",
|
||||
page=1,
|
||||
page_size=20,
|
||||
start_at="2026-03-17T00:00:00+08:00",
|
||||
end_at="2026-03-18T00:00:00+08:00",
|
||||
session=SimpleNamespace(),
|
||||
owner_id=uuid4(),
|
||||
)
|
||||
payload = _decode_tool_response(result)
|
||||
result_data = json.loads(payload["result"])
|
||||
|
||||
assert payload["status"] == "success"
|
||||
assert result_data["total"] == 1
|
||||
assert result_data["items"][0]["id"] == fake_service.created_id
|
||||
assert result_data["items"][0]["timezone"] == "Asia/Shanghai"
|
||||
assert result_data["items"][0]["description"] == "今天下午五点的会议"
|
||||
assert result_data["items"][0]["status"] == "active"
|
||||
assert fake_service.range_calls == [
|
||||
{
|
||||
"start_at": datetime(2026, 3, 16, 16, 0, tzinfo=timezone.utc),
|
||||
"end_at": datetime(2026, 3, 17, 16, 0, tzinfo=timezone.utc),
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_calendar_read_rejects_naive_datetime_string(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
fake_service = _FakeService()
|
||||
monkeypatch.setattr(
|
||||
calendar_module, "create_schedule_service", lambda *_: fake_service
|
||||
)
|
||||
|
||||
result = await calendar_module.calendar_read(
|
||||
start_at="2026-03-17T00:00:00",
|
||||
end_at="2026-03-18T00:00:00+08:00",
|
||||
session=SimpleNamespace(),
|
||||
owner_id=uuid4(),
|
||||
)
|
||||
payload = _decode_tool_response(result)
|
||||
|
||||
assert payload["status"] == "success"
|
||||
assert payload["result"].startswith("status=success")
|
||||
assert "total=1" in payload["result"]
|
||||
assert "timezone=Asia/Shanghai" in payload["result"]
|
||||
assert "description=今天下午五点的会议" in payload["result"]
|
||||
assert "status=active" in payload["result"]
|
||||
assert fake_service.created_id in payload["result"]
|
||||
assert fake_service.list_calls == [{"page": 1, "page_size": 20, "query": "会议"}]
|
||||
assert payload["status"] == "failure"
|
||||
assert payload["error"]["code"] == "INVALID_ARGUMENT"
|
||||
assert "时区" in payload["error"]["message"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -312,3 +362,39 @@ async def test_calendar_share_rejects_invalid_phone(
|
||||
|
||||
assert payload["status"] == "failure"
|
||||
assert payload["error"]["code"] == "INVALID_ARGUMENT"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_calendar_share_accepts_json_invitee_payload(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
fake_service = _FakeService()
|
||||
monkeypatch.setattr(
|
||||
calendar_module, "create_schedule_service", lambda *_: fake_service
|
||||
)
|
||||
event_id = str(uuid4())
|
||||
|
||||
result = await calendar_module.calendar_share(
|
||||
event_id=event_id,
|
||||
invitees=cast(
|
||||
Any,
|
||||
[
|
||||
{
|
||||
"phone": "8613900001234",
|
||||
"permissionView": True,
|
||||
"permissionEdit": False,
|
||||
"permissionInvite": False,
|
||||
}
|
||||
],
|
||||
),
|
||||
session=SimpleNamespace(),
|
||||
owner_id=uuid4(),
|
||||
)
|
||||
payload = _decode_tool_response(result)
|
||||
|
||||
assert payload["status"] == "success"
|
||||
assert payload["result"].startswith("status=success success=1 failed=0")
|
||||
assert len(fake_service.share_calls) == 1
|
||||
share_call = fake_service.share_calls[0]
|
||||
assert share_call["item_id"] == event_id
|
||||
assert share_call["request"].phone == "+8613900001234"
|
||||
|
||||
Reference in New Issue
Block a user