# tests/unit/test_monitor_router.py """Tests unitaires pour MonitorRouter (QW1).""" import pytest from agent_v0.server_v1.monitor_router import resolve_target_monitor, MonitorTarget # Geometry de référence pour les 3 tests : 2 écrans côte à côte TWO_MONITORS = [ {"idx": 0, "x": 0, "y": 0, "w": 1920, "h": 1080, "primary": True}, {"idx": 1, "x": 1920, "y": 0, "w": 1920, "h": 1080, "primary": False}, ] def test_resolve_uses_action_monitor_index_when_present(): """Si action.monitor_index présent et valide → cible cet écran.""" action = {"monitor_index": 1} session_state = {"monitors_geometry": TWO_MONITORS, "last_focused_monitor": 0} result = resolve_target_monitor(action, session_state) assert result.idx == 1 assert result.offset_x == 1920 assert result.offset_y == 0 assert result.source == "action" def test_resolve_falls_back_to_focused_monitor_when_action_missing(): """Si action.monitor_index absent → fallback focus actif.""" action = {} # pas de monitor_index session_state = {"monitors_geometry": TWO_MONITORS, "last_focused_monitor": 1} result = resolve_target_monitor(action, session_state) assert result.idx == 1 assert result.source == "focus" def test_resolve_falls_back_to_composite_when_geometry_empty(): """Si geometry vide (vieux Agent V1) → fallback composite (idx=-1, offset=0).""" action = {} session_state = {"monitors_geometry": [], "last_focused_monitor": None} result = resolve_target_monitor(action, session_state) assert result.source == "composite_fallback" assert result.offset_x == 0 assert result.offset_y == 0 def test_resolve_falls_back_when_action_index_out_of_range(): """Si action.monitor_index hors limites (écran débranché) → fallback focus.""" action = {"monitor_index": 5} # n'existe pas session_state = {"monitors_geometry": TWO_MONITORS, "last_focused_monitor": 0} result = resolve_target_monitor(action, session_state) assert result.idx == 0 assert result.source == "focus"