diff --git a/src/BookingsDomain/Events.cs b/src/BookingsDomain/Events.cs
index c2df573e..aff0e435 100644
--- a/src/BookingsDomain/Events.cs
+++ b/src/BookingsDomain/Events.cs
@@ -24,9 +24,9 @@ public static Created Create(Identifier id, Identifier organizationId)
public required DateTime OccurredUtc { get; set; }
}
-#pragma warning disable SAS063
+#pragma warning disable SAASDDD043
public sealed class ReservationMade : IDomainEvent
-#pragma warning restore SAS063
+#pragma warning restore SAASDDD043
{
public static ReservationMade Create(Identifier id, Identifier organizationId, Identifier borrowerId,
DateTime start, DateTime end)
@@ -99,9 +99,9 @@ public static TripAdded Create(Identifier id, Identifier organizationId)
public required DateTime OccurredUtc { get; set; }
}
-#pragma warning disable SAS063
+#pragma warning disable SAASDDD043
public sealed class TripBegan : IDomainEvent
-#pragma warning restore SAS063
+#pragma warning restore SAASDDD043
{
public static TripBegan Create(Identifier id, Identifier organizationId, Identifier tripId,
DateTime beganAt, Location from)
diff --git a/src/SaaStack.sln.DotSettings b/src/SaaStack.sln.DotSettings
index bc2606b1..fe01bcd7 100644
--- a/src/SaaStack.sln.DotSettings
+++ b/src/SaaStack.sln.DotSettings
@@ -1079,6 +1079,10 @@ public void When$condition$_Then$outcome$()
True
True
True
+ True
+ True
+ True
+ True
True
True
True
diff --git a/src/Tools.Analyzers.Common/AnalyzerConstants.cs b/src/Tools.Analyzers.Common/AnalyzerConstants.cs
index 5b443776..3c760ba6 100644
--- a/src/Tools.Analyzers.Common/AnalyzerConstants.cs
+++ b/src/Tools.Analyzers.Common/AnalyzerConstants.cs
@@ -2,6 +2,10 @@ namespace Tools.Analyzers.Common;
public static class AnalyzerConstants
{
+ public const string ServiceOperationTypesNamespace = "Infrastructure.Web.Api.Operations.Shared";
+ public const string ResourceTypesNamespace = "Application.Resources.Shared";
+ public const string RequestTypeSuffix = "Request";
+ public const string ResponseTypeSuffix = "Response";
public static readonly string[] PlatformNamespaces =
{
#if TESTINGONLY
@@ -19,13 +23,11 @@ public static class AnalyzerConstants
"IntegrationTesting.WebApi.Common", "UnitTesting.Common"
};
- public const string ResourceTypesNamespace = "Application.Resources.Shared";
-
public static class Categories
{
+ public const string Application = "SaaStackApplication";
public const string Ddd = "SaaStackDDD";
public const string Documentation = "SaaStackDocumentation";
public const string WebApi = "SaaStackWebApi";
- public const string Application = "SaaStackApplication";
}
}
\ No newline at end of file
diff --git a/src/Tools.Analyzers.NonPlatform.UnitTests/ApiLayerAnalyzerSpec.cs b/src/Tools.Analyzers.NonPlatform.UnitTests/ApiLayerAnalyzerSpec.cs
new file mode 100644
index 00000000..aa34991d
--- /dev/null
+++ b/src/Tools.Analyzers.NonPlatform.UnitTests/ApiLayerAnalyzerSpec.cs
@@ -0,0 +1,2112 @@
+extern alias NonPlatformAnalyzers;
+extern alias CommonAnalyzers;
+using CommonAnalyzers::Tools.Analyzers.Common;
+using Xunit;
+using TypeExtensions = NonPlatformAnalyzers::Tools.Analyzers.NonPlatform.TypeExtensions;
+using ServiceOperation = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.ServiceOperation;
+using IWebResponse = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebResponse;
+using IWebSearchResponse = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebSearchResponse;
+using Route = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.RouteAttribute;
+using Authorize = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.AuthorizeAttribute;
+using SearchResultMetadata = NonPlatformAnalyzers::Application.Interfaces.SearchResultMetadata;
+using AccessType = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.AccessType;
+using ApiLayerAnalyzer = NonPlatformAnalyzers::Tools.Analyzers.NonPlatform.ApiLayerAnalyzer;
+using Roles = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.Roles;
+using UsedImplicitly = NonPlatformAnalyzers::JetBrains.Annotations.UsedImplicitlyAttribute;
+
+namespace Tools.Analyzers.NonPlatform.UnitTests;
+
+[UsedImplicitly]
+public class ApiLayerAnalyzerSpec
+{
+ [UsedImplicitly]
+ public class GivenAWebApiService
+ {
+ [Trait("Category", "Unit")]
+ public class GivenAnyRule
+ {
+ [Fact]
+ public async Task WhenInExcludedNamespace_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+namespace Common;
+public class AClass : IWebApiService
+{
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenNotWebApiClass_ThenNoAlert()
+ {
+ const string input = @"
+namespace ANamespace;
+public class AClass
+{
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasNoMethods_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPrivateMethod_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ private void AMethod(){}
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasInternalMethod_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ internal void AMethod(){}
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule010
+ {
+ [Fact]
+ public async Task WhenHasPublicMethodWithVoidReturnType_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public void AMethod(){}
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule010,
+ input, 6, 17, "AMethod",
+ TypeExtensions.Stringify(
+ ApiLayerAnalyzer.AllowableServiceOperationReturnTypes));
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithTaskReturnType_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public Task AMethod(){ return Task.CompletedTask; }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule010,
+ input, 7, 17, "AMethod",
+ TypeExtensions.Stringify(
+ ApiLayerAnalyzer.AllowableServiceOperationReturnTypes));
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithWrongTaskReturnType_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public Task AMethod(){ return Task.FromResult(string.Empty); }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule010,
+ input, 7, 25, "AMethod",
+ TypeExtensions.Stringify(
+ ApiLayerAnalyzer.AllowableServiceOperationReturnTypes));
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithTaskOfApiEmptyResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public Task AMethod(TestGetRouteAttributeRequest request)
+ {
+ return Task.FromResult(() => new Result());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithTaskOfApiResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public Task> AMethod(TestGetRouteAttributeRequest request)
+ {
+ return Task.FromResult>(() => new Result());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithTaskOfApiPostResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public Task> AMethod(TestPostRouteAttributeRequest request)
+ {
+ return Task.FromResult>(() => new Result, Error>());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithTaskOfApiGetResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public Task> AMethod(TestGetRouteAttributeRequest request)
+ {
+ return Task.FromResult>(() => new Result());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithTaskOfApiSearchResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public Task> AMethod(TestSearchRouteAttributeRequest request)
+ {
+ return Task.FromResult>(() => new Result());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithTaskOfApiPutPatchResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public Task> AMethod(TestPutPatchRouteAttributeRequest request)
+ {
+ return Task.FromResult>(() => new Result());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithTaskOfApiDeleteResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public Task AMethod(TestDeleteRouteAttributeRequest request)
+ {
+ return Task.FromResult(() => new Result());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithWrongNakedReturnType_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public string AMethod(){ return string.Empty; }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule010,
+ input, 6,
+ 19, "AMethod",
+ TypeExtensions.Stringify(
+ ApiLayerAnalyzer
+ .AllowableServiceOperationReturnTypes));
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithNakedApiEmptyResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestGetRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithNakedApiResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiResult AMethod(TestGetRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithNakedApiPostResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiPostResult AMethod(TestPostRouteAttributeRequest request)
+ {
+ return () => new Result, Error>();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithNakedApiGetResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiGetResult AMethod(TestGetRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithNakedApiSearchResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiSearchResult AMethod(TestSearchRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithNakedApiPutPatchResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiPutPatchResult AMethod(TestPutPatchRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenHasPublicMethodWithNakedApiDeleteResultReturnType_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiDeleteResult AMethod(TestDeleteRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule011And012
+ {
+ [Fact]
+ public async Task WhenHasNoParameters_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod()
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule011,
+ input, 8, 27, "AMethod");
+ }
+
+ [Fact]
+ public async Task WhenHasTooManyParameters_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestGetRouteAttributeRequest request, CancellationToken cancellationToken, string value)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule011,
+ input, 10, 27, "AMethod");
+ }
+
+ [Fact]
+ public async Task WhenFirstParameterIsNotRequestType_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(string value)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule011,
+ input, 8, 27, "AMethod");
+ }
+
+ [Fact]
+ public async Task WhenSecondParameterIsNotCancellationToken_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestGetRouteAttributeRequest request, string value)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule012,
+ input, 9, 27, "AMethod");
+ }
+
+ [Fact]
+ public async Task WhenOnlyRequest_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestGetRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenRequestAndCancellation_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestGetRouteAttributeRequest request, CancellationToken cancellationToken)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule013AndRule017
+ {
+ [Fact]
+ public async Task WhenHasNoAttributes_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestNoRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.DiagnosticExists(input,
+ (ApiLayerAnalyzer.Rule013, 9, 27, "AMethod", null),
+ (ApiLayerAnalyzer.Rule017, 9, 35, "TestNoRouteAttributeRequest", null));
+ }
+
+ [Fact]
+ public async Task WhenMissingAttribute_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ [TestAttribute]
+ public ApiEmptyResult AMethod(TestNoRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.DiagnosticExists(input,
+ (ApiLayerAnalyzer.Rule013, 10, 27, "AMethod", null),
+ (ApiLayerAnalyzer.Rule017, 10, 35, "TestNoRouteAttributeRequest", null));
+ }
+
+ [Fact]
+ public async Task WhenAttribute_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestGetRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule014
+ {
+ [Fact]
+ public async Task WhenOneRoute_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod1(TestGetRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenTwoWithSameRoute_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod1(TestGetRouteAttributeRequest1 request)
+ {
+ return () => new Result();
+ }
+ public ApiEmptyResult AMethod2(TestGetRouteAttributeRequest2 request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenThreeWithSameRouteFirstSegment_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod1(TestGetRouteAttributeRequest1 request)
+ {
+ return () => new Result();
+ }
+ public ApiEmptyResult AMethod2(TestGetRouteAttributeRequest2 request)
+ {
+ return () => new Result();
+ }
+ public ApiEmptyResult AMethod3(TestGetRouteAttributeRequest3 request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenDifferentRouteSegments_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod1(TestGetRouteAttributeRequest1 request)
+ {
+ return () => new Result();
+ }
+ public ApiEmptyResult AMethod2(TestGetRouteAttributeRequest2 request)
+ {
+ return () => new Result();
+ }
+ public ApiEmptyResult AMethod4(TestGetRouteAttributeRequest4 request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule014,
+ input, 17, 27, "AMethod4");
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule015
+ {
+ [Fact]
+ public async Task WhenNoDuplicateRequests_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestGetRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenDuplicateRequests_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod1(TestGetRouteAttributeRequest1 request)
+ {
+ return () => new Result();
+ }
+ public ApiEmptyResult AMethod2(TestGetRouteAttributeRequest1 request)
+ {
+ return () => new Result();
+ }
+ public ApiEmptyResult AMethod3(TestGetRouteAttributeRequest2 request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule015,
+ input,
+ (9, 27, "AMethod1"),
+ (13, 27, "AMethod2"));
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule016
+ {
+ [Fact]
+ public async Task WhenPostAndReturnsApiEmptyResult_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestPostRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenGetAndReturnsApiEmptyResult_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestGetRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenSearchAndReturnsApiEmptyResult_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestSearchRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenPutPatchAndReturnsApiEmptyResult_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestPutPatchRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenDeleteAndReturnsApiEmptyResult_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestDeleteRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenPostAndReturnsApiResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiResult AMethod(TestPostRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 44, "AMethod", ServiceOperation.Post, ExpectedAllowedResultTypes(ServiceOperation.Post));
+ }
+
+ [Fact]
+ public async Task WhenGetAndReturnsApiResult_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiResult AMethod(TestGetRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenSearchAndReturnsApiResult_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiResult AMethod(TestSearchRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenPutPatchAndReturnsApiResult_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiResult AMethod(TestPutPatchRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenDeleteAndReturnsApiResult_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiResult AMethod(TestDeleteRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenPostAndReturnsApiPostResult_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiPostResult AMethod(TestPostRouteAttributeRequest request)
+ {
+ return () => new PostResult(new TestResponse(), ""/alocation"");
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenGetAndReturnsApiPostResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiPostResult AMethod(TestGetRouteAttributeRequest request)
+ {
+ return () => new PostResult(new TestResponse(), ""/alocation"");
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 54, "AMethod", ServiceOperation.Get, ExpectedAllowedResultTypes(ServiceOperation.Get));
+ }
+
+ [Fact]
+ public async Task WhenSearchAndReturnsApiPostResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiPostResult AMethod(TestSearchRouteAttributeRequest request)
+ {
+ return () => new PostResult(new TestResponse(), ""/alocation"");
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 54, "AMethod", ServiceOperation.Search,
+ ExpectedAllowedResultTypes(ServiceOperation.Search));
+ }
+
+ [Fact]
+ public async Task WhenPutPatchAndReturnsApiPostResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiPostResult AMethod(TestPutPatchRouteAttributeRequest request)
+ {
+ return () => new PostResult(new TestResponse(), ""/alocation"");
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 54, "AMethod", ServiceOperation.PutPatch,
+ ExpectedAllowedResultTypes(ServiceOperation.PutPatch));
+ }
+
+ [Fact]
+ public async Task WhenDeleteAndReturnsApiPostResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiPostResult AMethod(TestDeleteRouteAttributeRequest request)
+ {
+ return () => new PostResult(new TestResponse(), ""/alocation"");
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 54, "AMethod", ServiceOperation.Delete,
+ ExpectedAllowedResultTypes(ServiceOperation.Delete));
+ }
+
+ [Fact]
+ public async Task WhenPostAndReturnsApiGetResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiGetResult AMethod(TestPostRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 47, "AMethod", ServiceOperation.Post, ExpectedAllowedResultTypes(ServiceOperation.Post));
+ }
+
+ [Fact]
+ public async Task WhenGetAndReturnsApiGetResult_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiGetResult AMethod(TestGetRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenSearchAndReturnsApiGetResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiGetResult AMethod(TestSearchRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenPutPatchAndReturnsApiGetResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiGetResult AMethod(TestPutPatchRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 47, "AMethod", ServiceOperation.PutPatch,
+ ExpectedAllowedResultTypes(ServiceOperation.PutPatch));
+ }
+
+ [Fact]
+ public async Task WhenDeleteAndReturnsApiGetResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiGetResult AMethod(TestDeleteRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 47, "AMethod", ServiceOperation.Delete,
+ ExpectedAllowedResultTypes(ServiceOperation.Delete));
+ }
+
+ [Fact]
+ public async Task WhenPostAndReturnsApiSearchResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiSearchResult AMethod(TestPostRouteAttributeRequest request)
+ {
+ return () => new Result(new TestSearchResponse());
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 56, "AMethod", ServiceOperation.Post, ExpectedAllowedResultTypes(ServiceOperation.Post));
+ }
+
+ [Fact]
+ public async Task WhenGetAndReturnsApiSearchResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiSearchResult AMethod(TestGetRouteAttributeRequest request)
+ {
+ return () => new Result(new TestSearchResponse());
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 56, "AMethod", ServiceOperation.Get, ExpectedAllowedResultTypes(ServiceOperation.Get));
+ }
+
+ [Fact]
+ public async Task WhenSearchAndReturnsApiSearchResult_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiSearchResult AMethod(TestSearchRouteAttributeRequest request)
+ {
+ return () => new Result(new TestSearchResponse());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenPutPatchAndReturnsApiSearchResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiSearchResult AMethod(TestPutPatchRouteAttributeRequest request)
+ {
+ return () => new Result(new TestSearchResponse());
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 56, "AMethod", ServiceOperation.PutPatch,
+ ExpectedAllowedResultTypes(ServiceOperation.PutPatch));
+ }
+
+ [Fact]
+ public async Task WhenDeleteAndReturnsApiSearchResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiSearchResult AMethod(TestDeleteRouteAttributeRequest request)
+ {
+ return () => new Result(new TestSearchResponse());
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 56, "AMethod", ServiceOperation.Delete,
+ ExpectedAllowedResultTypes(ServiceOperation.Delete));
+ }
+
+ [Fact]
+ public async Task WhenPostAndReturnsApiPutPatchResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiPutPatchResult AMethod(TestPostRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 52, "AMethod", ServiceOperation.Post, ExpectedAllowedResultTypes(ServiceOperation.Post));
+ }
+
+ [Fact]
+ public async Task WhenGetAndReturnsApiPutPatchResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiPutPatchResult AMethod(TestGetRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 52, "AMethod", ServiceOperation.Get, ExpectedAllowedResultTypes(ServiceOperation.Get));
+ }
+
+ [Fact]
+ public async Task WhenSearchAndReturnsApiPutPatchResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiPutPatchResult AMethod(TestSearchRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 52, "AMethod", ServiceOperation.Search,
+ ExpectedAllowedResultTypes(ServiceOperation.Search));
+ }
+
+ [Fact]
+ public async Task WhenPutPatchAndReturnsApiPutPatchResult_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiPutPatchResult AMethod(TestPutPatchRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenDeleteAndReturnsApiPutPatchResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiPutPatchResult AMethod(TestDeleteRouteAttributeRequest request)
+ {
+ return () => new Result(new TestResponse());
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 52, "AMethod", ServiceOperation.Delete,
+ ExpectedAllowedResultTypes(ServiceOperation.Delete));
+ }
+
+ [Fact]
+ public async Task WhenPostAndReturnsApiDeleteResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiDeleteResult AMethod(TestPostRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 28, "AMethod", ServiceOperation.Post, ExpectedAllowedResultTypes(ServiceOperation.Post));
+ }
+
+ [Fact]
+ public async Task WhenGetAndReturnsApiDeleteResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiDeleteResult AMethod(TestGetRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 28, "AMethod", ServiceOperation.Get, ExpectedAllowedResultTypes(ServiceOperation.Get));
+ }
+
+ [Fact]
+ public async Task WhenSearchAndReturnsApiDeleteResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiDeleteResult AMethod(TestSearchRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 28, "AMethod", ServiceOperation.Search,
+ ExpectedAllowedResultTypes(ServiceOperation.Search));
+ }
+
+ [Fact]
+ public async Task WhenPutPatchAndReturnsApiDeleteResult_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiDeleteResult AMethod(TestPutPatchRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule016,
+ input, 9, 28, "AMethod", ServiceOperation.PutPatch,
+ ExpectedAllowedResultTypes(ServiceOperation.PutPatch));
+ }
+
+ [Fact]
+ public async Task WhenDeleteAndReturnsApiDeleteResult_ThenNotAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiDeleteResult AMethod(TestDeleteRouteAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ private static string ExpectedAllowedResultTypes(ServiceOperation operation)
+ {
+ return TypeExtensions.Stringify(
+ ApiLayerAnalyzer
+ .AllowableOperationReturnTypes[operation].ToArray());
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule018AndRule019
+ {
+ [Fact]
+ public async Task WhenRouteIsAnonymousAndMissingAuthorizeAttribute_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestAnonymousRouteNoAuthorizeAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenRouteIsNotAnonymousAndAuthorizeAttribute_ThenNoAlert()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestSecureRouteAuthorizeAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+
+ [Fact]
+ public async Task WhenRouteIsAnonymousAndAuthorizeAttribute_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestAnonymousRouteAuthorizeAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule018,
+ input, 9, 35, "TestAnonymousRouteAuthorizeAttributeRequest");
+ }
+
+ [Fact]
+ public async Task WhenRouteIsNotAnonymousAndNoAuthorizeAttribute_ThenAlerts()
+ {
+ const string input = @"
+using Infrastructure.Web.Api.Interfaces;
+using System.Threading.Tasks;
+using Common;
+using Tools.Analyzers.NonPlatform.UnitTests;
+namespace ANamespace;
+public class AClass : IWebApiService
+{
+ public ApiEmptyResult AMethod(TestSecureRouteNoAuthorizeAttributeRequest request)
+ {
+ return () => new Result();
+ }
+}";
+ await Verify.DiagnosticExists(ApiLayerAnalyzer.Rule019,
+ input, 9, 35, "TestSecureRouteNoAuthorizeAttributeRequest");
+ }
+ }
+ }
+
+ [UsedImplicitly]
+ public class GivenARequest
+ {
+ [Trait("Category", "Unit")]
+ public class GivenRule030
+ {
+ [Fact]
+ public async Task WhenIsNotPublic_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+[Route(""/apath"", ServiceOperation.Get)]
+internal class ARequest : IWebRequest
+{
+ public required string AProperty { get; set; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule030, input, 6, 16, "ARequest");
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule031
+ {
+ [Fact]
+ public async Task WhenIsNotNamedCorrectly_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+[Route(""/apath"", ServiceOperation.Get)]
+public class AClass : IWebRequest
+{
+ public required string AProperty { get; set; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule031, input, 6, 14, "AClass");
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule032
+ {
+ [Fact]
+ public async Task WhenIsNotInCorrectAssembly_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace anamespace;
+[Route(""/apath"", ServiceOperation.Get)]
+public class ARequest : IWebRequest
+{
+ public required string AProperty { get; set; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule032, input, 6, 14, "ARequest",
+ AnalyzerConstants.ServiceOperationTypesNamespace);
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule033
+ {
+ [Fact]
+ public async Task WhenHasNoRouteAttribute_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+public class ARequest : IWebRequest
+{
+ public required string AProperty { get; set; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule033, input, 5, 14, "ARequest");
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule034
+ {
+ [Fact]
+ public async Task WhenHasCtorAndNotParameterless_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+[Route(""/apath"", ServiceOperation.Get)]
+public class ARequest : IWebRequest
+{
+ public ARequest(string value)
+ {
+ AProperty = value;
+ }
+
+ public required string AProperty { get; set; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule034, input, 6, 14, "ARequest");
+ }
+
+ [Fact]
+ public async Task WhenHasCtorAndPrivate_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+[Route(""/apath"", ServiceOperation.Get)]
+public class ARequest : IWebRequest
+{
+ private ARequest()
+ {
+ AProperty = string.Empty;
+ }
+
+ public required string AProperty { get; set; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule034, input, 6, 14, "ARequest");
+ }
+
+ [Fact]
+ public async Task WhenHasCtorAndIsParameterless_ThenNoAlert()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+[Route(""/apath"", ServiceOperation.Get)]
+public class ARequest : IWebRequest
+{
+ public ARequest()
+ {
+ AProperty = string.Empty;
+ }
+
+ public required string AProperty { get; set; }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule035
+ {
+ [Fact]
+ public async Task WhenAnyPropertyHasNoSetter_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+[Route(""/apath"", ServiceOperation.Get)]
+public class ARequest : IWebRequest
+{
+ public string? AProperty { get; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule035, input, 8, 20, "AProperty");
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule036
+ {
+ [Fact]
+ public async Task WhenAnyPropertyReferenceTypeIsOptional_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Common;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+[Route(""/apath"", ServiceOperation.Get)]
+public class ARequest : IWebRequest
+{
+ public Optional AProperty { get; set; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule036, input, 9, 29, "AProperty");
+ }
+
+ [Fact]
+ public async Task WhenAnyPropertyReferenceTypeIsNullable_ThenNoAlert()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+[Route(""/apath"", ServiceOperation.Get)]
+public class ARequest : IWebRequest
+{
+ public string? AProperty { get; set; }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+ }
+ }
+
+ [UsedImplicitly]
+ public class GivenAResponse
+ {
+ [Trait("Category", "Unit")]
+ public class GivenRule040
+ {
+ [Fact]
+ public async Task WhenIsNotPublic_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+internal class AResponse : IWebResponse
+{
+ public required string AProperty { get; set; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule040, input, 5, 16, "AResponse");
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule041
+ {
+ [Fact]
+ public async Task WhenIsNotNamedCorrectly_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+public class AClass : IWebResponse
+{
+ public required string AProperty { get; set; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule041, input, 5, 14, "AClass");
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule042
+ {
+ [Fact]
+ public async Task WhenIsNotInCorrectAssembly_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace anamespace;
+public class AResponse : IWebResponse
+{
+ public required string AProperty { get; set; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule042, input, 5, 14, "AResponse",
+ AnalyzerConstants.ServiceOperationTypesNamespace);
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ [Trait("Category", "Unit")]
+ public class GivenRule043
+ {
+ [Fact]
+ public async Task WhenHasCtorAndNotParameterless_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+public class AResponse : IWebResponse
+{
+ public AResponse(string value)
+ {
+ AProperty = value;
+ }
+
+ public required string AProperty { get; set; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule043, input, 5, 14, "AResponse");
+ }
+
+ [Fact]
+ public async Task WhenHasCtorAndPrivate_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+public class AResponse : IWebResponse
+{
+ private AResponse()
+ {
+ AProperty = string.Empty;
+ }
+
+ public required string AProperty { get; set; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule043, input, 5, 14, "AResponse");
+ }
+
+ [Fact]
+ public async Task WhenHasCtorAndIsParameterless_ThenNoAlert()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+public class AResponse : IWebResponse
+{
+ public AResponse()
+ {
+ AProperty = string.Empty;
+ }
+
+ public required string AProperty { get; set; }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule044
+ {
+ [Fact]
+ public async Task WhenAnyPropertyHasNoSetter_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+public class AResponse : IWebResponse
+{
+ public string? AProperty { get; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule044, input, 7, 20, "AProperty");
+ }
+ }
+
+ [Trait("Category", "Unit")]
+ public class GivenRule045
+ {
+ [Fact]
+ public async Task WhenAnyPropertyReferenceTypeIsOptional_ThenAlerts()
+ {
+ const string input = @"
+using System;
+using Common;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+public class AResponse : IWebResponse
+{
+ public Optional AProperty { get; set; }
+}";
+
+ await Verify.DiagnosticExists(
+ ApiLayerAnalyzer.Rule045, input, 8, 29, "AProperty");
+ }
+
+ [Fact]
+ public async Task WhenAnyPropertyReferenceTypeIsNullable_ThenNoAlert()
+ {
+ const string input = @"
+using System;
+using Infrastructure.Web.Api.Interfaces;
+namespace Infrastructure.Web.Api.Operations.Shared.Test;
+public class AResponse : IWebResponse
+{
+ public string? AProperty { get; set; }
+}";
+
+ await Verify.NoDiagnosticExists(input);
+ }
+ }
+ }
+}
+
+[UsedImplicitly]
+public class TestResource;
+
+[UsedImplicitly]
+public class TestResponse : IWebResponse;
+
+[UsedImplicitly]
+public class TestSearchResponse : IWebSearchResponse
+{
+ public SearchResultMetadata? Metadata { get; set; }
+}
+
+[UsedImplicitly]
+public class TestNoRouteAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
+
+[Route("/aresource", ServiceOperation.Search)]
+[UsedImplicitly]
+public class TestSearchRouteAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
+
+[Route("/aresource", ServiceOperation.Post)]
+[UsedImplicitly]
+public class TestPostRouteAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
+
+[Route("/aresource", ServiceOperation.Get)]
+[UsedImplicitly]
+public class TestGetRouteAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
+
+[Route("/aresource/1", ServiceOperation.Get)]
+[UsedImplicitly]
+public class TestGetRouteAttributeRequest1 : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
+
+[Route("/aresource/2", ServiceOperation.Get)]
+[UsedImplicitly]
+public class TestGetRouteAttributeRequest2 : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
+
+[Route("/aresource/3", ServiceOperation.Get)]
+[UsedImplicitly]
+public class TestGetRouteAttributeRequest3 : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
+
+[Route("/anotherresource/1", ServiceOperation.Get)]
+[UsedImplicitly]
+public class TestGetRouteAttributeRequest4 : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
+
+[Route("/aresource", ServiceOperation.PutPatch)]
+[UsedImplicitly]
+public class TestPutPatchRouteAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
+
+[Route("/aresource", ServiceOperation.Delete)]
+[UsedImplicitly]
+public class TestDeleteRouteAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
+
+[AttributeUsage(AttributeTargets.Method)]
+[UsedImplicitly]
+public class TestAttribute : Attribute;
+
+[Route("/aresource", ServiceOperation.Post)]
+[UsedImplicitly]
+public class TestAnonymousRouteNoAuthorizeAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
+
+[Route("/aresource", ServiceOperation.Post)]
+[Authorize(Roles.Platform_Standard)]
+[UsedImplicitly]
+public class TestAnonymousRouteAuthorizeAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
+
+[Route("/aresource", ServiceOperation.Post, AccessType.Token)]
+[Authorize(Roles.Platform_Standard)]
+[UsedImplicitly]
+public class TestSecureRouteAuthorizeAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
+
+[Route("/aresource", ServiceOperation.Post, AccessType.Token)]
+[UsedImplicitly]
+public class TestSecureRouteNoAuthorizeAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest;
\ No newline at end of file
diff --git a/src/Tools.Analyzers.NonPlatform.UnitTests/ApplicationLayerAnalyzerSpec.cs b/src/Tools.Analyzers.NonPlatform.UnitTests/ApplicationLayerAnalyzerSpec.cs
index 57ddcd6c..9cb2ecfd 100644
--- a/src/Tools.Analyzers.NonPlatform.UnitTests/ApplicationLayerAnalyzerSpec.cs
+++ b/src/Tools.Analyzers.NonPlatform.UnitTests/ApplicationLayerAnalyzerSpec.cs
@@ -33,7 +33,7 @@ public class AClass : IIdentifiableResource
}
[Trait("Category", "Unit")]
- public class GivenRuleSas070
+ public class GivenRule010
{
[Fact]
public async Task WhenIsNotPublic_ThenAlerts()
@@ -48,12 +48,12 @@ internal class AClass : IIdentifiableResource
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas070, input, 5, 16, "AClass");
+ ApplicationLayerAnalyzer.Rule010, input, 5, 16, "AClass");
}
}
[Trait("Category", "Unit")]
- public class GivenRuleSas071
+ public class GivenRule011
{
[Fact]
public async Task WhenHasCtorAndNotParameterless_ThenAlerts()
@@ -73,7 +73,7 @@ public AClass(string id)
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas071, input, 5, 14, "AClass");
+ ApplicationLayerAnalyzer.Rule011, input, 5, 14, "AClass");
}
[Fact]
@@ -94,7 +94,7 @@ private AClass()
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas071, input, 5, 14, "AClass");
+ ApplicationLayerAnalyzer.Rule011, input, 5, 14, "AClass");
}
[Fact]
@@ -119,7 +119,7 @@ public AClass()
}
[Trait("Category", "Unit")]
- public class GivenRuleSas072
+ public class GivenRule012
{
[Fact]
public async Task WhenAnyPropertyHasNoSetter_ThenAlerts()
@@ -136,12 +136,12 @@ public class AClass : IIdentifiableResource
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas072, input, 9, 20, "AProperty");
+ ApplicationLayerAnalyzer.Rule012, input, 9, 20, "AProperty");
}
}
[Trait("Category", "Unit")]
- public class GivenRuleSas073
+ public class GivenRule013
{
[Fact]
public async Task WhenAnyPropertyReferenceTypeIsOptional_ThenAlerts()
@@ -159,9 +159,9 @@ public class AClass : IIdentifiableResource
}";
await Verify.DiagnosticExists(input,
- (ApplicationLayerAnalyzer.Sas073, 10, 29, "AProperty", null),
- (ApplicationLayerAnalyzer.Sas074, 10, 29, "AProperty", [
- GivenRuleSas074.AllTypes,
+ (ApplicationLayerAnalyzer.Rule013, 10, 29, "AProperty", null),
+ (ApplicationLayerAnalyzer.Rule014, 10, 29, "AProperty", [
+ GivenRule014.AllTypes,
AnalyzerConstants.ResourceTypesNamespace
]));
}
@@ -185,7 +185,7 @@ public class AClass : IIdentifiableResource
}
[Trait("Category", "Unit")]
- public class GivenRuleSas074
+ public class GivenRule014
{
public const string AllTypes =
"bool or string or ulong or int or long or double or decimal or System.DateTime or byte or System.IO.Stream";
@@ -206,7 +206,7 @@ public class AClass : IIdentifiableResource
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas074, input, 10, 26, "AProperty", AllTypes,
+ ApplicationLayerAnalyzer.Rule014, input, 10, 26, "AProperty", AllTypes,
AnalyzerConstants.ResourceTypesNamespace);
}
@@ -226,7 +226,7 @@ public class AClass : IIdentifiableResource
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas074, input, 10, 32, "AProperty", AllTypes,
+ ApplicationLayerAnalyzer.Rule014, input, 10, 32, "AProperty", AllTypes,
AnalyzerConstants.ResourceTypesNamespace);
}
@@ -246,7 +246,7 @@ public class AClass : IIdentifiableResource
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas074, input, 10, 46, "AProperty", AllTypes,
+ ApplicationLayerAnalyzer.Rule014, input, 10, 46, "AProperty", AllTypes,
AnalyzerConstants.ResourceTypesNamespace);
}
@@ -266,7 +266,7 @@ public class AClass : IIdentifiableResource
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas074, input, 10, 46, "AProperty", AllTypes,
+ ApplicationLayerAnalyzer.Rule014, input, 10, 46, "AProperty", AllTypes,
AnalyzerConstants.ResourceTypesNamespace);
}
@@ -423,7 +423,7 @@ public enum AnotherClass
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas074, input, 12, 38, "AProperty", AllTypes,
+ ApplicationLayerAnalyzer.Rule014, input, 12, 38, "AProperty", AllTypes,
AnalyzerConstants.ResourceTypesNamespace);
}
@@ -509,7 +509,7 @@ public enum AnEnum
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas074, input, 12, 32, "AProperty", AllTypes,
+ ApplicationLayerAnalyzer.Rule014, input, 12, 32, "AProperty", AllTypes,
AnalyzerConstants.ResourceTypesNamespace);
}
@@ -610,7 +610,7 @@ public enum AnotherClass
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas074, input, 12, 44, "AProperty", AllTypes,
+ ApplicationLayerAnalyzer.Rule014, input, 12, 44, "AProperty", AllTypes,
AnalyzerConstants.ResourceTypesNamespace);
}
@@ -711,7 +711,7 @@ public enum AnotherClass
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas074, input, 12, 58, "AProperty", AllTypes,
+ ApplicationLayerAnalyzer.Rule014, input, 12, 58, "AProperty", AllTypes,
AnalyzerConstants.ResourceTypesNamespace);
}
}
@@ -743,7 +743,7 @@ public class AClass : ReadModelEntity
}
[Trait("Category", "Unit")]
- public class GivenRuleSas080
+ public class GivenRule020
{
[Fact]
public async Task WhenIsNotPublic_ThenAlerts()
@@ -761,12 +761,12 @@ internal class AClass : ReadModelEntity
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas080, input, 8, 16, "AClass");
+ ApplicationLayerAnalyzer.Rule020, input, 8, 16, "AClass");
}
}
[Trait("Category", "Unit")]
- public class GivenRuleSas081
+ public class GivenRule021
{
[Fact]
public async Task WhenMissingEntityNameAttribute_ThenAlerts()
@@ -783,12 +783,12 @@ public class AClass : ReadModelEntity
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas081, input, 7, 14, "AClass");
+ ApplicationLayerAnalyzer.Rule021, input, 7, 14, "AClass");
}
}
[Trait("Category", "Unit")]
- public class GivenRuleSas082
+ public class GivenRule022
{
[Fact]
public async Task WhenHasCtorAndNotParameterless_ThenAlerts()
@@ -811,7 +811,7 @@ public AClass(string id)
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas082, input, 8, 14, "AClass");
+ ApplicationLayerAnalyzer.Rule022, input, 8, 14, "AClass");
}
[Fact]
@@ -835,7 +835,7 @@ private AClass()
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas082, input, 8, 14, "AClass");
+ ApplicationLayerAnalyzer.Rule022, input, 8, 14, "AClass");
}
[Fact]
@@ -863,7 +863,7 @@ public AClass()
}
[Trait("Category", "Unit")]
- public class GivenRuleSas083
+ public class GivenRule023
{
[Fact]
public async Task WhenAnyPropertyHasNoSetter_ThenAlerts()
@@ -881,12 +881,12 @@ public class AClass : ReadModelEntity
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas083, input, 10, 29, "AProperty");
+ ApplicationLayerAnalyzer.Rule023, input, 10, 29, "AProperty");
}
}
[Trait("Category", "Unit")]
- public class GivenRuleSas084
+ public class GivenRule024
{
[Fact]
public async Task WhenAnyPropertyIsNullable_ThenAlerts()
@@ -904,7 +904,7 @@ public class AClass : ReadModelEntity
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas084, input, 10, 20, "AProperty");
+ ApplicationLayerAnalyzer.Rule024, input, 10, 20, "AProperty");
}
[Fact]
@@ -947,7 +947,7 @@ public class AClass : ReadModelEntity
}
[Trait("Category", "Unit")]
- public class GivenRuleSas085
+ public class GivenRule025
{
private const string AllTypes =
"bool or string or ulong or int or long or double or decimal or System.DateTime or byte";
@@ -970,7 +970,7 @@ public class AClass : ReadModelEntity
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas085, input, 12, 27, "AProperty", AllTypes);
+ ApplicationLayerAnalyzer.Rule025, input, 12, 27, "AProperty", AllTypes);
}
[Fact]
@@ -991,7 +991,7 @@ public class AClass : ReadModelEntity
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas085, input, 12, 33, "AProperty", AllTypes);
+ ApplicationLayerAnalyzer.Rule025, input, 12, 33, "AProperty", AllTypes);
}
[Fact]
@@ -1012,7 +1012,7 @@ public class AClass : ReadModelEntity
}";
await Verify.DiagnosticExists(
- ApplicationLayerAnalyzer.Sas085, input, 12, 47, "AProperty", AllTypes);
+ ApplicationLayerAnalyzer.Rule025, input, 12, 47, "AProperty", AllTypes);
}
[Fact]
@@ -1033,7 +1033,7 @@ public class AClass : ReadModelEntity
}";
await Verify.DiagnosticExists