Duncan Tourolle ac6a3842dd
Some checks failed
🏗️ Build Plugin / call (push) Failing after 0s
📝 Create/Update Release Draft & Release Bump PR / call (push) Failing after 0s
🧪 Test Plugin / call (push) Failing after 0s
🔬 Run CodeQL / call (push) Failing after 0s
first commit
2025-11-12 22:05:36 +01:00

285 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Plugin.SRFPlay.Api;
using Jellyfin.Plugin.SRFPlay.Api.Models;
using Jellyfin.Plugin.SRFPlay.Configuration;
using Jellyfin.Plugin.SRFPlay.Services;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Plugin.SRFPlay.Tests
{
class Program
{
static async Task Main(string[] args)
{
// Run the new Play v3 API tests
await TestPlayV3Api.RunTests();
Console.WriteLine("\n\n");
Console.WriteLine("=================================================================");
Console.WriteLine("OLD API TESTS (DEPRECATED - Expected to fail)");
Console.WriteLine("=================================================================\n");
Console.WriteLine("=== SRFPlay Plugin Test Suite (Old API) ===\n");
// Setup logging
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Warning); // Only show warnings and errors
});
var apiClient = new SRFApiClient(loggerFactory);
var streamResolver = new StreamUrlResolver(loggerFactory.CreateLogger<StreamUrlResolver>());
var cancellationToken = CancellationToken.None;
// Test 1: Check API connectivity
Console.WriteLine("[Test 1] API Connectivity Test");
Console.WriteLine("-------------------------------");
try
{
var latestVideos = await apiClient.GetLatestVideosAsync("srf", cancellationToken);
if (latestVideos?.ChapterList != null && latestVideos.ChapterList.Any())
{
Console.WriteLine($"✓ Successfully fetched latest videos: {latestVideos.ChapterList.Count} items");
Console.WriteLine($" First video: {latestVideos.ChapterList[0]?.Title}");
}
else
{
Console.WriteLine("✗ Failed: No videos returned");
}
}
catch (Exception ex)
{
Console.WriteLine($"✗ Error: {ex.Message}");
}
Console.WriteLine();
// Test 2: Check trending videos
Console.WriteLine("[Test 2] Trending Videos Test");
Console.WriteLine("-----------------------------");
try
{
var trendingVideos = await apiClient.GetTrendingVideosAsync("srf", cancellationToken);
if (trendingVideos?.ChapterList != null && trendingVideos.ChapterList.Any())
{
Console.WriteLine($"✓ Successfully fetched trending videos: {trendingVideos.ChapterList.Count} items");
Console.WriteLine($" First video: {trendingVideos.ChapterList[0]?.Title}");
}
else
{
Console.WriteLine("✗ Failed: No videos returned");
}
}
catch (Exception ex)
{
Console.WriteLine($"✗ Error: {ex.Message}");
}
Console.WriteLine();
// Test 3: Get specific video and check stream URL
Console.WriteLine("[Test 3] Stream URL Resolution Test");
Console.WriteLine("-----------------------------------");
try
{
var latestVideos = await apiClient.GetLatestVideosAsync("srf", cancellationToken);
if (latestVideos?.ChapterList != null && latestVideos.ChapterList.Any())
{
var firstChapter = latestVideos.ChapterList[0];
Console.WriteLine($"Testing with: {firstChapter.Title}");
Console.WriteLine($"URN: {firstChapter.Urn}");
// Fetch full media composition for this URN
var mediaComposition = await apiClient.GetMediaCompositionByUrnAsync(firstChapter.Urn, cancellationToken);
if (mediaComposition?.ChapterList != null && mediaComposition.ChapterList.Any())
{
var chapter = mediaComposition.ChapterList[0];
// Check if content is playable
bool hasPlayableContent = streamResolver.HasPlayableContent(chapter);
Console.WriteLine($"Has playable content: {hasPlayableContent}");
// Check if content is expired
bool isExpired = streamResolver.IsContentExpired(chapter);
Console.WriteLine($"Is expired: {isExpired}");
// Try to get stream URL
if (hasPlayableContent && !isExpired)
{
var streamUrl = streamResolver.GetStreamUrl(chapter, Jellyfin.Plugin.SRFPlay.Configuration.QualityPreference.Auto);
if (!string.IsNullOrEmpty(streamUrl))
{
Console.WriteLine($"✓ Stream URL resolved: {streamUrl.Substring(0, Math.Min(80, streamUrl.Length))}...");
// Show available resources
if (chapter.ResourceList != null)
{
Console.WriteLine($" Available resources: {chapter.ResourceList.Count}");
foreach (var resource in chapter.ResourceList.Take(5))
{
var hasDrm = resource.DrmList != null && resource.DrmList.ToString() != "[]";
Console.WriteLine($" - {resource.Quality} ({resource.Protocol}) {(hasDrm ? "[DRM]" : "[No DRM]")}");
}
}
}
else
{
Console.WriteLine("✗ Failed to resolve stream URL");
}
}
else
{
if (!hasPlayableContent)
Console.WriteLine("✗ Content is not playable (likely DRM protected)");
if (isExpired)
Console.WriteLine($"✗ Content is expired (ValidTo: {chapter.ValidTo})");
}
}
else
{
Console.WriteLine("✗ Failed to fetch media composition");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"✗ Error: {ex.Message}");
Console.WriteLine($"Stack trace: {ex.StackTrace}");
}
Console.WriteLine();
// Test 4: Check multiple videos for playability
Console.WriteLine("[Test 4] Multiple Videos Playability Check");
Console.WriteLine("------------------------------------------");
try
{
var latestVideos = await apiClient.GetLatestVideosAsync("srf", cancellationToken);
if (latestVideos?.ChapterList != null)
{
int totalVideos = Math.Min(10, latestVideos.ChapterList.Count);
int playableCount = 0;
int expiredCount = 0;
int drmCount = 0;
Console.WriteLine($"Checking {totalVideos} videos...\n");
for (int i = 0; i < totalVideos; i++)
{
var chapter = latestVideos.ChapterList[i];
var mediaComp = await apiClient.GetMediaCompositionByUrnAsync(chapter.Urn, cancellationToken);
if (mediaComp?.ChapterList != null && mediaComp.ChapterList.Any())
{
var fullChapter = mediaComp.ChapterList[0];
bool hasPlayable = streamResolver.HasPlayableContent(fullChapter);
bool isExpired = streamResolver.IsContentExpired(fullChapter);
string status;
if (isExpired)
{
status = "EXPIRED";
expiredCount++;
}
else if (!hasPlayable)
{
status = "DRM";
drmCount++;
}
else
{
status = "PLAYABLE";
playableCount++;
}
Console.WriteLine($"{i + 1}. [{status}] {fullChapter.Title}");
}
}
Console.WriteLine();
Console.WriteLine($"Summary:");
Console.WriteLine($" Playable: {playableCount}/{totalVideos} ({(playableCount * 100.0 / totalVideos):F1}%)");
Console.WriteLine($" DRM Protected: {drmCount}/{totalVideos} ({(drmCount * 100.0 / totalVideos):F1}%)");
Console.WriteLine($" Expired: {expiredCount}/{totalVideos} ({(expiredCount * 100.0 / totalVideos):F1}%)");
}
}
catch (Exception ex)
{
Console.WriteLine($"✗ Error: {ex.Message}");
}
Console.WriteLine();
// Test 5: Test library content discovery (simulates what would be in the library)
Console.WriteLine("[Test 5] Library Content Discovery Simulation");
Console.WriteLine("----------------------------------------------");
try
{
var latestVideos = await apiClient.GetLatestVideosAsync("srf", cancellationToken);
var trendingVideos = await apiClient.GetTrendingVideosAsync("srf", cancellationToken);
var allUrns = new HashSet<string>();
if (latestVideos?.ChapterList != null)
{
foreach (var chapter in latestVideos.ChapterList)
{
if (!string.IsNullOrEmpty(chapter.Urn))
allUrns.Add(chapter.Urn);
}
}
if (trendingVideos?.ChapterList != null)
{
foreach (var chapter in trendingVideos.ChapterList)
{
if (!string.IsNullOrEmpty(chapter.Urn))
allUrns.Add(chapter.Urn);
}
}
Console.WriteLine($"✓ Latest videos available: {latestVideos?.ChapterList?.Count ?? 0}");
Console.WriteLine($"✓ Trending videos available: {trendingVideos?.ChapterList?.Count ?? 0}");
Console.WriteLine($"✓ Total unique items for library (deduplicated): {allUrns.Count}");
}
catch (Exception ex)
{
Console.WriteLine($"✗ Error: {ex.Message}");
}
Console.WriteLine();
// Test 6: Test different business units
Console.WriteLine("[Test 6] Business Units Test");
Console.WriteLine("----------------------------");
var businessUnits = new[] { "srf", "rts", "rsi", "rtr", "swi" };
foreach (var bu in businessUnits)
{
try
{
var videos = await apiClient.GetLatestVideosAsync(bu, cancellationToken);
if (videos?.ChapterList != null && videos.ChapterList.Any())
{
Console.WriteLine($"✓ {bu.ToUpper()}: {videos.ChapterList.Count} videos available");
}
else
{
Console.WriteLine($"✗ {bu.ToUpper()}: No videos found");
}
}
catch (Exception ex)
{
Console.WriteLine($"✗ {bu.ToUpper()}: Error - {ex.Message}");
}
}
Console.WriteLine();
Console.WriteLine("=== Test Suite Complete ===");
}
}
}