feat: 增强日历功能并集成 AgentScope 代理服务
This commit is contained in:
@@ -86,3 +86,30 @@ def test_metadata_attachment_reminder() -> None:
|
||||
)
|
||||
assert attachment.type == AttachmentType.REMINDER
|
||||
assert attachment.content == "Don't forget!"
|
||||
|
||||
|
||||
def test_metadata_rejects_invalid_color() -> None:
|
||||
with pytest.raises(ValidationError):
|
||||
ScheduleItemMetadata(color="blue")
|
||||
|
||||
|
||||
def test_metadata_rejects_invalid_version() -> None:
|
||||
with pytest.raises(ValidationError):
|
||||
ScheduleItemMetadata(version=2)
|
||||
|
||||
|
||||
def test_metadata_rejects_unknown_field() -> None:
|
||||
with pytest.raises(ValidationError):
|
||||
ScheduleItemMetadata.model_validate({"color": "#FF6B6B", "unknown": True})
|
||||
|
||||
|
||||
def test_metadata_attachment_rejects_unknown_field() -> None:
|
||||
with pytest.raises(ValidationError):
|
||||
ScheduleItemMetadataAttachment.model_validate(
|
||||
{
|
||||
"name": "memo",
|
||||
"type": "document",
|
||||
"url": "https://example.com",
|
||||
"unexpected": "x",
|
||||
}
|
||||
)
|
||||
|
||||
@@ -13,6 +13,7 @@ from models.schedule_items import (
|
||||
)
|
||||
from v1.schedule_items.schemas import (
|
||||
ScheduleItemCreateRequest,
|
||||
ScheduleItemMetadata,
|
||||
ScheduleItemUpdateRequest,
|
||||
)
|
||||
from v1.schedule_items.service import ScheduleItemService
|
||||
@@ -50,6 +51,11 @@ class FakeRepo:
|
||||
return self._item
|
||||
return None
|
||||
|
||||
async def get_by_id(self, entity_id: UUID) -> ScheduleItem | None:
|
||||
if self._item and entity_id == self._item.id:
|
||||
return self._item
|
||||
return None
|
||||
|
||||
async def create(self, data: dict) -> ScheduleItem:
|
||||
return _create_mock_schedule_item(
|
||||
owner_id=data["owner_id"],
|
||||
@@ -77,6 +83,20 @@ class FakeRepo:
|
||||
) -> list[ScheduleItem]:
|
||||
return [self._item] if self._item else []
|
||||
|
||||
async def list_paginated(
|
||||
self,
|
||||
owner_id: UUID,
|
||||
*,
|
||||
page: int,
|
||||
page_size: int,
|
||||
) -> tuple[list[ScheduleItem], int]:
|
||||
del owner_id, page, page_size
|
||||
return ([self._item] if self._item else [], 1 if self._item else 0)
|
||||
|
||||
async def create_subscription(self, data: dict):
|
||||
del data
|
||||
return MagicMock()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_session() -> AsyncMock:
|
||||
@@ -183,3 +203,70 @@ async def test_delete_success(mock_session: AsyncMock) -> None:
|
||||
await service.delete(item.id)
|
||||
|
||||
mock_session.commit.assert_awaited_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_maps_metadata_to_extra_metadata(mock_session: AsyncMock) -> None:
|
||||
user_id = UUID("00000000-0000-0000-0000-000000000001")
|
||||
captured: dict | None = None
|
||||
|
||||
class CaptureRepo(FakeRepo):
|
||||
async def create(self, data: dict) -> ScheduleItem:
|
||||
nonlocal captured
|
||||
captured = data
|
||||
return _create_mock_schedule_item(
|
||||
owner_id=data["owner_id"], title=data["title"]
|
||||
)
|
||||
|
||||
request = ScheduleItemCreateRequest(
|
||||
title="Roadmap",
|
||||
start_at=datetime(2026, 2, 28, 16, 0, 0, tzinfo=timezone.utc),
|
||||
metadata=ScheduleItemMetadata(location="会议室A", color="#4F46E5", version=1),
|
||||
)
|
||||
service = ScheduleItemService(
|
||||
repository=CaptureRepo(None),
|
||||
session=mock_session,
|
||||
current_user=CurrentUser(id=user_id),
|
||||
)
|
||||
|
||||
await service.create(request)
|
||||
|
||||
assert captured is not None
|
||||
assert "extra_metadata" in captured
|
||||
assert captured["extra_metadata"]["location"] == "会议室A"
|
||||
assert "metadata" not in captured
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_maps_metadata_to_extra_metadata(mock_session: AsyncMock) -> None:
|
||||
user_id = UUID("00000000-0000-0000-0000-000000000001")
|
||||
item = _create_mock_schedule_item()
|
||||
captured: dict | None = None
|
||||
|
||||
class CaptureRepo(FakeRepo):
|
||||
async def update_by_item_id(
|
||||
self, item_id: UUID, owner_id: UUID, data: dict
|
||||
) -> ScheduleItem | None:
|
||||
nonlocal captured
|
||||
captured = data
|
||||
return await super().update_by_item_id(item_id, owner_id, data)
|
||||
|
||||
service = ScheduleItemService(
|
||||
repository=CaptureRepo(item),
|
||||
session=mock_session,
|
||||
current_user=CurrentUser(id=user_id),
|
||||
)
|
||||
|
||||
await service.update(
|
||||
item.id,
|
||||
ScheduleItemUpdateRequest(
|
||||
metadata=ScheduleItemMetadata(
|
||||
location="线上会议", color="#3B82F6", version=1
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
assert captured is not None
|
||||
assert "extra_metadata" in captured
|
||||
assert captured["extra_metadata"]["location"] == "线上会议"
|
||||
assert "metadata" not in captured
|
||||
|
||||
Reference in New Issue
Block a user