import json def test_new_session_creates_folder_and_state(tmp_path): from core.session import new_session, load_state session_id = new_session("message", question="test question", base_dir=tmp_path) session_dir = tmp_path / session_id assert session_dir.is_dir() state = load_state(session_id, base_dir=tmp_path) assert state["session_id"] == session_id assert state["input_mode"] == "message" assert state["question"] == "test question" assert state["current_step"] == 0 assert state["bind_results"] == {} def test_new_session_chips_mode(tmp_path): from core.session import new_session, load_state session_id = new_session("chips", base_dir=tmp_path) state = load_state(session_id, base_dir=tmp_path) assert state["input_mode"] == "chips" assert state["question"] == "" def test_write_state_merges_patch(tmp_path): from core.session import new_session, write_state, load_state session_id = new_session("message", question="q", base_dir=tmp_path) write_state(session_id, {"current_step": 1, "route": {"sectors": ["WASH"]}}, base_dir=tmp_path) state = load_state(session_id, base_dir=tmp_path) assert state["current_step"] == 1 assert state["route"] == {"sectors": ["WASH"]} assert state["question"] == "q" # untouched field preserved def test_write_state_deep_merges_bind_results(tmp_path): from core.session import new_session, write_state, load_state session_id = new_session("message", question="q", base_dir=tmp_path) write_state(session_id, {"bind_results": {"rcsi": {"verdict": "PROXY"}}}, base_dir=tmp_path) write_state(session_id, {"bind_results": {"fcs": {"verdict": "NOT_MEASURABLE"}}}, base_dir=tmp_path) state = load_state(session_id, base_dir=tmp_path) assert "rcsi" in state["bind_results"] assert "fcs" in state["bind_results"] def test_write_state_is_atomic(tmp_path): """state.json should never be in a partial-write state.""" from core.session import new_session, write_state session_id = new_session("message", question="q", base_dir=tmp_path) write_state(session_id, {"current_step": 2}, base_dir=tmp_path) state_file = tmp_path / session_id / "state.json" # No .tmp file should remain after write assert not (tmp_path / session_id / "state.json.tmp").exists() # state.json is valid JSON json.loads(state_file.read_text())