""" Tests unitaires pour RawSession Property 1: RawSession Serialization Round Trip Validates: Requirements 1.4, 1.5 """ import pytest from datetime import datetime from pathlib import Path import tempfile import json from core.models.raw_session import ( RawSession, Event, Screenshot, WindowContext ) class TestWindowContext: """Tests pour WindowContext""" def test_to_dict(self): """Test sérialisation WindowContext""" ctx = WindowContext(title="Test Window", app_name="test.exe") data = ctx.to_dict() assert data["title"] == "Test Window" assert data["app_name"] == "test.exe" def test_from_dict(self): """Test désérialisation WindowContext""" data = {"title": "Test Window", "app_name": "test.exe"} ctx = WindowContext.from_dict(data) assert ctx.title == "Test Window" assert ctx.app_name == "test.exe" class TestEvent: """Tests pour Event""" def test_mouse_click_event(self): """Test événement mouse_click""" window = WindowContext(title="App", app_name="app.exe") event = Event( t=1.5, type="mouse_click", window=window, screenshot_id="shot_001", data={"button": "left", "pos": [800, 400]} ) assert event.t == 1.5 assert event.type == "mouse_click" assert event.data["button"] == "left" def test_event_to_dict(self): """Test sérialisation Event""" window = WindowContext(title="App", app_name="app.exe") event = Event( t=1.5, type="mouse_click", window=window, screenshot_id="shot_001", data={"button": "left", "pos": [800, 400]} ) data = event.to_dict() assert data["t"] == 1.5 assert data["type"] == "mouse_click" assert data["screenshot_id"] == "shot_001" assert data["button"] == "left" assert data["pos"] == [800, 400] def test_event_from_dict(self): """Test désérialisation Event""" data = { "t": 1.5, "type": "mouse_click", "window": {"title": "App", "app_name": "app.exe"}, "screenshot_id": "shot_001", "button": "left", "pos": [800, 400] } event = Event.from_dict(data) assert event.t == 1.5 assert event.type == "mouse_click" assert event.screenshot_id == "shot_001" assert event.data["button"] == "left" assert event.data["pos"] == [800, 400] class TestScreenshot: """Tests pour Screenshot""" def test_screenshot_serialization(self): """Test sérialisation/désérialisation Screenshot""" screenshot = Screenshot( screenshot_id="shot_001", relative_path="shots/shot_001.png", captured_at="2025-11-22T10:15:00.523Z" ) data = screenshot.to_dict() screenshot2 = Screenshot.from_dict(data) assert screenshot2.screenshot_id == screenshot.screenshot_id assert screenshot2.relative_path == screenshot.relative_path assert screenshot2.captured_at == screenshot.captured_at class TestRawSession: """Tests pour RawSession""" def test_create_session(self): """Test création d'une session""" session = RawSession( session_id="sess_test_001", agent_version="0.1.0", environment={"platform": "linux", "hostname": "test-machine"}, user={"id": "test_user", "label": "Test User"}, context={"customer": "Test", "training_label": "test_workflow"}, started_at=datetime(2025, 11, 22, 10, 15, 0) ) assert session.session_id == "sess_test_001" assert session.schema_version == "rawsession_v1" assert len(session.events) == 0 assert len(session.screenshots) == 0 def test_add_event(self): """Test ajout d'événement""" session = RawSession( session_id="sess_test_001", agent_version="0.1.0", environment={}, user={}, context={}, started_at=datetime.now() ) window = WindowContext(title="App", app_name="app.exe") event = Event(t=1.0, type="mouse_click", window=window) session.add_event(event) assert len(session.events) == 1 assert session.events[0].type == "mouse_click" def test_add_screenshot(self): """Test ajout de screenshot""" session = RawSession( session_id="sess_test_001", agent_version="0.1.0", environment={}, user={}, context={}, started_at=datetime.now() ) screenshot = Screenshot( screenshot_id="shot_001", relative_path="shots/shot_001.png", captured_at="2025-11-22T10:15:00.523Z" ) session.add_screenshot(screenshot) assert len(session.screenshots) == 1 assert session.screenshots[0].screenshot_id == "shot_001" def test_to_json(self): """Test sérialisation JSON""" session = RawSession( session_id="sess_test_001", agent_version="0.1.0", environment={"platform": "linux"}, user={"id": "test_user"}, context={"customer": "Test"}, started_at=datetime(2025, 11, 22, 10, 15, 0), ended_at=datetime(2025, 11, 22, 10, 30, 0) ) data = session.to_json() assert data["schema_version"] == "rawsession_v1" assert data["session_id"] == "sess_test_001" assert data["started_at"] == "2025-11-22T10:15:00" assert data["ended_at"] == "2025-11-22T10:30:00" def test_from_json(self): """Test désérialisation JSON""" data = { "schema_version": "rawsession_v1", "session_id": "sess_test_001", "agent_version": "0.1.0", "environment": {"platform": "linux"}, "user": {"id": "test_user"}, "context": {"customer": "Test"}, "started_at": "2025-11-22T10:15:00", "ended_at": "2025-11-22T10:30:00", "events": [], "screenshots": [] } session = RawSession.from_json(data) assert session.session_id == "sess_test_001" assert session.schema_version == "rawsession_v1" assert session.started_at == datetime(2025, 11, 22, 10, 15, 0) def test_from_json_invalid_schema(self): """Test désérialisation avec schéma invalide""" data = { "schema_version": "rawsession_v2", # Version non supportée "session_id": "sess_test_001", "agent_version": "0.1.0", "environment": {}, "user": {}, "context": {}, "started_at": "2025-11-22T10:15:00" } with pytest.raises(ValueError, match="Unsupported schema version"): RawSession.from_json(data) def test_round_trip_serialization(self): """ Property 1: RawSession Serialization Round Trip Pour toute RawSession valide, sérialiser puis désérialiser doit produire une RawSession équivalente. Validates: Requirements 1.4, 1.5 """ # Créer session complète window = WindowContext(title="App", app_name="app.exe") event = Event( t=1.5, type="mouse_click", window=window, screenshot_id="shot_001", data={"button": "left", "pos": [800, 400]} ) screenshot = Screenshot( screenshot_id="shot_001", relative_path="shots/shot_001.png", captured_at="2025-11-22T10:15:00.523Z" ) session = RawSession( session_id="sess_test_001", agent_version="0.1.0", environment={"platform": "linux", "hostname": "test"}, user={"id": "test_user", "label": "Test User"}, context={"customer": "Test", "training_label": "test"}, started_at=datetime(2025, 11, 22, 10, 15, 0), ended_at=datetime(2025, 11, 22, 10, 30, 0) ) session.add_event(event) session.add_screenshot(screenshot) # Round trip data = session.to_json() session2 = RawSession.from_json(data) # Vérifier équivalence assert session2.session_id == session.session_id assert session2.agent_version == session.agent_version assert session2.schema_version == session.schema_version assert session2.started_at == session.started_at assert session2.ended_at == session.ended_at assert len(session2.events) == len(session.events) assert len(session2.screenshots) == len(session.screenshots) # Vérifier événement assert session2.events[0].t == session.events[0].t assert session2.events[0].type == session.events[0].type assert session2.events[0].data["button"] == "left" # Vérifier screenshot assert session2.screenshots[0].screenshot_id == "shot_001" def test_save_and_load_file(self): """Test sauvegarde et chargement depuis fichier""" session = RawSession( session_id="sess_test_001", agent_version="0.1.0", environment={"platform": "linux"}, user={"id": "test_user"}, context={"customer": "Test"}, started_at=datetime(2025, 11, 22, 10, 15, 0) ) with tempfile.TemporaryDirectory() as tmpdir: filepath = Path(tmpdir) / "test_session.json" # Sauvegarder session.save_to_file(filepath) assert filepath.exists() # Charger session2 = RawSession.load_from_file(filepath) assert session2.session_id == session.session_id assert session2.agent_version == session.agent_version