285 lines
12 KiB
C#
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 ===");
|
|
}
|
|
}
|
|
}
|