From 42b11528b4699b8343887185c93a02b139192d83 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Fri, 26 Jan 2024 21:03:05 -0800 Subject: [PATCH] New: Improve multi-language negate Custom Format Closes #6408 --- .../MultiLanguageFixture.cs | 71 ++++++++++++++++ .../OriginalLanguageFixture.cs | 80 +++++++++++++++++++ .../SingleLanguageFixture.cs | 70 ++++++++++++++++ .../CustomFormatSpecificationBase.cs | 2 +- .../Specifications/LanguageSpecification.cs | 19 +++++ 5 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/MultiLanguageFixture.cs create mode 100644 src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/OriginalLanguageFixture.cs create mode 100644 src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/SingleLanguageFixture.cs diff --git a/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/MultiLanguageFixture.cs b/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/MultiLanguageFixture.cs new file mode 100644 index 000000000..5527610ed --- /dev/null +++ b/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/MultiLanguageFixture.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.CustomFormats; +using NzbDrone.Core.Languages; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Tv; + +namespace NzbDrone.Core.Test.CustomFormats.Specifications.LanguageSpecification +{ + [TestFixture] + public class MultiLanguageFixture : CoreTest + { + private CustomFormatInput _input; + + [SetUp] + public void Setup() + { + _input = new CustomFormatInput + { + EpisodeInfo = Builder.CreateNew().Build(), + Series = Builder.CreateNew().With(s => s.OriginalLanguage = Language.English).Build(), + Size = 100.Megabytes(), + Languages = new List + { + Language.English, + Language.French + }, + Filename = "Series.Title.S01E01" + }; + } + + [Test] + public void should_match_one_language() + { + Subject.Value = Language.French.Id; + Subject.Negate = false; + + Subject.IsSatisfiedBy(_input).Should().BeTrue(); + } + + [Test] + public void should_not_match_different_language() + { + Subject.Value = Language.Spanish.Id; + Subject.Negate = false; + + Subject.IsSatisfiedBy(_input).Should().BeFalse(); + } + + [Test] + public void should_not_match_negated_when_one_language_matches() + { + Subject.Value = Language.French.Id; + Subject.Negate = true; + + Subject.IsSatisfiedBy(_input).Should().BeFalse(); + } + + [Test] + public void should_not_match_negated_when_all_languages_do_not_match() + { + Subject.Value = Language.Spanish.Id; + Subject.Negate = true; + + Subject.IsSatisfiedBy(_input).Should().BeTrue(); + } + } +} diff --git a/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/OriginalLanguageFixture.cs b/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/OriginalLanguageFixture.cs new file mode 100644 index 000000000..33f2b65fc --- /dev/null +++ b/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/OriginalLanguageFixture.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; +using System.Linq; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.CustomFormats; +using NzbDrone.Core.Languages; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Tv; + +namespace NzbDrone.Core.Test.CustomFormats.Specifications.LanguageSpecification +{ + [TestFixture] + public class OriginalLanguageFixture : CoreTest + { + private CustomFormatInput _input; + + [SetUp] + public void Setup() + { + _input = new CustomFormatInput + { + EpisodeInfo = Builder.CreateNew().Build(), + Series = Builder.CreateNew().With(s => s.OriginalLanguage = Language.English).Build(), + Size = 100.Megabytes(), + Languages = new List + { + Language.French + }, + Filename = "Series.Title.S01E01" + }; + } + + public void GivenLanguages(params Language[] languages) + { + _input.Languages = languages.ToList(); + } + + [Test] + public void should_match_same_single_language() + { + GivenLanguages(Language.English); + + Subject.Value = Language.Original.Id; + Subject.Negate = false; + + Subject.IsSatisfiedBy(_input).Should().BeTrue(); + } + + [Test] + public void should_not_match_different_single_language() + { + Subject.Value = Language.Original.Id; + Subject.Negate = false; + + Subject.IsSatisfiedBy(_input).Should().BeFalse(); + } + + [Test] + public void should_not_match_negated_same_single_language() + { + GivenLanguages(Language.English); + + Subject.Value = Language.Original.Id; + Subject.Negate = true; + + Subject.IsSatisfiedBy(_input).Should().BeFalse(); + } + + [Test] + public void should_match_negated_different_single_language() + { + Subject.Value = Language.Original.Id; + Subject.Negate = true; + + Subject.IsSatisfiedBy(_input).Should().BeTrue(); + } + } +} diff --git a/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/SingleLanguageFixture.cs b/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/SingleLanguageFixture.cs new file mode 100644 index 000000000..6718057a2 --- /dev/null +++ b/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/SingleLanguageFixture.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.CustomFormats; +using NzbDrone.Core.Languages; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Tv; + +namespace NzbDrone.Core.Test.CustomFormats.Specifications.LanguageSpecification +{ + [TestFixture] + public class SingleLanguageFixture : CoreTest + { + private CustomFormatInput _input; + + [SetUp] + public void Setup() + { + _input = new CustomFormatInput + { + EpisodeInfo = Builder.CreateNew().Build(), + Series = Builder.CreateNew().With(s => s.OriginalLanguage = Language.English).Build(), + Size = 100.Megabytes(), + Languages = new List + { + Language.French + }, + Filename = "Series.Title.S01E01" + }; + } + + [Test] + public void should_match_same_language() + { + Subject.Value = Language.French.Id; + Subject.Negate = false; + + Subject.IsSatisfiedBy(_input).Should().BeTrue(); + } + + [Test] + public void should_not_match_different_language() + { + Subject.Value = Language.Spanish.Id; + Subject.Negate = false; + + Subject.IsSatisfiedBy(_input).Should().BeFalse(); + } + + [Test] + public void should_not_match_negated_same_language() + { + Subject.Value = Language.French.Id; + Subject.Negate = true; + + Subject.IsSatisfiedBy(_input).Should().BeFalse(); + } + + [Test] + public void should_match_negated_different_language() + { + Subject.Value = Language.Spanish.Id; + Subject.Negate = true; + + Subject.IsSatisfiedBy(_input).Should().BeTrue(); + } + } +} diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/CustomFormatSpecificationBase.cs b/src/NzbDrone.Core/CustomFormats/Specifications/CustomFormatSpecificationBase.cs index 7b2e2c0a3..fa0dbb80e 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/CustomFormatSpecificationBase.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/CustomFormatSpecificationBase.cs @@ -20,7 +20,7 @@ public ICustomFormatSpecification Clone() public abstract NzbDroneValidationResult Validate(); - public bool IsSatisfiedBy(CustomFormatInput input) + public virtual bool IsSatisfiedBy(CustomFormatInput input) { var match = IsSatisfiedByWithoutNegate(input); diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/LanguageSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/LanguageSpecification.cs index fcd5f5374..d841b7053 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/LanguageSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/LanguageSpecification.cs @@ -30,6 +30,16 @@ public class LanguageSpecification : CustomFormatSpecificationBase [FieldDefinition(1, Label = "CustomFormatsSpecificationLanguage", Type = FieldType.Select, SelectOptions = typeof(LanguageFieldConverter))] public int Value { get; set; } + public override bool IsSatisfiedBy(CustomFormatInput input) + { + if (Negate) + { + return IsSatisfiedByWithNegate(input); + } + + return IsSatisfiedByWithoutNegate(input); + } + protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input) { var comparedLanguage = input.EpisodeInfo != null && input.Series != null && Value == Language.Original.Id && input.Series.OriginalLanguage != Language.Unknown @@ -39,6 +49,15 @@ protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input) return input.Languages?.Contains(comparedLanguage) ?? false; } + private bool IsSatisfiedByWithNegate(CustomFormatInput input) + { + var comparedLanguage = input.EpisodeInfo != null && input.Series != null && Value == Language.Original.Id && input.Series.OriginalLanguage != Language.Unknown + ? input.Series.OriginalLanguage + : (Language)Value; + + return !input.Languages?.Contains(comparedLanguage) ?? false; + } + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this));