File size: 5,622 Bytes
f9609df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
"""
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")