From 8ca356303beb81d34306d74a6e0907c6bf198094 Mon Sep 17 00:00:00 2001 From: Kyle Robbertze Date: Tue, 21 Sep 2021 21:42:57 +0200 Subject: [PATCH] correctly filter schedule items based on is_valid Fixes: #1360 --- .../tests/models/test_schedule.py | 4 +- api/libretimeapi/tests/test_views.py | 62 ++++++++++++++++--- api/libretimeapi/views.py | 13 +++- 3 files changed, 67 insertions(+), 12 deletions(-) diff --git a/api/libretimeapi/tests/models/test_schedule.py b/api/libretimeapi/tests/models/test_schedule.py index 4892c3385..9392a723f 100644 --- a/api/libretimeapi/tests/models/test_schedule.py +++ b/api/libretimeapi/tests/models/test_schedule.py @@ -1,10 +1,10 @@ from datetime import datetime, timedelta -from django.test import SimpleTestCase +from django.test import TestCase from libretimeapi.models import Schedule, ShowInstance -class TestSchedule(SimpleTestCase): +class TestSchedule(TestCase): @classmethod def setUpTestData(cls): cls.show_instance = ShowInstance( diff --git a/api/libretimeapi/tests/test_views.py b/api/libretimeapi/tests/test_views.py index a4693a14f..5ec6acf81 100644 --- a/api/libretimeapi/tests/test_views.py +++ b/api/libretimeapi/tests/test_views.py @@ -1,5 +1,5 @@ import os -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from django.conf import settings from django.contrib.auth.models import AnonymousUser @@ -66,13 +66,13 @@ class TestScheduleViewSet(APITestCase): ) show = baker.make( "libretimeapi.ShowInstance", - starts=datetime.now(tz=datetime.timezone.utc) - timedelta(minutes=5), - ends=datetime.now(tz=datetime.timezone.utc) + timedelta(minutes=5), + starts=datetime.now(tz=timezone.utc) - timedelta(minutes=5), + ends=datetime.now(tz=timezone.utc) + timedelta(minutes=5), ) scheduleItem = baker.make( "libretimeapi.Schedule", - starts=datetime.now(tz=datetime.timezone.utc), - ends=datetime.now(tz=datetime.timezone.utc) + f.length, + starts=datetime.now(tz=timezone.utc), + ends=datetime.now(tz=timezone.utc) + f.length, cue_out=f.cueout, instance=show, file=f, @@ -100,13 +100,13 @@ class TestScheduleViewSet(APITestCase): ) show = baker.make( "libretimeapi.ShowInstance", - starts=datetime.now(tz=datetime.timezone.utc) - timedelta(minutes=5), - ends=datetime.now(tz=datetime.timezone.utc) + timedelta(seconds=20), + starts=datetime.now(tz=timezone.utc) - timedelta(minutes=5), + ends=datetime.now(tz=timezone.utc) + timedelta(seconds=20), ) scheduleItem = baker.make( "libretimeapi.Schedule", - starts=datetime.now(tz=datetime.timezone.utc), - ends=datetime.now(tz=datetime.timezone.utc) + f.length, + starts=datetime.now(tz=timezone.utc), + ends=datetime.now(tz=timezone.utc) + f.length, instance=show, file=f, ) @@ -120,3 +120,47 @@ class TestScheduleViewSet(APITestCase): self.assertNotEqual( dateparse.parse_datetime(result[0]["ends"]), scheduleItem.ends ) + + def test_schedule_item_invalid(self): + music_dir = baker.make( + "libretimeapi.MusicDir", + directory=os.path.join(os.path.dirname(__file__), "resources"), + ) + f = baker.make( + "libretimeapi.File", + directory=music_dir, + mime="audio/mp3", + filepath="song.mp3", + length=timedelta(seconds=40.86), + cuein=timedelta(seconds=0), + cueout=timedelta(seconds=40.8131), + ) + show = baker.make( + "libretimeapi.ShowInstance", + starts=datetime.now(tz=timezone.utc) - timedelta(minutes=5), + ends=datetime.now(tz=timezone.utc) + timedelta(minutes=5), + ) + scheduleItem = baker.make( + "libretimeapi.Schedule", + starts=datetime.now(tz=timezone.utc), + ends=datetime.now(tz=timezone.utc) + f.length, + cue_out=f.cueout, + instance=show, + file=f, + ) + invalidScheduleItem = baker.make( + "libretimeapi.Schedule", + starts=show.ends + timedelta(minutes=1), + ends=show.ends + timedelta(minutes=1) + f.length, + cue_out=f.cueout, + instance=show, + file=f, + ) + self.client.credentials(HTTP_AUTHORIZATION="Api-Key {}".format(self.token)) + response = self.client.get(self.path, {"is_valid": True}) + self.assertEqual(response.status_code, 200) + result = response.json() + # The invalid item should be filtered out and not returned + self.assertEqual(len(result), 1) + self.assertEqual(dateparse.parse_datetime(result[0]["ends"]), scheduleItem.ends) + self.assertEqual(dateparse.parse_duration(result[0]["cue_out"]), f.cueout) diff --git a/api/libretimeapi/views.py b/api/libretimeapi/views.py index 7bc360717..1863af685 100644 --- a/api/libretimeapi/views.py +++ b/api/libretimeapi/views.py @@ -1,6 +1,7 @@ import os from django.conf import settings +from django.db.models import F from django.http import FileResponse from django.shortcuts import get_object_or_404 from rest_framework import status, viewsets @@ -141,9 +142,19 @@ class PreferenceViewSet(viewsets.ModelViewSet): class ScheduleViewSet(viewsets.ModelViewSet): queryset = Schedule.objects.all() serializer_class = ScheduleSerializer - filter_fields = ("starts", "ends", "playout_status", "broadcasted", "is_valid") + filter_fields = ("starts", "ends", "playout_status", "broadcasted") model_permission_name = "schedule" + def get_queryset(self): + filter_valid = self.request.query_params.get("is_valid") + if filter_valid is None: + return self.queryset.all() + filter_valid = filter_valid.strip().lower() in ["true", "yes", "1"] + if filter_valid: + return self.queryset.filter(starts__lt=F("instance__ends")) + else: + return self.queryset.filter(starts__gte=F("instance__ends")) + class ServiceRegisterViewSet(viewsets.ModelViewSet): queryset = ServiceRegister.objects.all()