def test_replace_availabilities(availabilitiesform):
    instance = Room.objects.create(event_id=availabilitiesform.event.id)
    Availability.objects.bulk_create([
        Availability(room_id=instance.id,
                     event_id=availabilitiesform.event.id,
                     start=datetime.datetime(2017, 1, 1, 10),
                     end=datetime.datetime(2017, 1, 1, 12)),
        Availability(room_id=instance.id,
                     event_id=availabilitiesform.event.id,
                     start=datetime.datetime(2017, 1, 2, 10),
                     end=datetime.datetime(2017, 1, 2, 15)),
    ])

    expected = [
        Availability(room_id=instance.id,
                     event_id=availabilitiesform.event.id,
                     start=datetime.datetime(2017, 1, 1, 12, tzinfo=pytz.utc),
                     end=datetime.datetime(2017, 1, 1, 12)),
        Availability(room_id=instance.id,
                     event_id=availabilitiesform.event.id,
                     start=datetime.datetime(2017, 1, 2, 12, tzinfo=pytz.utc),
                     end=datetime.datetime(2017, 1, 2, 15)),
    ]

    availabilitiesform._replace_availabilities(instance, expected)

    actual = instance.availabilities.all()
    for act, exp in zip(actual, expected):
        assert act.start == exp.start
def test_availability_equality():
    avail = Availability(start=dt.datetime(2017, 1, 1, 5),
                         end=dt.datetime(2017, 1, 1, 7))
    avail2 = Availability(start=dt.datetime(2017, 1, 1, 5),
                          end=dt.datetime(2017, 1, 1, 7))
    assert "None" in str(avail)

    assert avail == avail2
Exemple #3
0
def test_equality():
    avail = Availability(start=datetime.datetime(2017, 1, 1, 5),
                         end=datetime.datetime(2017, 1, 1, 7)),
    avail2 = Availability(start=datetime.datetime(2017, 1, 1, 5),
                          end=datetime.datetime(2017, 1, 1, 7)),

    assert avail == avail2
    assert avail != 'avail2'
Exemple #4
0
def test_equality(event):
    avail = Availability(start=datetime.datetime(2017, 1, 1, 5),
                         end=datetime.datetime(2017, 1, 1, 7)),
    avail2 = Availability(start=datetime.datetime(2017, 1, 1, 5),
                          end=datetime.datetime(2017, 1, 1, 7)),
    assert 'None' in str(avail)

    assert avail == avail2
def test_intersection(availsets, expected):
    actual1 = Availability.intersection(*availsets)
    actual2 = Availability.intersection(*reversed(availsets))

    assert len(actual1) == len(expected)
    assert len(actual2) == len(expected)

    for act1, act2, exp in zip(actual1, actual2, expected):
        assert act1.start == act2.start == exp.start
        assert act1.end == act2.end == exp.end
def test_set_foreignkeys(availabilitiesform, instancegen, fk_name):
    availabilities = [
        Availability(start=datetime.datetime(2017, 1, 1, 10), end=datetime.datetime(2017, 1, 1, 12)),
        Availability(start=datetime.datetime(2017, 1, 2, 10), end=datetime.datetime(2017, 1, 2, 15)),
    ]
    instance = instancegen(availabilitiesform.event.id)
    availabilitiesform._set_foreignkeys(instance, availabilities)

    for avail in availabilities:
        assert getattr(avail, fk_name) == instance.id
def test_overlaps(one, two, expected_strict, expected):
    one = Availability(start=datetime.datetime(*one[0]), end=datetime.datetime(*one[1]))
    two = Availability(start=datetime.datetime(*two[0]), end=datetime.datetime(*two[1]))

    def test(strict, expected):
        nonlocal one, two
        actual1 = one.overlaps(two, strict)
        actual2 = two.overlaps(one, strict)
        assert expected == actual1
        assert expected == actual2

    test(True, expected_strict)
    test(False, expected)
def test_availability_fail(method, args, expected):
    avail = Availability(start=datetime.datetime(2017, 1, 1), end=datetime.datetime(2017, 1, 1, 1))

    with pytest.raises(Exception) as excinfo:
        method(avail, *args)

    assert expected in str(excinfo)
Exemple #9
0
    def as_availability(self):
        """ 'Casts' a slot as availability, useful for availability arithmetics. """
        from pretalx.schedule.models import Availability

        return Availability(start=self.start,
                            end=self.real_end,
                            event=self.submission.event)
Exemple #10
0
def test_union(avails, expected):
    actual = Availability.union(avails)

    assert len(actual) == len(expected)

    for act, exp in zip(actual, expected):
        assert act.start == exp.start
        assert act.end == exp.end
Exemple #11
0
def test_availability_str_person_room(room, speaker):
    actual = str(Availability(
        start=datetime.datetime(2017, 1, 1, 0),
        end=datetime.datetime(2017, 1, 1, 5),
        person=speaker.profiles.first(),
        room=room,
    ))
    assert 'room=Roomy' in actual
    assert 'person=Jane Speaker' in actual
Exemple #12
0
def test_availability_str_person_room(room, speaker):
    actual = str(Availability(
        start=datetime.datetime(2017, 1, 1, 0),
        end=datetime.datetime(2017, 1, 1, 5),
        person=speaker.profiles.first(),
        room=room,
    ))
    assert f'room={room.name}' in actual
    assert f'person={speaker.name}' in actual
Exemple #13
0
def availability(event):
    return Availability(
        event=event,
        start=datetime.datetime.combine(event.date_from,
                                        datetime.time.min,
                                        tzinfo=pytz.utc),
        end=datetime.datetime.combine(event.date_to,
                                      datetime.time.max,
                                      tzinfo=pytz.utc),
    )
Exemple #14
0
    def clean_availabilities(self):
        if self.cleaned_data['availabilities'] == '':
            return None

        rawavailabilities = self._parse_availabilities_json(self.cleaned_data['availabilities'])
        availabilities = []

        for rawavail in rawavailabilities:
            self._validate_availability(rawavail)
            availabilities.append(Availability(event_id=self.event.id, **rawavail))

        return availabilities
Exemple #15
0
    def as_availability(self):
        """'Casts' a slot as.

        :class:`~pretalx.schedule.models.availability.Availability`, useful for
        availability arithmetic.
        """
        from pretalx.schedule.models import Availability

        return Availability(
            start=self.start,
            end=self.real_end,
        )
Exemple #16
0
 def get(self, request, event, talkid, roomid):
     talk = request.event.wip_schedule.talks.filter(pk=talkid).first()
     room = request.event.rooms.filter(pk=roomid).first()
     if not (talk and room):
         return JsonResponse({'results': []})
     if talk.submission.availabilities:
         availabilitysets = [
             room.availabilities.all(),
             talk.submission.availabilities,
         ]
         availabilities = Availability.intersection(*availabilitysets)
     else:
         availabilities = room.availabilities.all()
     return JsonResponse(
         {'results': [avail.serialize() for avail in availabilities]})
Exemple #17
0
 def get(self, request, event, talkid, roomid):
     talk = request.event.wip_schedule.talks.filter(pk=talkid).first()
     room = request.event.rooms.filter(pk=roomid).first()
     if not (talk and room):
         return JsonResponse({"results": []})
     if talk.submission and talk.submission.availabilities:
         availabilitysets = [
             room.availabilities.all(),
             talk.submission.availabilities,
         ]
         availabilities = Availability.intersection(*availabilitysets)
     else:
         availabilities = room.availabilities.all()
     return JsonResponse(
         {"results": AvailabilitySerializer(availabilities, many=True).data}
     )
Exemple #18
0
def test_availability_equality(event):
    avail = Availability(start=datetime.datetime(2017, 1, 1, 5), end=datetime.datetime(2017, 1, 1, 7))
    avail2 = Availability(start=datetime.datetime(2017, 1, 1, 5), end=datetime.datetime(2017, 1, 1, 7))
    assert 'None' in str(avail)

    assert avail == avail2

    avail.event = event
    assert hash(avail) != hash(avail2)

    avail2.event = event
    assert hash(avail) == hash(avail2)
Exemple #19
0
    def clean_availabilities(self):
        data = self.cleaned_data.get('availabilities')
        required = (
            'availabilities' in self.fields and self.fields['availabilities'].required
        )
        if not data:
            if required:
                raise forms.ValidationError(_('Please fill in your availabilities!'))
            return None

        rawavailabilities = self._parse_availabilities_json(data)
        availabilities = []

        for rawavail in rawavailabilities:
            self._validate_availability(rawavail)
            availabilities.append(Availability(event_id=self.event.id, **rawavail))
        if not availabilities and required:
            raise forms.ValidationError(_('Please fill in your availabilities!'))
        return availabilities
Exemple #20
0
    def get(self, request, event, talkid, roomid):
        talk = request.event.wip_schedule.talks.get(pk=talkid)
        room = request.event.rooms.get(pk=roomid)

        availabilitysets = [
            room.availabilities.all(),
            *[
                speaker.profiles.filter(
                    event=request.event).first().availabilities.all()
                for speaker in talk.submission.speakers.all()
                if speaker.profiles.filter(event=request.event).exists()
            ],
        ]

        availabilities = Availability.intersection(*availabilitysets)

        return JsonResponse({
            'results': [avail.serialize() for avail in availabilities],
        })
Exemple #21
0
    def clean_availabilities(self):
        data = self.cleaned_data.get("availabilities")
        required = ("availabilities" in self.fields
                    and self.fields["availabilities"].required)
        if not data:
            if required:
                raise forms.ValidationError(
                    _("Please fill in your availability!"))
            return None

        rawavailabilities = (self.data["availabilities"] if isinstance(
            self.data.get("availabilities"), list) else
                             self._parse_availabilities_json(data))
        availabilities = []

        for rawavail in rawavailabilities:
            self._validate_availability(rawavail)
            availabilities.append(
                Availability(event_id=self.event.id, **rawavail))
        if not availabilities and required:
            raise forms.ValidationError(_("Please fill in your availability!"))
        return availabilities
    ('{"availabilities": [1]}', 'format'),
))
def test_clean_availabilities_fail(availabilitiesform, json, error):
    with pytest.raises(ValidationError) as excinfo:
        availabilitiesform.cleaned_data = {'availabilities': json}
        availabilitiesform.clean_availabilities()

    assert error in str(excinfo.value)


@pytest.mark.django_db
@pytest.mark.parametrize('json,expected', (
    ('{"availabilities": []}', []),
    ('{"availabilities": [{"start": "2017-01-01 10:00:00", "end": "2017-01-01 12:00:00"},'
     '{"start": "2017-01-02 11:00:00", "end": "2017-01-02 13:00:00"}]}', [
         Availability(start=datetime.datetime(2017, 1, 1, 10),
                      end=datetime.datetime(2017, 1, 1, 12)),
         Availability(start=datetime.datetime(2017, 1, 2, 11),
                      end=datetime.datetime(2017, 1, 2, 13)),
     ]),
))
def test_clean_availabilities_success(availabilitiesform, json, expected):
    availabilitiesform.cleaned_data = {'availabilities': json}
    actual = availabilitiesform.clean_availabilities()

    assert len(actual) == len(expected)

    for act, exp in zip(actual, expected):
        assert act.start.replace(tzinfo=None) == exp.start
        assert act.end.replace(tzinfo=None) == exp.end
        assert act.event_id == availabilitiesform.event.id
        assert act.id is None
Exemple #23
0
def test_availability_contains(one, two, expected):
    one = Availability(start=datetime.datetime(*one[0]), end=datetime.datetime(*one[1]))
    two = Availability(start=datetime.datetime(*two[0]), end=datetime.datetime(*two[1]))
    assert one.contains(two) is expected
        nonlocal one, two
        actual1 = one.overlaps(two, strict)
        actual2 = two.overlaps(one, strict)
        assert expected == actual1
        assert expected == actual2

    test(True, expected_strict)
    test(False, expected)


@pytest.mark.parametrize(
    "one,two,expected",
    (
        (
            # real overlap
            Availability(start=dt.datetime(2017, 1, 1, 4),
                         end=dt.datetime(2017, 1, 1, 7)),
            Availability(start=dt.datetime(2017, 1, 1, 5),
                         end=dt.datetime(2017, 1, 1, 9)),
            Availability(start=dt.datetime(2017, 1, 1, 4),
                         end=dt.datetime(2017, 1, 1, 9)),
        ),
        (
            # just adjacent
            Availability(start=dt.datetime(2017, 1, 1, 4),
                         end=dt.datetime(2017, 1, 1, 7)),
            Availability(start=dt.datetime(2017, 1, 1, 7),
                         end=dt.datetime(2017, 1, 1, 8)),
            Availability(start=dt.datetime(2017, 1, 1, 4),
                         end=dt.datetime(2017, 1, 1, 8)),
        ),
    ),
Exemple #25
0
def test_availability_str_person(speaker):
    assert f'person={speaker.name}' in str(Availability(
        start=datetime.datetime(2017, 1, 1, 0),
        end=datetime.datetime(2017, 1, 1, 5),
        person=speaker.profiles.first(),
    ))
Exemple #26
0
def test_availability_str_event(event):
    assert f'event={event.name}' in str(Availability(
        start=datetime.datetime(2017, 1, 1, 0),
        end=datetime.datetime(2017, 1, 1, 5),
        event=event
    ))
Exemple #27
0
    def get_talk_warnings(
        self,
        talk,
        with_speakers=True,
        room_avails=None,
        speaker_avails=None,
    ) -> list:
        """A list of warnings that apply to this slot.

        Warnings are dictionaries with a ``type`` (``room`` or
        ``speaker``, for now) and a ``message`` fit for public display.
        This property only shows availability based warnings.
        """
        from pretalx.schedule.models import Availability, TalkSlot

        if not talk.start or not talk.submission:
            return []
        warnings = []
        availability = talk.as_availability
        if talk.room:
            if room_avails is None:
                room_avails = talk.room.availabilities.all()
            if not any(
                    room_availability.contains(availability)
                    for room_availability in Availability.union(room_avails)):
                warnings.append({
                    "type":
                    "room",
                    "message":
                    _("The room is not available at the scheduled time."),
                })
        for speaker in talk.submission.speakers.all():
            if with_speakers:
                profile = speaker.event_profile(event=self.event)
                if speaker_avails is not None:
                    profile_availabilities = speaker_avails.get(profile.pk)
                else:
                    profile_availabilities = list(profile.availabilities.all())
                if profile_availabilities and not any(
                        speaker_availability.contains(availability)
                        for speaker_availability in Availability.union(
                            profile_availabilities)):
                    warnings.append({
                        "type":
                        "speaker",
                        "speaker": {
                            "name": speaker.get_display_name(),
                            "id": speaker.pk,
                        },
                        "message":
                        _("A speaker is not available at the scheduled time."),
                    })
            overlaps = (TalkSlot.objects.filter(
                schedule=self, submission__speakers__in=[speaker]).filter(
                    models.Q(start__lt=talk.start, end__gt=talk.start)
                    | models.Q(start__lt=talk.real_end, end__gt=talk.real_end)
                    | models.Q(start__gt=talk.start, end__lt=talk.real_end)).
                        exists())
            if overlaps:
                warnings.append({
                    "type":
                    "speaker",
                    "speaker": {
                        "name": speaker.get_display_name(),
                        "id": speaker.pk,
                    },
                    "message":
                    _("A speaker is holding another session at the scheduled time."
                      ),
                })

        return warnings
Exemple #28
0
    def test(strict, expected):
        nonlocal one, two
        actual1 = one.overlaps(two, strict)
        actual2 = two.overlaps(one, strict)
        assert expected == actual1
        assert expected == actual2

    test(True, expected_strict)
    test(False, expected)


@pytest.mark.django_db
@pytest.mark.parametrize('one,two,expected', (
    (
        # real overlap
        Availability(start=datetime.datetime(2017, 1, 1, 4), end=datetime.datetime(2017, 1, 1, 7)),
        Availability(start=datetime.datetime(2017, 1, 1, 5), end=datetime.datetime(2017, 1, 1, 9)),
        Availability(start=datetime.datetime(2017, 1, 1, 4), end=datetime.datetime(2017, 1, 1, 9)),
    ),
    (
        # just adjacent
        Availability(start=datetime.datetime(2017, 1, 1, 4), end=datetime.datetime(2017, 1, 1, 7)),
        Availability(start=datetime.datetime(2017, 1, 1, 7), end=datetime.datetime(2017, 1, 1, 8)),
        Availability(start=datetime.datetime(2017, 1, 1, 4), end=datetime.datetime(2017, 1, 1, 8)),
    ),
))
def test_merge_with(one, two, expected):
    actual1 = one.merge_with(two)
    actual2 = two.merge_with(one)
    actual1_magic = one | two
    actual2_magic = two | one
        availabilitiesform.cleaned_data = {"availabilities": json}
        availabilitiesform.clean_availabilities()

    assert error in str(excinfo.value)


@pytest.mark.django_db
@pytest.mark.parametrize(
    "json,expected",
    (
        ('{"availabilities": []}', []),
        (
            '{"availabilities": [{"start": "2017-01-01 10:00:00", "end": "2017-01-01 12:00:00"},'
            '{"start": "2017-01-02 11:00:00", "end": "2017-01-02 13:00:00"}]}',
            [
                Availability(start=dt.datetime(2017, 1, 1, 10),
                             end=dt.datetime(2017, 1, 1, 12)),
                Availability(start=dt.datetime(2017, 1, 2, 11),
                             end=dt.datetime(2017, 1, 2, 13)),
            ],
        ),
    ),
)
def test_clean_availabilities_success(availabilitiesform, json, expected):
    availabilitiesform.cleaned_data = {"availabilities": json}
    actual = availabilitiesform.clean_availabilities()

    assert len(actual) == len(expected)

    for act, exp in zip(actual, expected):
        assert act.start.replace(tzinfo=None) == exp.start
        assert act.end.replace(tzinfo=None) == exp.end
Exemple #30
0
def test_availability_str_room(room):
    assert f'room={room.name}' in str(Availability(
        start=datetime.datetime(2017, 1, 1, 0),
        end=datetime.datetime(2017, 1, 1, 5),
        room=room,
    ))