# -*- coding: utf-8 -*-
"""
Channel Management Tests

This module contains comprehensive test cases for the channel management
application including models, views, API endpoints, signals, and tasks.
"""

import json
import tempfile
from datetime import datetime, timedelta
from decimal import Decimal
from unittest.mock import patch, MagicMock

from django.test import TestCase, TransactionTestCase
from django.contrib.auth import get_user_model
from django.urls import reverse
from django.utils import timezone
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.cache import cache
from django.db import transaction
from django.test.utils import override_settings

from rest_framework.test import APITestCase, APIClient
from rest_framework import status

from .models import (
    Channel, ChannelZone, ChannelCodec, ChannelZoneRelation,
    EPGProgram, Jingle, JingleDetection, ChannelSchedule,
    IPSecConfiguration, OpenVPNConfiguration, WireGuardConfiguration
)
from .forms import ChannelForm, ChannelZoneForm, EPGProgramForm
from .permissions import ChannelManagementPermissions
from .tasks import (
    perform_channel_health_check, generate_jingle_fingerprint,
    update_channel_statistics, test_vpn_connection
)
from .signals import *  # Import all signals

User = get_user_model()


# ============================================================================
# Model Tests
# ============================================================================

class ChannelZoneModelTest(TestCase):
    """
    Test cases for ChannelZone model.
    """
    
    def setUp(self):
        self.zone_data = {
            'name': 'Europe West',
            'description': 'Western European broadcasting zone',
            'country': 'FR',
            'region': 'Western Europe',
            'timezone': 'Europe/Paris',
            'is_active': True
        }
    
    def test_zone_creation(self):
        """
        Test creating a channel zone.
        """
        zone = ChannelZone.objects.create(**self.zone_data)
        self.assertEqual(zone.name, 'Europe West')
        self.assertEqual(zone.country, 'FR')
        self.assertTrue(zone.is_active)
        self.assertIsNotNone(zone.created_at)
    
    def test_zone_str_representation(self):
        """
        Test string representation of zone.
        """
        zone = ChannelZone.objects.create(**self.zone_data)
        self.assertEqual(str(zone), 'Europe West')
    
    def test_zone_unique_name(self):
        """
        Test that zone names are unique.
        """
        ChannelZone.objects.create(**self.zone_data)
        
        with self.assertRaises(Exception):
            ChannelZone.objects.create(**self.zone_data)


class ChannelCodecModelTest(TestCase):
    """
    Test cases for ChannelCodec model.
    """
    
    def setUp(self):
        self.codec_data = {
            'name': 'H.264 HD',
            'description': 'High Definition H.264 codec',
            'codec_type': 'h264',
            'parameters': {'bitrate': '5000', 'resolution': '1920x1080'},
            'is_active': True
        }
    
    def test_codec_creation(self):
        """
        Test creating a channel codec.
        """
        codec = ChannelCodec.objects.create(**self.codec_data)
        self.assertEqual(codec.name, 'H.264 HD')
        self.assertEqual(codec.codec_type, 'h264')
        self.assertIsInstance(codec.parameters, dict)
    
    def test_codec_str_representation(self):
        """
        Test string representation of codec.
        """
        codec = ChannelCodec.objects.create(**self.codec_data)
        self.assertEqual(str(codec), 'H.264 HD')


class ChannelModelTest(TestCase):
    """
    Test cases for Channel model.
    """
    
    def setUp(self):
        self.codec = ChannelCodec.objects.create(
            name='Test Codec',
            codec_type='h264',
            is_active=True
        )
        
        self.channel_data = {
            'name': 'Test Channel',
            'description': 'A test television channel',
            'channel_number': '001',
            'category': 'entertainment',
            'status': 'active',
            'stream_url': 'http://example.com/stream.m3u8',
            'is_hd': True,
            'is_encrypted': False,
            'language': 'en',
            'country': 'US',
            'timezone': 'America/New_York',
            'codec': self.codec
        }
    
    def test_channel_creation(self):
        """
        Test creating a channel.
        """
        channel = Channel.objects.create(**self.channel_data)
        self.assertEqual(channel.name, 'Test Channel')
        self.assertEqual(channel.channel_number, '001')
        self.assertTrue(channel.is_hd)
        self.assertEqual(channel.codec, self.codec)
    
    def test_channel_str_representation(self):
        """
        Test string representation of channel.
        """
        channel = Channel.objects.create(**self.channel_data)
        self.assertEqual(str(channel), 'Test Channel (001)')
    
    def test_channel_health_status_default(self):
        """
        Test that health status defaults to None.
        """
        channel = Channel.objects.create(**self.channel_data)
        self.assertIsNone(channel.health_status)
        self.assertIsNone(channel.last_health_check)
    
    def test_channel_metadata_field(self):
        """
        Test metadata JSON field.
        """
        metadata = {'custom_field': 'value', 'rating': 4.5}
        self.channel_data['metadata'] = metadata
        
        channel = Channel.objects.create(**self.channel_data)
        self.assertEqual(channel.metadata, metadata)


class EPGProgramModelTest(TestCase):
    """
    Test cases for EPGProgram model.
    """
    
    def setUp(self):
        self.codec = ChannelCodec.objects.create(
            name='Test Codec',
            codec_type='h264',
            is_active=True
        )
        
        self.channel = Channel.objects.create(
            name='Test Channel',
            channel_number='001',
            category='entertainment',
            status='active',
            codec=self.codec
        )
        
        self.program_data = {
            'channel': self.channel,
            'title': 'Test Program',
            'description': 'A test television program',
            'category': 'movie',
            'genre': 'action',
            'start_time': timezone.now(),
            'end_time': timezone.now() + timedelta(hours=2),
            'duration': timedelta(hours=2),
            'rating': 'PG-13',
            'language': 'en',
            'has_subtitles': True,
            'has_ad_breaks': True
        }
    
    def test_program_creation(self):
        """
        Test creating an EPG program.
        """
        program = EPGProgram.objects.create(**self.program_data)
        self.assertEqual(program.title, 'Test Program')
        self.assertEqual(program.channel, self.channel)
        self.assertTrue(program.has_subtitles)
    
    def test_program_str_representation(self):
        """
        Test string representation of program.
        """
        program = EPGProgram.objects.create(**self.program_data)
        expected = f'Test Program - Test Channel ({program.start_time.strftime("%Y-%m-%d %H:%M")})'
        self.assertEqual(str(program), expected)


class JingleModelTest(TestCase):
    """
    Test cases for Jingle model.
    """
    
    def setUp(self):
        self.codec = ChannelCodec.objects.create(
            name='Test Codec',
            codec_type='h264',
            is_active=True
        )
        
        self.channel = Channel.objects.create(
            name='Test Channel',
            channel_number='001',
            category='entertainment',
            status='active',
            codec=self.codec
        )
        
        # Create a simple audio file for testing
        self.audio_file = SimpleUploadedFile(
            "test_jingle.mp3",
            b"fake audio content",
            content_type="audio/mpeg"
        )
        
        self.jingle_data = {
            'channel': self.channel,
            'name': 'Test Jingle',
            'description': 'A test jingle',
            'jingle_type': 'intro',
            'file': self.audio_file,
            'duration': timedelta(seconds=30),
            'volume_level': Decimal('0.8'),
            'is_active': True
        }
    
    def test_jingle_creation(self):
        """
        Test creating a jingle.
        """
        jingle = Jingle.objects.create(**self.jingle_data)
        self.assertEqual(jingle.name, 'Test Jingle')
        self.assertEqual(jingle.channel, self.channel)
        self.assertEqual(jingle.jingle_type, 'intro')
        self.assertEqual(jingle.volume_level, Decimal('0.8'))
    
    def test_jingle_str_representation(self):
        """
        Test string representation of jingle.
        """
        jingle = Jingle.objects.create(**self.jingle_data)
        self.assertEqual(str(jingle), 'Test Jingle - Test Channel')
    
    def test_jingle_play_count_default(self):
        """
        Test that play count defaults to 0.
        """
        jingle = Jingle.objects.create(**self.jingle_data)
        self.assertEqual(jingle.play_count, 0)
        self.assertIsNone(jingle.last_played)


# ============================================================================
# Form Tests
# ============================================================================

class ChannelFormTest(TestCase):
    """
    Test cases for ChannelForm.
    """
    
    def setUp(self):
        self.codec = ChannelCodec.objects.create(
            name='Test Codec',
            codec_type='h264',
            is_active=True
        )
    
    def test_valid_form(self):
        """
        Test form with valid data.
        """
        form_data = {
            'name': 'Test Channel',
            'channel_number': '001',
            'category': 'entertainment',
            'status': 'active',
            'stream_url': 'http://example.com/stream.m3u8',
            'codec': self.codec.id,
            'language': 'en',
            'country': 'US'
        }
        
        form = ChannelForm(data=form_data)
        self.assertTrue(form.is_valid())
    
    def test_invalid_form_missing_required(self):
        """
        Test form with missing required fields.
        """
        form_data = {
            'name': 'Test Channel'
            # Missing required fields
        }
        
        form = ChannelForm(data=form_data)
        self.assertFalse(form.is_valid())
        self.assertIn('channel_number', form.errors)
    
    def test_form_stream_url_validation(self):
        """
        Test stream URL validation.
        """
        form_data = {
            'name': 'Test Channel',
            'channel_number': '001',
            'category': 'entertainment',
            'status': 'active',
            'stream_url': 'invalid-url',
            'codec': self.codec.id
        }
        
        form = ChannelForm(data=form_data)
        self.assertFalse(form.is_valid())
        self.assertIn('stream_url', form.errors)


# ============================================================================
# View Tests
# ============================================================================

class ChannelViewTest(TestCase):
    """
    Test cases for channel views.
    """
    
    def setUp(self):
        self.user = User.objects.create_user(
            username='testuser',
            email='test@example.com',
            password='testpass123'
        )
        
        self.codec = ChannelCodec.objects.create(
            name='Test Codec',
            codec_type='h264',
            is_active=True
        )
        
        self.channel = Channel.objects.create(
            name='Test Channel',
            channel_number='001',
            category='entertainment',
            status='active',
            codec=self.codec
        )
    
    def test_channel_list_view(self):
        """
        Test channel list view.
        """
        self.client.login(username='testuser', password='testpass123')
        
        url = reverse('channels:channel_list')
        response = self.client.get(url)
        
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, 'Test Channel')
    
    def test_channel_detail_view(self):
        """
        Test channel detail view.
        """
        self.client.login(username='testuser', password='testpass123')
        
        url = reverse('channels:channel_detail', kwargs={'pk': self.channel.pk})
        response = self.client.get(url)
        
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, 'Test Channel')
    
    def test_channel_dashboard_view(self):
        """
        Test channel dashboard view.
        """
        self.client.login(username='testuser', password='testpass123')
        
        url = reverse('channels:dashboard')
        response = self.client.get(url)
        
        self.assertEqual(response.status_code, 200)


# ============================================================================
# API Tests
# ============================================================================

class ChannelAPITest(APITestCase):
    """
    Test cases for Channel API endpoints.
    """
    
    def setUp(self):
        self.user = User.objects.create_user(
            username='testuser',
            email='test@example.com',
            password='testpass123'
        )
        
        self.client = APIClient()
        self.client.force_authenticate(user=self.user)
        
        self.codec = ChannelCodec.objects.create(
            name='Test Codec',
            codec_type='h264',
            is_active=True
        )
        
        self.channel = Channel.objects.create(
            name='Test Channel',
            channel_number='001',
            category='entertainment',
            status='active',
            codec=self.codec
        )
    
    def test_channel_list_api(self):
        """
        Test channel list API endpoint.
        """
        url = reverse('channels:api:channel-list')
        response = self.client.get(url)
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['results']), 1)
        self.assertEqual(response.data['results'][0]['name'], 'Test Channel')
    
    def test_channel_detail_api(self):
        """
        Test channel detail API endpoint.
        """
        url = reverse('channels:api:channel-detail', kwargs={'pk': self.channel.pk})
        response = self.client.get(url)
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['name'], 'Test Channel')
        self.assertIn('statistics', response.data)
    
    def test_channel_create_api(self):
        """
        Test channel creation via API.
        """
        url = reverse('channels:api:channel-list')
        data = {
            'name': 'New Channel',
            'channel_number': '002',
            'category': 'news',
            'status': 'active',
            'codec_id': self.codec.id,
            'stream_url': 'http://example.com/new_stream.m3u8'
        }
        
        response = self.client.post(url, data, format='json')
        
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(Channel.objects.count(), 2)
    
    def test_channel_update_api(self):
        """
        Test channel update via API.
        """
        url = reverse('channels:api:channel-detail', kwargs={'pk': self.channel.pk})
        data = {
            'name': 'Updated Channel',
            'description': 'Updated description'
        }
        
        response = self.client.patch(url, data, format='json')
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.channel.refresh_from_db()
        self.assertEqual(self.channel.name, 'Updated Channel')


# ============================================================================
# Signal Tests
# ============================================================================

class ChannelSignalTest(TestCase):
    """
    Test cases for channel signals.
    """
    
    def setUp(self):
        self.codec = ChannelCodec.objects.create(
            name='Test Codec',
            codec_type='h264',
            is_active=True
        )
    
    @patch('apps.channels.tasks.perform_channel_health_check.delay')
    def test_channel_post_save_signal(self, mock_health_check):
        """
        Test that health check is triggered on channel save.
        """
        channel = Channel.objects.create(
            name='Test Channel',
            channel_number='001',
            category='entertainment',
            status='active',
            codec=self.codec
        )
        
        # Health check should be triggered for new channels
        mock_health_check.assert_called_once_with(channel.id)
    
    @patch('django.core.cache.cache.delete_many')
    def test_channel_cache_invalidation(self, mock_cache_delete):
        """
        Test that cache is invalidated on channel changes.
        """
        channel = Channel.objects.create(
            name='Test Channel',
            channel_number='001',
            category='entertainment',
            status='active',
            codec=self.codec
        )
        
        # Update the channel
        channel.name = 'Updated Channel'
        channel.save()
        
        # Cache should be invalidated
        self.assertTrue(mock_cache_delete.called)


# ============================================================================
# Task Tests
# ============================================================================

class ChannelTaskTest(TestCase):
    """
    Test cases for channel Celery tasks.
    """
    
    def setUp(self):
        self.codec = ChannelCodec.objects.create(
            name='Test Codec',
            codec_type='h264',
            is_active=True
        )
        
        self.channel = Channel.objects.create(
            name='Test Channel',
            channel_number='001',
            category='entertainment',
            status='active',
            stream_url='http://example.com/stream.m3u8',
            codec=self.codec
        )
    
    @patch('requests.get')
    def test_perform_channel_health_check_success(self, mock_get):
        """
        Test successful channel health check.
        """
        # Mock successful HTTP response
        mock_response = MagicMock()
        mock_response.status_code = 200
        mock_response.headers = {'content-type': 'application/vnd.apple.mpegurl'}
        mock_get.return_value = mock_response
        
        # Run the task
        result = perform_channel_health_check(self.channel.id)
        
        # Check results
        self.assertTrue(result['success'])
        self.channel.refresh_from_db()
        self.assertEqual(self.channel.health_status, 'healthy')
        self.assertIsNotNone(self.channel.last_health_check)
    
    @patch('requests.get')
    def test_perform_channel_health_check_failure(self, mock_get):
        """
        Test failed channel health check.
        """
        # Mock failed HTTP response
        mock_get.side_effect = Exception('Connection failed')
        
        # Run the task
        result = perform_channel_health_check(self.channel.id)
        
        # Check results
        self.assertFalse(result['success'])
        self.channel.refresh_from_db()
        self.assertEqual(self.channel.health_status, 'unhealthy')
    
    @patch('librosa.load')
    @patch('librosa.feature.mfcc')
    def test_generate_jingle_fingerprint(self, mock_mfcc, mock_load):
        """
        Test jingle fingerprint generation.
        """
        # Create a jingle
        audio_file = SimpleUploadedFile(
            "test_jingle.mp3",
            b"fake audio content",
            content_type="audio/mpeg"
        )
        
        jingle = Jingle.objects.create(
            channel=self.channel,
            name='Test Jingle',
            jingle_type='intro',
            file=audio_file,
            duration=timedelta(seconds=30)
        )
        
        # Mock librosa functions
        mock_load.return_value = ([0.1, 0.2, 0.3], 22050)
        mock_mfcc.return_value = [[0.1, 0.2], [0.3, 0.4]]
        
        # Run the task
        result = generate_jingle_fingerprint(jingle.id)
        
        # Check results
        self.assertTrue(result['success'])
        jingle.refresh_from_db()
        self.assertIsNotNone(jingle.fingerprint)
        self.assertIsNotNone(jingle.fingerprint_generated_at)


# ============================================================================
# Permission Tests
# ============================================================================

class ChannelPermissionTest(TestCase):
    """
    Test cases for channel permissions.
    """
    
    def setUp(self):
        self.user = User.objects.create_user(
            username='testuser',
            email='test@example.com',
            password='testpass123'
        )
        
        self.superuser = User.objects.create_superuser(
            username='admin',
            email='admin@example.com',
            password='adminpass123'
        )
    
    def test_channel_management_permissions(self):
        """
        Test channel management permission constants.
        """
        self.assertIsNotNone(ChannelManagementPermissions.VIEW_CHANNEL)
        self.assertIsNotNone(ChannelManagementPermissions.ADD_CHANNEL)
        self.assertIsNotNone(ChannelManagementPermissions.CHANGE_CHANNEL)
        self.assertIsNotNone(ChannelManagementPermissions.DELETE_CHANNEL)
    
    def test_superuser_has_all_permissions(self):
        """
        Test that superuser has all channel permissions.
        """
        self.assertTrue(self.superuser.has_perm(ChannelManagementPermissions.VIEW_CHANNEL))
        self.assertTrue(self.superuser.has_perm(ChannelManagementPermissions.ADD_CHANNEL))
        self.assertTrue(self.superuser.has_perm(ChannelManagementPermissions.CHANGE_CHANNEL))
        self.assertTrue(self.superuser.has_perm(ChannelManagementPermissions.DELETE_CHANNEL))


# ============================================================================
# Integration Tests
# ============================================================================

class ChannelIntegrationTest(TransactionTestCase):
    """
    Integration tests for channel management workflow.
    """
    
    def setUp(self):
        self.user = User.objects.create_user(
            username='testuser',
            email='test@example.com',
            password='testpass123'
        )
        
        self.codec = ChannelCodec.objects.create(
            name='Test Codec',
            codec_type='h264',
            is_active=True
        )
        
        self.zone = ChannelZone.objects.create(
            name='Test Zone',
            country='US',
            timezone='America/New_York',
            is_active=True
        )
    
    def test_complete_channel_workflow(self):
        """
        Test complete channel creation and management workflow.
        """
        # 1. Create channel
        channel = Channel.objects.create(
            name='Integration Test Channel',
            channel_number='999',
            category='entertainment',
            status='active',
            stream_url='http://example.com/stream.m3u8',
            codec=self.codec
        )
        
        # 2. Add zone relation
        zone_relation = ChannelZoneRelation.objects.create(
            channel=channel,
            zone=self.zone,
            priority=1,
            is_active=True
        )
        
        # 3. Add EPG program
        program = EPGProgram.objects.create(
            channel=channel,
            title='Test Program',
            category='movie',
            start_time=timezone.now(),
            end_time=timezone.now() + timedelta(hours=2),
            duration=timedelta(hours=2)
        )
        
        # 4. Add jingle
        audio_file = SimpleUploadedFile(
            "test_jingle.mp3",
            b"fake audio content",
            content_type="audio/mpeg"
        )
        
        jingle = Jingle.objects.create(
            channel=channel,
            name='Test Jingle',
            jingle_type='intro',
            file=audio_file,
            duration=timedelta(seconds=30)
        )
        
        # 5. Verify relationships
        self.assertEqual(channel.zones.count(), 1)
        self.assertEqual(channel.programs.count(), 1)
        self.assertEqual(channel.jingles.count(), 1)
        
        # 6. Test channel statistics
        self.assertEqual(channel.zones.first(), self.zone)
        self.assertEqual(channel.programs.first().title, 'Test Program')
        self.assertEqual(channel.jingles.first().name, 'Test Jingle')
    
    @patch('apps.channels.tasks.perform_channel_health_check.delay')
    def test_bulk_channel_operations(self, mock_health_check):
        """
        Test bulk operations on multiple channels.
        """
        # Create multiple channels
        channels = []
        for i in range(5):
            channel = Channel.objects.create(
                name=f'Bulk Test Channel {i}',
                channel_number=f'99{i}',
                category='entertainment',
                status='active',
                codec=self.codec
            )
            channels.append(channel)
        
        # Test bulk status update
        Channel.objects.filter(id__in=[c.id for c in channels]).update(status='inactive')
        
        # Verify all channels are inactive
        for channel in channels:
            channel.refresh_from_db()
            self.assertEqual(channel.status, 'inactive')
        
        # Health checks should have been triggered
        self.assertEqual(mock_health_check.call_count, 5)


# ============================================================================
# Performance Tests
# ============================================================================

class ChannelPerformanceTest(TestCase):
    """
    Performance tests for channel operations.
    """
    
    def setUp(self):
        self.codec = ChannelCodec.objects.create(
            name='Test Codec',
            codec_type='h264',
            is_active=True
        )
    
    def test_bulk_channel_creation_performance(self):
        """
        Test performance of bulk channel creation.
        """
        import time
        
        start_time = time.time()
        
        # Create 100 channels
        channels = []
        for i in range(100):
            channels.append(Channel(
                name=f'Performance Test Channel {i}',
                channel_number=f'{i:03d}',
                category='entertainment',
                status='active',
                codec=self.codec
            ))
        
        Channel.objects.bulk_create(channels)
        
        end_time = time.time()
        creation_time = end_time - start_time
        
        # Should create 100 channels in less than 1 second
        self.assertLess(creation_time, 1.0)
        self.assertEqual(Channel.objects.count(), 100)
    
    def test_channel_query_performance(self):
        """
        Test performance of channel queries with relationships.
        """
        # Create test data
        zone = ChannelZone.objects.create(
            name='Test Zone',
            country='US',
            timezone='America/New_York',
            is_active=True
        )
        
        channels = []
        for i in range(50):
            channel = Channel.objects.create(
                name=f'Query Test Channel {i}',
                channel_number=f'{i:03d}',
                category='entertainment',
                status='active',
                codec=self.codec
            )
            channels.append(channel)
            
            # Add zone relation
            ChannelZoneRelation.objects.create(
                channel=channel,
                zone=zone,
                priority=1,
                is_active=True
            )
        
        import time
        
        # Test query performance with select_related and prefetch_related
        start_time = time.time()
        
        channels_with_relations = Channel.objects.select_related('codec').prefetch_related(
            'zones', 'programs', 'jingles'
        ).all()
        
        # Force evaluation
        list(channels_with_relations)
        
        end_time = time.time()
        query_time = end_time - start_time
        
        # Should query all channels with relations in less than 0.1 seconds
        self.assertLess(query_time, 0.1)


# ============================================================================
# Cache Tests
# ============================================================================

class ChannelCacheTest(TestCase):
    """
    Test cases for channel caching functionality.
    """
    
    def setUp(self):
        self.codec = ChannelCodec.objects.create(
            name='Test Codec',
            codec_type='h264',
            is_active=True
        )
        
        self.channel = Channel.objects.create(
            name='Cache Test Channel',
            channel_number='001',
            category='entertainment',
            status='active',
            codec=self.codec
        )
    
    def tearDown(self):
        cache.clear()
    
    def test_channel_cache_invalidation_on_save(self):
        """
        Test that channel cache is invalidated when channel is saved.
        """
        # Set cache
        cache_key = f'channel_{self.channel.id}'
        cache.set(cache_key, self.channel, 300)
        
        # Verify cache is set
        self.assertIsNotNone(cache.get(cache_key))
        
        # Update channel (should trigger cache invalidation)
        self.channel.name = 'Updated Cache Test Channel'
        self.channel.save()
        
        # Cache should be cleared
        self.assertIsNone(cache.get(cache_key))
    
    def test_channel_statistics_caching(self):
        """
        Test caching of channel statistics.
        """
        # Create some related data
        EPGProgram.objects.create(
            channel=self.channel,
            title='Test Program',
            category='movie',
            start_time=timezone.now(),
            end_time=timezone.now() + timedelta(hours=2),
            duration=timedelta(hours=2)
        )
        
        # Test statistics caching
        stats_cache_key = f'channel_stats_{self.channel.id}'
        
        # First call should set cache
        stats = {
            'total_programs': self.channel.programs.count(),
            'total_jingles': self.channel.jingles.count(),
            'total_zones': self.channel.zones.count()
        }
        
        cache.set(stats_cache_key, stats, 300)
        
        # Verify cache is set
        cached_stats = cache.get(stats_cache_key)
        self.assertIsNotNone(cached_stats)
        self.assertEqual(cached_stats['total_programs'], 1)
