- Frontend v4 accessible sur réseau local (192.168.1.40) - Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard) - Ollama GPU fonctionnel - Self-healing interactif - Dashboard confiance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
312 lines
10 KiB
Python
312 lines
10 KiB
Python
"""
|
|
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
|