diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/CutoffSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/CutoffSpecificationFixture.cs index 30a0b9789..c2ad7adab 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/CutoffSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/CutoffSpecificationFixture.cs @@ -22,12 +22,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests new QualityProfile { Cutoff = Quality.Bluray1080p.Id, - Items = Qualities.QualityFixture.GetDefaultQualities() + Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }, new LanguageProfile { Languages = LanguageFixture.GetDefaultLanguages(Language.English), - Cutoff = Language.English + Cutoff = Language.English, + UpgradeAllowed = true }, new QualityModel(Quality.DVD, new Revision(version: 2)), Language.English, @@ -41,12 +43,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests new QualityProfile { Cutoff = Quality.HDTV720p.Id, - Items = Qualities.QualityFixture.GetDefaultQualities() + Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }, new LanguageProfile { Languages = LanguageFixture.GetDefaultLanguages(Language.English), - Cutoff = Language.English + Cutoff = Language.English, + UpgradeAllowed = true }, new QualityModel(Quality.HDTV720p, new Revision(version: 2)), Language.English, @@ -60,12 +64,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests new QualityProfile { Cutoff = Quality.HDTV720p.Id, - Items = Qualities.QualityFixture.GetDefaultQualities() + Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }, new LanguageProfile { Languages = LanguageFixture.GetDefaultLanguages(Language.English), - Cutoff = Language.English + Cutoff = Language.English, + UpgradeAllowed = true }, new QualityModel(Quality.Bluray1080p, new Revision(version: 2)), Language.English, @@ -79,12 +85,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests new QualityProfile { Cutoff = Quality.HDTV720p.Id, - Items = Qualities.QualityFixture.GetDefaultQualities() + Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }, new LanguageProfile { Languages = LanguageFixture.GetDefaultLanguages(Language.English), - Cutoff = Language.English + Cutoff = Language.English, + UpgradeAllowed = true }, new QualityModel(Quality.HDTV720p, new Revision(version: 1)), Language.English, @@ -100,12 +108,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests new QualityProfile { Cutoff = Quality.HDTV720p.Id, - Items = Qualities.QualityFixture.GetDefaultQualities() + Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }, new LanguageProfile { Languages = LanguageFixture.GetDefaultLanguages(Language.English), - Cutoff = Language.English + Cutoff = Language.English, + UpgradeAllowed = true }, new QualityModel(Quality.HDTV720p, new Revision(version: 2)), Language.English, @@ -121,13 +131,15 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { Cutoff = Quality.HDTV720p.Id, Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }; LanguageProfile _langProfile = new LanguageProfile { Cutoff = Language.Spanish, - Languages = LanguageFixture.GetDefaultLanguages() - }; + Languages = LanguageFixture.GetDefaultLanguages(), + UpgradeAllowed = true + }; Subject.CutoffNotMet(_profile, _langProfile, @@ -145,12 +157,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { Cutoff = Quality.HDTV720p.Id, Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }; LanguageProfile _langProfile = new LanguageProfile { Cutoff = Language.Spanish, - Languages = LanguageFixture.GetDefaultLanguages() + Languages = LanguageFixture.GetDefaultLanguages(), + UpgradeAllowed = true }; Subject.CutoffNotMet( @@ -170,12 +184,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { Cutoff = Quality.HDTV720p.Id, Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }; LanguageProfile _langProfile = new LanguageProfile { Cutoff = Language.Spanish, - Languages = LanguageFixture.GetDefaultLanguages() + Languages = LanguageFixture.GetDefaultLanguages(), + UpgradeAllowed = true }; Subject.CutoffNotMet( @@ -195,12 +211,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { Cutoff = Quality.HDTV720p.Id, Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }; LanguageProfile _langProfile = new LanguageProfile { Cutoff = Language.Spanish, - Languages = LanguageFixture.GetDefaultLanguages() + Languages = LanguageFixture.GetDefaultLanguages(), + UpgradeAllowed = true }; Subject.CutoffNotMet( @@ -220,12 +238,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { Cutoff = Quality.HDTV720p.Id, Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }; LanguageProfile _langProfile = new LanguageProfile { Cutoff = Language.Spanish, - Languages = LanguageFixture.GetDefaultLanguages() + Languages = LanguageFixture.GetDefaultLanguages(), + UpgradeAllowed = true }; Subject.CutoffNotMet( @@ -243,13 +263,15 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { Cutoff = Quality.HDTV720p.Id, Items = Qualities.QualityFixture.GetDefaultQualities(), - }; + UpgradeAllowed = true + }; LanguageProfile _langProfile = new LanguageProfile { Cutoff = Language.Spanish, - Languages = LanguageFixture.GetDefaultLanguages() - }; + Languages = LanguageFixture.GetDefaultLanguages(), + UpgradeAllowed = true + }; Subject.CutoffNotMet( _profile, @@ -268,13 +290,15 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { Cutoff = Quality.HDTV1080p.Id, Items = Qualities.QualityFixture.GetDefaultQualities(), - }; + UpgradeAllowed = true + }; LanguageProfile _langProfile = new LanguageProfile { Cutoff = Language.English, - Languages = LanguageFixture.GetDefaultLanguages() - }; + Languages = LanguageFixture.GetDefaultLanguages(), + UpgradeAllowed = true + }; Subject.CutoffNotMet( _profile, @@ -285,5 +309,59 @@ namespace NzbDrone.Core.Test.DecisionEngineTests new QualityModel(Quality.WEBDL1080p, new Revision(version: 2)), NoPreferredWordScore).Should().BeTrue(); } + + [Test] + public void should_return_false_if_language_profile_does_not_allow_upgrades_but_cutoff_is_set_to_highest_language_and_quality_cutoff_is_met() + { + QualityProfile _profile = new QualityProfile + { + Cutoff = Quality.WEBDL1080p.Id, + Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true + }; + + LanguageProfile _langProfile = new LanguageProfile + { + Cutoff = Language.Arabic, + Languages = LanguageFixture.GetDefaultLanguages(Language.Spanish, Language.English, Language.Arabic), + UpgradeAllowed = false + }; + + Subject.CutoffNotMet( + _profile, + _langProfile, + new QualityModel(Quality.WEBDL1080p), + Language.English, + NoPreferredWordScore, + new QualityModel(Quality.Bluray1080p), + NoPreferredWordScore).Should().BeFalse(); + } + + [Test] + public void should_return_false_if_quality_profile_does_not_allow_upgrades_but_cutoff_is_set_to_highest_quality_and_language_cutoff_is_met() + { + QualityProfile _profile = new QualityProfile + { + Cutoff = Quality.WEBDL1080p.Id, + Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = false + }; + + LanguageProfile _langProfile = new LanguageProfile + { + Cutoff = Language.English, + Languages = LanguageFixture.GetDefaultLanguages(Language.Spanish, Language.English, Language.Arabic), + UpgradeAllowed = true + }; + + Subject.CutoffNotMet( + _profile, + _langProfile, + new QualityModel(Quality.WEBDL1080p), + Language.English, + NoPreferredWordScore, + new QualityModel(Quality.Bluray1080p), + NoPreferredWordScore).Should().BeFalse(); + } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs index f34c5962b..71f9bb384 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs @@ -98,7 +98,8 @@ namespace NzbDrone.Core.DecisionEngine.Specifications public bool QualityCutoffNotMet(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null) { - var cutoffCompare = new QualityModelComparer(profile).Compare(currentQuality.Quality.Id, profile.Cutoff); + var cutoff = profile.UpgradeAllowed ? profile.Cutoff : profile.FirststAllowedQuality().Id; + var cutoffCompare = new QualityModelComparer(profile).Compare(currentQuality.Quality.Id, cutoff); if (cutoffCompare < 0) { @@ -115,7 +116,11 @@ namespace NzbDrone.Core.DecisionEngine.Specifications public bool LanguageCutoffNotMet(LanguageProfile languageProfile, Language currentLanguage) { - var languageCompare = new LanguageComparer(languageProfile).Compare(currentLanguage, languageProfile.Cutoff); + var cutoff = languageProfile.UpgradeAllowed + ? languageProfile.Cutoff + : languageProfile.FirstAllowedLanguage(); + + var languageCompare = new LanguageComparer(languageProfile).Compare(currentLanguage, cutoff); return languageCompare < 0; } diff --git a/src/NzbDrone.Core/Profiles/Languages/LanguageProfile.cs b/src/NzbDrone.Core/Profiles/Languages/LanguageProfile.cs index b81ff7e1a..feece2da2 100644 --- a/src/NzbDrone.Core/Profiles/Languages/LanguageProfile.cs +++ b/src/NzbDrone.Core/Profiles/Languages/LanguageProfile.cs @@ -12,6 +12,11 @@ namespace NzbDrone.Core.Profiles.Languages public bool UpgradeAllowed { get; set; } public Language Cutoff { get; set; } + public Language FirstAllowedLanguage() + { + return Languages.First(q => q.Allowed).Language; + } + public Language LastAllowedLanguage() { return Languages.Last(q => q.Allowed).Language; diff --git a/src/NzbDrone.Core/Profiles/Qualities/QualityProfile.cs b/src/NzbDrone.Core/Profiles/Qualities/QualityProfile.cs index 083a5ca9c..8833492a5 100644 --- a/src/NzbDrone.Core/Profiles/Qualities/QualityProfile.cs +++ b/src/NzbDrone.Core/Profiles/Qualities/QualityProfile.cs @@ -12,6 +12,20 @@ namespace NzbDrone.Core.Profiles.Qualities public int Cutoff { get; set; } public List Items { get; set; } + public Quality FirststAllowedQuality() + { + var firstAllowed = Items.First(q => q.Allowed); + + if (firstAllowed.Quality != null) + { + return firstAllowed.Quality; + } + + // Returning any item from the group will work, + // returning the first because it's the true first quality. + return firstAllowed.Items.First().Quality; + } + public Quality LastAllowedQuality() { var lastAllowed = Items.Last(q => q.Allowed);