Files
awoooi/apps/api/tests/test_approval_pending_visibility.py
Your Name cd17a67774
Some checks failed
CD Pipeline / tests (push) Successful in 1m21s
Code Review / ai-code-review (push) Successful in 13s
Type Sync Check / check-type-sync (push) Failing after 40s
CD Pipeline / build-and-deploy (push) Successful in 5m22s
CD Pipeline / post-deploy-checks (push) Successful in 2m19s
fix(alerts): surface legacy hitl backlog
2026-05-31 13:16:22 +08:00

123 lines
3.9 KiB
Python

from datetime import UTC, datetime, timedelta
from types import SimpleNamespace
from uuid import UUID
from src.models.approval import (
ApprovalRequest,
ApprovalRequestResponse,
ApprovalStatus,
RiskLevel,
)
from src.services.approval_db import approval_record_to_request
from src.services.heartbeat_report_service import (
AlertPipelineStats,
DbRedisStats,
FlywheelStats,
HeartbeatReport,
HeartbeatReportService,
)
def test_approval_response_exposes_incident_delivery_and_playbook_fields():
approval = ApprovalRequest(
id=UUID("11111111-1111-1111-1111-111111111111"),
action="kubectl rollout restart deployment/awoooi-api",
description="manual gate",
risk_level=RiskLevel.MEDIUM,
requested_by="OpenClaw",
required_signatures=1,
incident_id="INC-20260531-VISIBLE",
matched_playbook_id="PB-20260531-VISIBLE",
telegram_message_id=98765,
telegram_chat_id=-1001234567890,
)
response = ApprovalRequestResponse.from_approval(approval)
assert response.incident_id == "INC-20260531-VISIBLE"
assert response.matched_playbook_id == "PB-20260531-VISIBLE"
assert response.telegram_message_id == 98765
assert response.telegram_chat_id == -1001234567890
def test_approval_db_converter_preserves_incident_and_telegram_fields():
now = datetime.now(UTC)
record = SimpleNamespace(
id="22222222-2222-2222-2222-222222222222",
action="OBSERVE",
description="[LLM Failed] observe only",
status=ApprovalStatus.PENDING,
risk_level=RiskLevel.MEDIUM,
blast_radius={
"affected_pods": 0,
"estimated_downtime": "0",
"related_services": [],
"data_impact": "none",
},
dry_run_checks=[],
required_signatures=1,
current_signatures=0,
signatures=[],
requested_by="OpenClaw (fallback)",
created_at=now,
expires_at=now + timedelta(hours=1),
resolved_at=None,
rejection_reason=None,
extra_metadata={"source": "fallback"},
fingerprint="abc123",
hit_count=2,
last_seen_at=now,
incident_id="INC-20260531-LEGACY",
matched_playbook_id="PB-20260531-LEGACY",
telegram_message_id=45678,
telegram_chat_id=-1001234567890,
)
approval = approval_record_to_request(record)
assert approval.incident_id == "INC-20260531-LEGACY"
assert approval.matched_playbook_id == "PB-20260531-LEGACY"
assert approval.telegram_message_id == 45678
assert approval.telegram_chat_id == -1001234567890
def _report_with_pipeline(stats: AlertPipelineStats) -> HeartbeatReport:
return HeartbeatReport(
timestamp=datetime.now(UTC),
flywheel=FlywheelStats(playbook_count=1),
db_redis=DbRedisStats(db_ok=True, db_status="ok", redis_ok=True, redis_status="ok"),
alert_pipeline=stats,
)
def test_heartbeat_does_not_warn_when_pending_backlog_is_observe_only():
report = _report_with_pipeline(
AlertPipelineStats(
total_24h=25,
pending_approval=21,
pending_actionable=1,
pending_observe_only=20,
)
)
warnings = HeartbeatReportService()._build_warnings(report)
assert not any("待人工審核" in warning for warning in warnings)
assert not any("PENDING 積壓" in warning for warning in warnings)
def test_heartbeat_warns_with_frontend_route_for_actionable_backlog():
report = _report_with_pipeline(
AlertPipelineStats(
total_24h=25,
pending_approval=21,
pending_actionable=11,
pending_observe_only=10,
)
)
warnings = HeartbeatReportService()._build_warnings(report)
assert any("/awooop/approvals" in warning for warning in warnings)
assert any("觀察類 10" in warning for warning in warnings)