diff --git a/benchmarks/Query/QueryParserBenchmarks.cs b/benchmarks/Query/QueryParserBenchmarks.cs index e4d639727f..990d2a1995 100644 --- a/benchmarks/Query/QueryParserBenchmarks.cs +++ b/benchmarks/Query/QueryParserBenchmarks.cs @@ -107,12 +107,10 @@ private void Run(int iterations, Action action) { private sealed class FakeRequestQueryStringAccessor : IRequestQueryStringAccessor { - public QueryString QueryString { get; private set; } public IQueryCollection Query { get; private set; } public void SetQueryString(string queryString) { - QueryString = new QueryString(queryString); Query = new QueryCollection(QueryHelpers.ParseQuery(queryString)); } } diff --git a/src/JsonApiDotNetCore/Controllers/JsonApiController.cs b/src/JsonApiDotNetCore/Controllers/JsonApiController.cs index b403b72dbd..793ba9cef2 100644 --- a/src/JsonApiDotNetCore/Controllers/JsonApiController.cs +++ b/src/JsonApiDotNetCore/Controllers/JsonApiController.cs @@ -16,10 +16,10 @@ namespace JsonApiDotNetCore.Controllers /// /// The resource type. /// The resource identifier type. - public class JsonApiController : BaseJsonApiController where TResource : class, IIdentifiable + public abstract class JsonApiController : BaseJsonApiController where TResource : class, IIdentifiable { /// - public JsonApiController( + protected JsonApiController( IJsonApiOptions options, ILoggerFactory loggerFactory, IResourceService resourceService) @@ -27,7 +27,7 @@ public JsonApiController( { } /// - public JsonApiController( + protected JsonApiController( IJsonApiOptions options, ILoggerFactory loggerFactory, IGetAllService getAll = null, @@ -118,10 +118,10 @@ public override async Task DeleteRelationshipAsync(TId id, string } /// - public class JsonApiController : JsonApiController where TResource : class, IIdentifiable + public abstract class JsonApiController : JsonApiController where TResource : class, IIdentifiable { /// - public JsonApiController( + protected JsonApiController( IJsonApiOptions options, ILoggerFactory loggerFactory, IResourceService resourceService) @@ -129,7 +129,7 @@ public JsonApiController( { } /// - public JsonApiController( + protected JsonApiController( IJsonApiOptions options, ILoggerFactory loggerFactory, IGetAllService getAll = null, diff --git a/src/JsonApiDotNetCore/Middleware/IControllerResourceMapping.cs b/src/JsonApiDotNetCore/Middleware/IControllerResourceMapping.cs index de48544e79..28719247a9 100644 --- a/src/JsonApiDotNetCore/Middleware/IControllerResourceMapping.cs +++ b/src/JsonApiDotNetCore/Middleware/IControllerResourceMapping.cs @@ -10,6 +10,6 @@ public interface IControllerResourceMapping /// /// Get the associated resource type for the provided controller name. /// - Type GetAssociatedResource(string controllerName); + Type GetResourceTypeForController(string controllerName); } } diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs index 84d861ab26..db24ccc2f4 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs @@ -69,7 +69,7 @@ private static ResourceContext CreatePrimaryResourceContext(RouteValueDictionary var controllerName = (string) routeValues["controller"]; if (controllerName != null) { - var resourceType = controllerResourceMapping.GetAssociatedResource(controllerName); + var resourceType = controllerResourceMapping.GetResourceTypeForController(controllerName); if (resourceType != null) { return resourceContextProvider.GetResourceContext(resourceType); diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs b/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs index 81192b1c29..9a4fde58aa 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs @@ -31,20 +31,20 @@ namespace JsonApiDotNetCore.Middleware public class JsonApiRoutingConvention : IJsonApiRoutingConvention { private readonly IJsonApiOptions _options; - private readonly IResourceGraph _resourceGraph; + private readonly IResourceContextProvider _resourceContextProvider; private readonly HashSet _registeredTemplates = new HashSet(); private readonly Dictionary _registeredResources = new Dictionary(); - public JsonApiRoutingConvention(IJsonApiOptions options, IResourceGraph resourceGraph) + public JsonApiRoutingConvention(IJsonApiOptions options, IResourceContextProvider resourceContextProvider) { _options = options ?? throw new ArgumentNullException(nameof(options)); - _resourceGraph = resourceGraph ?? throw new ArgumentNullException(nameof(resourceGraph)); + _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); } /// - public Type GetAssociatedResource(string controllerName) + public Type GetResourceTypeForController(string controllerName) { if (controllerName == null) throw new ArgumentNullException(nameof(controllerName)); @@ -67,7 +67,7 @@ public void Apply(ApplicationModel application) if (resourceType != null) { - var resourceContext = _resourceGraph.GetResourceContext(resourceType); + var resourceContext = _resourceContextProvider.GetResourceContext(resourceType); if (resourceContext != null) { diff --git a/src/JsonApiDotNetCore/Queries/IQueryLayerComposer.cs b/src/JsonApiDotNetCore/Queries/IQueryLayerComposer.cs index 347beef2e4..1f1628edd0 100644 --- a/src/JsonApiDotNetCore/Queries/IQueryLayerComposer.cs +++ b/src/JsonApiDotNetCore/Queries/IQueryLayerComposer.cs @@ -53,8 +53,8 @@ QueryLayer WrapLayerForSecondaryEndpoint(QueryLayer secondaryLayer, Resourc QueryLayer ComposeForGetRelationshipRightIds(RelationshipAttribute relationship, ICollection rightResourceIds); /// - /// Builds a query for a many-to-many relationship with a filter to match on its left and right resource IDs. + /// Builds a query for a to-many relationship with a filter to match on its left and right resource IDs. /// - QueryLayer ComposeForHasManyThrough(HasManyThroughAttribute hasManyThroughRelationship, TId leftId, ICollection rightResourceIds); + QueryLayer ComposeForHasMany(HasManyAttribute hasManyRelationship, TId leftId, ICollection rightResourceIds); } } diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs index cca019af6e..62d1a8a485 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs @@ -337,12 +337,12 @@ public QueryLayer ComposeForGetRelationshipRightIds(RelationshipAttribute relati } /// - public QueryLayer ComposeForHasManyThrough(HasManyThroughAttribute hasManyThroughRelationship, TId leftId, ICollection rightResourceIds) + public QueryLayer ComposeForHasMany(HasManyAttribute hasManyRelationship, TId leftId, ICollection rightResourceIds) { - var leftResourceContext = _resourceContextProvider.GetResourceContext(hasManyThroughRelationship.LeftType); + var leftResourceContext = _resourceContextProvider.GetResourceContext(hasManyRelationship.LeftType); var leftIdAttribute = GetIdAttribute(leftResourceContext); - var rightResourceContext = _resourceContextProvider.GetResourceContext(hasManyThroughRelationship.RightType); + var rightResourceContext = _resourceContextProvider.GetResourceContext(hasManyRelationship.RightType); var rightIdAttribute = GetIdAttribute(rightResourceContext); var rightTypedIds = rightResourceIds.Select(resource => resource.GetTypedId()).ToArray(); @@ -351,11 +351,11 @@ public QueryLayer ComposeForHasManyThrough(HasManyThroughAttribute hasManyT return new QueryLayer(leftResourceContext) { - Include = new IncludeExpression(new[] {new IncludeElementExpression(hasManyThroughRelationship)}), + Include = new IncludeExpression(new[] {new IncludeElementExpression(hasManyRelationship)}), Filter = leftFilter, Projection = new Dictionary { - [hasManyThroughRelationship] = new QueryLayer(rightResourceContext) + [hasManyRelationship] = new QueryLayer(rightResourceContext) { Filter = rightFilter, Projection = new Dictionary diff --git a/src/JsonApiDotNetCore/QueryStrings/IRequestQueryStringAccessor.cs b/src/JsonApiDotNetCore/QueryStrings/IRequestQueryStringAccessor.cs index c94d5dd533..52a5a5eace 100644 --- a/src/JsonApiDotNetCore/QueryStrings/IRequestQueryStringAccessor.cs +++ b/src/JsonApiDotNetCore/QueryStrings/IRequestQueryStringAccessor.cs @@ -7,7 +7,6 @@ namespace JsonApiDotNetCore.QueryStrings /// public interface IRequestQueryStringAccessor { - QueryString QueryString { get; } IQueryCollection Query { get; } } } diff --git a/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs b/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs index 11c5f0ad2d..c014fe27b3 100644 --- a/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs +++ b/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs @@ -194,7 +194,7 @@ protected void AssertIsNotClearingRequiredRelationship(RelationshipAttribute rel var relationshipIsBeingCleared = relationship is HasOneAttribute ? rightValue == null - : IsRequiredToManyRelationshipBeingCleared(relationship, leftResource, rightValue); + : IsToManyRelationshipBeingCleared(relationship, leftResource, rightValue); if (relationshipIsRequired && relationshipIsBeingCleared) { @@ -203,7 +203,7 @@ protected void AssertIsNotClearingRequiredRelationship(RelationshipAttribute rel } } - private static bool IsRequiredToManyRelationshipBeingCleared(RelationshipAttribute relationship, TResource leftResource, object valueToAssign) + private static bool IsToManyRelationshipBeingCleared(RelationshipAttribute relationship, TResource leftResource, object valueToAssign) { ICollection newRightResourceIds = TypeHelper.ExtractResources(valueToAssign); diff --git a/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs b/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs index bc0c5b44b1..1c1c696ca2 100644 --- a/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs +++ b/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs @@ -36,31 +36,23 @@ public JsonApiWriter(IJsonApiSerializer serializer, IExceptionHandler exceptionH public async Task WriteAsync(OutputFormatterWriteContext context) { - if (context == null) - throw new ArgumentNullException(nameof(context)); + if (context == null) throw new ArgumentNullException(nameof(context)); var response = context.HttpContext.Response; + response.ContentType = HeaderConstants.MediaType; + await using var writer = context.WriterFactory(response.Body, Encoding.UTF8); string responseContent; - - if (_serializer == null) + try { - responseContent = JsonConvert.SerializeObject(context.Object); + responseContent = SerializeResponse(context.Object, (HttpStatusCode) response.StatusCode); } - else + catch (Exception exception) { - response.ContentType = HeaderConstants.MediaType; - try - { - responseContent = SerializeResponse(context.Object, (HttpStatusCode)response.StatusCode); - } - catch (Exception exception) - { - var errorDocument = _exceptionHandler.HandleException(exception); - responseContent = _serializer.Serialize(errorDocument); + var errorDocument = _exceptionHandler.HandleException(exception); + responseContent = _serializer.Serialize(errorDocument); - response.StatusCode = (int)errorDocument.GetErrorStatusCode(); - } + response.StatusCode = (int) errorDocument.GetErrorStatusCode(); } var url = context.HttpContext.Request.GetEncodedUrl(); diff --git a/src/JsonApiDotNetCore/Serialization/Objects/Document.cs b/src/JsonApiDotNetCore/Serialization/Objects/Document.cs index 0be16785de..386309aedd 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/Document.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/Document.cs @@ -14,6 +14,12 @@ public sealed class Document : ExposableData [JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)] public IDictionary Meta { get; set; } + /// + /// see "jsonapi" in https://jsonapi.org/format/#document-top-level + /// + [JsonProperty("jsonapi", NullValueHandling = NullValueHandling.Ignore)] + public IDictionary JsonApi { get; set; } + /// /// see "links" in https://jsonapi.org/format/#document-top-level /// diff --git a/src/JsonApiDotNetCore/Serialization/Objects/RelationshipEntry.cs b/src/JsonApiDotNetCore/Serialization/Objects/RelationshipEntry.cs index 6228f83972..8ebbbf1b16 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/RelationshipEntry.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/RelationshipEntry.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Newtonsoft.Json; namespace JsonApiDotNetCore.Serialization.Objects @@ -6,5 +7,8 @@ public sealed class RelationshipEntry : ExposableData { [JsonProperty("links", NullValueHandling = NullValueHandling.Ignore)] public RelationshipLinks Links { get; set; } + + [JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)] + public IDictionary Meta { get; set; } } } diff --git a/src/JsonApiDotNetCore/Serialization/Objects/ResourceIdentifierObject.cs b/src/JsonApiDotNetCore/Serialization/Objects/ResourceIdentifierObject.cs index af10bc0cab..f3e0268a81 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/ResourceIdentifierObject.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/ResourceIdentifierObject.cs @@ -4,14 +4,6 @@ namespace JsonApiDotNetCore.Serialization.Objects { public class ResourceIdentifierObject { - public ResourceIdentifierObject() { } - - public ResourceIdentifierObject(string type, string id) - { - Type = type; - Id = id; - } - [JsonProperty("type", Order = -3)] public string Type { get; set; } diff --git a/src/JsonApiDotNetCore/Serialization/Objects/TopLevelLinks.cs b/src/JsonApiDotNetCore/Serialization/Objects/TopLevelLinks.cs index 482a89b331..eb868ab837 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/TopLevelLinks.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/TopLevelLinks.cs @@ -13,6 +13,9 @@ public sealed class TopLevelLinks [JsonProperty("related")] public string Related { get; set; } + [JsonProperty("describedby")] + public string DescribedBy { get; set; } + [JsonProperty("first")] public string First { get; set; } @@ -28,6 +31,7 @@ public sealed class TopLevelLinks // http://www.newtonsoft.com/json/help/html/ConditionalProperties.htm public bool ShouldSerializeSelf() => !string.IsNullOrEmpty(Self); public bool ShouldSerializeRelated() => !string.IsNullOrEmpty(Related); + public bool ShouldSerializeDescribedBy() => !string.IsNullOrEmpty(DescribedBy); public bool ShouldSerializeFirst() => !string.IsNullOrEmpty(First); public bool ShouldSerializeLast() => !string.IsNullOrEmpty(Last); public bool ShouldSerializePrev() => !string.IsNullOrEmpty(Prev); diff --git a/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs b/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs index b7fead0fcc..4d776d4e3d 100644 --- a/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs +++ b/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs @@ -186,10 +186,13 @@ public virtual async Task CreateAsync(TResource resource, Cancellatio } catch (DataStoreUpdateException) { - var existingResource = await TryGetPrimaryResourceByIdAsync(resourceFromRequest.Id, TopFieldSelection.OnlyIdAttribute, cancellationToken); - if (existingResource != null) + if (!Equals(resourceFromRequest.Id, default(TId))) { - throw new ResourceAlreadyExistsException(resourceFromRequest.StringId, _request.PrimaryResource.PublicName); + var existingResource = await TryGetPrimaryResourceByIdAsync(resourceFromRequest.Id, TopFieldSelection.OnlyIdAttribute, cancellationToken); + if (existingResource != null) + { + throw new ResourceAlreadyExistsException(resourceFromRequest.StringId, _request.PrimaryResource.PublicName); + } } await AssertResourcesToAssignInRelationshipsExistAsync(resourceFromRequest, cancellationToken); @@ -287,7 +290,7 @@ public async Task AddToToManyRelationshipAsync(TId primaryId, string relationshi private async Task RemoveExistingIdsFromSecondarySet(TId primaryId, ISet secondaryResourceIds, HasManyThroughAttribute hasManyThrough, CancellationToken cancellationToken) { - var queryLayer = _queryLayerComposer.ComposeForHasManyThrough(hasManyThrough, primaryId, secondaryResourceIds); + var queryLayer = _queryLayerComposer.ComposeForHasMany(hasManyThrough, primaryId, secondaryResourceIds); var primaryResources = await _repositoryAccessor.GetAsync(queryLayer, cancellationToken); var primaryResource = primaryResources.FirstOrDefault(); diff --git a/test/JsonApiDotNetCoreExampleTests/Helpers/Extensions/TestServerExtensions.cs b/test/JsonApiDotNetCoreExampleTests/Helpers/Extensions/TestServerExtensions.cs deleted file mode 100644 index a15ad59bb4..0000000000 --- a/test/JsonApiDotNetCoreExampleTests/Helpers/Extensions/TestServerExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Microsoft.AspNetCore.TestHost; -using Microsoft.Extensions.DependencyInjection; - -namespace JsonApiDotNetCoreExampleTests.Helpers.Extensions -{ - public static class TestServerExtensions - { - public static T GetRequiredService(this TestServer server) - { - return (T)server.Host.Services.GetRequiredService(typeof(T)); - } - } -} diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Filtering/FilterDataTypeTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Filtering/FilterDataTypeTests.cs index 1cb8987091..90aa2dd639 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Filtering/FilterDataTypeTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Filtering/FilterDataTypeTests.cs @@ -44,7 +44,7 @@ public async Task Can_filter_equality_on_type(string propertyName, object value) await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, new FilterableResource()); await dbContext.SaveChangesAsync(); @@ -71,7 +71,7 @@ public async Task Can_filter_equality_on_type_Decimal() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, new FilterableResource()); await dbContext.SaveChangesAsync(); @@ -97,7 +97,7 @@ public async Task Can_filter_equality_on_type_Guid() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, new FilterableResource()); await dbContext.SaveChangesAsync(); @@ -123,7 +123,7 @@ public async Task Can_filter_equality_on_type_DateTime() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, new FilterableResource()); await dbContext.SaveChangesAsync(); @@ -152,7 +152,7 @@ public async Task Can_filter_equality_on_type_DateTimeOffset() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, new FilterableResource()); await dbContext.SaveChangesAsync(); @@ -178,7 +178,7 @@ public async Task Can_filter_equality_on_type_TimeSpan() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, new FilterableResource()); await dbContext.SaveChangesAsync(); @@ -204,7 +204,7 @@ public async Task Cannot_filter_equality_on_incompatible_value() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, new FilterableResource()); await dbContext.SaveChangesAsync(); @@ -261,7 +261,7 @@ public async Task Can_filter_is_null_on_type(string propertyName) await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, otherResource); await dbContext.SaveChangesAsync(); @@ -312,7 +312,7 @@ public async Task Can_filter_is_not_null_on_type(string propertyName) await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, new FilterableResource()); await dbContext.SaveChangesAsync(); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Filtering/FilterOperatorTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Filtering/FilterOperatorTests.cs index 792de65335..69254c0632 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Filtering/FilterOperatorTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Filtering/FilterOperatorTests.cs @@ -36,7 +36,7 @@ public async Task Can_filter_equality_on_special_characters() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, new FilterableResource()); await dbContext.SaveChangesAsync(); @@ -72,7 +72,7 @@ public async Task Can_filter_equality_on_two_attributes_of_same_type() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, otherResource); await dbContext.SaveChangesAsync(); @@ -109,7 +109,7 @@ public async Task Can_filter_equality_on_two_attributes_of_same_nullable_type() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, otherResource); await dbContext.SaveChangesAsync(); @@ -146,7 +146,7 @@ public async Task Can_filter_equality_on_two_attributes_with_nullable_at_start() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, otherResource); await dbContext.SaveChangesAsync(); @@ -183,7 +183,7 @@ public async Task Can_filter_equality_on_two_attributes_with_nullable_at_end() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, otherResource); await dbContext.SaveChangesAsync(); @@ -220,7 +220,7 @@ public async Task Can_filter_equality_on_two_attributes_of_compatible_types() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, otherResource); await dbContext.SaveChangesAsync(); @@ -282,7 +282,7 @@ public async Task Can_filter_comparison_on_whole_number(int matchingValue, int n await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, otherResource); await dbContext.SaveChangesAsync(); @@ -324,7 +324,7 @@ public async Task Can_filter_comparison_on_fractional_number(double matchingValu await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, otherResource); await dbContext.SaveChangesAsync(); @@ -366,7 +366,7 @@ public async Task Can_filter_comparison_on_DateTime(string matchingDateTime, str await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, otherResource); await dbContext.SaveChangesAsync(); @@ -405,7 +405,7 @@ public async Task Can_filter_text_match(string matchingText, string nonMatchingT await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, otherResource); await dbContext.SaveChangesAsync(); @@ -441,7 +441,7 @@ public async Task Can_filter_in_set(string matchingText, string nonMatchingText, await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, otherResource); await dbContext.SaveChangesAsync(); @@ -473,7 +473,7 @@ public async Task Can_filter_on_has() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, new FilterableResource()); await dbContext.SaveChangesAsync(); @@ -506,7 +506,7 @@ public async Task Can_filter_on_count() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource, new FilterableResource()); await dbContext.SaveChangesAsync(); @@ -548,7 +548,7 @@ public async Task Can_filter_on_logical_functions(string filterExpression) await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.FilterableResources); + await dbContext.ClearTableAsync(); dbContext.FilterableResources.AddRange(resource1, resource2); await dbContext.SaveChangesAsync(); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs index e39c2bf3c1..8190d2d839 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs @@ -614,7 +614,7 @@ public async Task Can_create_resource_with_attributes_and_multiple_relationship_ { // Arrange var existingUserAccounts = _fakers.UserAccount.Generate(2); - var existingTag = _fakers.WorkTags.Generate(); + var existingTag = _fakers.WorkTag.Generate(); var newDescription = _fakers.WorkItem.Generate().Description; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs index e8d3a32dfa..fa4737837f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs @@ -240,7 +240,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Can_create_HasManyThrough_relationship_with_include_and_fieldsets() { // Arrange - var existingTags = _fakers.WorkTags.Generate(3); + var existingTags = _fakers.WorkTag.Generate(3); var workItemToCreate = _fakers.WorkItem.Generate(); await _testContext.RunOnDatabaseAsync(async dbContext => diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs index deec2340b9..63d996451e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs @@ -187,7 +187,7 @@ public async Task Can_delete_resource_with_HasManyThrough_relationship() var existingWorkItemTag = new WorkItemTag { Item = _fakers.WorkItem.Generate(), - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() }; await _testContext.RunOnDatabaseAsync(async dbContext => diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchRelationshipTests.cs index 14b8a6f490..624b9c9147 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchRelationshipTests.cs @@ -134,11 +134,11 @@ public async Task Can_get_HasManyThrough_relationship() { new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() }, new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() } }; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchResourceTests.cs index 5068c58be1..bb8d39a428 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchResourceTests.cs @@ -256,11 +256,11 @@ public async Task Can_get_secondary_HasManyThrough_resources() { new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() }, new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() } }; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs index ab29923123..9d0e22eaf9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs @@ -120,14 +120,14 @@ public async Task Can_add_to_HasManyThrough_relationship_with_already_assigned_r { new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() } }; existingWorkItems[1].WorkItemTags = new[] { new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() } }; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs index 8f9a1c3e5b..1bb5c9d9b8 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs @@ -121,14 +121,14 @@ public async Task Can_remove_from_HasManyThrough_relationship_with_unassigned_ex { new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() }, new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() } }; - var existingTag = _fakers.WorkTags.Generate(); + var existingTag = _fakers.WorkTag.Generate(); await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs index a5c3449212..309247b8a3 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs @@ -67,7 +67,7 @@ public async Task Can_clear_HasManyThrough_relationship() { new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() } }; @@ -166,15 +166,15 @@ public async Task Can_replace_HasManyThrough_relationship_with_already_assigned_ { new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() }, new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() } }; - var existingTags = _fakers.WorkTags.Generate(2); + var existingTags = _fakers.WorkTag.Generate(2); await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs index 3412c145fe..f05702e1a7 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs @@ -78,7 +78,7 @@ public async Task Can_clear_HasManyThrough_relationship() { new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() } }; @@ -199,15 +199,15 @@ public async Task Can_replace_HasManyThrough_relationship_with_already_assigned_ { new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() }, new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() } }; - var existingTags = _fakers.WorkTags.Generate(2); + var existingTags = _fakers.WorkTag.Generate(2); await _testContext.RunOnDatabaseAsync(async dbContext => { @@ -346,7 +346,7 @@ public async Task Can_replace_HasManyThrough_relationship_with_include_and_field { // Arrange var existingWorkItem = _fakers.WorkItem.Generate(); - var existingTag = _fakers.WorkTags.Generate(); + var existingTag = _fakers.WorkTag.Generate(); await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs index d7a08a4908..e3f5964b1e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs @@ -423,7 +423,7 @@ public async Task Can_update_resource_with_side_effects_with_include_and_fieldse { new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() } }; @@ -977,12 +977,12 @@ public async Task Can_update_resource_with_attributes_and_multiple_relationship_ { new WorkItemTag { - Tag = _fakers.WorkTags.Generate() + Tag = _fakers.WorkTag.Generate() } }; var existingUserAccounts = _fakers.UserAccount.Generate(2); - var existingTag = _fakers.WorkTags.Generate(); + var existingTag = _fakers.WorkTag.Generate(); var newDescription = _fakers.WorkItem.Generate().Description; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WriteFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WriteFakers.cs index ce2ec19eda..737f20eeed 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WriteFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WriteFakers.cs @@ -12,7 +12,7 @@ internal sealed class WriteFakers : FakerContainer .RuleFor(workItem => workItem.DueAt, f => f.Date.Future()) .RuleFor(workItem => workItem.Priority, f => f.PickRandom())); - private readonly Lazy> _lazyWorkTagsFaker = new Lazy>(() => + private readonly Lazy> _lazyWorkTagFaker = new Lazy>(() => new Faker() .UseSeed(GetFakerSeed()) .RuleFor(workTag => workTag.Text, f => f.Lorem.Word()) @@ -37,7 +37,7 @@ internal sealed class WriteFakers : FakerContainer .RuleFor(color => color.DisplayName, f => f.Lorem.Word())); public Faker WorkItem => _lazyWorkItemFaker.Value; - public Faker WorkTags => _lazyWorkTagsFaker.Value; + public Faker WorkTag => _lazyWorkTagFaker.Value; public Faker UserAccount => _lazyUserAccountFaker.Value; public Faker WorkItemGroup => _lazyWorkItemGroupFaker.Value; public Faker RgbColor => _lazyRgbColorFaker.Value; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs index 8e6d6b2d8c..5a49ad59e5 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs @@ -93,7 +93,7 @@ public async Task Filter_from_resource_definition_is_applied() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.CallableResources); + await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); await dbContext.SaveChangesAsync(); @@ -144,7 +144,7 @@ public async Task Filter_from_resource_definition_and_query_string_are_applied() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.CallableResources); + await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); await dbContext.SaveChangesAsync(); @@ -192,7 +192,7 @@ public async Task Sort_from_resource_definition_is_applied() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.CallableResources); + await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); await dbContext.SaveChangesAsync(); @@ -240,7 +240,7 @@ public async Task Sort_from_query_string_is_applied() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.CallableResources); + await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); await dbContext.SaveChangesAsync(); @@ -273,7 +273,7 @@ public async Task Page_size_from_resource_definition_is_applied() await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.CallableResources); + await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); await dbContext.SaveChangesAsync(); @@ -447,7 +447,7 @@ public async Task Queryable_parameter_handler_from_resource_definition_is_applie await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.CallableResources); + await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); await dbContext.SaveChangesAsync(); @@ -496,7 +496,7 @@ public async Task Queryable_parameter_handler_from_resource_definition_and_query await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.RemoveRange(dbContext.CallableResources); + await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); await dbContext.SaveChangesAsync(); diff --git a/test/UnitTests/Builders/LinkBuilderTests.cs b/test/UnitTests/Builders/LinkBuilderTests.cs index 76fce6e770..3799a6d3bf 100644 --- a/test/UnitTests/Builders/LinkBuilderTests.cs +++ b/test/UnitTests/Builders/LinkBuilderTests.cs @@ -224,12 +224,10 @@ private ResourceContext GetArticleResourceContext(LinkTypes resourceLinks = Link private sealed class FakeRequestQueryStringAccessor : IRequestQueryStringAccessor { - public QueryString QueryString { get; } public IQueryCollection Query { get; } public FakeRequestQueryStringAccessor(string queryString) { - QueryString = new QueryString(queryString); Query = new QueryCollection(QueryHelpers.ParseQuery(queryString)); } } diff --git a/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs b/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs index 5ab2fcd1e0..f11f6b3f27 100644 --- a/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs +++ b/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs @@ -98,7 +98,7 @@ private InvokeConfiguration GetConfiguration(string path, string resourceName = }); var forcedNamespace = "api/v1"; var mockMapping = new Mock(); - mockMapping.Setup(x => x.GetAssociatedResource(It.IsAny())).Returns(typeof(string)); + mockMapping.Setup(x => x.GetResourceTypeForController(It.IsAny())).Returns(typeof(string)); Mock mockOptions = CreateMockOptions(forcedNamespace); var mockGraph = CreateMockResourceGraph(resourceName, includeRelationship: relType != null); diff --git a/test/UnitTests/Middleware/JsonApiRequestTests.cs b/test/UnitTests/Middleware/JsonApiRequestTests.cs index f3b2a62508..af1e3a27c5 100644 --- a/test/UnitTests/Middleware/JsonApiRequestTests.cs +++ b/test/UnitTests/Middleware/JsonApiRequestTests.cs @@ -47,7 +47,7 @@ public async Task Sets_request_properties_correctly(string requestMethod, string var controllerResourceMappingMock = new Mock(); controllerResourceMappingMock - .Setup(x => x.GetAssociatedResource(It.IsAny())) + .Setup(x => x.GetResourceTypeForController(It.IsAny())) .Returns(typeof(Article)); var httpContext = new DefaultHttpContext();