from __future__ import annotations import tempfile import unittest from datetime import datetime, timedelta from pathlib import Path from mr_reachy.medication import MedicationMemory, build_plan from mr_reachy.reminders import confirm_due_dose, process_due_reminders from mr_reachy.storage import HybridMedicationStore, LocalMedicationStore def _store_with_due_plan(tmp: str) -> tuple[HybridMedicationStore, datetime]: now = datetime(2026, 5, 28, 9, 5).astimezone() plan = build_plan( raw_instruction="Take metformin once a day for one day.", medication_name="metformin", frequency_per_day=1, duration_days=1, dose_times=["09:00"], now=now, ) store = HybridMedicationStore(LocalMedicationStore(Path(tmp) / "memory.json"), auto_sync=False) store.save(MedicationMemory(plans=[plan])) return store, now class ReminderTest(unittest.TestCase): def test_due_dose_triggers_reminder(self) -> None: with tempfile.TemporaryDirectory() as tmp: store, now = _store_with_due_plan(tmp) replies = [] changed = process_due_reminders(store=store, notify=replies.append, now=now) memory = store.load() self.assertTrue(changed) self.assertEqual(len(replies), 1) self.assertIn("metformin", replies[0].speech) self.assertEqual(memory.plans[0].doses[0].reminder_count, 1) def test_confirmation_marks_due_dose_complete(self) -> None: with tempfile.TemporaryDirectory() as tmp: store, now = _store_with_due_plan(tmp) confirmed, message = confirm_due_dose(store, now=now) memory = store.load() self.assertTrue(confirmed) self.assertIn("metformin", message) self.assertEqual(memory.plans[0].doses[0].status, "confirmed") def test_missed_dose_after_three_reminders(self) -> None: with tempfile.TemporaryDirectory() as tmp: store, now = _store_with_due_plan(tmp) memory = store.load() dose = memory.plans[0].doses[0] dose.reminder_count = 3 dose.last_reminded_at = (now - timedelta(minutes=10)).isoformat() store.save(memory) replies = [] changed = process_due_reminders(store=store, notify=replies.append, now=now) updated = store.load() self.assertTrue(changed) self.assertEqual(updated.plans[0].doses[0].status, "missed") self.assertEqual(replies[0].emotion, "sad") if __name__ == "__main__": unittest.main()