diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ed1eea959b..3e23a87e27 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,4 +7,3 @@ Closes #{ISSUE_NUMBER} - [ ] Complies with our [contributing guidelines](./.github/CONTRIBUTING.md) - [ ] Adapted tests - [ ] Documentation updated -- [ ] Created issue to update [Templates](https://github.com/json-api-dotnet/Templates/issues/new): {ISSUE_NUMBER} diff --git a/src/JsonApiDotNetCore/Configuration/TypeLocator.cs b/src/JsonApiDotNetCore/Configuration/TypeLocator.cs index 2a0369d940..2f004ffdf1 100644 --- a/src/JsonApiDotNetCore/Configuration/TypeLocator.cs +++ b/src/JsonApiDotNetCore/Configuration/TypeLocator.cs @@ -89,7 +89,7 @@ internal sealed class TypeLocator private static (Type implementationType, Type serviceInterface)? GetContainerRegistrationFromType(Type nextType, Type unboundInterface, Type[] interfaceTypeArguments) { - if (!nextType.IsNested) + if (!nextType.IsNested && !nextType.IsAbstract && !nextType.IsInterface) { foreach (Type nextConstructedInterface in nextType.GetInterfaces().Where(type => type.IsGenericType)) { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/HostingInIIS/HostingStartup.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/HostingInIIS/HostingStartup.cs index 24546c2062..a22dfe5954 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/HostingInIIS/HostingStartup.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/HostingInIIS/HostingStartup.cs @@ -1,9 +1,7 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; using TestBuildingBlocks; namespace JsonApiDotNetCoreTests.IntegrationTests.HostingInIIS; @@ -20,10 +18,10 @@ protected override void SetJsonApiOptions(JsonApiOptions options) options.IncludeTotalResourceCount = true; } - public override void Configure(IApplicationBuilder app, IWebHostEnvironment environment, ILoggerFactory loggerFactory) + public override void Configure(IApplicationBuilder app) { app.UsePathBase("/iis-application-virtual-directory"); - base.Configure(app, environment, loggerFactory); + base.Configure(app); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/DuplicateResourceControllerTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/DuplicateResourceControllerTests.cs index 7fec2a877e..b130523588 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/DuplicateResourceControllerTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/DuplicateResourceControllerTests.cs @@ -22,9 +22,4 @@ public void Fails_at_startup_when_multiple_controllers_exist_for_same_resource_t // Assert action.Should().ThrowExactly().WithMessage("Multiple controllers found for resource type 'knownResources'."); } - - public override void Dispose() - { - // Prevents crash when test cleanup tries to access lazily constructed Factory. - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiControllerTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiControllerTests.cs index 9c3364f4c5..f3dbbefd63 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiControllerTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiControllerTests.cs @@ -23,10 +23,10 @@ public async Task Get_skips_middleware_and_formatters() // Arrange using var request = new HttpRequestMessage(HttpMethod.Get, "/NonJsonApi"); - HttpClient client = _testContext.Factory.CreateClient(); + using HttpClient client = _testContext.Factory.CreateClient(); // Act - HttpResponseMessage httpResponse = await client.SendAsync(request); + using HttpResponseMessage httpResponse = await client.SendAsync(request); // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); @@ -52,10 +52,10 @@ public async Task Post_skips_middleware_and_formatters() } }; - HttpClient client = _testContext.Factory.CreateClient(); + using HttpClient client = _testContext.Factory.CreateClient(); // Act - HttpResponseMessage httpResponse = await client.SendAsync(request); + using HttpResponseMessage httpResponse = await client.SendAsync(request); // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); @@ -72,10 +72,10 @@ public async Task Post_skips_error_handler() // Arrange using var request = new HttpRequestMessage(HttpMethod.Post, "/NonJsonApi"); - HttpClient client = _testContext.Factory.CreateClient(); + using HttpClient client = _testContext.Factory.CreateClient(); // Act - HttpResponseMessage httpResponse = await client.SendAsync(request); + using HttpResponseMessage httpResponse = await client.SendAsync(request); // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); @@ -101,10 +101,10 @@ public async Task Put_skips_middleware_and_formatters() } }; - HttpClient client = _testContext.Factory.CreateClient(); + using HttpClient client = _testContext.Factory.CreateClient(); // Act - HttpResponseMessage httpResponse = await client.SendAsync(request); + using HttpResponseMessage httpResponse = await client.SendAsync(request); // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); @@ -121,10 +121,10 @@ public async Task Patch_skips_middleware_and_formatters() // Arrange using var request = new HttpRequestMessage(HttpMethod.Patch, "/NonJsonApi?name=Janice"); - HttpClient client = _testContext.Factory.CreateClient(); + using HttpClient client = _testContext.Factory.CreateClient(); // Act - HttpResponseMessage httpResponse = await client.SendAsync(request); + using HttpResponseMessage httpResponse = await client.SendAsync(request); // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); @@ -141,10 +141,10 @@ public async Task Delete_skips_middleware_and_formatters() // Arrange using var request = new HttpRequestMessage(HttpMethod.Delete, "/NonJsonApi"); - HttpClient client = _testContext.Factory.CreateClient(); + using HttpClient client = _testContext.Factory.CreateClient(); // Act - HttpResponseMessage httpResponse = await client.SendAsync(request); + using HttpResponseMessage httpResponse = await client.SendAsync(request); // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/UnknownResourceControllerTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/UnknownResourceControllerTests.cs index 1cfb3cc34c..55d09dc2fe 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/UnknownResourceControllerTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/UnknownResourceControllerTests.cs @@ -22,9 +22,4 @@ public void Fails_at_startup_when_using_controller_for_resource_type_that_is_not action.Should().ThrowExactly().WithMessage($"Controller '{typeof(UnknownResourcesController)}' " + $"depends on resource type '{typeof(UnknownResource)}', which does not exist in the resource graph."); } - - public override void Dispose() - { - // Prevents crash when test cleanup tries to access lazily constructed Factory. - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/Blog.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/Blog.cs index 58a4546ef5..1ad9f4b526 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/Blog.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/Blog.cs @@ -17,6 +17,8 @@ public sealed class Blog : Identifiable [Attr(Capabilities = AttrCapabilities.All & ~(AttrCapabilities.AllowCreate | AttrCapabilities.AllowChange))] public bool ShowAdvertisements => PlatformName.EndsWith("(using free account)", StringComparison.Ordinal); + public bool IsPublished { get; set; } + [HasMany] public IList Posts { get; set; } = new List(); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs index 49a6c99ad6..cfe90a295d 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs @@ -26,10 +26,9 @@ public FilterDataTypeTests(IntegrationTestContext(); options.EnableLegacyFilterNotation = false; - if (!options.SerializerOptions.Converters.Any(converter => converter is JsonStringEnumMemberConverter)) + if (!options.SerializerOptions.Converters.Any(converter => converter is JsonStringEnumConverter)) { - options.SerializerOptions.Converters.Add(new JsonStringEnumMemberConverter()); - options.SerializerOptions.Converters.Add(new JsonTimeSpanConverter()); + options.SerializerOptions.Converters.Add(new JsonStringEnumConverter()); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/LabelColor.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/LabelColor.cs index 4402ecdb05..ce7419c3d6 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/LabelColor.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/LabelColor.cs @@ -4,7 +4,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.QueryStrings; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -[JsonConverter(typeof(JsonStringEnumMemberConverter))] +[JsonConverter(typeof(JsonStringEnumConverter))] public enum LabelColor { Red, diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs index 141c0addb4..292f7edfd8 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs @@ -749,6 +749,7 @@ public async Task Retrieves_all_properties_when_fieldset_contains_readonly_attri store.Clear(); Blog blog = _fakers.Blog.Generate(); + blog.IsPublished = true; await _testContext.RunOnDatabaseAsync(async dbContext => { @@ -771,7 +772,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Data.SingleValue.Relationships.Should().BeNull(); var blogCaptured = (Blog)store.Resources.Should().ContainSingle(resource => resource is Blog).And.Subject.Single(); - blogCaptured.ShowAdvertisements.Should().Be(blogCaptured.ShowAdvertisements); + blogCaptured.ShowAdvertisements.Should().Be(blog.ShowAdvertisements); + blogCaptured.IsPublished.Should().Be(blog.IsPublished); blogCaptured.Title.Should().Be(blog.Title); } @@ -817,7 +819,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var postCaptured = (BlogPost)store.Resources.Should().ContainSingle(resource => resource is BlogPost).And.Subject.Single(); postCaptured.Id.Should().Be(post.Id); postCaptured.Caption.Should().Be(post.Caption); - postCaptured.Url.Should().Be(postCaptured.Url); + postCaptured.Url.Should().Be(post.Url); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs index 67ca5070e7..c7174ec225 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs @@ -168,6 +168,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Act (HttpResponseMessage httpResponse, string responseDocument) = await _testContext.ExecutePatchAsync(route, requestBody); + // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.NoContent); responseDocument.Should().BeEmpty(); @@ -222,6 +223,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Act (HttpResponseMessage httpResponse, string responseDocument) = await _testContext.ExecutePatchAsync(route, requestBody); + // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.NoContent); responseDocument.Should().BeEmpty(); @@ -760,6 +762,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.NoContent); + // Assert responseDocument.Should().BeEmpty(); await _testContext.RunOnDatabaseAsync(async dbContext => diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs index 3b0e69c5f1..8c1a5a4ee8 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs @@ -114,6 +114,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Act (HttpResponseMessage httpResponse, string responseDocument) = await _testContext.ExecutePatchAsync(route, requestBody); + // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.NoContent); responseDocument.Should().BeEmpty(); @@ -283,6 +284,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Act (HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecutePatchAsync(route, requestBody); + // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); responseDocument.Data.SingleValue.ShouldNotBeNull(); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/WorkItemPriority.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/WorkItemPriority.cs index 5a09a274d8..52710fbfbf 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/WorkItemPriority.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/WorkItemPriority.cs @@ -4,7 +4,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ReadWrite; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -[JsonConverter(typeof(JsonStringEnumMemberConverter))] +[JsonConverter(typeof(JsonStringEnumConverter))] public enum WorkItemPriority { Low, diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/ResourceDefinitionReadTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/ResourceDefinitionReadTests.cs index d6b97d556a..efd1f577e6 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/ResourceDefinitionReadTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/ResourceDefinitionReadTests.cs @@ -331,7 +331,7 @@ public async Task Filter_from_resource_definition_is_applied_on_secondary_endpoi await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); - dbContext.Stars.AddRange(star); + dbContext.Stars.Add(star); await dbContext.SaveChangesAsync(); }); @@ -387,7 +387,7 @@ public async Task Filter_from_resource_definition_is_applied_on_relationship_end await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); - dbContext.Stars.AddRange(star); + dbContext.Stars.Add(star); await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/StarKind.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/StarKind.cs index 5e64c578e7..51918a8a3a 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/StarKind.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/StarKind.cs @@ -4,7 +4,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceDefinitions.Reading; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -[JsonConverter(typeof(JsonStringEnumMemberConverter))] +[JsonConverter(typeof(JsonStringEnumConverter))] public enum StarKind { Other, diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs index 85c93428a2..574b3ac622 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationTests.cs @@ -1,6 +1,5 @@ using System.Globalization; using System.Net; -using System.Text.Json.Serialization; using FluentAssertions; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; @@ -34,11 +33,6 @@ public SerializationTests(IntegrationTestContext converter is JsonTimeSpanConverter)) - { - options.SerializerOptions.Converters.Add(new JsonTimeSpanConverter()); - } } [Fact] diff --git a/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj b/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj index b68d9ae4a4..ddb7550e5e 100644 --- a/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj +++ b/test/JsonApiDotNetCoreTests/JsonApiDotNetCoreTests.csproj @@ -17,7 +17,6 @@ - diff --git a/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs b/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs index 200bbfa308..37716fafd1 100644 --- a/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs +++ b/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs @@ -17,8 +17,8 @@ public sealed class HttpResponseMessageAssertions : ReferenceTypeAssertions "response"; - public HttpResponseMessageAssertions(HttpResponseMessage instance) - : base(instance) + public HttpResponseMessageAssertions(HttpResponseMessage subject) + : base(subject) { } diff --git a/test/TestBuildingBlocks/IntegrationTestContext.cs b/test/TestBuildingBlocks/IntegrationTestContext.cs index f25eb29070..8ccbc14079 100644 --- a/test/TestBuildingBlocks/IntegrationTestContext.cs +++ b/test/TestBuildingBlocks/IntegrationTestContext.cs @@ -103,11 +103,14 @@ private WebApplicationFactory CreateFactory() return factoryWithConfiguredContentRoot; } - public virtual void Dispose() + public void Dispose() { - RunOnDatabaseAsync(async dbContext => await dbContext.Database.EnsureDeletedAsync()).Wait(); + if (_lazyFactory.IsValueCreated) + { + RunOnDatabaseAsync(async dbContext => await dbContext.Database.EnsureDeletedAsync()).Wait(); - Factory.Dispose(); + _lazyFactory.Value.Dispose(); + } } public void ConfigureLogging(Action loggingConfiguration) diff --git a/test/TestBuildingBlocks/TestableStartup.cs b/test/TestBuildingBlocks/TestableStartup.cs index a54a317fed..687b9aa406 100644 --- a/test/TestBuildingBlocks/TestableStartup.cs +++ b/test/TestBuildingBlocks/TestableStartup.cs @@ -1,9 +1,7 @@ using JsonApiDotNetCore.Configuration; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; namespace TestBuildingBlocks; @@ -24,7 +22,7 @@ protected virtual void SetJsonApiOptions(JsonApiOptions options) options.SerializerOptions.WriteIndented = true; } - public virtual void Configure(IApplicationBuilder app, IWebHostEnvironment environment, ILoggerFactory loggerFactory) + public virtual void Configure(IApplicationBuilder app) { app.UseRouting(); app.UseJsonApi();