using System; using System.Collections.Generic; using System.Linq; using FluentAssertions; using Moq; using NUnit.Framework; using NzbDrone.Common.Disk; using NzbDrone.Common.Http; using NzbDrone.Core.Download; using NzbDrone.Core.Download.Clients; using NzbDrone.Core.Download.Clients.FreeboxDownload; using NzbDrone.Core.Download.Clients.FreeboxDownload.Responses; using NzbDrone.Core.Movies; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Test.Download.DownloadClientTests.FreeboxDownloadTests { [TestFixture] public class TorrentFreeboxDownloadFixture : DownloadClientFixtureBase { protected FreeboxDownloadSettings _settings; protected FreeboxDownloadConfiguration _downloadConfiguration; protected FreeboxDownloadTask _task; protected string _defaultDestination = @"/some/path"; protected string _encodedDefaultDestination = "L3NvbWUvcGF0aA=="; protected string _category = "somecat"; protected string _encodedDefaultDestinationAndCategory = "L3NvbWUvcGF0aC9zb21lY2F0"; protected string _destinationDirectory = @"/path/to/media"; protected string _encodedDestinationDirectory = "L3BhdGgvdG8vbWVkaWE="; protected OsPath _physicalPath = new OsPath("/mnt/sdb1/mydata"); protected string _downloadURL => "magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcad53426&dn=download"; [SetUp] public void Setup() { Subject.Definition = new DownloadClientDefinition(); _settings = new FreeboxDownloadSettings() { Host = "127.0.0.1", Port = 443, ApiUrl = "/api/v1/", AppId = "someid", AppToken = "S0mEv3RY1oN9T0k3n" }; Subject.Definition.Settings = _settings; _downloadConfiguration = new FreeboxDownloadConfiguration() { DownloadDirectory = _encodedDefaultDestination }; _task = new FreeboxDownloadTask() { Id = "id0", Name = "name", DownloadDirectory = "L3NvbWUvcGF0aA==", InfoHash = "HASH", QueuePosition = 1, Status = FreeboxDownloadTaskStatus.Unknown, Eta = 0, Error = "none", Type = FreeboxDownloadTaskType.Bt.ToString(), IoPriority = FreeboxDownloadTaskIoPriority.Normal.ToString(), StopRatio = 150, PieceLength = 125, CreatedTimestamp = 1665261599, Size = 1000, ReceivedPrct = 0, ReceivedBytes = 0, ReceivedRate = 0, TransmittedPrct = 0, TransmittedBytes = 0, TransmittedRate = 0, }; Mocker.GetMock() .Setup(s => s.Get(It.IsAny())) .Returns(r => new HttpResponse(r, new HttpHeader(), Array.Empty())); } protected void GivenCategory() { _settings.Category = _category; } protected void GivenDestinationDirectory() { _settings.DestinationDirectory = _destinationDirectory; } protected virtual void GivenDownloadConfiguration() { Mocker.GetMock() .Setup(s => s.GetDownloadConfiguration(It.IsAny())) .Returns(_downloadConfiguration); } protected virtual void GivenTasks(List torrents) { if (torrents == null) { torrents = new List(); } Mocker.GetMock() .Setup(s => s.GetTasks(It.IsAny())) .Returns(torrents); } protected void PrepareClientToReturnQueuedItem() { _task.Status = FreeboxDownloadTaskStatus.Queued; GivenTasks(new List { _task }); } protected void GivenSuccessfulDownload() { Mocker.GetMock() .Setup(s => s.Get(It.IsAny())) .Returns(r => new HttpResponse(r, new HttpHeader(), new byte[1000])); Mocker.GetMock() .Setup(s => s.AddTaskFromUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Callback(PrepareClientToReturnQueuedItem); Mocker.GetMock() .Setup(s => s.AddTaskFromFile(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Callback(PrepareClientToReturnQueuedItem); } protected override RemoteMovie CreateRemoteMovie() { var movie = base.CreateRemoteMovie(); movie.Release.DownloadUrl = _downloadURL; return movie; } [Test] public void Download_with_DestinationDirectory_should_force_directory() { GivenDestinationDirectory(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); Subject.Download(remoteMovie); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), _encodedDestinationDirectory, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } [Test] public void Download_with_Category_should_force_directory() { GivenDownloadConfiguration(); GivenCategory(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); Subject.Download(remoteMovie); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), _encodedDefaultDestinationAndCategory, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } [Test] public void Download_without_DestinationDirectory_and_Category_should_use_default() { GivenDownloadConfiguration(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); Subject.Download(remoteMovie); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), _encodedDefaultDestination, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } [TestCase(false, false)] [TestCase(true, true)] public void Download_should_pause_torrent_as_expected(bool addPausedSetting, bool toBePausedFlag) { _settings.AddPaused = addPausedSetting; GivenDownloadConfiguration(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); Subject.Download(remoteMovie); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), It.IsAny(), toBePausedFlag, It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } [TestCase(0, (int)FreeboxDownloadPriority.First, (int)FreeboxDownloadPriority.First, true)] [TestCase(0, (int)FreeboxDownloadPriority.Last, (int)FreeboxDownloadPriority.First, true)] [TestCase(0, (int)FreeboxDownloadPriority.First, (int)FreeboxDownloadPriority.Last, false)] [TestCase(0, (int)FreeboxDownloadPriority.Last, (int)FreeboxDownloadPriority.Last, false)] [TestCase(22, (int)FreeboxDownloadPriority.First, (int)FreeboxDownloadPriority.First, true)] [TestCase(22, (int)FreeboxDownloadPriority.Last, (int)FreeboxDownloadPriority.First, false)] [TestCase(22, (int)FreeboxDownloadPriority.First, (int)FreeboxDownloadPriority.Last, true)] [TestCase(22, (int)FreeboxDownloadPriority.Last, (int)FreeboxDownloadPriority.Last, false)] public void Download_should_queue_torrent_first_as_expected(int ageDay, int olderPriority, int recentPriority, bool toBeQueuedFirstFlag) { _settings.OlderPriority = olderPriority; _settings.RecentPriority = recentPriority; GivenDownloadConfiguration(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); remoteMovie.Movie.MovieMetadata.Value.PhysicalRelease = DateTime.UtcNow.AddDays(-ageDay); Subject.Download(remoteMovie); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), It.IsAny(), It.IsAny(), toBeQueuedFirstFlag, It.IsAny(), It.IsAny()), Times.Once()); } [TestCase(0, 0)] [TestCase(1.5, 150)] public void Download_should_define_seed_ratio_as_expected(double? providerSeedRatio, double? expectedSeedRatio) { GivenDownloadConfiguration(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); remoteMovie.SeedConfiguration = new TorrentSeedConfiguration(); remoteMovie.SeedConfiguration.Ratio = providerSeedRatio; Subject.Download(remoteMovie); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), expectedSeedRatio, It.IsAny()), Times.Once()); } [Test] public void GetItems_should_return_empty_list_if_no_tasks_available() { GivenTasks(new List()); Subject.GetItems().Should().BeEmpty(); } [Test] public void GetItems_should_return_ignore_tasks_of_unknown_type() { _task.Status = FreeboxDownloadTaskStatus.Done; _task.Type = "toto"; GivenTasks(new List { _task }); Subject.GetItems().Should().BeEmpty(); } [Test] public void GetItems_when_destinationdirectory_is_set_should_ignore_downloads_in_wrong_folder() { _settings.DestinationDirectory = @"/some/path/that/will/not/match"; _task.Status = FreeboxDownloadTaskStatus.Done; GivenTasks(new List { _task }); Subject.GetItems().Should().BeEmpty(); } [Test] public void GetItems_when_category_is_set_should_ignore_downloads_in_wrong_folder() { _settings.Category = "somecategory"; _task.Status = FreeboxDownloadTaskStatus.Done; GivenTasks(new List { _task }); Subject.GetItems().Should().BeEmpty(); } [TestCase(FreeboxDownloadTaskStatus.Downloading, false, false)] [TestCase(FreeboxDownloadTaskStatus.Done, true, true)] [TestCase(FreeboxDownloadTaskStatus.Seeding, false, false)] [TestCase(FreeboxDownloadTaskStatus.Stopped, false, false)] public void GetItems_should_return_canBeMoved_and_canBeDeleted_as_expected(FreeboxDownloadTaskStatus apiStatus, bool canMoveFilesExpected, bool canBeRemovedExpected) { _task.Status = apiStatus; GivenTasks(new List() { _task }); var items = Subject.GetItems(); items.Should().HaveCount(1); items.First().CanBeRemoved.Should().Be(canBeRemovedExpected); items.First().CanMoveFiles.Should().Be(canMoveFilesExpected); } [TestCase(FreeboxDownloadTaskStatus.Stopped, DownloadItemStatus.Paused)] [TestCase(FreeboxDownloadTaskStatus.Stopping, DownloadItemStatus.Paused)] [TestCase(FreeboxDownloadTaskStatus.Queued, DownloadItemStatus.Queued)] [TestCase(FreeboxDownloadTaskStatus.Starting, DownloadItemStatus.Downloading)] [TestCase(FreeboxDownloadTaskStatus.Downloading, DownloadItemStatus.Downloading)] [TestCase(FreeboxDownloadTaskStatus.Retry, DownloadItemStatus.Downloading)] [TestCase(FreeboxDownloadTaskStatus.Checking, DownloadItemStatus.Downloading)] [TestCase(FreeboxDownloadTaskStatus.Error, DownloadItemStatus.Warning)] [TestCase(FreeboxDownloadTaskStatus.Seeding, DownloadItemStatus.Completed)] [TestCase(FreeboxDownloadTaskStatus.Done, DownloadItemStatus.Completed)] [TestCase(FreeboxDownloadTaskStatus.Unknown, DownloadItemStatus.Downloading)] public void GetItems_should_return_item_as_downloadItemStatus(FreeboxDownloadTaskStatus apiStatus, DownloadItemStatus expectedItemStatus) { _task.Status = apiStatus; GivenTasks(new List() { _task }); var items = Subject.GetItems(); items.Should().HaveCount(1); items.First().Status.Should().Be(expectedItemStatus); } [Test] public void GetItems_should_return_decoded_destination_directory() { var decodedDownloadDirectory = "/that/the/path"; _task.Status = FreeboxDownloadTaskStatus.Done; _task.DownloadDirectory = "L3RoYXQvdGhlL3BhdGg="; GivenTasks(new List { _task }); var items = Subject.GetItems(); items.Should().HaveCount(1); items.First().OutputPath.Should().Be(decodedDownloadDirectory); } [Test] public void GetItems_should_return_message_if_tasks_in_error() { _task.Status = FreeboxDownloadTaskStatus.Error; _task.Error = "internal"; GivenTasks(new List { _task }); var items = Subject.GetItems(); items.Should().HaveCount(1); items.First().Message.Should().Be("Internal error."); items.First().Status.Should().Be(DownloadItemStatus.Warning); } } }