From ea0a78b62042bd3666a11946d5de75fcefb65894 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 17 Apr 2023 01:44:01 +0300 Subject: [PATCH] Fixed: Migrate to FluentValidation 9 --- src/Lidarr.Api.V1/Artist/ArtistController.cs | 2 +- .../Config/HostConfigController.cs | 2 +- src/Lidarr.Api.V1/Lidarr.Api.V1.csproj | 2 +- .../Profiles/Metadata/MetadataValidator.cs | 60 ++----------- .../Quality/QualityCutoffValidator.cs | 21 +---- .../Profiles/Quality/QualityItemsValidator.cs | 89 ++++++------------- .../RemotePathMappingController.cs | 2 +- .../RootFolders/RootFolderController.cs | 2 +- src/Lidarr.Http/Lidarr.Http.csproj | 2 +- src/Lidarr.Http/REST/ResourceValidator.cs | 10 +-- .../Validation/EmptyCollectionValidator.cs | 5 +- .../Validation/RssSyncIntervalValidator.cs | 12 +-- .../Extensions/UrlExtensions.cs | 13 +-- .../EmailSettingsValidatorFixture.cs | 5 -- .../rTorrent/RTorrentDirectoryValidator.cs | 14 +-- .../ImportListExclusionExistsValidator.cs | 3 +- src/NzbDrone.Core/Lidarr.Core.csproj | 2 +- .../Music/Utilities/AddArtistValidator.cs | 2 +- .../Organizer/FileNameValidation.cs | 31 ++----- .../Delay/DelayProfileTagInUseValidator.cs | 7 +- .../Validation/FileChmodValidator.cs | 3 +- .../Validation/FolderValidator.cs | 5 +- src/NzbDrone.Core/Validation/GuidValidator.cs | 5 +- .../MetadataProfileExistsValidator.cs | 3 +- .../Paths/ArtistAncestorValidator.cs | 3 +- .../Validation/Paths/ArtistExistsValidator.cs | 3 +- .../Validation/Paths/ArtistPathValidator.cs | 3 +- .../Validation/Paths/FileExistsValidator.cs | 3 +- .../Paths/FolderWritableValidator.cs | 3 +- .../Paths/MappedNetworkDriveValidator.cs | 10 +-- .../Validation/Paths/PathExistsValidator.cs | 3 +- .../Validation/Paths/PathValidator.cs | 5 +- .../Validation/Paths/RecycleBinValidator.cs | 3 +- .../Paths/RootFolderAncestorValidator.cs | 3 +- .../Validation/Paths/RootFolderValidator.cs | 3 +- .../Paths/StartupFolderValidator.cs | 3 +- .../Validation/Paths/SystemFolderValidator.cs | 5 +- .../QualityProfileExistsValidator.cs | 3 +- src/NzbDrone.Core/Validation/UrlValidator.cs | 5 +- .../Lidarr.Test.Common.csproj | 2 +- 40 files changed, 108 insertions(+), 254 deletions(-) diff --git a/src/Lidarr.Api.V1/Artist/ArtistController.cs b/src/Lidarr.Api.V1/Artist/ArtistController.cs index 23b481451..5ac36b7a8 100644 --- a/src/Lidarr.Api.V1/Artist/ArtistController.cs +++ b/src/Lidarr.Api.V1/Artist/ArtistController.cs @@ -78,7 +78,7 @@ namespace Lidarr.Api.V1.Artist Http.Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.MetadataProfileId)); SharedValidator.RuleFor(s => s.Path) - .Cascade(CascadeMode.StopOnFirstFailure) + .Cascade(CascadeMode.Stop) .IsValidPath() .SetValidator(rootFolderValidator) .SetValidator(mappedNetworkDriveValidator) diff --git a/src/Lidarr.Api.V1/Config/HostConfigController.cs b/src/Lidarr.Api.V1/Config/HostConfigController.cs index 5656288d1..d60280300 100644 --- a/src/Lidarr.Api.V1/Config/HostConfigController.cs +++ b/src/Lidarr.Api.V1/Config/HostConfigController.cs @@ -51,7 +51,7 @@ namespace Lidarr.Api.V1.Config SharedValidator.RuleFor(c => c.SslPort).NotEqual(c => c.Port).When(c => c.EnableSsl); SharedValidator.RuleFor(c => c.SslCertPath) - .Cascade(CascadeMode.StopOnFirstFailure) + .Cascade(CascadeMode.Stop) .NotEmpty() .IsValidPath() .SetValidator(fileExistsValidator) diff --git a/src/Lidarr.Api.V1/Lidarr.Api.V1.csproj b/src/Lidarr.Api.V1/Lidarr.Api.V1.csproj index 16e1a8fc3..ca4688cf5 100644 --- a/src/Lidarr.Api.V1/Lidarr.Api.V1.csproj +++ b/src/Lidarr.Api.V1/Lidarr.Api.V1.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/Lidarr.Api.V1/Profiles/Metadata/MetadataValidator.cs b/src/Lidarr.Api.V1/Profiles/Metadata/MetadataValidator.cs index 303af1c24..62bfd8891 100644 --- a/src/Lidarr.Api.V1/Profiles/Metadata/MetadataValidator.cs +++ b/src/Lidarr.Api.V1/Profiles/Metadata/MetadataValidator.cs @@ -31,76 +31,34 @@ namespace Lidarr.Api.V1.Profiles.Metadata public class PrimaryTypeValidator : PropertyValidator { - public PrimaryTypeValidator() - : base("Must have at least one allowed primary type") - { - } + protected override string GetDefaultMessageTemplate() => "Must have at least one allowed primary type"; protected override bool IsValid(PropertyValidatorContext context) { - var list = context.PropertyValue as IList; - - if (list == null) - { - return false; - } - - if (!list.Any(c => c.Allowed)) - { - return false; - } - - return true; + return context.PropertyValue is IList list && + list.Any(c => c.Allowed); } } public class SecondaryTypeValidator : PropertyValidator { - public SecondaryTypeValidator() - : base("Must have at least one allowed secondary type") - { - } + protected override string GetDefaultMessageTemplate() => "Must have at least one allowed secondary type"; protected override bool IsValid(PropertyValidatorContext context) { - var list = context.PropertyValue as IList; - - if (list == null) - { - return false; - } - - if (!list.Any(c => c.Allowed)) - { - return false; - } - - return true; + return context.PropertyValue is IList list && + list.Any(c => c.Allowed); } } public class ReleaseStatusValidator : PropertyValidator { - public ReleaseStatusValidator() - : base("Must have at least one allowed release status") - { - } + protected override string GetDefaultMessageTemplate() => "Must have at least one allowed release status"; protected override bool IsValid(PropertyValidatorContext context) { - var list = context.PropertyValue as IList; - - if (list == null) - { - return false; - } - - if (!list.Any(c => c.Allowed)) - { - return false; - } - - return true; + return context.PropertyValue is IList list && + list.Any(c => c.Allowed); } } } diff --git a/src/Lidarr.Api.V1/Profiles/Quality/QualityCutoffValidator.cs b/src/Lidarr.Api.V1/Profiles/Quality/QualityCutoffValidator.cs index f3c333e32..982bf860d 100644 --- a/src/Lidarr.Api.V1/Profiles/Quality/QualityCutoffValidator.cs +++ b/src/Lidarr.Api.V1/Profiles/Quality/QualityCutoffValidator.cs @@ -15,30 +15,17 @@ namespace Lidarr.Api.V1.Profiles.Quality public class ValidCutoffValidator : PropertyValidator { - public ValidCutoffValidator() - : base("Cutoff must be an allowed quality or group") - { - } + protected override string GetDefaultMessageTemplate() => "Cutoff must be an allowed quality or group"; protected override bool IsValid(PropertyValidatorContext context) { - int cutoff = (int)context.PropertyValue; + var cutoff = (int)context.PropertyValue; dynamic instance = context.ParentContext.InstanceToValidate; var items = instance.Items as IList; - QualityProfileQualityItemResource cutoffItem = items.SingleOrDefault(i => (i.Quality == null && i.Id == cutoff) || i.Quality?.Id == cutoff); - - if (cutoffItem == null) - { - return false; - } - - if (!cutoffItem.Allowed) - { - return false; - } + var cutoffItem = items?.SingleOrDefault(i => (i.Quality == null && i.Id == cutoff) || i.Quality?.Id == cutoff); - return true; + return cutoffItem is { Allowed: true }; } } } diff --git a/src/Lidarr.Api.V1/Profiles/Quality/QualityItemsValidator.cs b/src/Lidarr.Api.V1/Profiles/Quality/QualityItemsValidator.cs index 7e0ee12d1..772a18bb0 100644 --- a/src/Lidarr.Api.V1/Profiles/Quality/QualityItemsValidator.cs +++ b/src/Lidarr.Api.V1/Profiles/Quality/QualityItemsValidator.cs @@ -23,139 +23,104 @@ namespace Lidarr.Api.V1.Profiles.Quality public class AllowedValidator : PropertyValidator { - public AllowedValidator() - : base("Must contain at least one allowed quality") - { - } + protected override string GetDefaultMessageTemplate() => "Must contain at least one allowed quality"; protected override bool IsValid(PropertyValidatorContext context) { - var list = context.PropertyValue as IList; - - if (list == null) - { - return false; - } - - if (!list.Any(c => c.Allowed)) - { - return false; - } - - return true; + return context.PropertyValue is IList list && + list.Any(c => c.Allowed); } } public class GroupItemValidator : PropertyValidator { - public GroupItemValidator() - : base("Groups must contain multiple qualities") - { - } + protected override string GetDefaultMessageTemplate() => "Groups must contain multiple qualities"; protected override bool IsValid(PropertyValidatorContext context) { - var items = context.PropertyValue as IList; - - if (items.Any(i => i.Name.IsNotNullOrWhiteSpace() && i.Items.Count <= 1)) + if (context.PropertyValue is not IList items) { return false; } - return true; + return !items.Any(i => i.Name.IsNotNullOrWhiteSpace() && i.Items.Count <= 1); } } public class QualityNameValidator : PropertyValidator { - public QualityNameValidator() - : base("Individual qualities should not be named") - { - } + protected override string GetDefaultMessageTemplate() => "Individual qualities should not be named"; protected override bool IsValid(PropertyValidatorContext context) { - var items = context.PropertyValue as IList; - - if (items.Any(i => i.Name.IsNotNullOrWhiteSpace() && i.Quality != null)) + if (context.PropertyValue is not IList items) { return false; } - return true; + return !items.Any(i => i.Name.IsNotNullOrWhiteSpace() && i.Quality != null); } } public class ItemGroupNameValidator : PropertyValidator { - public ItemGroupNameValidator() - : base("Groups must have a name") - { - } + protected override string GetDefaultMessageTemplate() => "Groups must have a name"; protected override bool IsValid(PropertyValidatorContext context) { - var items = context.PropertyValue as IList; - - if (items.Any(i => i.Quality == null && i.Name.IsNullOrWhiteSpace())) + if (context.PropertyValue is not IList items) { return false; } - return true; + return !items.Any(i => i.Quality == null && i.Name.IsNullOrWhiteSpace()); } } public class ItemGroupIdValidator : PropertyValidator { - public ItemGroupIdValidator() - : base("Groups must have an ID") - { - } + protected override string GetDefaultMessageTemplate() => "Groups must have an ID"; protected override bool IsValid(PropertyValidatorContext context) { - var items = context.PropertyValue as IList; - - if (items.Any(i => i.Quality == null && i.Id == 0)) + if (context.PropertyValue is not IList items) { return false; } - return true; + return !items.Any(i => i.Quality == null && i.Id == 0); } } public class UniqueIdValidator : PropertyValidator { - public UniqueIdValidator() - : base("Groups must have a unique ID") - { - } + protected override string GetDefaultMessageTemplate() => "Groups must have a unique ID"; protected override bool IsValid(PropertyValidatorContext context) { - var items = context.PropertyValue as IList; - - if (items.Where(i => i.Id > 0).Select(i => i.Id).GroupBy(i => i).Any(g => g.Count() > 1)) + if (context.PropertyValue is not IList items) { return false; } - return true; + var ids = items.Where(i => i.Id > 0).Select(i => i.Id); + var groupedIds = ids.GroupBy(i => i); + + return groupedIds.All(g => g.Count() == 1); } } public class UniqueQualityIdValidator : PropertyValidator { - public UniqueQualityIdValidator() - : base("Qualities can only be used once") - { - } + protected override string GetDefaultMessageTemplate() => "Qualities can only be used once"; protected override bool IsValid(PropertyValidatorContext context) { - var items = context.PropertyValue as IList; + if (context.PropertyValue is not IList items) + { + return false; + } + var qualityIds = new HashSet(); foreach (var item in items) diff --git a/src/Lidarr.Api.V1/RemotePathMappings/RemotePathMappingController.cs b/src/Lidarr.Api.V1/RemotePathMappings/RemotePathMappingController.cs index bb32b336a..08be0a54f 100644 --- a/src/Lidarr.Api.V1/RemotePathMappings/RemotePathMappingController.cs +++ b/src/Lidarr.Api.V1/RemotePathMappings/RemotePathMappingController.cs @@ -28,7 +28,7 @@ namespace Lidarr.Api.V1.RemotePathMappings .NotEmpty(); SharedValidator.RuleFor(c => c.LocalPath) - .Cascade(CascadeMode.StopOnFirstFailure) + .Cascade(CascadeMode.Stop) .IsValidPath() .SetValidator(mappedNetworkDriveValidator) .SetValidator(pathExistsValidator); diff --git a/src/Lidarr.Api.V1/RootFolders/RootFolderController.cs b/src/Lidarr.Api.V1/RootFolders/RootFolderController.cs index 8d7473b4c..346e7d0ca 100644 --- a/src/Lidarr.Api.V1/RootFolders/RootFolderController.cs +++ b/src/Lidarr.Api.V1/RootFolders/RootFolderController.cs @@ -32,7 +32,7 @@ namespace Lidarr.Api.V1.RootFolders _rootFolderService = rootFolderService; SharedValidator.RuleFor(c => c.Path) - .Cascade(CascadeMode.StopOnFirstFailure) + .Cascade(CascadeMode.Stop) .IsValidPath() .SetValidator(mappedNetworkDriveValidator) .SetValidator(startupFolderValidator) diff --git a/src/Lidarr.Http/Lidarr.Http.csproj b/src/Lidarr.Http/Lidarr.Http.csproj index 99ef46bc2..5633a8174 100644 --- a/src/Lidarr.Http/Lidarr.Http.csproj +++ b/src/Lidarr.Http/Lidarr.Http.csproj @@ -3,7 +3,7 @@ net6.0 - + diff --git a/src/Lidarr.Http/REST/ResourceValidator.cs b/src/Lidarr.Http/REST/ResourceValidator.cs index 6ead3ab48..fd7394f6a 100644 --- a/src/Lidarr.Http/REST/ResourceValidator.cs +++ b/src/Lidarr.Http/REST/ResourceValidator.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Linq.Expressions; using FluentValidation; using FluentValidation.Internal; -using FluentValidation.Resources; using Lidarr.Http.ClientSchema; namespace Lidarr.Http.REST @@ -15,7 +14,7 @@ namespace Lidarr.Http.REST { var rule = new PropertyRule(fieldListAccessor.GetMember(), c => GetValue(c, fieldListAccessor.Compile(), fieldName), null, () => CascadeMode.Continue, typeof(TProperty), typeof(TResource)); rule.PropertyName = fieldName; - rule.DisplayName = new StaticStringSource(fieldName); + rule.SetDisplayName(fieldName); AddRule(rule); return new RuleBuilder(rule, this); @@ -25,12 +24,7 @@ namespace Lidarr.Http.REST { var resource = fieldListAccessor((TResource)container).SingleOrDefault(c => c.Name == fieldName); - if (resource == null) - { - return null; - } - - return resource.Value; + return resource?.Value; } } } diff --git a/src/Lidarr.Http/Validation/EmptyCollectionValidator.cs b/src/Lidarr.Http/Validation/EmptyCollectionValidator.cs index 735f766a7..24ebeeb7d 100644 --- a/src/Lidarr.Http/Validation/EmptyCollectionValidator.cs +++ b/src/Lidarr.Http/Validation/EmptyCollectionValidator.cs @@ -6,10 +6,7 @@ namespace Lidarr.Http.Validation { public class EmptyCollectionValidator : PropertyValidator { - public EmptyCollectionValidator() - : base("Collection Must Be Empty") - { - } + protected override string GetDefaultMessageTemplate() => "Collection Must Be Empty"; protected override bool IsValid(PropertyValidatorContext context) { diff --git a/src/Lidarr.Http/Validation/RssSyncIntervalValidator.cs b/src/Lidarr.Http/Validation/RssSyncIntervalValidator.cs index 797103b2b..678c6a826 100644 --- a/src/Lidarr.Http/Validation/RssSyncIntervalValidator.cs +++ b/src/Lidarr.Http/Validation/RssSyncIntervalValidator.cs @@ -4,10 +4,7 @@ namespace Lidarr.Http.Validation { public class RssSyncIntervalValidator : PropertyValidator { - public RssSyncIntervalValidator() - : base("Must be between 10 and 120 or 0 to disable") - { - } + protected override string GetDefaultMessageTemplate() => "Must be between 10 and 120 or 0 to disable"; protected override bool IsValid(PropertyValidatorContext context) { @@ -23,12 +20,7 @@ namespace Lidarr.Http.Validation return true; } - if (value >= 10 && value <= 120) - { - return true; - } - - return false; + return value is >= 10 and <= 120; } } } diff --git a/src/NzbDrone.Common/Extensions/UrlExtensions.cs b/src/NzbDrone.Common/Extensions/UrlExtensions.cs index e44843838..d71cfec15 100644 --- a/src/NzbDrone.Common/Extensions/UrlExtensions.cs +++ b/src/NzbDrone.Common/Extensions/UrlExtensions.cs @@ -16,18 +16,7 @@ namespace NzbDrone.Common.Extensions return false; } - Uri uri; - if (!Uri.TryCreate(path, UriKind.Absolute, out uri)) - { - return false; - } - - if (!uri.IsWellFormedOriginalString()) - { - return false; - } - - return true; + return Uri.TryCreate(path, UriKind.Absolute, out var uri) && uri.IsWellFormedOriginalString(); } } } diff --git a/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs index fb55f16cb..e6a5c25d7 100644 --- a/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs +++ b/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs @@ -40,7 +40,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests public void should_not_be_valid_if_port_is_out_of_range() { _emailSettings.Port = 900000; - _validator.Validate(_emailSettings).IsValid.Should().BeFalse(); } @@ -48,7 +47,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests public void should_not_be_valid_if_server_is_empty() { _emailSettings.Server = ""; - _validator.Validate(_emailSettings).IsValid.Should().BeFalse(); } @@ -61,7 +59,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests } [TestCase("lidarr")] - [TestCase("lidarr@lidarr")] [TestCase("lidarr.audio")] public void should_not_be_valid_if_to_is_invalid(string email) { @@ -71,7 +68,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests } [TestCase("lidarr")] - [TestCase("lidarr@lidarr")] [TestCase("lidarr.audio")] public void should_not_be_valid_if_cc_is_invalid(string email) { @@ -81,7 +77,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests } [TestCase("lidarr")] - [TestCase("lidarr@lidarr")] [TestCase("lidarr.audio")] public void should_not_be_valid_if_bcc_is_invalid(string email) { diff --git a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentDirectoryValidator.cs b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentDirectoryValidator.cs index cc652c7f8..aa472aa34 100644 --- a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentDirectoryValidator.cs +++ b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentDirectoryValidator.cs @@ -17,13 +17,13 @@ namespace NzbDrone.Core.Download.Clients.rTorrent PathExistsValidator pathExistsValidator, MappedNetworkDriveValidator mappedNetworkDriveValidator) { - RuleFor(c => c.MusicDirectory).Cascade(CascadeMode.StopOnFirstFailure) - .IsValidPath() - .SetValidator(rootFolderValidator) - .SetValidator(mappedNetworkDriveValidator) - .SetValidator(pathExistsValidator) - .When(c => c.MusicDirectory.IsNotNullOrWhiteSpace()) - .When(c => c.Host == "localhost" || c.Host == "127.0.0.1"); + RuleFor(c => c.MusicDirectory).Cascade(CascadeMode.Stop) + .IsValidPath() + .SetValidator(rootFolderValidator) + .SetValidator(mappedNetworkDriveValidator) + .SetValidator(pathExistsValidator) + .When(c => c.MusicDirectory.IsNotNullOrWhiteSpace()) + .When(c => c.Host == "localhost" || c.Host == "127.0.0.1"); } } } diff --git a/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionExistsValidator.cs b/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionExistsValidator.cs index 7911eb713..2883f473a 100644 --- a/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionExistsValidator.cs +++ b/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionExistsValidator.cs @@ -7,11 +7,12 @@ namespace NzbDrone.Core.ImportLists.Exclusions private readonly IImportListExclusionService _importListExclusionService; public ImportListExclusionExistsValidator(IImportListExclusionService importListExclusionService) - : base("This exclusion has already been added.") { _importListExclusionService = importListExclusionService; } + protected override string GetDefaultMessageTemplate() => "This exclusion has already been added."; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Lidarr.Core.csproj b/src/NzbDrone.Core/Lidarr.Core.csproj index 8b972475a..572803e2c 100644 --- a/src/NzbDrone.Core/Lidarr.Core.csproj +++ b/src/NzbDrone.Core/Lidarr.Core.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/NzbDrone.Core/Music/Utilities/AddArtistValidator.cs b/src/NzbDrone.Core/Music/Utilities/AddArtistValidator.cs index 77287c780..4e34fa6c6 100644 --- a/src/NzbDrone.Core/Music/Utilities/AddArtistValidator.cs +++ b/src/NzbDrone.Core/Music/Utilities/AddArtistValidator.cs @@ -19,7 +19,7 @@ namespace NzbDrone.Core.Music QualityProfileExistsValidator qualityProfileExistsValidator, MetadataProfileExistsValidator metadataProfileExistsValidator) { - RuleFor(c => c.Path).Cascade(CascadeMode.StopOnFirstFailure) + RuleFor(c => c.Path).Cascade(CascadeMode.Stop) .IsValidPath() .SetValidator(rootFolderValidator) .SetValidator(recycleBinValidator) diff --git a/src/NzbDrone.Core/Organizer/FileNameValidation.cs b/src/NzbDrone.Core/Organizer/FileNameValidation.cs index fb59d38de..6634e3601 100644 --- a/src/NzbDrone.Core/Organizer/FileNameValidation.cs +++ b/src/NzbDrone.Core/Organizer/FileNameValidation.cs @@ -41,53 +41,36 @@ namespace NzbDrone.Core.Organizer public class ValidStandardTrackFormatValidator : PropertyValidator { - public ValidStandardTrackFormatValidator() - : base("Must contain Track Title and Track numbers OR Original Title") - { - } + protected override string GetDefaultMessageTemplate() => "Must contain Track Title and Track numbers OR Original Title"; protected override bool IsValid(PropertyValidatorContext context) { - var value = context.PropertyValue as string; - - if (!(FileNameBuilder.TrackTitleRegex.IsMatch(value) && - FileNameBuilder.TrackRegex.IsMatch(value)) && - !FileNameValidation.OriginalTokenRegex.IsMatch(value)) + if (context.PropertyValue is not string value) { return false; } - return true; + return (FileNameBuilder.TrackTitleRegex.IsMatch(value) && FileNameBuilder.TrackRegex.IsMatch(value)) || + FileNameValidation.OriginalTokenRegex.IsMatch(value); } } public class IllegalCharactersValidator : PropertyValidator { - private readonly char[] _invalidPathChars = Path.GetInvalidPathChars(); + private static readonly char[] InvalidPathChars = Path.GetInvalidPathChars(); - public IllegalCharactersValidator() - : base("Contains illegal characters: {InvalidCharacters}") - { - } + protected override string GetDefaultMessageTemplate() => "Contains illegal characters: {InvalidCharacters}"; protected override bool IsValid(PropertyValidatorContext context) { var value = context.PropertyValue as string; - var invalidCharacters = new List(); if (value.IsNullOrWhiteSpace()) { return true; } - foreach (var i in _invalidPathChars) - { - if (value.IndexOf(i) >= 0) - { - invalidCharacters.Add(i); - } - } - + var invalidCharacters = InvalidPathChars.Where(i => value!.IndexOf(i) >= 0).ToList(); if (invalidCharacters.Any()) { context.MessageFormatter.AppendArgument("InvalidCharacters", string.Join("", invalidCharacters)); diff --git a/src/NzbDrone.Core/Profiles/Delay/DelayProfileTagInUseValidator.cs b/src/NzbDrone.Core/Profiles/Delay/DelayProfileTagInUseValidator.cs index cfd08a2f4..124d75e54 100644 --- a/src/NzbDrone.Core/Profiles/Delay/DelayProfileTagInUseValidator.cs +++ b/src/NzbDrone.Core/Profiles/Delay/DelayProfileTagInUseValidator.cs @@ -10,11 +10,12 @@ namespace NzbDrone.Core.Profiles.Delay private readonly IDelayProfileService _delayProfileService; public DelayProfileTagInUseValidator(IDelayProfileService delayProfileService) - : base("One or more tags is used in another profile") { _delayProfileService = delayProfileService; } + protected override string GetDefaultMessageTemplate() => "One or more tags is used in another profile"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) @@ -25,9 +26,7 @@ namespace NzbDrone.Core.Profiles.Delay dynamic instance = context.ParentContext.InstanceToValidate; var instanceId = (int)instance.Id; - var collection = context.PropertyValue as HashSet; - - if (collection == null || collection.Empty()) + if (context.PropertyValue is not HashSet collection || collection.Empty()) { return true; } diff --git a/src/NzbDrone.Core/Validation/FileChmodValidator.cs b/src/NzbDrone.Core/Validation/FileChmodValidator.cs index 3e90bf9fa..5677526af 100644 --- a/src/NzbDrone.Core/Validation/FileChmodValidator.cs +++ b/src/NzbDrone.Core/Validation/FileChmodValidator.cs @@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation private readonly IDiskProvider _diskProvider; public FolderChmodValidator(IDiskProvider diskProvider) - : base("Must contain a valid Unix permissions octal") { _diskProvider = diskProvider; } + protected override string GetDefaultMessageTemplate() => "Must contain a valid Unix permissions octal"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/FolderValidator.cs b/src/NzbDrone.Core/Validation/FolderValidator.cs index 9eedeb459..6f88c9009 100644 --- a/src/NzbDrone.Core/Validation/FolderValidator.cs +++ b/src/NzbDrone.Core/Validation/FolderValidator.cs @@ -5,10 +5,7 @@ namespace NzbDrone.Core.Validation { public class FolderValidator : PropertyValidator { - public FolderValidator() - : base("Invalid Path") - { - } + protected override string GetDefaultMessageTemplate() => "Invalid Path"; protected override bool IsValid(PropertyValidatorContext context) { diff --git a/src/NzbDrone.Core/Validation/GuidValidator.cs b/src/NzbDrone.Core/Validation/GuidValidator.cs index 92fd53ad3..152a06fd5 100644 --- a/src/NzbDrone.Core/Validation/GuidValidator.cs +++ b/src/NzbDrone.Core/Validation/GuidValidator.cs @@ -5,10 +5,7 @@ namespace NzbDrone.Core.Validation { public class GuidValidator : PropertyValidator { - public GuidValidator() - : base("String is not a valid Guid") - { - } + protected override string GetDefaultMessageTemplate() => "String is not a valid Guid"; protected override bool IsValid(PropertyValidatorContext context) { diff --git a/src/NzbDrone.Core/Validation/MetadataProfileExistsValidator.cs b/src/NzbDrone.Core/Validation/MetadataProfileExistsValidator.cs index 8fd3e96d4..328d7f8c3 100644 --- a/src/NzbDrone.Core/Validation/MetadataProfileExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/MetadataProfileExistsValidator.cs @@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation private readonly IMetadataProfileService _profileService; public MetadataProfileExistsValidator(IMetadataProfileService profileService) - : base("Metadata profile does not exist") { _profileService = profileService; } + protected override string GetDefaultMessageTemplate() => "Metadata profile does not exist"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/ArtistAncestorValidator.cs b/src/NzbDrone.Core/Validation/Paths/ArtistAncestorValidator.cs index 01ba3996c..fae6cb5a7 100644 --- a/src/NzbDrone.Core/Validation/Paths/ArtistAncestorValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/ArtistAncestorValidator.cs @@ -10,11 +10,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IArtistService _artistService; public ArtistAncestorValidator(IArtistService artistService) - : base("Path is an ancestor of an existing artist") { _artistService = artistService; } + protected override string GetDefaultMessageTemplate() => "Path is an ancestor of an existing artist"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/ArtistExistsValidator.cs b/src/NzbDrone.Core/Validation/Paths/ArtistExistsValidator.cs index e17a8ab16..138f444c3 100644 --- a/src/NzbDrone.Core/Validation/Paths/ArtistExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/ArtistExistsValidator.cs @@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IArtistService _artistService; public ArtistExistsValidator(IArtistService artistService) - : base("This artist has already been added.") { _artistService = artistService; } + protected override string GetDefaultMessageTemplate() => "This artist has already been added."; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/ArtistPathValidator.cs b/src/NzbDrone.Core/Validation/Paths/ArtistPathValidator.cs index 824974e37..4c96b9666 100644 --- a/src/NzbDrone.Core/Validation/Paths/ArtistPathValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/ArtistPathValidator.cs @@ -10,11 +10,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IArtistService _artistService; public ArtistPathValidator(IArtistService artistService) - : base("Path is already configured for an existing artist") { _artistService = artistService; } + protected override string GetDefaultMessageTemplate() => "Path is already configured for an existing artist"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/FileExistsValidator.cs b/src/NzbDrone.Core/Validation/Paths/FileExistsValidator.cs index 9adb200aa..02e2aef81 100644 --- a/src/NzbDrone.Core/Validation/Paths/FileExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/FileExistsValidator.cs @@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IDiskProvider _diskProvider; public FileExistsValidator(IDiskProvider diskProvider) - : base("File does not exist") { _diskProvider = diskProvider; } + protected override string GetDefaultMessageTemplate() => "File does not exist"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/FolderWritableValidator.cs b/src/NzbDrone.Core/Validation/Paths/FolderWritableValidator.cs index c58b5a273..6838b3ea6 100644 --- a/src/NzbDrone.Core/Validation/Paths/FolderWritableValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/FolderWritableValidator.cs @@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IDiskProvider _diskProvider; public FolderWritableValidator(IDiskProvider diskProvider) - : base($"Folder is not writable by user {Environment.UserName}") { _diskProvider = diskProvider; } + protected override string GetDefaultMessageTemplate() => $"Folder is not writable by user {Environment.UserName}"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/MappedNetworkDriveValidator.cs b/src/NzbDrone.Core/Validation/Paths/MappedNetworkDriveValidator.cs index 48e3da21e..2476800ce 100644 --- a/src/NzbDrone.Core/Validation/Paths/MappedNetworkDriveValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/MappedNetworkDriveValidator.cs @@ -14,12 +14,13 @@ namespace NzbDrone.Core.Validation.Paths private static readonly Regex DriveRegex = new Regex(@"[a-z]\:\\", RegexOptions.Compiled | RegexOptions.IgnoreCase); public MappedNetworkDriveValidator(IRuntimeInfo runtimeInfo, IDiskProvider diskProvider) - : base("Mapped Network Drive and Windows Service") { _runtimeInfo = runtimeInfo; _diskProvider = diskProvider; } + protected override string GetDefaultMessageTemplate() => "Mapped Network Drive and Windows Service"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) @@ -46,12 +47,7 @@ namespace NzbDrone.Core.Validation.Paths var mount = _diskProvider.GetMount(path); - if (mount != null && mount.DriveType == DriveType.Network) - { - return false; - } - - return true; + return mount is not { DriveType: DriveType.Network }; } } } diff --git a/src/NzbDrone.Core/Validation/Paths/PathExistsValidator.cs b/src/NzbDrone.Core/Validation/Paths/PathExistsValidator.cs index 77398b5e8..91493482f 100644 --- a/src/NzbDrone.Core/Validation/Paths/PathExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/PathExistsValidator.cs @@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IDiskProvider _diskProvider; public PathExistsValidator(IDiskProvider diskProvider) - : base("Path does not exist") { _diskProvider = diskProvider; } + protected override string GetDefaultMessageTemplate() => "Path does not exist"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/PathValidator.cs b/src/NzbDrone.Core/Validation/Paths/PathValidator.cs index c546d3e79..fe0b496ed 100644 --- a/src/NzbDrone.Core/Validation/Paths/PathValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/PathValidator.cs @@ -14,10 +14,7 @@ namespace NzbDrone.Core.Validation.Paths public class PathValidator : PropertyValidator { - public PathValidator() - : base("Invalid Path") - { - } + protected override string GetDefaultMessageTemplate() => "Invalid Path"; protected override bool IsValid(PropertyValidatorContext context) { diff --git a/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs b/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs index a8a714fe6..1299b72ac 100644 --- a/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs @@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IConfigService _configService; public RecycleBinValidator(IConfigService configService) - : base("Path is {relationship} configured recycle bin folder") { _configService = configService; } + protected override string GetDefaultMessageTemplate() => "Path is {relationship} configured recycle bin folder"; + protected override bool IsValid(PropertyValidatorContext context) { var recycleBin = _configService.RecycleBin; diff --git a/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs b/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs index 19f0800b5..1b7dd0bfa 100644 --- a/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs @@ -10,11 +10,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IRootFolderService _rootFolderService; public RootFolderAncestorValidator(IRootFolderService rootFolderService) - : base("Path is an ancestor of an existing root folder") { _rootFolderService = rootFolderService; } + protected override string GetDefaultMessageTemplate() => "Path is an ancestor of an existing root folder"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/RootFolderValidator.cs b/src/NzbDrone.Core/Validation/Paths/RootFolderValidator.cs index 8494ac28b..7ceffdd7a 100644 --- a/src/NzbDrone.Core/Validation/Paths/RootFolderValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/RootFolderValidator.cs @@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IRootFolderService _rootFolderService; public RootFolderValidator(IRootFolderService rootFolderService) - : base("Path is already configured as a root folder") { _rootFolderService = rootFolderService; } + protected override string GetDefaultMessageTemplate() => "Path is already configured as a root folder"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/StartupFolderValidator.cs b/src/NzbDrone.Core/Validation/Paths/StartupFolderValidator.cs index 9f097f8d2..0243923f1 100644 --- a/src/NzbDrone.Core/Validation/Paths/StartupFolderValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/StartupFolderValidator.cs @@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IAppFolderInfo _appFolderInfo; public StartupFolderValidator(IAppFolderInfo appFolderInfo) - : base("Path cannot be {relationship} the start up folder") { _appFolderInfo = appFolderInfo; } + protected override string GetDefaultMessageTemplate() => "Path cannot be {relationship} the start up folder"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/SystemFolderValidator.cs b/src/NzbDrone.Core/Validation/Paths/SystemFolderValidator.cs index d8f3a7f15..6b891394e 100644 --- a/src/NzbDrone.Core/Validation/Paths/SystemFolderValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/SystemFolderValidator.cs @@ -6,10 +6,7 @@ namespace NzbDrone.Core.Validation.Paths { public class SystemFolderValidator : PropertyValidator { - public SystemFolderValidator() - : base("Is {relationship} system folder {systemFolder}") - { - } + protected override string GetDefaultMessageTemplate() => "Is {relationship} system folder {systemFolder}"; protected override bool IsValid(PropertyValidatorContext context) { diff --git a/src/NzbDrone.Core/Validation/QualityProfileExistsValidator.cs b/src/NzbDrone.Core/Validation/QualityProfileExistsValidator.cs index ba22b3174..f6aae29f8 100644 --- a/src/NzbDrone.Core/Validation/QualityProfileExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/QualityProfileExistsValidator.cs @@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation private readonly IQualityProfileService _profileService; public QualityProfileExistsValidator(IQualityProfileService profileService) - : base("Quality Profile does not exist") { _profileService = profileService; } + protected override string GetDefaultMessageTemplate() => "Quality Profile does not exist"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/UrlValidator.cs b/src/NzbDrone.Core/Validation/UrlValidator.cs index 844ab80f2..8588b4848 100644 --- a/src/NzbDrone.Core/Validation/UrlValidator.cs +++ b/src/NzbDrone.Core/Validation/UrlValidator.cs @@ -14,10 +14,7 @@ namespace NzbDrone.Core.Validation public class UrlValidator : PropertyValidator { - public UrlValidator() - : base("Invalid Url") - { - } + protected override string GetDefaultMessageTemplate() => "Invalid Url"; protected override bool IsValid(PropertyValidatorContext context) { diff --git a/src/NzbDrone.Test.Common/Lidarr.Test.Common.csproj b/src/NzbDrone.Test.Common/Lidarr.Test.Common.csproj index 68749c7b0..2df882ffb 100644 --- a/src/NzbDrone.Test.Common/Lidarr.Test.Common.csproj +++ b/src/NzbDrone.Test.Common/Lidarr.Test.Common.csproj @@ -4,7 +4,7 @@ - +