86 lines
3.7 KiB
C#
86 lines
3.7 KiB
C#
using Jellyfin.Plugin.Multilang.Services;
|
|
using Jellyfin.Plugin.Multilang.Services.Refresh;
|
|
|
|
namespace Jellyfin.Plugin.Multilang.Tests;
|
|
|
|
public sealed class RefreshCoordinatorTests
|
|
{
|
|
[Fact]
|
|
public async Task QueuedItemsUseSourceTierThenWorkClassPriority()
|
|
{
|
|
var coordinator = new RefreshCoordinator(new ItemsProxyCache());
|
|
var activeStarted = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
var releaseActive = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
var order = new List<string>();
|
|
|
|
var active = coordinator.EnqueueAsync("active", RefreshSourceTier.Background, RefreshWorkClass.Series, RefreshJobType.Full, async (_, _) =>
|
|
{
|
|
activeStarted.SetResult();
|
|
await releaseActive.Task;
|
|
return true;
|
|
}, CancellationToken.None);
|
|
await activeStarted.Task;
|
|
|
|
var series = coordinator.EnqueueAsync("series", RefreshSourceTier.Background, RefreshWorkClass.Series, RefreshJobType.Full, (_, _) =>
|
|
{
|
|
order.Add("series");
|
|
return Task.FromResult(true);
|
|
}, CancellationToken.None);
|
|
var movie = coordinator.EnqueueAsync("movie", RefreshSourceTier.Background, RefreshWorkClass.Movies, RefreshJobType.Full, (_, _) =>
|
|
{
|
|
order.Add("movie");
|
|
return Task.FromResult(true);
|
|
}, CancellationToken.None);
|
|
var onTheFlyCollection = coordinator.EnqueueAsync("collection", RefreshSourceTier.OnTheFly, RefreshWorkClass.Collections, RefreshJobType.Full, (_, _) =>
|
|
{
|
|
order.Add("collection");
|
|
return Task.FromResult(true);
|
|
}, CancellationToken.None);
|
|
|
|
releaseActive.SetResult();
|
|
await Task.WhenAll(active, series, movie, onTheFlyCollection);
|
|
|
|
Assert.Equal(["collection", "movie", "series"], order);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DuplicateQueuedItemUsesTheHighestJobAndTierAndInvalidatesCache()
|
|
{
|
|
var cache = new ItemsProxyCache();
|
|
Assert.True(cache.Store("target", "user", "/Items", ["target"], "body", "application/json", 1, 1024, TimeSpan.FromMinutes(1)));
|
|
var coordinator = new RefreshCoordinator(cache);
|
|
var activeStarted = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
var releaseActive = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
var runs = new List<RefreshJobType>();
|
|
|
|
var active = coordinator.EnqueueAsync("active", RefreshSourceTier.Background, RefreshWorkClass.Series, RefreshJobType.Full, async (_, _) =>
|
|
{
|
|
activeStarted.SetResult();
|
|
await releaseActive.Task;
|
|
return true;
|
|
}, CancellationToken.None);
|
|
await activeStarted.Task;
|
|
|
|
var missing = coordinator.EnqueueAsync("target", RefreshSourceTier.Background, RefreshWorkClass.Series, RefreshJobType.Missing, (job, _) =>
|
|
{
|
|
runs.Add(job);
|
|
return Task.FromResult(true);
|
|
}, CancellationToken.None);
|
|
var full = coordinator.EnqueueAsync("target", RefreshSourceTier.Manual, RefreshWorkClass.Series, RefreshJobType.Full, (job, _) =>
|
|
{
|
|
runs.Add(job);
|
|
return Task.FromResult(true);
|
|
}, CancellationToken.None);
|
|
|
|
Assert.Same(missing, full);
|
|
releaseActive.SetResult();
|
|
await Task.WhenAll(active, full);
|
|
|
|
Assert.Equal([RefreshJobType.Full], runs);
|
|
Assert.False(cache.TryGet("target", TimeSpan.FromMinutes(1), out _));
|
|
var recent = coordinator.GetDiagnostics().Recent.Single(item => item.ItemId == "target");
|
|
Assert.Equal("Manual", recent.SourceTier);
|
|
Assert.Equal("Full", recent.JobType);
|
|
}
|
|
}
|