111 lines
4.5 KiB
Python
111 lines
4.5 KiB
Python
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
from src.services.visual_watch.snapshot_capture_service import VisualSnapshotCaptureService
|
|
|
|
|
|
class VisualSnapshotCaptureServiceTests(unittest.TestCase):
|
|
def test_capture_watch_run_snapshot_writes_html_and_manifest(self) -> None:
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
service = VisualSnapshotCaptureService(
|
|
review_packet_service=_ReviewPacketService(),
|
|
output_root=Path(tmp),
|
|
browser_capture_enabled=False,
|
|
)
|
|
|
|
result = service.capture_watch_run_snapshot(
|
|
watch_run={
|
|
"id": 11,
|
|
"trigger_type": "candidate_actionable_watch",
|
|
"instrument_id": 1,
|
|
"candidate_id": 22,
|
|
"signal_id": 33,
|
|
"decision_packet_id": 44,
|
|
"symbol": "BTC-USDT",
|
|
"timeframe": "1m",
|
|
"status": "reserved",
|
|
},
|
|
source_name="unit_capture",
|
|
)
|
|
|
|
self.assertEqual(result["status"], "captured")
|
|
self.assertEqual(result["capture_mode"], "review_packet_html")
|
|
self.assertEqual(result["browser_capture_status"], "disabled")
|
|
self.assertEqual(result["source_name"], "unit_capture")
|
|
self.assertTrue(Path(result["image_path"]).is_file())
|
|
self.assertTrue(Path(result["html_path"]).is_file())
|
|
self.assertTrue(Path(result["artifact_path"]).is_file())
|
|
html = Path(result["image_path"]).read_text(encoding="utf-8")
|
|
self.assertIn("Visual Watch Snapshot", html)
|
|
self.assertIn("BTC-USDT", html)
|
|
self.assertIn("confirm_ticket", html)
|
|
self.assertEqual(result["payload"]["review_packet_summary"]["recent_alert_count"], 1)
|
|
|
|
def test_capture_watch_run_snapshot_can_write_browser_screenshot(self) -> None:
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
def fake_browser_capture(*, url, screenshot_path, viewport):
|
|
Path(screenshot_path).write_bytes(b"\x89PNG\r\n\x1a\nunit")
|
|
return {
|
|
"status": "captured",
|
|
"url": url,
|
|
"image_path": str(screenshot_path),
|
|
"viewport": viewport or {},
|
|
}
|
|
|
|
service = VisualSnapshotCaptureService(
|
|
review_packet_service=_ReviewPacketService(),
|
|
output_root=Path(tmp),
|
|
browser_capture_func=fake_browser_capture,
|
|
)
|
|
|
|
result = service.capture_watch_run_snapshot(
|
|
watch_run={
|
|
"id": 12,
|
|
"trigger_type": "candidate_actionable_watch",
|
|
"instrument_id": 1,
|
|
"decision_packet_id": 44,
|
|
"symbol": "BTC-USDT",
|
|
"timeframe": "1m",
|
|
"status": "reserved",
|
|
},
|
|
source_name="unit_browser_capture",
|
|
viewport={"width": 800, "height": 600},
|
|
)
|
|
|
|
self.assertEqual(result["status"], "captured")
|
|
self.assertEqual(result["capture_mode"], "browser_screenshot")
|
|
self.assertEqual(result["browser_capture_status"], "captured")
|
|
self.assertTrue(str(result["image_path"]).endswith(".png"))
|
|
self.assertTrue(Path(result["screenshot_path"]).is_file())
|
|
self.assertTrue(Path(result["html_path"]).is_file())
|
|
self.assertEqual(result["payload"]["browser_capture"]["status"], "captured")
|
|
|
|
|
|
class _ReviewPacketService:
|
|
def build_packet(self, *, instrument_id: int) -> dict:
|
|
return {
|
|
"instrument_id": instrument_id,
|
|
"generated_ts": "2026-05-11T01:00:00+00:00",
|
|
"decision_packet": {
|
|
"id": 44,
|
|
"status": "actionable",
|
|
"action_recommendation": "confirm_ticket",
|
|
},
|
|
"recent_alerts": [{"id": 1}],
|
|
"recent_notes": [{"id": 2}],
|
|
"recent_executions": [{"id": 3}],
|
|
"weekly_review": {"entry_count": 4},
|
|
"trust_score": {"models": [{"model_code": "research_council"}]},
|
|
"research_council": {"id": 31},
|
|
"research_council_summary": {
|
|
"present": True,
|
|
"overall_stance": "observe_only",
|
|
},
|
|
"research_council_optimization_review": {"health_state": "healthy"},
|
|
}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|