Skip to content

Commit

Permalink
Fix iCal imported schedules related users and next shifts per user (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
matiasb authored Oct 23, 2023
1 parent 0d22ae7 commit d546d0b
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Discard old pending network requests in the UI (Users/Schedules) [#3172](https://github.com/grafana/oncall/pull/3172)
- Fix resolution note source for mobile app by @vadimkerr ([#3174](https://github.com/grafana/oncall/pull/3174))
- Fix iCal imported schedules related users and next shifts per user ([#3178](https://github.com/grafana/oncall/pull/3178))
- Fix references to removed access control functions in Grafana @mderynck ([#3184](https://github.com/grafana/oncall/pull/3184))

## v1.3.45 (2023-10-19)
Expand Down
52 changes: 52 additions & 0 deletions engine/apps/api/tests/test_schedules.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import textwrap
from unittest.mock import patch

import pytest
Expand Down Expand Up @@ -1487,6 +1488,57 @@ def test_next_shifts_per_user(
assert returned_data == expected


@pytest.mark.django_db
def test_next_shifts_per_user_ical_schedule_using_emails(
make_organization_and_user_with_plugin_token, make_user_for_organization, make_user_auth_headers, make_schedule
):
organization, admin, token = make_organization_and_user_with_plugin_token()
client = APIClient()

user = make_user_for_organization(organization, username="testing", email="testing@testing.com")
# ical file using emails as reference
cached_ical_primary_schedule = textwrap.dedent(
"""
BEGIN:VCALENDAR
VERSION:2.0
PRODID:testing
CALSCALE:GREGORIAN
BEGIN:VEVENT
CREATED:20220316T121102Z
LAST-MODIFIED:20230127T151619Z
DTSTAMP:20230127T151619Z
UID:something
SUMMARY:testing@testing.com
RRULE:FREQ=WEEKLY
DTSTART;TZID=Europe/Madrid:20220309T130000
DTEND;TZID=Europe/Madrid:20220309T133000
END:VEVENT
BEGIN:VEVENT
CREATED:20220316T121102Z
LAST-MODIFIED:20230127T151619Z
DTSTAMP:20230127T151619Z
UID:something-else
SUMMARY:testing_unknown@testing.com
RRULE:FREQ=WEEKLY
DTSTART;TZID=Europe/Madrid:20220309T150000
DTEND;TZID=Europe/Madrid:20220309T153000
END:VEVENT
END:VCALENDAR
"""
)
schedule = make_schedule(
organization,
schedule_class=OnCallScheduleICal,
cached_ical_file_primary=cached_ical_primary_schedule,
)

url = reverse("api-internal:schedule-next-shifts-per-user", kwargs={"pk": schedule.public_primary_key})
response = client.get(url, format="json", **make_user_auth_headers(admin, token))
assert response.status_code == status.HTTP_200_OK

assert set(response.data["users"].keys()) == {user.public_primary_key}


@pytest.mark.django_db
def test_related_users(
make_organization_and_user_with_plugin_token,
Expand Down
2 changes: 1 addition & 1 deletion engine/apps/api/views/schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ def next_shifts_per_user(self, request, pk):
added_users = set()
for e in events:
user = e["users"][0]["pk"] if e["users"] else None
if user is not None and user not in added_users and e["end"] > now:
if user is not None and user not in added_users and user in users and e["end"] > now:
users[user].update(e)
added_users.add(user)

Expand Down
10 changes: 10 additions & 0 deletions engine/apps/schedules/models/on_call_schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,16 @@ def _refresh_overrides_ical_file(self):
)
self.save(update_fields=["cached_ical_file_overrides", "prev_ical_file_overrides", "ical_file_error_overrides"])

def related_users(self):
"""Return users referenced in the schedule."""
# combine users based on usernames and users via email (allowed in iCal based schedules)
usernames = []
if self.cached_ical_file_primary:
usernames += RE_ICAL_FETCH_USERNAME.findall(self.cached_ical_file_primary)
if self.cached_ical_file_overrides:
usernames += RE_ICAL_FETCH_USERNAME.findall(self.cached_ical_file_overrides)
return self.organization.users.filter(Q(username__in=usernames) | Q(email__in=usernames))

# Insight logs
@property
def insight_logs_serialized(self):
Expand Down
34 changes: 34 additions & 0 deletions engine/apps/schedules/tests/test_on_call_schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -1304,6 +1304,40 @@ def test_schedule_related_users_usernames(
assert set(schedule.related_users()) == set(users)


@pytest.mark.django_db
def test_schedule_related_users_emails(make_organization, make_user_for_organization, make_schedule):
organization = make_organization()
user = make_user_for_organization(organization, username="testing", email="testing@testing.com")
# ical file using email as reference
cached_ical_primary_schedule = textwrap.dedent(
"""
BEGIN:VCALENDAR
VERSION:2.0
PRODID:testing
CALSCALE:GREGORIAN
BEGIN:VEVENT
CREATED:20220316T121102Z
LAST-MODIFIED:20230127T151619Z
DTSTAMP:20230127T151619Z
UID:something
SUMMARY:testing@testing.com
RRULE:FREQ=WEEKLY;UNTIL=20221231T010101
DTSTART;TZID=Europe/Madrid:20220309T130000
DTEND;TZID=Europe/Madrid:20220309T133000
SEQUENCE:4
END:VEVENT
END:VCALENDAR
"""
)
schedule = make_schedule(
organization,
schedule_class=OnCallScheduleICal,
cached_ical_file_primary=cached_ical_primary_schedule,
)

assert set(schedule.related_users()) == {user}


@pytest.mark.django_db(transaction=True)
def test_filter_events_none_cache_unchanged(
make_organization, make_user_for_organization, make_schedule, make_on_call_shift
Expand Down

0 comments on commit d546d0b

Please sign in to comment.