235 lines
7.6 KiB
C#
235 lines
7.6 KiB
C#
using System.Reflection;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using Moq;
|
|
using RdtClient.Data.Models.Data;
|
|
using RdtClient.Service.BackgroundServices;
|
|
using RdtClient.Service.Services;
|
|
|
|
namespace RdtClient.Service.Test.BackgroundServices;
|
|
|
|
public class WatchFolderCheckerTests : IDisposable
|
|
{
|
|
private readonly Mock<ILogger<WatchFolderChecker>> _loggerMock;
|
|
private readonly Mock<IServiceProvider> _scopeServiceProviderMock;
|
|
private readonly Mock<IServiceProvider> _serviceProviderMock;
|
|
private readonly Mock<IServiceScope> _serviceScopeMock;
|
|
private readonly String _testPath;
|
|
private readonly TestSettings _settings;
|
|
private readonly Mock<Torrents> _torrentsServiceMock;
|
|
|
|
public WatchFolderCheckerTests()
|
|
{
|
|
_loggerMock = new();
|
|
_serviceProviderMock = new();
|
|
_serviceScopeMock = new();
|
|
_scopeServiceProviderMock = new();
|
|
_settings = new(new()
|
|
{
|
|
Watch = new()
|
|
{
|
|
Interval = 0,
|
|
Default = new()
|
|
},
|
|
DownloadClient = new()
|
|
});
|
|
_torrentsServiceMock = new(null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, _settings, new TorrentRunnerState());
|
|
|
|
_serviceProviderMock
|
|
.Setup(x => x.GetService(typeof(IServiceScopeFactory)))
|
|
.Returns(new MockScopeFactory(_serviceScopeMock.Object));
|
|
|
|
_serviceScopeMock
|
|
.Setup(x => x.ServiceProvider)
|
|
.Returns(_scopeServiceProviderMock.Object);
|
|
|
|
_scopeServiceProviderMock
|
|
.Setup(x => x.GetService(typeof(Torrents)))
|
|
.Returns(_torrentsServiceMock.Object);
|
|
|
|
_testPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
|
Directory.CreateDirectory(_testPath);
|
|
|
|
SetStartupReady(true);
|
|
_settings.Current.Watch.Path = _testPath;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (Directory.Exists(_testPath))
|
|
{
|
|
Directory.Delete(_testPath, true);
|
|
}
|
|
}
|
|
|
|
private static void SetStartupReady(Boolean ready)
|
|
{
|
|
var property = typeof(Startup).GetProperty("Ready", BindingFlags.Public | BindingFlags.Static);
|
|
property?.SetValue(null, ready);
|
|
}
|
|
|
|
private static void ResetPrevCheck(WatchFolderChecker checker)
|
|
{
|
|
var field = typeof(WatchFolderChecker).GetField("_prevCheck", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
field?.SetValue(checker, DateTime.MinValue);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ExecuteAsync_ShouldProcessTorrentFile()
|
|
{
|
|
// Arrange
|
|
var filePath = Path.Combine(_testPath, "test.torrent");
|
|
var content = "torrent content"u8.ToArray();
|
|
await File.WriteAllBytesAsync(filePath, content);
|
|
|
|
var checker = new WatchFolderChecker(_loggerMock.Object, _serviceProviderMock.Object, _settings);
|
|
ResetPrevCheck(checker);
|
|
|
|
var cts = new CancellationTokenSource();
|
|
|
|
_torrentsServiceMock
|
|
.Setup(x => x.AddFileToDebridQueue(It.IsAny<Byte[]>(), It.IsAny<Torrent>()))
|
|
.ReturnsAsync(new Torrent());
|
|
|
|
// Act
|
|
var task = checker.StartAsync(cts.Token);
|
|
await Task.Delay(500); // Give it some time to process
|
|
await cts.CancelAsync();
|
|
|
|
try
|
|
{
|
|
await task;
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
}
|
|
|
|
// Assert
|
|
_torrentsServiceMock.Verify(x => x.AddFileToDebridQueue(It.Is<Byte[]>(b => b.AsEnumerable().SequenceEqual(content)),
|
|
It.IsAny<Torrent>()),
|
|
Times.AtLeastOnce);
|
|
|
|
Assert.False(File.Exists(filePath));
|
|
Assert.True(File.Exists(Path.Combine(_testPath, "processed", "test.torrent")));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ExecuteAsync_ShouldProcessMagnetFile()
|
|
{
|
|
// Arrange
|
|
var filePath = Path.Combine(_testPath, "test.magnet");
|
|
var content = "magnet:?xt=urn:btih:123";
|
|
await File.WriteAllTextAsync(filePath, content);
|
|
|
|
var checker = new WatchFolderChecker(_loggerMock.Object, _serviceProviderMock.Object, _settings);
|
|
ResetPrevCheck(checker);
|
|
|
|
var cts = new CancellationTokenSource();
|
|
|
|
_torrentsServiceMock
|
|
.Setup(x => x.AddMagnetToDebridQueue(It.IsAny<String>(), It.IsAny<Torrent>()))
|
|
.ReturnsAsync(new Torrent());
|
|
|
|
// Act
|
|
var task = checker.StartAsync(cts.Token);
|
|
await Task.Delay(500);
|
|
await cts.CancelAsync();
|
|
|
|
try
|
|
{
|
|
await task;
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
}
|
|
|
|
// Assert
|
|
_torrentsServiceMock.Verify(x => x.AddMagnetToDebridQueue(content,
|
|
It.IsAny<Torrent>()),
|
|
Times.AtLeastOnce);
|
|
|
|
Assert.False(File.Exists(filePath));
|
|
Assert.True(File.Exists(Path.Combine(_testPath, "processed", "test.magnet")));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ExecuteAsync_ShouldProcessNzbFile()
|
|
{
|
|
// Arrange
|
|
var filePath = Path.Combine(_testPath, "test.nzb");
|
|
var content = "nzb content"u8.ToArray();
|
|
await File.WriteAllBytesAsync(filePath, content);
|
|
|
|
var checker = new WatchFolderChecker(_loggerMock.Object, _serviceProviderMock.Object, _settings);
|
|
ResetPrevCheck(checker);
|
|
|
|
var cts = new CancellationTokenSource();
|
|
|
|
_torrentsServiceMock
|
|
.Setup(x => x.AddNzbFileToDebridQueue(It.IsAny<Byte[]>(), It.IsAny<String>(), It.IsAny<Torrent>()))
|
|
.ReturnsAsync(new Torrent());
|
|
|
|
// Act
|
|
var task = checker.StartAsync(cts.Token);
|
|
await Task.Delay(500);
|
|
await cts.CancelAsync();
|
|
|
|
try
|
|
{
|
|
await task;
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
}
|
|
|
|
// Assert
|
|
_torrentsServiceMock.Verify(x => x.AddNzbFileToDebridQueue(It.Is<Byte[]>(b => b.AsEnumerable().SequenceEqual(content)),
|
|
"test.nzb",
|
|
It.IsAny<Torrent>()),
|
|
Times.AtLeastOnce);
|
|
|
|
Assert.False(File.Exists(filePath));
|
|
Assert.True(File.Exists(Path.Combine(_testPath, "processed", "test.nzb")));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ExecuteAsync_ShouldIgnoreOtherFiles()
|
|
{
|
|
// Arrange
|
|
var filePath = Path.Combine(_testPath, "test.txt");
|
|
await File.WriteAllTextAsync(filePath, "ignore me");
|
|
|
|
var checker = new WatchFolderChecker(_loggerMock.Object, _serviceProviderMock.Object, _settings);
|
|
ResetPrevCheck(checker);
|
|
|
|
var cts = new CancellationTokenSource();
|
|
|
|
// Act
|
|
var task = checker.StartAsync(cts.Token);
|
|
await Task.Delay(500);
|
|
await cts.CancelAsync();
|
|
|
|
try
|
|
{
|
|
await task;
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
}
|
|
|
|
// Assert
|
|
_torrentsServiceMock.Verify(x => x.AddFileToDebridQueue(It.IsAny<Byte[]>(), It.IsAny<Torrent>()), Times.Never);
|
|
_torrentsServiceMock.Verify(x => x.AddMagnetToDebridQueue(It.IsAny<String>(), It.IsAny<Torrent>()), Times.Never);
|
|
_torrentsServiceMock.Verify(x => x.AddNzbFileToDebridQueue(It.IsAny<Byte[]>(), It.IsAny<String>(), It.IsAny<Torrent>()), Times.Never);
|
|
|
|
Assert.True(File.Exists(filePath));
|
|
}
|
|
|
|
private class MockScopeFactory(IServiceScope scope) : IServiceScopeFactory
|
|
{
|
|
public IServiceScope CreateScope()
|
|
{
|
|
return scope;
|
|
}
|
|
}
|
|
}
|