diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index 01deffe50..7894d92ff 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -102,6 +102,7 @@ + @@ -123,7 +124,7 @@ - + @@ -137,16 +138,16 @@ - + - + - + diff --git a/NzbDrone.Core.Test/ProviderTests/InventoryProvider_IsAcceptableSizeTest.cs b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsAcceptableSizeTestFixture.cs similarity index 99% rename from NzbDrone.Core.Test/ProviderTests/InventoryProvider_IsAcceptableSizeTest.cs rename to NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsAcceptableSizeTestFixture.cs index 04322d2ea..0930e1d47 100644 --- a/NzbDrone.Core.Test/ProviderTests/InventoryProvider_IsAcceptableSizeTest.cs +++ b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsAcceptableSizeTestFixture.cs @@ -14,11 +14,11 @@ using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; -namespace NzbDrone.Core.Test.ProviderTests +namespace NzbDrone.Core.Test.ProviderTests.InventoryProviderTests { [TestFixture] // ReSharper disable InconsistentNaming - public class InventoryProvider_IsAcceptableSizeTest : CoreTest + public class IsAcceptableSizeTestFixture : CoreTest { private EpisodeParseResult parseResultMulti; private EpisodeParseResult parseResultSingle; diff --git a/NzbDrone.Core.Test/ProviderTests/InventoryProvider_IsMonitoredTest.cs b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsMonitoredFixture.cs similarity index 98% rename from NzbDrone.Core.Test/ProviderTests/InventoryProvider_IsMonitoredTest.cs rename to NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsMonitoredFixture.cs index 91a39a988..7b9b3ab4b 100644 --- a/NzbDrone.Core.Test/ProviderTests/InventoryProvider_IsMonitoredTest.cs +++ b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsMonitoredFixture.cs @@ -14,11 +14,11 @@ using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; -namespace NzbDrone.Core.Test.ProviderTests +namespace NzbDrone.Core.Test.ProviderTests.InventoryProviderTests { [TestFixture] // ReSharper disable InconsistentNaming - public class InventoryProvider_IsMonitoredTest : CoreTest + public class IsMonitoredFixture : CoreTest { private EpisodeParseResult parseResultMulti; private Series series; diff --git a/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsUpgradePossibleFixture.cs b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsUpgradePossibleFixture.cs new file mode 100644 index 000000000..61421fb0e --- /dev/null +++ b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsUpgradePossibleFixture.cs @@ -0,0 +1,106 @@ +// ReSharper disable RedundantUsingDirective + +using System; +using System.Collections.Generic; + +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; +using NzbDrone.Test.Common.AutoMoq; + +namespace NzbDrone.Core.Test.ProviderTests.InventoryProviderTests +{ + [TestFixture] + // ReSharper disable InconsistentNaming + public class IsUpgradePossibleFixture : CoreTest + { + private void WithWebdlCutoff() + { + var profile = new QualityProfile { Cutoff = QualityTypes.WEBDL }; + Mocker.GetMock().Setup(s => s.Get(It.IsAny())).Returns(profile); + } + + private Series _series; + private EpisodeFile _episodeFile; + private Episode _episode; + + [SetUp] + public void SetUp() + { + _series = Builder.CreateNew() + .Build(); + + _episodeFile = Builder.CreateNew() + .With(f => f.Quality = QualityTypes.SDTV) + .Build(); + + _episode = Builder.CreateNew() + .With(e => e.EpisodeFileId = 0) + .With(e => e.SeriesId = _series.SeriesId) + .With(e => e.Series = _series) + .With(e => e.EpisodeFileId = _episodeFile.EpisodeFileId) + .With(e => e.EpisodeFile = _episodeFile) + .Build(); + } + + [Test] + public void IsUpgradePossible_should_return_true_if_no_episode_file_exists() + { + var episode = Builder.CreateNew() + .With(e => e.EpisodeFileId = 0) + .Build(); + + //Act + bool result = Mocker.Resolve().IsUpgradePossible(episode); + + //Assert + result.Should().BeTrue(); + } + + [Test] + public void IsUpgradePossible_should_return_true_if_current_episode_is_less_than_cutoff() + { + WithWebdlCutoff(); + + //Act + bool result = Mocker.Resolve().IsUpgradePossible(_episode); + + //Assert + result.Should().BeTrue(); + } + + [Test] + public void IsUpgradePossible_should_return_false_if_current_episode_is_equal_to_cutoff() + { + WithWebdlCutoff(); + + _episodeFile.Quality = QualityTypes.WEBDL; + + //Act + bool result = Mocker.Resolve().IsUpgradePossible(_episode); + + //Assert + result.Should().BeFalse(); + } + + [Test] + public void IsUpgradePossible_should_return_false_if_current_episode_is_greater_than_cutoff() + { + WithWebdlCutoff(); + + _episodeFile.Quality = QualityTypes.Bluray720p; + + //Act + bool result = Mocker.Resolve().IsUpgradePossible(_episode); + + //Assert + result.Should().BeFalse(); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core.Test/ProviderTests/InventoryProvider_QualityNeededTest.cs b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/QualityNeededFixture.cs similarity index 99% rename from NzbDrone.Core.Test/ProviderTests/InventoryProvider_QualityNeededTest.cs rename to NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/QualityNeededFixture.cs index 997a29876..cad8d46d3 100644 --- a/NzbDrone.Core.Test/ProviderTests/InventoryProvider_QualityNeededTest.cs +++ b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/QualityNeededFixture.cs @@ -14,11 +14,11 @@ using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; -namespace NzbDrone.Core.Test.ProviderTests +namespace NzbDrone.Core.Test.ProviderTests.InventoryProviderTests { [TestFixture] // ReSharper disable InconsistentNaming - public class InventoryProvider_QualityNeededTest : CoreTest + public class QualityNeededFixture : CoreTest { private Episode episode; private Episode episode2; diff --git a/NzbDrone.Core.Test/ProviderTests/MediaFileProvider_GetNewFilenameTest.cs b/NzbDrone.Core.Test/ProviderTests/MediaFileProviderTests/GetNewFilenameFixture.cs similarity index 99% rename from NzbDrone.Core.Test/ProviderTests/MediaFileProvider_GetNewFilenameTest.cs rename to NzbDrone.Core.Test/ProviderTests/MediaFileProviderTests/GetNewFilenameFixture.cs index 6e951b658..84f8536fa 100644 --- a/NzbDrone.Core.Test/ProviderTests/MediaFileProvider_GetNewFilenameTest.cs +++ b/NzbDrone.Core.Test/ProviderTests/MediaFileProviderTests/GetNewFilenameFixture.cs @@ -11,7 +11,7 @@ using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; -namespace NzbDrone.Core.Test.ProviderTests +namespace NzbDrone.Core.Test.ProviderTests.MediaFileProviderTests { [TestFixture] // ReSharper disable InconsistentNaming diff --git a/NzbDrone.Core.Test/ProviderTests/SearchProviderTests/SearchFixture.cs b/NzbDrone.Core.Test/ProviderTests/SearchProviderTests/SearchFixture.cs index c4e207cc8..a1278cce0 100644 --- a/NzbDrone.Core.Test/ProviderTests/SearchProviderTests/SearchFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/SearchProviderTests/SearchFixture.cs @@ -192,6 +192,9 @@ namespace NzbDrone.Core.Test.ProviderTests.SearchProviderTests episode.AirDate = null; episode.Series = _series; + Mocker.GetMock().Setup(s => s.IsUpgradePossible(It.IsAny())) + .Returns(true); + Mocker.GetMock().Setup(s => s.GetEpisode(episode.EpisodeId)) .Returns(episode); diff --git a/NzbDrone.Core/Providers/InventoryProvider.cs b/NzbDrone.Core/Providers/InventoryProvider.cs index 449c138b5..22fa6b4a1 100644 --- a/NzbDrone.Core/Providers/InventoryProvider.cs +++ b/NzbDrone.Core/Providers/InventoryProvider.cs @@ -15,17 +15,20 @@ namespace NzbDrone.Core.Providers private readonly EpisodeProvider _episodeProvider; private readonly HistoryProvider _historyProvider; private readonly QualityTypeProvider _qualityTypeProvider; + private readonly QualityProvider _qualityProvider; private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); [Inject] public InventoryProvider(SeriesProvider seriesProvider, EpisodeProvider episodeProvider, - HistoryProvider historyProvider, QualityTypeProvider qualityTypeProvider) + HistoryProvider historyProvider, QualityTypeProvider qualityTypeProvider, + QualityProvider qualityProvider) { _seriesProvider = seriesProvider; _episodeProvider = episodeProvider; _historyProvider = historyProvider; _qualityTypeProvider = qualityTypeProvider; + _qualityProvider = qualityProvider; } public InventoryProvider() @@ -179,5 +182,23 @@ namespace NzbDrone.Core.Providers return true; } + + public virtual bool IsUpgradePossible(Episode episode) + { + //Used to check if the existing episode can be upgraded by searching (Before we search) + + //If no episode file exists on disk, then an upgrade is possible + if (episode.EpisodeFileId == 0) + return true; + + //Get the quality profile for the series + var profile = _qualityProvider.Get(episode.Series.QualityProfileId); + + //If the current episode file meets or exceeds the cutoff, do not attempt upgrade + if (episode.EpisodeFile.Quality >= profile.Cutoff) + return false; + + return true; + } } } \ No newline at end of file diff --git a/NzbDrone.Core/Providers/SearchProvider.cs b/NzbDrone.Core/Providers/SearchProvider.cs index 3c0a183eb..57c8aee07 100644 --- a/NzbDrone.Core/Providers/SearchProvider.cs +++ b/NzbDrone.Core/Providers/SearchProvider.cs @@ -129,6 +129,14 @@ namespace NzbDrone.Core.Providers return false; } + //Check to see if an upgrade is possible before attempting + if (!_inventoryProvider.IsUpgradePossible(episode)) + { + Logger.Info("Search for {0} was aborted, file in disk meets or exceeds Profile's Cutoff", episode); + notification.CurrentMessage = String.Format("Aborting search for {0}, Upgrade is not possible", episode); + return false; + } + notification.CurrentMessage = "Searching for " + episode; if (episode.Series.IsDaily && !episode.AirDate.HasValue)