using Cleanuparr.Domain.Enums;
using Cleanuparr.Infrastructure.Events;
using Cleanuparr.Infrastructure.Events.Interfaces;
using Cleanuparr.Infrastructure.Features.DownloadClient;
using Cleanuparr.Infrastructure.Features.DownloadClient.Deluge;
using Cleanuparr.Infrastructure.Features.DownloadClient.QBittorrent;
using Cleanuparr.Infrastructure.Features.DownloadClient.RTorrent;
using Cleanuparr.Infrastructure.Features.DownloadClient.Sabnzbd;
using Cleanuparr.Infrastructure.Features.DownloadClient.Transmission;
using Cleanuparr.Infrastructure.Features.DownloadClient.UTorrent;
using Cleanuparr.Infrastructure.Features.Files;
using Cleanuparr.Infrastructure.Features.ItemStriker;
using Cleanuparr.Infrastructure.Features.MalwareBlocker;
using Cleanuparr.Infrastructure.Features.Notifications;
using Cleanuparr.Infrastructure.Http;
using Cleanuparr.Infrastructure.Interceptors;
using Cleanuparr.Infrastructure.Realtime;
using Cleanuparr.Infrastructure.Services.Interfaces;
using Cleanuparr.Persistence;
using Cleanuparr.Persistence.Models.Configuration;
using Cleanuparr.Persistence.Models.Configuration.DownloadCleaner;
using Cleanuparr.Persistence.Providers;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NSubstitute;
using Shouldly;
using Xunit;
namespace Cleanuparr.Infrastructure.Tests.Features.DownloadClient;
///
/// Guards the capability map in against drifting from what
/// each client's service actually implements: a new client type, or a service that gains or drops an
/// I*Capable interface without updating the map, fails here instead of silently falling out of
/// whichever job narrows via OfType<T>().
///
public class DownloadClientCapabilityConsistencyTests : IDisposable
{
private readonly IServiceProvider _serviceProvider;
private readonly DownloadServiceFactory _factory;
private readonly MemoryCache _memoryCache;
public DownloadClientCapabilityConsistencyTests()
{
var services = new ServiceCollection();
_memoryCache = new MemoryCache(Options.Create(new MemoryCacheOptions()));
services.AddSingleton(_memoryCache);
services.AddSingleton(Substitute.For>());
services.AddSingleton(Substitute.For>());
services.AddSingleton(Substitute.For>());
services.AddSingleton(Substitute.For>());
services.AddSingleton(Substitute.For>());
services.AddSingleton(Substitute.For>());
services.AddSingleton(Substitute.For>());
services.AddSingleton(Substitute.For());
services.AddSingleton(Substitute.For());
services.AddSingleton(Substitute.For());
services.AddSingleton(Substitute.For());
var httpClientProvider = Substitute.For();
httpClientProvider.CreateClient(Arg.Any()).Returns(new HttpClient());
services.AddSingleton(httpClientProvider);
services.AddSingleton(Substitute.For());
services.AddSingleton(Substitute.For());
services.AddSingleton(Substitute.For());
services.AddLogging();
var eventsContextOptions = new DbContextOptionsBuilder()
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
.Options;
var eventsContext = new EventsContext(eventsContextOptions);
IEventNotifier eventNotifier = Substitute.For();
services.AddSingleton(new EventPublisher(
eventsContext,
eventNotifier,
Substitute.For>(),
Substitute.For(),
Substitute.For(),
new SqliteDatabaseProvider(),
TimeProvider.System));
var scopeFactory = Substitute.For();
services.AddSingleton(new BlocklistProvider(
Substitute.For>(),
scopeFactory,
_memoryCache,
TimeProvider.System));
services.AddSingleton(TimeProvider.System);
_serviceProvider = services.BuildServiceProvider();
_factory = new DownloadServiceFactory(Substitute.For>(), _serviceProvider);
}
public void Dispose()
{
_memoryCache.Dispose();
}
public static IEnumerable