import pytest from django.utils import timezone from datetime import timedelta from core.models import MediaSource, MediaItem, Channel, ScheduleBlock, ChannelSourceRule, Airing, AppUser, Library from api.routers.channel import AiringSchema from django.test import Client @pytest.fixture def test_channel(db): user = AppUser.objects.create(username="playback_tester") library = Library.objects.create(name="Test Library", owner_user=user) channel = Channel.objects.create(name="Test Channel", channel_number=10, owner_user=user, library=library) source = MediaSource.objects.create(library=library, name="Test Source", source_type="solid_color") ChannelSourceRule.objects.create(channel=channel, media_source=source, rule_mode='allow', weight=1.0) # Create media item item = MediaItem.objects.create( media_source=source, title="Color Loop", item_kind="solid_color", runtime_seconds=600 # 10 minutes length ) return channel, item import uuid @pytest.mark.django_db def test_playback_offset_calculation(test_channel): channel, item = test_channel now = timezone.now() # Airing started exactly 3 minutes ago starts_at = now - timedelta(minutes=3) ends_at = starts_at + timedelta(minutes=30) airing = Airing.objects.create( channel=channel, media_item=item, starts_at=starts_at, ends_at=ends_at, slot_kind='content', generation_batch_uuid=uuid.uuid4() ) schema = AiringSchema.from_airing(airing) # Airing started 3 minutes (180 seconds) ago. # The item runtime is 600s, so offset is simply 180s. assert schema.exact_playback_offset_seconds == pytest.approx(180.0, rel=1e-2) @pytest.mark.django_db def test_playback_offset_modulo(test_channel): channel, item = test_channel now = timezone.now() # Airing started exactly 14 minutes ago starts_at = now - timedelta(minutes=14) ends_at = starts_at + timedelta(minutes=30) airing = Airing.objects.create( channel=channel, media_item=item, starts_at=starts_at, ends_at=ends_at, slot_kind='content', generation_batch_uuid=uuid.uuid4() ) schema = AiringSchema.from_airing(airing) # 14 minutes = 840 seconds. # Video is 600 seconds. # 840 % 600 = 240 seconds offset into the second loop. assert schema.exact_playback_offset_seconds == pytest.approx(240.0, rel=1e-2) @pytest.mark.django_db def test_channel_now_api_returns_offset(test_channel, client: Client): channel, item = test_channel now = timezone.now() starts_at = now - timedelta(seconds=45) ends_at = starts_at + timedelta(minutes=10) Airing.objects.create( channel=channel, media_item=item, starts_at=starts_at, ends_at=ends_at, slot_kind='content', generation_batch_uuid=uuid.uuid4() ) response = client.get(f"/api/channel/{channel.id}/now") assert response.status_code == 200 data = response.json() assert "exact_playback_offset_seconds" in data assert data["exact_playback_offset_seconds"] == pytest.approx(45.0, rel=1e-1)