Spaces:
Sleeping
Sleeping
| from datetime import datetime, timedelta | |
| from calendar_out.freebusy import ( | |
| annotate_conflicts, | |
| check_conflicts, | |
| load_ics_busy, | |
| propose_times, | |
| ) | |
| from calendar_out.ics import events_to_ics | |
| from server.schema import ActionPlan, Event | |
| def _event_at(hour, minutes=60): | |
| start = (datetime.now() + timedelta(days=1)).replace( | |
| hour=hour, minute=0, second=0, microsecond=0 | |
| ) | |
| return Event(title="Lunch", start=start.isoformat(), | |
| end=(start + timedelta(minutes=minutes)).isoformat()) | |
| def _busy_overlapping(ev): | |
| start = datetime.fromisoformat(ev.start) | |
| clash = Event(title="Standup", start=start.isoformat(), | |
| end=(start + timedelta(minutes=30)).isoformat()) | |
| return load_ics_busy(events_to_ics([clash])) | |
| def test_overlap_detected_and_alternatives_proposed(): | |
| ev = _event_at(13) | |
| busy = _busy_overlapping(ev) | |
| conflicts = check_conflicts([ev], busy) | |
| assert conflicts and conflicts[0].severity == "overlap" | |
| alts = propose_times(ev, busy) | |
| assert alts # non-empty alternatives | |
| def test_clear_calendar_has_no_conflicts(): | |
| ev = _event_at(13) | |
| far = Event(title="Faraway", | |
| start=(datetime.fromisoformat(ev.start) + timedelta(days=10)).isoformat()) | |
| busy = load_ics_busy(events_to_ics([far])) | |
| assert check_conflicts([ev], busy) == [] | |
| def test_annotate_fills_plan(): | |
| ev = _event_at(13) | |
| plan = ActionPlan(events=[ev]) | |
| plan = annotate_conflicts(plan, _busy_overlapping(ev)) | |
| assert plan.conflicts and plan.proposed_times | |