Skip to content

Commit d546d0b

Browse files
authoredOct 23, 2023
Fix iCal imported schedules related users and next shifts per user (#3178)
Fixes grafana/oncall-private#2212
1 parent 0d22ae7 commit d546d0b

File tree

5 files changed

+98
-1
lines changed

5 files changed

+98
-1
lines changed
 

‎CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515

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

2021
## v1.3.45 (2023-10-19)

‎engine/apps/api/tests/test_schedules.py

+52
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import textwrap
23
from unittest.mock import patch
34

45
import pytest
@@ -1487,6 +1488,57 @@ def test_next_shifts_per_user(
14871488
assert returned_data == expected
14881489

14891490

1491+
@pytest.mark.django_db
1492+
def test_next_shifts_per_user_ical_schedule_using_emails(
1493+
make_organization_and_user_with_plugin_token, make_user_for_organization, make_user_auth_headers, make_schedule
1494+
):
1495+
organization, admin, token = make_organization_and_user_with_plugin_token()
1496+
client = APIClient()
1497+
1498+
user = make_user_for_organization(organization, username="testing", email="testing@testing.com")
1499+
# ical file using emails as reference
1500+
cached_ical_primary_schedule = textwrap.dedent(
1501+
"""
1502+
BEGIN:VCALENDAR
1503+
VERSION:2.0
1504+
PRODID:testing
1505+
CALSCALE:GREGORIAN
1506+
BEGIN:VEVENT
1507+
CREATED:20220316T121102Z
1508+
LAST-MODIFIED:20230127T151619Z
1509+
DTSTAMP:20230127T151619Z
1510+
UID:something
1511+
SUMMARY:testing@testing.com
1512+
RRULE:FREQ=WEEKLY
1513+
DTSTART;TZID=Europe/Madrid:20220309T130000
1514+
DTEND;TZID=Europe/Madrid:20220309T133000
1515+
END:VEVENT
1516+
BEGIN:VEVENT
1517+
CREATED:20220316T121102Z
1518+
LAST-MODIFIED:20230127T151619Z
1519+
DTSTAMP:20230127T151619Z
1520+
UID:something-else
1521+
SUMMARY:testing_unknown@testing.com
1522+
RRULE:FREQ=WEEKLY
1523+
DTSTART;TZID=Europe/Madrid:20220309T150000
1524+
DTEND;TZID=Europe/Madrid:20220309T153000
1525+
END:VEVENT
1526+
END:VCALENDAR
1527+
"""
1528+
)
1529+
schedule = make_schedule(
1530+
organization,
1531+
schedule_class=OnCallScheduleICal,
1532+
cached_ical_file_primary=cached_ical_primary_schedule,
1533+
)
1534+
1535+
url = reverse("api-internal:schedule-next-shifts-per-user", kwargs={"pk": schedule.public_primary_key})
1536+
response = client.get(url, format="json", **make_user_auth_headers(admin, token))
1537+
assert response.status_code == status.HTTP_200_OK
1538+
1539+
assert set(response.data["users"].keys()) == {user.public_primary_key}
1540+
1541+
14901542
@pytest.mark.django_db
14911543
def test_related_users(
14921544
make_organization_and_user_with_plugin_token,

‎engine/apps/api/views/schedule.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ def next_shifts_per_user(self, request, pk):
380380
added_users = set()
381381
for e in events:
382382
user = e["users"][0]["pk"] if e["users"] else None
383-
if user is not None and user not in added_users and e["end"] > now:
383+
if user is not None and user not in added_users and user in users and e["end"] > now:
384384
users[user].update(e)
385385
added_users.add(user)
386386

‎engine/apps/schedules/models/on_call_schedule.py

+10
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,16 @@ def _refresh_overrides_ical_file(self):
10921092
)
10931093
self.save(update_fields=["cached_ical_file_overrides", "prev_ical_file_overrides", "ical_file_error_overrides"])
10941094

1095+
def related_users(self):
1096+
"""Return users referenced in the schedule."""
1097+
# combine users based on usernames and users via email (allowed in iCal based schedules)
1098+
usernames = []
1099+
if self.cached_ical_file_primary:
1100+
usernames += RE_ICAL_FETCH_USERNAME.findall(self.cached_ical_file_primary)
1101+
if self.cached_ical_file_overrides:
1102+
usernames += RE_ICAL_FETCH_USERNAME.findall(self.cached_ical_file_overrides)
1103+
return self.organization.users.filter(Q(username__in=usernames) | Q(email__in=usernames))
1104+
10951105
# Insight logs
10961106
@property
10971107
def insight_logs_serialized(self):

‎engine/apps/schedules/tests/test_on_call_schedule.py

+34
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,40 @@ def test_schedule_related_users_usernames(
13041304
assert set(schedule.related_users()) == set(users)
13051305

13061306

1307+
@pytest.mark.django_db
1308+
def test_schedule_related_users_emails(make_organization, make_user_for_organization, make_schedule):
1309+
organization = make_organization()
1310+
user = make_user_for_organization(organization, username="testing", email="testing@testing.com")
1311+
# ical file using email as reference
1312+
cached_ical_primary_schedule = textwrap.dedent(
1313+
"""
1314+
BEGIN:VCALENDAR
1315+
VERSION:2.0
1316+
PRODID:testing
1317+
CALSCALE:GREGORIAN
1318+
BEGIN:VEVENT
1319+
CREATED:20220316T121102Z
1320+
LAST-MODIFIED:20230127T151619Z
1321+
DTSTAMP:20230127T151619Z
1322+
UID:something
1323+
SUMMARY:testing@testing.com
1324+
RRULE:FREQ=WEEKLY;UNTIL=20221231T010101
1325+
DTSTART;TZID=Europe/Madrid:20220309T130000
1326+
DTEND;TZID=Europe/Madrid:20220309T133000
1327+
SEQUENCE:4
1328+
END:VEVENT
1329+
END:VCALENDAR
1330+
"""
1331+
)
1332+
schedule = make_schedule(
1333+
organization,
1334+
schedule_class=OnCallScheduleICal,
1335+
cached_ical_file_primary=cached_ical_primary_schedule,
1336+
)
1337+
1338+
assert set(schedule.related_users()) == {user}
1339+
1340+
13071341
@pytest.mark.django_db(transaction=True)
13081342
def test_filter_events_none_cache_unchanged(
13091343
make_organization, make_user_for_organization, make_schedule, make_on_call_shift

0 commit comments

Comments
 (0)