File size: 1,560 Bytes
0366d65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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