From 63c3bff27a54592fefba5bff857ded992ab99f30 Mon Sep 17 00:00:00 2001 From: Robert Dailey Date: Sat, 10 Sep 2022 11:39:47 -0500 Subject: [PATCH] feat!: Remove names support for custom formats BREAKING CHANGE: The `names` property is no longer supported under `custom_formats:`. This feature was previously deprecated. --- CHANGELOG.md | 5 + .../FluentAssertions/JsonEquivalencyStep.cs | 5 +- .../CustomFormat/CachePersisterTest.cs | 22 +-- .../Processors/GuideProcessorTest.cs | 20 +- .../Processors/GuideSteps/ConfigStepTest.cs | 122 ++---------- .../GuideSteps/CustomFormatStepTest.cs | 179 +----------------- .../CustomFormatApiPersistenceStepTest.cs | 4 +- .../JsonTransactionStepTest.cs | 37 ++-- .../QualityProfileApiPersistenceStepTest.cs | 10 +- src/TrashLib.Tests/GlobalTestSetup.cs | 14 ++ .../Radarr/RadarrConfigurationTest.cs | 8 +- .../Config/Services/ServiceConfiguration.cs | 1 - .../CustomFormat/CustomFormatUpdater.cs | 40 +--- .../Models/Cache/CustomFormatCache.cs | 4 +- .../Models/ProcessedCustomFormatData.cs | 3 +- .../CustomFormat/Processors/GuideProcessor.cs | 6 - .../Processors/GuideSteps/ConfigStep.cs | 40 +--- .../Processors/GuideSteps/CustomFormatStep.cs | 60 ------ .../GuideSteps/ICustomFormatStep.cs | 2 - .../Processors/IGuideProcessor.cs | 2 - .../PersistenceSteps/JsonTransactionStep.cs | 13 +- .../Config/IRadarrValidationMessages.cs | 2 +- .../Config/RadarrConfigurationValidator.cs | 3 +- .../Radarr/Config/RadarrValidationMessages.cs | 4 +- 24 files changed, 112 insertions(+), 494 deletions(-) create mode 100644 src/TrashLib.Tests/GlobalTestSetup.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index c8fc9dde..310b0236 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] +### Removed + +- **BREAKING**: Completely removed support for `names` under `custom_formats` in `recyclarr.yml`. + Note that this had already been deprecated for quite some time. + ## [2.6.1] - 2022-10-15 ### Fixed diff --git a/src/TestLibrary/FluentAssertions/JsonEquivalencyStep.cs b/src/TestLibrary/FluentAssertions/JsonEquivalencyStep.cs index 51e7d070..0b0adf12 100644 --- a/src/TestLibrary/FluentAssertions/JsonEquivalencyStep.cs +++ b/src/TestLibrary/FluentAssertions/JsonEquivalencyStep.cs @@ -1,3 +1,4 @@ +using FluentAssertions; using FluentAssertions.Equivalency; using FluentAssertions.Json; using Newtonsoft.Json.Linq; @@ -16,7 +17,9 @@ public class JsonEquivalencyStep : IEquivalencyStep } ((JToken) comparands.Subject!).Should().BeEquivalentTo( - (JToken) comparands.Expectation, context.Reason.FormattedMessage, context.Reason.Arguments); + (JToken) comparands.Expectation, + context.Reason.FormattedMessage, + context.Reason.Arguments); return EquivalencyResult.AssertionCompleted; } diff --git a/src/TrashLib.Tests/CustomFormat/CachePersisterTest.cs b/src/TrashLib.Tests/CustomFormat/CachePersisterTest.cs index 85533694..f8c3dec6 100644 --- a/src/TrashLib.Tests/CustomFormat/CachePersisterTest.cs +++ b/src/TrashLib.Tests/CustomFormat/CachePersisterTest.cs @@ -29,15 +29,6 @@ public class CachePersisterTest public IServiceCache ServiceCache { get; } } - private static ProcessedCustomFormatData QuickMakeCf(string cfName, string trashId, int cfId) - { - var cf = NewCf.Data(cfName, trashId); - return new ProcessedCustomFormatData(cf) - { - CacheEntry = new TrashIdMapping(trashId, cfName) {CustomFormatId = cfId} - }; - } - [TestCase(CustomFormatCache.LatestVersion - 1)] [TestCase(CustomFormatCache.LatestVersion + 1)] public void Set_loaded_cache_to_null_if_versions_mismatch(int versionToTest) @@ -47,7 +38,7 @@ public class CachePersisterTest var testCfObj = new CustomFormatCache { Version = versionToTest, - TrashIdMappings = new Collection {new("", "", 5)} + TrashIdMappings = new Collection {new("", 5)} }; ctx.ServiceCache.Load().Returns(testCfObj); ctx.Persister.Load(); @@ -62,7 +53,7 @@ public class CachePersisterTest var testCfObj = new CustomFormatCache { Version = CustomFormatCache.LatestVersion, - TrashIdMappings = new Collection {new("", "", 5)} + TrashIdMappings = new Collection {new("", 5)} }; ctx.ServiceCache.Load().Returns(testCfObj); ctx.Persister.Load(); @@ -117,19 +108,18 @@ public class CachePersisterTest // Load initial CfCache just to test that it gets replaced var testCfObj = new CustomFormatCache { - TrashIdMappings = new Collection {new("", "") {CustomFormatId = 5}} + TrashIdMappings = new Collection {new("") {CustomFormatId = 5}} }; ctx.ServiceCache.Load().Returns(testCfObj); ctx.Persister.Load(); // Update with new cached items var results = new CustomFormatTransactionData(); - results.NewCustomFormats.Add(QuickMakeCf("cfname", "trashid", 10)); + results.NewCustomFormats.Add(NewCf.Processed("cfname", "trashid", 10)); var customFormatData = new List { - new(NewCf.Data("", "trashid")) - {CacheEntry = new TrashIdMapping("trashid", "cfname", 10)} + new(NewCf.Data("", "trashid")) {CacheEntry = new TrashIdMapping("trashid", 10)} }; ctx.Persister.Update(customFormatData); @@ -140,7 +130,7 @@ public class CachePersisterTest customFormatData.Should().ContainSingle() .Which.CacheEntry.Should().BeEquivalentTo( - new TrashIdMapping("trashid", "cfname") {CustomFormatId = 10}); + new TrashIdMapping("trashid") {CustomFormatId = 10}); } [Test] diff --git a/src/TrashLib.Tests/CustomFormat/Processors/GuideProcessorTest.cs b/src/TrashLib.Tests/CustomFormat/Processors/GuideProcessorTest.cs index 47595bb6..27bafd35 100644 --- a/src/TrashLib.Tests/CustomFormat/Processors/GuideProcessorTest.cs +++ b/src/TrashLib.Tests/CustomFormat/Processors/GuideProcessorTest.cs @@ -4,7 +4,6 @@ using FluentAssertions; using Newtonsoft.Json.Linq; using NSubstitute; using NUnit.Framework; -using Serilog; using TestLibrary.FluentAssertions; using TrashLib.Config.Services; using TrashLib.Services.CustomFormat.Guide; @@ -23,7 +22,7 @@ public class GuideProcessorTest private class TestGuideProcessorSteps : IGuideProcessorSteps { public ICustomFormatStep CustomFormat { get; } = new CustomFormatStep(); - public IConfigStep Config { get; } = new ConfigStep(Substitute.For()); + public IConfigStep Config { get; } = new ConfigStep(); public IQualityProfileStep QualityProfile { get; } = new QualityProfileStep(); } @@ -68,7 +67,13 @@ public class GuideProcessorTest { new() { - Names = new List {"Surround SOUND", "DTS-HD/DTS:X", "no score", "not in guide 1"}, + TrashIds = new List + { + "43bb5f09c79641e7a22e48d440bd8868", // Surround SOUND + "4eb3c272d48db8ab43c2c85283b69744", // DTS-HD/DTS:X + "abc", // no score + "not in guide 1" + }, QualityProfiles = new List { new() {Name = "profile1"}, @@ -77,7 +82,11 @@ public class GuideProcessorTest }, new() { - Names = new List {"no score", "not in guide 2"}, + TrashIds = new List + { + "abc", // no score + "not in guide 2" + }, QualityProfiles = new List { new() {Name = "profile3"}, @@ -97,7 +106,8 @@ public class GuideProcessorTest NewCf.Processed("No Score", "abc") }; - guideProcessor.ProcessedCustomFormats.Should().BeEquivalentTo(expectedProcessedCustomFormatData); + guideProcessor.ProcessedCustomFormats.Should() + .BeEquivalentTo(expectedProcessedCustomFormatData, op => op.Using(new JsonEquivalencyStep())); guideProcessor.ConfigData.Should() .BeEquivalentTo(new List diff --git a/src/TrashLib.Tests/CustomFormat/Processors/GuideSteps/ConfigStepTest.cs b/src/TrashLib.Tests/CustomFormat/Processors/GuideSteps/ConfigStepTest.cs index d7a2e8c1..49c718c4 100644 --- a/src/TrashLib.Tests/CustomFormat/Processors/GuideSteps/ConfigStepTest.cs +++ b/src/TrashLib.Tests/CustomFormat/Processors/GuideSteps/ConfigStepTest.cs @@ -4,7 +4,6 @@ using NUnit.Framework; using TestLibrary.AutoFixture; using TrashLib.Config.Services; using TrashLib.Services.CustomFormat.Models; -using TrashLib.Services.CustomFormat.Models.Cache; using TrashLib.Services.CustomFormat.Processors.GuideSteps; using TrashLib.TestLibrary; @@ -14,52 +13,20 @@ namespace TrashLib.Tests.CustomFormat.Processors.GuideSteps; [Parallelizable(ParallelScope.All)] public class ConfigStepTest { - [Test, AutoMockData] - public void Cache_names_are_used_instead_of_name_in_json_data(ConfigStep processor) - { - var testProcessedCfs = new List - { - NewCf.Processed("name1", "id1", 100), - NewCf.Processed("name3", "id3", new TrashIdMapping("id3", "name1")) - }; - - var testConfig = new CustomFormatConfig[] - { - new() - { - Names = new List {"name1"} - } - }; - - processor.Process(testProcessedCfs, testConfig); - - processor.CustomFormatsNotInGuide.Should().BeEmpty(); - processor.ConfigData.Should().BeEquivalentTo(new List - { - new() - { - CustomFormats = new List - {testProcessedCfs[1]} - } - }, op => op - .Using(jctx => jctx.Subject.Should().BeEquivalentTo(jctx.Expectation)) - .WhenTypeIs()); - } - [Test, AutoMockData] public void Custom_formats_missing_from_config_are_skipped(ConfigStep processor) { var testProcessedCfs = new List { - NewCf.Processed("name1", ""), - NewCf.Processed("name2", "") + NewCf.Processed("name1", "id1"), + NewCf.Processed("name2", "id2") }; var testConfig = new CustomFormatConfig[] { new() { - Names = new List {"name1"} + TrashIds = new List {"id1"} } }; @@ -72,7 +39,7 @@ public class ConfigStepTest { CustomFormats = new List { - NewCf.Processed("name1", "") + NewCf.Processed("name1", "id1") } } }, op => op @@ -85,21 +52,21 @@ public class ConfigStepTest { var testProcessedCfs = new List { - NewCf.Processed("name1", ""), - NewCf.Processed("name2", "") + NewCf.Processed("name1", "id1"), + NewCf.Processed("name2", "id2") }; var testConfig = new CustomFormatConfig[] { new() { - Names = new List {"name1", "name3"} + TrashIds = new List {"id1", "id3"} } }; processor.Process(testProcessedCfs, testConfig); - processor.CustomFormatsNotInGuide.Should().BeEquivalentTo(new List {"name3"}, op => op + processor.CustomFormatsNotInGuide.Should().BeEquivalentTo(new List {"id3"}, op => op .Using(jctx => jctx.Subject.Should().BeEquivalentTo(jctx.Expectation)) .WhenTypeIs()); processor.ConfigData.Should().BeEquivalentTo(new List @@ -108,7 +75,7 @@ public class ConfigStepTest { CustomFormats = new List { - NewCf.Processed("name1", "") + NewCf.Processed("name1", "id1") } } }, op => op @@ -117,7 +84,7 @@ public class ConfigStepTest } [Test, AutoMockData] - public void Duplicate_config_name_and_id_are_ignored(ConfigStep processor) + public void Duplicate_config_trash_ids_are_ignored(ConfigStep processor) { var testProcessedCfs = new List { @@ -126,11 +93,7 @@ public class ConfigStepTest var testConfig = new CustomFormatConfig[] { - new() - { - Names = new List {"name1"}, - TrashIds = new List {"id1"} - } + new() {TrashIds = new List {"id1", "id1"}} }; processor.Process(testProcessedCfs, testConfig); @@ -144,67 +107,4 @@ public class ConfigStepTest } }); } - - [Test, AutoMockData] - public void Duplicate_config_names_are_ignored(ConfigStep processor) - { - var testProcessedCfs = new List - { - NewCf.Processed("name1", "id1") - }; - - var testConfig = new CustomFormatConfig[] - { - new() {Names = new List {"name1", "name1"}} - }; - - processor.Process(testProcessedCfs, testConfig); - - processor.CustomFormatsNotInGuide.Should().BeEmpty(); - processor.ConfigData.Should().BeEquivalentTo(new List - { - new() - { - CustomFormats = new List {testProcessedCfs[0]} - } - }); - } - - [Test, AutoMockData] - public void Find_custom_formats_by_name_and_trash_id(ConfigStep processor) - { - var testProcessedCfs = new List - { - NewCf.Processed("name1", "id1", 100), - NewCf.Processed("name3", "id3"), - NewCf.Processed("name4", "id4") - }; - - var testConfig = new CustomFormatConfig[] - { - new() - { - Names = new List {"name1", "name3"}, - TrashIds = new List {"id1", "id4"}, - QualityProfiles = new List - { - new() {Name = "profile1", Score = 50} - } - } - }; - - processor.Process(testProcessedCfs, testConfig); - - processor.CustomFormatsNotInGuide.Should().BeEmpty(); - processor.ConfigData.Should().BeEquivalentTo(new List - { - new() - { - CustomFormats = testProcessedCfs, - QualityProfiles = testConfig[0].QualityProfiles - } - }, op => op - .Using(jctx => jctx.Subject.Should().BeEquivalentTo(jctx.Expectation)) - .WhenTypeIs()); - } } diff --git a/src/TrashLib.Tests/CustomFormat/Processors/GuideSteps/CustomFormatStepTest.cs b/src/TrashLib.Tests/CustomFormat/Processors/GuideSteps/CustomFormatStepTest.cs index 71bfa4c6..5e961272 100644 --- a/src/TrashLib.Tests/CustomFormat/Processors/GuideSteps/CustomFormatStepTest.cs +++ b/src/TrashLib.Tests/CustomFormat/Processors/GuideSteps/CustomFormatStepTest.cs @@ -25,88 +25,17 @@ public class CustomFormatStepTest }; } - [TestCase("name1", 0)] - [TestCase("naME1", 0)] - [TestCase("DifferentName", 1)] - public void Match_cf_in_guide_with_different_name_with_cache_using_same_name_in_config(string variableCfName, - int outdatedCount) - { - var testConfig = new List - { - new() {Names = new List {"name1"}} - }; - - var testCache = new CustomFormatCache - { - TrashIdMappings = new Collection - { - new("id1", "name1") - } - }; - - var testGuideData = new List - { - NewCf.Data(variableCfName, "id1") - }; - - var processor = new CustomFormatStep(); - processor.Process(testGuideData, testConfig, testCache); - - processor.DuplicatedCustomFormats.Should().BeEmpty(); - processor.CustomFormatsWithOutdatedNames.Should().HaveCount(outdatedCount); - processor.DeletedCustomFormatsInCache.Should().BeEmpty(); - processor.ProcessedCustomFormats.Should().BeEquivalentTo(new List - { - NewCf.Processed(variableCfName, "id1", testCache.TrashIdMappings[0]) - }); - } - - [Test, AutoMockData] - public void Cache_entry_is_not_set_when_id_is_different(CustomFormatStep processor) - { - var guideData = new List - { - NewCf.Data("name1", "id1") - }; - - var testConfig = new List - { - new() {Names = new List {"name1"}} - }; - - var testCache = new CustomFormatCache - { - TrashIdMappings = new Collection - { - new("id1000", "name1") - } - }; - - processor.Process(guideData, testConfig, testCache); - - processor.DuplicatedCustomFormats.Should().BeEmpty(); - processor.CustomFormatsWithOutdatedNames.Should().BeEmpty(); - processor.DeletedCustomFormatsInCache.Count.Should().Be(1); - processor.ProcessedCustomFormats.Should() - .BeEquivalentTo(new List - { - NewCf.Processed("name1", "id1") - }); - } - [Test, AutoMockData] public void Cfs_not_in_config_are_skipped(CustomFormatStep processor) { var ctx = new Context(); var testConfig = new List { - new() {Names = new List {"name1", "name3"}} + new() {TrashIds = new List {"id1", "id3"}} }; processor.Process(ctx.TestGuideData, testConfig, new CustomFormatCache()); - processor.DuplicatedCustomFormats.Should().BeEmpty(); - processor.CustomFormatsWithOutdatedNames.Should().BeEmpty(); processor.DeletedCustomFormatsInCache.Should().BeEmpty(); processor.ProcessedCustomFormats.Should() .BeEquivalentTo(new List @@ -122,14 +51,12 @@ public class CustomFormatStepTest var ctx = new Context(); var testConfig = new List { - new() {Names = new List {"name1", "name3"}}, - new() {Names = new List {"name2"}} + new() {TrashIds = new List {"id1", "id3"}}, + new() {TrashIds = new List {"id2"}} }; processor.Process(ctx.TestGuideData, testConfig, new CustomFormatCache()); - processor.DuplicatedCustomFormats.Should().BeEmpty(); - processor.CustomFormatsWithOutdatedNames.Should().BeEmpty(); processor.DeletedCustomFormatsInCache.Should().BeEmpty(); processor.ProcessedCustomFormats.Should().BeEquivalentTo(new List { @@ -150,20 +77,18 @@ public class CustomFormatStepTest var testConfig = new List { - new() {Names = new List {"name1"}} + new() {TrashIds = new List {"id1"}} }; var testCache = new CustomFormatCache { - TrashIdMappings = new Collection {new("id1000", "name1")} + TrashIdMappings = new Collection {new("id1000")} }; processor.Process(guideData, testConfig, testCache); - processor.DuplicatedCustomFormats.Should().BeEmpty(); - processor.CustomFormatsWithOutdatedNames.Should().BeEmpty(); processor.DeletedCustomFormatsInCache.Should() - .BeEquivalentTo(new[] {new TrashIdMapping("id1000", "name1")}); + .BeEquivalentTo(new[] {new TrashIdMapping("id1000")}); processor.ProcessedCustomFormats.Should().BeEquivalentTo(new List { NewCf.Processed("name1", "id1") @@ -175,7 +100,7 @@ public class CustomFormatStepTest { var cache = new CustomFormatCache { - TrashIdMappings = new Collection {new("id1", "3D", 9)} + TrashIdMappings = new Collection {new("id1", 9)} }; var guideCfs = new List @@ -185,90 +110,10 @@ public class CustomFormatStepTest processor.Process(guideCfs, Array.Empty(), cache); - processor.DuplicatedCustomFormats.Should().BeEmpty(); - processor.CustomFormatsWithOutdatedNames.Should().BeEmpty(); processor.DeletedCustomFormatsInCache.Should().BeEquivalentTo(new[] {cache.TrashIdMappings[0]}); processor.ProcessedCustomFormats.Should().BeEmpty(); } - [Test, AutoMockData] - public void Custom_format_name_in_cache_is_updated_if_renamed_in_guide_and_config(CustomFormatStep processor) - { - var guideData = new List - { - NewCf.Data("name2", "id1") - }; - - var testConfig = new List - { - new() {Names = new List {"name2"}} - }; - - var testCache = new CustomFormatCache - { - TrashIdMappings = new Collection {new("id1", "name1")} - }; - - processor.Process(guideData, testConfig, testCache); - - processor.DuplicatedCustomFormats.Should().BeEmpty(); - processor.CustomFormatsWithOutdatedNames.Should().BeEmpty(); - processor.DeletedCustomFormatsInCache.Should().BeEmpty(); - processor.ProcessedCustomFormats.Should() - .ContainSingle().Which.CacheEntry.Should() - .BeEquivalentTo(new TrashIdMapping("id1", "name2")); - } - - [Test, AutoMockData] - public void Duplicates_are_recorded_and_removed_from_processed_custom_formats_list(CustomFormatStep processor) - { - var guideData = new List - { - NewCf.Data("name1", "id1"), - NewCf.Data("name1", "id2") - }; - - var testConfig = new List - { - new() {Names = new List {"name1"}} - }; - - processor.Process(guideData, testConfig, null); - - //Dictionary> - processor.DuplicatedCustomFormats.Should() - .ContainKey("name1").WhoseValue.Should() - .BeEquivalentTo(new List - { - NewCf.Processed("name1", "id1"), - NewCf.Processed("name1", "id2") - }); - processor.CustomFormatsWithOutdatedNames.Should().BeEmpty(); - processor.DeletedCustomFormatsInCache.Should().BeEmpty(); - processor.ProcessedCustomFormats.Should().BeEmpty(); - } - - [Test, AutoMockData] - public void Match_cf_names_regardless_of_case_in_config(CustomFormatStep processor) - { - var ctx = new Context(); - var testConfig = new List - { - new() {Names = new List {"name1", "NAME1"}} - }; - - processor.Process(ctx.TestGuideData, testConfig, new CustomFormatCache()); - - processor.DuplicatedCustomFormats.Should().BeEmpty(); - processor.CustomFormatsWithOutdatedNames.Should().BeEmpty(); - processor.DeletedCustomFormatsInCache.Should().BeEmpty(); - processor.ProcessedCustomFormats.Should().BeEquivalentTo(new List - { - NewCf.Processed("name1", "id1") - }, - op => op.Using(new JsonEquivalencyStep())); - } - [Test, AutoMockData] public void Match_custom_format_using_trash_id(CustomFormatStep processor) { @@ -285,8 +130,6 @@ public class CustomFormatStepTest processor.Process(guideData, testConfig, null); - processor.DuplicatedCustomFormats.Should().BeEmpty(); - processor.CustomFormatsWithOutdatedNames.Should().BeEmpty(); processor.DeletedCustomFormatsInCache.Should().BeEmpty(); processor.ProcessedCustomFormats.Should() .BeEquivalentTo(new List @@ -301,13 +144,11 @@ public class CustomFormatStepTest var ctx = new Context(); var testConfig = new List { - new() {Names = new List {"doesnt_exist"}} + new() {TrashIds = new List {"doesnt_exist"}} }; processor.Process(ctx.TestGuideData, testConfig, new CustomFormatCache()); - processor.DuplicatedCustomFormats.Should().BeEmpty(); - processor.CustomFormatsWithOutdatedNames.Should().BeEmpty(); processor.DeletedCustomFormatsInCache.Should().BeEmpty(); processor.ProcessedCustomFormats.Should().BeEmpty(); } @@ -324,7 +165,7 @@ public class CustomFormatStepTest { new() { - Names = new List {"name1"}, + TrashIds = new List {"id1"}, QualityProfiles = new List { new() {Name = "profile", Score = 200} @@ -334,8 +175,6 @@ public class CustomFormatStepTest processor.Process(guideData, testConfig, null); - processor.DuplicatedCustomFormats.Should().BeEmpty(); - processor.CustomFormatsWithOutdatedNames.Should().BeEmpty(); processor.DeletedCustomFormatsInCache.Should().BeEmpty(); processor.ProcessedCustomFormats.Should() .BeEquivalentTo(new List diff --git a/src/TrashLib.Tests/CustomFormat/Processors/PersistenceSteps/CustomFormatApiPersistenceStepTest.cs b/src/TrashLib.Tests/CustomFormat/Processors/PersistenceSteps/CustomFormatApiPersistenceStepTest.cs index b3e9987e..ca46575c 100644 --- a/src/TrashLib.Tests/CustomFormat/Processors/PersistenceSteps/CustomFormatApiPersistenceStepTest.cs +++ b/src/TrashLib.Tests/CustomFormat/Processors/PersistenceSteps/CustomFormatApiPersistenceStepTest.cs @@ -14,7 +14,7 @@ public class CustomFormatApiPersistenceStepTest { private static ProcessedCustomFormatData QuickMakeCf(string cfName, string trashId, int cfId) { - return NewCf.Processed(cfName, trashId, new TrashIdMapping(trashId, cfName) {CustomFormatId = cfId}); + return NewCf.Processed(cfName, trashId, new TrashIdMapping(trashId) {CustomFormatId = cfId}); } [Test] @@ -24,7 +24,7 @@ public class CustomFormatApiPersistenceStepTest transactions.NewCustomFormats.Add(QuickMakeCf("cfname1", "trashid1", 1)); transactions.UpdatedCustomFormats.Add(QuickMakeCf("cfname2", "trashid2", 2)); transactions.UnchangedCustomFormats.Add(QuickMakeCf("cfname3", "trashid3", 3)); - transactions.DeletedCustomFormatIds.Add(new TrashIdMapping("trashid4", "cfname4") {CustomFormatId = 4}); + transactions.DeletedCustomFormatIds.Add(new TrashIdMapping("trashid4") {CustomFormatId = 4}); var api = Substitute.For(); diff --git a/src/TrashLib.Tests/CustomFormat/Processors/PersistenceSteps/JsonTransactionStepTest.cs b/src/TrashLib.Tests/CustomFormat/Processors/PersistenceSteps/JsonTransactionStepTest.cs index 284bf4e6..e69efff3 100644 --- a/src/TrashLib.Tests/CustomFormat/Processors/PersistenceSteps/JsonTransactionStepTest.cs +++ b/src/TrashLib.Tests/CustomFormat/Processors/PersistenceSteps/JsonTransactionStepTest.cs @@ -68,7 +68,7 @@ public class JsonTransactionStepTest } }] }"); - var cacheEntry = id != null ? new TrashIdMapping("", "") {CustomFormatId = id.Value} : null; + var cacheEntry = id != null ? new TrashIdMapping("") {CustomFormatId = id.Value} : null; var guideCfs = new List { @@ -101,7 +101,8 @@ public class JsonTransactionStepTest [Test] public void Combination_of_create_update_and_unchanged_and_verify_proper_json_merging() { - const string radarrCfData = @"[{ + var radarrCfs = JsonConvert.DeserializeObject>(@" +[{ 'id': 1, 'name': 'user_defined', 'specifications': [{ @@ -135,8 +136,9 @@ public class JsonTransactionStepTest 'value': 'value1' }] }] -}]"; - var guideCfData = JsonConvert.DeserializeObject>(@"[{ +}]")!; + var guideCfData = JsonConvert.DeserializeObject>(@" +[{ 'name': 'created', 'specifications': [{ 'name': 'spec5', @@ -169,18 +171,17 @@ public class JsonTransactionStepTest 'value': 'value1' } }] -}]"); +}]")!; - var radarrCfs = JsonConvert.DeserializeObject>(radarrCfData); var guideCfs = new List { - NewCf.Processed("created", "", guideCfData![0]), - NewCf.Processed("updated_different_name", "", guideCfData[1], new TrashIdMapping("", "", 2)), - NewCf.Processed("no_change", "", guideCfData[2]) + NewCf.Processed("created", "id1", guideCfData[0]), + NewCf.Processed("updated_different_name", "id2", guideCfData[1], new TrashIdMapping("id2", 2)), + NewCf.Processed("no_change", "id3", guideCfData[2], new TrashIdMapping("id3", 3)) }; var processor = new JsonTransactionStep(); - processor.Process(guideCfs, radarrCfs!); + processor.Process(guideCfs, radarrCfs); var expectedJson = new[] { @@ -282,12 +283,12 @@ public class JsonTransactionStepTest }"); var deletedCfsInCache = new List { - new("", "") {CustomFormatId = 2} + new("") {CustomFormatId = 2} }; var guideCfs = new List { - NewCf.Processed("updated", "", guideCfData, new TrashIdMapping("", "") {CustomFormatId = 1}) + NewCf.Processed("updated", "", guideCfData, new TrashIdMapping("") {CustomFormatId = 1}) }; var radarrCfs = JsonConvert.DeserializeObject>(radarrCfData); @@ -308,7 +309,7 @@ public class JsonTransactionStepTest }] }"; var expectedTransactions = new CustomFormatTransactionData(); - expectedTransactions.DeletedCustomFormatIds.Add(new TrashIdMapping("", "", 2)); + expectedTransactions.DeletedCustomFormatIds.Add(new TrashIdMapping("", 2)); expectedTransactions.UpdatedCustomFormats.Add(guideCfs[0]); processor.Transactions.Should().BeEquivalentTo(expectedTransactions); @@ -345,8 +346,8 @@ public class JsonTransactionStepTest }]"; var deletedCfsInCache = new List { - new("testtrashid", "testname") {CustomFormatId = 2}, - new("", "not_deleted") {CustomFormatId = 3} + new("testtrashid", 2), + new("", 3) }; var radarrCfs = JsonConvert.DeserializeObject>(radarrCfData); @@ -355,7 +356,7 @@ public class JsonTransactionStepTest processor.RecordDeletions(deletedCfsInCache, radarrCfs!); var expectedTransactions = new CustomFormatTransactionData(); - expectedTransactions.DeletedCustomFormatIds.Add(new TrashIdMapping("testtrashid", "testname", 2)); + expectedTransactions.DeletedCustomFormatIds.Add(new TrashIdMapping("testtrashid", 2)); processor.Transactions.Should().BeEquivalentTo(expectedTransactions); } @@ -414,9 +415,9 @@ public class JsonTransactionStepTest processor.Process(guideCfs, radarrCfs!); processor.Transactions.UpdatedCustomFormats.First().CacheEntry.Should() - .BeEquivalentTo(new TrashIdMapping("", "updated", 1)); + .BeEquivalentTo(new TrashIdMapping("", 1)); processor.Transactions.UnchangedCustomFormats.First().CacheEntry.Should() - .BeEquivalentTo(new TrashIdMapping("", "no_change", 2)); + .BeEquivalentTo(new TrashIdMapping("", 2)); } } diff --git a/src/TrashLib.Tests/CustomFormat/Processors/PersistenceSteps/QualityProfileApiPersistenceStepTest.cs b/src/TrashLib.Tests/CustomFormat/Processors/PersistenceSteps/QualityProfileApiPersistenceStepTest.cs index ee3e9e9d..cc45c09c 100644 --- a/src/TrashLib.Tests/CustomFormat/Processors/PersistenceSteps/QualityProfileApiPersistenceStepTest.cs +++ b/src/TrashLib.Tests/CustomFormat/Processors/PersistenceSteps/QualityProfileApiPersistenceStepTest.cs @@ -48,7 +48,7 @@ public class QualityProfileApiPersistenceStepTest { { "profile1", CfTestUtils.NewMapping(new FormatMappingEntry( - NewCf.Processed("", "", new TrashIdMapping("", "") {CustomFormatId = 4}), 100)) + NewCf.Processed("", "", new TrashIdMapping("") {CustomFormatId = 4}), 100)) } }; @@ -109,7 +109,7 @@ public class QualityProfileApiPersistenceStepTest { { "profile1", CfTestUtils.NewMappingWithReset( - new FormatMappingEntry(NewCf.Processed("", "", new TrashIdMapping("", "", 2)), 100)) + new FormatMappingEntry(NewCf.Processed("", "", new TrashIdMapping("", 2)), 100)) } }; @@ -183,11 +183,11 @@ public class QualityProfileApiPersistenceStepTest { "profile1", CfTestUtils.NewMapping( // First match by ID - new FormatMappingEntry(NewCf.Processed("", "", new TrashIdMapping("", "", 4)), 100), + new FormatMappingEntry(NewCf.Processed("", "", new TrashIdMapping("", 4)), 100), // Should NOT match because we do not use names to assign scores - new FormatMappingEntry(NewCf.Processed("", "", new TrashIdMapping("", "BR-DISK")), 101), + new FormatMappingEntry(NewCf.Processed("", "", new TrashIdMapping("")), 101), // Second match by ID - new FormatMappingEntry(NewCf.Processed("", "", new TrashIdMapping("", "", 1)), 102)) + new FormatMappingEntry(NewCf.Processed("", "", new TrashIdMapping("", 1)), 102)) } }; diff --git a/src/TrashLib.Tests/GlobalTestSetup.cs b/src/TrashLib.Tests/GlobalTestSetup.cs new file mode 100644 index 00000000..1bf5a195 --- /dev/null +++ b/src/TrashLib.Tests/GlobalTestSetup.cs @@ -0,0 +1,14 @@ +using System.Diagnostics.CodeAnalysis; +using FluentAssertions; +using NUnit.Framework; + +[SetUpFixture] +[SuppressMessage("ReSharper", "CheckNamespace")] +public class GlobalTestSetup +{ + [OneTimeSetUp] + public void Setup() + { + AssertionOptions.FormattingOptions.MaxDepth = 100; + } +} diff --git a/src/TrashLib.Tests/Radarr/RadarrConfigurationTest.cs b/src/TrashLib.Tests/Radarr/RadarrConfigurationTest.cs index 40f62250..58b8d814 100644 --- a/src/TrashLib.Tests/Radarr/RadarrConfigurationTest.cs +++ b/src/TrashLib.Tests/Radarr/RadarrConfigurationTest.cs @@ -32,7 +32,7 @@ public class RadarrConfigurationTest }; [TestCaseSource(nameof(NameOrIdsTestData))] - public void Custom_format_is_valid_with_one_of_either_names_or_trash_id(Collection namesList, + public void Custom_format_is_valid_with_trash_id(Collection namesList, Collection trashIdsList) { var config = new RadarrConfiguration @@ -41,7 +41,7 @@ public class RadarrConfigurationTest BaseUrl = "required value", CustomFormats = new List { - new() {Names = namesList, TrashIds = trashIdsList} + new() {TrashIds = trashIdsList} } }; @@ -65,7 +65,7 @@ public class RadarrConfigurationTest { "Property 'base_url' is required", "Property 'api_key' is required", - "'custom_formats' elements must contain at least one element in either 'names' or 'trash_ids'", + "'custom_formats' elements must contain at least one element under 'trash_ids'", "'name' is required for elements under 'quality_profiles'", "'type' is required for 'quality_definition'" }; @@ -86,7 +86,7 @@ public class RadarrConfigurationTest { new() { - Names = new List {"required value"}, + TrashIds = new List {"required value"}, QualityProfiles = new List { new() {Name = "required value"} diff --git a/src/TrashLib/Config/Services/ServiceConfiguration.cs b/src/TrashLib/Config/Services/ServiceConfiguration.cs index e6371943..077e6b14 100644 --- a/src/TrashLib/Config/Services/ServiceConfiguration.cs +++ b/src/TrashLib/Config/Services/ServiceConfiguration.cs @@ -13,7 +13,6 @@ public abstract class ServiceConfiguration : IServiceConfiguration [UsedImplicitly(ImplicitUseTargetFlags.WithMembers)] public class CustomFormatConfig { - public ICollection Names { get; init; } = new List(); public ICollection TrashIds { get; init; } = new List(); public ICollection QualityProfiles { get; init; } = new List(); } diff --git a/src/TrashLib/Services/CustomFormat/CustomFormatUpdater.cs b/src/TrashLib/Services/CustomFormat/CustomFormatUpdater.cs index f2443e35..22af038e 100644 --- a/src/TrashLib/Services/CustomFormat/CustomFormatUpdater.cs +++ b/src/TrashLib/Services/CustomFormat/CustomFormatUpdater.cs @@ -120,7 +120,7 @@ internal class CustomFormatUpdater : ICustomFormatUpdater if (deleted.Count > 0) { _log.Information("Deleted {Count} Custom Formats: {CustomFormats}", deleted.Count, - deleted.Select(r => r.CustomFormatName)); + deleted.Select(r => r.TrashId)); } var totalCount = created.Count + updated.Count; @@ -138,31 +138,11 @@ internal class CustomFormatUpdater : ICustomFormatUpdater { _console.Output.WriteLine(""); - if (_guideProcessor.DuplicatedCustomFormats.Count > 0) - { - _log.Warning("One or more of the custom formats you want are duplicated in the guide. These custom " + - "formats WILL BE SKIPPED. Recyclarr is not able to choose which one you actually " + - "wanted. To resolve this ambiguity, use the `trash_ids` property in your YML " + - "configuration to refer to the custom format using its Trash ID instead of its name"); - - foreach (var (cfName, dupes) in _guideProcessor.DuplicatedCustomFormats) - { - _log.Warning("{CfName} is duplicated {DupeTimes} with the following Trash IDs:", cfName, dupes.Count); - foreach (var cf in dupes) - { - _log.Warning(" - {TrashId}", cf.TrashId); - } - } - - _console.Output.WriteLine(""); - } - if (_guideProcessor.CustomFormatsNotInGuide.Count > 0) { _log.Warning("The Custom Formats below do not exist in the guide and will " + - "be skipped. Names must match the 'name' field in the actual JSON, not the header in " + - "the guide! Either fix the names or remove them from your YAML config to resolve this " + - "warning"); + "be skipped. Trash IDs must match what is listed in the output when using the " + + "`--list-custom-formats` option"); _log.Warning("{CfList}", _guideProcessor.CustomFormatsNotInGuide); _console.Output.WriteLine(""); @@ -220,20 +200,6 @@ internal class CustomFormatUpdater : ICustomFormatUpdater _console.Output.WriteLine(""); } - if (_guideProcessor.CustomFormatsWithOutdatedNames.Count > 0) - { - _log.Warning("One or more custom format names in your YAML config have been renamed in the guide and " + - "are outdated. Each outdated name will be listed below. These custom formats will refuse " + - "to sync if your cache is deleted. To fix this warning, rename each one to its new name"); - - foreach (var (oldName, newName) in _guideProcessor.CustomFormatsWithOutdatedNames) - { - _log.Warning(" - '{OldName}' -> '{NewName}'", oldName, newName); - } - - _console.Output.WriteLine(""); - } - return true; } diff --git a/src/TrashLib/Services/CustomFormat/Models/Cache/CustomFormatCache.cs b/src/TrashLib/Services/CustomFormat/Models/Cache/CustomFormatCache.cs index 389e1f63..8d34b86a 100644 --- a/src/TrashLib/Services/CustomFormat/Models/Cache/CustomFormatCache.cs +++ b/src/TrashLib/Services/CustomFormat/Models/Cache/CustomFormatCache.cs @@ -14,14 +14,12 @@ public class CustomFormatCache public class TrashIdMapping { - public TrashIdMapping(string trashId, string customFormatName, int customFormatId = default) + public TrashIdMapping(string trashId, int customFormatId = default) { - CustomFormatName = customFormatName; TrashId = trashId; CustomFormatId = customFormatId; } - public string CustomFormatName { get; set; } public string TrashId { get; } public int CustomFormatId { get; set; } } diff --git a/src/TrashLib/Services/CustomFormat/Models/ProcessedCustomFormatData.cs b/src/TrashLib/Services/CustomFormat/Models/ProcessedCustomFormatData.cs index 55012d3e..1702ac0a 100644 --- a/src/TrashLib/Services/CustomFormat/Models/ProcessedCustomFormatData.cs +++ b/src/TrashLib/Services/CustomFormat/Models/ProcessedCustomFormatData.cs @@ -19,11 +19,10 @@ public class ProcessedCustomFormatData public int? Score => _data.Score; public JObject Json { get; set; } public TrashIdMapping? CacheEntry { get; set; } - public string CacheAwareName => CacheEntry?.CustomFormatName ?? Name; public void SetCache(int customFormatId) { - CacheEntry ??= new TrashIdMapping(TrashId, Name); + CacheEntry ??= new TrashIdMapping(TrashId); CacheEntry.CustomFormatId = customFormatId; } diff --git a/src/TrashLib/Services/CustomFormat/Processors/GuideProcessor.cs b/src/TrashLib/Services/CustomFormat/Processors/GuideProcessor.cs index b9409437..2d7580c6 100644 --- a/src/TrashLib/Services/CustomFormat/Processors/GuideProcessor.cs +++ b/src/TrashLib/Services/CustomFormat/Processors/GuideProcessor.cs @@ -44,12 +44,6 @@ internal class GuideProcessor : IGuideProcessor public IReadOnlyCollection DeletedCustomFormatsInCache => _steps.CustomFormat.DeletedCustomFormatsInCache; - public IReadOnlyCollection<(string, string)> CustomFormatsWithOutdatedNames - => _steps.CustomFormat.CustomFormatsWithOutdatedNames; - - public IDictionary> DuplicatedCustomFormats - => _steps.CustomFormat.DuplicatedCustomFormats; - public Task BuildGuideDataAsync(IEnumerable config, CustomFormatCache? cache, IGuideService guideService) { diff --git a/src/TrashLib/Services/CustomFormat/Processors/GuideSteps/ConfigStep.cs b/src/TrashLib/Services/CustomFormat/Processors/GuideSteps/ConfigStep.cs index d87e7777..84685222 100644 --- a/src/TrashLib/Services/CustomFormat/Processors/GuideSteps/ConfigStep.cs +++ b/src/TrashLib/Services/CustomFormat/Processors/GuideSteps/ConfigStep.cs @@ -1,52 +1,31 @@ using Common.Extensions; -using Serilog; using TrashLib.Config.Services; using TrashLib.Services.CustomFormat.Models; namespace TrashLib.Services.CustomFormat.Processors.GuideSteps; +/// +/// The purpose of this step is to validate the custom format data in the configs: +/// +/// - Validate that custom formats specified in the config exist in the guide. +/// - Removal of duplicates. +/// public class ConfigStep : IConfigStep { - private readonly ILogger _log; private readonly List _configData = new(); private readonly List _customFormatsNotInGuide = new(); public IReadOnlyCollection CustomFormatsNotInGuide => _customFormatsNotInGuide; public IReadOnlyCollection ConfigData => _configData; - public ConfigStep(ILogger log) - { - _log = log; - } - public void Process( IReadOnlyCollection processedCfs, IReadOnlyCollection config) { - if (config.SelectMany(x => x.Names).Any()) - { - _log.Warning( - "`names` list for `custom_formats` is deprecated and will be removed in the future; use " + - "`trash_ids` instead"); - } - foreach (var singleConfig in config) { var validCfs = new List(); - foreach (var name in singleConfig.Names) - { - var match = FindCustomFormatByName(processedCfs, name); - if (match == null) - { - _customFormatsNotInGuide.Add(name); - } - else - { - validCfs.Add(match); - } - } - foreach (var trashId in singleConfig.TrashIds) { var match = processedCfs.FirstOrDefault(cf => cf.TrashId.EqualsIgnoreCase(trashId)); @@ -69,11 +48,4 @@ public class ConfigStep : IConfigStep }); } } - - private static ProcessedCustomFormatData? FindCustomFormatByName( - IReadOnlyCollection processedCfs, string name) - { - return processedCfs.FirstOrDefault(cf => cf.CacheEntry?.CustomFormatName.EqualsIgnoreCase(name) ?? false) - ?? processedCfs.FirstOrDefault(cf => cf.Name.EqualsIgnoreCase(name)); - } } diff --git a/src/TrashLib/Services/CustomFormat/Processors/GuideSteps/CustomFormatStep.cs b/src/TrashLib/Services/CustomFormat/Processors/GuideSteps/CustomFormatStep.cs index 8ce6ec75..4e5e8fab 100644 --- a/src/TrashLib/Services/CustomFormat/Processors/GuideSteps/CustomFormatStep.cs +++ b/src/TrashLib/Services/CustomFormat/Processors/GuideSteps/CustomFormatStep.cs @@ -1,4 +1,3 @@ -using Common.Extensions; using TrashLib.Config.Services; using TrashLib.Services.CustomFormat.Models; using TrashLib.Services.CustomFormat.Models.Cache; @@ -7,15 +6,11 @@ namespace TrashLib.Services.CustomFormat.Processors.GuideSteps; public class CustomFormatStep : ICustomFormatStep { - private readonly List<(string, string)> _customFormatsWithOutdatedNames = new(); private readonly List _processedCustomFormats = new(); private readonly List _deletedCustomFormatsInCache = new(); - private readonly Dictionary> _duplicatedCustomFormats = new(); - public IReadOnlyCollection<(string, string)> CustomFormatsWithOutdatedNames => _customFormatsWithOutdatedNames; public IReadOnlyCollection ProcessedCustomFormats => _processedCustomFormats; public IReadOnlyCollection DeletedCustomFormatsInCache => _deletedCustomFormatsInCache; - public IDictionary> DuplicatedCustomFormats => _duplicatedCustomFormats; public void Process( IList customFormatGuideData, @@ -36,63 +31,8 @@ public class CustomFormatStep : ICustomFormatStep (_, cf) => cf, StringComparer.InvariantCultureIgnoreCase)); - // Build a list of CF names under the `names` property in YAML. Exclude any names that - // are already provided by the `trash_ids` property. - var allConfigCfNames = config - .SelectMany(c => c.Names) - .Distinct(StringComparer.CurrentCultureIgnoreCase) - .Where(n => !ProcessedCustomFormats.Any(cf => cf.CacheAwareName.EqualsIgnoreCase(n))) - .ToList(); - - // Perform updates and deletions based on matches in the cache. Matches in the cache are by ID. - foreach (var cf in processedCfs) - { - // Does the name of the CF in the guide match a name in the config? If yes, we keep it. - var configName = allConfigCfNames.FirstOrDefault(n => n.EqualsIgnoreCase(cf.Name)); - if (configName != null) - { - if (cf.CacheEntry != null) - { - // The cache entry might be using an old name. This will happen if: - // - A user has synced this CF before, AND - // - The name of the CF in the guide changed, AND - // - The user updated the name in their config to match the name in the guide. - cf.CacheEntry.CustomFormatName = cf.Name; - } - - _processedCustomFormats.Add(cf); - continue; - } - - // Does the name of the CF in the cache match a name in the config? If yes, we keep it. - configName = allConfigCfNames.FirstOrDefault(n => n.EqualsIgnoreCase(cf.CacheEntry?.CustomFormatName)); - if (configName != null) - { - // Config name is out of sync with the guide and should be updated - _customFormatsWithOutdatedNames.Add((configName, cf.Name)); - _processedCustomFormats.Add(cf); - } - - // If we get here, we can't find a match in the config using cache or guide name, so the user must have - // removed it from their config. This will get marked for deletion later. - } - // Orphaned entries in cache represent custom formats we need to delete. ProcessDeletedCustomFormats(cache); - - // Check for multiple custom formats with the same name in the guide data (e.g. "DoVi") - ProcessDuplicates(); - } - - private void ProcessDuplicates() - { - _duplicatedCustomFormats.Clear(); - _duplicatedCustomFormats.AddRange(ProcessedCustomFormats - .GroupBy(cf => cf.Name) - .Where(grp => grp.Count() > 1) - .ToDictionary(grp => grp.Key, grp => grp.ToList())); - - _processedCustomFormats.RemoveAll(cf => DuplicatedCustomFormats.ContainsKey(cf.Name)); } private static ProcessedCustomFormatData ProcessCustomFormatData(CustomFormatData cf, diff --git a/src/TrashLib/Services/CustomFormat/Processors/GuideSteps/ICustomFormatStep.cs b/src/TrashLib/Services/CustomFormat/Processors/GuideSteps/ICustomFormatStep.cs index 8815f523..9eb4ba77 100644 --- a/src/TrashLib/Services/CustomFormat/Processors/GuideSteps/ICustomFormatStep.cs +++ b/src/TrashLib/Services/CustomFormat/Processors/GuideSteps/ICustomFormatStep.cs @@ -8,8 +8,6 @@ public interface ICustomFormatStep { IReadOnlyCollection ProcessedCustomFormats { get; } IReadOnlyCollection DeletedCustomFormatsInCache { get; } - IReadOnlyCollection<(string, string)> CustomFormatsWithOutdatedNames { get; } - IDictionary> DuplicatedCustomFormats { get; } void Process(IList customFormatGuideData, IReadOnlyCollection config, CustomFormatCache? cache); diff --git a/src/TrashLib/Services/CustomFormat/Processors/IGuideProcessor.cs b/src/TrashLib/Services/CustomFormat/Processors/IGuideProcessor.cs index 871d35f7..14cb3f74 100644 --- a/src/TrashLib/Services/CustomFormat/Processors/IGuideProcessor.cs +++ b/src/TrashLib/Services/CustomFormat/Processors/IGuideProcessor.cs @@ -13,8 +13,6 @@ internal interface IGuideProcessor IDictionary ProfileScores { get; } IReadOnlyCollection<(string name, string trashId, string profileName)> CustomFormatsWithoutScore { get; } IReadOnlyCollection DeletedCustomFormatsInCache { get; } - IReadOnlyCollection<(string, string)> CustomFormatsWithOutdatedNames { get; } - IDictionary> DuplicatedCustomFormats { get; } IReadOnlyDictionary>> DuplicateScores { get; } Task BuildGuideDataAsync(IEnumerable config, CustomFormatCache? cache, diff --git a/src/TrashLib/Services/CustomFormat/Processors/PersistenceSteps/JsonTransactionStep.cs b/src/TrashLib/Services/CustomFormat/Processors/PersistenceSteps/JsonTransactionStep.cs index e6606ecb..d818da79 100644 --- a/src/TrashLib/Services/CustomFormat/Processors/PersistenceSteps/JsonTransactionStep.cs +++ b/src/TrashLib/Services/CustomFormat/Processors/PersistenceSteps/JsonTransactionStep.cs @@ -1,5 +1,4 @@ using System.Collections.ObjectModel; -using Common.Extensions; using Newtonsoft.Json.Linq; using TrashLib.Services.CustomFormat.Models; using TrashLib.Services.CustomFormat.Models.Cache; @@ -65,7 +64,7 @@ internal class JsonTransactionStep : IJsonTransactionStep // The 'Where' excludes cached CFs that were deleted manually by the user in Radarr // FindRadarrCf() specifies 'null' for name because we should never delete unless an ID is found foreach (var del in deletedCfsInCache.Where( - del => FindServiceCf(cfs, del.CustomFormatId, null) != null)) + del => FindServiceCf(cfs, del.CustomFormatId) != null)) { Transactions.DeletedCustomFormatIds.Add(del); } @@ -73,10 +72,10 @@ internal class JsonTransactionStep : IJsonTransactionStep private static JObject? FindServiceCf(IReadOnlyCollection serviceCfs, ProcessedCustomFormatData guideCf) { - return FindServiceCf(serviceCfs, guideCf.CacheEntry?.CustomFormatId, guideCf.Name); + return FindServiceCf(serviceCfs, guideCf.CacheEntry?.CustomFormatId); } - private static JObject? FindServiceCf(IReadOnlyCollection serviceCfs, int? cfId, string? cfName) + private static JObject? FindServiceCf(IReadOnlyCollection serviceCfs, int? cfId) { JObject? match = null; @@ -86,12 +85,6 @@ internal class JsonTransactionStep : IJsonTransactionStep match = serviceCfs.FirstOrDefault(rcf => cfId == rcf.Value("id")); } - // If we don't find by ID, search by name (if a name was given) - if (match == null && cfName != null) - { - match = serviceCfs.FirstOrDefault(rcf => cfName.EqualsIgnoreCase(rcf.Value("name"))); - } - return match; } diff --git a/src/TrashLib/Services/Radarr/Config/IRadarrValidationMessages.cs b/src/TrashLib/Services/Radarr/Config/IRadarrValidationMessages.cs index b54ebf39..45d70178 100644 --- a/src/TrashLib/Services/Radarr/Config/IRadarrValidationMessages.cs +++ b/src/TrashLib/Services/Radarr/Config/IRadarrValidationMessages.cs @@ -4,7 +4,7 @@ public interface IRadarrValidationMessages { string BaseUrl { get; } string ApiKey { get; } - string CustomFormatNamesAndIds { get; } + string CustomFormatTrashIds { get; } string QualityProfileName { get; } string QualityDefinitionType { get; } } diff --git a/src/TrashLib/Services/Radarr/Config/RadarrConfigurationValidator.cs b/src/TrashLib/Services/Radarr/Config/RadarrConfigurationValidator.cs index e901ed86..f37b611e 100644 --- a/src/TrashLib/Services/Radarr/Config/RadarrConfigurationValidator.cs +++ b/src/TrashLib/Services/Radarr/Config/RadarrConfigurationValidator.cs @@ -27,8 +27,7 @@ internal class CustomFormatConfigValidator : AbstractValidator qualityProfileConfigValidator) { - RuleFor(x => x.Names).NotEmpty().When(x => x.TrashIds.Count == 0) - .WithMessage(messages.CustomFormatNamesAndIds); + RuleFor(x => x.TrashIds).NotEmpty().WithMessage(messages.CustomFormatTrashIds); RuleForEach(x => x.QualityProfiles).SetValidator(qualityProfileConfigValidator); } } diff --git a/src/TrashLib/Services/Radarr/Config/RadarrValidationMessages.cs b/src/TrashLib/Services/Radarr/Config/RadarrValidationMessages.cs index 8cbd3411..23fd34a9 100644 --- a/src/TrashLib/Services/Radarr/Config/RadarrValidationMessages.cs +++ b/src/TrashLib/Services/Radarr/Config/RadarrValidationMessages.cs @@ -8,8 +8,8 @@ internal class RadarrValidationMessages : IRadarrValidationMessages public string ApiKey => "Property 'api_key' is required"; - public string CustomFormatNamesAndIds => - "'custom_formats' elements must contain at least one element in either 'names' or 'trash_ids'"; + public string CustomFormatTrashIds => + "'custom_formats' elements must contain at least one element under 'trash_ids'"; public string QualityProfileName => "'name' is required for elements under 'quality_profiles'";