feat(adapter): implement process_session and CLI
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"""Tests for Balabit Mouse Dynamics Challenge data adapter."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
@@ -261,3 +262,75 @@ class TestFilterSegments:
|
||||
result = filter_segments([seg], min_events=5, min_dist=50,
|
||||
max_span_ms=5000, max_gap_ms=200)
|
||||
assert len(result) == 1
|
||||
|
||||
|
||||
class TestProcessSession:
|
||||
def test_writes_jsonl_in_expected_format(self, tmp_path):
|
||||
from ai_mouse.config import BalabitAdapterConfig
|
||||
from ai_mouse.data_adapters.balabit import process_session
|
||||
|
||||
# Construct a Balabit-format CSV with one valid segment
|
||||
csv_path = tmp_path / "user_session_42"
|
||||
rows = []
|
||||
# 10 Move events going from (100,100) to (500,200) over 500ms
|
||||
for i in range(10):
|
||||
t = i * 0.05
|
||||
x = 100 + i * 40
|
||||
y = 100 + i * 10
|
||||
rows.append(f"0,{t:.3f},NoButton,Move,{x},{y}")
|
||||
rows.append(f"0,0.550,Left,Pressed,510,210")
|
||||
_write_csv(csv_path, rows)
|
||||
|
||||
out = tmp_path / "out.jsonl"
|
||||
config = BalabitAdapterConfig(
|
||||
window_ms=1200, min_dist=50, min_events=5,
|
||||
max_span_ms=5000, max_gap_ms=200,
|
||||
)
|
||||
n = process_session(csv_path, out, config)
|
||||
assert n == 1
|
||||
assert out.exists()
|
||||
|
||||
line = out.read_text(encoding="utf-8").strip()
|
||||
record = json.loads(line)
|
||||
assert record["meta"]["start"] == [100, 100]
|
||||
assert record["meta"]["end"] == [510, 210]
|
||||
assert record["meta"]["dist"] > 0
|
||||
assert record["meta"]["source"] == "balabit"
|
||||
assert record["meta"]["session_id"] == "user_session_42"
|
||||
# Events: only move events, no down/up
|
||||
assert all(e["type"] == "move" for e in record["events"])
|
||||
# Timestamps relative (start at 0)
|
||||
assert record["events"][0]["t"] == 0
|
||||
|
||||
def test_returns_zero_for_session_with_no_valid_segments(self, tmp_path):
|
||||
from ai_mouse.config import BalabitAdapterConfig
|
||||
from ai_mouse.data_adapters.balabit import process_session
|
||||
|
||||
csv_path = tmp_path / "empty_session"
|
||||
_write_csv(csv_path, ["0,0.000,NoButton,Move,100,100"]) # no clicks
|
||||
|
||||
out = tmp_path / "out.jsonl"
|
||||
config = BalabitAdapterConfig()
|
||||
n = process_session(csv_path, out, config)
|
||||
assert n == 0
|
||||
# File may not exist or may be empty — both acceptable
|
||||
if out.exists():
|
||||
assert out.read_text() == ""
|
||||
|
||||
def test_appends_to_existing_jsonl(self, tmp_path):
|
||||
from ai_mouse.config import BalabitAdapterConfig
|
||||
from ai_mouse.data_adapters.balabit import process_session
|
||||
|
||||
out = tmp_path / "out.jsonl"
|
||||
out.write_text('{"meta":{"start":[0,0],"end":[1,1]},"events":[]}\n', encoding="utf-8")
|
||||
|
||||
csv_path = tmp_path / "session_x"
|
||||
rows = [f"0,{i*0.05:.3f},NoButton,Move,{100+i*40},100" for i in range(10)]
|
||||
rows.append("0,0.550,Left,Pressed,510,100")
|
||||
_write_csv(csv_path, rows)
|
||||
|
||||
config = BalabitAdapterConfig()
|
||||
process_session(csv_path, out, config)
|
||||
|
||||
lines = out.read_text(encoding="utf-8").strip().split("\n")
|
||||
assert len(lines) == 2 # original + appended
|
||||
|
||||
Reference in New Issue
Block a user