Fixed some issues with PostDownloadProvider.

Added tests for PostDownloadProvider.
This commit is contained in:
Mark McDowall 2011-10-17 13:05:38 -07:00
parent 1ff34c8e38
commit 642707e46d
4 changed files with 189 additions and 28 deletions

View File

@ -1,6 +1,7 @@
// ReSharper disable RedundantUsingDirective
using System;
using System.Collections.Generic;
using System.Data.SqlServerCe;
using System.Linq;
using AutoMoq;
using FizzWare.NBuilder;
@ -1502,5 +1503,74 @@ namespace NzbDrone.Core.Test
var result = db.Fetch<Episode>();
result.Where(e => e.PostDownloadStatus == postDownloadStatus).Count().Should().Be(episodeCount);
}
[Test]
public void SetPostDownloadStatus_Invalid_EpisodeId()
{
var db = MockLib.GetEmptyDatabase();
var mocker = new AutoMoqer();
mocker.SetConstant(db);
var postDownloadStatus = PostDownloadStatusType.Failed;
var fakeSeries = Builder<Series>.CreateNew()
.With(s => s.SeriesId = 12345)
.With(s => s.CleanTitle = "officeus")
.Build();
var fakeEpisodes = Builder<Episode>.CreateListOfSize(1)
.WhereAll()
.Have(c => c.SeriesId = 12345)
.Have(c => c.SeasonNumber = 1)
.Have(c => c.PostDownloadStatus = PostDownloadStatusType.Unknown)
.Build();
db.Insert(fakeSeries);
db.InsertMany(fakeEpisodes);
mocker.GetMock<SeriesProvider>().Setup(s => s.FindSeries("officeus")).Returns(fakeSeries);
//Act
mocker.Resolve<EpisodeProvider>().SetPostDownloadStatus(new List<int>{300}, postDownloadStatus);
//Assert
var result = db.Fetch<Episode>();
result.Where(e => e.PostDownloadStatus == postDownloadStatus).Count().Should().Be(0);
}
[Test]
[ExpectedException(typeof(SqlCeException))]
public void SetPostDownloadStatus_No_EpisodeId_In_Database()
{
var db = MockLib.GetEmptyDatabase();
var mocker = new AutoMoqer();
mocker.SetConstant(db);
var postDownloadStatus = PostDownloadStatusType.Failed;
var fakeSeries = Builder<Series>.CreateNew()
.With(s => s.SeriesId = 12345)
.With(s => s.CleanTitle = "officeus")
.Build();
var fakeEpisodes = Builder<Episode>.CreateListOfSize(1)
.WhereAll()
.Have(c => c.SeriesId = 12345)
.Have(c => c.SeasonNumber = 1)
.Have(c => c.PostDownloadStatus = PostDownloadStatusType.Unknown)
.Build();
db.Insert(fakeSeries);
db.InsertMany(fakeEpisodes);
mocker.GetMock<SeriesProvider>().Setup(s => s.FindSeries("officeus")).Returns(fakeSeries);
//Act
mocker.Resolve<EpisodeProvider>().SetPostDownloadStatus(new List<int>(), postDownloadStatus);
//Assert
var result = db.Fetch<Episode>();
result.Where(e => e.PostDownloadStatus == postDownloadStatus).Count().Should().Be(0);
}
}
}

View File

@ -23,13 +23,13 @@ namespace NzbDrone.Core.Test
// ReSharper disable InconsistentNaming
public class PostDownloadProviderTest : TestBase
{
[TestCase("The Office (US) - S01E05 - Episode Title", PostDownloadStatusType.Unpacking, 1)]
[TestCase("The Office (US) - S01E05 - Episode Title", PostDownloadStatusType.Failed, 1)]
[TestCase("The Office (US) - S01E05E06 - Episode Title", PostDownloadStatusType.Unpacking, 2)]
[TestCase("The Office (US) - S01E05E06 - Episode Title", PostDownloadStatusType.Failed, 2)]
[TestCase("The Office (US) - Season 01 - Episode Title", PostDownloadStatusType.Unpacking, 10)]
[TestCase("The Office (US) - Season 01 - Episode Title", PostDownloadStatusType.Failed, 10)]
public void SetPostDownloadStatus(string folderName, PostDownloadStatusType postDownloadStatus, int episodeCount)
[TestCase("_UNPACK_The Office (US) - S01E01 - Episode Title", PostDownloadStatusType.Unpacking, 1)]
[TestCase("_FAILED_The Office (US) - S01E01 - Episode Title", PostDownloadStatusType.Failed, 1)]
[TestCase("_UNPACK_The Office (US) - S01E01E02 - Episode Title", PostDownloadStatusType.Unpacking, 2)]
[TestCase("_FAILED_The Office (US) - S01E01E02 - Episode Title", PostDownloadStatusType.Failed, 2)]
[TestCase("_UNPACK_The Office (US) - Season 01 - Episode Title", PostDownloadStatusType.Unpacking, 10)]
[TestCase("_FAILED_The Office (US) - Season 01 - Episode Title", PostDownloadStatusType.Failed, 10)]
public void ProcessFailedOrUnpackingDownload(string folderName, PostDownloadStatusType postDownloadStatus, int episodeCount)
{
var db = MockLib.GetEmptyDatabase();
var mocker = new AutoMoqer();
@ -40,24 +40,78 @@ namespace NzbDrone.Core.Test
.With(s => s.CleanTitle = "officeus")
.Build();
var fakeEpisodes = Builder<Episode>.CreateListOfSize(10)
var fakeEpisodes = Builder<Episode>.CreateListOfSize(episodeCount)
.WhereAll()
.Have(c => c.SeriesId = 12345)
.Have(c => c.SeasonNumber = 1)
.Have(c => c.PostDownloadStatus = PostDownloadStatusType.Unknown)
.Build();
db.Insert(fakeSeries);
db.InsertMany(fakeEpisodes);
var expectedEpisodesNumbers = fakeEpisodes.Select(e => e.EpisodeId);
mocker.GetMock<SeriesProvider>().Setup(s => s.FindSeries("officeus")).Returns(fakeSeries);
mocker.GetMock<EpisodeProvider>().Setup(s => s.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>(), false)).Returns(fakeEpisodes);
mocker.GetMock<EpisodeProvider>().Setup(s => s.GetEpisodesBySeason(12345, 1)).Returns(fakeEpisodes);
mocker.GetMock<EpisodeProvider>().Setup(
s => s.SetPostDownloadStatus(expectedEpisodesNumbers, postDownloadStatus)).Verifiable();
//Act
//mocker.Resolve<EpisodeProvider>().SetPostDownloadStatus(folderName, postDownloadStatus);
mocker.Resolve<PostDownloadProvider>().ProcessFailedOrUnpackingDownload(new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), folderName)),postDownloadStatus);
//Assert
var result = db.Fetch<Episode>();
result.Where(e => e.PostDownloadStatus == postDownloadStatus).Count().Should().Be(episodeCount);
mocker.GetMock<EpisodeProvider>().Verify(c => c.SetPostDownloadStatus(expectedEpisodesNumbers, postDownloadStatus), Times.Once());
}
[Test]
public void ProcessFailedOrUnpackingDownload_Already_Existing_Time_Not_Passed()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
var path = Path.Combine(Directory.GetCurrentDirectory(),
"_FAILED_The Office (US) - S01E01 - Episode Provider");
var postDownloadStatus = PostDownloadStatusType.Failed;
var postDownloadProvider = new PostDownloadProvider();
postDownloadProvider.Add(new PostDownloadInfoModel
{
Name = path,
Status = postDownloadStatus,
Added = DateTime.Now.AddMinutes(-5)
});
//Act
mocker.Resolve<PostDownloadProvider>().ProcessFailedOrUnpackingDownload(new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), path)), postDownloadStatus);
//Assert
mocker.VerifyAllMocks();
}
[Test]
public void ProcessFailedOrUnpackingDownload_Invalid_Episode()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
var path = Path.Combine(Directory.GetCurrentDirectory(),
"_FAILED_The Office (US) - S01E01 - Episode Provider");
var postDownloadStatus = PostDownloadStatusType.Failed;
var fakeSeries = Builder<Series>.CreateNew()
.With(s => s.SeriesId = 12345)
.With(s => s.CleanTitle = "officeus")
.Build();
mocker.GetMock<SeriesProvider>().Setup(s => s.FindSeries("officeus")).Returns(fakeSeries);
mocker.GetMock<EpisodeProvider>().Setup(s => s.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>(), false)).Returns(new List<Episode>());
mocker.GetMock<DiskProvider>().Setup(s => s.MoveDirectory(It.IsAny<string>(), It.IsAny<string>()));
//Act
mocker.Resolve<PostDownloadProvider>().ProcessFailedOrUnpackingDownload(new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), path)), postDownloadStatus);
//Assert
ExceptionVerification.ExcpectedWarns(1);
mocker.VerifyAllMocks();
}
[TestCase(PostDownloadStatusType.Unpacking, 8)]

View File

@ -30,6 +30,11 @@
/// <summary>
/// ParseError
/// </summary>
ParseError = 5
ParseError = 5,
/// <summary>
/// InvalidEpisode
/// </summary>
InvalidEpisode = 6,
}
}

View File

@ -36,7 +36,7 @@ namespace NzbDrone.Core.Providers
_episodeProvider = episodeProvider;
}
PostDownloadProvider()
public PostDownloadProvider()
{
}
@ -157,27 +157,24 @@ namespace NzbDrone.Core.Providers
public virtual void ProcessFailedOrUnpackingDownload(DirectoryInfo directoryInfo, PostDownloadStatusType postDownloadStatus)
{
//Check to see if its already in InfoList, if it is, check if enough time has passed to process
if (InfoList.Any(i => i.Name == directoryInfo.FullName))
{
var model = InfoList.Single(i => i.Name == directoryInfo.FullName);
var model = CheckForExisting(directoryInfo.FullName);
if (model != null)
{
//Process if 30 minutes has passed
if (model.Added > DateTime.Now.AddMinutes(30))
{
ReProcessDownload(model);
//If everything processed successfully up until now, remove it from InfoList
InfoList.Remove(model);
//If everything processed successfully up until now, remove it from InfoList
Remove(model);
}
return;
}
//Add to InfoList for possible later processing
InfoList.Add(new PostDownloadInfoModel{ Name = directoryInfo.FullName,
Added = DateTime.Now,
Status = postDownloadStatus
});
//Remove the first 8 characters of the folder name (removes _UNPACK_ or _FAILED_) before processing
var parseResult = Parser.ParseTitle(directoryInfo.Name.Substring(8));
//Remove the error prefix before processing
var parseResult = Parser.ParseTitle(directoryInfo.Name.Substring(GetPrefixLength(postDownloadStatus)));
parseResult.Series = _seriesProvider.FindSeries(parseResult.CleanTitle);
var episodeIds = new List<int>();
@ -190,7 +187,27 @@ namespace NzbDrone.Core.Providers
else
episodeIds = _episodeProvider.GetEpisodesByParseResult(parseResult).Select(e => e.EpisodeId).ToList();
if (episodeIds.Count == 0)
{
//Mark as InvalidEpisode
Logger.Warn("Unable to Import new download [{0}], no episode(s) found in database.", directoryInfo.FullName);
_diskProvider.MoveDirectory(directoryInfo.FullName,
Path.Combine(directoryInfo.Parent.FullName,
"_NzbDrone_InvalidEpisode_" + directoryInfo.Name.Substring(GetPrefixLength(postDownloadStatus))));
return;
}
//Set the PostDownloadStatus for all found episodes
_episodeProvider.SetPostDownloadStatus(episodeIds, postDownloadStatus);
//Add to InfoList for possible later processing
Add(new PostDownloadInfoModel
{
Name = directoryInfo.FullName,
Added = DateTime.Now,
Status = postDownloadStatus
});
}
public virtual void ReProcessDownload(PostDownloadInfoModel model)
@ -226,5 +243,20 @@ namespace NzbDrone.Core.Providers
//Default to zero
return 0;
}
public void Add(PostDownloadInfoModel model)
{
InfoList.Add(model);
}
public void Remove(PostDownloadInfoModel model)
{
InfoList.Remove(model);
}
public PostDownloadInfoModel CheckForExisting(string path)
{
return InfoList.SingleOrDefault(i => i.Name == path);
}
}
}