From 710f60be78d469b8e1f651933a564956d6cbb4aa Mon Sep 17 00:00:00 2001 From: Hangzhi Yu <hangzhi@protonmail.com> Date: Sun, 2 Feb 2025 19:25:06 +0100 Subject: [PATCH 1/4] Fix constraint for all day events --- aleksis/core/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aleksis/core/models.py b/aleksis/core/models.py index c02ec1548..a080955bf 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -1713,7 +1713,7 @@ class CalendarEvent(CalendarEventMixin, ExtensiblePolymorphicModel, RecurrenceMo check=Q(datetime_end__gt=F("datetime_start")), name="datetime_start_before_end" ), models.CheckConstraint( - check=Q(date_end__gt=F("date_start")), name="date_start_before_end" + check=Q(date_end__gte=F("date_start")), name="date_start_before_end" ), models.CheckConstraint( check=~(Q(datetime_start__isnull=False, timezone="") & ~Q(recurrences="")), -- GitLab From 30942148e2cc9e392938867244dfceeddb584f1e Mon Sep 17 00:00:00 2001 From: Hangzhi Yu <hangzhi@protonmail.com> Date: Sun, 2 Feb 2025 19:42:51 +0100 Subject: [PATCH 2/4] Fix handling of all day events in backend and frontend --- aleksis/core/frontend/components/calendar/Calendar.vue | 5 ++++- aleksis/core/models.py | 7 ++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/aleksis/core/frontend/components/calendar/Calendar.vue b/aleksis/core/frontend/components/calendar/Calendar.vue index d8fcdfe39..511af38d5 100644 --- a/aleksis/core/frontend/components/calendar/Calendar.vue +++ b/aleksis/core/frontend/components/calendar/Calendar.vue @@ -217,7 +217,10 @@ export default { .flatMap((cf) => cf.events.map((event) => { const start = this.$parseISODate(event.start); - const end = this.$parseISODate(event.end); + let end = this.$parseISODate(event.end); + if (event.allDay) { + end = end.minus({ days: 1 }); + } return { ...event, category: cf.verboseName, diff --git a/aleksis/core/models.py b/aleksis/core/models.py index a080955bf..fcf9384b2 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -1561,11 +1561,8 @@ class CalendarEvent(CalendarEventMixin, ExtensiblePolymorphicModel, RecurrenceMo """Return the end datetime of the calendar event.""" if reference_object.datetime_end: return reference_object.datetime_end.astimezone(reference_object.timezone) - if reference_object.date_end == reference_object.date_start: - # Rule for all day events: If the event is only one day long, - # the end date has to be empty - return None - return reference_object.date_end + # RFC 5545 states that the end date is not inclusive + return reference_object.date_end + timedelta(days=1) @classmethod def value_rrule( -- GitLab From 1b5563ebe89612e80bec7a94ad5679aa5e0c0c00 Mon Sep 17 00:00:00 2001 From: Hangzhi Yu <hangzhi@protonmail.com> Date: Sun, 2 Feb 2025 20:05:26 +0100 Subject: [PATCH 3/4] Add test --- aleksis/core/tests/regression/test_regression.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/aleksis/core/tests/regression/test_regression.py b/aleksis/core/tests/regression/test_regression.py index a578145db..c4e2b393e 100644 --- a/aleksis/core/tests/regression/test_regression.py +++ b/aleksis/core/tests/regression/test_regression.py @@ -1,4 +1,5 @@ import base64 +from datetime import date from django.contrib.auth import get_user_model from django.test import override_settings @@ -6,7 +7,7 @@ from django.urls import reverse import pytest -from aleksis.core.models import Group, OAuthApplication, Person +from aleksis.core.models import Holiday, Group, OAuthApplication, Person pytestmark = pytest.mark.django_db @@ -147,3 +148,16 @@ def test_change_password_not_logged_in(client): assert response.status_code == 200 assert "Please login to see this page." in response.content.decode("utf-8") + + +def test_all_day_events_end_date(): + """Tests that CalendarEvent's value method returns a non-inclusive end date for all day events. + + https://edugit.org/AlekSIS/official/AlekSIS-Core/-/issues/1199 + """ + holiday = Holiday.objects.create( + date_start=date(2024, 2, 1), date_end=date(2024, 2, 1), holiday_name="Test Holiday" + ) + + assert holiday.value_start_datetime(holiday) == date(2024, 2, 1) + assert holiday.value_end_datetime(holiday) == date(2024, 2, 2) -- GitLab From e2283936c7538f43f12026af15e5184f43c637e7 Mon Sep 17 00:00:00 2001 From: Hangzhi Yu <hangzhi@protonmail.com> Date: Sun, 2 Feb 2025 20:12:32 +0100 Subject: [PATCH 4/4] Fix constraint in migration --- .../0071_constrain_calendar_event_starting_before_ending.py | 2 +- aleksis/core/tests/regression/test_regression.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aleksis/core/migrations/0071_constrain_calendar_event_starting_before_ending.py b/aleksis/core/migrations/0071_constrain_calendar_event_starting_before_ending.py index cd1620e7d..4567be588 100644 --- a/aleksis/core/migrations/0071_constrain_calendar_event_starting_before_ending.py +++ b/aleksis/core/migrations/0071_constrain_calendar_event_starting_before_ending.py @@ -16,7 +16,7 @@ class Migration(migrations.Migration): ), migrations.AddConstraint( model_name='calendarevent', - constraint=models.CheckConstraint(check=Q(date_end__gt=F('date_start')), + constraint=models.CheckConstraint(check=Q(date_end__gte=F('date_start')), name="date_start_before_end" ), ), diff --git a/aleksis/core/tests/regression/test_regression.py b/aleksis/core/tests/regression/test_regression.py index c4e2b393e..74e41227a 100644 --- a/aleksis/core/tests/regression/test_regression.py +++ b/aleksis/core/tests/regression/test_regression.py @@ -7,7 +7,7 @@ from django.urls import reverse import pytest -from aleksis.core.models import Holiday, Group, OAuthApplication, Person +from aleksis.core.models import Group, Holiday, OAuthApplication, Person pytestmark = pytest.mark.django_db -- GitLab