diff --git a/Directory.Build.props b/Directory.Build.props
index f2b80f15bd..d6f4df58b2 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -39,7 +39,6 @@
6.0.*
2.3.*
- 4.18.*
17.7.*
diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs
index b38ad986dd..29774c6eab 100644
--- a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs
+++ b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs
@@ -23,10 +23,12 @@ public sealed class JsonApiMiddleware
private static readonly MediaTypeHeaderValue MediaType = MediaTypeHeaderValue.Parse(HeaderConstants.MediaType);
private static readonly MediaTypeHeaderValue AtomicOperationsMediaType = MediaTypeHeaderValue.Parse(HeaderConstants.AtomicOperationsMediaType);
- private readonly RequestDelegate _next;
+ private readonly RequestDelegate? _next;
- public JsonApiMiddleware(RequestDelegate next, IHttpContextAccessor httpContextAccessor)
+ public JsonApiMiddleware(RequestDelegate? next, IHttpContextAccessor httpContextAccessor)
{
+ ArgumentGuard.NotNull(httpContextAccessor);
+
_next = next;
var session = new AspNetCodeTimerSession(httpContextAccessor);
@@ -77,9 +79,12 @@ public async Task InvokeAsync(HttpContext httpContext, IControllerResourceMappin
httpContext.RegisterJsonApiRequest();
}
- using (CodeTimingSessionManager.Current.Measure("Subsequent middleware"))
+ if (_next != null)
{
- await _next(httpContext);
+ using (CodeTimingSessionManager.Current.Measure("Subsequent middleware"))
+ {
+ await _next(httpContext);
+ }
}
}
diff --git a/src/JsonApiDotNetCore/Properties/AssemblyInfo.cs b/src/JsonApiDotNetCore/Properties/AssemblyInfo.cs
index e4f127b725..34fc8971d1 100644
--- a/src/JsonApiDotNetCore/Properties/AssemblyInfo.cs
+++ b/src/JsonApiDotNetCore/Properties/AssemblyInfo.cs
@@ -3,5 +3,3 @@
[assembly: InternalsVisibleTo("Benchmarks")]
[assembly: InternalsVisibleTo("JsonApiDotNetCoreTests")]
[assembly: InternalsVisibleTo("UnitTests")]
-[assembly: InternalsVisibleTo("DiscoveryTests")]
-[assembly: InternalsVisibleTo("TestBuildingBlocks")]
diff --git a/test/DiscoveryTests/DiscoveryTests.csproj b/test/DiscoveryTests/DiscoveryTests.csproj
index 0eae11e850..a09e322203 100644
--- a/test/DiscoveryTests/DiscoveryTests.csproj
+++ b/test/DiscoveryTests/DiscoveryTests.csproj
@@ -12,6 +12,5 @@
-
diff --git a/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs b/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs
index 3396aed54b..78c4213e93 100644
--- a/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs
+++ b/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs
@@ -1,7 +1,5 @@
using FluentAssertions;
using JsonApiDotNetCore.Configuration;
-using JsonApiDotNetCore.Middleware;
-using JsonApiDotNetCore.Queries;
using JsonApiDotNetCore.Repositories;
using JsonApiDotNetCore.Resources;
using JsonApiDotNetCore.Services;
@@ -10,7 +8,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
-using Moq;
using TestBuildingBlocks;
using Xunit;
@@ -18,45 +15,26 @@ namespace DiscoveryTests;
public sealed class ServiceDiscoveryFacadeTests
{
- private static readonly ILoggerFactory LoggerFactory = NullLoggerFactory.Instance;
- private readonly IServiceCollection _services = new ServiceCollection();
- private readonly ResourceGraphBuilder _resourceGraphBuilder;
+ private readonly ServiceCollection _services = new();
public ServiceDiscoveryFacadeTests()
{
- var dbResolverMock = new Mock();
- dbResolverMock.Setup(resolver => resolver.GetContext()).Returns(new Mock().Object);
- _services.AddScoped(_ => dbResolverMock.Object);
-
- IJsonApiOptions options = new JsonApiOptions();
-
- _services.AddSingleton(options);
- _services.AddSingleton(LoggerFactory);
- _services.AddScoped(_ => new Mock().Object);
- _services.AddScoped(_ => new Mock().Object);
- _services.AddScoped(_ => new Mock().Object);
- _services.AddScoped(typeof(IResourceChangeTracker<>), typeof(ResourceChangeTracker<>));
- _services.AddScoped(_ => new Mock().Object);
- _services.AddScoped(_ => new Mock().Object);
- _services.AddScoped(_ => new Mock().Object);
- _services.AddScoped(_ => new Mock().Object);
- _services.AddScoped(_ => new Mock().Object);
-
- _resourceGraphBuilder = new ResourceGraphBuilder(options, LoggerFactory);
+ _services.AddSingleton(_ => NullLoggerFactory.Instance);
+ _services.AddScoped(_ => new FakeDbContextResolver());
}
[Fact]
public void Can_add_resources_from_assembly_to_graph()
{
// Arrange
- var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, LoggerFactory);
- facade.AddAssembly(typeof(Person).Assembly);
+ Action addAction = facade => facade.AddAssembly(typeof(Person).Assembly);
// Act
- facade.DiscoverResources();
+ _services.AddJsonApi(discovery: facade => addAction(facade));
// Assert
- IResourceGraph resourceGraph = _resourceGraphBuilder.Build();
+ ServiceProvider serviceProvider = _services.BuildServiceProvider();
+ var resourceGraph = serviceProvider.GetRequiredService();
ResourceType? personType = resourceGraph.FindResourceType(typeof(Person));
personType.ShouldNotBeNull();
@@ -69,33 +47,32 @@ public void Can_add_resources_from_assembly_to_graph()
public void Can_add_resource_from_current_assembly_to_graph()
{
// Arrange
- var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, LoggerFactory);
- facade.AddCurrentAssembly();
+ Action addAction = facade => facade.AddCurrentAssembly();
// Act
- facade.DiscoverResources();
+ _services.AddJsonApi(discovery: facade => addAction(facade));
// Assert
- IResourceGraph resourceGraph = _resourceGraphBuilder.Build();
+ ServiceProvider serviceProvider = _services.BuildServiceProvider();
+ var resourceGraph = serviceProvider.GetRequiredService();
- ResourceType? testResourceType = resourceGraph.FindResourceType(typeof(PrivateResource));
- testResourceType.ShouldNotBeNull();
+ ResourceType? resourceType = resourceGraph.FindResourceType(typeof(PrivateResource));
+ resourceType.ShouldNotBeNull();
}
[Fact]
public void Can_add_resource_service_from_current_assembly_to_container()
{
// Arrange
- var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, LoggerFactory);
- facade.AddCurrentAssembly();
+ Action addAction = facade => facade.AddCurrentAssembly();
// Act
- facade.DiscoverInjectables();
+ _services.AddJsonApi(discovery: facade => addAction(facade));
// Assert
- ServiceProvider services = _services.BuildServiceProvider();
+ ServiceProvider serviceProvider = _services.BuildServiceProvider();
+ var resourceService = serviceProvider.GetRequiredService>();
- var resourceService = services.GetRequiredService>();
resourceService.Should().BeOfType();
}
@@ -103,16 +80,15 @@ public void Can_add_resource_service_from_current_assembly_to_container()
public void Can_add_resource_repository_from_current_assembly_to_container()
{
// Arrange
- var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, LoggerFactory);
- facade.AddCurrentAssembly();
+ Action addAction = facade => facade.AddCurrentAssembly();
// Act
- facade.DiscoverInjectables();
+ _services.AddJsonApi(discovery: facade => addAction(facade));
// Assert
- ServiceProvider services = _services.BuildServiceProvider();
+ ServiceProvider serviceProvider = _services.BuildServiceProvider();
+ var resourceRepository = serviceProvider.GetRequiredService>();
- var resourceRepository = services.GetRequiredService>();
resourceRepository.Should().BeOfType();
}
@@ -120,16 +96,35 @@ public void Can_add_resource_repository_from_current_assembly_to_container()
public void Can_add_resource_definition_from_current_assembly_to_container()
{
// Arrange
- var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, LoggerFactory);
- facade.AddCurrentAssembly();
+ Action addAction = facade => facade.AddCurrentAssembly();
// Act
- facade.DiscoverInjectables();
+ _services.AddJsonApi(discovery: facade => addAction(facade));
// Assert
- ServiceProvider services = _services.BuildServiceProvider();
+ ServiceProvider serviceProvider = _services.BuildServiceProvider();
+ var resourceDefinition = serviceProvider.GetRequiredService>();
- var resourceDefinition = services.GetRequiredService>();
resourceDefinition.Should().BeOfType();
}
+
+ private sealed class FakeDbContextResolver : IDbContextResolver
+ {
+ private readonly FakeDbContextOptions _dbContextOptions = new();
+
+ public DbContext GetContext()
+ {
+ return new DbContext(_dbContextOptions);
+ }
+
+ private sealed class FakeDbContextOptions : DbContextOptions
+ {
+ public override Type ContextType => typeof(object);
+
+ public override DbContextOptions WithExtension(TExtension extension)
+ {
+ return this;
+ }
+ }
+ }
}
diff --git a/test/UnitTests/Middleware/JsonApiRequestTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs
similarity index 85%
rename from test/UnitTests/Middleware/JsonApiRequestTests.cs
rename to test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs
index aad627371d..a57f5ff5b0 100644
--- a/test/UnitTests/Middleware/JsonApiRequestTests.cs
+++ b/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs
@@ -7,17 +7,17 @@
using JsonApiDotNetCore.Resources.Annotations;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
+using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.Logging.Abstractions;
-using Moq;
using TestBuildingBlocks;
using Xunit;
#pragma warning disable AV1561 // Signature contains too many parameters
-namespace UnitTests.Middleware;
+namespace JsonApiDotNetCoreTests.UnitTests.Middleware;
-public sealed class JsonApiRequestTests
+public sealed class JsonApiMiddlewareTests
{
// @formatter:wrap_lines false
[Theory]
@@ -65,7 +65,7 @@ public async Task Sets_request_properties_correctly(string requestMethod, string
var httpContext = new DefaultHttpContext();
IControllerResourceMapping controllerResourceMapping = SetupRoutes(httpContext, resourceGraph, requestMethod, requestPath);
- var middleware = new JsonApiMiddleware(_ => Task.CompletedTask, new HttpContextAccessor
+ var middleware = new JsonApiMiddleware(null, new HttpContextAccessor
{
HttpContext = httpContext
});
@@ -153,16 +153,10 @@ private static IControllerResourceMapping SetupRoutes(HttpContext httpContext, I
ControllerTypeInfo = (TypeInfo)typeof(object)
};
- var controllerResourceMappingMock = new Mock();
+ httpContext.SetEndpoint(new Endpoint(null, new EndpointMetadataCollection(controllerActionDescriptor), null));
- controllerResourceMappingMock.Setup(mapping => mapping.GetResourceTypeForController(It.IsAny())).Returns(() =>
- {
- return pathSegments.Length > 0 ? resourceGraph.GetResourceTypes().FirstOrDefault(resourceType => resourceType.PublicName == pathSegments[0]) : null;
- });
-
- httpContext.SetEndpoint(new Endpoint(_ => Task.CompletedTask, new EndpointMetadataCollection(controllerActionDescriptor), null));
-
- return controllerResourceMappingMock.Object;
+ string? resourceTypePublicName = pathSegments.Length > 0 ? pathSegments[0] : null;
+ return new FakeJsonApiRoutingConvention(resourceGraph, resourceTypePublicName);
}
public enum IsReadOnly
@@ -198,4 +192,31 @@ private sealed class TodoItem : Identifiable
[HasMany]
public ISet Tags { get; set; } = new HashSet();
}
+
+ private sealed class FakeJsonApiRoutingConvention : IJsonApiRoutingConvention
+ {
+ private readonly IResourceGraph _resourceGraph;
+ private readonly string? _resourceTypePublicName;
+
+ public FakeJsonApiRoutingConvention(IResourceGraph resourceGraph, string? resourceTypePublicName)
+ {
+ _resourceGraph = resourceGraph;
+ _resourceTypePublicName = resourceTypePublicName;
+ }
+
+ public void Apply(ApplicationModel application)
+ {
+ throw new NotImplementedException();
+ }
+
+ public ResourceType? GetResourceTypeForController(Type? controllerType)
+ {
+ return _resourceTypePublicName != null ? _resourceGraph.FindResourceType(_resourceTypePublicName) : null;
+ }
+
+ public string GetControllerNameForResourceType(ResourceType? resourceType)
+ {
+ throw new NotImplementedException();
+ }
+ }
}
diff --git a/test/UnitTests/UnitTests.csproj b/test/UnitTests/UnitTests.csproj
index 35ceca88a4..85bcc57484 100644
--- a/test/UnitTests/UnitTests.csproj
+++ b/test/UnitTests/UnitTests.csproj
@@ -12,6 +12,5 @@
-