199 lines
9.2 KiB
Python
199 lines
9.2 KiB
Python
import os
|
|
import unittest
|
|
|
|
os.environ.setdefault("DATABASE_URL", "postgresql+psycopg://user:pass@localhost:5432/ai_ict_test")
|
|
|
|
from src.api.alerts import (
|
|
_build_archive_bundle_manifest,
|
|
_build_archive_selection_provenance_summary,
|
|
_build_external_context_surface_history_summary,
|
|
_build_workflow_archive_artifact_bundle_summary,
|
|
_build_workflow_archive_compare_writeback_summary,
|
|
_build_workflow_archive_handoff_bundle_summary,
|
|
_build_workflow_archive_handoff_packet_starter,
|
|
_build_workflow_archive_replay_note_bridge_summary,
|
|
)
|
|
|
|
|
|
class AlertArchiveHelperTests(unittest.TestCase):
|
|
def test_workflow_handoff_bundle_summary_handles_empty_items(self) -> None:
|
|
result = _build_workflow_archive_handoff_bundle_summary(
|
|
{"items": [], "bridge_summary": {"bridge_target_count": 3, "next_handoff_prompt": "later"}},
|
|
None,
|
|
)
|
|
|
|
self.assertEqual(result["status"], "idle")
|
|
self.assertEqual(result["bridge_target_count"], 3)
|
|
self.assertIsNone(result["latest_snapshot_id"])
|
|
|
|
def test_workflow_bridge_extension_helpers_build_active_payloads(self) -> None:
|
|
archive = {
|
|
"items": [
|
|
{
|
|
"snapshot_id": 9,
|
|
"current_session": "LONDON",
|
|
"next_phase": "intraday",
|
|
"next_artifact_kind": "intraday_digest",
|
|
"created_ts": "2026-05-15T01:00:00+00:00",
|
|
}
|
|
],
|
|
"bridge_summary": {
|
|
"bridge_target_count": 3,
|
|
"next_handoff_prompt": "handoff now",
|
|
"next_replay_prompt": "replay now",
|
|
"next_note_prompt": "note now",
|
|
},
|
|
"daily_groups": [{"group_date": "2026-05-15"}],
|
|
"session_groups": [{"session_code": "LONDON"}],
|
|
}
|
|
compare = {
|
|
"status": "active",
|
|
"left": {"snapshot_id": 9, "current_session": "LONDON", "next_phase": "intraday"},
|
|
"right": {"snapshot_id": 7, "current_session": "NY_AM", "next_phase": "post_trade"},
|
|
"phase_changes": [{"phase": "intraday", "changed": True}],
|
|
"count_delta": {"artifact_count": 1, "ready_for_handoff_count": 1, "needs_update_count": 0},
|
|
"summary": "compare summary",
|
|
}
|
|
|
|
packet = _build_workflow_archive_handoff_packet_starter(archive, compare)
|
|
replay = _build_workflow_archive_replay_note_bridge_summary(archive, compare)
|
|
bundle = _build_workflow_archive_artifact_bundle_summary(archive)
|
|
|
|
self.assertEqual(packet["status"], "active")
|
|
self.assertTrue(packet["starter_prompt"])
|
|
self.assertEqual(replay["status"], "active")
|
|
self.assertIn("Changed phases", replay["note_body"])
|
|
self.assertEqual(bundle["status"], "active")
|
|
self.assertEqual(bundle["day_group_count"], 1)
|
|
|
|
def test_workflow_compare_writeback_summary_persists_note_context(self) -> None:
|
|
result = _build_workflow_archive_compare_writeback_summary(
|
|
note={
|
|
"id": 21,
|
|
"note_scope": "workflow_compare",
|
|
"author": "local_operator",
|
|
"tags": ["workflow-compare", "session:LONDON"],
|
|
"created_ts": "2026-05-16T02:00:00+00:00",
|
|
},
|
|
replay_note_bridge_summary={
|
|
"note_title": "Workflow replay compare #9 vs #8",
|
|
"note_body": "compare body",
|
|
"compare_left_snapshot_id": 9,
|
|
"compare_right_snapshot_id": 8,
|
|
"changed_phase_count": 2,
|
|
},
|
|
compare={"summary": "compare summary"},
|
|
query_context={"profile_scope": "selected_profile", "left_id": 9, "right_id": 8},
|
|
)
|
|
|
|
self.assertEqual(result["status"], "persisted")
|
|
self.assertEqual(result["note_id"], 21)
|
|
self.assertEqual(result["note_title"], "Workflow replay compare #9 vs #8")
|
|
self.assertEqual(result["compare_left_snapshot_id"], 9)
|
|
self.assertEqual(result["changed_phase_count"], 2)
|
|
|
|
def test_archive_selection_provenance_summary_tracks_scope_filters_and_compare(self) -> None:
|
|
result = _build_archive_selection_provenance_summary(
|
|
archive={
|
|
"status": "active",
|
|
"profile_scope": "all_profiles",
|
|
"query_preset": "recent_7d",
|
|
"filters": {"query_text": "candidate", "created_after": "", "digest_mode": "high_value_only"},
|
|
"archive_baseline_state": {"digest_snapshot_id": 9},
|
|
"item_count": 5,
|
|
},
|
|
compare={"left": {"snapshot_id": 4}, "right": {"snapshot_id": 3}},
|
|
export_scope="selected_compare",
|
|
selection_kind="digest_archive",
|
|
)
|
|
|
|
self.assertEqual(result["status"], "active")
|
|
self.assertEqual(result["export_scope"], "selected_compare")
|
|
self.assertEqual(result["active_filter_count"], 2)
|
|
self.assertEqual(result["selected_snapshot_ids"], [4, 3])
|
|
self.assertEqual(result["baseline_snapshot_id"], 9)
|
|
|
|
def test_archive_bundle_manifest_normalizes_export_sections(self) -> None:
|
|
manifest = _build_archive_bundle_manifest(
|
|
archive={
|
|
"status": "active",
|
|
"profile_scope": "all_profiles",
|
|
"query_preset": "recent_7d",
|
|
"item_count": 5,
|
|
},
|
|
compare={"status": "active"},
|
|
generated_ts="2026-05-17T03:00:00+00:00",
|
|
export_kind="digest_archive_bundle",
|
|
export_scope="selected_compare",
|
|
selection_provenance_summary={
|
|
"active_filter_count": 2,
|
|
"selected_snapshot_ids": [4, 3],
|
|
"baseline_snapshot_id": 9,
|
|
},
|
|
structured_export_summary={"status": "active"},
|
|
)
|
|
|
|
self.assertEqual(manifest["normalization_status"], "normalized")
|
|
self.assertEqual(manifest["manifest_version"], "decision_assistant_archive_bundle_manifest_v1")
|
|
self.assertEqual(manifest["status"], "active")
|
|
self.assertIn("compare", manifest["included_sections"])
|
|
self.assertEqual(manifest["baseline_snapshot_id"], 9)
|
|
|
|
def test_external_context_surface_history_summary_includes_e30_resolution_follow_up_fields(self) -> None:
|
|
result = _build_external_context_surface_history_summary(
|
|
instrument_id=1,
|
|
profile_key="local_operator",
|
|
history=[
|
|
{
|
|
"surface_id": "okx_help_announcements_page",
|
|
"title": "okx_help_announcements_page",
|
|
"source_group": "exchange_context_surface",
|
|
"selection_kind": "target_url",
|
|
"target_url": "https://www.okx.com/help",
|
|
"selected_ts": "2026-05-16T00:00:00+00:00",
|
|
"revisit_acknowledged": True,
|
|
"revisit_acknowledged_by": "alice",
|
|
"revisit_acknowledged_ts": "2026-05-16T08:00:00+00:00",
|
|
},
|
|
{
|
|
"surface_id": "tradingview_public_chart_reference",
|
|
"title": "tradingview_public_chart_reference",
|
|
"source_group": "visual_reference_card",
|
|
"selection_kind": "target_url",
|
|
"target_url": "https://www.tradingview.com/",
|
|
"selected_ts": "2026-05-15T00:00:00+00:00",
|
|
"revisit_acknowledged": True,
|
|
"revisit_acknowledged_by": "bob",
|
|
"revisit_acknowledged_ts": "2026-05-16T07:30:00+00:00",
|
|
"revisit_ack_note": "checked",
|
|
},
|
|
{
|
|
"surface_id": "binance_public_chart_reference",
|
|
"title": "binance_public_chart_reference",
|
|
"source_group": "visual_reference_card",
|
|
"selection_kind": "target_url",
|
|
"target_url": "https://www.binance.com/en/trade/BTC_USDT?type=spot",
|
|
"selected_ts": "2026-05-14T00:00:00+00:00",
|
|
"revisit_acknowledged": True,
|
|
"revisit_acknowledged_by": "bob",
|
|
"revisit_acknowledged_ts": "2026-05-16T07:00:00+00:00",
|
|
"revisit_ack_note": "done",
|
|
},
|
|
],
|
|
)
|
|
|
|
resolution = result["resolution_filter_summary"]
|
|
self.assertIn("resolved_owner_drift_status", resolution)
|
|
self.assertIn("carry_forward_follow_up_lane_status", resolution)
|
|
self.assertEqual(resolution["resolved_owner_drift_status"], "drift_detected")
|
|
self.assertEqual(resolution["carry_forward_follow_up_lane_status"], "active")
|
|
self.assertEqual(resolution["resolved_owner_drift_review_status"], "review_required")
|
|
self.assertEqual(resolution["resolved_owner_drift_review_queue_status"], "active")
|
|
self.assertEqual(resolution["resolved_owner_drift_review_queue_aging_status"], "stale")
|
|
self.assertEqual(resolution["carry_forward_follow_up_lane_rollover_status"], "rollover_required")
|
|
self.assertEqual(resolution["carry_forward_follow_up_lane_rollover_handoff_status"], "handoff_required")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|