From 66d9f3dcdd2ef4cb37579991b1d501f9b7f6a6c3 Mon Sep 17 00:00:00 2001 From: Robert Dailey Date: Sun, 6 Mar 2022 11:24:06 -0600 Subject: [PATCH] fix(sonarr): Profile filtering considers the IncludeOptionals setting When `IncludeOptionals` was set to false, release profiles with only optional terms in them would fail to sync to Sonarr because they were empty. The filter profile logic now considers this config setting and if set to false, it will ensure that optionals-only release profiles get filtered out and not pushed to Sonarr. --- CHANGELOG.md | 5 +++ .../Sonarr/ReleaseProfile/UtilsTest.cs | 39 +++++++++++++++---- .../ReleaseProfile/ReleaseProfileUpdater.cs | 3 +- src/TrashLib/Sonarr/ReleaseProfile/Utils.cs | 30 +++++++++----- 4 files changed, 59 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4320cb27..6e39dad3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Sonarr: Error when syncing optionals release profile with the `IncludeOptionals` filter setting + set to `false`. + ## [1.8.1] - 2022-03-05 ### Changed diff --git a/src/TrashLib.Tests/Sonarr/ReleaseProfile/UtilsTest.cs b/src/TrashLib.Tests/Sonarr/ReleaseProfile/UtilsTest.cs index f19dea2f..cb90479f 100644 --- a/src/TrashLib.Tests/Sonarr/ReleaseProfile/UtilsTest.cs +++ b/src/TrashLib.Tests/Sonarr/ReleaseProfile/UtilsTest.cs @@ -1,5 +1,6 @@ using FluentAssertions; using NUnit.Framework; +using TrashLib.Sonarr.Config; using TrashLib.Sonarr.ReleaseProfile; namespace TrashLib.Tests.Sonarr.ReleaseProfile; @@ -8,13 +9,16 @@ namespace TrashLib.Tests.Sonarr.ReleaseProfile; [Parallelizable(ParallelScope.All)] public class UtilsTest { + private static readonly SonarrProfileFilterConfig _filterIncludeOptional = new() {IncludeOptional = true}; + private static readonly SonarrProfileFilterConfig _filterExcludeOptional = new() {IncludeOptional = false}; + [Test] public void Profile_with_only_ignored_should_not_be_filtered_out() { var profileData = new ProfileData {Ignored = new List {"term"}}; var data = new Dictionary {{"actualData", profileData}}; - var filteredData = Utils.FilterProfiles(data); + var filteredData = Utils.FilterProfiles(data, _filterIncludeOptional); filteredData.Should().BeEquivalentTo(data); } @@ -25,7 +29,7 @@ public class UtilsTest var profileData = new ProfileData {Required = new List {"term"}}; var data = new Dictionary {{"actualData", profileData}}; - var filteredData = Utils.FilterProfiles(data); + var filteredData = Utils.FilterProfiles(data, _filterIncludeOptional); filteredData.Should().BeEquivalentTo(data); } @@ -43,7 +47,7 @@ public class UtilsTest var data = new Dictionary {{"actualData", profileData}}; - var filteredData = Utils.FilterProfiles(data); + var filteredData = Utils.FilterProfiles(data, _filterIncludeOptional); filteredData.Should().BeEquivalentTo(data); } @@ -61,7 +65,7 @@ public class UtilsTest var data = new Dictionary {{"actualData", profileData}}; - var filteredData = Utils.FilterProfiles(data); + var filteredData = Utils.FilterProfiles(data, _filterIncludeOptional); filteredData.Should().BeEquivalentTo(data); } @@ -82,7 +86,7 @@ public class UtilsTest {"actualData", profileData} }; - var filteredData = Utils.FilterProfiles(data); + var filteredData = Utils.FilterProfiles(data, _filterIncludeOptional); filteredData.Should().BeEquivalentTo(data); } @@ -103,7 +107,7 @@ public class UtilsTest var data = new Dictionary {{"actualData", profileData}}; - var filteredData = Utils.FilterProfiles(data); + var filteredData = Utils.FilterProfiles(data, _filterIncludeOptional); filteredData.Should().BeEquivalentTo(data); } @@ -116,8 +120,29 @@ public class UtilsTest {"emptyData", new ProfileData()} }; - var filteredData = Utils.FilterProfiles(data); + var filteredData = Utils.FilterProfiles(data, _filterIncludeOptional); filteredData.Should().NotContainKey("emptyData"); } + + [Test] + public void Profile_with_only_optionals_should_be_filtered_out_when_config_excludes_optionals() + { + var profileData = new ProfileData + { + Optional = new ProfileDataOptional + { + Preferred = new Dictionary> + { + {100, new List {"term"}} + } + } + }; + + var data = new Dictionary {{"actualData", profileData}}; + + var filteredData = Utils.FilterProfiles(data, _filterExcludeOptional); + + filteredData.Should().BeEmpty(); + } } diff --git a/src/TrashLib/Sonarr/ReleaseProfile/ReleaseProfileUpdater.cs b/src/TrashLib/Sonarr/ReleaseProfile/ReleaseProfileUpdater.cs index 3692ae7f..fc6f295a 100644 --- a/src/TrashLib/Sonarr/ReleaseProfile/ReleaseProfileUpdater.cs +++ b/src/TrashLib/Sonarr/ReleaseProfile/ReleaseProfileUpdater.cs @@ -34,7 +34,8 @@ internal class ReleaseProfileUpdater : IReleaseProfileUpdater { Log.Information("Processing Release Profile: {ProfileName}", profile.Type); var markdown = await _parser.GetMarkdownData(profile.Type); - var profiles = Utils.FilterProfiles(_parser.ParseMarkdown(profile, markdown)); + var profileData = _parser.ParseMarkdown(profile, markdown); + var profiles = Utils.FilterProfiles(profileData, profile.Filter); if (profile.Filter.IncludeOptional) { diff --git a/src/TrashLib/Sonarr/ReleaseProfile/Utils.cs b/src/TrashLib/Sonarr/ReleaseProfile/Utils.cs index 282a2e77..e60cf388 100644 --- a/src/TrashLib/Sonarr/ReleaseProfile/Utils.cs +++ b/src/TrashLib/Sonarr/ReleaseProfile/Utils.cs @@ -1,25 +1,35 @@ -namespace TrashLib.Sonarr.ReleaseProfile; +using TrashLib.Sonarr.Config; + +namespace TrashLib.Sonarr.ReleaseProfile; using ProfileDataCollection = IDictionary; public static class Utils { - public static ProfileDataCollection FilterProfiles(ProfileDataCollection profiles) + public static ProfileDataCollection FilterProfiles(ProfileDataCollection profiles, SonarrProfileFilterConfig filter) { - static bool IsEmpty(ProfileData data) + bool IsEmpty(ProfileData data) { - return data is + var isEmpty = data is { // Non-optional Required.Count: 0, Ignored.Count: 0, - Preferred.Count: 0, - - // Optional - Optional.Required.Count: 0, - Optional.Ignored.Count: 0, - Optional.Preferred.Count: 0 + Preferred.Count: 0 }; + + if (isEmpty && filter.IncludeOptional) + { + isEmpty = data is + { + // Optional + Optional.Required.Count: 0, + Optional.Ignored.Count: 0, + Optional.Preferred.Count: 0 + }; + } + + return isEmpty; } // A few false-positive profiles are added sometimes. We filter these out by checking if they