using System; using System.Linq; using System.Threading; using System.Threading.Tasks; using Jellyfin.Plugin.SRFPlay.Api; using Microsoft.Extensions.Logging; namespace Jellyfin.Plugin.SRFPlay.Tests { public class TestPlayV3Api { public static async Task RunTests() { Console.WriteLine("=== Play v3 API Test Suite ===\n"); using var loggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); builder.SetMinimumLevel(LogLevel.Warning); }); var apiClient = new SRFApiClient(loggerFactory); var cancellationToken = CancellationToken.None; // Test 1: Get all shows Console.WriteLine("[Test 1] Fetch All Shows"); Console.WriteLine("------------------------"); try { var shows = await apiClient.GetAllShowsAsync("srf", cancellationToken); if (shows != null && shows.Any()) { Console.WriteLine($"✓ Successfully fetched {shows.Count} shows"); Console.WriteLine($" First show: {shows[0]?.Title} ({shows[0]?.NumberOfEpisodes} episodes)"); Console.WriteLine($" Show ID: {shows[0]?.Id}"); Console.WriteLine($" URN: {shows[0]?.Urn}"); } else { Console.WriteLine("✗ Failed: No shows returned"); } } catch (Exception ex) { Console.WriteLine($"✗ Error: {ex.Message}"); } Console.WriteLine(); // Test 2: Get videos for a show Console.WriteLine("[Test 2] Fetch Videos for a Show"); Console.WriteLine("--------------------------------"); try { var shows = await apiClient.GetAllShowsAsync("srf", cancellationToken); if (shows != null && shows.Any()) { // Find a show with episodes var showWithEpisodes = shows.FirstOrDefault(s => s.NumberOfEpisodes > 0); if (showWithEpisodes != null && showWithEpisodes.Id != null) { Console.WriteLine($"Testing with show: {showWithEpisodes.Title}"); var videos = await apiClient.GetVideosForShowAsync("srf", showWithEpisodes.Id, cancellationToken); if (videos != null && videos.Any()) { Console.WriteLine($"✓ Successfully fetched {videos.Count} videos"); var firstVideo = videos[0]; Console.WriteLine($" First video: {firstVideo?.Title}"); Console.WriteLine($" URN: {firstVideo?.Urn}"); Console.WriteLine($" Duration: {firstVideo?.Duration / 1000}s"); Console.WriteLine($" Date: {firstVideo?.Date}"); Console.WriteLine($" Playable abroad: {firstVideo?.PlayableAbroad}"); } else { Console.WriteLine("✗ Failed: No videos returned"); } } else { Console.WriteLine("✗ Failed: No shows with episodes found"); } } } catch (Exception ex) { Console.WriteLine($"✗ Error: {ex.Message}"); } Console.WriteLine(); // Test 3: Get video stream URL using Integration Layer Console.WriteLine("[Test 3] Get Stream URL for Video"); Console.WriteLine("---------------------------------"); try { var shows = await apiClient.GetAllShowsAsync("srf", cancellationToken); if (shows != null && shows.Any()) { var showWithEpisodes = shows.FirstOrDefault(s => s.NumberOfEpisodes > 0); if (showWithEpisodes != null && showWithEpisodes.Id != null) { var videos = await apiClient.GetVideosForShowAsync("srf", showWithEpisodes.Id, cancellationToken); if (videos != null && videos.Any()) { var video = videos[0]; if (video.Urn != null) { Console.WriteLine($"Fetching stream for: {video.Title}"); // Use Integration Layer 2.0 to get stream URL var mediaComposition = await apiClient.GetMediaCompositionByUrnAsync(video.Urn, cancellationToken); if (mediaComposition?.ChapterList != null && mediaComposition.ChapterList.Any()) { var chapter = mediaComposition.ChapterList[0]; if (chapter.ResourceList != null && chapter.ResourceList.Any()) { var hlsResource = chapter.ResourceList.FirstOrDefault(r => r.Protocol == "HLS" && (r.DrmList == null || r.DrmList.ToString() == "[]")); if (hlsResource != null) { Console.WriteLine($"✓ Stream URL found:"); Console.WriteLine($" URL: {hlsResource.Url?.Substring(0, Math.Min(80, hlsResource.Url?.Length ?? 0))}..."); Console.WriteLine($" Quality: {hlsResource.Quality}"); Console.WriteLine($" Protocol: {hlsResource.Protocol}"); } else { Console.WriteLine("✗ No HLS stream without DRM found"); } } else { Console.WriteLine("✗ No resources found"); } } else { Console.WriteLine("✗ Failed to fetch media composition"); } } } } } } catch (Exception ex) { Console.WriteLine($"✗ Error: {ex.Message}"); } Console.WriteLine(); // Test 4: Check multiple shows Console.WriteLine("[Test 4] Check Multiple Shows"); Console.WriteLine("----------------------------"); try { var shows = await apiClient.GetAllShowsAsync("srf", cancellationToken); if (shows != null) { var showsWithEpisodes = shows.Where(s => s.NumberOfEpisodes > 0).Take(10).ToList(); Console.WriteLine($"Checking {showsWithEpisodes.Count} shows with episodes...\n"); int successCount = 0; foreach (var show in showsWithEpisodes) { if (show.Id != null) { var videos = await apiClient.GetVideosForShowAsync("srf", show.Id, cancellationToken); if (videos != null && videos.Any()) { Console.WriteLine($"✓ {show.Title}: {videos.Count} videos available"); successCount++; } else { Console.WriteLine($"✗ {show.Title}: No videos found"); } } } Console.WriteLine(); Console.WriteLine($"Summary: {successCount}/{showsWithEpisodes.Count} shows successfully fetched videos"); } } catch (Exception ex) { Console.WriteLine($"✗ Error: {ex.Message}"); } Console.WriteLine(); // Test 5: Test all business units Console.WriteLine("[Test 5] Test All Business Units"); Console.WriteLine("--------------------------------"); var businessUnits = new[] { "srf", "rts", "rsi", "rtr", "swi" }; foreach (var bu in businessUnits) { try { var shows = await apiClient.GetAllShowsAsync(bu, cancellationToken); if (shows != null && shows.Any()) { Console.WriteLine($"✓ {bu.ToUpper()}: {shows.Count} shows available"); } else { Console.WriteLine($"✗ {bu.ToUpper()}: No shows found"); } } catch (Exception ex) { Console.WriteLine($"✗ {bu.ToUpper()}: Error - {ex.Message}"); } } Console.WriteLine(); Console.WriteLine("=== Test Suite Complete ==="); } } }