feat: 添加飞书用户模块和订阅功能支持 - 新增feishu_users模块用于处理飞书用户身份验证和权限管理 - 新增subscriptions模块用于处理订阅相关功能 - 新增personalization模块用于个性化服务 - 在alembic迁移配置中注册新的模型模块 - 在API路由器中添加feishu_users和subscriptions路由 - 实现事件调度服务的改进,包括错误处理和状态更新优化 - 添加飞书命令处理的权限检查机制 - 实现飞书应用票据事件处理 - 改进审计日志记录功能 ```
70 lines
2.4 KiB
Python
70 lines
2.4 KiB
Python
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
from sqlalchemy import create_engine, select
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
from app.core.background.task_queue import lifecycle as lifecycle_queue
|
|
from app.core.database import Base
|
|
from app.modules.reports.constants import ReportType
|
|
from app.modules.workflows.constants import WorkflowStatus, WorkflowType
|
|
from app.modules.workflows.models import WorkflowAction, WorkflowInstance
|
|
from app.tasks import celery_app
|
|
|
|
|
|
def test_lifecycle_enqueue_failure_marks_workflow_failed(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
engine = create_engine("sqlite://")
|
|
Base.metadata.create_all(engine)
|
|
factory = sessionmaker(bind=engine, expire_on_commit=False)
|
|
|
|
class BrokenSignature:
|
|
def apply_async(self) -> None:
|
|
raise RuntimeError("broker unavailable")
|
|
|
|
monkeypatch.setattr(lifecycle_queue, "SessionLocal", factory)
|
|
monkeypatch.setattr(
|
|
lifecycle_queue,
|
|
"get_settings",
|
|
lambda: SimpleNamespace(task_queue_enabled=True),
|
|
)
|
|
monkeypatch.setattr(
|
|
celery_app,
|
|
"signature",
|
|
lambda *args, **kwargs: BrokenSignature(),
|
|
)
|
|
try:
|
|
with pytest.raises(RuntimeError, match="broker unavailable"):
|
|
lifecycle_queue.enqueue_lifecycle_report(
|
|
report_type=ReportType.WEEKLY,
|
|
actor="pytest",
|
|
)
|
|
|
|
with factory() as db:
|
|
workflow = db.execute(
|
|
select(WorkflowInstance).where(
|
|
WorkflowInstance.workflow_type
|
|
== WorkflowType.LIFECYCLE_REPORT
|
|
)
|
|
).scalar_one()
|
|
actions = list(
|
|
db.execute(
|
|
select(WorkflowAction)
|
|
.where(WorkflowAction.workflow_code == workflow.code)
|
|
.order_by(WorkflowAction.id.asc())
|
|
).scalars()
|
|
)
|
|
|
|
assert workflow.status == WorkflowStatus.FAILED
|
|
assert workflow.current_step == "enqueue_failed"
|
|
assert workflow.completed_at is not None
|
|
assert workflow.payload == {"error": "broker unavailable"}
|
|
assert [action.action for action in actions] == [
|
|
"queued",
|
|
"enqueue_failed",
|
|
]
|
|
assert actions[-1].to_status == WorkflowStatus.FAILED
|
|
finally:
|
|
engine.dispose()
|