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.
pull/47/head
Robert Dailey 2 years ago
parent 9f088db16e
commit 66d9f3dcdd

@ -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

@ -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<string> {"term"}};
var data = new Dictionary<string, ProfileData> {{"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<string> {"term"}};
var data = new Dictionary<string, ProfileData> {{"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<string, ProfileData> {{"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<string, ProfileData> {{"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<string, ProfileData> {{"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<int, List<string>>
{
{100, new List<string> {"term"}}
}
}
};
var data = new Dictionary<string, ProfileData> {{"actualData", profileData}};
var filteredData = Utils.FilterProfiles(data, _filterExcludeOptional);
filteredData.Should().BeEmpty();
}
}

@ -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)
{

@ -1,25 +1,35 @@
namespace TrashLib.Sonarr.ReleaseProfile;
using TrashLib.Sonarr.Config;
namespace TrashLib.Sonarr.ReleaseProfile;
using ProfileDataCollection = IDictionary<string, ProfileData>;
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

Loading…
Cancel
Save