From 41f769790d55b66f5c23fe5b4f7afed2f4685dd2 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 11 Apr 2017 17:57:29 -0700 Subject: [PATCH] Fix issue adding a series when TitleSlug for another series is null Fixed: Adding a series when an existing series is has a null slug Closes #1840 --- .../NzbDrone.Core.Test.csproj | 1 + .../SeriesTitleSlugValidatorFixture.cs | 76 +++++++++++++++++++ .../Tv/SeriesTitleSlugValidator.cs | 9 ++- src/NzbDrone.Test.Common/App.config | 4 + .../NzbDrone.Test.Common.csproj | 4 + src/NzbDrone.Test.Common/TestValidator.cs | 16 ++++ src/NzbDrone.Test.Common/packages.config | 1 + 7 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 src/NzbDrone.Core.Test/TvTests/SeriesTitleSlugValidatorFixture.cs create mode 100644 src/NzbDrone.Test.Common/TestValidator.cs diff --git a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index f8e7b07c9..61dff5f73 100644 --- a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -383,6 +383,7 @@ + diff --git a/src/NzbDrone.Core.Test/TvTests/SeriesTitleSlugValidatorFixture.cs b/src/NzbDrone.Core.Test/TvTests/SeriesTitleSlugValidatorFixture.cs new file mode 100644 index 000000000..9cc7c435b --- /dev/null +++ b/src/NzbDrone.Core.Test/TvTests/SeriesTitleSlugValidatorFixture.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using System.Linq; +using FizzWare.NBuilder; +using FluentAssertions; +using FluentValidation.Validators; +using NUnit.Framework; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Tv; +using NzbDrone.Test.Common; + +namespace NzbDrone.Core.Test.TvTests +{ + [TestFixture] + public class SeriesTitleSlugValidatorFixture : CoreTest + { + private List _series; + private TestValidator _validator; + + [SetUp] + public void Setup() + { + _series = Builder.CreateListOfSize(1) + .Build() + .ToList(); + + _validator = new TestValidator + { + v => v.RuleFor(s => s.TitleSlug).SetValidator(Subject) + }; + + Mocker.GetMock() + .Setup(s => s.GetAllSeries()) + .Returns(_series); + } + + [Test] + public void should_not_be_valid_if_there_is_an_existing_series_with_the_same_title_slug() + { + var series = Builder.CreateNew() + .With(s => s.Id = 100) + .With(s => s.TitleSlug = _series.First().TitleSlug) + .Build(); + + _validator.Validate(series).IsValid.Should().BeFalse(); + } + + [Test] + public void should_be_valid_if_there_is_not_an_existing_series_with_the_same_title_slug() + { + var series = Builder.CreateNew() + .With(s => s.TitleSlug = "MyTitleSlug") + .Build(); + + _validator.Validate(series).IsValid.Should().BeTrue(); + } + + [Test] + public void should_be_valid_if_there_is_an_existing_series_with_a_null_title_slug() + { + _series.First().TitleSlug = null; + + var series = Builder.CreateNew() + .With(s => s.TitleSlug = "MyTitleSlug") + .Build(); + + _validator.Validate(series).IsValid.Should().BeTrue(); + } + + [Test] + public void should_be_valid_when_updating_an_existing_series() + { + _validator.Validate(_series.First().JsonClone()).IsValid.Should().BeTrue(); + } + } +} diff --git a/src/NzbDrone.Core/Tv/SeriesTitleSlugValidator.cs b/src/NzbDrone.Core/Tv/SeriesTitleSlugValidator.cs index 97ff29095..ce3d7ecbf 100644 --- a/src/NzbDrone.Core/Tv/SeriesTitleSlugValidator.cs +++ b/src/NzbDrone.Core/Tv/SeriesTitleSlugValidator.cs @@ -1,4 +1,6 @@ -using FluentValidation.Validators; +using System.Linq; +using FluentValidation.Validators; +using NzbDrone.Common.Extensions; namespace NzbDrone.Core.Tv { @@ -16,10 +18,13 @@ namespace NzbDrone.Core.Tv { if (context.PropertyValue == null) return true; + dynamic instance = context.ParentContext.InstanceToValidate; var instanceId = (int)instance.Id; - return !_seriesService.GetAllSeries().Exists(s => s.TitleSlug.Equals(context.PropertyValue.ToString()) && s.Id != instanceId); + return !_seriesService.GetAllSeries().Where(s => s.TitleSlug.IsNotNullOrWhiteSpace()) + .ToList() + .Exists(s => s.TitleSlug.Equals(context.PropertyValue.ToString()) && s.Id != instanceId); } } } diff --git a/src/NzbDrone.Test.Common/App.config b/src/NzbDrone.Test.Common/App.config index 886337c3a..c7a8ca18c 100644 --- a/src/NzbDrone.Test.Common/App.config +++ b/src/NzbDrone.Test.Common/App.config @@ -21,6 +21,10 @@ + + + + \ No newline at end of file diff --git a/src/NzbDrone.Test.Common/NzbDrone.Test.Common.csproj b/src/NzbDrone.Test.Common/NzbDrone.Test.Common.csproj index 08bf03d3f..addbe954c 100644 --- a/src/NzbDrone.Test.Common/NzbDrone.Test.Common.csproj +++ b/src/NzbDrone.Test.Common/NzbDrone.Test.Common.csproj @@ -43,6 +43,9 @@ ..\packages\FluentAssertions.4.19.0\lib\net40\FluentAssertions.Core.dll + + ..\packages\FluentValidation.6.2.1.0\lib\portable-net40+sl50+wp80+win8+wpa81\FluentValidation.dll + ..\packages\Newtonsoft.Json.9.0.1\lib\net40\Newtonsoft.Json.dll True @@ -94,6 +97,7 @@ + diff --git a/src/NzbDrone.Test.Common/TestValidator.cs b/src/NzbDrone.Test.Common/TestValidator.cs new file mode 100644 index 000000000..2801eb442 --- /dev/null +++ b/src/NzbDrone.Test.Common/TestValidator.cs @@ -0,0 +1,16 @@ +using System; +using FluentValidation; + +namespace NzbDrone.Test.Common +{ + public class TestValidator : InlineValidator + { + public TestValidator(params Action>[] actions) + { + foreach (var action in actions) + { + action(this); + } + } + } +} diff --git a/src/NzbDrone.Test.Common/packages.config b/src/NzbDrone.Test.Common/packages.config index ea89c79fc..2a00b679d 100644 --- a/src/NzbDrone.Test.Common/packages.config +++ b/src/NzbDrone.Test.Common/packages.config @@ -2,6 +2,7 @@ +