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 b80e32ec1..35aa38fdf 100644 --- a/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs +++ b/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs @@ -62,7 +62,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests } [TestCase("sonarr")] - [TestCase("sonarr@sonarr")] [TestCase("email.me")] [Ignore("Allowed coz some email servers allow arbitrary source, we probably need to support 'Name ' syntax")] public void should_not_be_valid_if_from_is_invalid(string email) @@ -73,7 +72,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests } [TestCase("sonarr")] - [TestCase("sonarr@sonarr")] [TestCase("email.me")] public void should_not_be_valid_if_to_is_invalid(string email) { @@ -83,7 +81,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests } [TestCase("sonarr")] - [TestCase("sonarr@sonarr")] [TestCase("email.me")] public void should_not_be_valid_if_cc_is_invalid(string email) { @@ -93,7 +90,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests } [TestCase("sonarr")] - [TestCase("sonarr@sonarr")] [TestCase("email.me")] 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 872e71b28..b9f9fa78d 100644 --- a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentDirectoryValidator.cs +++ b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentDirectoryValidator.cs @@ -17,8 +17,8 @@ namespace NzbDrone.Core.Download.Clients.rTorrent PathExistsValidator pathExistsValidator, MappedNetworkDriveValidator mappedNetworkDriveValidator) { - RuleFor(c => c.TvDirectory).Cascade(CascadeMode.StopOnFirstFailure) - .IsValidPath() + RuleFor(c => c.TvDirectory).Cascade(CascadeMode.Stop) + .IsValidPath() .SetValidator(rootFolderValidator) .SetValidator(mappedNetworkDriveValidator) .SetValidator(pathExistsValidator) diff --git a/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionExistsValidator.cs b/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionExistsValidator.cs index f7aa42763..88b4c0026 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/Organizer/FileNameValidation.cs b/src/NzbDrone.Core/Organizer/FileNameValidation.cs index 0ae7987f6..bcda9c884 100644 --- a/src/NzbDrone.Core/Organizer/FileNameValidation.cs +++ b/src/NzbDrone.Core/Organizer/FileNameValidation.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; @@ -66,96 +65,70 @@ namespace NzbDrone.Core.Organizer public class ValidStandardEpisodeFormatValidator : PropertyValidator { - public ValidStandardEpisodeFormatValidator() - : base("Must contain season and episode numbers OR Original Title") - { - } + protected override string GetDefaultMessageTemplate() => "Must contain season and episode numbers OR Original Title"; protected override bool IsValid(PropertyValidatorContext context) { - var value = context.PropertyValue as string; - - if (!FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) && - !FileNameValidation.OriginalTokenRegex.IsMatch(value)) + if (context.PropertyValue is not string value) { return false; } - return true; + return FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) || + FileNameValidation.OriginalTokenRegex.IsMatch(value); } } public class ValidDailyEpisodeFormatValidator : PropertyValidator { - public ValidDailyEpisodeFormatValidator() - : base("Must contain Air Date OR Season and Episode OR Original Title") - { - } + protected override string GetDefaultMessageTemplate() => "Must contain Air Date OR Season and Episode OR Original Title"; protected override bool IsValid(PropertyValidatorContext context) { - var value = context.PropertyValue as string; - - if (!FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) && - !FileNameBuilder.AirDateRegex.IsMatch(value) && - !FileNameValidation.OriginalTokenRegex.IsMatch(value)) + if (context.PropertyValue is not string value) { return false; } - return true; + return FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) || + FileNameBuilder.AirDateRegex.IsMatch(value) || + FileNameValidation.OriginalTokenRegex.IsMatch(value); } } public class ValidAnimeEpisodeFormatValidator : PropertyValidator { - public ValidAnimeEpisodeFormatValidator() - : base("Must contain Absolute Episode number OR Season and Episode OR Original Title") - { - } + protected override string GetDefaultMessageTemplate() => + "Must contain Absolute Episode number OR Season and Episode OR Original Title"; protected override bool IsValid(PropertyValidatorContext context) { - var value = context.PropertyValue as string; - - if (!FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) && - !FileNameBuilder.AbsoluteEpisodePatternRegex.IsMatch(value) && - !FileNameValidation.OriginalTokenRegex.IsMatch(value)) + if (context.PropertyValue is not string value) { return false; } - return true; + return FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) || + FileNameBuilder.AbsoluteEpisodePatternRegex.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/Sonarr.Core.csproj b/src/NzbDrone.Core/Sonarr.Core.csproj index 144fd96c5..68b3ddb17 100644 --- a/src/NzbDrone.Core/Sonarr.Core.csproj +++ b/src/NzbDrone.Core/Sonarr.Core.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/NzbDrone.Core/Tv/AddSeriesValidator.cs b/src/NzbDrone.Core/Tv/AddSeriesValidator.cs index a9d1e2e75..a4ab39a61 100644 --- a/src/NzbDrone.Core/Tv/AddSeriesValidator.cs +++ b/src/NzbDrone.Core/Tv/AddSeriesValidator.cs @@ -16,8 +16,8 @@ namespace NzbDrone.Core.Tv SeriesAncestorValidator seriesAncestorValidator, SeriesTitleSlugValidator seriesTitleSlugValidator) { - RuleFor(c => c.Path).Cascade(CascadeMode.StopOnFirstFailure) - .IsValidPath() + RuleFor(c => c.Path).Cascade(CascadeMode.Stop) + .IsValidPath() .SetValidator(rootFolderValidator) .SetValidator(seriesPathValidator) .SetValidator(seriesAncestorValidator); diff --git a/src/NzbDrone.Core/Tv/SeriesTitleSlugValidator.cs b/src/NzbDrone.Core/Tv/SeriesTitleSlugValidator.cs index 90664f00f..6a2a54baa 100644 --- a/src/NzbDrone.Core/Tv/SeriesTitleSlugValidator.cs +++ b/src/NzbDrone.Core/Tv/SeriesTitleSlugValidator.cs @@ -9,11 +9,13 @@ namespace NzbDrone.Core.Tv private readonly ISeriesService _seriesService; public SeriesTitleSlugValidator(ISeriesService seriesService) - : base("Title slug '{slug}' is in use by series '{seriesTitle}'. Check the FAQ for more information") { _seriesService = seriesService; } + protected override string GetDefaultMessageTemplate() => + "Title slug '{slug}' is in use by series '{seriesTitle}'. Check the FAQ for more information"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) 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 9d327b9c6..405fe14bd 100644 --- a/src/NzbDrone.Core/Validation/FolderValidator.cs +++ b/src/NzbDrone.Core/Validation/FolderValidator.cs @@ -6,10 +6,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/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 40ca0579f..831d0e2a7 100644 --- a/src/NzbDrone.Core/Validation/Paths/PathValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/PathValidator.cs @@ -15,10 +15,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/SeriesAncestorValidator.cs b/src/NzbDrone.Core/Validation/Paths/SeriesAncestorValidator.cs index 4df9466ea..401246d47 100644 --- a/src/NzbDrone.Core/Validation/Paths/SeriesAncestorValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/SeriesAncestorValidator.cs @@ -10,11 +10,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly ISeriesService _seriesService; public SeriesAncestorValidator(ISeriesService seriesService) - : base("Path is an ancestor of an existing series") { _seriesService = seriesService; } + protected override string GetDefaultMessageTemplate() => "Path is an ancestor of an existing series"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/SeriesExistsValidator.cs b/src/NzbDrone.Core/Validation/Paths/SeriesExistsValidator.cs index 337a53a3b..c53ea1182 100644 --- a/src/NzbDrone.Core/Validation/Paths/SeriesExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/SeriesExistsValidator.cs @@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly ISeriesService _seriesService; public SeriesExistsValidator(ISeriesService seriesService) - : base("This series has already been added") { _seriesService = seriesService; } + protected override string GetDefaultMessageTemplate() => "This series has already been added"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/SeriesPathValidator.cs b/src/NzbDrone.Core/Validation/Paths/SeriesPathValidator.cs index 2194913b2..5b1ff9373 100644 --- a/src/NzbDrone.Core/Validation/Paths/SeriesPathValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/SeriesPathValidator.cs @@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly ISeriesService _seriesService; public SeriesPathValidator(ISeriesService seriesService) - : base("Path is already configured for another series") { _seriesService = seriesService; } + protected override string GetDefaultMessageTemplate() => "Path is already configured for another series"; + 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/ProfileExistsValidator.cs b/src/NzbDrone.Core/Validation/ProfileExistsValidator.cs index 6970b875f..b8dceb294 100644 --- a/src/NzbDrone.Core/Validation/ProfileExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/ProfileExistsValidator.cs @@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation private readonly IQualityProfileService _qualityProfileService; public ProfileExistsValidator(IQualityProfileService qualityProfileService) - : base("QualityProfile does not exist") { _qualityProfileService = qualityProfileService; } + protected override string GetDefaultMessageTemplate() => "QualityProfile 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/Sonarr.Test.Common.csproj b/src/NzbDrone.Test.Common/Sonarr.Test.Common.csproj index 0fbe39105..bc5f721f6 100644 --- a/src/NzbDrone.Test.Common/Sonarr.Test.Common.csproj +++ b/src/NzbDrone.Test.Common/Sonarr.Test.Common.csproj @@ -4,7 +4,7 @@ - + diff --git a/src/Sonarr.Api.V3/Config/HostConfigController.cs b/src/Sonarr.Api.V3/Config/HostConfigController.cs index 7feb7c037..e138dcf01 100644 --- a/src/Sonarr.Api.V3/Config/HostConfigController.cs +++ b/src/Sonarr.Api.V3/Config/HostConfigController.cs @@ -51,7 +51,7 @@ namespace Sonarr.Api.V3.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/Sonarr.Api.V3/Profiles/Quality/QualityCutoffValidator.cs b/src/Sonarr.Api.V3/Profiles/Quality/QualityCutoffValidator.cs index 67bde6196..827391b16 100644 --- a/src/Sonarr.Api.V3/Profiles/Quality/QualityCutoffValidator.cs +++ b/src/Sonarr.Api.V3/Profiles/Quality/QualityCutoffValidator.cs @@ -15,10 +15,7 @@ namespace Sonarr.Api.V3.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) { @@ -26,19 +23,9 @@ namespace Sonarr.Api.V3.Profiles.Quality dynamic instance = context.ParentContext.InstanceToValidate; var items = instance.Items as IList; - var 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/Sonarr.Api.V3/Profiles/Quality/QualityItemsValidator.cs b/src/Sonarr.Api.V3/Profiles/Quality/QualityItemsValidator.cs index 3de76a16a..3db337213 100644 --- a/src/Sonarr.Api.V3/Profiles/Quality/QualityItemsValidator.cs +++ b/src/Sonarr.Api.V3/Profiles/Quality/QualityItemsValidator.cs @@ -23,139 +23,104 @@ namespace Sonarr.Api.V3.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/Sonarr.Api.V3/RemotePathMappings/RemotePathMappingController.cs b/src/Sonarr.Api.V3/RemotePathMappings/RemotePathMappingController.cs index c08a4eb6c..251b51e3f 100644 --- a/src/Sonarr.Api.V3/RemotePathMappings/RemotePathMappingController.cs +++ b/src/Sonarr.Api.V3/RemotePathMappings/RemotePathMappingController.cs @@ -28,8 +28,8 @@ namespace Sonarr.Api.V3.RemotePathMappings .NotEmpty(); SharedValidator.RuleFor(c => c.LocalPath) - .Cascade(CascadeMode.StopOnFirstFailure) - .IsValidPath() + .Cascade(CascadeMode.Stop) + .IsValidPath() .SetValidator(mappedNetworkDriveValidator) .SetValidator(pathExistsValidator); } diff --git a/src/Sonarr.Api.V3/RootFolders/RootFolderController.cs b/src/Sonarr.Api.V3/RootFolders/RootFolderController.cs index 701d79fa0..87abcb067 100644 --- a/src/Sonarr.Api.V3/RootFolders/RootFolderController.cs +++ b/src/Sonarr.Api.V3/RootFolders/RootFolderController.cs @@ -30,8 +30,8 @@ namespace Sonarr.Api.V3.RootFolders _rootFolderService = rootFolderService; SharedValidator.RuleFor(c => c.Path) - .Cascade(CascadeMode.StopOnFirstFailure) - .IsValidPath() + .Cascade(CascadeMode.Stop) + .IsValidPath() .SetValidator(rootFolderValidator) .SetValidator(mappedNetworkDriveValidator) .SetValidator(startupFolderValidator) diff --git a/src/Sonarr.Api.V3/Series/SeriesController.cs b/src/Sonarr.Api.V3/Series/SeriesController.cs index 06e80e855..b8a4c1c29 100644 --- a/src/Sonarr.Api.V3/Series/SeriesController.cs +++ b/src/Sonarr.Api.V3/Series/SeriesController.cs @@ -73,8 +73,8 @@ namespace Sonarr.Api.V3.Series Http.Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.QualityProfileId)); SharedValidator.RuleFor(s => s.Path) - .Cascade(CascadeMode.StopOnFirstFailure) - .IsValidPath() + .Cascade(CascadeMode.Stop) + .IsValidPath() .SetValidator(rootFolderValidator) .SetValidator(mappedNetworkDriveValidator) .SetValidator(seriesPathValidator) diff --git a/src/Sonarr.Api.V3/Series/SeriesFolderAsRootFolderValidator.cs b/src/Sonarr.Api.V3/Series/SeriesFolderAsRootFolderValidator.cs index 45d110a87..383d1d540 100644 --- a/src/Sonarr.Api.V3/Series/SeriesFolderAsRootFolderValidator.cs +++ b/src/Sonarr.Api.V3/Series/SeriesFolderAsRootFolderValidator.cs @@ -11,11 +11,12 @@ namespace Sonarr.Api.V3.Series private readonly IBuildFileNames _fileNameBuilder; public SeriesFolderAsRootFolderValidator(IBuildFileNames fileNameBuilder) - : base("Root folder path contains series folder") { _fileNameBuilder = fileNameBuilder; } + protected override string GetDefaultMessageTemplate() => "Root folder path contains series folder"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) @@ -23,7 +24,7 @@ namespace Sonarr.Api.V3.Series return true; } - var seriesResource = context.Instance as SeriesResource; + var seriesResource = context.InstanceToValidate as SeriesResource; if (seriesResource == null) { @@ -37,7 +38,7 @@ namespace Sonarr.Api.V3.Series return true; } - var rootFolder = new DirectoryInfo(rootFolderPath).Name; + var rootFolder = new DirectoryInfo(rootFolderPath!).Name; var series = seriesResource.ToModel(); var seriesFolder = _fileNameBuilder.GetSeriesFolder(series); diff --git a/src/Sonarr.Api.V3/Sonarr.Api.V3.csproj b/src/Sonarr.Api.V3/Sonarr.Api.V3.csproj index 2859afdad..332f902ee 100644 --- a/src/Sonarr.Api.V3/Sonarr.Api.V3.csproj +++ b/src/Sonarr.Api.V3/Sonarr.Api.V3.csproj @@ -3,7 +3,7 @@ net6.0 - + diff --git a/src/Sonarr.Http/REST/ResourceValidator.cs b/src/Sonarr.Http/REST/ResourceValidator.cs index a33d2ef3c..81f44d65b 100644 --- a/src/Sonarr.Http/REST/ResourceValidator.cs +++ b/src/Sonarr.Http/REST/ResourceValidator.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Linq.Expressions; using FluentValidation; using FluentValidation.Internal; -using FluentValidation.Resources; using Sonarr.Http.ClientSchema; namespace Sonarr.Http.REST @@ -15,7 +14,7 @@ namespace Sonarr.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 Sonarr.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/Sonarr.Http/Sonarr.Http.csproj b/src/Sonarr.Http/Sonarr.Http.csproj index 7f6619b81..6c0adc7d8 100644 --- a/src/Sonarr.Http/Sonarr.Http.csproj +++ b/src/Sonarr.Http/Sonarr.Http.csproj @@ -3,7 +3,7 @@ net6.0 - + diff --git a/src/Sonarr.Http/Validation/EmptyCollectionValidator.cs b/src/Sonarr.Http/Validation/EmptyCollectionValidator.cs index 91be1efcc..2ac7c1d05 100644 --- a/src/Sonarr.Http/Validation/EmptyCollectionValidator.cs +++ b/src/Sonarr.Http/Validation/EmptyCollectionValidator.cs @@ -6,10 +6,7 @@ namespace Sonarr.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/Sonarr.Http/Validation/RssSyncIntervalValidator.cs b/src/Sonarr.Http/Validation/RssSyncIntervalValidator.cs index 4e56e2923..54f329408 100644 --- a/src/Sonarr.Http/Validation/RssSyncIntervalValidator.cs +++ b/src/Sonarr.Http/Validation/RssSyncIntervalValidator.cs @@ -4,10 +4,7 @@ namespace Sonarr.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 Sonarr.Http.Validation return true; } - if (value >= 10 && value <= 120) - { - return true; - } - - return false; + return value is >= 10 and <= 120; } } } diff --git a/src/Sonarr.sln.DotSettings b/src/Sonarr.sln.DotSettings index fac9652d9..c44ed9723 100644 --- a/src/Sonarr.sln.DotSettings +++ b/src/Sonarr.sln.DotSettings @@ -1,2 +1,3 @@  - True \ No newline at end of file + True + True \ No newline at end of file