diff --git a/NzbDrone.Common/DiskProvider.cs b/NzbDrone.Common/DiskProvider.cs index 66b7414bf..a0e10589a 100644 --- a/NzbDrone.Common/DiskProvider.cs +++ b/NzbDrone.Common/DiskProvider.cs @@ -42,6 +42,14 @@ namespace NzbDrone.Common .Max(c => c.LastWriteTimeUtc); } + public virtual DateTime GetLastFileWrite(string path) + { + if (!FileExists(path)) + throw new FileNotFoundException("File doesn't exist: " + path); + + return new FileInfo(path).LastWriteTimeUtc; + } + public virtual bool FolderExists(string path) { return Directory.Exists(path); @@ -209,5 +217,13 @@ namespace NzbDrone.Common { return String.Equals(firstPath.NormalizePath(), secondPath.NormalizePath(), StringComparison.InvariantCultureIgnoreCase); } + + public virtual long GetFileSize(string path) + { + if (!FileExists(path)) + throw new FileNotFoundException("File doesn't exist: " + path); + + return new FileInfo(path).Length; + } } } \ No newline at end of file diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index 78d59655d..20c5a8d66 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -114,8 +114,14 @@ + + + + + + @@ -139,9 +145,9 @@ - + - + @@ -157,9 +163,9 @@ - + - + diff --git a/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTest.cs b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTest.cs deleted file mode 100644 index 8973b29c0..000000000 --- a/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTest.cs +++ /dev/null @@ -1,376 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Linq.Expressions; -using FizzWare.NBuilder; -using FluentAssertions; -using Moq; -using NUnit.Framework; -using NzbDrone.Common; -using NzbDrone.Core.Model; -using NzbDrone.Core.Providers; -using NzbDrone.Core.Providers.Core; -using NzbDrone.Core.Repository; -using NzbDrone.Core.Repository.Quality; -using NzbDrone.Core.Test.Framework; -using NzbDrone.Test.Common; -using NzbDrone.Test.Common.AutoMoq; - -namespace NzbDrone.Core.Test.ProviderTests -{ - // ReSharper disable InconsistentNaming - public class DiskScanProviderTest : CoreTest - { - [Test] - public void scan_series_should_update_the_last_scan_date() - { - - - Mocker.GetMock() - .Setup(c => c.UpdateSeries(It.Is(s => s.LastDiskSync != null))).Verifiable(); - - Mocker.GetMock() - .Setup(c => c.GetEpisodeBySeries(It.IsAny())) - .Returns(new List { new Episode() }); - - Mocker.GetMock() - .Setup(c => c.FolderExists(It.IsAny())) - .Returns(true); - - Mocker.GetMock() - .Setup(c => c.GetSeriesFiles(It.IsAny())) - .Returns(new List()); - - Mocker.Resolve().Scan(new Series()); - - Mocker.VerifyAllMocks(); - - } - - [Test] - public void cleanup_should_skip_existing_files() - { - WithStrictMocker(); - var episodes = Builder.CreateListOfSize(10).Build(); - - Mocker.GetMock() - .Setup(e => e.FileExists(It.IsAny())) - .Returns(true); - - - //Act - Mocker.Resolve().CleanUp(episodes); - - //Assert - Mocker.VerifyAllMocks(); - } - - [Test] - public void cleanup_should_delete_none_existing_files() - { - WithStrictMocker(); - var episodes = Builder.CreateListOfSize(10).Build(); - - Mocker.GetMock() - .Setup(e => e.FileExists(It.IsAny())) - .Returns(false); - - Mocker.GetMock() - .Setup(e => e.GetEpisodesByFileId(It.IsAny())) - .Returns(new List()); - - Mocker.GetMock() - .Setup(e => e.Delete(It.IsAny())); - - - //Act - Mocker.Resolve().CleanUp(episodes); - - //Assert - Mocker.VerifyAllMocks(); - - Mocker.GetMock() - .Verify(e => e.GetEpisodesByFileId(It.IsAny()), Times.Exactly(10)); - - Mocker.GetMock() - .Verify(e => e.Delete(It.IsAny()), Times.Exactly(10)); - - } - - [Test] - public void cleanup_should_delete_none_existing_files_remove_links_to_episodes() - { - WithStrictMocker(); - var episodes = Builder.CreateListOfSize(10).Build(); - - Mocker.GetMock() - .Setup(e => e.FileExists(It.IsAny())) - .Returns(false); - - Mocker.GetMock() - .Setup(e => e.GetEpisodesByFileId(It.IsAny())) - .Returns(new List { new Episode { EpisodeFileId = 10 }, new Episode { EpisodeFileId = 10 } }); - - Mocker.GetMock() - .Setup(e => e.UpdateEpisode(It.IsAny())); - - Mocker.GetMock() - .Setup(e => e.Delete(It.IsAny())); - - Mocker.GetMock() - .SetupGet(s => s.AutoIgnorePreviouslyDownloadedEpisodes) - .Returns(true); - - //Act - Mocker.Resolve().CleanUp(episodes); - - //Assert - Mocker.VerifyAllMocks(); - - Mocker.GetMock() - .Verify(e => e.GetEpisodesByFileId(It.IsAny()), Times.Exactly(10)); - - Mocker.GetMock() - .Verify(e => e.UpdateEpisode(It.Is(g=>g.EpisodeFileId == 0)), Times.Exactly(20)); - - Mocker.GetMock() - .Verify(e => e.Delete(It.IsAny()), Times.Exactly(10)); - - Mocker.GetMock() - .Verify(e => e.Delete(It.IsAny()), Times.Exactly(10)); - - } - - [Test] - public void scan_series_should_log_warning_if_path_doesnt_exist_on_disk() - { - //Setup - WithStrictMocker(); - - var series = Builder.CreateNew() - .With(s => s.Path = @"C:\Test\TV\SeriesName\") - .Build(); - - - Mocker.GetMock() - .Setup(c => c.CleanUpDatabase()); - - - Mocker.GetMock() - .Setup(c => c.FolderExists(series.Path)) - .Returns(false); - - //Act - Mocker.Resolve().Scan(series, series.Path); - - //Assert - Mocker.VerifyAllMocks(); - ExceptionVerification.ExpectedWarns(1); - } - - [Test] - public void move_should_not_move_file_if_source_and_destination_are_the_same_path() - { - var fakeSeries = Builder.CreateNew() - .With(s => s.SeriesId = 5) - .With(s => s.Title = "30 Rock") - .Build(); - - var fakeEpisode = Builder.CreateListOfSize(1) - .All() - .With(e => e.SeriesId = fakeSeries.SeriesId) - .With(e => e.SeasonNumber = 1) - .With(e => e.EpisodeNumber = 1) - .Build(); - - const string filename = @"30 Rock - S01E01 - TBD"; - var fi = new FileInfo(Path.Combine(@"C:\Test\TV\30 Rock\Season 01\", filename + ".avi")); - - var file = Builder.CreateNew() - .With(f => f.SeriesId = fakeSeries.SeriesId) - .With(f => f.Path = fi.FullName) - .Build(); - - Mocker.GetMock() - .Setup(e => e.GetSeries(fakeSeries.SeriesId)) - .Returns(fakeSeries); - - Mocker.GetMock() - .Setup(e => e.GetEpisodesByFileId(file.EpisodeFileId)) - .Returns(fakeEpisode); - - Mocker.GetMock() - .Setup(e => e.GetNewFilename(fakeEpisode, fakeSeries.Title, It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(filename); - - Mocker.GetMock() - .Setup(e => e.CalculateFilePath(It.IsAny(), fakeEpisode.First().SeasonNumber, filename, ".avi")) - .Returns(fi); - - //Act - var result = Mocker.Resolve().MoveEpisodeFile(file, false); - - //Assert - result.Should().BeNull(); - } - - [Test] - public void CleanUpDropFolder_should_do_nothing_if_no_files_are_found() - { - //Setup - var folder = @"C:\Test\DropDir\The Office"; - - Mocker.GetMock().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories)) - .Returns(new string[0]); - - //Act - Mocker.Resolve().CleanUpDropFolder(folder); - - //Assert - Mocker.GetMock().Verify(v => v.GetFileByPath(It.IsAny()), Times.Never()); - } - - [Test] - public void CleanUpDropFolder_should_do_nothing_if_no_conflicting_files_are_found() - { - //Setup - var folder = @"C:\Test\DropDir\The Office"; - var filename = Path.Combine(folder, "NotAProblem.avi"); - - var episodeFile = Builder.CreateNew() - .With(f => f.Path = filename.NormalizePath()) - .With(f => f.SeriesId = 12345) - .Build(); - - Mocker.GetMock().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories)) - .Returns(new string[] { filename }); - - Mocker.GetMock().Setup(s => s.GetFileByPath(filename)) - .Returns(() => null); - - //Act - Mocker.Resolve().CleanUpDropFolder(folder); - - //Assert - Mocker.GetMock().Verify(v => v.GetFileByPath(filename), Times.Once()); - Mocker.GetMock().Verify(v => v.GetSeries(It.IsAny()), Times.Never()); - } - - [Test] - public void CleanUpDropFolder_should_move_file_if_a_conflict_is_found() - { - //Setup - var folder = @"C:\Test\DropDir\The Office"; - var filename = Path.Combine(folder, "Problem.avi"); - var seriesId = 12345; - var newFilename = "S01E01 - Title"; - var newFilePath = @"C:\Test\TV\The Office\Season 01\S01E01 - Title.avi"; - - var episodeFile = Builder.CreateNew() - .With(f => f.Path = filename.NormalizePath()) - .With(f => f.SeriesId = seriesId) - .Build(); - - var series = Builder.CreateNew() - .With(s => s.SeriesId = seriesId) - .With(s => s.Title = "The Office") - .Build(); - - var episode = Builder.CreateListOfSize(1) - .All() - .With(e => e.SeriesId = seriesId) - .With(e => e.EpisodeFileId = episodeFile.EpisodeFileId) - .Build(); - - Mocker.GetMock().Setup(v => v.GetFileByPath(filename)) - .Returns(() => null); - - Mocker.GetMock().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories)) - .Returns(new string[] { filename }); - - Mocker.GetMock().Setup(s => s.GetFileByPath(filename)) - .Returns(episodeFile); - - Mocker.GetMock().Setup(s => s.GetSeries(It.IsAny())) - .Returns(series); - - Mocker.GetMock().Setup(s => s.GetEpisodesByFileId(episodeFile.EpisodeFileId)) - .Returns(episode); - - Mocker.GetMock().Setup(s => s.GetNewFilename(It.IsAny>(), series.Title, QualityTypes.Unknown, false, It.IsAny())) - .Returns(newFilename); - - Mocker.GetMock().Setup(s => s.CalculateFilePath(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(new FileInfo(newFilePath)); - - Mocker.GetMock().Setup(s => s.MoveFile(episodeFile.Path, newFilePath)); - - //Act - Mocker.Resolve().CleanUpDropFolder(folder); - - //Assert - Mocker.GetMock().Verify(v => v.GetFileByPath(filename), Times.Once()); - Mocker.GetMock().Verify(v => v.MoveFile(filename.NormalizePath(), newFilePath), Times.Once()); - } - - [Test] - public void MoveEpisodeFile_should_use_EpisodeFiles_quality() - { - var fakeSeries = Builder.CreateNew() - .With(s => s.SeriesId = 5) - .With(s => s.Title = "30 Rock") - .Build(); - - var fakeEpisode = Builder.CreateListOfSize(1) - .All() - .With(e => e.SeriesId = fakeSeries.SeriesId) - .With(e => e.SeasonNumber = 1) - .With(e => e.EpisodeNumber = 1) - .Build(); - - const string filename = @"30 Rock - S01E01 - TBD"; - var fi = new FileInfo(Path.Combine(@"C:\Test\TV\30 Rock\Season 01\", filename + ".mkv")); - var currentFilename = Path.Combine(@"C:\Test\TV\30 Rock\Season 01\", "30.Rock.S01E01.Test.WED-DL.mkv"); - const string message = "30 Rock - 1x01 - [WEBDL]"; - - var file = Builder.CreateNew() - .With(f => f.SeriesId = fakeSeries.SeriesId) - .With(f => f.Path = currentFilename) - .With(f => f.Quality = QualityTypes.WEBDL) - .With(f => f.Proper = false) - .Build(); - - Mocker.GetMock() - .Setup(e => e.GetSeries(fakeSeries.SeriesId)) - .Returns(fakeSeries); - - Mocker.GetMock() - .Setup(e => e.GetEpisodesByFileId(file.EpisodeFileId)) - .Returns(fakeEpisode); - - Mocker.GetMock() - .Setup(e => e.GetNewFilename(fakeEpisode, fakeSeries.Title, It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(filename); - - Mocker.GetMock() - .Setup(e => e.CalculateFilePath(It.IsAny(), fakeEpisode.First().SeasonNumber, filename, ".mkv")) - .Returns(fi); - - Mocker.GetMock() - .Setup(s => s.GetDownloadTitle(It.Is(e => e.Quality == new Quality{ QualityType = QualityTypes.WEBDL, Proper = false }))) - .Returns(message); - - Mocker.GetMock() - .Setup(e => e.OnDownload("30 Rock - 1x01 - [WEBDL]", It.IsAny())); - - //Act - var result = Mocker.Resolve().MoveEpisodeFile(file, true); - - //Assert - result.Should().NotBeNull(); - Mocker.GetMock() - .Verify(e => e.OnDownload("30 Rock - 1x01 - [WEBDL]", It.IsAny()), Times.Once()); - } - } -} diff --git a/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/CleanUpDropFolderFixture.cs b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/CleanUpDropFolderFixture.cs new file mode 100644 index 000000000..87d308148 --- /dev/null +++ b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/CleanUpDropFolderFixture.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using FizzWare.NBuilder; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using NzbDrone.Common; +using NzbDrone.Core.Model; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Providers.Core; +using NzbDrone.Core.Repository; +using NzbDrone.Core.Repository.Quality; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Test.Common; +using NzbDrone.Test.Common.AutoMoq; + +namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests +{ + // ReSharper disable InconsistentNaming + public class CleanUpDropFolderFixture : CoreTest + { + [Test] + public void should_do_nothing_if_no_files_are_found() + { + //Setup + var folder = @"C:\Test\DropDir\The Office"; + + Mocker.GetMock().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories)) + .Returns(new string[0]); + + //Act + Mocker.Resolve().CleanUpDropFolder(folder); + + //Assert + Mocker.GetMock().Verify(v => v.GetFileByPath(It.IsAny()), Times.Never()); + } + + [Test] + public void should_do_nothing_if_no_conflicting_files_are_found() + { + //Setup + var folder = @"C:\Test\DropDir\The Office"; + var filename = Path.Combine(folder, "NotAProblem.avi"); + + var episodeFile = Builder.CreateNew() + .With(f => f.Path = filename.NormalizePath()) + .With(f => f.SeriesId = 12345) + .Build(); + + Mocker.GetMock().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories)) + .Returns(new string[] { filename }); + + Mocker.GetMock().Setup(s => s.GetFileByPath(filename)) + .Returns(() => null); + + //Act + Mocker.Resolve().CleanUpDropFolder(folder); + + //Assert + Mocker.GetMock().Verify(v => v.GetFileByPath(filename), Times.Once()); + Mocker.GetMock().Verify(v => v.GetSeries(It.IsAny()), Times.Never()); + } + + [Test] + public void should_move_file_if_a_conflict_is_found() + { + //Setup + var folder = @"C:\Test\DropDir\The Office"; + var filename = Path.Combine(folder, "Problem.avi"); + var seriesId = 12345; + var newFilename = "S01E01 - Title"; + var newFilePath = @"C:\Test\TV\The Office\Season 01\S01E01 - Title.avi"; + + var episodeFile = Builder.CreateNew() + .With(f => f.Path = filename.NormalizePath()) + .With(f => f.SeriesId = seriesId) + .Build(); + + var series = Builder.CreateNew() + .With(s => s.SeriesId = seriesId) + .With(s => s.Title = "The Office") + .Build(); + + var episode = Builder.CreateListOfSize(1) + .All() + .With(e => e.SeriesId = seriesId) + .With(e => e.EpisodeFileId = episodeFile.EpisodeFileId) + .Build(); + + Mocker.GetMock().Setup(v => v.GetFileByPath(filename)) + .Returns(() => null); + + Mocker.GetMock().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories)) + .Returns(new string[] { filename }); + + Mocker.GetMock().Setup(s => s.GetFileByPath(filename)) + .Returns(episodeFile); + + Mocker.GetMock().Setup(s => s.GetSeries(It.IsAny())) + .Returns(series); + + Mocker.GetMock().Setup(s => s.GetEpisodesByFileId(episodeFile.EpisodeFileId)) + .Returns(episode); + + Mocker.GetMock().Setup(s => s.GetNewFilename(It.IsAny>(), series.Title, QualityTypes.Unknown, false, It.IsAny())) + .Returns(newFilename); + + Mocker.GetMock().Setup(s => s.CalculateFilePath(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(new FileInfo(newFilePath)); + + Mocker.GetMock().Setup(s => s.MoveFile(episodeFile.Path, newFilePath)); + + //Act + Mocker.Resolve().CleanUpDropFolder(folder); + + //Assert + Mocker.GetMock().Verify(v => v.GetFileByPath(filename), Times.Once()); + Mocker.GetMock().Verify(v => v.MoveFile(filename.NormalizePath(), newFilePath), Times.Once()); + } + } +} diff --git a/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/CleanUpFixture.cs b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/CleanUpFixture.cs new file mode 100644 index 000000000..236fda84c --- /dev/null +++ b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/CleanUpFixture.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using FizzWare.NBuilder; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using NzbDrone.Common; +using NzbDrone.Core.Model; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Providers.Core; +using NzbDrone.Core.Repository; +using NzbDrone.Core.Repository.Quality; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Test.Common; +using NzbDrone.Test.Common.AutoMoq; + +namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests +{ + // ReSharper disable InconsistentNaming + public class CleanUpFixture : CoreTest + { + [Test] + public void should_skip_existing_files() + { + var episodes = Builder.CreateListOfSize(10).Build(); + + Mocker.GetMock() + .Setup(e => e.FileExists(It.IsAny())) + .Returns(true); + + + //Act + Mocker.Resolve().CleanUp(episodes); + + //Assert + Mocker.VerifyAllMocks(); + } + + [Test] + public void should_delete_none_existing_files() + { + var episodes = Builder.CreateListOfSize(10).Build(); + + Mocker.GetMock() + .Setup(e => e.FileExists(It.IsAny())) + .Returns(false); + + Mocker.GetMock() + .Setup(e => e.GetEpisodesByFileId(It.IsAny())) + .Returns(new List()); + + Mocker.GetMock() + .Setup(e => e.Delete(It.IsAny())); + + + //Act + Mocker.Resolve().CleanUp(episodes); + + //Assert + Mocker.VerifyAllMocks(); + + Mocker.GetMock() + .Verify(e => e.GetEpisodesByFileId(It.IsAny()), Times.Exactly(10)); + + Mocker.GetMock() + .Verify(e => e.Delete(It.IsAny()), Times.Exactly(10)); + + } + + [Test] + public void should_delete_none_existing_files_remove_links_to_episodes() + { + var episodes = Builder.CreateListOfSize(10).Build(); + + Mocker.GetMock() + .Setup(e => e.FileExists(It.IsAny())) + .Returns(false); + + Mocker.GetMock() + .Setup(e => e.GetEpisodesByFileId(It.IsAny())) + .Returns(new List { new Episode { EpisodeFileId = 10 }, new Episode { EpisodeFileId = 10 } }); + + Mocker.GetMock() + .Setup(e => e.UpdateEpisode(It.IsAny())); + + Mocker.GetMock() + .Setup(e => e.Delete(It.IsAny())); + + Mocker.GetMock() + .SetupGet(s => s.AutoIgnorePreviouslyDownloadedEpisodes) + .Returns(true); + + //Act + Mocker.Resolve().CleanUp(episodes); + + //Assert + Mocker.VerifyAllMocks(); + + Mocker.GetMock() + .Verify(e => e.GetEpisodesByFileId(It.IsAny()), Times.Exactly(10)); + + Mocker.GetMock() + .Verify(e => e.UpdateEpisode(It.Is(g=>g.EpisodeFileId == 0)), Times.Exactly(20)); + + Mocker.GetMock() + .Verify(e => e.Delete(It.IsAny()), Times.Exactly(10)); + + Mocker.GetMock() + .Verify(e => e.Delete(It.IsAny()), Times.Exactly(10)); + + } + } +} diff --git a/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/GetVideoFilesFixture.cs b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/GetVideoFilesFixture.cs new file mode 100644 index 000000000..13973bfe8 --- /dev/null +++ b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/GetVideoFilesFixture.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using FizzWare.NBuilder; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using NzbDrone.Common; +using NzbDrone.Core.Model; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Providers.Core; +using NzbDrone.Core.Repository; +using NzbDrone.Core.Repository.Quality; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Test.Common; +using NzbDrone.Test.Common.AutoMoq; + +namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests +{ + // ReSharper disable InconsistentNaming + public class GetVideoFilesFixture : CoreTest + { + private string[] _files; + + [SetUp] + public void Setup() + { + _files = new string[] + { + @"C:\Test\30 Rock1.mkv", + @"C:\Test\30 Rock2.avi", + @"C:\Test\30 Rock3.mp4", + @"C:\Test\30 Rock4.wmv", + @"C:\Test\movie.exe" + }; + + Mocker.GetMock() + .Setup(s => s.GetFiles(It.IsAny(), SearchOption.AllDirectories)) + .Returns(_files); + } + + [Test] + public void should_check_all_directories() + { + var path = @"C:\Test\"; + + Mocker.Resolve().GetVideoFiles(path); + + Mocker.GetMock().Verify(s => s.GetFiles(path, SearchOption.AllDirectories), Times.Once()); + Mocker.GetMock().Verify(s => s.GetFiles(path, SearchOption.TopDirectoryOnly), Times.Never()); + } + + [Test] + public void should_check_all_directories_when_allDirectories_is_true() + { + var path = @"C:\Test\"; + + Mocker.Resolve().GetVideoFiles(path, true); + + Mocker.GetMock().Verify(s => s.GetFiles(path, SearchOption.AllDirectories), Times.Once()); + Mocker.GetMock().Verify(s => s.GetFiles(path, SearchOption.TopDirectoryOnly), Times.Never()); + } + + [Test] + public void should_check_top_level_directory_only_when_allDirectories_is_false() + { + var path = @"C:\Test\"; + + Mocker.Resolve().GetVideoFiles(path, false); + + Mocker.GetMock().Verify(s => s.GetFiles(path, SearchOption.AllDirectories), Times.Never()); + Mocker.GetMock().Verify(s => s.GetFiles(path, SearchOption.TopDirectoryOnly), Times.Once()); + } + + [Test] + public void should_return_video_files_only() + { + var path = @"C:\Test\"; + + Mocker.Resolve().GetVideoFiles(path).Should().HaveCount(4); + } + } +} diff --git a/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTest_ImportFile.cs b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/ImportFileFixture.cs similarity index 99% rename from NzbDrone.Core.Test/ProviderTests/DiskScanProviderTest_ImportFile.cs rename to NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/ImportFileFixture.cs index 9298ec064..f6549b075 100644 --- a/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTest_ImportFile.cs +++ b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/ImportFileFixture.cs @@ -15,10 +15,10 @@ using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common; using NzbDrone.Test.Common.AutoMoq; -namespace NzbDrone.Core.Test.ProviderTests +namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests { // ReSharper disable InconsistentNaming - public class DiskScanProviderTest_ImportFile : CoreTest + public class ImportFileFixture : CoreTest { [Test] public void import_new_file_should_succeed() diff --git a/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/MoveEpisodeFileFixture.cs b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/MoveEpisodeFileFixture.cs new file mode 100644 index 000000000..a45f4fab3 --- /dev/null +++ b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/MoveEpisodeFileFixture.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using FizzWare.NBuilder; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using NzbDrone.Common; +using NzbDrone.Core.Model; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Providers.Core; +using NzbDrone.Core.Repository; +using NzbDrone.Core.Repository.Quality; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Test.Common; +using NzbDrone.Test.Common.AutoMoq; + +namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests +{ + // ReSharper disable InconsistentNaming + public class MoveEpisodeFileFixture : CoreTest + { + [Test] + public void should_not_move_file_if_source_and_destination_are_the_same_path() + { + var fakeSeries = Builder.CreateNew() + .With(s => s.SeriesId = 5) + .With(s => s.Title = "30 Rock") + .Build(); + + var fakeEpisode = Builder.CreateListOfSize(1) + .All() + .With(e => e.SeriesId = fakeSeries.SeriesId) + .With(e => e.SeasonNumber = 1) + .With(e => e.EpisodeNumber = 1) + .Build(); + + const string filename = @"30 Rock - S01E01 - TBD"; + var fi = new FileInfo(Path.Combine(@"C:\Test\TV\30 Rock\Season 01\", filename + ".avi")); + + var file = Builder.CreateNew() + .With(f => f.SeriesId = fakeSeries.SeriesId) + .With(f => f.Path = fi.FullName) + .Build(); + + Mocker.GetMock() + .Setup(e => e.GetSeries(fakeSeries.SeriesId)) + .Returns(fakeSeries); + + Mocker.GetMock() + .Setup(e => e.GetEpisodesByFileId(file.EpisodeFileId)) + .Returns(fakeEpisode); + + Mocker.GetMock() + .Setup(e => e.GetNewFilename(fakeEpisode, fakeSeries.Title, It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(filename); + + Mocker.GetMock() + .Setup(e => e.CalculateFilePath(It.IsAny(), fakeEpisode.First().SeasonNumber, filename, ".avi")) + .Returns(fi); + + //Act + var result = Mocker.Resolve().MoveEpisodeFile(file, false); + + //Assert + result.Should().BeNull(); + } + + [Test] + public void should_use_EpisodeFiles_quality() + { + var fakeSeries = Builder.CreateNew() + .With(s => s.SeriesId = 5) + .With(s => s.Title = "30 Rock") + .Build(); + + var fakeEpisode = Builder.CreateListOfSize(1) + .All() + .With(e => e.SeriesId = fakeSeries.SeriesId) + .With(e => e.SeasonNumber = 1) + .With(e => e.EpisodeNumber = 1) + .Build(); + + const string filename = @"30 Rock - S01E01 - TBD"; + var fi = new FileInfo(Path.Combine(@"C:\Test\TV\30 Rock\Season 01\", filename + ".mkv")); + var currentFilename = Path.Combine(@"C:\Test\TV\30 Rock\Season 01\", "30.Rock.S01E01.Test.WED-DL.mkv"); + const string message = "30 Rock - 1x01 - [WEBDL]"; + + var file = Builder.CreateNew() + .With(f => f.SeriesId = fakeSeries.SeriesId) + .With(f => f.Path = currentFilename) + .With(f => f.Quality = QualityTypes.WEBDL) + .With(f => f.Proper = false) + .Build(); + + Mocker.GetMock() + .Setup(e => e.GetSeries(fakeSeries.SeriesId)) + .Returns(fakeSeries); + + Mocker.GetMock() + .Setup(e => e.GetEpisodesByFileId(file.EpisodeFileId)) + .Returns(fakeEpisode); + + Mocker.GetMock() + .Setup(e => e.GetNewFilename(fakeEpisode, fakeSeries.Title, It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(filename); + + Mocker.GetMock() + .Setup(e => e.CalculateFilePath(It.IsAny(), fakeEpisode.First().SeasonNumber, filename, ".mkv")) + .Returns(fi); + + Mocker.GetMock() + .Setup(s => s.GetDownloadTitle(It.Is(e => e.Quality == new Quality{ QualityType = QualityTypes.WEBDL, Proper = false }))) + .Returns(message); + + Mocker.GetMock() + .Setup(e => e.OnDownload("30 Rock - 1x01 - [WEBDL]", It.IsAny())); + + //Act + var result = Mocker.Resolve().MoveEpisodeFile(file, true); + + //Assert + result.Should().NotBeNull(); + Mocker.GetMock() + .Verify(e => e.OnDownload("30 Rock - 1x01 - [WEBDL]", It.IsAny()), Times.Once()); + } + } +} diff --git a/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/ScanFixture.cs b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/ScanFixture.cs new file mode 100644 index 000000000..2c1d22613 --- /dev/null +++ b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/ScanFixture.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using FizzWare.NBuilder; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using NzbDrone.Common; +using NzbDrone.Core.Model; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Providers.Core; +using NzbDrone.Core.Repository; +using NzbDrone.Core.Repository.Quality; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Test.Common; +using NzbDrone.Test.Common.AutoMoq; + +namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests +{ + // ReSharper disable InconsistentNaming + public class ScanFixture : CoreTest + { + [Test] + public void series_should_update_the_last_scan_date() + { + + + Mocker.GetMock() + .Setup(c => c.UpdateSeries(It.Is(s => s.LastDiskSync != null))).Verifiable(); + + Mocker.GetMock() + .Setup(c => c.GetEpisodeBySeries(It.IsAny())) + .Returns(new List { new Episode() }); + + Mocker.GetMock() + .Setup(c => c.FolderExists(It.IsAny())) + .Returns(true); + + Mocker.GetMock() + .Setup(c => c.GetSeriesFiles(It.IsAny())) + .Returns(new List()); + + Mocker.Resolve().Scan(new Series()); + + Mocker.VerifyAllMocks(); + + } + + [Test] + public void series_should_log_warning_if_path_doesnt_exist_on_disk() + { + //Setup + WithStrictMocker(); + + var series = Builder.CreateNew() + .With(s => s.Path = @"C:\Test\TV\SeriesName\") + .Build(); + + + Mocker.GetMock() + .Setup(c => c.CleanUpDatabase()); + + + Mocker.GetMock() + .Setup(c => c.FolderExists(series.Path)) + .Returns(false); + + //Act + Mocker.Resolve().Scan(series, series.Path); + + //Assert + Mocker.VerifyAllMocks(); + ExceptionVerification.ExpectedWarns(1); + } + } +} diff --git a/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/PostDownloadProviderFixture.cs b/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/GetFolderNameWithStatusFixture.cs similarity index 97% rename from NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/PostDownloadProviderFixture.cs rename to NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/GetFolderNameWithStatusFixture.cs index 501d56d84..1e45f27ba 100644 --- a/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/PostDownloadProviderFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/GetFolderNameWithStatusFixture.cs @@ -13,7 +13,7 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests { [TestFixture] // ReSharper disable InconsistentNaming - public class PostDownloadProviderFixture : CoreTest + public class GetFolderNameWithStatusFixture : CoreTest { [TestCase(@"c:\_NzbDrone_InvalidEpisode_Title", @"c:\_UnknownSeries_Title", PostDownloadStatusType.UnknownSeries)] [TestCase(@"c:\Title", @"c:\_Failed_Title", PostDownloadStatusType.Failed)] diff --git a/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessDownloadProviderFixture.cs b/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessDownloadFixture.cs similarity index 87% rename from NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessDownloadProviderFixture.cs rename to NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessDownloadFixture.cs index 484e07209..be2b61fd4 100644 --- a/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessDownloadProviderFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessDownloadFixture.cs @@ -18,7 +18,7 @@ using NzbDrone.Test.Common.AutoMoq; namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests { [TestFixture] - public class ProcessDownloadProviderFixture : CoreTest + public class ProcessDownloadFixture : CoreTest { Series fakeSeries; @@ -328,51 +328,7 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests } [Test] - public void ProcessDropFolder_should_only_process_folders_that_arent_known_series_folders() - { - WithLotsOfFreeDiskSpace(); - - var subFolders = new[] - { - @"c:\drop\episode1", - @"c:\drop\episode2", - @"c:\drop\episode3", - @"c:\drop\episode4" - }; - - Mocker.GetMock() - .Setup(c => c.GetDirectories(It.IsAny())) - .Returns(subFolders); - - Mocker.GetMock() - .Setup(c => c.SeriesPathExists(subFolders[1])) - .Returns(true); - - Mocker.GetMock() - .Setup(c => c.FindSeries(It.IsAny())) - .Returns(fakeSeries); - - Mocker.GetMock() - .Setup(c => c.Scan(It.IsAny(), It.IsAny())) - .Returns(new List()); - - Mocker.GetMock() - .Setup(c => c.GetDirectorySize(It.IsAny())) - .Returns(10); - - //Act - Mocker.Resolve().ProcessDropFolder(@"C:\drop\"); - - - //Assert - Mocker.GetMock().Verify(c => c.Scan(It.IsAny(), subFolders[0]), Times.Once()); - Mocker.GetMock().Verify(c => c.Scan(It.IsAny(), subFolders[1]), Times.Never()); - Mocker.GetMock().Verify(c => c.Scan(It.IsAny(), subFolders[2]), Times.Once()); - Mocker.GetMock().Verify(c => c.Scan(It.IsAny(), subFolders[3]), Times.Once()); - } - - [Test] - public void ProcessDownload_should_logError_and_return_if_size_exceeds_free_space() + public void should_logError_and_return_if_size_exceeds_free_space() { var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot"); @@ -403,7 +359,7 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests } [Test] - public void ProcessDownload_should_process_if_free_disk_space_exceeds_size() + public void should_process_if_free_disk_space_exceeds_size() { WithLotsOfFreeDiskSpace(); WithValidSeries(); @@ -429,7 +385,7 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests } [Test] - public void ProcessDownload_should_process_if_free_disk_space_equals_size() + public void should_process_if_free_disk_space_equals_size() { var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot"); diff --git a/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessDropDirectoryFixture.cs b/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessDropDirectoryFixture.cs new file mode 100644 index 000000000..688e4e470 --- /dev/null +++ b/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessDropDirectoryFixture.cs @@ -0,0 +1,123 @@ +// ReSharper disable InconsistentNaming +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +using FizzWare.NBuilder; +using Moq; +using NUnit.Framework; +using NzbDrone.Common; +using NzbDrone.Core.Model; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Repository; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Test.Common; +using NzbDrone.Test.Common.AutoMoq; + +namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests +{ + [TestFixture] + public class ProcessDropDirectoryFixture : CoreTest + { + Series fakeSeries; + + [SetUp] + public void Setup() + { + fakeSeries = Builder.CreateNew() + .With(s => s.Path = @"C:\Test\TV\30 Rock") + .Build(); + } + + private void WithLotsOfFreeDiskSpace() + { + Mocker.GetMock().Setup(s => s.FreeDiskSpace(It.IsAny())).Returns(1000000000); + } + + [Test] + public void ProcessDropFolder_should_only_process_folders_that_arent_known_series_folders() + { + WithLotsOfFreeDiskSpace(); + + var subFolders = new[] + { + @"c:\drop\episode1", + @"c:\drop\episode2", + @"c:\drop\episode3", + @"c:\drop\episode4" + }; + + Mocker.GetMock() + .Setup(c => c.GetVideoFiles(It.IsAny(), false)) + .Returns(new List()); + + Mocker.GetMock() + .Setup(c => c.GetDirectories(It.IsAny())) + .Returns(subFolders); + + Mocker.GetMock() + .Setup(c => c.SeriesPathExists(subFolders[1])) + .Returns(true); + + Mocker.GetMock() + .Setup(c => c.FindSeries(It.IsAny())) + .Returns(fakeSeries); + + Mocker.GetMock() + .Setup(c => c.Scan(It.IsAny(), It.IsAny())) + .Returns(new List()); + + Mocker.GetMock() + .Setup(c => c.GetDirectorySize(It.IsAny())) + .Returns(10); + + //Act + Mocker.Resolve().ProcessDropFolder(@"C:\drop\"); + + + //Assert + Mocker.GetMock().Verify(c => c.Scan(It.IsAny(), subFolders[0]), Times.Once()); + Mocker.GetMock().Verify(c => c.Scan(It.IsAny(), subFolders[1]), Times.Never()); + Mocker.GetMock().Verify(c => c.Scan(It.IsAny(), subFolders[2]), Times.Once()); + Mocker.GetMock().Verify(c => c.Scan(It.IsAny(), subFolders[3]), Times.Once()); + } + + [Test] + public void ProcessDropFolder_should_process_individual_video_files_in_drop_folder() + { + WithLotsOfFreeDiskSpace(); + + var files = new List + { + @"c:\drop\30 Rock - episode1.avi", + @"c:\drop\30 Rock - episode2.mkv", + @"c:\drop\30 Rock - episode3.mp4", + @"c:\drop\30 Rock - episode4.wmv" + }; + + Mocker.GetMock() + .Setup(c => c.GetVideoFiles(It.IsAny(), false)) + .Returns(files); + + Mocker.GetMock() + .Setup(c => c.FindSeries(It.IsAny())) + .Returns(fakeSeries); + + Mocker.GetMock() + .Setup(c => c.Scan(It.IsAny(), It.IsAny())) + .Returns(new List()); + + Mocker.GetMock() + .Setup(c => c.GetDirectorySize(It.IsAny())) + .Returns(10); + + //Act + Mocker.Resolve().ProcessDropFolder(@"C:\drop\"); + + + //Assert + Mocker.GetMock().Verify(c => c.ImportFile(It.IsAny(), It.IsAny()), Times.Exactly(4)); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessVideoFileFixture.cs b/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessVideoFileFixture.cs new file mode 100644 index 000000000..e66203ec4 --- /dev/null +++ b/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessVideoFileFixture.cs @@ -0,0 +1,215 @@ +// ReSharper disable InconsistentNaming +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +using FizzWare.NBuilder; +using Moq; +using NUnit.Framework; +using NzbDrone.Common; +using NzbDrone.Core.Model; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Repository; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Test.Common; +using NzbDrone.Test.Common.AutoMoq; + +namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests +{ + [TestFixture] + public class ProcessVideoFileFixture : CoreTest + { + Series fakeSeries; + + [SetUp] + public void Setup() + { + fakeSeries = Builder.CreateNew() + .With(s => s.Path = @"C:\Test\TV\30 Rock") + .Build(); + } + + private void WithOldWrite() + { + Mocker.GetMock() + .Setup(c => c.GetLastFileWrite(It.IsAny())) + .Returns(DateTime.Now.AddDays(-5)); + } + + private void WithRecentWrite() + { + Mocker.GetMock() + .Setup(c => c.GetLastFileWrite(It.IsAny())) + .Returns(DateTime.UtcNow); + } + + private void WithValidSeries() + { + Mocker.GetMock() + .Setup(c => c.FindSeries(It.IsAny())) + .Returns(fakeSeries); + } + + private void WithImportableFiles() + { + Mocker.GetMock() + .Setup(c => c.Scan(It.IsAny(), It.IsAny())) + .Returns(Builder.CreateListOfSize(1).Build().ToList()); + } + + private void WithLotsOfFreeDiskSpace() + { + Mocker.GetMock().Setup(s => s.FreeDiskSpace(It.IsAny())).Returns(1000000000); + } + + private void WithImportedFile(string file) + { + var fakeEpisodeFile = Builder.CreateNew() + .With(f => f.SeriesId = fakeSeries.SeriesId) + .Build(); + + Mocker.GetMock().Setup(s => s.ImportFile(fakeSeries, file)).Returns(fakeEpisodeFile); + } + + [Test] + public void should_skip_if_and_too_fresh() + { + WithStrictMocker(); + WithRecentWrite(); + + var file = Path.Combine(TempFolder, "test.avi"); + + Mocker.Resolve().ProcessVideoFile(file); + } + + [Test] + public void should_continue_processing_if_not_fresh() + { + WithOldWrite(); + + var file = Path.Combine(TempFolder, "test.avi"); + + //Act + Mocker.GetMock().Setup(s => s.FindSeries(It.IsAny())).Returns(null).Verifiable(); + Mocker.Resolve().ProcessVideoFile(file); + + //Assert + Mocker.GetMock().Verify(s => s.FindSeries(It.IsAny()), Times.Once()); + ExceptionVerification.IgnoreWarns(); + } + + [Test] + public void should_return_if_series_is_not_found() + { + WithOldWrite(); + + var file = Path.Combine(TempFolder, "test.avi"); + + //Act + Mocker.GetMock().Setup(s => s.FindSeries(It.IsAny())).Returns(null); + Mocker.Resolve().ProcessVideoFile(file); + + //Assert + Mocker.GetMock().Verify(s => s.GetFileSize(It.IsAny()), Times.Never()); + ExceptionVerification.IgnoreWarns(); + } + + [Test] + public void should_move_file_if_imported() + { + WithLotsOfFreeDiskSpace(); + WithOldWrite(); + + var file = Path.Combine(TempFolder, "test.avi"); + + WithValidSeries(); + WithImportedFile(file); + + //Act + Mocker.Resolve().ProcessVideoFile(file); + + //Assert + Mocker.GetMock().Verify(s => s.MoveEpisodeFile(It.IsAny(), true), Times.Once()); + ExceptionVerification.IgnoreWarns(); + } + + [Test] + public void should_logError_and_return_if_size_exceeds_free_space() + { + var downloadName = @"C:\Test\Drop\30.Rock.S01E01.Pilot.mkv"; + + var series = Builder.CreateNew() + .With(s => s.Title = "30 Rock") + .With(s => s.Path = @"C:\Test\TV\30 Rock") + .Build(); + + Mocker.GetMock() + .Setup(c => c.FindSeries("rock")) + .Returns(series); + + Mocker.GetMock() + .Setup(s => s.GetFileSize(downloadName)) + .Returns(10); + + Mocker.GetMock() + .Setup(s => s.FreeDiskSpace(new DirectoryInfo(series.Path))) + .Returns(9); + + //Act + Mocker.Resolve().ProcessVideoFile(downloadName); + + + //Assert + Mocker.GetMock().Verify(c => c.ImportFile(series, downloadName), Times.Never()); + ExceptionVerification.ExpectedErrors(1); + } + + [Test] + public void should_process_if_free_disk_space_exceeds_size() + { + WithLotsOfFreeDiskSpace(); + WithValidSeries(); + + var downloadName = @"C:\Test\Drop\30.Rock.S01E01.Pilot.mkv"; + + Mocker.GetMock() + .Setup(c => c.FindSeries("rock")) + .Returns(fakeSeries); + + Mocker.GetMock() + .Setup(s => s.GetFileSize(downloadName)) + .Returns(8); + + //Act + Mocker.Resolve().ProcessVideoFile(downloadName); + + + //Assert + Mocker.GetMock().Verify(c => c.ImportFile(fakeSeries, downloadName), Times.Once()); + } + + [Test] + public void should_process_if_free_disk_space_equals_size() + { + var downloadName = @"C:\Test\Drop\30.Rock.S01E01.Pilot.mkv"; + + WithValidSeries(); + + Mocker.GetMock() + .Setup(s => s.GetDirectorySize(downloadName)) + .Returns(10); + + Mocker.GetMock() + .Setup(s => s.FreeDiskSpace(It.IsAny())) + .Returns(10); + + //Act + Mocker.Resolve().ProcessVideoFile(downloadName); + + + //Assert + Mocker.GetMock().Verify(c => c.ImportFile(fakeSeries, downloadName), Times.Once()); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index dc3c29be6..2bdf59ae4 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -289,6 +289,7 @@ + diff --git a/NzbDrone.Core/Providers/DiskScanProvider.cs b/NzbDrone.Core/Providers/DiskScanProvider.cs index 5c897ffa0..215b17f63 100644 --- a/NzbDrone.Core/Providers/DiskScanProvider.cs +++ b/NzbDrone.Core/Providers/DiskScanProvider.cs @@ -284,7 +284,7 @@ namespace NzbDrone.Core.Providers } } - public List GetVideoFiles(string path, bool allDirectories = true) + public virtual List GetVideoFiles(string path, bool allDirectories = true) { Logger.Debug("Scanning '{0}' for video files", path); diff --git a/NzbDrone.Core/Providers/PostDownloadProvider.cs b/NzbDrone.Core/Providers/PostDownloadProvider.cs index 469fc3479..af18a5134 100644 --- a/NzbDrone.Core/Providers/PostDownloadProvider.cs +++ b/NzbDrone.Core/Providers/PostDownloadProvider.cs @@ -50,7 +50,6 @@ namespace NzbDrone.Core.Providers } } - //Todo: Process files directly in the drop folder foreach(var videoFile in _diskScanProvider.GetVideoFiles(dropFolder, false)) { try @@ -124,6 +123,12 @@ namespace NzbDrone.Core.Providers public virtual void ProcessVideoFile(string videoFile) { + if (_diskProvider.GetLastFileWrite(videoFile).AddMinutes(2) > DateTime.UtcNow) + { + Logger.Trace("[{0}] is too fresh. skipping", videoFile); + return; + } + var seriesName = Parser.ParseSeriesName(Path.GetFileNameWithoutExtension(videoFile)); var series = _seriesProvider.FindSeries(seriesName); @@ -133,6 +138,15 @@ namespace NzbDrone.Core.Providers return; } + var size = _diskProvider.GetFileSize(videoFile); + var freeSpace = _diskProvider.FreeDiskSpace(new DirectoryInfo(series.Path)); + + if (Convert.ToUInt64(size) > freeSpace) + { + Logger.Error("Not enough free disk space for series: {0}, {1}", series.Title, series.Path); + return; + } + var episodeFile = _diskScanProvider.ImportFile(series, videoFile); if (episodeFile != null) {