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 // ReSharper disable RedundantUsingDirective
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.SqlServerCe;
using System.Linq; using System.Linq;
using AutoMoq; using AutoMoq;
using FizzWare.NBuilder; using FizzWare.NBuilder;
@ -1502,5 +1503,74 @@ namespace NzbDrone.Core.Test
var result = db.Fetch<Episode>(); var result = db.Fetch<Episode>();
result.Where(e => e.PostDownloadStatus == postDownloadStatus).Count().Should().Be(episodeCount); 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 // ReSharper disable InconsistentNaming
public class PostDownloadProviderTest : TestBase public class PostDownloadProviderTest : TestBase
{ {
[TestCase("The Office (US) - S01E05 - Episode Title", PostDownloadStatusType.Unpacking, 1)] [TestCase("_UNPACK_The Office (US) - S01E01 - Episode Title", PostDownloadStatusType.Unpacking, 1)]
[TestCase("The Office (US) - S01E05 - Episode Title", PostDownloadStatusType.Failed, 1)] [TestCase("_FAILED_The Office (US) - S01E01 - Episode Title", PostDownloadStatusType.Failed, 1)]
[TestCase("The Office (US) - S01E05E06 - Episode Title", PostDownloadStatusType.Unpacking, 2)] [TestCase("_UNPACK_The Office (US) - S01E01E02 - Episode Title", PostDownloadStatusType.Unpacking, 2)]
[TestCase("The Office (US) - S01E05E06 - Episode Title", PostDownloadStatusType.Failed, 2)] [TestCase("_FAILED_The Office (US) - S01E01E02 - Episode Title", PostDownloadStatusType.Failed, 2)]
[TestCase("The Office (US) - Season 01 - Episode Title", PostDownloadStatusType.Unpacking, 10)] [TestCase("_UNPACK_The Office (US) - Season 01 - Episode Title", PostDownloadStatusType.Unpacking, 10)]
[TestCase("The Office (US) - Season 01 - Episode Title", PostDownloadStatusType.Failed, 10)] [TestCase("_FAILED_The Office (US) - Season 01 - Episode Title", PostDownloadStatusType.Failed, 10)]
public void SetPostDownloadStatus(string folderName, PostDownloadStatusType postDownloadStatus, int episodeCount) public void ProcessFailedOrUnpackingDownload(string folderName, PostDownloadStatusType postDownloadStatus, int episodeCount)
{ {
var db = MockLib.GetEmptyDatabase(); var db = MockLib.GetEmptyDatabase();
var mocker = new AutoMoqer(); var mocker = new AutoMoqer();
@ -40,24 +40,78 @@ namespace NzbDrone.Core.Test
.With(s => s.CleanTitle = "officeus") .With(s => s.CleanTitle = "officeus")
.Build(); .Build();
var fakeEpisodes = Builder<Episode>.CreateListOfSize(10) var fakeEpisodes = Builder<Episode>.CreateListOfSize(episodeCount)
.WhereAll() .WhereAll()
.Have(c => c.SeriesId = 12345) .Have(c => c.SeriesId = 12345)
.Have(c => c.SeasonNumber = 1) .Have(c => c.SeasonNumber = 1)
.Have(c => c.PostDownloadStatus = PostDownloadStatusType.Unknown) .Have(c => c.PostDownloadStatus = PostDownloadStatusType.Unknown)
.Build(); .Build();
db.Insert(fakeSeries); var expectedEpisodesNumbers = fakeEpisodes.Select(e => e.EpisodeId);
db.InsertMany(fakeEpisodes);
mocker.GetMock<SeriesProvider>().Setup(s => s.FindSeries("officeus")).Returns(fakeSeries); 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 //Act
//mocker.Resolve<EpisodeProvider>().SetPostDownloadStatus(folderName, postDownloadStatus); mocker.Resolve<PostDownloadProvider>().ProcessFailedOrUnpackingDownload(new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), folderName)),postDownloadStatus);
//Assert //Assert
var result = db.Fetch<Episode>(); mocker.GetMock<EpisodeProvider>().Verify(c => c.SetPostDownloadStatus(expectedEpisodesNumbers, postDownloadStatus), Times.Once());
result.Where(e => e.PostDownloadStatus == postDownloadStatus).Count().Should().Be(episodeCount); }
[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)] [TestCase(PostDownloadStatusType.Unpacking, 8)]

View File

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

View File

@ -36,7 +36,7 @@ namespace NzbDrone.Core.Providers
_episodeProvider = episodeProvider; _episodeProvider = episodeProvider;
} }
PostDownloadProvider() public PostDownloadProvider()
{ {
} }
@ -157,27 +157,24 @@ namespace NzbDrone.Core.Providers
public virtual void ProcessFailedOrUnpackingDownload(DirectoryInfo directoryInfo, PostDownloadStatusType postDownloadStatus) 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 //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 = CheckForExisting(directoryInfo.FullName);
{
var model = InfoList.Single(i => i.Name == directoryInfo.FullName);
if (model != null)
{
//Process if 30 minutes has passed //Process if 30 minutes has passed
if (model.Added > DateTime.Now.AddMinutes(30)) if (model.Added > DateTime.Now.AddMinutes(30))
{
ReProcessDownload(model); ReProcessDownload(model);
//If everything processed successfully up until now, remove it from InfoList //If everything processed successfully up until now, remove it from InfoList
InfoList.Remove(model); Remove(model);
}
return; return;
} }
//Add to InfoList for possible later processing //Remove the error prefix before processing
InfoList.Add(new PostDownloadInfoModel{ Name = directoryInfo.FullName, var parseResult = Parser.ParseTitle(directoryInfo.Name.Substring(GetPrefixLength(postDownloadStatus)));
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));
parseResult.Series = _seriesProvider.FindSeries(parseResult.CleanTitle); parseResult.Series = _seriesProvider.FindSeries(parseResult.CleanTitle);
var episodeIds = new List<int>(); var episodeIds = new List<int>();
@ -190,7 +187,27 @@ namespace NzbDrone.Core.Providers
else else
episodeIds = _episodeProvider.GetEpisodesByParseResult(parseResult).Select(e => e.EpisodeId).ToList(); 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); _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) public virtual void ReProcessDownload(PostDownloadInfoModel model)
@ -226,5 +243,20 @@ namespace NzbDrone.Core.Providers
//Default to zero //Default to zero
return 0; 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);
}
} }
} }