From 0592f35aee509ad59488d4e6311b55cce61e14fd Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 16 Feb 2022 17:55:14 -0800 Subject: [PATCH] Fixed: Profiles with upgrades disabled incorrectly allowing upgrades in some cases Closes #2649 --- .../CutoffSpecificationFixture.cs | 16 +++++++++++----- .../Specifications/UpgradableSpecification.cs | 3 ++- .../Profiles/Qualities/QualityProfile.cs | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/CutoffSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/CutoffSpecificationFixture.cs index 23761abc3..9243ba028 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/CutoffSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/CutoffSpecificationFixture.cs @@ -19,7 +19,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests new QualityProfile { Cutoff = Quality.MP3_256.Id, - Items = Qualities.QualityFixture.GetDefaultQualities() + Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }, new List { new QualityModel(Quality.MP3_192, new Revision(version: 2)) }, new List()).Should().BeTrue(); @@ -32,7 +33,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests new QualityProfile { Cutoff = Quality.MP3_256.Id, - Items = Qualities.QualityFixture.GetDefaultQualities() + Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }, new List { new QualityModel(Quality.MP3_256, new Revision(version: 2)) }, new List()).Should().BeFalse(); @@ -45,7 +47,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests new QualityProfile { Cutoff = Quality.MP3_256.Id, - Items = Qualities.QualityFixture.GetDefaultQualities() + Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }, new List { new QualityModel(Quality.MP3_320, new Revision(version: 2)) }, new List()).Should().BeFalse(); @@ -58,7 +61,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests new QualityProfile { Cutoff = Quality.MP3_320.Id, - Items = Qualities.QualityFixture.GetDefaultQualities() + Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }, new List { new QualityModel(Quality.MP3_320, new Revision(version: 1)) }, new List(), @@ -72,7 +76,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests new QualityProfile { Cutoff = Quality.MP3_320.Id, - Items = Qualities.QualityFixture.GetDefaultQualities() + Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }, new List { new QualityModel(Quality.MP3_320, new Revision(version: 2)) }, new List(), @@ -86,6 +91,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { Cutoff = Quality.MP3_320.Id, Items = Qualities.QualityFixture.GetDefaultQualities(), + UpgradeAllowed = true }; Subject.CutoffNotMet( diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs index c3ca140cf..e5fe3194f 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs @@ -99,7 +99,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.FirstAllowedQuality().Id; + var cutoffCompare = new QualityModelComparer(profile).Compare(currentQuality.Quality.Id, cutoff); if (cutoffCompare < 0) { diff --git a/src/NzbDrone.Core/Profiles/Qualities/QualityProfile.cs b/src/NzbDrone.Core/Profiles/Qualities/QualityProfile.cs index c345e0271..0c3a59c8e 100644 --- a/src/NzbDrone.Core/Profiles/Qualities/QualityProfile.cs +++ b/src/NzbDrone.Core/Profiles/Qualities/QualityProfile.cs @@ -21,6 +21,20 @@ namespace NzbDrone.Core.Profiles.Qualities public List FormatItems { get; set; } public List Items { get; set; } + public Quality FirstAllowedQuality() + { + 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);