Expand integration coverage and fix settings UI
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user