jarvis-assist/Claude outputs/tests/test_calendar.py

176 lines
6.1 KiB
Python

import os
import sys
from datetime import datetime, date
from unittest.mock import MagicMock, patch
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
import main
class _Val:
def __init__(self, v):
self.dt = v
def _fake_component(summary, dtstart_value, dtend_value, description="", uid="uid-1"):
comp = {}
comp["summary"] = summary
comp["description"] = description
comp["uid"] = uid
comp["dtstart"] = _Val(dtstart_value)
comp["dtend"] = _Val(dtend_value)
def get(key, default=None):
return comp.get(key, default)
fake = MagicMock()
fake.get = get
return fake
class _MutableComponent(dict):
def get(self, key, default=None):
return super().get(key, default)
def test_list_upcoming_events_maps_timed_and_all_day_events():
timed = MagicMock()
timed.icalendar_component = _fake_component(
"THL FM LS", datetime(2026, 9, 14, 19, 0, 0), datetime(2026, 9, 14, 20, 0, 0)
)
all_day = MagicMock()
all_day.icalendar_component = _fake_component(
"Volksfestwache", date(2026, 9, 19), date(2026, 9, 20)
)
fake_calendar = MagicMock()
fake_calendar.search.return_value = [all_day, timed] # unsorted on purpose
with patch.object(main, "_caldav_calendar", return_value=fake_calendar):
events = main._list_upcoming_events_sync(14, calendar="feuerwehr")
assert [e["summary"] for e in events] == ["THL FM LS", "Volksfestwache"]
assert events[0]["all_day"] is False
assert events[1]["all_day"] is True
assert events[0]["uid"] == "uid-1"
assert events[0]["calendar"] == "feuerwehr"
def test_list_upcoming_events_merges_both_calendars_when_none_given():
personal_event = MagicMock()
personal_event.icalendar_component = _fake_component(
"Zahnarzt", datetime(2026, 9, 14, 9, 0, 0), datetime(2026, 9, 14, 9, 30, 0), uid="uid-p"
)
ffw_event = MagicMock()
ffw_event.icalendar_component = _fake_component(
"Einsatz", datetime(2026, 9, 14, 10, 0, 0), datetime(2026, 9, 14, 11, 0, 0), uid="uid-f"
)
def fake_caldav_calendar(calendar=main.DEFAULT_CALENDAR):
cal = MagicMock()
cal.search.return_value = [personal_event] if calendar == "personal" else [ffw_event]
return cal
with patch.object(main, "_caldav_calendar", side_effect=fake_caldav_calendar):
events = main._list_upcoming_events_sync(14)
assert [e["uid"] for e in events] == ["uid-p", "uid-f"]
assert [e["calendar"] for e in events] == ["personal", "feuerwehr"]
def test_create_event_calls_save_event_with_parsed_dates():
fake_calendar = MagicMock()
with patch.object(main, "_caldav_calendar", return_value=fake_calendar):
result = main._create_event_sync(
"JARVIS Testtermin", "2026-09-20T10:00:00", "2026-09-20T11:00:00", "desc"
)
fake_calendar.save_event.assert_called_once()
_, kwargs = fake_calendar.save_event.call_args
assert kwargs["summary"] == "JARVIS Testtermin"
assert kwargs["dtstart"] == datetime(2026, 9, 20, 10, 0, 0, tzinfo=main.CALENDAR_TIMEZONE)
assert kwargs["dtstart"].tzinfo is not None
assert result["summary"] == "JARVIS Testtermin"
assert result["calendar"] == "personal"
def test_create_event_passes_calendar_argument_through():
fake_calendar = MagicMock()
with patch.object(main, "_caldav_calendar", return_value=fake_calendar) as mock_get_calendar:
result = main._create_event_sync(
"Einsatz", "2026-09-20T10:00:00", "2026-09-20T11:00:00", calendar="feuerwehr"
)
mock_get_calendar.assert_called_once_with("feuerwehr")
assert result["calendar"] == "feuerwehr"
def test_update_event_moves_and_renames_by_uid():
comp = _MutableComponent()
comp["dtstart"] = _Val(datetime(2026, 9, 27, 10, 0, 0))
comp["dtend"] = _Val(datetime(2026, 9, 27, 11, 0, 0))
comp["summary"] = "Old"
comp["description"] = "old desc"
fake_event = MagicMock()
fake_event.icalendar_component = comp
fake_calendar = MagicMock()
fake_calendar.event_by_uid.return_value = fake_event
with patch.object(main, "_caldav_calendar", return_value=fake_calendar):
result = main._update_event_sync("uid-123", start="2026-09-28T14:00:00", summary="New")
fake_calendar.event_by_uid.assert_called_once_with("uid-123")
fake_event.save.assert_called_once()
assert comp["dtstart"].dt == datetime(2026, 9, 28, 14, 0, 0, tzinfo=main.CALENDAR_TIMEZONE)
assert comp["dtend"].dt == datetime(2026, 9, 27, 11, 0, 0) # untouched - not passed
assert comp["summary"] == "New"
assert comp["description"] == "old desc" # untouched - not passed
assert result["uid"] == "uid-123"
def test_update_event_passes_calendar_argument_through():
comp = _MutableComponent()
comp["dtstart"] = _Val(datetime(2026, 9, 27, 10, 0, 0))
comp["dtend"] = _Val(datetime(2026, 9, 27, 11, 0, 0))
comp["summary"] = "Old"
comp["description"] = "old desc"
fake_event = MagicMock()
fake_event.icalendar_component = comp
fake_calendar = MagicMock()
fake_calendar.event_by_uid.return_value = fake_event
with patch.object(main, "_caldav_calendar", return_value=fake_calendar) as mock_get_calendar:
main._update_event_sync("uid-123", summary="New", calendar="feuerwehr")
mock_get_calendar.assert_called_once_with("feuerwehr")
def test_delete_event_by_uid():
fake_event = MagicMock()
fake_calendar = MagicMock()
fake_calendar.event_by_uid.return_value = fake_event
with patch.object(main, "_caldav_calendar", return_value=fake_calendar):
result = main._delete_event_sync("uid-456")
fake_calendar.event_by_uid.assert_called_once_with("uid-456")
fake_event.delete.assert_called_once()
assert result == {"deleted": True, "uid": "uid-456"}
def test_delete_event_passes_calendar_argument_through():
fake_event = MagicMock()
fake_calendar = MagicMock()
fake_calendar.event_by_uid.return_value = fake_event
with patch.object(main, "_caldav_calendar", return_value=fake_calendar) as mock_get_calendar:
main._delete_event_sync("uid-456", calendar="feuerwehr")
mock_get_calendar.assert_called_once_with("feuerwehr")