using System; using System.Collections.Generic; using System.IO; using System.Linq; using FizzWare.NBuilder; using FluentAssertions; using Moq; using NUnit.Framework; using NzbDrone.Common; 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())) .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().BeFalse(); } [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)) .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()); } } }