Skip to content
Snippets Groups Projects
test_services.py 3.16 KiB
Newer Older
from datetime import datetime

import pytest

from django.utils.timezone import make_aware
from program.models import TimeSlot
from program.services import generate_conflicts
from program.tests.factories import TimeslotFactory

pytestmark = pytest.mark.django_db


def create_timeslot(once_schedule) -> None:
    """creates and saves a timeslot instance for a "once" schedule for 2024-05-21 16:00-18:00."""

    TimeslotFactory.create(
        start=make_aware(datetime(2024, 5, 21, 16, 0)),
        end=make_aware(datetime(2024, 5, 21, 18, 0)),
        schedule=once_schedule,
    )


def build_timeslot(once_schedule, start: tuple[int, int], end: tuple[int, int]) -> TimeSlot:
    """builds and returns a timeslot object for a "once" schedule for 2020-05-21 `start`-`end`."""

    start_hour, start_minute = start
    end_hour, end_minute = end

    return TimeslotFactory.build(
        start=make_aware(datetime(2024, 5, 21, start_hour, start_minute)),
        end=make_aware(datetime(2024, 5, 21, end_hour, end_minute)),
        schedule=once_schedule,
    )


def test_generate_conflicts_partially_overlapping_end(once_schedule):
    create_timeslot(once_schedule)  # 16:00 - 18:00
    # Partly overlapping timeslot: start before existing start, end before existing end
    timeslots = [build_timeslot(once_schedule, start=(15, 30), end=(17, 30))]

    conflicts = generate_conflicts(timeslots)

    assert "theirs-end" and "ours-end" in conflicts["projected"][0]["solution_choices"]


def test_generate_conflicts_partially_overlapping_start(once_schedule):
    create_timeslot(once_schedule)  # 16:00 - 18:00
    # Partly overlapping timeslots: start after existing start, end after existing end
    timeslots = [build_timeslot(once_schedule, start=(16, 30), end=(18, 30))]

    conflicts = generate_conflicts(timeslots)

    assert "theirs-start" and "ours-start" in conflicts["projected"][0]["solution_choices"]


def test_generate_conflicts_fully_overlapping_theirs(once_schedule):
    create_timeslot(once_schedule)  # 16:00 - 18:00
    # Fully overlapping timeslot: start before existing start, end after existing end
    timeslots = [build_timeslot(once_schedule, start=(15, 30), end=(18, 30))]

    conflicts = generate_conflicts(timeslots)

    assert (
        "theirs-end"
        and "theirs-start"
        and "theirs-both" in conflicts["projected"][0]["solution_choices"]
    )


def test_generate_conflicts_fully_overlapping_ours(once_schedule):
    create_timeslot(once_schedule)  # 16:00 - 18:00
    # Fully overlapping: start after existing start, end before existing end
    timeslots = [build_timeslot(once_schedule, start=(16, 30), end=(17, 30))]

    conflicts = generate_conflicts(timeslots)

    assert (
        "ours-end"
        and "ours-start"
        and "ours-both" in conflicts["projected"][0]["solution_choices"]
    )


def test_generate_conflicts_overlapping_ours_theirs(once_schedule):
    create_timeslot(once_schedule)  # 16:00 - 18:00
    # Fully overlapping: starts and ends are equal
    timeslots = [build_timeslot(once_schedule, start=(16, 0), end=(18, 0))]

    conflicts = generate_conflicts(timeslots)

    assert "ours" and "theirs" in conflicts["projected"][0]["solution_choices"]