Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ical schedule creation/update to trigger final schedule refresh #3156

Merged
merged 2 commits into from
Oct 18, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Update ical schedule creation/update to trigger final schedule refresh
matiasb committed Oct 17, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 87b876a43e8c436914159a5afac7105269ff70bb
14 changes: 13 additions & 1 deletion engine/apps/api/serializers/schedule_ical.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from apps.api.serializers.schedule_base import ScheduleBaseSerializer
from apps.schedules.models import OnCallScheduleICal
from apps.schedules.tasks import schedule_notify_about_empty_shifts_in_schedule, schedule_notify_about_gaps_in_schedule
from apps.schedules.tasks import (
refresh_ical_final_schedule,
schedule_notify_about_empty_shifts_in_schedule,
schedule_notify_about_gaps_in_schedule,
)
from apps.slack.models import SlackChannel, SlackUserGroup
from common.api_helpers.custom_fields import OrganizationFilteredPrimaryKeyRelatedField
from common.api_helpers.utils import validate_ical_url
@@ -37,6 +41,12 @@ class ScheduleICalCreateSerializer(ScheduleICalSerializer):
allow_null=True,
)

def create(self, validated_data):
created_schedule = super().create(validated_data)
# for iCal-based schedules we need to refresh final schedule information
refresh_ical_final_schedule.apply_async((created_schedule.pk,))
return created_schedule

class Meta:
model = OnCallScheduleICal
fields = [
@@ -80,4 +90,6 @@ def update(self, instance, validated_data):
updated_schedule.check_gaps_for_next_week()
schedule_notify_about_empty_shifts_in_schedule.apply_async((instance.pk,))
schedule_notify_about_gaps_in_schedule.apply_async((instance.pk,))
# for iCal-based schedules we need to refresh final schedule information
refresh_ical_final_schedule.apply_async((instance.pk,))
return updated_schedule
70 changes: 50 additions & 20 deletions engine/apps/api/tests/test_schedules.py
Original file line number Diff line number Diff line change
@@ -601,25 +601,25 @@ def test_create_ical_schedule(schedule_internal_api_setup, make_user_auth_header
user, token, _, _, _, _ = schedule_internal_api_setup
client = APIClient()
url = reverse("api-internal:schedule-list")
data = {
"ical_url_primary": ICAL_URL,
"ical_url_overrides": None,
"name": "created_ical_schedule",
"type": 1,
"slack_channel_id": None,
"user_group": None,
"team": None,
"warnings": [],
"on_call_now": [],
"has_gaps": False,
"mention_oncall_next": False,
"mention_oncall_start": True,
"notify_empty_oncall": 0,
"notify_oncall_shift_freq": 1,
}
with patch(
"apps.api.serializers.schedule_ical.ScheduleICalSerializer.validate_ical_url_primary", return_value=ICAL_URL
):
data = {
"ical_url_primary": ICAL_URL,
"ical_url_overrides": None,
"name": "created_ical_schedule",
"type": 1,
"slack_channel_id": None,
"user_group": None,
"team": None,
"warnings": [],
"on_call_now": [],
"has_gaps": False,
"mention_oncall_next": False,
"mention_oncall_start": True,
"notify_empty_oncall": 0,
"notify_oncall_shift_freq": 1,
}
), patch("apps.schedules.tasks.refresh_ical_final_schedule.apply_async") as mock_refresh_final:
response = client.post(url, data, format="json", **make_user_auth_headers(user, token))
# modify initial data by adding id and None for optional fields
schedule = OnCallSchedule.objects.get(public_primary_key=response.data["id"])
@@ -628,6 +628,8 @@ def test_create_ical_schedule(schedule_internal_api_setup, make_user_auth_header
data["enable_web_overrides"] = False
assert response.status_code == status.HTTP_201_CREATED
assert response.data == data
# check final schedule refresh triggered
mock_refresh_final.assert_called_once_with((schedule.pk,))


@pytest.mark.django_db
@@ -736,12 +738,40 @@ def test_update_ical_schedule(schedule_internal_api_setup, make_user_auth_header
"type": 1,
"team": None,
}
response = client.put(
url, data=json.dumps(data), content_type="application/json", **make_user_auth_headers(user, token)
)
with patch("apps.schedules.tasks.refresh_ical_final_schedule.apply_async") as mock_refresh_final:
response = client.put(
url, data=json.dumps(data), content_type="application/json", **make_user_auth_headers(user, token)
)
updated_instance = OnCallSchedule.objects.get(public_primary_key=ical_schedule.public_primary_key)
assert response.status_code == status.HTTP_200_OK
assert updated_instance.name == "updated_ical_schedule"
# check refresh final is not triggered (url unchanged)
assert not mock_refresh_final.called


@pytest.mark.django_db
def test_update_ical_schedule_url(schedule_internal_api_setup, make_user_auth_headers):
user, token, _, ical_schedule, _, _ = schedule_internal_api_setup
client = APIClient()

url = reverse("api-internal:schedule-detail", kwargs={"pk": ical_schedule.public_primary_key})

updated_url = "another-url"
data = {
"name": ical_schedule.name,
"type": 1,
"ical_url_primary": updated_url,
}
with patch(
"apps.api.serializers.schedule_ical.ScheduleICalSerializer.validate_ical_url_primary", return_value=updated_url
), patch("apps.schedules.tasks.refresh_ical_final_schedule.apply_async") as mock_refresh_final:
response = client.put(
url, data=json.dumps(data), content_type="application/json", **make_user_auth_headers(user, token)
)
updated_instance = OnCallSchedule.objects.get(public_primary_key=ical_schedule.public_primary_key)
assert response.status_code == status.HTTP_200_OK
# check refresh final triggered (changing url)
mock_refresh_final.assert_called_once_with((updated_instance.pk,))


@pytest.mark.django_db
8 changes: 8 additions & 0 deletions engine/apps/public_api/serializers/schedules_ical.py
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
from apps.schedules.models import OnCallScheduleICal
from apps.schedules.tasks import (
drop_cached_ical_task,
refresh_ical_final_schedule,
schedule_notify_about_empty_shifts_in_schedule,
schedule_notify_about_gaps_in_schedule,
)
@@ -32,6 +33,12 @@ def validate_ical_url_primary(self, url):
def validate_ical_url_overrides(self, url):
return validate_ical_url(url)

def create(self, validated_data):
created_schedule = super().create(validated_data)
# for iCal-based schedules we need to refresh final schedule information
refresh_ical_final_schedule.apply_async((created_schedule.pk,))
return created_schedule


class ScheduleICalUpdateSerializer(ScheduleICalSerializer):
team_id = TeamPrimaryKeyRelatedField(required=False, allow_null=True, source="team")
@@ -70,4 +77,5 @@ def update(self, instance, validated_data):
)
schedule_notify_about_empty_shifts_in_schedule.apply_async((instance.pk,))
schedule_notify_about_gaps_in_schedule.apply_async((instance.pk,))
refresh_ical_final_schedule.apply_async((instance.pk,))
return super().update(instance, validated_data)
41 changes: 22 additions & 19 deletions engine/apps/public_api/tests/test_schedules.py
Original file line number Diff line number Diff line change
@@ -393,24 +393,24 @@ def test_update_ical_url_overrides_calendar_schedule(
with patch("common.api_helpers.utils.validate_ical_url", return_value=ICAL_URL):
response = client.put(url, data=data, format="json", HTTP_AUTHORIZATION=f"{token}")

result = {
"id": schedule.public_primary_key,
"team_id": None,
"name": schedule.name,
"type": "calendar",
"time_zone": schedule.time_zone,
"on_call_now": [],
"shifts": [],
"slack": {
"channel_id": "SLACKCHANNELID",
"user_group_id": None,
},
"ical_url_overrides": ICAL_URL,
"enable_web_overrides": False,
}
result = {
"id": schedule.public_primary_key,
"team_id": None,
"name": schedule.name,
"type": "calendar",
"time_zone": schedule.time_zone,
"on_call_now": [],
"shifts": [],
"slack": {
"channel_id": "SLACKCHANNELID",
"user_group_id": None,
},
"ical_url_overrides": ICAL_URL,
"enable_web_overrides": False,
}

assert response.status_code == status.HTTP_200_OK
assert response.json() == result
assert response.status_code == status.HTTP_200_OK
assert response.json() == result


@pytest.mark.django_db
@@ -633,7 +633,7 @@ def test_create_ical_schedule(make_organization_and_user_with_token):
with patch(
"apps.public_api.serializers.schedules_ical.ScheduleICalSerializer.validate_ical_url_primary",
return_value=ICAL_URL,
):
), patch("apps.schedules.tasks.refresh_ical_final_schedule.apply_async") as mock_refresh_final:
response = client.post(url, data=data, format="json", HTTP_AUTHORIZATION=f"{token}")
schedule = OnCallSchedule.objects.get(public_primary_key=response.data["id"])

@@ -653,6 +653,7 @@ def test_create_ical_schedule(make_organization_and_user_with_token):

assert response.status_code == status.HTTP_201_CREATED
assert response.json() == result
mock_refresh_final.assert_called_once_with((schedule.pk,))


@pytest.mark.django_db
@@ -680,7 +681,8 @@ def test_update_ical_schedule(

assert schedule.name != data["name"]

response = client.put(url, data=data, format="json", HTTP_AUTHORIZATION=f"{token}")
with patch("apps.schedules.tasks.refresh_ical_final_schedule.apply_async") as mock_refresh_final:
response = client.put(url, data=data, format="json", HTTP_AUTHORIZATION=f"{token}")

result = {
"id": schedule.public_primary_key,
@@ -700,6 +702,7 @@ def test_update_ical_schedule(
schedule.refresh_from_db()
assert schedule.name == data["name"]
assert response.json() == result
assert not mock_refresh_final.called


@pytest.mark.django_db