Fix iCal imported schedules related users and next shifts per user (#3178)

Fixes https://github.com/grafana/oncall-private/issues/2212
This commit is contained in:
Matias Bordese 2023-10-23 19:15:02 -03:00 committed by GitHub
parent 0d22ae7e53
commit d546d0b7ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 98 additions and 1 deletions

View file

@ -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) - 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 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)) - Fix references to removed access control functions in Grafana @mderynck ([#3184](https://github.com/grafana/oncall/pull/3184))
## v1.3.45 (2023-10-19) ## v1.3.45 (2023-10-19)

View file

@ -1,4 +1,5 @@
import json import json
import textwrap
from unittest.mock import patch from unittest.mock import patch
import pytest import pytest
@ -1487,6 +1488,57 @@ def test_next_shifts_per_user(
assert returned_data == expected 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 @pytest.mark.django_db
def test_related_users( def test_related_users(
make_organization_and_user_with_plugin_token, make_organization_and_user_with_plugin_token,

View file

@ -380,7 +380,7 @@ class ScheduleView(
added_users = set() added_users = set()
for e in events: for e in events:
user = e["users"][0]["pk"] if e["users"] else None 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) users[user].update(e)
added_users.add(user) added_users.add(user)

View file

@ -1092,6 +1092,16 @@ class OnCallScheduleICal(OnCallSchedule):
) )
self.save(update_fields=["cached_ical_file_overrides", "prev_ical_file_overrides", "ical_file_error_overrides"]) 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 # Insight logs
@property @property
def insight_logs_serialized(self): def insight_logs_serialized(self):

View file

@ -1304,6 +1304,40 @@ def test_schedule_related_users_usernames(
assert set(schedule.related_users()) == set(users) 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) @pytest.mark.django_db(transaction=True)
def test_filter_events_none_cache_unchanged( def test_filter_events_none_cache_unchanged(
make_organization, make_user_for_organization, make_schedule, make_on_call_shift make_organization, make_user_for_organization, make_schedule, make_on_call_shift