"""Tests para mark_claude_role.""" import json import os import pytest from mark_claude_role import mark_claude_role def _write_session(sessions_dir, pid, session_id): """Escribe un sessions/.json con el sessionId dado.""" os.makedirs(sessions_dir, exist_ok=True) path = os.path.join(sessions_dir, f"{pid}.json") with open(path, "w", encoding="utf-8") as fh: json.dump({"sessionId": session_id, "cwd": "/tmp/whatever"}, fh) return path def _write_goal(goals_dir, session_id, goal): """Escribe un goal/.json con el dict dado.""" os.makedirs(goals_dir, exist_ok=True) path = os.path.join(goals_dir, f"{session_id}.json") with open(path, "w", encoding="utf-8") as fh: json.dump(goal, fh) return path def _read_goal(goals_dir, session_id): path = os.path.join(goals_dir, f"{session_id}.json") with open(path, "r", encoding="utf-8") as fh: return json.load(fh) def test_sessions_presente_resuelve_y_escribe_role_preservando_otros_campos(tmp_path): sessions_dir = str(tmp_path / "sessions") goals_dir = str(tmp_path / "goals") pid = 4242 sid = "abc-123-uuid" _write_session(sessions_dir, pid, sid) # Goal preexistente con campos que NO deben perderse. _write_goal( goals_dir, sid, { "goal": "implementar fase 3", "phase": "trabajando", "dod": ["compila", "tests verdes"], "dod_contract": {"capa1": "mecanica"}, }, ) res = mark_claude_role(pid, "orchestrator", wait_s=2.0, sessions_dir=sessions_dir, goals_dir=goals_dir) assert res["ok"] is True assert res["pid"] == pid assert res["session_id"] == sid assert res["role"] == "orchestrator" assert res["path"] == os.path.join(goals_dir, f"{sid}.json") goal = _read_goal(goals_dir, sid) assert goal["role"] == "orchestrator" # Todos los demas campos del goal se preservan intactos. assert goal["goal"] == "implementar fase 3" assert goal["phase"] == "trabajando" assert goal["dod"] == ["compila", "tests verdes"] assert goal["dod_contract"] == {"capa1": "mecanica"} def test_role_invalido_lanza_value_error_sin_escribir(tmp_path): sessions_dir = str(tmp_path / "sessions") goals_dir = str(tmp_path / "goals") pid = 4242 sid = "abc-123-uuid" _write_session(sessions_dir, pid, sid) with pytest.raises(ValueError): mark_claude_role(pid, "supervisor", wait_s=2.0, sessions_dir=sessions_dir, goals_dir=goals_dir) # No escribio nada: el goals_dir ni siquiera deberia existir. assert not os.path.exists(goals_dir) def test_sessions_ausente_devuelve_timeout_sin_crash(tmp_path): sessions_dir = str(tmp_path / "sessions") goals_dir = str(tmp_path / "goals") pid = 9999 # sin sessions/.json escrito res = mark_claude_role(pid, "executor", wait_s=0.5, sessions_dir=sessions_dir, goals_dir=goals_dir) assert res["ok"] is False assert res["pid"] == pid assert "timeout" in res["error"] assert f"{pid}.json" in res["error"] # No se escribio ningun goal. assert not os.path.exists(goals_dir) def test_goal_inexistente_se_crea_con_solo_role(tmp_path): sessions_dir = str(tmp_path / "sessions") goals_dir = str(tmp_path / "goals") pid = 7 sid = "fresh-session-uuid" _write_session(sessions_dir, pid, sid) # No existe goal previo para esta sesion. res = mark_claude_role(pid, "executor", wait_s=2.0, sessions_dir=sessions_dir, goals_dir=goals_dir) assert res["ok"] is True assert res["session_id"] == sid assert res["role"] == "executor" goal = _read_goal(goals_dir, sid) assert goal == {"role": "executor"}