feat: 统一自动化任务调度配置并增强聊天流恢复

This commit is contained in:
qzl
2026-03-24 18:19:33 +08:00
parent 23359c2d01
commit 389f5248fc
30 changed files with 1144 additions and 888 deletions
@@ -1,6 +1,6 @@
from datetime import datetime, time, timezone
from datetime import datetime, timezone
from unittest.mock import AsyncMock, MagicMock
from uuid import uuid4
from uuid import UUID, uuid4
import pytest
from fastapi import HTTPException
@@ -23,6 +23,8 @@ from schemas.automation import (
ContextSource,
ContextWindowMode,
MessageContextConfig,
ScheduleConfig,
ScheduleRunAt,
)
@@ -35,14 +37,16 @@ def _make_config() -> AutomationJobConfig:
window_mode=ContextWindowMode.DAY,
window_count=2,
),
schedule=ScheduleConfig(
type=ScheduleType.DAILY,
run_at=ScheduleRunAt(hour=9, minute=0),
),
)
def _make_create_request() -> AutomationJobCreateRequest:
return AutomationJobCreateRequest(
title="Test Job",
schedule_type=ScheduleType.DAILY,
run_at=time(9, 0, 0),
timezone="Asia/Shanghai",
status=AutomationJobStatus.ACTIVE,
config=_make_config(),
@@ -50,18 +54,28 @@ def _make_create_request() -> AutomationJobCreateRequest:
def _make_job(
owner_id: MagicMock | None = None, bootstrap_key: str | None = None
owner_id: UUID | None = None, bootstrap_key: str | None = None
) -> MagicMock:
job = MagicMock()
job.id = uuid4()
job.owner_id = owner_id or uuid4()
job.bootstrap_key = bootstrap_key
job.title = "Test Job"
job.schedule_type = ScheduleType.DAILY
job.run_at = datetime(2024, 1, 1, 9, 0, 0, tzinfo=timezone.utc)
job.timezone = "Asia/Shanghai"
job.status = AutomationJobStatus.ACTIVE
job.config = {"input_template": "Hello"}
job.config = {
"input_template": "Hello",
"enabled_tools": ["memory.write"],
"context": {
"source": "latest_chat",
"window_mode": "day",
"window_count": 2,
},
"schedule": {
"type": "daily",
"run_at": {"hour": 9, "minute": 0},
},
}
job.next_run_at = datetime(2024, 1, 2, 9, 0, 0, tzinfo=timezone.utc)
job.last_run_at = None
job.created_at = datetime(2024, 1, 1, 9, 0, 0, tzinfo=timezone.utc)
@@ -210,7 +224,9 @@ class TestUpdate:
with pytest.raises(AutomationJobNotFound):
await service.update(
job_id, owner_id, AutomationJobUpdateRequest(title="New")
job_id,
owner_id,
AutomationJobUpdateRequest(title="New", timezone="UTC"),
)
@pytest.mark.asyncio
@@ -225,7 +241,9 @@ class TestUpdate:
with pytest.raises(AutomationJobNotFound):
await service.update(
job.id, owner_id, AutomationJobUpdateRequest(title="New")
job.id,
owner_id,
AutomationJobUpdateRequest(title="New", timezone="UTC"),
)
@pytest.mark.asyncio
@@ -239,7 +257,9 @@ class TestUpdate:
with pytest.raises(SystemJobModificationForbidden):
await service.update(
job.id, owner_id, AutomationJobUpdateRequest(title="New")
job.id,
owner_id,
AutomationJobUpdateRequest(title="New", timezone="UTC"),
)
repository.update.assert_not_called()
@@ -257,12 +277,15 @@ class TestUpdate:
repository.update.return_value = updated_job
result = await service.update(
job.id, owner_id, AutomationJobUpdateRequest(title="Updated Title")
job.id,
owner_id,
AutomationJobUpdateRequest(title="Updated Title", timezone="UTC"),
)
assert result.title == "Updated Title"
repository.update.assert_awaited_once_with(
job.id, AutomationJobUpdateRequest(title="Updated Title")
job.id,
AutomationJobUpdateRequest(title="Updated Title", timezone="UTC"),
)
session.commit.assert_awaited_once()
@@ -278,7 +301,9 @@ class TestUpdate:
with pytest.raises(AutomationJobNotFound):
await service.update(
job.id, owner_id, AutomationJobUpdateRequest(title="New")
job.id,
owner_id,
AutomationJobUpdateRequest(title="New", timezone="UTC"),
)
@pytest.mark.asyncio
@@ -293,7 +318,9 @@ class TestUpdate:
with pytest.raises(HTTPException) as exc:
await service.update(
job.id, owner_id, AutomationJobUpdateRequest(title="New")
job.id,
owner_id,
AutomationJobUpdateRequest(title="New", timezone="UTC"),
)
assert exc.value.status_code == 503