""" Unit tests for participants.py — pure/stdlib-only, no camera or webview needed. Every test gets its own tmp_path as owner_dir. """ import os import pytest import participants # --- create_participant ------------------------------------------------- def test_create_participant_rejects_empty_name(tmp_path): with pytest.raises(participants.ParticipantError): participants.create_participant(str(tmp_path), " ") def test_create_participant_returns_expected_fields(tmp_path): record = participants.create_participant(str(tmp_path), "Rahul", "left-handed") assert record["name"] == "Rahul" assert record["notes"] == "left-handed" assert record["session_count"] == 0 assert record["last_session_at"] is None assert "id" in record and "created_at" in record def test_create_participant_strips_whitespace(tmp_path): record = participants.create_participant(str(tmp_path), " Rahul ", " notes ") assert record["name"] == "Rahul" assert record["notes"] == "notes" def test_create_participant_persists_to_disk(tmp_path): record = participants.create_participant(str(tmp_path), "Rahul") profile_path = os.path.join(str(tmp_path), "participants", record["id"], "profile.json") assert os.path.exists(profile_path) # --- get_participant / list_participants --------------------------------- def test_get_participant_returns_none_for_missing(tmp_path): assert participants.get_participant(str(tmp_path), "does-not-exist") is None def test_get_participant_returns_none_for_falsy_id(tmp_path): assert participants.get_participant(str(tmp_path), "") is None assert participants.get_participant(str(tmp_path), None) is None def test_get_participant_roundtrips(tmp_path): created = participants.create_participant(str(tmp_path), "Rahul") fetched = participants.get_participant(str(tmp_path), created["id"]) assert fetched == created def test_list_participants_sorted_by_name(tmp_path): participants.create_participant(str(tmp_path), "Zara") participants.create_participant(str(tmp_path), "Aman") names = [p["name"] for p in participants.list_participants(str(tmp_path))] assert names == ["Aman", "Zara"] def test_list_participants_empty_when_none_created(tmp_path): assert participants.list_participants(str(tmp_path)) == [] # --- update_participant --------------------------------------------------- def test_update_participant_changes_name_and_notes(tmp_path): created = participants.create_participant(str(tmp_path), "Rahul", "old notes") updated = participants.update_participant(str(tmp_path), created["id"], name="Rahul K", notes="new notes") assert updated["name"] == "Rahul K" assert updated["notes"] == "new notes" def test_update_participant_leaves_untouched_field_when_none(tmp_path): created = participants.create_participant(str(tmp_path), "Rahul", "keep me") updated = participants.update_participant(str(tmp_path), created["id"], name="Rahul K", notes=None) assert updated["name"] == "Rahul K" assert updated["notes"] == "keep me" def test_update_participant_rejects_empty_name(tmp_path): created = participants.create_participant(str(tmp_path), "Rahul") with pytest.raises(participants.ParticipantError): participants.update_participant(str(tmp_path), created["id"], name=" ") def test_update_participant_rejects_missing_participant(tmp_path): with pytest.raises(participants.ParticipantError): participants.update_participant(str(tmp_path), "does-not-exist", name="X") def test_update_participant_preserves_session_stats(tmp_path): created = participants.create_participant(str(tmp_path), "Rahul") participants.touch_session_stats(str(tmp_path), created["id"]) updated = participants.update_participant(str(tmp_path), created["id"], name="Rahul K") assert updated["session_count"] == 1 # --- delete_participant --------------------------------------------------- def test_delete_participant_removes_folder(tmp_path): created = participants.create_participant(str(tmp_path), "Rahul") pdir = participants.participant_dir(str(tmp_path), created["id"]) assert os.path.isdir(pdir) participants.delete_participant(str(tmp_path), created["id"]) assert not os.path.exists(pdir) assert participants.get_participant(str(tmp_path), created["id"]) is None def test_delete_participant_rejects_missing_participant(tmp_path): with pytest.raises(participants.ParticipantError): participants.delete_participant(str(tmp_path), "does-not-exist") def test_delete_participant_rejects_falsy_id(tmp_path): with pytest.raises(participants.ParticipantError): participants.delete_participant(str(tmp_path), "") # --- touch_session_stats --------------------------------------------------- def test_touch_session_stats_increments_count_and_sets_timestamp(tmp_path): created = participants.create_participant(str(tmp_path), "Rahul") assert created["session_count"] == 0 participants.touch_session_stats(str(tmp_path), created["id"]) updated = participants.get_participant(str(tmp_path), created["id"]) assert updated["session_count"] == 1 assert updated["last_session_at"] is not None def test_touch_session_stats_noop_for_missing_participant(tmp_path): # Should not raise -- just silently does nothing, since the caller # (browser_session.py's _write_session_meta) has already committed to # the session by this point and shouldn't crash a session over it. participants.touch_session_stats(str(tmp_path), "does-not-exist")