104 lines
3.6 KiB
Python
104 lines
3.6 KiB
Python
import pytest
|
|
import os
|
|
from datetime import timedelta
|
|
from django.utils import timezone
|
|
from core.models import Channel, MediaSource, MediaItem, Airing
|
|
from api.routers.channel import channel_now_playing
|
|
from django.conf import settings
|
|
|
|
@pytest.mark.django_db
|
|
def test_channel_signaling_now_playing():
|
|
"""
|
|
Test what file should be playing on a channel, and whether the API
|
|
response correctly signals an existing local file or fallback.
|
|
"""
|
|
channel = Channel.objects.first()
|
|
if not channel:
|
|
pytest.skip("No channels found in test database to test signaling")
|
|
|
|
# Clear current airings to set up a controlled test
|
|
Airing.objects.filter(channel=channel).delete()
|
|
|
|
source = MediaSource.objects.first()
|
|
|
|
# 1. Test a fully downloaded video
|
|
good_item = MediaItem.objects.create(
|
|
title="Valid Cached Video",
|
|
media_source=source,
|
|
cached_file_path=os.path.join(settings.MEDIA_ROOT, "test_valid.mp4"),
|
|
runtime_seconds=600,
|
|
is_active=True
|
|
)
|
|
|
|
# Create a dummy file to simulate it existing
|
|
os.makedirs(settings.MEDIA_ROOT, exist_ok=True)
|
|
with open(good_item.cached_file_path, 'w') as f:
|
|
f.write("dummy video data")
|
|
|
|
now = timezone.now()
|
|
|
|
airing = Airing.objects.create(
|
|
channel=channel,
|
|
media_item=good_item,
|
|
starts_at=now - timedelta(minutes=5),
|
|
ends_at=now + timedelta(minutes=5),
|
|
slot_kind="program"
|
|
)
|
|
|
|
# Call the API function
|
|
response = channel_now_playing(None, channel.id)
|
|
|
|
# Assertions
|
|
assert response is not None, "API should return an airing"
|
|
assert response.media_item_title == "Valid Cached Video"
|
|
assert response.media_item_path is not None, "A valid path must be returned"
|
|
|
|
# Check if the returned path maps to a real file
|
|
if not response.media_item_path.startswith("http"):
|
|
# The API returns a URL path like /media/..., we need to strip /media to get rel_path
|
|
rel_path = response.media_item_path.replace(settings.MEDIA_URL, "")
|
|
fs_path = os.path.join(settings.MEDIA_ROOT, rel_path)
|
|
assert os.path.exists(fs_path), f"Signaled file {fs_path} does not actually exist!"
|
|
|
|
# Cleanup
|
|
if os.path.exists(good_item.cached_file_path):
|
|
os.remove(good_item.cached_file_path)
|
|
|
|
@pytest.mark.django_db
|
|
def test_channel_signaling_youtube_raw_url():
|
|
"""
|
|
Test what happens if the video is NOT downloaded and only has a raw YouTube URL.
|
|
This demonstrates the bug where the frontend fails to play it.
|
|
"""
|
|
channel = Channel.objects.first()
|
|
if not channel:
|
|
pytest.skip("No channels found")
|
|
|
|
Airing.objects.filter(channel=channel).delete()
|
|
source = MediaSource.objects.filter(source_type__icontains='youtube').first()
|
|
if not source:
|
|
pytest.skip("No youtube source found")
|
|
|
|
raw_item = MediaItem.objects.create(
|
|
title="Uncached YouTube URL",
|
|
media_source=source,
|
|
file_path="https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
|
cached_file_path=None,
|
|
runtime_seconds=600,
|
|
is_active=True
|
|
)
|
|
|
|
now = timezone.now()
|
|
Airing.objects.create(
|
|
channel=channel,
|
|
media_item=raw_item,
|
|
starts_at=now - timedelta(minutes=5),
|
|
ends_at=now + timedelta(minutes=5),
|
|
slot_kind="program"
|
|
)
|
|
|
|
response = channel_now_playing(None, channel.id)
|
|
assert response is not None
|
|
assert response.media_item_path == "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
|
print(f"\\nWARNING: Backend signaled {response.media_item_path} which HTML5 <video> CANNOT play directly.")
|