|
@@ -1,6 +1,8 @@
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
+using System.Threading;
|
|
|
+using System.Threading.Tasks;
|
|
|
using MediaBrowser.Controller.BaseItemManager;
|
|
|
using MediaBrowser.Controller.Configuration;
|
|
|
using MediaBrowser.Controller.Entities;
|
|
@@ -9,6 +11,7 @@ using MediaBrowser.Controller.Library;
|
|
|
using MediaBrowser.Controller.Providers;
|
|
|
using MediaBrowser.Model.Configuration;
|
|
|
using MediaBrowser.Providers.Manager;
|
|
|
+using Microsoft.Extensions.Logging;
|
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
|
using Moq;
|
|
|
using Xunit;
|
|
@@ -17,6 +20,95 @@ namespace Jellyfin.Providers.Tests.Manager
|
|
|
{
|
|
|
public class ProviderManagerTests
|
|
|
{
|
|
|
+ private static readonly ILogger<ProviderManager> _logger = new NullLogger<ProviderManager>();
|
|
|
+
|
|
|
+ private static TheoryData<Mock<IMetadataService>[], int> RefreshSingleItemOrderData()
|
|
|
+ => new ()
|
|
|
+ {
|
|
|
+ // no order set, uses provided order
|
|
|
+ {
|
|
|
+ new[]
|
|
|
+ {
|
|
|
+ MockIMetadataService(true, true),
|
|
|
+ MockIMetadataService(true, true)
|
|
|
+ },
|
|
|
+ 0
|
|
|
+ },
|
|
|
+ // sort order sets priority when all match
|
|
|
+ {
|
|
|
+ new[]
|
|
|
+ {
|
|
|
+ MockIMetadataService(true, true, 1),
|
|
|
+ MockIMetadataService(true, true, 0),
|
|
|
+ MockIMetadataService(true, true, 2)
|
|
|
+ },
|
|
|
+ 1
|
|
|
+ },
|
|
|
+ // CanRefreshPrimary prioritized
|
|
|
+ {
|
|
|
+ new[]
|
|
|
+ {
|
|
|
+ MockIMetadataService(false, true),
|
|
|
+ MockIMetadataService(true, true),
|
|
|
+ },
|
|
|
+ 1
|
|
|
+ },
|
|
|
+ // falls back to CanRefresh
|
|
|
+ {
|
|
|
+ new[]
|
|
|
+ {
|
|
|
+ MockIMetadataService(false, false),
|
|
|
+ MockIMetadataService(false, true)
|
|
|
+ },
|
|
|
+ 1
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ [Theory]
|
|
|
+ [MemberData(nameof(RefreshSingleItemOrderData))]
|
|
|
+ public void RefreshSingleItem_ServiceOrdering_FollowsPriority(Mock<IMetadataService>[] servicesList, int expectedIndex)
|
|
|
+ {
|
|
|
+ var item = new Movie();
|
|
|
+
|
|
|
+ using var providerManager = GetProviderManager();
|
|
|
+ AddParts(providerManager, metadataServices: servicesList.Select(s => s.Object).ToArray());
|
|
|
+
|
|
|
+ var refreshOptions = new MetadataRefreshOptions(Mock.Of<IDirectoryService>(MockBehavior.Strict));
|
|
|
+ var actual = providerManager.RefreshSingleItem(item, refreshOptions, CancellationToken.None);
|
|
|
+
|
|
|
+ Assert.Equal(ItemUpdateType.MetadataDownload, actual.Result);
|
|
|
+ for (var i = 0; i < servicesList.Length; i++)
|
|
|
+ {
|
|
|
+ if (i == expectedIndex)
|
|
|
+ {
|
|
|
+ servicesList[i].Verify(mock => mock.RefreshMetadata(It.IsAny<BaseItem>(), It.IsAny<MetadataRefreshOptions>(), It.IsAny<CancellationToken>()), Times.Once());
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ servicesList[i].Verify(mock => mock.RefreshMetadata(It.IsAny<BaseItem>(), It.IsAny<MetadataRefreshOptions>(), It.IsAny<CancellationToken>()), Times.Never());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [Theory]
|
|
|
+ [InlineData(true)]
|
|
|
+ [InlineData(false)]
|
|
|
+ public void RefreshSingleItem_RefreshMetadata_WhenServiceFound(bool serviceFound)
|
|
|
+ {
|
|
|
+ var item = new Movie();
|
|
|
+
|
|
|
+ var servicesList = new[] { MockIMetadataService(false, serviceFound) };
|
|
|
+
|
|
|
+ using var providerManager = GetProviderManager();
|
|
|
+ AddParts(providerManager, metadataServices: servicesList.Select(s => s.Object).ToArray());
|
|
|
+
|
|
|
+ var refreshOptions = new MetadataRefreshOptions(Mock.Of<IDirectoryService>(MockBehavior.Strict));
|
|
|
+ var actual = providerManager.RefreshSingleItem(item, refreshOptions, CancellationToken.None);
|
|
|
+
|
|
|
+ var expectedResult = serviceFound ? ItemUpdateType.MetadataDownload : ItemUpdateType.None;
|
|
|
+ Assert.Equal(expectedResult, actual.Result);
|
|
|
+ }
|
|
|
+
|
|
|
private static TheoryData<int, int[]?, int[]?, int?[]?, int[]> GetImageProvidersOrderData()
|
|
|
=> new ()
|
|
|
{
|
|
@@ -313,6 +405,20 @@ namespace Jellyfin.Providers.Tests.Manager
|
|
|
Assert.Equal(expected ? 1 : 0, actualProviders.Length);
|
|
|
}
|
|
|
|
|
|
+ private static Mock<IMetadataService> MockIMetadataService(bool refreshPrimary, bool canRefresh, int order = 0)
|
|
|
+ {
|
|
|
+ var service = new Mock<IMetadataService>(MockBehavior.Strict);
|
|
|
+ service.Setup(s => s.Order)
|
|
|
+ .Returns(order);
|
|
|
+ service.Setup(s => s.CanRefreshPrimary(It.IsAny<Type>()))
|
|
|
+ .Returns(refreshPrimary);
|
|
|
+ service.Setup(s => s.CanRefresh(It.IsAny<BaseItem>()))
|
|
|
+ .Returns(canRefresh);
|
|
|
+ service.Setup(s => s.RefreshMetadata(It.IsAny<BaseItem>(), It.IsAny<MetadataRefreshOptions>(), It.IsAny<CancellationToken>()))
|
|
|
+ .Returns(Task.FromResult(ItemUpdateType.MetadataDownload));
|
|
|
+ return service;
|
|
|
+ }
|
|
|
+
|
|
|
private static IImageProvider MockIImageProvider<TProviderType>(string name, BaseItem expectedType, bool supports = true, int? order = null, bool errorOnSupported = false)
|
|
|
where TProviderType : class, IImageProvider
|
|
|
{
|
|
@@ -460,11 +566,11 @@ namespace Jellyfin.Providers.Tests.Manager
|
|
|
null,
|
|
|
serverConfigurationManager.Object,
|
|
|
null,
|
|
|
- new NullLogger<ProviderManager>(),
|
|
|
+ _logger,
|
|
|
null,
|
|
|
null,
|
|
|
libraryManager.Object,
|
|
|
- baseItemManager);
|
|
|
+ baseItemManager!);
|
|
|
|
|
|
return providerManager;
|
|
|
}
|