diff --git a/exceptional_situations/management/commands/import_traffic_situations.py b/exceptional_situations/management/commands/import_traffic_situations.py index a936a1f9..61ccf8e5 100644 --- a/exceptional_situations/management/commands/import_traffic_situations.py +++ b/exceptional_situations/management/commands/import_traffic_situations.py @@ -4,13 +4,12 @@ import logging from copy import deepcopy -from datetime import datetime +from datetime import datetime, timezone import requests from dateutil import parser from django.contrib.gis.geos import GEOSGeometry, Polygon from django.core.management import BaseCommand -from django.utils import timezone from munigeo.models import Municipality from exceptional_situations.models import ( @@ -148,7 +147,7 @@ def save_features(self, features): if release_time.microsecond != 0: release_time.replace(microsecond=0) - release_time = timezone.make_aware(release_time, timezone.utc) + release_time = release_time.replace(tzinfo=timezone.utc) type_name = properties.get("situationType", None) sub_type_name = properties.get("trafficAnnouncementType", None) diff --git a/exceptional_situations/models.py b/exceptional_situations/models.py index a4c10d61..894b92e8 100644 --- a/exceptional_situations/models.py +++ b/exceptional_situations/models.py @@ -68,12 +68,14 @@ def situation_sub_type_str(self) -> str: @property def is_active(self) -> bool: + now = datetime.now().replace(tzinfo=timezone.get_default_timezone()) if not self.announcements.exists(): return False start_times_in_future = all( - {a.start_time > timezone.now() for a in self.announcements.all()} + {a.start_time > now for a in self.announcements.all()} ) + # If all start times are in future, return False if start_times_in_future: return False @@ -84,7 +86,7 @@ def is_active(self) -> bool: # If end_time is past for all announcements, return True, else False return any( { - a.end_time > timezone.now() + a.end_time > now for a in self.announcements.filter(end_time__isnull=False) } ) diff --git a/exceptional_situations/tests/conftest.py b/exceptional_situations/tests/conftest.py index 18ebb85d..cb3e5048 100644 --- a/exceptional_situations/tests/conftest.py +++ b/exceptional_situations/tests/conftest.py @@ -1,4 +1,4 @@ -from datetime import timedelta +from datetime import datetime, timedelta import pytest from django.contrib.gis.geos import GEOSGeometry @@ -13,14 +13,17 @@ SituationType, ) -NOW = timezone.now() - @pytest.fixture def api_client(): return APIClient() +@pytest.fixture +def now(): + return datetime.now().replace(tzinfo=timezone.get_default_timezone()) + + @pytest.mark.django_db @pytest.fixture def municipalities(): @@ -58,15 +61,16 @@ def locations(): @pytest.mark.django_db @pytest.fixture -def announcements(locations, municipalities): +def announcements(locations, municipalities, now): + json_data = {"test_key": "test_value"} sa = SituationAnnouncement.objects.create( - title="two hours", - description="two hours long situation", + title="Twelve hours", + description="Twelve hours long situation", additional_info=json_data, location=locations[0], - start_time=NOW - timedelta(hours=1), - end_time=NOW + timedelta(hours=1), + start_time=now, + end_time=now + timedelta(hours=12), ) sa.municipalities.add(municipalities.filter(id="turku").first()) sa.municipalities.add(municipalities.filter(id="lieto").first()) @@ -75,8 +79,8 @@ def announcements(locations, municipalities): description="two days long situation", additional_info=json_data, location=locations[1], - start_time=NOW - timedelta(days=1), - end_time=NOW + timedelta(days=1), + start_time=now - timedelta(days=1), + end_time=now + timedelta(days=1), ) sa.municipalities.add(municipalities.filter(id="raisio").first()) return SituationAnnouncement.objects.all() @@ -84,24 +88,24 @@ def announcements(locations, municipalities): @pytest.mark.django_db @pytest.fixture -def inactive_announcements(locations): +def inactive_announcements(locations, now): json_data = {"test_key": "test_value"} SituationAnnouncement.objects.create( title="in past", description="inactive announcement", additional_info=json_data, location=locations[2], - start_time=NOW - timedelta(days=2), - end_time=NOW - timedelta(days=1), + start_time=now - timedelta(days=2), + end_time=now - timedelta(days=1), ) return SituationAnnouncement.objects.all() @pytest.mark.django_db @pytest.fixture -def inactive_situations(situation_types, inactive_announcements): +def inactive_situations(situation_types, inactive_announcements, now): situation = Situation.objects.create( - release_time=NOW, + release_time=now, situation_id="inactive", situation_type=situation_types.first(), ) @@ -111,15 +115,15 @@ def inactive_situations(situation_types, inactive_announcements): @pytest.mark.django_db @pytest.fixture -def situations(situation_types, announcements): +def situations(situation_types, announcements, now): situation = Situation.objects.create( - release_time=NOW, - situation_id="TwoHoursLong", + release_time=now, + situation_id="TwelveHoursLong", situation_type=situation_types.first(), ) situation.announcements.add(announcements[0]) situation = Situation.objects.create( - release_time=NOW - timedelta(days=1), + release_time=now - timedelta(days=1), situation_id="TwoDaysLong", situation_type=situation_types.first(), ) diff --git a/exceptional_situations/tests/test_api.py b/exceptional_situations/tests/test_api.py index cc32fc3f..d1f979c4 100644 --- a/exceptional_situations/tests/test_api.py +++ b/exceptional_situations/tests/test_api.py @@ -1,7 +1,6 @@ from datetime import datetime, timedelta import pytest -from django.utils import timezone from rest_framework.reverse import reverse SITUATION_LIST_URL = reverse("exceptional_situations:situation-list") @@ -70,12 +69,13 @@ def test_situation_retrieve(api_client, situations): @pytest.mark.django_db -def test_situation_filter_by_start_time(api_client, situations): - start_time = timezone.now() +def test_situation_filter_by_start_time(api_client, situations, now): + start_time = now - timedelta(hours=6) response = api_client.get( SITUATION_LIST_URL + f"?start_time__gt={datetime.strftime(start_time, DATETIME_FORMAT)}" ) + assert response.json()["count"] == 1 response = api_client.get( SITUATION_LIST_URL @@ -83,7 +83,7 @@ def test_situation_filter_by_start_time(api_client, situations): ) assert response.json()["count"] == 1 - start_time = timezone.now() - timedelta(days=2) + start_time = now - timedelta(days=2) response = api_client.get( SITUATION_LIST_URL + f"?start_time__gt={datetime.strftime(start_time, DATETIME_FORMAT)}" @@ -97,8 +97,8 @@ def test_situation_filter_by_start_time(api_client, situations): @pytest.mark.django_db -def test_situation_filter_by_end_time(api_client, situations): - end_time = timezone.now() +def test_situation_filter_by_end_time(api_client, situations, now): + end_time = now response = api_client.get( SITUATION_LIST_URL + f"?end_time__gt={datetime.strftime(end_time, DATETIME_FORMAT)}" @@ -110,7 +110,7 @@ def test_situation_filter_by_end_time(api_client, situations): ) assert response.json()["count"] == 0 - end_time = timezone.now() - timedelta(days=2) + end_time = now - timedelta(days=2) response = api_client.get( SITUATION_LIST_URL + f"?end_time__gt={datetime.strftime(end_time, DATETIME_FORMAT)}" diff --git a/exceptional_situations/tests/test_models.py b/exceptional_situations/tests/test_models.py index db1c38fc..56ee23d1 100644 --- a/exceptional_situations/tests/test_models.py +++ b/exceptional_situations/tests/test_models.py @@ -1,58 +1,57 @@ from datetime import timedelta import pytest -from django.utils import timezone from exceptional_situations.models import Situation, SituationAnnouncement -NOW = timezone.now() - @pytest.mark.django_db -def test_situation_is_active(situation_types): - announcement_1 = SituationAnnouncement.objects.create(start_time=NOW, title="test1") - announcement_2 = SituationAnnouncement.objects.create(start_time=NOW, title="test2") +def test_situation_is_active(situation_types, now): + + announcement_1 = SituationAnnouncement.objects.create(start_time=now, title="test1") + announcement_2 = SituationAnnouncement.objects.create(start_time=now, title="test2") situation = Situation.objects.create( - release_time=NOW, situation_type=situation_types.first(), situation_id="TestID" + release_time=now, situation_type=situation_types.first(), situation_id="TestID" ) + # No announcements, returns False assert situation.is_active is False situation.announcements.add(announcement_1) situation.announcements.add(announcement_2) assert situation.is_active is True - announcement_1.start_time = NOW - timedelta(days=2) - announcement_1.end_time = NOW - timedelta(days=1) + announcement_1.start_time = now - timedelta(days=2) + announcement_1.end_time = now - timedelta(days=1) announcement_1.save() - announcement_2.start_time = NOW - timedelta(hours=2) - announcement_2.end_time = NOW - timedelta(hours=1) + announcement_2.start_time = now - timedelta(hours=2) + announcement_2.end_time = now - timedelta(hours=1) announcement_2.save() assert situation.is_active is False - announcement_2.start_time = NOW - timedelta(hours=2) - announcement_2.end_time = NOW + timedelta(hours=1) + announcement_2.start_time = now - timedelta(hours=2) + announcement_2.end_time = now + timedelta(hours=1) announcement_2.save() assert situation.is_active is True # Test that returns False if all start times are in future - announcement_1.start_time = NOW + timedelta(days=2) - announcement_1.end_time = NOW + timedelta(days=3) + announcement_1.start_time = now + timedelta(days=2) + announcement_1.end_time = now + timedelta(days=3) announcement_1.save() - announcement_2.start_time = NOW + timedelta(hours=2) - announcement_2.end_time = NOW + timedelta(hours=3) + announcement_2.start_time = now + timedelta(hours=2) + announcement_2.end_time = now + timedelta(hours=3) announcement_2.save() assert situation.is_active is False @pytest.mark.django_db -def test_situation_start_time(situation_types): +def test_situation_start_time(situation_types, now): announcement_1 = SituationAnnouncement.objects.create( - start_time=NOW, title="starts now" + start_time=now, title="starts now" ) announcement_2 = SituationAnnouncement.objects.create( - start_time=NOW - timedelta(hours=1), title="started an hour ago" + start_time=now - timedelta(hours=1), title="started an hour ago" ) situation = Situation.objects.create( - release_time=NOW, situation_type=situation_types.first(), situation_id="TestID" + release_time=now, situation_type=situation_types.first(), situation_id="TestID" ) situation.announcements.add(announcement_1) situation.announcements.add(announcement_2) @@ -60,17 +59,17 @@ def test_situation_start_time(situation_types): @pytest.mark.django_db -def test_situation_end_time(situation_types): +def test_situation_end_time(situation_types, now): announcement_1 = SituationAnnouncement.objects.create( - start_time=NOW - timedelta(hours=1), - end_time=NOW + timedelta(hours=2), + start_time=now - timedelta(hours=1), + end_time=now + timedelta(hours=2), title="ends after two hours", ) announcement_2 = SituationAnnouncement.objects.create( - start_time=NOW, end_time=NOW + timedelta(days=2), title="ends after two days" + start_time=now, end_time=now + timedelta(days=2), title="ends after two days" ) situation = Situation.objects.create( - release_time=NOW, situation_type=situation_types.first(), situation_id="TestID" + release_time=now, situation_type=situation_types.first(), situation_id="TestID" ) situation.announcements.add(announcement_1) situation.announcements.add(announcement_2)