Report size is now verified to ensure it is under the MaxSize for that quality type, with tests.

pull/4/head
Mark McDowall 13 years ago
parent e4f01ae0d4
commit 4b2427ade7

@ -1355,5 +1355,71 @@ namespace NzbDrone.Core.Test
episodes.First().ShouldHave().AllPropertiesBut(e => e.Series).EqualTo(fakeEpisode);
mocker.VerifyAllMocks();
}
[Test]
public void IsFirstOrLastEpisodeInSeason_false()
{
var db = MockLib.GetEmptyDatabase();
var mocker = new AutoMoqer();
mocker.SetConstant(db);
var fakeEpisodes = Builder<Episode>.CreateListOfSize(10)
.WhereAll()
.Have(c => c.SeriesId = 10)
.Have(c => c.SeasonNumber = 1)
.Build();
db.InsertMany(fakeEpisodes);
//Act
var result = mocker.Resolve<EpisodeProvider>().IsFirstOrLastEpisodeOfSeason(10, 1, 5);
//Assert
result.Should().BeFalse();
}
[Test]
public void IsFirstOrLastEpisodeInSeason_true_first()
{
var db = MockLib.GetEmptyDatabase();
var mocker = new AutoMoqer();
mocker.SetConstant(db);
var fakeEpisodes = Builder<Episode>.CreateListOfSize(10)
.WhereAll()
.Have(c => c.SeriesId = 10)
.Have(c => c.SeasonNumber = 1)
.Build();
db.InsertMany(fakeEpisodes);
//Act
var result = mocker.Resolve<EpisodeProvider>().IsFirstOrLastEpisodeOfSeason(10, 1, 1);
//Assert
result.Should().BeFalse();
}
[Test]
public void IsFirstOrLastEpisodeInSeason_true_last()
{
var db = MockLib.GetEmptyDatabase();
var mocker = new AutoMoqer();
mocker.SetConstant(db);
var fakeEpisodes = Builder<Episode>.CreateListOfSize(10)
.WhereAll()
.Have(c => c.SeriesId = 10)
.Have(c => c.SeasonNumber = 1)
.Build();
db.InsertMany(fakeEpisodes);
//Act
var result = mocker.Resolve<EpisodeProvider>().IsFirstOrLastEpisodeOfSeason(10, 1, 10);
//Assert
result.Should().BeFalse();
}
}
}

@ -0,0 +1,323 @@
// ReSharper disable RedundantUsingDirective
using System;
using System.Collections.Generic;
using AutoMoq;
using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test
{
[TestFixture]
// ReSharper disable InconsistentNaming
public class InventoryProvider_IsAcceptableSizeTest : TestBase
{
private EpisodeParseResult parseResultMulti;
private EpisodeParseResult parseResultSingle;
private Series series30minutes;
private Series series60minutes;
private QualityType qualityType;
[SetUp]
public new void Setup()
{
parseResultMulti = new EpisodeParseResult
{
CleanTitle = "Title",
Language = LanguageType.English,
Quality = new Quality(QualityTypes.SDTV, true),
EpisodeNumbers = new List<int> { 3, 4 },
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date
};
parseResultSingle = new EpisodeParseResult
{
CleanTitle = "Title",
Language = LanguageType.English,
Quality = new Quality(QualityTypes.SDTV, true),
EpisodeNumbers = new List<int> { 3 },
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date
};
series30minutes = Builder<Series>.CreateNew()
.With(c => c.Monitored = true)
.With(d => d.CleanTitle = parseResultMulti.CleanTitle)
.With(c => c.Runtime = 30)
.Build();
series60minutes = Builder<Series>.CreateNew()
.With(c => c.Monitored = true)
.With(d => d.CleanTitle = parseResultMulti.CleanTitle)
.With(c => c.Runtime = 60)
.Build();
qualityType = Builder<QualityType>.CreateNew()
.With(q => q.MinSize = 0)
.With(q => q.MaxSize = 314572800)
.With(q => q.QualityTypeId = 1)
.Build();
base.Setup();
}
[Test]
public void IsAcceptableSize_true_single_episode_not_first_or_last_30_minute()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series = series30minutes;
parseResultSingle.Size = 184572800;
mocker.GetMock<QualityTypeProvider>().Setup(s => s.Get(1)).Returns(qualityType);
mocker.GetMock<EpisodeProvider>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(false);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsAcceptableSize(parseResultSingle);
//Assert
result.Should().BeTrue();
}
[Test]
public void IsAcceptableSize_true_single_episode_not_first_or_last_60_minute()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series = series60minutes;
parseResultSingle.Size = 368572800;
mocker.GetMock<QualityTypeProvider>().Setup(s => s.Get(1)).Returns(qualityType);
mocker.GetMock<EpisodeProvider>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(false);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsAcceptableSize(parseResultSingle);
//Assert
result.Should().BeTrue();
}
[Test]
public void IsAcceptableSize_false_single_episode_not_first_or_last_30_minute()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series = series30minutes;
parseResultSingle.Size = 1184572800;
mocker.GetMock<QualityTypeProvider>().Setup(s => s.Get(1)).Returns(qualityType);
mocker.GetMock<EpisodeProvider>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(false);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsAcceptableSize(parseResultSingle);
//Assert
result.Should().BeFalse();
}
[Test]
public void IsAcceptableSize_false_single_episode_not_first_or_last_60_minute()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series = series60minutes;
parseResultSingle.Size = 1368572800;
mocker.GetMock<QualityTypeProvider>().Setup(s => s.Get(1)).Returns(qualityType);
mocker.GetMock<EpisodeProvider>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(false);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsAcceptableSize(parseResultSingle);
//Assert
result.Should().BeFalse();
}
[Test]
public void IsAcceptableSize_true_multi_episode_not_first_or_last_30_minute()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultMulti.Series = series30minutes;
parseResultMulti.Size = 184572800;
mocker.GetMock<QualityTypeProvider>().Setup(s => s.Get(1)).Returns(qualityType);
mocker.GetMock<EpisodeProvider>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(false);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsAcceptableSize(parseResultMulti);
//Assert
result.Should().BeTrue();
}
[Test]
public void IsAcceptableSize_true_multi_episode_not_first_or_last_60_minute()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultMulti.Series = series60minutes;
parseResultMulti.Size = 368572800;
mocker.GetMock<QualityTypeProvider>().Setup(s => s.Get(1)).Returns(qualityType);
mocker.GetMock<EpisodeProvider>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(false);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsAcceptableSize(parseResultMulti);
//Assert
result.Should().BeTrue();
}
[Test]
public void IsAcceptableSize_false_multi_episode_not_first_or_last_30_minute()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultMulti.Series = series30minutes;
parseResultMulti.Size = 1184572800;
mocker.GetMock<QualityTypeProvider>().Setup(s => s.Get(1)).Returns(qualityType);
mocker.GetMock<EpisodeProvider>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(false);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsAcceptableSize(parseResultMulti);
//Assert
result.Should().BeFalse();
}
[Test]
public void IsAcceptableSize_false_multi_episode_not_first_or_last_60_minute()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultMulti.Series = series60minutes;
parseResultMulti.Size = 1368572800;
mocker.GetMock<QualityTypeProvider>().Setup(s => s.Get(1)).Returns(qualityType);
mocker.GetMock<EpisodeProvider>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(false);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsAcceptableSize(parseResultMulti);
//Assert
result.Should().BeFalse();
}
[Test]
public void IsAcceptableSize_true_single_episode_first_30_minute()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series = series30minutes;
parseResultSingle.Size = 184572800;
mocker.GetMock<QualityTypeProvider>().Setup(s => s.Get(1)).Returns(qualityType);
mocker.GetMock<EpisodeProvider>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(true);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsAcceptableSize(parseResultSingle);
//Assert
result.Should().BeTrue();
}
[Test]
public void IsAcceptableSize_true_single_episode_first_60_minute()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series = series60minutes;
parseResultSingle.Size = 368572800;
mocker.GetMock<QualityTypeProvider>().Setup(s => s.Get(1)).Returns(qualityType);
mocker.GetMock<EpisodeProvider>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(true);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsAcceptableSize(parseResultSingle);
//Assert
result.Should().BeTrue();
}
[Test]
public void IsAcceptableSize_false_single_episode_first_30_minute()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series = series30minutes;
parseResultSingle.Size = 1184572800;
mocker.GetMock<QualityTypeProvider>().Setup(s => s.Get(1)).Returns(qualityType);
mocker.GetMock<EpisodeProvider>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(true);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsAcceptableSize(parseResultSingle);
//Assert
result.Should().BeFalse();
}
[Test]
public void IsAcceptableSize_false_single_episode_first_60_minute()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series = series60minutes;
parseResultSingle.Size = 1368572800;
mocker.GetMock<QualityTypeProvider>().Setup(s => s.Get(1)).Returns(qualityType);
mocker.GetMock<EpisodeProvider>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(true);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsAcceptableSize(parseResultSingle);
//Assert
result.Should().BeFalse();
}
}
}

@ -135,6 +135,10 @@ namespace NzbDrone.Core.Test
.Setup(p => p.GetEpisodesByParseResult(parseResultMulti, true))
.Returns(new List<Episode> { episode, episode2 });
mocker.GetMock<QualityTypeProvider>()
.Setup(s => s.Get(It.IsAny<int>()))
.Returns(new QualityType { MaxSize = 10.Gigabytes(), MinSize = 0 });
episode.EpisodeFile.Quality = QualityTypes.Bluray720p;
//Act
@ -145,7 +149,6 @@ namespace NzbDrone.Core.Test
mocker.VerifyAllMocks();
}
[Test]
public void IsQualityNeeded_file_in_history_should_be_skipped()
{
@ -162,6 +165,14 @@ namespace NzbDrone.Core.Test
.Setup(p => p.GetEpisodesByParseResult(parseResultSingle, true))
.Returns(new List<Episode> { episode });
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(false);
mocker.GetMock<QualityTypeProvider>()
.Setup(s => s.Get(It.IsAny<int>()))
.Returns(new QualityType { MaxSize = 10.Gigabytes(), MinSize = 0 });
episode.EpisodeFile.Quality = QualityTypes.SDTV;
//Act
@ -188,6 +199,14 @@ namespace NzbDrone.Core.Test
.Setup(p => p.GetEpisodesByParseResult(parseResultSingle, true))
.Returns(new List<Episode> { episode });
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(false);
mocker.GetMock<QualityTypeProvider>()
.Setup(s => s.Get(It.IsAny<int>()))
.Returns(new QualityType { MaxSize = 10.Gigabytes(), MinSize = 0 });
episode.EpisodeFile.Quality = QualityTypes.SDTV;
//Act
@ -210,11 +229,18 @@ namespace NzbDrone.Core.Test
.Setup(p => p.GetBestQualityInHistory(episode.EpisodeId))
.Returns<Quality>(null);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisodesByParseResult(parseResultSingle, true))
.Returns(new List<Episode> { episode });
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(false);
mocker.GetMock<QualityTypeProvider>()
.Setup(s => s.Get(It.IsAny<int>()))
.Returns(new QualityType { MaxSize = 10.Gigabytes(), MinSize = 0 });
episode.EpisodeFile.Quality = QualityTypes.SDTV;
//Act
bool result = mocker.Resolve<InventoryProvider>().IsQualityNeeded(parseResultSingle);

@ -90,6 +90,7 @@
<ItemGroup>
<Compile Include="BacklogSearchJobTest.cs" />
<Compile Include="BannerDownloadJobTest.cs" />
<Compile Include="InventoryProvider_IsAcceptableSizeTest.cs" />
<Compile Include="QualityTypeProviderTest.cs" />
<Compile Include="MisnamedProviderTest.cs" />
<Compile Include="SeasonSearchJobTest.cs" />

@ -330,6 +330,21 @@ namespace NzbDrone.Core.Providers
Logger.Info("Ignore flag for Episode:{0} successfully set to {1}", episodeId, isIgnored);
}
public virtual bool IsFirstOrLastEpisodeOfSeason(int seriesId, int seasonNumber, int episodeNumber)
{
var episodes = GetEpisodesBySeason(seriesId, seasonNumber).OrderBy(e => e.EpisodeNumber);
if (episodes.Count() == 0)
return false;
//Ensure that this is either the first episode
//or is the last episode in a season that has 10 or more episodes
if (episodes.First().EpisodeNumber == episodeNumber || (episodes.Count() >= 10 && episodes.Last().EpisodeNumber == episodeNumber))
return true;
return false;
}
public IList<Episode> AttachSeries(IList<Episode> episodes)
{
if (episodes.Count == 0) return episodes;

@ -14,15 +14,18 @@ namespace NzbDrone.Core.Providers
private readonly SeriesProvider _seriesProvider;
private readonly EpisodeProvider _episodeProvider;
private readonly HistoryProvider _historyProvider;
private readonly QualityTypeProvider _qualityTypeProvider;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[Inject]
public InventoryProvider(SeriesProvider seriesProvider, EpisodeProvider episodeProvider, HistoryProvider historyProvider)
public InventoryProvider(SeriesProvider seriesProvider, EpisodeProvider episodeProvider,
HistoryProvider historyProvider, QualityTypeProvider qualityTypeProvider)
{
_seriesProvider = seriesProvider;
_episodeProvider = episodeProvider;
_historyProvider = historyProvider;
_qualityTypeProvider = qualityTypeProvider;
}
public InventoryProvider()
@ -79,6 +82,9 @@ namespace NzbDrone.Core.Providers
var cutoff = parsedReport.Series.QualityProfile.Cutoff;
if (!IsAcceptableSize(parsedReport))
return false;
foreach (var episode in _episodeProvider.GetEpisodesByParseResult(parsedReport, true))
{
//Checking File
@ -132,5 +138,39 @@ namespace NzbDrone.Core.Providers
Logger.Debug("New item has better quality than existing item");
return true;
}
public virtual bool IsAcceptableSize(EpisodeParseResult parseResult)
{
var qualityType = _qualityTypeProvider.Get((int) parseResult.Quality.QualityType);
//Need to determine if this is a 30 or 60 minute episode
//Is it a multi-episode release?
//Is it the first or last series of a season?
var maxSize = qualityType.MaxSize;
var series = parseResult.Series;
//If this is an hour long episode (between 50 and 65 minutes) then multiply by 2
if (series.Runtime >= 50 && series.Runtime <= 65)
maxSize = maxSize * 2;
//Multiply maxSize by the number of episodes parsed
maxSize = maxSize * parseResult.EpisodeNumbers.Count;
//Check if there was only one episode parsed
//and it is the first or last episode of the season
if (parseResult.EpisodeNumbers.Count == 1 &&
_episodeProvider.IsFirstOrLastEpisodeOfSeason(series.SeriesId,
parseResult.SeasonNumber, parseResult.EpisodeNumbers[0]))
{
maxSize = maxSize * 2;
}
//If the parsed size is greater than maxSize we don't want it
if (parseResult.Size > maxSize)
return false;
return true;
}
}
}

@ -19,6 +19,11 @@ namespace NzbDrone.Core.Providers
_database = database;
}
public QualityTypeProvider()
{
}
public virtual void Update(QualityType qualityType)
{
_database.Update(qualityType);

Loading…
Cancel
Save