cleaned up parsing logic and structure.

This commit is contained in:
kay.one
2013-04-14 18:41:39 -07:00
parent cd2761d07d
commit 6e88f55a54
120 changed files with 2149 additions and 3064 deletions
@@ -1,15 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.IO;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common.AutoMoq;
namespace NzbDrone.Core.Test.ProviderTests.DiskProviderTests
{
@@ -19,7 +12,7 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskProviderTests
[Test]
public void should_return_free_disk_space()
{
var result = Subject.FreeDiskSpace(Directory.GetCurrentDirectory());
var result = Subject.GetAvilableSpace(Directory.GetCurrentDirectory());
//Checks to ensure that the free space on the first is greater than 0 (It should be in 99.99999999999999% of cases... I hope)
result.Should().BeGreaterThan(0);
@@ -27,7 +20,7 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskProviderTests
[Test]
public void should_throw_if_drive_doesnt_exist()
{
Assert.Throws<DirectoryNotFoundException>(() => Subject.FreeDiskSpace(@"Z:\NOT_A_REAL_PATH\DOES_NOT_EXIST"));
Assert.Throws<DirectoryNotFoundException>(() => Subject.GetAvilableSpace(@"Z:\NOT_A_REAL_PATH\DOES_NOT_EXIST"));
}
}
}
@@ -1,123 +0,0 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FizzWare.NBuilder;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
{
public class CleanUpDropFolderFixture : CoreTest
{
[Test]
public void should_do_nothing_if_no_files_are_found()
{
var folder = @"C:\Test\DropDir\The Office";
Mocker.GetMock<DiskProvider>().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories))
.Returns(new string[0]);
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
Mocker.GetMock<IMediaFileService>().Verify(v => v.GetFileByPath(It.IsAny<string>()), Times.Never());
}
[Test]
public void should_do_nothing_if_no_conflicting_files_are_found()
{
var folder = @"C:\Test\DropDir\The Office";
var filename = Path.Combine(folder, "NotAProblem.avi");
var episodeFile = Builder<EpisodeFile>.CreateNew()
.With(f => f.Path = filename.NormalizePath())
.With(f => f.SeriesId = 12345)
.Build();
Mocker.GetMock<DiskProvider>().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories))
.Returns(new string[] { filename });
Mocker.GetMock<IMediaFileService>().Setup(s => s.GetFileByPath(filename))
.Returns(() => null);
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
Mocker.GetMock<IMediaFileService>().Verify(v => v.GetFileByPath(filename), Times.Once());
Mocker.GetMock<ISeriesRepository>().Verify(v => v.Get(It.IsAny<int>()), Times.Never());
}
[Test]
public void should_move_file_if_a_conflict_is_found()
{
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<EpisodeFile>.CreateNew()
.With(f => f.Path = filename.NormalizePath())
.With(f => f.SeriesId = seriesId)
.Build();
var series = Builder<Series>.CreateNew()
.With(s => s.Id = seriesId)
.With(s => s.Title = "The Office")
.Build();
var episode = Builder<Episode>.CreateListOfSize(1)
.All()
.With(e => e.SeriesId = seriesId)
.With(e => e.EpisodeFile = episodeFile)
.Build().ToList();
Mocker.GetMock<IMediaFileService>().Setup(v => v.GetFileByPath(filename))
.Returns(() => null);
Mocker.GetMock<DiskProvider>().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories))
.Returns(new string[] { filename });
Mocker.GetMock<IMediaFileService>().Setup(s => s.GetFileByPath(filename))
.Returns(episodeFile);
Mocker.GetMock<ISeriesRepository>().Setup(s => s.Get(It.IsAny<int>()))
.Returns(series);
Mocker.GetMock<IEpisodeService>().Setup(s => s.GetEpisodesByFileId(episodeFile.Id))
.Returns(episode);
Mocker.GetMock<IBuildFileNames>().Setup(s => s.BuildFilename(It.IsAny<IList<Episode>>(), series, It.IsAny<EpisodeFile>()))
.Returns(newFilename);
Mocker.GetMock<IBuildFileNames>().Setup(s => s.BuildFilePath(It.IsAny<Series>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns(newFilePath);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FileExists(filename))
.Returns(true);
Mocker.GetMock<DiskProvider>().Setup(s => s.MoveFile(episodeFile.Path, newFilePath));
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
Mocker.GetMock<IMediaFileService>().Verify(v => v.GetFileByPath(filename), Times.Once());
Mocker.GetMock<DiskProvider>().Verify(v => v.MoveFile(filename.NormalizePath(), newFilePath), Times.Once());
}
}
}
@@ -7,562 +7,281 @@ using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
using NzbDrone.Test.Common.AutoMoq;
namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
{
public class ImportFileFixture : CoreTest
public class ImportFileFixture : CoreTest<DiskScanProvider>
{
public static object[] ImportTestCases =
{
new object[] { Quality.SDTV, false },
new object[] { Quality.DVD, true },
new object[] { Quality.HDTV720p, false }
};
private readonly long SIZE = 80.Megabytes();
private Series _series;
private long _fileSize = 80.Megabytes();
private Series _fakeSeries;
private List<Episode> _fakeEpisodes;
private Episode _fakeEpisode;
[SetUp]
public void Setup()
{
_series = Builder<Series>
_fakeSeries = Builder<Series>
.CreateNew()
.With(s => s.SeriesType = SeriesTypes.Standard)
.Build();
_fakeEpisode = Builder<Episode>
.CreateNew()
.Build();
_fakeEpisodes = Builder<Episode>.CreateListOfSize(2)
.All()
.With(c => c.SeasonNumber = 3)
.With(e => e.EpisodeFile = new EpisodeFile())
.BuildList();
GivenNewFile();
GivenVideoDuration(TimeSpan.FromMinutes(20));
GivenFileSize(_fileSize);
}
public void With80MBFile()
private void GivenFileSize(long size)
{
_fileSize = size;
Mocker.GetMock<DiskProvider>()
.Setup(d => d.GetSize(It.IsAny<String>()))
.Returns(80.Megabytes());
.Returns(size);
}
public void WithDailySeries()
private void GivenVideoDuration(TimeSpan duration)
{
_series.SeriesType = SeriesTypes.Daily;
Mocker.GetMock<IVideoFileInfoReader>()
.Setup(d => d.GetRunTime(It.IsAny<String>()))
.Returns(duration);
}
private void GivenEpisodes(IEnumerable<Episode> episodes, QualityModel quality)
{
Mocker.GetMock<IParsingService>()
.Setup(c => c.GetEpisodes(It.IsAny<string>(), It.IsAny<Series>()))
.Returns(new LocalEpisode
{
Episodes = episodes.ToList(),
Quality = quality
});
}
private void GivenNewFile()
{
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
}
[Test]
public void import_new_file_should_succeed()
{
const string newFile = @"WEEDS.S03E01.DUAL.dvd.HELLYWOOD.avi";
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisode = Builder<Episode>.CreateNew().Build();
//Mocks
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, newFile);
VerifyFileImport(result, Mocker, fakeEpisode, SIZE);
GivenEpisodes(new[] { _fakeEpisode }, new QualityModel());
var result = Subject.ImportFile(_fakeSeries, "file.ext");
VerifyFileImport(result);
}
[Test, TestCaseSource("ImportTestCases")]
public void import_new_file_with_better_same_quality_should_succeed(Quality currentFileQuality, bool currentFileProper)
[Test]
public void import_new_file_with_same_quality_should_succeed()
{
const string newFile = @"WEEDS.S03E01.DUAL.1080p.HELLYWOOD.mkv";
_fakeEpisode.EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.SDTV) };
GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.SDTV));
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisode = Builder<Episode>.CreateNew()
.With(e => e.EpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(g => g.Quality = new QualityModel(currentFileQuality, currentFileProper))
.Build()
).Build();
With80MBFile();
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, newFile);
VerifyFileImport(result, Mocker, fakeEpisode, SIZE);
var result = Subject.ImportFile(_fakeSeries, "file.ext");
VerifyFileImport(result);
}
[TestCase("WEEDS.S03E01.DUAL.DVD.XviD.AC3.-HELLYWOOD.avi")]
[TestCase("WEEDS.S03E01.DUAL.SDTV.XviD.AC3.-HELLYWOOD.avi")]
public void import_new_file_episode_has_same_or_better_quality_should_skip(string fileName)
[Test]
public void import_new_file_with_better_quality_should_succeed()
{
_fakeEpisode.EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.SDTV) };
GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.HDTV1080p));
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisode = Builder<Episode>.CreateNew()
.With(c => c.EpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(e => e.Quality = new QualityModel(Quality.Bluray720p)).Build()
)
.Build();
//Mocks
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifySkipImport(result, Mocker);
var result = Subject.ImportFile(_fakeSeries, "file.ext");
VerifyFileImport(result);
}
[Test]
public void import_new_file_episode_has_better_quality_should_skip()
{
_fakeEpisode.EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV1080p) };
GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.SDTV));
var result = Subject.ImportFile(_fakeSeries, "file.ext");
VerifySkipImport(result);
}
[Test]
public void import_unparsable_file_should_skip()
{
const string fileName = @"C:\Test\WEEDS.avi";
Mocker.GetMock<IParsingService>()
.Setup(c => c.GetEpisodes(It.IsAny<string>(), It.IsAny<Series>()))
.Returns<LocalEpisode>(null);
var fakeSeries = Builder<Series>.CreateNew().Build();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>())).Returns(false);
With80MBFile();
var result = Subject.ImportFile(_fakeSeries, "file.ext");
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifySkipImport(result, Mocker);
ExceptionVerification.ExpectedWarns(1);
VerifySkipImport(result);
}
[Test]
public void import_existing_file_should_skip()
{
const string fileName = "WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi";
var fakeSeries = Builder<Series>.CreateNew().Build();
WithStrictMocker();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(true);
With80MBFile();
var result = Subject.ImportFile(_fakeSeries, "file.ext");
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifySkipImport(result, Mocker);
VerifySkipImport(result);
}
[Test]
public void import_file_with_no_episode_in_db_should_skip()
{
//Constants
const string fileName = "WEEDS.S03E01.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi";
GivenEpisodes(new List<Episode>(), new QualityModel());
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var result = Subject.ImportFile(_fakeSeries, "file.ext");
//Mocks
Mocker.GetMock<DiskProvider>(MockBehavior.Strict)
.Setup(e => e.IsChildOfPath(fileName, fakeSeries.Path)).Returns(false);
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(c => c.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>()))
.Returns(new List<Episode>());
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifySkipImport(result, Mocker);
}
[TestCase("WEEDS.S03E01.DUAL.DVD.XviD.AC3.-HELLYWOOD.avi")]
[TestCase("WEEDS.S03E01.DUAL.bluray.x264.AC3.-HELLYWOOD.mkv")]
public void import_new_file_episode_has_better_quality_than_existing(string fileName)
{
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisode = Builder<Episode>.CreateNew()
.With(c => c.EpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(e => e.Quality = new QualityModel(Quality.SDTV)).Build()
)
.Build();
//Mocks
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifyFileImport(result, Mocker, fakeEpisode, SIZE);
Mocker.GetMock<RecycleBinProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Once());
}
[TestCase("WEEDS.S03E01.DUAL.hdtv.XviD.AC3.-HELLYWOOD.avi")]
[TestCase("WEEDS.S03E01.DUAL.DVD.XviD.AC3.-HELLYWOOD.avi")]
[TestCase("WEEDS.S03E01.DUAL.bluray.x264.AC3.-HELLYWOOD.mkv")]
public void import_new_multi_part_file_episode_has_equal_or_better_quality_than_existing(string fileName)
{
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisodes = Builder<Episode>.CreateListOfSize(2)
.All()
.With(e => e.EpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(f => f.Quality = new QualityModel(Quality.SDTV))
.Build())
.Build().ToList();
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(fakeEpisodes);
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifyFileImport(result, Mocker, fakeEpisodes[0], SIZE);
Mocker.GetMock<RecycleBinProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Once());
}
[TestCase("WEEDS.S03E01.DUAL.DVD.XviD.AC3.-HELLYWOOD.avi")]
[TestCase("WEEDS.S03E01.DUAL.HDTV.XviD.AC3.-HELLYWOOD.avi")]
public void skip_import_new_multi_part_file_episode_existing_has_better_quality(string fileName)
{
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisodes = Builder<Episode>.CreateListOfSize(2)
.All()
.With(e => e.EpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(f => f.Quality = new QualityModel(Quality.Bluray720p))
.Build())
.Build().ToList();
//Mocks
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(fakeEpisodes);
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifySkipImport(result, Mocker);
VerifySkipImport(result);
}
[Test]
public void import_new_multi_part_file_episode_replace_two_files()
public void import_new_multi_part_file_episode_with_better_quality_than_existing()
{
const string fileName = "WEEDS.S03E01E02.DUAL.bluray.x264.AC3.-HELLYWOOD.mkv";
_fakeEpisodes[0].EpisodeFile = new EpisodeFile();
_fakeEpisodes[1].EpisodeFile = new EpisodeFile();
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
_fakeEpisodes[0].EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.SDTV) };
_fakeEpisodes[1].EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.SDTV) };
var fakeEpisodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
.All()
.With(e => e.Quality = new QualityModel(Quality.SDTV))
.Build();
GivenEpisodes(_fakeEpisodes, new QualityModel(Quality.HDTV1080p));
var fakeEpisode1 = Builder<Episode>.CreateNew()
.With(c => c.EpisodeFile = fakeEpisodeFiles[0])
.Build();
var fakeEpisode2 = Builder<Episode>.CreateNew()
.With(c => c.EpisodeFile = fakeEpisodeFiles[1])
.Build();
//Mocks
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode1, fakeEpisode2 });
var result = Subject.ImportFile(_fakeSeries, "file.ext");
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifyFileImport(result, Mocker, fakeEpisode1, SIZE);
Mocker.GetMock<RecycleBinProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Exactly(2));
VerifyFileImport(result);
}
[Test]
public void should_import_new_episode_no_existing_episode_file()
public void skip_import_new_multi_part_file_episode_existing_has_better_quality()
{
const string fileName = "WEEDS.S03E01E02.DUAL.bluray.x264.AC3.-HELLYWOOD.mkv";
_fakeEpisodes[0].EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV1080p) };
_fakeEpisodes[1].EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV1080p) };
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
GivenEpisodes(_fakeEpisodes, new QualityModel(Quality.SDTV));
var fakeEpisode = Builder<Episode>.CreateNew()
.Build();
//Mocks
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Subject.ImportFile(_fakeSeries, "file.ext");
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifyFileImport(result, Mocker, fakeEpisode, SIZE);
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
VerifySkipImport(result);
}
[Test]
public void should_set_parseResult_SceneSource_if_not_in_series_Path()
{
var series = Builder<Series>
.CreateNew()
.With(s => s.Path == @"C:\Test\TV\30 Rock")
.Build();
const string path = @"C:\Test\Unsorted TV\30 Rock\30.rock.s01e01.pilot.mkv";
With80MBFile();
Mocker.GetMock<IEpisodeService>().Setup(s => s.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>()))
.Returns(new List<Episode>());
Mocker.GetMock<DiskProvider>().Setup(s => s.IsChildOfPath(path, series.Path))
.Returns(false);
Mocker.Resolve<DiskScanProvider>().ImportFile(series, path);
Mocker.Verify<IEpisodeService>(s => s.GetEpisodesByParseResult(It.Is<IndexerParseResult>(p => p.SceneSource)), Times.Once());
}
[Test]
public void should_not_set_parseResult_SceneSource_if_in_series_Path()
public void should_skip_if_file_size_is_under_70MB_and_runTime_under_3_minutes()
{
var series = Builder<Series>
.CreateNew()
.With(s => s.Path == @"C:\Test\TV\30 Rock")
.Build();
GivenFileSize(50.Megabytes());
GivenVideoDuration(TimeSpan.FromMinutes(1));
const string path = @"C:\Test\TV\30 Rock\30.rock.s01e01.pilot.mkv";
GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.HDTV1080p));
With80MBFile();
var result = Subject.ImportFile(_fakeSeries, "file.ext");
Mocker.GetMock<IEpisodeService>().Setup(s => s.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>()))
.Returns(new List<Episode>());
Mocker.GetMock<DiskProvider>().Setup(s => s.IsChildOfPath(path, series.Path))
.Returns(true);
Mocker.Resolve<DiskScanProvider>().ImportFile(series, path);
Mocker.Verify<IEpisodeService>(s => s.GetEpisodesByParseResult(It.Is<IndexerParseResult>(p => p.SceneSource == false)), Times.Once());
}
[Test]
public void should_return_null_if_file_size_is_under_70MB_and_runTime_under_3_minutes()
{
const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi";
Mocker.GetMock<IMediaFileService>()
.Setup(m => m.Exists(path))
.Returns(false);
Mocker.GetMock<DiskProvider>()
.Setup(d => d.GetSize(path))
.Returns(20.Megabytes());
Mocker.GetMock<MediaInfoProvider>()
.Setup(s => s.GetRunTime(path))
.Returns(60);
Mocker.Resolve<DiskScanProvider>().ImportFile(_series, path).Should().BeNull();
VerifySkipImport(result);
}
[Test]
public void should_import_if_file_size_is_under_70MB_but_runTime_over_3_minutes()
{
var fakeEpisode = Builder<Episode>.CreateNew()
.Build();
GivenFileSize(50.Megabytes());
GivenVideoDuration(TimeSpan.FromMinutes(20));
const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi";
GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.HDTV1080p));
Mocker.GetMock<IMediaFileService>()
.Setup(m => m.Exists(path))
.Returns(false);
var result = Subject.ImportFile(_fakeSeries, "file.ext");
Mocker.GetMock<DiskProvider>()
.Setup(d => d.GetSize(path))
.Returns(20.Megabytes());
Mocker.GetMock<MediaInfoProvider>()
.Setup(s => s.GetRunTime(path))
.Returns(600);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(_series, path);
VerifyFileImport(result, Mocker, fakeEpisode, 20.Megabytes());
VerifyFileImport(result);
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
}
[Test]
public void should_import_if_file_size_is_over_70MB_but_runTime_under_3_minutes()
{
With80MBFile();
GivenFileSize(100.Megabytes());
GivenVideoDuration(TimeSpan.FromMinutes(1));
var fakeEpisode = Builder<Episode>.CreateNew()
.Build();
GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.HDTV1080p));
const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi";
var result = Subject.ImportFile(_fakeSeries, "file.ext");
Mocker.GetMock<IMediaFileService>()
.Setup(m => m.Exists(path))
.Returns(false);
Mocker.GetMock<MediaInfoProvider>()
.Setup(s => s.GetRunTime(path))
.Returns(60);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(_series, path);
VerifyFileImport(result, Mocker, fakeEpisode, SIZE);
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
VerifyFileImport(result);
}
[Test]
public void should_import_special_even_if_file_size_is_under_70MB_and_runTime_under_3_minutes()
{
With80MBFile();
GivenFileSize(10.Megabytes());
GivenVideoDuration(TimeSpan.FromMinutes(1));
var fakeEpisode = Builder<Episode>.CreateNew()
.Build();
_fakeEpisode.SeasonNumber = 0;
const string path = @"C:\Test\TV\30.rock.s00e01.pre-pilot.avi";
GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.HDTV1080p));
Mocker.GetMock<IMediaFileService>()
.Setup(m => m.Exists(path))
.Returns(false);
var result = Subject.ImportFile(_fakeSeries, "file.ext");
Mocker.GetMock<DiskProvider>()
.Setup(d => d.GetSize(path))
.Returns(20.Megabytes());
Mocker.GetMock<MediaInfoProvider>()
.Setup(s => s.GetRunTime(path))
.Returns(60);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(_series, path);
VerifyFileImport(result, Mocker, fakeEpisode, 20.Megabytes());
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
VerifyFileImport(result);
}
[Test]
public void should_return_null_if_daily_series_with_file_size_is_under_70MB_and_runTime_under_3_minutes()
public void should_skip_if_daily_series_with_file_size_is_under_70MB_and_runTime_under_3_minutes()
{
WithDailySeries();
GivenFileSize(10.Megabytes());
GivenVideoDuration(TimeSpan.FromMinutes(1));
const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi";
_fakeEpisode.SeasonNumber = 0;
_fakeSeries.SeriesType = SeriesTypes.Daily;
Mocker.GetMock<IMediaFileService>()
.Setup(m => m.Exists(path))
.Returns(false);
GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.HDTV1080p));
Mocker.GetMock<DiskProvider>()
.Setup(d => d.GetSize(path))
.Returns(20.Megabytes());
var result = Subject.ImportFile(_fakeSeries, "file.ext");
Mocker.GetMock<MediaInfoProvider>()
.Setup(s => s.GetRunTime(path))
.Returns(60);
Mocker.Resolve<DiskScanProvider>().ImportFile(_series, path).Should().BeNull();
VerifySkipImport(result);
}
private static void VerifyFileImport(EpisodeFile result, AutoMoqer Mocker, Episode fakeEpisode, long size)
private void VerifyFileImport(EpisodeFile result)
{
result.Should().NotBeNull();
result.SeriesId.Should().Be(fakeEpisode.SeriesId);
result.Size.Should().Be(size);
result.SeriesId.Should().Be(_fakeSeries.Id);
result.Size.Should().Be(_fileSize);
result.DateAdded.Should().HaveDay(DateTime.Now.Day);
Mocker.GetMock<IMediaFileService>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Once());
//Get the count of episodes linked
var count = Mocker.GetMock<IEpisodeService>().Object.GetEpisodesByParseResult(null).Count;
Mocker.GetMock<IEpisodeService>().Verify(p => p.UpdateEpisode(It.Is<Episode>(e => e.EpisodeFileId == result.Id)), Times.Exactly(count));
Mocker.GetMock<IMediaFileService>().Verify(c => c.Add(result), Times.Once());
}
private static void VerifySkipImport(EpisodeFile result, AutoMoqer Mocker)
private void VerifySkipImport(EpisodeFile result)
{
result.Should().BeNull();
Mocker.GetMock<IMediaFileService>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Never());
Mocker.GetMock<IEpisodeService>().Verify(p => p.UpdateEpisode(It.IsAny<Episode>()), Times.Never());
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
}
}
}
@@ -0,0 +1,145 @@
using System;
using System.IO;
using FizzWare.NBuilder;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
{
[TestFixture]
public class DropFolderImportServiceFixture : CoreTest<DropFolderImportService>
{
private EpisodeFile _fakeEpisodeFile;
private string[] _subFolders = new[] { "c:\\root\\foldername" };
private string[] _videoFiles = new[] { "c:\\root\\foldername\\video.ext" };
[SetUp]
public void Setup()
{
_fakeEpisodeFile = Builder<EpisodeFile>.CreateNew().Build();
Mocker.GetMock<DiskScanProvider>().Setup(c => c.GetVideoFiles(It.IsAny<string>(), It.IsAny<bool>()))
.Returns(_videoFiles);
Mocker.GetMock<DiskProvider>().Setup(c => c.GetDirectories(It.IsAny<string>()))
.Returns(_subFolders);
}
private void WithOldWrite()
{
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetLastFolderWrite(It.IsAny<String>()))
.Returns(DateTime.Now.AddDays(-5));
}
private void WithRecentFolderWrite()
{
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetLastFolderWrite(It.IsAny<String>()))
.Returns(DateTime.UtcNow);
}
[Test]
public void should_import_file()
{
Subject.ProcessDropFolder("c:\\drop\\");
VerifyImport();
}
[Test]
public void should_skip_if_folder_is_too_fresh()
{
WithRecentFolderWrite();
Subject.ProcessDropFolder("c:\\drop\\");
VerifyNoImport();
}
[Test]
public void should_search_for_series_using_folder_name()
{
WithOldWrite();
Subject.ProcessDropFolder("c:\\drop\\");
Mocker.GetMock<ISeriesService>().Verify(c => c.FindByTitle("foldername"), Times.Once());
}
[Test]
public void should_search_for_series_using_file_name()
{
/*WithOldWrite();
WithValidSeries();
WithImportableFiles();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - S01E01 - Episode Title");
Subject.ProcessDownload(droppedFolder);
Mocker.GetMock<DiskScanProvider>()
.Verify(c => c.Scan(_fakeSeries, It.IsAny<string>()));*/
}
[Test]
public void all_imported_files_should_be_moved()
{
Mocker.GetMock<DiskScanProvider>().Setup(c => c.ImportFile(It.IsAny<Series>(), It.IsAny<string>()))
.Returns(_fakeEpisodeFile);
Subject.ProcessDropFolder("c:\\drop\\");
Mocker.GetMock<IMoveEpisodeFiles>().Verify(c => c.MoveEpisodeFile(_fakeEpisodeFile, true), Times.Once());
}
[Test]
public void should_not_attempt_move_if_nothing_is_imported()
{
Mocker.GetMock<DiskScanProvider>().Setup(c => c.ImportFile(It.IsAny<Series>(), It.IsAny<string>()))
.Returns<EpisodeFile>(null);
Subject.ProcessDropFolder("c:\\drop\\");
Mocker.GetMock<IMoveEpisodeFiles>().Verify(c => c.MoveEpisodeFile(It.IsAny<EpisodeFile>(), It.IsAny<bool>()), Times.Never());
}
[Test]
public void should_skip_if_folder_is_in_use_by_another_process()
{
Mocker.GetMock<DiskProvider>().Setup(c => c.IsFileLocked(It.IsAny<FileInfo>()))
.Returns(true);
Subject.ProcessDropFolder("c:\\drop\\");
VerifyNoImport();
}
private void VerifyNoImport()
{
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(It.IsAny<Series>(), It.IsAny<string>()),
Times.Never());
}
private void VerifyImport()
{
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(It.IsAny<Series>(), It.IsAny<string>()),
Times.Once());
}
}
}
@@ -1,44 +0,0 @@
using System.Linq;
using System;
using System.IO;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
{
[TestFixture]
public class GetFolderNameWithStatusFixture : CoreTest
{
[TestCase(@"c:\_NzbDrone_InvalidEpisode_Title", @"c:\_UnknownSeries_Title", PostDownloadStatusType.UnknownSeries)]
[TestCase(@"c:\Title", @"c:\_Failed_Title", PostDownloadStatusType.Failed)]
[TestCase(@"c:\Root\Test Title", @"c:\Root\_ParseError_Test Title", PostDownloadStatusType.ParseError)]
public void GetFolderNameWithStatus_should_return_a_string_with_the_error_removing_existing_error(string currentName, string excpectedName, PostDownloadStatusType status)
{
PostDownloadProvider.GetTaggedFolderName(new DirectoryInfo(currentName), status).Should().Be(
excpectedName);
}
[TestCase(PostDownloadStatusType.NoError)]
[ExpectedException(typeof(InvalidOperationException))]
public void GetFolderNameWithStatus_should_throw_if_status_is_not_an_error(PostDownloadStatusType status)
{
PostDownloadProvider.GetTaggedFolderName(new DirectoryInfo(TempFolder), status);
}
[TestCase("_NzbDrone_ParseError_The Office (US) - S01E01 - Episode Title", "The Office (US) - S01E01 - Episode Title")]
[TestCase("_Status_The Office (US) - S01E01 - Episode Title", "The Office (US) - S01E01 - Episode Title")]
[TestCase("The Office (US) - S01E01 - Episode Title", "The Office (US) - S01E01 - Episode Title")]
[TestCase("_The Office (US) - S01E01 - Episode Title", "_The Office (US) - S01E01 - Episode Title")]
public void RemoveStatus_should_remove_status_string_from_folder_name(string folderName, string cleanFolderName)
{
PostDownloadProvider.RemoveStatusFromFolderName(folderName).Should().Be(cleanFolderName);
}
}
}
@@ -1,469 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FizzWare.NBuilder;
using Marr.Data;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
using NzbDrone.Test.Common.AutoMoq;
namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
{
[TestFixture]
public class ProcessDownloadFixture : CoreTest
{
Series fakeSeries;
[SetUp]
public void Setup()
{
fakeSeries = Builder<Series>.CreateNew()
.With(s => s.RootFolder = new LazyLoaded<RootFolder>(new RootFolder { Path = @"C:\Test\TV" }))
.With(s => s.FolderName = "30 Rock")
.Build();
}
private void WithOldWrite()
{
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetLastDirectoryWrite(It.IsAny<String>()))
.Returns(DateTime.Now.AddDays(-5));
}
private void WithRecentWrite()
{
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetLastDirectoryWrite(It.IsAny<String>()))
.Returns(DateTime.UtcNow);
}
private void WithValidSeries()
{
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle(It.IsAny<string>()))
.Returns(fakeSeries);
Mocker.GetMock<DiskProvider>()
.Setup(c => c.FolderExists(fakeSeries.Path))
.Returns(true);
}
private void WithImportableFiles()
{
Mocker.GetMock<DiskScanProvider>()
.Setup(c => c.Scan(It.IsAny<Series>(), It.IsAny<string>()))
.Returns(Builder<EpisodeFile>.CreateListOfSize(1).Build().ToList());
}
private void WithLotsOfFreeDiskSpace()
{
Mocker.GetMock<DiskProvider>().Setup(s => s.FreeDiskSpace(It.IsAny<string>())).Returns(1000000000);
}
private void WithImportedFiles(string droppedFolder)
{
var fakeEpisodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
.All()
.With(f => f.SeriesId = fakeSeries.Id)
.Build().ToList();
Mocker.GetMock<DiskScanProvider>().Setup(s => s.Scan(fakeSeries, droppedFolder)).Returns(fakeEpisodeFiles);
}
[Test]
public void should_skip_if_folder_is_tagged_and_too_fresh()
{
WithStrictMocker();
WithRecentWrite();
var droppedFolder = new DirectoryInfo(TempFolder + "\\_test\\");
droppedFolder.Create();
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
}
[Test]
public void should_continue_processing_if_folder_is_tagged_and_not_fresh()
{
WithOldWrite();
var droppedFolder = new DirectoryInfo(TempFolder + "\\_test\\");
droppedFolder.Create();
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle(It.IsAny<String>())).Returns<Series>(null).Verifiable();
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
ExceptionVerification.IgnoreWarns();
}
[Test]
public void should_search_for_series_using_title_without_status()
{
WithOldWrite();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\_unpack_The Office - S01E01 - Episode Title");
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns<Series>(null).Verifiable();
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
ExceptionVerification.IgnoreWarns();
}
[Test]
public void should_search_for_series_using_folder_name()
{
WithOldWrite();
WithValidSeries();
WithImportableFiles();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - S01E01 - Episode Title");
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.GetMock<DiskScanProvider>()
.Verify(c=>c.Scan(fakeSeries, It.IsAny<string>()));
}
[Test]
public void should_search_for_series_using_file_name()
{
WithOldWrite();
WithValidSeries();
WithImportableFiles();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - S01E01 - Episode Title");
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.GetMock<DiskScanProvider>()
.Verify(c => c.Scan(fakeSeries, It.IsAny<string>()));
}
[Test]
[Ignore("Disabled tagging")]
public void when_series_isnt_found_folder_should_be_tagged_as_unknown_series()
{
WithStrictMocker();
WithOldWrite();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - S01E01 - Episode Title");
var taggedFolder = @"C:\Test\Unsorted TV\_UnknownSeries_The Office - S01E01 - Episode Title";
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns<Series>(null);
Mocker.GetMock<DiskProvider>().Setup(s => s.MoveDirectory(droppedFolder.FullName, taggedFolder));
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
ExceptionVerification.ExpectedWarns(1);
}
[Test]
[Ignore("Disabled tagging")]
public void when_no_files_are_imported_folder_should_be_tagged_with_parse_error()
{
WithStrictMocker();
WithOldWrite();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - S01E01 - Episode Title");
var taggedFolder = @"C:\Test\Unsorted TV\_ParseError_The Office - S01E01 - Episode Title";
var fakeSeries = Builder<Series>.CreateNew()
.With(s => s.Title = "The Office")
.Build();
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns(fakeSeries);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.Scan(fakeSeries, droppedFolder.FullName)).Returns(new List<EpisodeFile>());
Mocker.GetMock<DiskProvider>().Setup(s => s.MoveDirectory(droppedFolder.FullName, taggedFolder));
Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize + 10.Megabytes());
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
ExceptionVerification.ExpectedWarns(1);
}
[Test]
[Ignore("Disabled tagging")]
public void when_no_file_are_imported_and_folder_size_isnt_small_enought_folder_should_be_tagged_unknown()
{
WithStrictMocker();
WithOldWrite();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - Season 01");
var taggedFolder = PostDownloadProvider.GetTaggedFolderName(droppedFolder, PostDownloadStatusType.Unknown);
var fakeSeries = Builder<Series>.CreateNew()
.With(s => s.Title = "The Office")
.Build();
var fakeEpisodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
.All()
.With(f => f.SeriesId = fakeSeries.Id)
.Build().ToList();
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns(fakeSeries);
Mocker.GetMock<DiskProvider>().Setup(s => s.MoveDirectory(droppedFolder.FullName, taggedFolder));
Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize + 10.Megabytes());
Mocker.GetMock<DiskScanProvider>().Setup(s => s.Scan(fakeSeries, droppedFolder.FullName)).Returns(fakeEpisodeFiles);
Mocker.GetMock<IMoveEpisodeFiles>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(new EpisodeFile());
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
ExceptionVerification.ExpectedWarns(1);
}
[TestCase(@"\_UnknownSeries_The Office - S01E01 - Episode Title")]
[TestCase(@"\_UnknownSeries_The Office - S01E01 - Episode Title\")]
[TestCase("\\Test\\_UnknownSeries_The Office - S01E01 - Episode Title\\")]
[TestCase("\\Test\\_UnknownSeries_The Office - S01E01 - Episode Title")]
public void folder_shouldnt_be_tagged_with_same_tag_again(string path)
{
var droppedFolder = new DirectoryInfo(TempFolder + path);
droppedFolder.Create();
WithOldWrite();
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle(It.IsAny<String>())).Returns<Series>(null);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
Mocker.GetMock<DiskProvider>().Verify(c => c.MoveDirectory(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
}
[Test]
public void folder_should_not_be_tagged_if_existing_tag_is_diffrent()
{
WithOldWrite();
var droppedFolder = new DirectoryInfo(TempFolder + @"\_UnknownEpisode_The Office - S01E01 - Episode Title");
droppedFolder.Create();
droppedFolder.LastWriteTime = DateTime.Now.AddHours(-1);
var taggedFolder = TempFolder + @"\_UnknownSeries_The Office - S01E01 - Episode Title";
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle(It.IsAny<String>())).Returns<Series>(null);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
Mocker.GetMock<DiskProvider>().Verify(c => c.MoveDirectory(droppedFolder.FullName, taggedFolder), Times.Never());
ExceptionVerification.IgnoreWarns();
}
[Test]
public void when_files_are_imported_and_folder_is_small_enough_dir_should_be_deleted()
{
WithStrictMocker();
WithLotsOfFreeDiskSpace();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - Season 01");
WithImportedFiles(droppedFolder.FullName);
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns(fakeSeries);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.CleanUpDropFolder(droppedFolder.FullName));
Mocker.GetMock<IMoveEpisodeFiles>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(new EpisodeFile());
Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize - 1.Megabytes());
Mocker.GetMock<DiskProvider>().Setup(s => s.DeleteFolder(droppedFolder.FullName, true));
Mocker.GetMock<DiskProvider>().Setup(s => s.FolderExists(fakeSeries.Path)).Returns(true);
Mocker.GetMock<DiskProvider>().Setup(s => s.IsFolderLocked(droppedFolder.FullName)).Returns(false);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
}
[Test]
public void all_imported_files_should_be_moved()
{
var droppedFolder = new DirectoryInfo(TempFolder);
var fakeSeries = Builder<Series>.CreateNew()
.Build();
var fakeEpisodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
.Build().ToList();
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle(It.IsAny<string>())).Returns(fakeSeries);
Mocker.GetMock<DiskProvider>().Setup(s => s.FolderExists(fakeSeries.Path)).Returns(true);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.Scan(fakeSeries, droppedFolder.FullName)).Returns(fakeEpisodeFiles);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.GetMock<IMoveEpisodeFiles>().Verify(c => c.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true),
Times.Exactly(fakeEpisodeFiles.Count));
Mocker.VerifyAllMocks();
}
[Test]
public void should_logError_and_return_if_size_exceeds_free_space()
{
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
var series = Builder<Series>.CreateNew()
.With(s => s.Title = "30 Rock")
.With(s => s.RootFolder = new LazyLoaded<RootFolder>(new RootFolder { Path = @"C:\Test\TV" }))
.With(s => s.FolderName = "30 Rock")
.Build();
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle("rock"))
.Returns(series);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.GetDirectorySize(downloadName.FullName))
.Returns(10);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FolderExists(series.Path))
.Returns(true);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(series.Path))
.Returns(9);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(downloadName);
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(series, downloadName.FullName), Times.Never());
ExceptionVerification.ExpectedErrors(1);
}
[Test]
public void should_process_if_free_disk_space_exceeds_size()
{
WithLotsOfFreeDiskSpace();
WithValidSeries();
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
WithImportedFiles(downloadName.FullName);
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle("rock"))
.Returns(fakeSeries);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.GetDirectorySize(downloadName.FullName))
.Returns(8);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(downloadName);
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(fakeSeries, downloadName.FullName), Times.Once());
}
[Test]
public void should_process_if_free_disk_space_equals_size()
{
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
WithImportedFiles(downloadName.FullName);
WithValidSeries();
Mocker.GetMock<DiskProvider>()
.Setup(s => s.GetDirectorySize(downloadName.FullName))
.Returns(10);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(It.IsAny<string>()))
.Returns(10);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(downloadName);
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(fakeSeries, downloadName.FullName), Times.Once());
}
[Test]
public void should_create_series_directory_if_series_path_does_not_exist()
{
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
WithValidSeries();
WithLotsOfFreeDiskSpace();
WithImportedFiles(downloadName.FullName);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FolderExists(fakeSeries.Path))
.Returns(false);
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns(fakeSeries);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.CleanUpDropFolder(downloadName.FullName));
Mocker.GetMock<IMoveEpisodeFiles>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(new EpisodeFile());
Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(downloadName.FullName)).Returns(Constants.IgnoreFileSize - 1.Megabytes());
Mocker.GetMock<DiskProvider>().Setup(s => s.DeleteFolder(downloadName.FullName, true));
Mocker.GetMock<DiskProvider>().Setup(s => s.IsFolderLocked(downloadName.FullName)).Returns(false);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(downloadName);
Mocker.GetMock<DiskProvider>().Verify(c => c.CreateDirectory(fakeSeries.Path), Times.Once());
ExceptionVerification.ExpectedWarns(1);
}
[Test]
public void should_skip_if_folder_is_in_use_by_another_process()
{
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
WithValidSeries();
Mocker.GetMock<DiskProvider>()
.Setup(s => s.IsFolderLocked(downloadName.FullName))
.Returns(true);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(downloadName);
Mocker.GetMock<DiskProvider>().Verify(c => c.GetDirectorySize(It.IsAny<String>()), Times.Never());
}
}
}
@@ -1,135 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FizzWare.NBuilder;
using Marr.Data;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
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<Series>.CreateNew()
.With(s => s.RootFolder = new LazyLoaded<RootFolder>(new RootFolder { Path = @"C:\Test\TV" }))
.With(s => s.FolderName = "30 Rock")
.Build();
}
private void WithLotsOfFreeDiskSpace()
{
Mocker.GetMock<DiskProvider>().Setup(s => s.FreeDiskSpace(It.IsAny<string>())).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<DiskScanProvider>()
.Setup(c => c.GetVideoFiles(It.IsAny<String>(), false))
.Returns(new List<String>());
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetDirectories(It.IsAny<String>()))
.Returns(subFolders);
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.SeriesPathExists(subFolders[1]))
.Returns(true);
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle(It.IsAny<String>()))
.Returns(fakeSeries);
Mocker.GetMock<DiskScanProvider>()
.Setup(c => c.Scan(It.IsAny<Series>(), It.IsAny<String>()))
.Returns(new List<EpisodeFile>());
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetDirectorySize(It.IsAny<String>()))
.Returns(10);
Mocker.GetMock<DiskProvider>()
.Setup(c => c.FolderExists(It.IsAny<String>()))
.Returns(true);
Mocker.Resolve<PostDownloadProvider>().ProcessDropFolder(@"C:\drop\");
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(It.IsAny<Series>(), subFolders[0]), Times.Once());
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(It.IsAny<Series>(), subFolders[1]), Times.Never());
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(It.IsAny<Series>(), subFolders[2]), Times.Once());
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(It.IsAny<Series>(), subFolders[3]), Times.Once());
}
[Test]
public void ProcessDropFolder_should_process_individual_video_files_in_drop_folder()
{
WithLotsOfFreeDiskSpace();
var files = new List<String>
{
@"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<DiskScanProvider>()
.Setup(c => c.GetVideoFiles(It.IsAny<String>(), false))
.Returns(files);
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle(It.IsAny<String>()))
.Returns(fakeSeries);
Mocker.GetMock<DiskScanProvider>()
.Setup(c => c.Scan(It.IsAny<Series>(), It.IsAny<String>()))
.Returns(new List<EpisodeFile>());
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetDirectorySize(It.IsAny<String>()))
.Returns(10);
Mocker.GetMock<DiskProvider>()
.Setup(c => c.FolderExists(It.IsAny<String>()))
.Returns(true);
Mocker.Resolve<PostDownloadProvider>().ProcessDropFolder(@"C:\drop\");
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(It.IsAny<Series>(), It.IsAny<String>()), Times.Exactly(4));
}
}
}
@@ -1,267 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FizzWare.NBuilder;
using Marr.Data;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
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<Series>.CreateNew()
.With(s => s.RootFolder = new LazyLoaded<RootFolder>(new RootFolder { Path = @"C:\Test\TV" }))
.With(s => s.FolderName = "30 Rock")
.Build();
}
private void WithOldWrite()
{
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetLastFileWrite(It.IsAny<String>()))
.Returns(DateTime.Now.AddDays(-5));
}
private void WithRecentWrite()
{
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetLastFileWrite(It.IsAny<String>()))
.Returns(DateTime.UtcNow);
}
private void WithValidSeries()
{
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle(It.IsAny<string>()))
.Returns(fakeSeries);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FolderExists(fakeSeries.Path))
.Returns(true);
}
private void WithImportableFiles()
{
Mocker.GetMock<DiskScanProvider>()
.Setup(c => c.Scan(It.IsAny<Series>(), It.IsAny<string>()))
.Returns(Builder<EpisodeFile>.CreateListOfSize(1).Build().ToList());
}
private void WithLotsOfFreeDiskSpace()
{
Mocker.GetMock<DiskProvider>().Setup(s => s.FreeDiskSpace(It.IsAny<string>())).Returns(1000000000);
}
private void WithImportedFile(string file)
{
var fakeEpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(f => f.SeriesId = fakeSeries.Id)
.Build();
Mocker.GetMock<DiskScanProvider>().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<PostDownloadProvider>().ProcessVideoFile(file);
}
[Test]
public void should_continue_processing_if_not_fresh()
{
WithOldWrite();
var file = Path.Combine(TempFolder, "test.avi");
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle(It.IsAny<String>())).Returns<Series>(null).Verifiable();
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(file);
Mocker.GetMock<ISeriesRepository>().Verify(s => s.GetByTitle(It.IsAny<String>()), Times.Once());
ExceptionVerification.IgnoreWarns();
}
[Test]
public void should_return_if_series_is_not_found()
{
WithOldWrite();
var file = Path.Combine(TempFolder, "test.avi");
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle(It.IsAny<String>())).Returns<Series>(null);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(file);
Mocker.GetMock<DiskProvider>().Verify(s => s.GetSize(It.IsAny<String>()), Times.Never());
ExceptionVerification.IgnoreWarns();
}
[Test]
public void should_move_file_if_imported()
{
WithLotsOfFreeDiskSpace();
WithOldWrite();
var file = Path.Combine(TempFolder, "test.avi");
WithValidSeries();
WithImportedFile(file);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(file);
Mocker.GetMock<IMoveEpisodeFiles>().Verify(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), 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<Series>.CreateNew()
.With(s => s.Title = "30 Rock")
.With(s => s.RootFolder = new LazyLoaded<RootFolder>(new RootFolder { Path = @"C:\Test\TV" }))
.With(s => s.FolderName = "30 Rock")
.Build();
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle("rock"))
.Returns(series);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.GetSize(downloadName))
.Returns(10);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(series.Path))
.Returns(9);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FolderExists(series.Path))
.Returns(true);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(downloadName);
Mocker.GetMock<DiskScanProvider>().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<ISeriesRepository>()
.Setup(c => c.GetByTitle("rock"))
.Returns(fakeSeries);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.GetSize(downloadName))
.Returns(8);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(downloadName);
Mocker.GetMock<DiskScanProvider>().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<DiskProvider>()
.Setup(s => s.GetDirectorySize(downloadName))
.Returns(10);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(It.IsAny<string>()))
.Returns(10);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(downloadName);
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(fakeSeries, downloadName), Times.Once());
}
[Test]
public void should_return_if_series_Path_doesnt_exist()
{
var downloadName = @"C:\Test\Drop\30.Rock.S01E01.Pilot.mkv";
WithValidSeries();
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FolderExists(fakeSeries.Path))
.Returns(false);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(downloadName);
ExceptionVerification.ExpectedWarns(1);
}
[Test]
public void should_skip_if_file_is_in_use_by_another_process()
{
var downloadName = @"C:\Test\Drop\30.Rock.S01E01.Pilot.mkv";
WithValidSeries();
Mocker.GetMock<DiskProvider>()
.Setup(s => s.IsFileLocked(It.Is<FileInfo>(f => f.FullName == downloadName)))
.Returns(true);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(downloadName);
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(fakeSeries, downloadName), Times.Never());
}
}
}
@@ -18,7 +18,7 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests
private void WithExpired()
{
Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastDirectoryWrite(It.IsAny<String>()))
Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastFolderWrite(It.IsAny<String>()))
.Returns(DateTime.UtcNow.AddDays(-10));
Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastFileWrite(It.IsAny<String>()))
@@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests
private void WithNonExpired()
{
Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastDirectoryWrite(It.IsAny<String>()))
Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastFolderWrite(It.IsAny<String>()))
.Returns(DateTime.UtcNow.AddDays(-3));
Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastFileWrite(It.IsAny<String>()))