Spaces:
Running
Running
File size: 7,635 Bytes
af9cde9 fb88636 af9cde9 cd73917 af9cde9 | 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 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | """Tests for new database methods: user profile and scheduled medications."""
import pytest
from reachy_mini_conversation_app.database import MiniMinderDB
@pytest.fixture
def db() -> MiniMinderDB:
"""Create an in-memory database for testing."""
return MiniMinderDB(":memory:")
# -----------------------------------------------------------------------------
# User Profile Tests
# -----------------------------------------------------------------------------
def test_get_or_create_profile(db: MiniMinderDB) -> None:
"""Profile should be created on first access."""
profile = db.get_or_create_profile()
assert profile is not None
assert profile["id"] == 1
assert profile["onboarding_completed"] == 0
assert profile["onboarding_step"] == "name"
def test_get_or_create_profile_idempotent(db: MiniMinderDB) -> None:
"""Getting profile multiple times should return same data."""
profile1 = db.get_or_create_profile()
profile2 = db.get_or_create_profile()
assert profile1["id"] == profile2["id"]
assert profile1["created_at"] == profile2["created_at"]
def test_update_profile(db: MiniMinderDB) -> None:
"""Profile updates should persist."""
db.update_profile(
{
"display_name": "Alice",
"onboarding_completed": 1,
"onboarding_step": "done",
}
)
profile = db.get_or_create_profile()
assert profile["display_name"] == "Alice"
assert profile["onboarding_completed"] == 1
assert profile["onboarding_step"] == "done"
def test_is_onboarding_complete_default(db: MiniMinderDB) -> None:
"""Onboarding should not be complete by default."""
assert db.is_onboarding_complete() is False
def test_is_onboarding_complete_after_update(db: MiniMinderDB) -> None:
"""Onboarding should be complete after marking it."""
db.update_profile({"onboarding_completed": 1})
assert db.is_onboarding_complete() is True
# -----------------------------------------------------------------------------
# Scheduled Medications Tests
# -----------------------------------------------------------------------------
def test_add_scheduled_medication(db: MiniMinderDB) -> None:
"""Add and retrieve a scheduled medication."""
med_id = db.add_scheduled_medication(
{
"medication_name": "Ibuprofen",
"dose": "400mg",
"frequency": "twice daily",
"times_of_day": ["morning", "evening"],
}
)
assert med_id == 1
meds = db.get_scheduled_medications()
assert len(meds) == 1
assert meds[0]["medication_name"] == "Ibuprofen"
assert meds[0]["dose"] == "400mg"
assert meds[0]["times_of_day"] == ["morning", "evening"]
def test_add_multiple_medications(db: MiniMinderDB) -> None:
"""Add multiple medications."""
db.add_scheduled_medication({"medication_name": "Med A"})
db.add_scheduled_medication({"medication_name": "Med B"})
db.add_scheduled_medication({"medication_name": "Med C"})
meds = db.get_scheduled_medications()
assert len(meds) == 3
names = [m["medication_name"] for m in meds]
assert "Med A" in names
assert "Med B" in names
assert "Med C" in names
def test_scheduled_medication_with_reminders(db: MiniMinderDB) -> None:
"""Medications can have reminder times."""
db.add_scheduled_medication(
{
"medication_name": "Blood Pressure Med",
"reminder_enabled": 1,
"reminder_times": ["07:55", "19:55"],
}
)
meds = db.get_scheduled_medications()
assert len(meds) == 1
assert meds[0]["reminder_enabled"] == 1
assert meds[0]["reminder_times"] == ["07:55", "19:55"]
def test_update_scheduled_medication(db: MiniMinderDB) -> None:
"""Update an existing medication."""
med_id = db.add_scheduled_medication(
{
"medication_name": "Aspirin",
"dose": "100mg",
}
)
success = db.update_scheduled_medication(
med_id,
{
"dose": "200mg",
"frequency": "once daily",
},
)
assert success is True
meds = db.get_scheduled_medications()
assert meds[0]["dose"] == "200mg"
assert meds[0]["frequency"] == "once daily"
def test_deactivate_scheduled_medication(db: MiniMinderDB) -> None:
"""Deactivated medications should not appear in active list."""
med_id = db.add_scheduled_medication({"medication_name": "Old Med"})
success = db.deactivate_scheduled_medication(med_id)
assert success is True
# Should not appear in active list
active_meds = db.get_scheduled_medications(active_only=True)
assert len(active_meds) == 0
# Should appear in full list
all_meds = db.get_scheduled_medications(active_only=False)
assert len(all_meds) == 1
assert all_meds[0]["active"] == 0
def test_update_nonexistent_medication(db: MiniMinderDB) -> None:
"""Updating a nonexistent medication should return False."""
success = db.update_scheduled_medication(999, {"dose": "100mg"})
# Note: SQLite UPDATE returns 0 rows affected, so this returns False
assert success is False
# -----------------------------------------------------------------------------
# Upsert Scheduled Medication Tests
# -----------------------------------------------------------------------------
def test_upsert_scheduled_medication_new(db: MiniMinderDB) -> None:
"""Upsert should create a new row when no match exists."""
med_id, is_new = db.upsert_scheduled_medication(
{"medication_name": "Aspirin", "dose": "100mg"}
)
assert is_new is True
assert med_id >= 1
meds = db.get_scheduled_medications()
assert len(meds) == 1
assert meds[0]["medication_name"] == "Aspirin"
def test_upsert_scheduled_medication_existing(db: MiniMinderDB) -> None:
"""Upsert should update existing row and not create a duplicate."""
# First call: creates the row
med_id_1, is_new_1 = db.upsert_scheduled_medication(
{"medication_name": "Amitriptyline"}
)
assert is_new_1 is True
# Second call: same name, adds dose — should update
med_id_2, is_new_2 = db.upsert_scheduled_medication(
{"medication_name": "Amitriptyline", "dose": "10mg"}
)
assert is_new_2 is False
assert med_id_2 == med_id_1
# Third call: same name, adds frequency — should update again
med_id_3, is_new_3 = db.upsert_scheduled_medication(
{"medication_name": "Amitriptyline", "dose": "10mg", "frequency": "once daily"}
)
assert is_new_3 is False
assert med_id_3 == med_id_1
# Only one row should exist with all the merged data
meds = db.get_scheduled_medications()
assert len(meds) == 1
assert meds[0]["dose"] == "10mg"
assert meds[0]["frequency"] == "once daily"
def test_upsert_case_insensitive(db: MiniMinderDB) -> None:
"""Upsert should match medication names case-insensitively."""
db.upsert_scheduled_medication({"medication_name": "Aspirin"})
med_id, is_new = db.upsert_scheduled_medication(
{"medication_name": "aspirin", "dose": "200mg"}
)
assert is_new is False
meds = db.get_scheduled_medications()
assert len(meds) == 1
def test_schema_includes_new_tables(db: MiniMinderDB) -> None:
"""The new tables should exist."""
conn = db._get_conn()
tables = conn.execute(
"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"
).fetchall()
table_names = [t["name"] for t in tables]
assert "user_profile" in table_names
assert "scheduled_medications" in table_names
|