Files
group_fqcd_jr/tests/integration/test_outbox_replay_mysql.py
T

64 lines
2.3 KiB
Python
Raw Normal View History

from datetime import UTC, datetime
from uuid import uuid4
import pytest
from sqlalchemy import delete, select
from app.infrastructure.db import SessionFactory
from app.model.audit import InteractionAudit
from app.model.platform import DomainEventOutbox
from app.service.outbox_admin_service import OutboxAdminService
# 依赖真实 MySQL:必须打 integration marker,否则按 marker 过滤时会漏测这批用例。
pytestmark = pytest.mark.integration
@pytest.mark.asyncio
async def test_dead_event_replay_is_audited() -> None:
event_id = str(uuid4())
now = datetime.now(UTC).replace(tzinfo=None)
try:
async with SessionFactory() as session:
session.add(
DomainEventOutbox(
event_id=event_id,
event_type="test.dead",
aggregate_type="test",
aggregate_id=event_id,
trace_id=event_id,
payload={},
status="dead",
retry_count=5,
last_error="RuntimeError",
occurred_at=now,
created_at=now,
updated_at=now,
)
)
await session.commit()
async with SessionFactory() as session:
event = await OutboxAdminService(session).replay_dead(event_id, actor_id=1)
await session.commit()
assert event.status == "pending"
assert event.retry_count == 0
async with SessionFactory() as session:
audit = await session.scalar(
select(InteractionAudit).where(
InteractionAudit.action_type == "outbox.dead_replay",
InteractionAudit.detail["event_id"] == event_id,
)
)
assert audit is not None
finally:
async with SessionFactory() as session:
await session.execute(
delete(InteractionAudit).where(
InteractionAudit.action_type == "outbox.dead_replay",
InteractionAudit.detail["event_id"] == event_id,
)
)
await session.execute(
delete(DomainEventOutbox).where(DomainEventOutbox.event_id == event_id)
)
await session.commit()