Matias Bordese 2024-08-13 17:51:18 -03:00 committed by GitHub
parent 17618214f9
commit a1c67cdfe7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 68 additions and 46 deletions

View file

@ -5,6 +5,7 @@ on:
env:
DJANGO_SETTINGS_MODULE: settings.ci_test
SKIP_SLACK_SDK_WARNING: True
DATABASE_HOST: localhost
RABBITMQ_URI: amqp://rabbitmq:rabbitmq@localhost:5672
SLACK_CLIENT_OAUTH_ID: 1

View file

@ -1,5 +1,3 @@
from datetime import timedelta
import pytest
from django.utils import timezone
@ -29,8 +27,8 @@ def make_resolved_ack_new_silenced_alert_groups(make_alert_group, make_alert_rec
resolved_alert_group = make_alert_group(
alert_receive_channel,
channel_filter=channel_filter,
acknowledged_at=timezone.now() + timedelta(hours=1),
resolved_at=timezone.now() + timedelta(hours=2),
acknowledged_at=timezone.now() + timezone.timedelta(hours=1),
resolved_at=timezone.now() + timezone.timedelta(hours=2),
resolved=True,
acknowledged=True,
)
@ -39,7 +37,7 @@ def make_resolved_ack_new_silenced_alert_groups(make_alert_group, make_alert_rec
ack_alert_group = make_alert_group(
alert_receive_channel,
channel_filter=channel_filter,
acknowledged_at=timezone.now() + timedelta(hours=1),
acknowledged_at=timezone.now() + timezone.timedelta(hours=1),
acknowledged=True,
)
make_alert(alert_group=ack_alert_group, raw_request_data=alert_raw_request_data)
@ -51,7 +49,7 @@ def make_resolved_ack_new_silenced_alert_groups(make_alert_group, make_alert_rec
alert_receive_channel,
channel_filter=channel_filter,
silenced=True,
silenced_at=timezone.now() + timedelta(hours=1),
silenced_at=timezone.now() + timezone.timedelta(hours=1),
)
make_alert(alert_group=silenced_alert_group, raw_request_data=alert_raw_request_data)

View file

@ -1,4 +1,3 @@
import datetime
from unittest.mock import Mock, patch
import pytest
@ -250,8 +249,8 @@ def test_get_filter_resolved_by(
resolved_alert_group = make_alert_group(
alert_receive_channel,
channel_filter=default_channel_filter,
acknowledged_at=timezone.now() + datetime.timedelta(hours=1),
resolved_at=timezone.now() + datetime.timedelta(hours=2),
acknowledged_at=timezone.now() + timezone.timedelta(hours=1),
resolved_at=timezone.now() + timezone.timedelta(hours=2),
resolved=True,
acknowledged=True,
resolved_by_user=first_user,
@ -302,8 +301,8 @@ def test_get_filter_resolved_by_multiple_values(
resolved_alert_group = make_alert_group(
alert_receive_channel,
channel_filter=default_channel_filter,
acknowledged_at=timezone.now() + datetime.timedelta(hours=1),
resolved_at=timezone.now() + datetime.timedelta(hours=2),
acknowledged_at=timezone.now() + timezone.timedelta(hours=1),
resolved_at=timezone.now() + timezone.timedelta(hours=2),
resolved=True,
acknowledged=True,
resolved_by_user=user,
@ -348,8 +347,8 @@ def test_get_filter_acknowledged_by(
acknowledged_alert_group = make_alert_group(
alert_receive_channel,
channel_filter=default_channel_filter,
acknowledged_at=timezone.now() + datetime.timedelta(hours=1),
resolved_at=timezone.now() + datetime.timedelta(hours=2),
acknowledged_at=timezone.now() + timezone.timedelta(hours=1),
resolved_at=timezone.now() + timezone.timedelta(hours=2),
acknowledged=True,
acknowledged_by_user=first_user,
)
@ -398,8 +397,8 @@ def test_get_filter_acknowledged_by_multiple_values(
acknowledged_alert_group = make_alert_group(
alert_receive_channel,
channel_filter=default_channel_filter,
acknowledged_at=timezone.now() + datetime.timedelta(hours=1),
resolved_at=timezone.now() + datetime.timedelta(hours=2),
acknowledged_at=timezone.now() + timezone.timedelta(hours=1),
resolved_at=timezone.now() + timezone.timedelta(hours=2),
acknowledged=True,
acknowledged_by_user=user,
)
@ -442,7 +441,7 @@ def test_get_filter_silenced_by(
silenced_alert_group = make_alert_group(
alert_receive_channel,
channel_filter=default_channel_filter,
silenced_at=timezone.now() + datetime.timedelta(hours=1),
silenced_at=timezone.now() + timezone.timedelta(hours=1),
silenced=True,
silenced_by_user=first_user,
)
@ -491,7 +490,7 @@ def test_get_filter_silenced_by_multiple_values(
acknowledged_alert_group = make_alert_group(
alert_receive_channel,
channel_filter=default_channel_filter,
silenced_at=timezone.now() + datetime.timedelta(hours=1),
silenced_at=timezone.now() + timezone.timedelta(hours=1),
silenced=True,
silenced_by_user=user,
)
@ -670,8 +669,8 @@ def test_get_filter_mine(
acknowledged_alert_group = make_alert_group(
alert_receive_channel,
channel_filter=default_channel_filter,
acknowledged_at=timezone.now() + datetime.timedelta(hours=1),
resolved_at=timezone.now() + datetime.timedelta(hours=2),
acknowledged_at=timezone.now() + timezone.timedelta(hours=1),
resolved_at=timezone.now() + timezone.timedelta(hours=2),
acknowledged=True,
acknowledged_by_user=first_user,
)
@ -724,8 +723,8 @@ def test_get_filter_involved_users(
acknowledged_alert_group = make_alert_group(
alert_receive_channel,
channel_filter=default_channel_filter,
acknowledged_at=timezone.now() + datetime.timedelta(hours=1),
resolved_at=timezone.now() + datetime.timedelta(hours=2),
acknowledged_at=timezone.now() + timezone.timedelta(hours=1),
resolved_at=timezone.now() + timezone.timedelta(hours=2),
acknowledged=True,
acknowledged_by_user=first_user,
)
@ -999,7 +998,7 @@ def test_get_title_search(
alert_receive_channel, channel_filter=channel_filter, web_title_cache=f"testing {i+1}"
)
# alert groups starting every months going back
alert_group.started_at = timezone.now() - datetime.timedelta(days=10 + 30 * i)
alert_group.started_at = timezone.now() - timezone.timedelta(days=10 + 30 * i)
alert_group.save(update_fields=["started_at"])
make_alert(alert_group=alert_group, raw_request_data=alert_raw_request_data)
alert_groups.append(alert_group)
@ -1021,8 +1020,8 @@ def test_get_title_search(
response = client.get(
url
+ "?search=testing&started_at={}_{}".format(
(timezone.now() - datetime.timedelta(days=500)).strftime(DateRangeFilterMixin.DATE_FORMAT),
(timezone.now() - datetime.timedelta(days=30)).strftime(DateRangeFilterMixin.DATE_FORMAT),
(timezone.now() - timezone.timedelta(days=500)).strftime(DateRangeFilterMixin.DATE_FORMAT),
(timezone.now() - timezone.timedelta(days=30)).strftime(DateRangeFilterMixin.DATE_FORMAT),
),
format="json",
**make_user_auth_headers(user, token),

View file

@ -242,7 +242,7 @@ class AlertReceiveChannelView(
)
# distinct to remove duplicates after alert_receive_channels X labels join
queryset = queryset.distinct()
queryset = queryset.distinct().order_by("id")
return queryset

View file

@ -65,7 +65,9 @@ class BaseShiftSwapViewSet(ModelViewSet):
return ShiftSwapRequestListSerializer if self.action == "list" else super().get_serializer_class()
def get_queryset(self):
queryset = ShiftSwapRequest.objects.filter(schedule__organization=self.request.auth.organization)
queryset = ShiftSwapRequest.objects.filter(schedule__organization=self.request.auth.organization).order_by(
"-created_at"
)
return self.serializer_class.setup_eager_loading(queryset)
def perform_destroy(self, instance: ShiftSwapRequest) -> None:

View file

@ -20,6 +20,7 @@ from apps.email.inbound import InboundEmailWebhookView
],
)
@pytest.mark.django_db
@pytest.mark.filterwarnings("ignore:::anymail.*") # ignore missing WEBHOOK_SECRET in amazon ses test setup
def test_amazon_ses_provider_load(
settings, make_organization_and_user_with_token, make_alert_receive_channel, recipients, expected
):
@ -128,7 +129,10 @@ def test_mailgun_provider_load(
"sender_value,expected_result",
[
("'Alex Smith' <test@example.com>", "test@example.com"),
("'Alex Smith' via [TEST] mail <test@example.com>", "'Alex Smith' via [TEST] mail <test@example.com>"),
# double quotes required when including special characters
("\"'Alex Smith' via [TEST] mail\" <test@example.com>", "test@example.com"),
# missing double quotes
("'Alex Smith' via [TEST] mail <test@example.com>", "\"'Alex Smith' via\""),
],
)
def test_get_sender_from_email_message(sender_value, expected_result):

View file

@ -1,3 +1,4 @@
import datetime
import time
from rest_framework import fields, serializers
@ -345,7 +346,9 @@ class CustomOnCallShiftSerializer(EagerLoadingMixin, serializers.ModelSerializer
if isinstance(validated_data.get(field), list) and len(validated_data[field]) == 0:
validated_data[field] = None
if validated_data.get("start") is not None:
validated_data["start"] = validated_data["start"].replace(tzinfo=None)
# store start date as UTC, TZ is really given by the time_zone field
# (see apps/schedules/models/custom_on_call_shift.py::convert_dt_to_schedule_timezone)
validated_data["start"] = validated_data["start"].replace(tzinfo=datetime.timezone.utc)
if validated_data.get("frequency") is not None and "interval" not in validated_data:
# if there is frequency but no interval is given, default to 1
validated_data["interval"] = 1

View file

@ -1,4 +1,3 @@
import datetime
from unittest.mock import patch
import pytest
@ -69,7 +68,7 @@ def test_refresh_ical_files_filter_orgs(
make_schedule,
):
organization = make_organization()
deleted_organization = make_organization(deleted_at=datetime.datetime.now())
deleted_organization = make_organization(deleted_at=timezone.now())
schedule_from_deleted_org = make_schedule(deleted_organization, schedule_class=OnCallScheduleWeb)
schedule = make_schedule(organization, schedule_class=OnCallScheduleWeb)

View file

@ -1,6 +1,6 @@
import datetime
import enum
import typing
from datetime import datetime
from apps.slack.client import SlackClient
from apps.slack.errors import (
@ -83,7 +83,7 @@ def post_message_to_channel(organization: "Organization", channel_id: str, text:
def _format_datetime_to_slack(timestamp: float, format: str) -> str:
fallback = datetime.utcfromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M (UTC)")
fallback = datetime.datetime.fromtimestamp(timestamp, datetime.UTC).strftime("%Y-%m-%d %H:%M (UTC)")
return f"<!date^{int(timestamp)}^{format}|{fallback}>"

View file

@ -136,9 +136,11 @@ def test_button_press_handler_non_existing_alert_group(
make_telegram_user_connector(user_1, telegram_chat_id=chat_id)
update = generate_button_press_ack_message(chat_id, 1234)
update_data = update.callback_query.data
handler = ButtonPressHandler(update=update)
with patch.object(update.callback_query, "answer") as mock_answer:
with patch.object(update, "callback_query", autospec=True) as mock_callback_query:
mock_callback_query.data = update_data
handler.process_update()
mock_answer.assert_called_once_with(NOT_FOUND_ERROR, show_alert=True)
mock_callback_query.answer.assert_called_once_with(NOT_FOUND_ERROR, show_alert=True)

View file

@ -1,8 +1,9 @@
from datetime import datetime
from django.conf import settings
from django.db.models import Q
from django.utils import timezone
from django_filters import rest_framework as filters
from django_filters.utils import handle_timezone
from drf_spectacular.utils import extend_schema_field
from rest_framework import serializers
@ -12,6 +13,14 @@ from common.api_helpers.exceptions import BadRequest
NO_TEAM_VALUE = "null"
def _handle_timezone(value):
if settings.USE_TZ and timezone.is_naive(value):
return timezone.make_aware(value, timezone.get_current_timezone())
elif not settings.USE_TZ and timezone.is_aware(value):
return timezone.make_naive(value, timezone.utc)
return value
class DateRangeFilterMixin:
DATE_FORMAT = "%Y-%m-%dT%H:%M:%S"
@ -44,8 +53,8 @@ class DateRangeFilterMixin:
if start_date > end_date:
raise BadRequest(detail="Invalid range value")
start_date = handle_timezone(start_date, False)
end_date = handle_timezone(end_date, False)
start_date = _handle_timezone(start_date)
end_date = _handle_timezone(end_date)
return start_date, end_date

View file

@ -439,7 +439,7 @@ def test_ordered_model_create_swap_and_delete_concurrent():
assert list(TestOrderedModel.objects.values_list("extra_field", flat=True)) == expected_extra_field_values
class TestOrderedModelSerializer(OrderedModelSerializer):
class OrderedModelSerializerForTests(OrderedModelSerializer):
class Meta:
model = TestOrderedModel
fields = OrderedModelSerializer.Meta.fields + ["test_field", "extra_field"]
@ -461,7 +461,7 @@ def test_ordered_model_swap_all_to_zero_via_serializer():
def update_order_to_zero(idx):
try:
instance = instances[idx]
serializer = TestOrderedModelSerializer(instance, data={"order": 0, "extra_field": idx}, partial=True)
serializer = OrderedModelSerializerForTests(instance, data={"order": 0, "extra_field": idx}, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
instance.swap(positions[idx])

View file

@ -10,7 +10,7 @@ logger = logging.getLogger(__name__)
class RequestTimeLoggingMiddleware(MiddlewareMixin):
@staticmethod
def log_message(request, response, tag, message=""):
dt = datetime.datetime.utcnow()
dt = datetime.datetime.now(datetime.UTC)
if not hasattr(request, "_logging_start_dt"):
request._logging_start_dt = dt
if request.path.startswith("/integrations/v1"):

View file

@ -5,7 +5,7 @@ cryptography==42.0.8
django==4.2.15
django-add-default-value==0.10.0
django-amazon-ses==4.0.1
django-anymail==8.6
django-anymail==11.1
django-cors-headers==3.7.0
# pyroscope-io==0.8.1
django-dbconn-retry==0.1.7
@ -32,7 +32,7 @@ emoji==2.4.0
grpcio==1.64.1
fcm-django @ https://github.com/grafana/fcm-django/archive/refs/tags/v1.0.12r1.tar.gz#sha256=7ec7cd9d353fc9edf19a4acd4fa14090a31d83d02ac986c5e5e081dea29f564f
hiredis==2.2.3
humanize==0.5.1
humanize==4.10.0
icalendar==5.0.10
lxml==5.2.2
markdown2==2.4.10

View file

@ -100,7 +100,7 @@ django-add-default-value==0.10.0
# via -r requirements.in
django-amazon-ses==4.0.1
# via -r requirements.in
django-anymail==8.6
django-anymail==11.1
# via -r requirements.in
django-cors-headers==3.7.0
# via -r requirements.in
@ -217,7 +217,7 @@ httplib2==0.22.0
# via
# google-api-python-client
# google-auth-httplib2
humanize==0.5.1
humanize==4.10.0
# via -r requirements.in
icalendar==5.0.10
# via
@ -458,6 +458,7 @@ urllib3==1.26.19
# via
# -r requirements.in
# botocore
# django-anymail
# requests
uwsgi==2.0.26
# via -r requirements.in

View file

@ -468,8 +468,6 @@ TIME_ZONE = "UTC"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)

View file

@ -17,3 +17,9 @@ banned-modules =
addopts = --dist no --no-migrations --color=yes --showlocals
# https://pytest-django.readthedocs.io/en/latest/faq.html#my-tests-are-not-being-found-why
python_files = tests.py test_*.py *_tests.py
filterwarnings =
ignore:::django_filters.*
ignore:::httpretty.*
ignore:::polymorphic.*
ignore:::telegram.*