From af6b52d0dd51e03a6b6c953b14c55669cecf6383 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Mon, 15 Feb 2021 11:29:55 +0100 Subject: [PATCH 01/60] Replaced null checks with argument guard --- src/JsonApiDotNetCore/ArgumentGuard.cs | 33 +++++++++++++ .../EntityFrameworkCoreTransaction.cs | 7 ++- .../EntityFrameworkCoreTransactionFactory.cs | 8 +-- .../AtomicOperations/LocalIdTracker.cs | 14 +++--- .../AtomicOperations/LocalIdValidator.cs | 8 +-- .../OperationProcessorAccessor.cs | 9 ++-- .../AtomicOperations/OperationsProcessor.cs | 21 +++++--- .../Processors/AddToRelationshipProcessor.cs | 7 +-- .../Processors/CreateProcessor.cs | 13 +++-- .../Processors/DeleteProcessor.cs | 7 +-- .../RemoveFromRelationshipProcessor.cs | 7 +-- .../Processors/SetRelationshipProcessor.cs | 7 +-- .../Processors/UpdateProcessor.cs | 7 +-- .../ApplicationBuilderExtensions.cs | 5 +- .../Configuration/GenericServiceFactory.cs | 14 +++--- .../InverseNavigationResolver.cs | 8 +-- .../JsonApiApplicationBuilder.cs | 13 +++-- .../Configuration/JsonApiValidationFilter.cs | 4 +- .../RequestScopedServiceProvider.cs | 6 ++- .../Configuration/ResourceGraph.cs | 16 +++--- .../Configuration/ResourceGraphBuilder.cs | 15 +++--- .../ServiceCollectionExtensions.cs | 8 +-- .../Configuration/ServiceDiscoveryFacade.cs | 23 ++++----- .../Configuration/TypeLocator.cs | 6 +-- .../DisableQueryStringAttribute.cs | 2 +- .../Annotations/HttpRestrictAttribute.cs | 5 +- .../Controllers/BaseJsonApiController.cs | 31 +++++++----- .../BaseJsonApiOperationsController.cs | 20 +++++--- .../Controllers/CoreJsonApiController.cs | 5 +- .../Controllers/ModelStateViolation.cs | 13 +++-- .../Errors/InvalidModelStateException.cs | 4 +- .../Errors/JsonApiException.cs | 4 +- .../Errors/MissingResourceInRelationship.cs | 12 +++-- .../UnsuccessfulActionResultException.cs | 5 +- .../Internal/ResourceHookExecutorFacade.cs | 9 ++-- .../JsonApiDotNetCore.csproj | 1 + .../AsyncConvertEmptyActionResultFilter.cs | 5 +- .../Middleware/AsyncJsonApiExceptionFilter.cs | 7 +-- .../AsyncQueryStringActionFilter.cs | 9 ++-- .../Middleware/ExceptionHandler.cs | 13 ++--- .../Middleware/HttpContextExtensions.cs | 5 +- .../Middleware/JsonApiInputFormatter.cs | 5 +- .../Middleware/JsonApiMiddleware.cs | 10 ++-- .../Middleware/JsonApiOutputFormatter.cs | 5 +- .../Middleware/JsonApiRequest.cs | 2 +- .../Middleware/JsonApiRoutingConvention.cs | 13 +++-- .../Queries/ExpressionInScope.cs | 5 +- .../CollectionNotEmptyExpression.cs | 5 +- .../Expressions/ComparisonExpression.cs | 7 ++- .../Queries/Expressions/CountExpression.cs | 5 +- .../Expressions/EqualsAnyOfExpression.cs | 7 ++- .../Expressions/IncludeChainConverter.cs | 11 +---- .../Expressions/IncludeElementExpression.cs | 7 ++- .../Queries/Expressions/IncludeExpression.cs | 4 +- .../Expressions/LiteralConstantExpression.cs | 6 +-- .../Queries/Expressions/LogicalExpression.cs | 5 +- .../Expressions/MatchTextExpression.cs | 7 ++- .../Queries/Expressions/NotExpression.cs | 5 +- .../Expressions/PaginationExpression.cs | 4 +- .../PaginationQueryStringValueExpression.cs | 6 ++- .../QueryStringParameterScopeExpression.cs | 4 +- .../Expressions/QueryableHandlerExpression.cs | 4 +- .../ResourceFieldChainExpression.cs | 9 ++-- .../Expressions/SortElementExpression.cs | 8 ++- .../Queries/Expressions/SortExpression.cs | 4 +- .../Expressions/SparseFieldSetExpression.cs | 4 +- .../SparseFieldSetExpressionExtensions.cs | 22 ++------- .../Expressions/SparseFieldTableExpression.cs | 4 +- .../Queries/Internal/Parsing/FilterParser.cs | 9 +++- .../Queries/Internal/Parsing/IncludeParser.cs | 5 +- .../Internal/Parsing/PaginationParser.cs | 5 +- .../QueryStringParameterScopeParser.cs | 5 +- .../Internal/Parsing/QueryTokenizer.cs | 5 +- .../Parsing/ResourceFieldChainResolver.cs | 4 +- .../Queries/Internal/Parsing/SortParser.cs | 5 +- .../Internal/Parsing/SparseFieldSetParser.cs | 5 +- .../Queries/Internal/QueryLayerComposer.cs | 49 +++++++++++-------- .../QueryableBuilding/IncludeClauseBuilder.cs | 16 +++--- .../LambdaParameterNameFactory.cs | 6 +-- .../LambdaParameterNameScope.cs | 7 ++- .../Internal/QueryableBuilding/LambdaScope.cs | 4 +- .../QueryableBuilding/LambdaScopeFactory.cs | 9 ++-- .../QueryableBuilding/OrderClauseBuilder.cs | 12 ++--- .../QueryableBuilding/QueryClauseBuilder.cs | 4 +- .../QueryableBuilding/QueryableBuilder.cs | 24 ++++++--- .../QueryableBuilding/SelectClauseBuilder.cs | 37 ++++++++------ .../SkipTakeClauseBuilder.cs | 12 ++--- .../QueryableBuilding/WhereClauseBuilder.cs | 12 ++--- .../Queries/Internal/SparseFieldSetCache.cs | 11 +++-- src/JsonApiDotNetCore/Queries/QueryLayer.cs | 4 +- .../DefaultsQueryStringParameterReader.cs | 7 +-- .../FilterQueryStringParameterReader.cs | 6 ++- .../IncludeQueryStringParameterReader.cs | 7 +-- .../Internal/LegacyFilterNotationConverter.cs | 4 +- .../NullsQueryStringParameterReader.cs | 7 +-- .../PaginationQueryStringParameterReader.cs | 6 ++- .../Internal/QueryStringParameterReader.cs | 9 ++-- .../Internal/QueryStringReader.cs | 13 ++--- .../Internal/RequestQueryStringAccessor.cs | 6 +-- ...ourceDefinitionQueryableParameterReader.cs | 8 +-- .../SortQueryStringParameterReader.cs | 2 +- ...parseFieldSetQueryStringParameterReader.cs | 2 +- .../Repositories/DbContextExtensions.cs | 11 ++--- .../Repositories/DbContextResolver.cs | 5 +- .../EntityFrameworkCoreRepository.cs | 41 ++++++++++------ .../MemoryLeakDetectionBugRewriter.cs | 3 +- .../PlaceholderEntityCollector.cs | 7 ++- .../ResourceRepositoryAccessor.cs | 12 +++-- .../Resources/Annotations/AttrAttribute.cs | 10 +--- .../Annotations/HasManyThroughAttribute.cs | 8 +-- .../Annotations/RelationshipAttribute.cs | 4 +- .../Annotations/ResourceAttribute.cs | 4 +- .../Resources/IdentifiableExtensions.cs | 4 +- .../Resources/JsonApiResourceDefinition.cs | 9 ++-- .../Resources/OperationContainer.cs | 12 +++-- .../Resources/ResourceChangeTracker.cs | 17 ++++--- .../Resources/ResourceDefinitionAccessor.cs | 23 +++++---- .../Resources/ResourceFactory.cs | 11 ++--- .../Resources/ResourceHooksDefinition.cs | 5 +- .../AtomicOperationsResponseSerializer.cs | 16 ++++-- .../Serialization/BaseDeserializer.cs | 17 ++++--- .../Serialization/BaseSerializer.cs | 8 +-- .../Building/IncludedResourceObjectBuilder.cs | 20 +++++--- .../Serialization/Building/LinkBuilder.cs | 24 +++++---- .../Serialization/Building/MetaBuilder.cs | 13 +++-- .../Building/ResourceObjectBuilder.cs | 18 ++++--- .../ResourceObjectBuilderSettingsProvider.cs | 8 +-- .../Building/ResponseResourceObjectBuilder.cs | 23 +++++---- .../Client/Internal/RequestSerializer.cs | 6 ++- .../Client/Internal/ResponseDeserializer.cs | 8 +-- .../Serialization/FieldsToSerialize.cs | 11 +++-- .../Serialization/JsonApiReader.cs | 16 +++--- .../Serialization/JsonApiWriter.cs | 10 ++-- .../Serialization/Objects/ErrorDocument.cs | 2 +- .../Serialization/RequestDeserializer.cs | 15 ++++-- .../Serialization/ResponseSerializer.cs | 22 ++++++--- .../ResponseSerializerFactory.cs | 7 ++- .../Services/JsonApiResourceService.cs | 47 +++++++++++------- src/JsonApiDotNetCore/TypeHelper.cs | 19 ++----- .../MusicTrackReleaseDefinition.cs | 5 +- .../InjectionDbContext.cs | 6 ++- .../InjectionFakers.cs | 5 +- .../Models/ResourceConstructionTests.cs | 9 +++- 143 files changed, 844 insertions(+), 598 deletions(-) create mode 100644 src/JsonApiDotNetCore/ArgumentGuard.cs diff --git a/src/JsonApiDotNetCore/ArgumentGuard.cs b/src/JsonApiDotNetCore/ArgumentGuard.cs new file mode 100644 index 0000000000..68c76ca96e --- /dev/null +++ b/src/JsonApiDotNetCore/ArgumentGuard.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using JetBrains.Annotations; + +namespace JsonApiDotNetCore +{ + public static class ArgumentGuard + { + [AssertionMethod] + [ContractAnnotation("value: null => halt")] + public static void NotNull([CanBeNull] [NoEnumeration] T value, [NotNull] [InvokerParameterName] string name) + where T : class + { + if (value is null) + { + throw new ArgumentNullException(name); + } + } + + [AssertionMethod] + [ContractAnnotation("value: null => halt")] + public static void NotNullNorEmpty([CanBeNull] IEnumerable value, [NotNull] [InvokerParameterName] string name) + { + NotNull(value, name); + + if (!value.Any()) + { + throw new ArgumentException("Collection cannot be empty.", name); + } + } + } +} diff --git a/src/JsonApiDotNetCore/AtomicOperations/EntityFrameworkCoreTransaction.cs b/src/JsonApiDotNetCore/AtomicOperations/EntityFrameworkCoreTransaction.cs index f863a03d1e..7e2bf88bb5 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/EntityFrameworkCoreTransaction.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/EntityFrameworkCoreTransaction.cs @@ -20,8 +20,11 @@ public sealed class EntityFrameworkCoreTransaction : IOperationsTransaction public EntityFrameworkCoreTransaction(IDbContextTransaction transaction, DbContext dbContext) { - _transaction = transaction ?? throw new ArgumentNullException(nameof(transaction)); - _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); + ArgumentGuard.NotNull(transaction, nameof(transaction)); + ArgumentGuard.NotNull(dbContext, nameof(dbContext)); + + _transaction = transaction; + _dbContext = dbContext; } /// diff --git a/src/JsonApiDotNetCore/AtomicOperations/EntityFrameworkCoreTransactionFactory.cs b/src/JsonApiDotNetCore/AtomicOperations/EntityFrameworkCoreTransactionFactory.cs index afde631c33..e115c133be 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/EntityFrameworkCoreTransactionFactory.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/EntityFrameworkCoreTransactionFactory.cs @@ -1,4 +1,3 @@ -using System; using System.Threading; using System.Threading.Tasks; using JsonApiDotNetCore.Configuration; @@ -17,8 +16,11 @@ public sealed class EntityFrameworkCoreTransactionFactory : IOperationsTransacti public EntityFrameworkCoreTransactionFactory(IDbContextResolver dbContextResolver, IJsonApiOptions options) { - _dbContextResolver = dbContextResolver ?? throw new ArgumentNullException(nameof(dbContextResolver)); - _options = options ?? throw new ArgumentNullException(nameof(options)); + ArgumentGuard.NotNull(dbContextResolver, nameof(dbContextResolver)); + ArgumentGuard.NotNull(options, nameof(options)); + + _dbContextResolver = dbContextResolver; + _options = options; } /// diff --git a/src/JsonApiDotNetCore/AtomicOperations/LocalIdTracker.cs b/src/JsonApiDotNetCore/AtomicOperations/LocalIdTracker.cs index ae475027c5..2c8b7ab53c 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/LocalIdTracker.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/LocalIdTracker.cs @@ -20,8 +20,8 @@ public void Reset() /// public void Declare(string localId, string resourceType) { - if (localId == null) throw new ArgumentNullException(nameof(localId)); - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(localId, nameof(localId)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); AssertIsNotDeclared(localId); @@ -43,9 +43,9 @@ private void AssertIsNotDeclared(string localId) /// public void Assign(string localId, string resourceType, string stringId) { - if (localId == null) throw new ArgumentNullException(nameof(localId)); - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); - if (stringId == null) throw new ArgumentNullException(nameof(stringId)); + ArgumentGuard.NotNull(localId, nameof(localId)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); + ArgumentGuard.NotNull(stringId, nameof(stringId)); AssertIsDeclared(localId); @@ -64,8 +64,8 @@ public void Assign(string localId, string resourceType, string stringId) /// public string GetValue(string localId, string resourceType) { - if (localId == null) throw new ArgumentNullException(nameof(localId)); - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(localId, nameof(localId)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); AssertIsDeclared(localId); diff --git a/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs b/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs index c5e2a09f03..13a03f9139 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; @@ -17,8 +16,11 @@ public sealed class LocalIdValidator public LocalIdValidator(ILocalIdTracker localIdTracker, IResourceContextProvider resourceContextProvider) { - _localIdTracker = localIdTracker ?? throw new ArgumentNullException(nameof(localIdTracker)); - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); + ArgumentGuard.NotNull(localIdTracker, nameof(localIdTracker)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + + _localIdTracker = localIdTracker; + _resourceContextProvider = resourceContextProvider; } public void Validate(IEnumerable operations) diff --git a/src/JsonApiDotNetCore/AtomicOperations/OperationProcessorAccessor.cs b/src/JsonApiDotNetCore/AtomicOperations/OperationProcessorAccessor.cs index 31dea19969..614dde20f6 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/OperationProcessorAccessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/OperationProcessorAccessor.cs @@ -18,14 +18,17 @@ public class OperationProcessorAccessor : IOperationProcessorAccessor public OperationProcessorAccessor(IResourceContextProvider resourceContextProvider, IServiceProvider serviceProvider) { - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); - _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + ArgumentGuard.NotNull(serviceProvider, nameof(serviceProvider)); + + _resourceContextProvider = resourceContextProvider; + _serviceProvider = serviceProvider; } /// public Task ProcessAsync(OperationContainer operation, CancellationToken cancellationToken) { - if (operation == null) throw new ArgumentNullException(nameof(operation)); + ArgumentGuard.NotNull(operation, nameof(operation)); var processor = ResolveProcessor(operation); return processor.ProcessAsync(operation, cancellationToken); diff --git a/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs index 80f2a2a454..fb97ccbd50 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs @@ -26,12 +26,19 @@ public OperationsProcessor(IOperationProcessorAccessor operationProcessorAccesso IOperationsTransactionFactory operationsTransactionFactory, ILocalIdTracker localIdTracker, IResourceContextProvider resourceContextProvider, IJsonApiRequest request, ITargetedFields targetedFields) { - _operationProcessorAccessor = operationProcessorAccessor ?? throw new ArgumentNullException(nameof(operationProcessorAccessor)); - _operationsTransactionFactory = operationsTransactionFactory ?? throw new ArgumentNullException(nameof(operationsTransactionFactory)); - _localIdTracker = localIdTracker ?? throw new ArgumentNullException(nameof(localIdTracker)); - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); - _request = request ?? throw new ArgumentNullException(nameof(request)); - _targetedFields = targetedFields ?? throw new ArgumentNullException(nameof(targetedFields)); + ArgumentGuard.NotNull(operationProcessorAccessor, nameof(operationProcessorAccessor)); + ArgumentGuard.NotNull(operationsTransactionFactory, nameof(operationsTransactionFactory)); + ArgumentGuard.NotNull(localIdTracker, nameof(localIdTracker)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + ArgumentGuard.NotNull(request, nameof(request)); + ArgumentGuard.NotNull(targetedFields, nameof(targetedFields)); + + _operationProcessorAccessor = operationProcessorAccessor; + _operationsTransactionFactory = operationsTransactionFactory; + _localIdTracker = localIdTracker; + _resourceContextProvider = resourceContextProvider; + _request = request; + _targetedFields = targetedFields; _localIdValidator = new LocalIdValidator(_localIdTracker, _resourceContextProvider); } @@ -39,7 +46,7 @@ public OperationsProcessor(IOperationProcessorAccessor operationProcessorAccesso public virtual async Task> ProcessAsync(IList operations, CancellationToken cancellationToken) { - if (operations == null) throw new ArgumentNullException(nameof(operations)); + ArgumentGuard.NotNull(operations, nameof(operations)); _localIdValidator.Validate(operations); _localIdTracker.Reset(); diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/AddToRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/AddToRelationshipProcessor.cs index 8aeba25d8f..a7c42a514c 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/AddToRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/AddToRelationshipProcessor.cs @@ -1,4 +1,3 @@ -using System; using System.Threading; using System.Threading.Tasks; using JsonApiDotNetCore.Resources; @@ -14,14 +13,16 @@ public class AddToRelationshipProcessor : IAddToRelationshipProc public AddToRelationshipProcessor(IAddToRelationshipService service) { - _service = service ?? throw new ArgumentNullException(nameof(service)); + ArgumentGuard.NotNull(service, nameof(service)); + + _service = service; } /// public virtual async Task ProcessAsync(OperationContainer operation, CancellationToken cancellationToken) { - if (operation == null) throw new ArgumentNullException(nameof(operation)); + ArgumentGuard.NotNull(operation, nameof(operation)); var primaryId = (TId) operation.Resource.GetTypedId(); var secondaryResourceIds = operation.GetSecondaryResources(); diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/CreateProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/CreateProcessor.cs index 062e096910..8e0b66d6c8 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/CreateProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/CreateProcessor.cs @@ -1,4 +1,3 @@ -using System; using System.Threading; using System.Threading.Tasks; using JsonApiDotNetCore.Configuration; @@ -18,16 +17,20 @@ public class CreateProcessor : ICreateProcessor public CreateProcessor(ICreateService service, ILocalIdTracker localIdTracker, IResourceContextProvider resourceContextProvider) { - _service = service ?? throw new ArgumentNullException(nameof(service)); - _localIdTracker = localIdTracker ?? throw new ArgumentNullException(nameof(localIdTracker)); - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); + ArgumentGuard.NotNull(service, nameof(service)); + ArgumentGuard.NotNull(localIdTracker, nameof(localIdTracker)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + + _service = service; + _localIdTracker = localIdTracker; + _resourceContextProvider = resourceContextProvider; } /// public virtual async Task ProcessAsync(OperationContainer operation, CancellationToken cancellationToken) { - if (operation == null) throw new ArgumentNullException(nameof(operation)); + ArgumentGuard.NotNull(operation, nameof(operation)); var newResource = await _service.CreateAsync((TResource) operation.Resource, cancellationToken); diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/DeleteProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/DeleteProcessor.cs index dea9ba72da..f5780ba1b8 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/DeleteProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/DeleteProcessor.cs @@ -1,4 +1,3 @@ -using System; using System.Threading; using System.Threading.Tasks; using JsonApiDotNetCore.Resources; @@ -14,14 +13,16 @@ public class DeleteProcessor : IDeleteProcessor public DeleteProcessor(IDeleteService service) { - _service = service ?? throw new ArgumentNullException(nameof(service)); + ArgumentGuard.NotNull(service, nameof(service)); + + _service = service; } /// public virtual async Task ProcessAsync(OperationContainer operation, CancellationToken cancellationToken) { - if (operation == null) throw new ArgumentNullException(nameof(operation)); + ArgumentGuard.NotNull(operation, nameof(operation)); var id = (TId) operation.Resource.GetTypedId(); await _service.DeleteAsync(id, cancellationToken); diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/RemoveFromRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/RemoveFromRelationshipProcessor.cs index 2ed9152d93..789b5d8592 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/RemoveFromRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/RemoveFromRelationshipProcessor.cs @@ -1,4 +1,3 @@ -using System; using System.Threading; using System.Threading.Tasks; using JsonApiDotNetCore.Resources; @@ -14,14 +13,16 @@ public class RemoveFromRelationshipProcessor : IRemoveFromRelati public RemoveFromRelationshipProcessor(IRemoveFromRelationshipService service) { - _service = service ?? throw new ArgumentNullException(nameof(service)); + ArgumentGuard.NotNull(service, nameof(service)); + + _service = service; } /// public virtual async Task ProcessAsync(OperationContainer operation, CancellationToken cancellationToken) { - if (operation == null) throw new ArgumentNullException(nameof(operation)); + ArgumentGuard.NotNull(operation, nameof(operation)); var primaryId = (TId) operation.Resource.GetTypedId(); var secondaryResourceIds = operation.GetSecondaryResources(); diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/SetRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/SetRelationshipProcessor.cs index 979f44237b..0c0b0a6a63 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/SetRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/SetRelationshipProcessor.cs @@ -1,4 +1,3 @@ -using System; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -16,14 +15,16 @@ public class SetRelationshipProcessor : ISetRelationshipProcesso public SetRelationshipProcessor(ISetRelationshipService service) { - _service = service ?? throw new ArgumentNullException(nameof(service)); + ArgumentGuard.NotNull(service, nameof(service)); + + _service = service; } /// public virtual async Task ProcessAsync(OperationContainer operation, CancellationToken cancellationToken) { - if (operation == null) throw new ArgumentNullException(nameof(operation)); + ArgumentGuard.NotNull(operation, nameof(operation)); var primaryId = (TId) operation.Resource.GetTypedId(); object rightValue = GetRelationshipRightValue(operation); diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/UpdateProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/UpdateProcessor.cs index 25f3232ffc..c714e96c7c 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/UpdateProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/UpdateProcessor.cs @@ -1,4 +1,3 @@ -using System; using System.Threading; using System.Threading.Tasks; using JsonApiDotNetCore.Resources; @@ -14,14 +13,16 @@ public class UpdateProcessor : IUpdateProcessor public UpdateProcessor(IUpdateService service) { - _service = service ?? throw new ArgumentNullException(nameof(service)); + ArgumentGuard.NotNull(service, nameof(service)); + + _service = service; } /// public virtual async Task ProcessAsync(OperationContainer operation, CancellationToken cancellationToken) { - if (operation == null) throw new ArgumentNullException(nameof(operation)); + ArgumentGuard.NotNull(operation, nameof(operation)); var resource = (TResource) operation.Resource; var updated = await _service.UpdateAsync(resource.Id, resource, cancellationToken); diff --git a/src/JsonApiDotNetCore/Configuration/ApplicationBuilderExtensions.cs b/src/JsonApiDotNetCore/Configuration/ApplicationBuilderExtensions.cs index b176df1ead..f0a4e6715e 100644 --- a/src/JsonApiDotNetCore/Configuration/ApplicationBuilderExtensions.cs +++ b/src/JsonApiDotNetCore/Configuration/ApplicationBuilderExtensions.cs @@ -1,4 +1,3 @@ -using System; using JsonApiDotNetCore.Middleware; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; @@ -22,8 +21,8 @@ public static class ApplicationBuilderExtensions /// public static void UseJsonApi(this IApplicationBuilder builder) { - if (builder == null) throw new ArgumentNullException(nameof(builder)); - + ArgumentGuard.NotNull(builder, nameof(builder)); + using var scope = builder.ApplicationServices.GetRequiredService().CreateScope(); var inverseNavigationResolver = scope.ServiceProvider.GetRequiredService(); inverseNavigationResolver.Resolve(); diff --git a/src/JsonApiDotNetCore/Configuration/GenericServiceFactory.cs b/src/JsonApiDotNetCore/Configuration/GenericServiceFactory.cs index d421102c08..ca71ae0470 100644 --- a/src/JsonApiDotNetCore/Configuration/GenericServiceFactory.cs +++ b/src/JsonApiDotNetCore/Configuration/GenericServiceFactory.cs @@ -9,14 +9,16 @@ public sealed class GenericServiceFactory : IGenericServiceFactory public GenericServiceFactory(IRequestScopedServiceProvider serviceProvider) { - _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + ArgumentGuard.NotNull(serviceProvider, nameof(serviceProvider)); + + _serviceProvider = serviceProvider; } /// public TInterface Get(Type openGenericType, Type resourceType) { - if (openGenericType == null) throw new ArgumentNullException(nameof(openGenericType)); - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(openGenericType, nameof(openGenericType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); return GetInternal(openGenericType, resourceType); } @@ -24,9 +26,9 @@ public TInterface Get(Type openGenericType, Type resourceType) /// public TInterface Get(Type openGenericType, Type resourceType, Type keyType) { - if (openGenericType == null) throw new ArgumentNullException(nameof(openGenericType)); - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); - if (keyType == null) throw new ArgumentNullException(nameof(keyType)); + ArgumentGuard.NotNull(openGenericType, nameof(openGenericType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); + ArgumentGuard.NotNull(keyType, nameof(keyType)); return GetInternal(openGenericType, resourceType, keyType); } diff --git a/src/JsonApiDotNetCore/Configuration/InverseNavigationResolver.cs b/src/JsonApiDotNetCore/Configuration/InverseNavigationResolver.cs index bc93eff7e0..4333623529 100644 --- a/src/JsonApiDotNetCore/Configuration/InverseNavigationResolver.cs +++ b/src/JsonApiDotNetCore/Configuration/InverseNavigationResolver.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using JsonApiDotNetCore.Repositories; using JsonApiDotNetCore.Resources.Annotations; @@ -16,8 +15,11 @@ public class InverseNavigationResolver : IInverseNavigationResolver public InverseNavigationResolver(IResourceContextProvider resourceContextProvider, IEnumerable dbContextResolvers) { - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); - _dbContextResolvers = dbContextResolvers ?? throw new ArgumentNullException(nameof(dbContextResolvers)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + ArgumentGuard.NotNull(dbContextResolvers, nameof(dbContextResolvers)); + + _resourceContextProvider = resourceContextProvider; + _dbContextResolvers = dbContextResolvers; } /// diff --git a/src/JsonApiDotNetCore/Configuration/JsonApiApplicationBuilder.cs b/src/JsonApiDotNetCore/Configuration/JsonApiApplicationBuilder.cs index 25fe41bbd7..0c0c12b54f 100644 --- a/src/JsonApiDotNetCore/Configuration/JsonApiApplicationBuilder.cs +++ b/src/JsonApiDotNetCore/Configuration/JsonApiApplicationBuilder.cs @@ -44,16 +44,19 @@ internal sealed class JsonApiApplicationBuilder : IJsonApiApplicationBuilder, ID public JsonApiApplicationBuilder(IServiceCollection services, IMvcCoreBuilder mvcBuilder) { - _services = services ?? throw new ArgumentNullException(nameof(services)); - _mvcBuilder = mvcBuilder ?? throw new ArgumentNullException(nameof(mvcBuilder)); - + ArgumentGuard.NotNull(services, nameof(services)); + ArgumentGuard.NotNull(mvcBuilder, nameof(mvcBuilder)); + + _services = services; + _mvcBuilder = mvcBuilder; _intermediateProvider = services.BuildServiceProvider(); + var loggerFactory = _intermediateProvider.GetRequiredService(); - + _resourceGraphBuilder = new ResourceGraphBuilder(_options, loggerFactory); _serviceDiscoveryFacade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, _options, loggerFactory); } - + /// /// Executes the action provided by the user to configure . /// diff --git a/src/JsonApiDotNetCore/Configuration/JsonApiValidationFilter.cs b/src/JsonApiDotNetCore/Configuration/JsonApiValidationFilter.cs index c866a831f0..9baa1e3194 100644 --- a/src/JsonApiDotNetCore/Configuration/JsonApiValidationFilter.cs +++ b/src/JsonApiDotNetCore/Configuration/JsonApiValidationFilter.cs @@ -17,7 +17,9 @@ internal sealed class JsonApiValidationFilter : IPropertyValidationFilter public JsonApiValidationFilter(IRequestScopedServiceProvider serviceProvider) { - _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + ArgumentGuard.NotNull(serviceProvider, nameof(serviceProvider)); + + _serviceProvider = serviceProvider; } /// diff --git a/src/JsonApiDotNetCore/Configuration/RequestScopedServiceProvider.cs b/src/JsonApiDotNetCore/Configuration/RequestScopedServiceProvider.cs index 1601e08c73..0bd2b71477 100644 --- a/src/JsonApiDotNetCore/Configuration/RequestScopedServiceProvider.cs +++ b/src/JsonApiDotNetCore/Configuration/RequestScopedServiceProvider.cs @@ -10,13 +10,15 @@ public sealed class RequestScopedServiceProvider : IRequestScopedServiceProvider public RequestScopedServiceProvider(IHttpContextAccessor httpContextAccessor) { - _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor)); + ArgumentGuard.NotNull(httpContextAccessor, nameof(httpContextAccessor)); + + _httpContextAccessor = httpContextAccessor; } /// public object GetService(Type serviceType) { - if (serviceType == null) throw new ArgumentNullException(nameof(serviceType)); + ArgumentGuard.NotNull(serviceType, nameof(serviceType)); if (_httpContextAccessor.HttpContext == null) { diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs index 90b5b0b83a..d729e7148f 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs @@ -15,7 +15,9 @@ public class ResourceGraph : IResourceGraph public ResourceGraph(IReadOnlyCollection resources) { - _resources = resources ?? throw new ArgumentNullException(nameof(resources)); + ArgumentGuard.NotNull(resources, nameof(resources)); + + _resources = resources; } /// @@ -24,7 +26,7 @@ public ResourceGraph(IReadOnlyCollection resources) /// public ResourceContext GetResourceContext(string resourceName) { - if (resourceName == null) throw new ArgumentNullException(nameof(resourceName)); + ArgumentGuard.NotNull(resourceName, nameof(resourceName)); return _resources.SingleOrDefault(e => e.PublicName == resourceName); } @@ -32,7 +34,7 @@ public ResourceContext GetResourceContext(string resourceName) /// public ResourceContext GetResourceContext(Type resourceType) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); return IsLazyLoadingProxyForResourceType(resourceType) ? _resources.SingleOrDefault(e => e.ResourceType == resourceType.BaseType) @@ -64,7 +66,7 @@ public IReadOnlyCollection GetRelationships(Ex /// public IReadOnlyCollection GetFields(Type type) { - if (type == null) throw new ArgumentNullException(nameof(type)); + ArgumentGuard.NotNull(type, nameof(type)); return GetResourceContext(type).Fields; } @@ -72,7 +74,7 @@ public IReadOnlyCollection GetFields(Type type) /// public IReadOnlyCollection GetAttributes(Type type) { - if (type == null) throw new ArgumentNullException(nameof(type)); + ArgumentGuard.NotNull(type, nameof(type)); return GetResourceContext(type).Attributes; } @@ -80,7 +82,7 @@ public IReadOnlyCollection GetAttributes(Type type) /// public IReadOnlyCollection GetRelationships(Type type) { - if (type == null) throw new ArgumentNullException(nameof(type)); + ArgumentGuard.NotNull(type, nameof(type)); return GetResourceContext(type).Relationships; } @@ -88,7 +90,7 @@ public IReadOnlyCollection GetRelationships(Type type) /// public RelationshipAttribute GetInverseRelationship(RelationshipAttribute relationship) { - if (relationship == null) throw new ArgumentNullException(nameof(relationship)); + ArgumentGuard.NotNull(relationship, nameof(relationship)); if (relationship.InverseNavigationProperty == null) { diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs index 998d153051..e1434ea252 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs @@ -20,9 +20,10 @@ public class ResourceGraphBuilder public ResourceGraphBuilder(IJsonApiOptions options, ILoggerFactory loggerFactory) { - if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); + ArgumentGuard.NotNull(options, nameof(options)); + ArgumentGuard.NotNull(loggerFactory, nameof(loggerFactory)); - _options = options ?? throw new ArgumentNullException(nameof(options)); + _options = options; _logger = loggerFactory.CreateLogger(); } @@ -80,7 +81,7 @@ public ResourceGraphBuilder Add(string publicName = null) where /// public ResourceGraphBuilder Add(Type resourceType, Type idType = null, string publicName = null) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); if (_resources.All(e => e.ResourceType != resourceType)) { @@ -112,7 +113,7 @@ public ResourceGraphBuilder Add(Type resourceType, Type idType = null, string pu private IReadOnlyCollection GetAttributes(Type resourceType) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); var attributes = new List(); @@ -153,7 +154,7 @@ private IReadOnlyCollection GetAttributes(Type resourceType) private IReadOnlyCollection GetRelationships(Type resourceType) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); var attributes = new List(); var properties = resourceType.GetProperties(); @@ -249,8 +250,8 @@ private Type TryGetThroughType(PropertyInfo throughProperty) private Type GetRelationshipType(RelationshipAttribute relationship, PropertyInfo property) { - if (relationship == null) throw new ArgumentNullException(nameof(relationship)); - if (property == null) throw new ArgumentNullException(nameof(property)); + ArgumentGuard.NotNull(relationship, nameof(relationship)); + ArgumentGuard.NotNull(property, nameof(property)); return relationship is HasOneAttribute ? property.PropertyType : property.PropertyType.GetGenericArguments()[0]; } diff --git a/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs b/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs index bfd3c5180f..ccc01d75cf 100644 --- a/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs +++ b/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs @@ -24,7 +24,7 @@ public static IServiceCollection AddJsonApi(this IServiceCollection services, IMvcCoreBuilder mvcBuilder = null, ICollection dbContextTypes = null) { - if (services == null) throw new ArgumentNullException(nameof(services)); + ArgumentGuard.NotNull(services, nameof(services)); SetupApplicationBuilder(services, options, discovery, resources, mvcBuilder, dbContextTypes ?? Array.Empty()); @@ -66,7 +66,7 @@ private static void SetupApplicationBuilder(IServiceCollection services, Action< /// public static IServiceCollection AddClientSerialization(this IServiceCollection services) { - if (services == null) throw new ArgumentNullException(nameof(services)); + ArgumentGuard.NotNull(services, nameof(services)); services.AddScoped(); services.AddScoped(sp => @@ -83,7 +83,7 @@ public static IServiceCollection AddClientSerialization(this IServiceCollection /// public static IServiceCollection AddResourceService(this IServiceCollection services) { - if (services == null) throw new ArgumentNullException(nameof(services)); + ArgumentGuard.NotNull(services, nameof(services)); RegisterForConstructedType(services, typeof(TService), ServiceDiscoveryFacade.ServiceInterfaces); @@ -96,7 +96,7 @@ public static IServiceCollection AddResourceService(this IServiceColle /// public static IServiceCollection AddResourceRepository(this IServiceCollection services) { - if (services == null) throw new ArgumentNullException(nameof(services)); + ArgumentGuard.NotNull(services, nameof(services)); RegisterForConstructedType(services, typeof(TRepository), ServiceDiscoveryFacade.RepositoryInterfaces); diff --git a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs index b9a4926d74..cee27f83b2 100644 --- a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs +++ b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs @@ -68,15 +68,15 @@ public class ServiceDiscoveryFacade public ServiceDiscoveryFacade(IServiceCollection services, ResourceGraphBuilder resourceGraphBuilder, IJsonApiOptions options, ILoggerFactory loggerFactory) { - if (loggerFactory == null) - { - throw new ArgumentNullException(nameof(loggerFactory)); - } - + ArgumentGuard.NotNull(services, nameof(services)); + ArgumentGuard.NotNull(resourceGraphBuilder, nameof(resourceGraphBuilder)); + ArgumentGuard.NotNull(loggerFactory, nameof(loggerFactory)); + ArgumentGuard.NotNull(options, nameof(options)); + _logger = loggerFactory.CreateLogger(); - _services = services ?? throw new ArgumentNullException(nameof(services)); - _resourceGraphBuilder = resourceGraphBuilder ?? throw new ArgumentNullException(nameof(resourceGraphBuilder)); - _options = options ?? throw new ArgumentNullException(nameof(options)); + _services = services; + _resourceGraphBuilder = resourceGraphBuilder; + _options = options; } /// @@ -89,11 +89,8 @@ public ServiceDiscoveryFacade(IServiceCollection services, ResourceGraphBuilder /// public ServiceDiscoveryFacade AddAssembly(Assembly assembly) { - if (assembly == null) - { - throw new ArgumentNullException(nameof(assembly)); - } - + ArgumentGuard.NotNull(assembly, nameof(assembly)); + _assemblyCache.RegisterAssembly(assembly); _logger.LogDebug($"Registering assembly '{assembly.FullName}' for discovery of resources and injectables."); diff --git a/src/JsonApiDotNetCore/Configuration/TypeLocator.cs b/src/JsonApiDotNetCore/Configuration/TypeLocator.cs index fd8b420b1b..f5b7b95d59 100644 --- a/src/JsonApiDotNetCore/Configuration/TypeLocator.cs +++ b/src/JsonApiDotNetCore/Configuration/TypeLocator.cs @@ -50,9 +50,9 @@ public static ResourceDescriptor TryGetResourceDescriptor(Type type) /// public static (Type implementation, Type registrationInterface)? GetGenericInterfaceImplementation(Assembly assembly, Type openGenericInterface, params Type[] interfaceGenericTypeArguments) { - if (assembly == null) throw new ArgumentNullException(nameof(assembly)); - if (openGenericInterface == null) throw new ArgumentNullException(nameof(openGenericInterface)); - if (interfaceGenericTypeArguments == null) throw new ArgumentNullException(nameof(interfaceGenericTypeArguments)); + ArgumentGuard.NotNull(assembly, nameof(assembly)); + ArgumentGuard.NotNull(openGenericInterface, nameof(openGenericInterface)); + ArgumentGuard.NotNull(interfaceGenericTypeArguments, nameof(interfaceGenericTypeArguments)); if (!openGenericInterface.IsInterface || !openGenericInterface.IsGenericType || openGenericInterface != openGenericInterface.GetGenericTypeDefinition()) diff --git a/src/JsonApiDotNetCore/Controllers/Annotations/DisableQueryStringAttribute.cs b/src/JsonApiDotNetCore/Controllers/Annotations/DisableQueryStringAttribute.cs index 6ed8711d97..f165c9758d 100644 --- a/src/JsonApiDotNetCore/Controllers/Annotations/DisableQueryStringAttribute.cs +++ b/src/JsonApiDotNetCore/Controllers/Annotations/DisableQueryStringAttribute.cs @@ -49,7 +49,7 @@ public DisableQueryStringAttribute(StandardQueryStringParameters parameters) /// public DisableQueryStringAttribute(string parameterNames) { - if (parameterNames == null) throw new ArgumentNullException(nameof(parameterNames)); + ArgumentGuard.NotNull(parameterNames, nameof(parameterNames)); ParameterNames = parameterNames.Split(",").ToList(); } diff --git a/src/JsonApiDotNetCore/Controllers/Annotations/HttpRestrictAttribute.cs b/src/JsonApiDotNetCore/Controllers/Annotations/HttpRestrictAttribute.cs index dcb3fd88af..00f4dbc195 100644 --- a/src/JsonApiDotNetCore/Controllers/Annotations/HttpRestrictAttribute.cs +++ b/src/JsonApiDotNetCore/Controllers/Annotations/HttpRestrictAttribute.cs @@ -1,4 +1,3 @@ -using System; using System.Linq; using System.Net.Http; using System.Threading.Tasks; @@ -15,8 +14,8 @@ public override async Task OnActionExecutionAsync( ActionExecutingContext context, ActionExecutionDelegate next) { - if (context == null) throw new ArgumentNullException(nameof(context)); - if (next == null) throw new ArgumentNullException(nameof(next)); + ArgumentGuard.NotNull(context, nameof(context)); + ArgumentGuard.NotNull(next, nameof(next)); var method = context.HttpContext.Request.Method; diff --git a/src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs b/src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs index 29ce0b6b8a..8b7f73ed86 100644 --- a/src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs +++ b/src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Net.Http; using System.Threading; @@ -72,9 +71,10 @@ protected BaseJsonApiController( IDeleteService delete = null, IRemoveFromRelationshipService removeFromRelationship = null) { - if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); + ArgumentGuard.NotNull(options, nameof(options)); + ArgumentGuard.NotNull(loggerFactory, nameof(loggerFactory)); - _options = options ?? throw new ArgumentNullException(nameof(options)); + _options = options; _traceWriter = new TraceLogWriter>(loggerFactory); _getAll = getAll; _getById = getById; @@ -125,7 +125,8 @@ public virtual async Task GetAsync(TId id, CancellationToken canc public virtual async Task GetSecondaryAsync(TId id, string relationshipName, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {id, relationshipName}); - if (relationshipName == null) throw new ArgumentNullException(nameof(relationshipName)); + + ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); if (_getSecondary == null) throw new RequestMethodNotAllowedException(HttpMethod.Get); var relationship = await _getSecondary.GetSecondaryAsync(id, relationshipName, cancellationToken); @@ -141,7 +142,8 @@ public virtual async Task GetSecondaryAsync(TId id, string relati public virtual async Task GetRelationshipAsync(TId id, string relationshipName, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {id, relationshipName}); - if (relationshipName == null) throw new ArgumentNullException(nameof(relationshipName)); + + ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); if (_getRelationship == null) throw new RequestMethodNotAllowedException(HttpMethod.Get); var rightResources = await _getRelationship.GetRelationshipAsync(id, relationshipName, cancellationToken); @@ -156,7 +158,8 @@ public virtual async Task GetRelationshipAsync(TId id, string rel public virtual async Task PostAsync([FromBody] TResource resource, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {resource}); - if (resource == null) throw new ArgumentNullException(nameof(resource)); + + ArgumentGuard.NotNull(resource, nameof(resource)); if (_create == null) throw new RequestMethodNotAllowedException(HttpMethod.Post); @@ -195,8 +198,9 @@ public virtual async Task PostAsync([FromBody] TResource resource public virtual async Task PostRelationshipAsync(TId id, string relationshipName, [FromBody] ISet secondaryResourceIds, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {id, relationshipName, secondaryResourceIds}); - if (relationshipName == null) throw new ArgumentNullException(nameof(relationshipName)); - if (secondaryResourceIds == null) throw new ArgumentNullException(nameof(secondaryResourceIds)); + + ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); + ArgumentGuard.NotNull(secondaryResourceIds, nameof(secondaryResourceIds)); if (_addToRelationship == null) throw new RequestMethodNotAllowedException(HttpMethod.Post); await _addToRelationship.AddToToManyRelationshipAsync(id, relationshipName, secondaryResourceIds, cancellationToken); @@ -212,7 +216,8 @@ public virtual async Task PostRelationshipAsync(TId id, string re public virtual async Task PatchAsync(TId id, [FromBody] TResource resource, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {id, resource}); - if (resource == null) throw new ArgumentNullException(nameof(resource)); + + ArgumentGuard.NotNull(resource, nameof(resource)); if (_update == null) throw new RequestMethodNotAllowedException(HttpMethod.Patch); @@ -238,7 +243,8 @@ public virtual async Task PatchAsync(TId id, [FromBody] TResource public virtual async Task PatchRelationshipAsync(TId id, string relationshipName, [FromBody] object secondaryResourceIds, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {id, relationshipName, secondaryResourceIds}); - if (relationshipName == null) throw new ArgumentNullException(nameof(relationshipName)); + + ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); if (_setRelationship == null) throw new RequestMethodNotAllowedException(HttpMethod.Patch); await _setRelationship.SetRelationshipAsync(id, relationshipName, secondaryResourceIds, cancellationToken); @@ -271,8 +277,9 @@ public virtual async Task DeleteAsync(TId id, CancellationToken c public virtual async Task DeleteRelationshipAsync(TId id, string relationshipName, [FromBody] ISet secondaryResourceIds, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {id, relationshipName, secondaryResourceIds}); - if (relationshipName == null) throw new ArgumentNullException(nameof(relationshipName)); - if (secondaryResourceIds == null) throw new ArgumentNullException(nameof(secondaryResourceIds)); + + ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); + ArgumentGuard.NotNull(secondaryResourceIds, nameof(secondaryResourceIds)); if (_removeFromRelationship == null) throw new RequestMethodNotAllowedException(HttpMethod.Delete); await _removeFromRelationship.RemoveFromToManyRelationshipAsync(id, relationshipName, secondaryResourceIds, cancellationToken); diff --git a/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs b/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs index f118d20e1f..3470c2155e 100644 --- a/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs +++ b/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -28,12 +27,16 @@ public abstract class BaseJsonApiOperationsController : CoreJsonApiController protected BaseJsonApiOperationsController(IJsonApiOptions options, ILoggerFactory loggerFactory, IOperationsProcessor processor, IJsonApiRequest request, ITargetedFields targetedFields) { - if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); - - _options = options ?? throw new ArgumentNullException(nameof(options)); - _processor = processor ?? throw new ArgumentNullException(nameof(processor)); - _request = request ?? throw new ArgumentNullException(nameof(request)); - _targetedFields = targetedFields ?? throw new ArgumentNullException(nameof(targetedFields)); + ArgumentGuard.NotNull(options, nameof(options)); + ArgumentGuard.NotNull(loggerFactory, nameof(loggerFactory)); + ArgumentGuard.NotNull(processor, nameof(processor)); + ArgumentGuard.NotNull(request, nameof(request)); + ArgumentGuard.NotNull(targetedFields, nameof(targetedFields)); + + _options = options; + _processor = processor; + _request = request; + _targetedFields = targetedFields; _traceWriter = new TraceLogWriter(loggerFactory); } @@ -99,7 +102,8 @@ public virtual async Task PostOperationsAsync([FromBody] IList errors) { - if (errors == null) throw new ArgumentNullException(nameof(errors)); + ArgumentGuard.NotNull(errors, nameof(errors)); var document = new ErrorDocument(errors); diff --git a/src/JsonApiDotNetCore/Controllers/ModelStateViolation.cs b/src/JsonApiDotNetCore/Controllers/ModelStateViolation.cs index b83453e919..f786b2045c 100644 --- a/src/JsonApiDotNetCore/Controllers/ModelStateViolation.cs +++ b/src/JsonApiDotNetCore/Controllers/ModelStateViolation.cs @@ -15,10 +15,15 @@ public sealed class ModelStateViolation public ModelStateViolation(string prefix, string propertyName, Type resourceType, ModelError error) { - Prefix = prefix ?? throw new ArgumentNullException(nameof(prefix)); - PropertyName = propertyName ?? throw new ArgumentNullException(nameof(propertyName)); - ResourceType = resourceType ?? throw new ArgumentNullException(nameof(resourceType)); - Error = error ?? throw new ArgumentNullException(nameof(error)); + ArgumentGuard.NotNull(prefix, nameof(prefix)); + ArgumentGuard.NotNull(propertyName, nameof(propertyName)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); + ArgumentGuard.NotNull(error, nameof(error)); + + Prefix = prefix; + PropertyName = propertyName; + ResourceType = resourceType; + Error = error; } } } diff --git a/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs b/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs index 7393a5596d..8670345755 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs @@ -42,8 +42,8 @@ public InvalidModelStateException(IEnumerable violations, private static IEnumerable FromModelStateViolations(IEnumerable violations, bool includeExceptionStackTraceInErrors, NamingStrategy namingStrategy) { - if (violations == null) throw new ArgumentNullException(nameof(violations)); - if (namingStrategy == null) throw new ArgumentNullException(nameof(namingStrategy)); + ArgumentGuard.NotNull(violations, nameof(violations)); + ArgumentGuard.NotNull(namingStrategy, nameof(namingStrategy)); foreach (var violation in violations) { diff --git a/src/JsonApiDotNetCore/Errors/JsonApiException.cs b/src/JsonApiDotNetCore/Errors/JsonApiException.cs index 7f0ef7be8b..18e28f37b6 100644 --- a/src/JsonApiDotNetCore/Errors/JsonApiException.cs +++ b/src/JsonApiDotNetCore/Errors/JsonApiException.cs @@ -22,7 +22,7 @@ public class JsonApiException : Exception public JsonApiException(Error error, Exception innerException = null) : base(null, innerException) { - if (error == null) throw new ArgumentNullException(nameof(error)); + ArgumentGuard.NotNull(error, nameof(error)); Errors = new[] {error}; } @@ -30,7 +30,7 @@ public JsonApiException(Error error, Exception innerException = null) public JsonApiException(IEnumerable errors, Exception innerException = null) : base(null, innerException) { - if (errors == null) throw new ArgumentNullException(nameof(errors)); + ArgumentGuard.NotNull(errors, nameof(errors)); Errors = errors.ToList(); diff --git a/src/JsonApiDotNetCore/Errors/MissingResourceInRelationship.cs b/src/JsonApiDotNetCore/Errors/MissingResourceInRelationship.cs index 421592abd8..9777bbb46e 100644 --- a/src/JsonApiDotNetCore/Errors/MissingResourceInRelationship.cs +++ b/src/JsonApiDotNetCore/Errors/MissingResourceInRelationship.cs @@ -1,5 +1,3 @@ -using System; - namespace JsonApiDotNetCore.Errors { public sealed class MissingResourceInRelationship @@ -10,9 +8,13 @@ public sealed class MissingResourceInRelationship public MissingResourceInRelationship(string relationshipName, string resourceType, string resourceId) { - RelationshipName = relationshipName ?? throw new ArgumentNullException(nameof(relationshipName)); - ResourceType = resourceType ?? throw new ArgumentNullException(nameof(resourceType)); - ResourceId = resourceId ?? throw new ArgumentNullException(nameof(resourceId)); + ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); + ArgumentGuard.NotNull(resourceId, nameof(resourceId)); + + RelationshipName = relationshipName; + ResourceType = resourceType; + ResourceId = resourceId; } } } diff --git a/src/JsonApiDotNetCore/Errors/UnsuccessfulActionResultException.cs b/src/JsonApiDotNetCore/Errors/UnsuccessfulActionResultException.cs index 7f8cd6fc9d..dbb8ccf24b 100644 --- a/src/JsonApiDotNetCore/Errors/UnsuccessfulActionResultException.cs +++ b/src/JsonApiDotNetCore/Errors/UnsuccessfulActionResultException.cs @@ -1,4 +1,3 @@ -using System; using System.Net; using JsonApiDotNetCore.Serialization.Objects; using Microsoft.AspNetCore.Mvc; @@ -25,8 +24,8 @@ public UnsuccessfulActionResultException(ProblemDetails problemDetails) private static Error ToError(ProblemDetails problemDetails) { - if (problemDetails == null) throw new ArgumentNullException(nameof(problemDetails)); - + ArgumentGuard.NotNull(problemDetails, nameof(problemDetails)); + var status = problemDetails.Status != null ? (HttpStatusCode) problemDetails.Status.Value : HttpStatusCode.InternalServerError; diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs index 2f41667a97..1700ec401a 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs @@ -1,4 +1,3 @@ -using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -19,9 +18,11 @@ internal sealed class ResourceHookExecutorFacade : IResourceHookExecutorFacade public ResourceHookExecutorFacade(IResourceHookExecutor resourceHookExecutor, IResourceFactory resourceFactory) { - _resourceHookExecutor = - resourceHookExecutor ?? throw new ArgumentNullException(nameof(resourceHookExecutor)); - _resourceFactory = resourceFactory ?? throw new ArgumentNullException(nameof(resourceFactory)); + ArgumentGuard.NotNull(resourceHookExecutor, nameof(resourceHookExecutor)); + ArgumentGuard.NotNull(resourceFactory, nameof(resourceFactory)); + + _resourceHookExecutor = resourceHookExecutor; + _resourceFactory = resourceFactory; } public void BeforeReadSingle(TId id, ResourcePipeline pipeline) diff --git a/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj b/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj index 7ef9f71a96..f19914dc3c 100644 --- a/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj +++ b/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj @@ -23,6 +23,7 @@ + diff --git a/src/JsonApiDotNetCore/Middleware/AsyncConvertEmptyActionResultFilter.cs b/src/JsonApiDotNetCore/Middleware/AsyncConvertEmptyActionResultFilter.cs index d7c78a94a8..63d74d18c0 100644 --- a/src/JsonApiDotNetCore/Middleware/AsyncConvertEmptyActionResultFilter.cs +++ b/src/JsonApiDotNetCore/Middleware/AsyncConvertEmptyActionResultFilter.cs @@ -1,4 +1,3 @@ -using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; @@ -12,8 +11,8 @@ public sealed class AsyncConvertEmptyActionResultFilter : IAsyncConvertEmptyActi /// public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) { - if (context == null) throw new ArgumentNullException(nameof(context)); - if (next == null) throw new ArgumentNullException(nameof(next)); + ArgumentGuard.NotNull(context, nameof(context)); + ArgumentGuard.NotNull(next, nameof(next)); if (context.HttpContext.IsJsonApiRequest()) { diff --git a/src/JsonApiDotNetCore/Middleware/AsyncJsonApiExceptionFilter.cs b/src/JsonApiDotNetCore/Middleware/AsyncJsonApiExceptionFilter.cs index 0334f3a9eb..8d447bb152 100644 --- a/src/JsonApiDotNetCore/Middleware/AsyncJsonApiExceptionFilter.cs +++ b/src/JsonApiDotNetCore/Middleware/AsyncJsonApiExceptionFilter.cs @@ -1,4 +1,3 @@ -using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; @@ -12,13 +11,15 @@ public class AsyncJsonApiExceptionFilter : IAsyncJsonApiExceptionFilter public AsyncJsonApiExceptionFilter(IExceptionHandler exceptionHandler) { - _exceptionHandler = exceptionHandler ?? throw new ArgumentNullException(nameof(exceptionHandler)); + ArgumentGuard.NotNull(exceptionHandler, nameof(exceptionHandler)); + + _exceptionHandler = exceptionHandler; } /// public Task OnExceptionAsync(ExceptionContext context) { - if (context == null) throw new ArgumentNullException(nameof(context)); + ArgumentGuard.NotNull(context, nameof(context)); if (context.HttpContext.IsJsonApiRequest()) { diff --git a/src/JsonApiDotNetCore/Middleware/AsyncQueryStringActionFilter.cs b/src/JsonApiDotNetCore/Middleware/AsyncQueryStringActionFilter.cs index 4bb9f88c32..65a7ac14b1 100644 --- a/src/JsonApiDotNetCore/Middleware/AsyncQueryStringActionFilter.cs +++ b/src/JsonApiDotNetCore/Middleware/AsyncQueryStringActionFilter.cs @@ -1,4 +1,3 @@ -using System; using System.Reflection; using System.Threading.Tasks; using JsonApiDotNetCore.Controllers.Annotations; @@ -14,14 +13,16 @@ public sealed class AsyncQueryStringActionFilter : IAsyncQueryStringActionFilter public AsyncQueryStringActionFilter(IQueryStringReader queryStringReader) { - _queryStringReader = queryStringReader ?? throw new ArgumentNullException(nameof(queryStringReader)); + ArgumentGuard.NotNull(queryStringReader, nameof(queryStringReader)); + + _queryStringReader = queryStringReader; } /// public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { - if (context == null) throw new ArgumentNullException(nameof(context)); - if (next == null) throw new ArgumentNullException(nameof(next)); + ArgumentGuard.NotNull(context, nameof(context)); + ArgumentGuard.NotNull(next, nameof(next)); if (context.HttpContext.IsJsonApiRequest()) { diff --git a/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs b/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs index b85125a821..70afbe24ad 100644 --- a/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs +++ b/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs @@ -16,15 +16,16 @@ public class ExceptionHandler : IExceptionHandler public ExceptionHandler(ILoggerFactory loggerFactory, IJsonApiOptions options) { - if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); + ArgumentGuard.NotNull(loggerFactory, nameof(loggerFactory)); + ArgumentGuard.NotNull(options, nameof(options)); - _options = options ?? throw new ArgumentNullException(nameof(options)); + _options = options; _logger = loggerFactory.CreateLogger(); } public ErrorDocument HandleException(Exception exception) { - if (exception == null) throw new ArgumentNullException(nameof(exception)); + ArgumentGuard.NotNull(exception, nameof(exception)); Exception demystified = exception.Demystify(); @@ -43,7 +44,7 @@ private void LogException(Exception exception) protected virtual LogLevel GetLogLevel(Exception exception) { - if (exception == null) throw new ArgumentNullException(nameof(exception)); + ArgumentGuard.NotNull(exception, nameof(exception)); if (exception is OperationCanceledException) { @@ -60,14 +61,14 @@ protected virtual LogLevel GetLogLevel(Exception exception) protected virtual string GetLogMessage(Exception exception) { - if (exception == null) throw new ArgumentNullException(nameof(exception)); + ArgumentGuard.NotNull(exception, nameof(exception)); return exception.Message; } protected virtual ErrorDocument CreateErrorDocument(Exception exception) { - if (exception == null) throw new ArgumentNullException(nameof(exception)); + ArgumentGuard.NotNull(exception, nameof(exception)); var errors = exception is JsonApiException jsonApiException ? jsonApiException.Errors diff --git a/src/JsonApiDotNetCore/Middleware/HttpContextExtensions.cs b/src/JsonApiDotNetCore/Middleware/HttpContextExtensions.cs index ccafcae28c..8bac477581 100644 --- a/src/JsonApiDotNetCore/Middleware/HttpContextExtensions.cs +++ b/src/JsonApiDotNetCore/Middleware/HttpContextExtensions.cs @@ -1,4 +1,3 @@ -using System; using Microsoft.AspNetCore.Http; namespace JsonApiDotNetCore.Middleware @@ -12,7 +11,7 @@ public static class HttpContextExtensions /// public static bool IsJsonApiRequest(this HttpContext httpContext) { - if (httpContext == null) throw new ArgumentNullException(nameof(httpContext)); + ArgumentGuard.NotNull(httpContext, nameof(httpContext)); string value = httpContext.Items[_isJsonApiRequestKey] as string; return value == bool.TrueString; @@ -20,7 +19,7 @@ public static bool IsJsonApiRequest(this HttpContext httpContext) internal static void RegisterJsonApiRequest(this HttpContext httpContext) { - if (httpContext == null) throw new ArgumentNullException(nameof(httpContext)); + ArgumentGuard.NotNull(httpContext, nameof(httpContext)); httpContext.Items[_isJsonApiRequestKey] = bool.TrueString; } diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiInputFormatter.cs b/src/JsonApiDotNetCore/Middleware/JsonApiInputFormatter.cs index ebab9cc134..fc5a1e2230 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiInputFormatter.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiInputFormatter.cs @@ -1,4 +1,3 @@ -using System; using System.Threading.Tasks; using JsonApiDotNetCore.Serialization; using Microsoft.AspNetCore.Mvc.Formatters; @@ -12,7 +11,7 @@ public sealed class JsonApiInputFormatter : IJsonApiInputFormatter /// public bool CanRead(InputFormatterContext context) { - if (context == null) throw new ArgumentNullException(nameof(context)); + ArgumentGuard.NotNull(context, nameof(context)); return context.HttpContext.IsJsonApiRequest(); } @@ -20,7 +19,7 @@ public bool CanRead(InputFormatterContext context) /// public async Task ReadAsync(InputFormatterContext context) { - if (context == null) throw new ArgumentNullException(nameof(context)); + ArgumentGuard.NotNull(context, nameof(context)); var reader = context.HttpContext.RequestServices.GetRequiredService(); return await reader.ReadAsync(context); diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs index 838d234c09..5e007236f3 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs @@ -39,11 +39,11 @@ public async Task Invoke(HttpContext httpContext, IJsonApiRequest request, IResourceContextProvider resourceContextProvider) { - if (httpContext == null) throw new ArgumentNullException(nameof(httpContext)); - if (controllerResourceMapping == null) throw new ArgumentNullException(nameof(controllerResourceMapping)); - if (options == null) throw new ArgumentNullException(nameof(options)); - if (request == null) throw new ArgumentNullException(nameof(request)); - if (resourceContextProvider == null) throw new ArgumentNullException(nameof(resourceContextProvider)); + ArgumentGuard.NotNull(httpContext, nameof(httpContext)); + ArgumentGuard.NotNull(controllerResourceMapping, nameof(controllerResourceMapping)); + ArgumentGuard.NotNull(options, nameof(options)); + ArgumentGuard.NotNull(request, nameof(request)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); var routeValues = httpContext.GetRouteData().Values; diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiOutputFormatter.cs b/src/JsonApiDotNetCore/Middleware/JsonApiOutputFormatter.cs index 9f77fc58e7..bd66f66067 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiOutputFormatter.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiOutputFormatter.cs @@ -1,4 +1,3 @@ -using System; using System.Threading.Tasks; using JsonApiDotNetCore.Serialization; using Microsoft.AspNetCore.Mvc.Formatters; @@ -12,7 +11,7 @@ public sealed class JsonApiOutputFormatter : IJsonApiOutputFormatter /// public bool CanWriteResult(OutputFormatterCanWriteContext context) { - if (context == null) throw new ArgumentNullException(nameof(context)); + ArgumentGuard.NotNull(context, nameof(context)); return context.HttpContext.IsJsonApiRequest(); } @@ -20,7 +19,7 @@ public bool CanWriteResult(OutputFormatterCanWriteContext context) /// public async Task WriteAsync(OutputFormatterWriteContext context) { - if (context == null) throw new ArgumentNullException(nameof(context)); + ArgumentGuard.NotNull(context, nameof(context)); var writer = context.HttpContext.RequestServices.GetRequiredService(); await writer.WriteAsync(context); diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiRequest.cs b/src/JsonApiDotNetCore/Middleware/JsonApiRequest.cs index b4776419e3..113199ff91 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiRequest.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiRequest.cs @@ -40,7 +40,7 @@ public sealed class JsonApiRequest : IJsonApiRequest /// public void CopyFrom(IJsonApiRequest other) { - if (other == null) throw new ArgumentNullException(nameof(other)); + ArgumentGuard.NotNull(other, nameof(other)); Kind = other.Kind; BasePath = other.BasePath; diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs b/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs index f751e2a6ec..c124806889 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs @@ -39,15 +39,18 @@ public class JsonApiRoutingConvention : IJsonApiRoutingConvention public JsonApiRoutingConvention(IJsonApiOptions options, IResourceContextProvider resourceContextProvider) { - _options = options ?? throw new ArgumentNullException(nameof(options)); - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); + ArgumentGuard.NotNull(options, nameof(options)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + + _options = options; + _resourceContextProvider = resourceContextProvider; } /// public Type GetResourceTypeForController(string controllerName) { - if (controllerName == null) throw new ArgumentNullException(nameof(controllerName)); - + ArgumentGuard.NotNull(controllerName, nameof(controllerName)); + if (_registeredResources.TryGetValue(controllerName, out var resourceContext)) { return resourceContext.ResourceType; @@ -59,7 +62,7 @@ public Type GetResourceTypeForController(string controllerName) /// public void Apply(ApplicationModel application) { - if (application == null) throw new ArgumentNullException(nameof(application)); + ArgumentGuard.NotNull(application, nameof(application)); foreach (var controller in application.Controllers) { diff --git a/src/JsonApiDotNetCore/Queries/ExpressionInScope.cs b/src/JsonApiDotNetCore/Queries/ExpressionInScope.cs index b24257a3fc..443f36f728 100644 --- a/src/JsonApiDotNetCore/Queries/ExpressionInScope.cs +++ b/src/JsonApiDotNetCore/Queries/ExpressionInScope.cs @@ -1,4 +1,3 @@ -using System; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; @@ -14,8 +13,10 @@ public class ExpressionInScope public ExpressionInScope(ResourceFieldChainExpression scope, QueryExpression expression) { + ArgumentGuard.NotNull(expression, nameof(expression)); + Scope = scope; - Expression = expression ?? throw new ArgumentNullException(nameof(expression)); + Expression = expression; } public override string ToString() diff --git a/src/JsonApiDotNetCore/Queries/Expressions/CollectionNotEmptyExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/CollectionNotEmptyExpression.cs index 66ceabe09c..7a9afb0e30 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/CollectionNotEmptyExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/CollectionNotEmptyExpression.cs @@ -1,4 +1,3 @@ -using System; using JsonApiDotNetCore.Queries.Internal.Parsing; namespace JsonApiDotNetCore.Queries.Expressions @@ -12,7 +11,9 @@ public class CollectionNotEmptyExpression : FilterExpression public CollectionNotEmptyExpression(ResourceFieldChainExpression targetCollection) { - TargetCollection = targetCollection ?? throw new ArgumentNullException(nameof(targetCollection)); + ArgumentGuard.NotNull(targetCollection, nameof(targetCollection)); + + TargetCollection = targetCollection; } public override TResult Accept(QueryExpressionVisitor visitor, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/ComparisonExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/ComparisonExpression.cs index 318d61fe68..c22d3d01fd 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/ComparisonExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/ComparisonExpression.cs @@ -14,9 +14,12 @@ public class ComparisonExpression : FilterExpression public ComparisonExpression(ComparisonOperator @operator, QueryExpression left, QueryExpression right) { + ArgumentGuard.NotNull(left, nameof(left)); + ArgumentGuard.NotNull(right, nameof(right)); + Operator = @operator; - Left = left ?? throw new ArgumentNullException(nameof(left)); - Right = right ?? throw new ArgumentNullException(nameof(right)); + Left = left; + Right = right; } public override TResult Accept(QueryExpressionVisitor visitor, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/CountExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/CountExpression.cs index 3f6b83bb8e..23a53a7be2 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/CountExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/CountExpression.cs @@ -1,4 +1,3 @@ -using System; using JsonApiDotNetCore.Queries.Internal.Parsing; namespace JsonApiDotNetCore.Queries.Expressions @@ -12,7 +11,9 @@ public class CountExpression : FunctionExpression public CountExpression(ResourceFieldChainExpression targetCollection) { - TargetCollection = targetCollection ?? throw new ArgumentNullException(nameof(targetCollection)); + ArgumentGuard.NotNull(targetCollection, nameof(targetCollection)); + + TargetCollection = targetCollection; } public override TResult Accept(QueryExpressionVisitor visitor, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/EqualsAnyOfExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/EqualsAnyOfExpression.cs index 134d8cebdd..44b867d590 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/EqualsAnyOfExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/EqualsAnyOfExpression.cs @@ -17,13 +17,16 @@ public class EqualsAnyOfExpression : FilterExpression public EqualsAnyOfExpression(ResourceFieldChainExpression targetAttribute, IReadOnlyCollection constants) { - TargetAttribute = targetAttribute ?? throw new ArgumentNullException(nameof(targetAttribute)); - Constants = constants ?? throw new ArgumentNullException(nameof(constants)); + ArgumentGuard.NotNull(targetAttribute, nameof(targetAttribute)); + ArgumentGuard.NotNull(constants, nameof(constants)); if (constants.Count < 2) { throw new ArgumentException("At least two constants are required.", nameof(constants)); } + + TargetAttribute = targetAttribute; + Constants = constants; } public override TResult Accept(QueryExpressionVisitor visitor, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs b/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs index b46759f85f..86158d0efa 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using JsonApiDotNetCore.Resources.Annotations; @@ -31,10 +30,7 @@ internal static class IncludeChainConverter /// public static IReadOnlyCollection GetRelationshipChains(IncludeExpression include) { - if (include == null) - { - throw new ArgumentNullException(nameof(include)); - } + ArgumentGuard.NotNull(include, nameof(include)); IncludeToChainsConverter converter = new IncludeToChainsConverter(); converter.Visit(include, null); @@ -62,10 +58,7 @@ public static IReadOnlyCollection GetRelationshipC /// public static IncludeExpression FromRelationshipChains(IReadOnlyCollection chains) { - if (chains == null) - { - throw new ArgumentNullException(nameof(chains)); - } + ArgumentGuard.NotNull(chains, nameof(chains)); var elements = ConvertChainsToElements(chains); return elements.Any() ? new IncludeExpression(elements) : IncludeExpression.Empty; diff --git a/src/JsonApiDotNetCore/Queries/Expressions/IncludeElementExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/IncludeElementExpression.cs index c24390bce1..198d412bc6 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/IncludeElementExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/IncludeElementExpression.cs @@ -21,8 +21,11 @@ public IncludeElementExpression(RelationshipAttribute relationship) public IncludeElementExpression(RelationshipAttribute relationship, IReadOnlyCollection children) { - Relationship = relationship ?? throw new ArgumentNullException(nameof(relationship)); - Children = children ?? throw new ArgumentNullException(nameof(children)); + ArgumentGuard.NotNull(relationship, nameof(relationship)); + ArgumentGuard.NotNull(children, nameof(children)); + + Relationship = relationship; + Children = children; } public override TResult Accept(QueryExpressionVisitor visitor, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/IncludeExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/IncludeExpression.cs index d580f6c18d..66a5110957 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/IncludeExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/IncludeExpression.cs @@ -20,12 +20,14 @@ private IncludeExpression() public IncludeExpression(IReadOnlyCollection elements) { - Elements = elements ?? throw new ArgumentNullException(nameof(elements)); + ArgumentGuard.NotNull(elements, nameof(elements)); if (!elements.Any()) { throw new ArgumentException("Must have one or more elements.", nameof(elements)); } + + Elements = elements; } public override TResult Accept(QueryExpressionVisitor visitor, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/LiteralConstantExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/LiteralConstantExpression.cs index 21876cf1e0..8da035d752 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/LiteralConstantExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/LiteralConstantExpression.cs @@ -1,5 +1,3 @@ -using System; - namespace JsonApiDotNetCore.Queries.Expressions { /// @@ -11,7 +9,9 @@ public class LiteralConstantExpression : IdentifierExpression public LiteralConstantExpression(string text) { - Value = text ?? throw new ArgumentNullException(nameof(text)); + ArgumentGuard.NotNull(text, nameof(text)); + + Value = text; } public override TResult Accept(QueryExpressionVisitor visitor, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/LogicalExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/LogicalExpression.cs index 474ed177d0..29f0396f31 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/LogicalExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/LogicalExpression.cs @@ -16,10 +16,7 @@ public class LogicalExpression : FilterExpression public LogicalExpression(LogicalOperator @operator, IReadOnlyCollection terms) { - if (terms == null) - { - throw new ArgumentNullException(nameof(terms)); - } + ArgumentGuard.NotNull(terms, nameof(terms)); if (terms.Count < 2) { diff --git a/src/JsonApiDotNetCore/Queries/Expressions/MatchTextExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/MatchTextExpression.cs index 099546c033..5ae5979a77 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/MatchTextExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/MatchTextExpression.cs @@ -16,8 +16,11 @@ public class MatchTextExpression : FilterExpression public MatchTextExpression(ResourceFieldChainExpression targetAttribute, LiteralConstantExpression textValue, TextMatchKind matchKind) { - TargetAttribute = targetAttribute ?? throw new ArgumentNullException(nameof(targetAttribute)); - TextValue = textValue ?? throw new ArgumentNullException(nameof(textValue)); + ArgumentGuard.NotNull(targetAttribute, nameof(targetAttribute)); + ArgumentGuard.NotNull(textValue, nameof(textValue)); + + TargetAttribute = targetAttribute; + TextValue = textValue; MatchKind = matchKind; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/NotExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/NotExpression.cs index e9fd9bb06d..d679fcc8a4 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/NotExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/NotExpression.cs @@ -1,4 +1,3 @@ -using System; using JsonApiDotNetCore.Queries.Internal.Parsing; namespace JsonApiDotNetCore.Queries.Expressions @@ -12,7 +11,9 @@ public class NotExpression : FilterExpression public NotExpression(QueryExpression child) { - Child = child ?? throw new ArgumentNullException(nameof(child)); + ArgumentGuard.NotNull(child, nameof(child)); + + Child = child; } public override TResult Accept(QueryExpressionVisitor visitor, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/PaginationExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/PaginationExpression.cs index a035b25167..a74538758d 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/PaginationExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/PaginationExpression.cs @@ -13,7 +13,9 @@ public class PaginationExpression : QueryExpression public PaginationExpression(PageNumber pageNumber, PageSize pageSize) { - PageNumber = pageNumber ?? throw new ArgumentNullException(nameof(pageNumber)); + ArgumentGuard.NotNull(pageNumber, nameof(pageNumber)); + + PageNumber = pageNumber; PageSize = pageSize; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/PaginationQueryStringValueExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/PaginationQueryStringValueExpression.cs index 7bd17ce921..a3dc88b3b2 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/PaginationQueryStringValueExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/PaginationQueryStringValueExpression.cs @@ -14,12 +14,14 @@ public class PaginationQueryStringValueExpression : QueryExpression public PaginationQueryStringValueExpression( IReadOnlyCollection elements) { - Elements = elements ?? throw new ArgumentNullException(nameof(elements)); + ArgumentGuard.NotNull(elements, nameof(elements)); - if (!Elements.Any()) + if (!elements.Any()) { throw new ArgumentException("Must have one or more elements.", nameof(elements)); } + + Elements = elements; } public override TResult Accept(QueryExpressionVisitor visitor, diff --git a/src/JsonApiDotNetCore/Queries/Expressions/QueryStringParameterScopeExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/QueryStringParameterScopeExpression.cs index 8c9279259a..4ae22a7380 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/QueryStringParameterScopeExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/QueryStringParameterScopeExpression.cs @@ -12,7 +12,9 @@ public class QueryStringParameterScopeExpression : QueryExpression public QueryStringParameterScopeExpression(LiteralConstantExpression parameterName, ResourceFieldChainExpression scope) { - ParameterName = parameterName ?? throw new ArgumentNullException(nameof(parameterName)); + ArgumentGuard.NotNull(parameterName, nameof(parameterName)); + + ParameterName = parameterName; Scope = scope; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/QueryableHandlerExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/QueryableHandlerExpression.cs index 37bb6cde07..ef411a132a 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/QueryableHandlerExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/QueryableHandlerExpression.cs @@ -15,7 +15,9 @@ public class QueryableHandlerExpression : QueryExpression public QueryableHandlerExpression(object queryableHandler, StringValues parameterValue) { - _queryableHandler = queryableHandler ?? throw new ArgumentNullException(nameof(queryableHandler)); + ArgumentGuard.NotNull(queryableHandler, nameof(queryableHandler)); + + _queryableHandler = queryableHandler; _parameterValue = parameterValue; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/ResourceFieldChainExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/ResourceFieldChainExpression.cs index 03de34a8f0..3d3527c72c 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/ResourceFieldChainExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/ResourceFieldChainExpression.cs @@ -14,22 +14,21 @@ public class ResourceFieldChainExpression : IdentifierExpression public ResourceFieldChainExpression(ResourceFieldAttribute field) { - if (field == null) - { - throw new ArgumentNullException(nameof(field)); - } + ArgumentGuard.NotNull(field, nameof(field)); Fields = new[] {field}; } public ResourceFieldChainExpression(IReadOnlyCollection fields) { - Fields = fields ?? throw new ArgumentNullException(nameof(fields)); + ArgumentGuard.NotNull(fields, nameof(fields)); if (!fields.Any()) { throw new ArgumentException("Must have one or more fields.", nameof(fields)); } + + Fields = fields; } public override TResult Accept(QueryExpressionVisitor visitor, diff --git a/src/JsonApiDotNetCore/Queries/Expressions/SortElementExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/SortElementExpression.cs index 186a85013f..12c4ff9d0a 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/SortElementExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/SortElementExpression.cs @@ -14,13 +14,17 @@ public class SortElementExpression : QueryExpression public SortElementExpression(ResourceFieldChainExpression targetAttribute, bool isAscending) { - TargetAttribute = targetAttribute ?? throw new ArgumentNullException(nameof(targetAttribute)); + ArgumentGuard.NotNull(targetAttribute, nameof(targetAttribute)); + + TargetAttribute = targetAttribute; IsAscending = isAscending; } public SortElementExpression(CountExpression count, in bool isAscending) { - Count = count ?? throw new ArgumentNullException(nameof(count)); + ArgumentGuard.NotNull(count, nameof(count)); + + Count = count; IsAscending = isAscending; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/SortExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/SortExpression.cs index 61683a95a6..625c152a5e 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/SortExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/SortExpression.cs @@ -13,12 +13,14 @@ public class SortExpression : QueryExpression public SortExpression(IReadOnlyCollection elements) { - Elements = elements ?? throw new ArgumentNullException(nameof(elements)); + ArgumentGuard.NotNull(elements, nameof(elements)); if (!elements.Any()) { throw new ArgumentException("Must have one or more elements.", nameof(elements)); } + + Elements = elements; } public override TResult Accept(QueryExpressionVisitor visitor, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpression.cs index 9e8a930703..224c9f162e 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpression.cs @@ -14,12 +14,14 @@ public class SparseFieldSetExpression : QueryExpression public SparseFieldSetExpression(IReadOnlyCollection fields) { - Fields = fields ?? throw new ArgumentNullException(nameof(fields)); + ArgumentGuard.NotNull(fields, nameof(fields)); if (!fields.Any()) { throw new ArgumentException("Must have one or more fields.", nameof(fields)); } + + Fields = fields; } public override TResult Accept(QueryExpressionVisitor visitor, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpressionExtensions.cs b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpressionExtensions.cs index 79b4b12781..e967b01d72 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpressionExtensions.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpressionExtensions.cs @@ -13,15 +13,8 @@ public static SparseFieldSetExpression Including(this SparseFieldSetE Expression> fieldSelector, IResourceGraph resourceGraph) where TResource : class, IIdentifiable { - if (fieldSelector == null) - { - throw new ArgumentNullException(nameof(fieldSelector)); - } - - if (resourceGraph == null) - { - throw new ArgumentNullException(nameof(resourceGraph)); - } + ArgumentGuard.NotNull(fieldSelector, nameof(fieldSelector)); + ArgumentGuard.NotNull(resourceGraph, nameof(resourceGraph)); foreach (var field in resourceGraph.GetFields(fieldSelector)) { @@ -47,15 +40,8 @@ public static SparseFieldSetExpression Excluding(this SparseFieldSetE Expression> fieldSelector, IResourceGraph resourceGraph) where TResource : class, IIdentifiable { - if (fieldSelector == null) - { - throw new ArgumentNullException(nameof(fieldSelector)); - } - - if (resourceGraph == null) - { - throw new ArgumentNullException(nameof(resourceGraph)); - } + ArgumentGuard.NotNull(fieldSelector, nameof(fieldSelector)); + ArgumentGuard.NotNull(resourceGraph, nameof(resourceGraph)); foreach (var field in resourceGraph.GetFields(fieldSelector)) { diff --git a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldTableExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldTableExpression.cs index 468e66a998..455b4fc5e9 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldTableExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldTableExpression.cs @@ -15,12 +15,14 @@ public class SparseFieldTableExpression : QueryExpression public SparseFieldTableExpression(IReadOnlyDictionary table) { - Table = table ?? throw new ArgumentNullException(nameof(table)); + ArgumentGuard.NotNull(table, nameof(table)); if (!table.Any()) { throw new ArgumentException("Must have one or more entries.", nameof(table)); } + + Table = table; } public override TResult Accept(QueryExpressionVisitor visitor, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/FilterParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/FilterParser.cs index 791089f00d..b35a983949 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/FilterParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/FilterParser.cs @@ -20,14 +20,19 @@ public FilterParser(IResourceContextProvider resourceContextProvider, IResourceF Action validateSingleFieldCallback = null) : base(resourceContextProvider) { - _resourceFactory = resourceFactory ?? throw new ArgumentNullException(nameof(resourceFactory)); + ArgumentGuard.NotNull(resourceFactory, nameof(resourceFactory)); + + _resourceFactory = resourceFactory; _validateSingleFieldCallback = validateSingleFieldCallback; } public FilterExpression Parse(string source, ResourceContext resourceContextInScope) { + ArgumentGuard.NotNull(resourceContextInScope, nameof(resourceContextInScope)); + + _resourceContextInScope = resourceContextInScope; + Tokenize(source); - _resourceContextInScope = resourceContextInScope ?? throw new ArgumentNullException(nameof(resourceContextInScope)); var expression = ParseFilter(); diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/IncludeParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/IncludeParser.cs index 5510509c97..4fd6e0aa2a 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/IncludeParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/IncludeParser.cs @@ -21,7 +21,10 @@ public IncludeParser(IResourceContextProvider resourceContextProvider, public IncludeExpression Parse(string source, ResourceContext resourceContextInScope, int? maximumDepth) { - _resourceContextInScope = resourceContextInScope ?? throw new ArgumentNullException(nameof(resourceContextInScope)); + ArgumentGuard.NotNull(resourceContextInScope, nameof(resourceContextInScope)); + + _resourceContextInScope = resourceContextInScope; + Tokenize(source); var expression = ParseInclude(maximumDepth); diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/PaginationParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/PaginationParser.cs index 765f62e7b1..8e04950a63 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/PaginationParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/PaginationParser.cs @@ -21,7 +21,10 @@ public PaginationParser(IResourceContextProvider resourceContextProvider, public PaginationQueryStringValueExpression Parse(string source, ResourceContext resourceContextInScope) { - _resourceContextInScope = resourceContextInScope ?? throw new ArgumentNullException(nameof(resourceContextInScope)); + ArgumentGuard.NotNull(resourceContextInScope, nameof(resourceContextInScope)); + + _resourceContextInScope = resourceContextInScope; + Tokenize(source); var expression = ParsePagination(); diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryStringParameterScopeParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryStringParameterScopeParser.cs index 39a00a3098..b6187e3f4b 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryStringParameterScopeParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryStringParameterScopeParser.cs @@ -22,7 +22,10 @@ public QueryStringParameterScopeParser(IResourceContextProvider resourceContextP public QueryStringParameterScopeExpression Parse(string source, ResourceContext resourceContextInScope) { - _resourceContextInScope = resourceContextInScope ?? throw new ArgumentNullException(nameof(resourceContextInScope)); + ArgumentGuard.NotNull(resourceContextInScope, nameof(resourceContextInScope)); + + _resourceContextInScope = resourceContextInScope; + Tokenize(source); var expression = ParseQueryStringParameterScope(); diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryTokenizer.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryTokenizer.cs index 25e7659001..d27df8ac38 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryTokenizer.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryTokenizer.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; @@ -26,7 +25,9 @@ public sealed class QueryTokenizer public QueryTokenizer(string source) { - _source = source ?? throw new ArgumentNullException(nameof(source)); + ArgumentGuard.NotNull(source, nameof(source)); + + _source = source; } public IEnumerable EnumerateTokens() diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/ResourceFieldChainResolver.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/ResourceFieldChainResolver.cs index 4dafa05c1f..15672107b0 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/ResourceFieldChainResolver.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/ResourceFieldChainResolver.cs @@ -15,7 +15,9 @@ internal sealed class ResourceFieldChainResolver public ResourceFieldChainResolver(IResourceContextProvider resourceContextProvider) { - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + + _resourceContextProvider = resourceContextProvider; } /// diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SortParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SortParser.cs index d8beac4d8f..c866b25398 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SortParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SortParser.cs @@ -21,7 +21,10 @@ public SortParser(IResourceContextProvider resourceContextProvider, public SortExpression Parse(string source, ResourceContext resourceContextInScope) { - _resourceContextInScope = resourceContextInScope ?? throw new ArgumentNullException(nameof(resourceContextInScope)); + ArgumentGuard.NotNull(resourceContextInScope, nameof(resourceContextInScope)); + + _resourceContextInScope = resourceContextInScope; + Tokenize(source); SortExpression expression = ParseSort(); diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldSetParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldSetParser.cs index 25d2a21e71..f428a1cd2b 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldSetParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldSetParser.cs @@ -20,7 +20,10 @@ public SparseFieldSetParser(IResourceContextProvider resourceContextProvider, Ac public SparseFieldSetExpression Parse(string source, ResourceContext resourceContext) { - _resourceContext = resourceContext ?? throw new ArgumentNullException(nameof(resourceContext)); + ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); + + _resourceContext = resourceContext; + Tokenize(source); var expression = ParseSparseFieldSet(); diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs index 62d1a8a485..ca6c888125 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs @@ -27,12 +27,19 @@ public QueryLayerComposer( IPaginationContext paginationContext, ITargetedFields targetedFields) { - _constraintProviders = constraintProviders ?? throw new ArgumentNullException(nameof(constraintProviders)); - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); - _resourceDefinitionAccessor = resourceDefinitionAccessor ?? throw new ArgumentNullException(nameof(resourceDefinitionAccessor)); - _options = options ?? throw new ArgumentNullException(nameof(options)); - _paginationContext = paginationContext ?? throw new ArgumentNullException(nameof(paginationContext)); - _targetedFields = targetedFields ?? throw new ArgumentNullException(nameof(targetedFields)); + ArgumentGuard.NotNull(constraintProviders, nameof(constraintProviders)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + ArgumentGuard.NotNull(resourceDefinitionAccessor, nameof(resourceDefinitionAccessor)); + ArgumentGuard.NotNull(options, nameof(options)); + ArgumentGuard.NotNull(paginationContext, nameof(paginationContext)); + ArgumentGuard.NotNull(targetedFields, nameof(targetedFields)); + + _constraintProviders = constraintProviders; + _resourceContextProvider = resourceContextProvider; + _resourceDefinitionAccessor = resourceDefinitionAccessor; + _options = options; + _paginationContext = paginationContext; + _targetedFields = targetedFields; _sparseFieldSetCache = new SparseFieldSetCache(constraintProviders, resourceDefinitionAccessor); } @@ -53,7 +60,7 @@ public FilterExpression GetTopFilterFromConstraints(ResourceContext resourceCont /// public QueryLayer ComposeFromConstraints(ResourceContext requestResource) { - if (requestResource == null) throw new ArgumentNullException(nameof(requestResource)); + ArgumentGuard.NotNull(requestResource, nameof(requestResource)); var constraints = _constraintProviders.SelectMany(provider => provider.GetConstraints()).ToArray(); @@ -173,7 +180,7 @@ private static IReadOnlyCollection ApplyIncludeElement /// public QueryLayer ComposeForGetById(TId id, ResourceContext resourceContext, TopFieldSelection fieldSelection) { - if (resourceContext == null) throw new ArgumentNullException(nameof(resourceContext)); + ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); var idAttribute = GetIdAttribute(resourceContext); @@ -204,7 +211,7 @@ public QueryLayer ComposeForGetById(TId id, ResourceContext resourceContext /// public QueryLayer ComposeSecondaryLayerForRelationship(ResourceContext secondaryResourceContext) { - if (secondaryResourceContext == null) throw new ArgumentNullException(nameof(secondaryResourceContext)); + ArgumentGuard.NotNull(secondaryResourceContext, nameof(secondaryResourceContext)); var secondaryLayer = ComposeFromConstraints(secondaryResourceContext); secondaryLayer.Projection = GetProjectionForRelationship(secondaryResourceContext); @@ -223,9 +230,9 @@ private IDictionary GetProjectionForRelation /// public QueryLayer WrapLayerForSecondaryEndpoint(QueryLayer secondaryLayer, ResourceContext primaryResourceContext, TId primaryId, RelationshipAttribute secondaryRelationship) { - if (secondaryLayer == null) throw new ArgumentNullException(nameof(secondaryLayer)); - if (primaryResourceContext == null) throw new ArgumentNullException(nameof(primaryResourceContext)); - if (secondaryRelationship == null) throw new ArgumentNullException(nameof(secondaryRelationship)); + ArgumentGuard.NotNull(secondaryLayer, nameof(secondaryLayer)); + ArgumentGuard.NotNull(primaryResourceContext, nameof(primaryResourceContext)); + ArgumentGuard.NotNull(secondaryRelationship, nameof(secondaryRelationship)); var innerInclude = secondaryLayer.Include; secondaryLayer.Include = null; @@ -281,7 +288,7 @@ private FilterExpression CreateFilterByIds(ICollection ids, AttrAttrib /// public QueryLayer ComposeForUpdate(TId id, ResourceContext primaryResource) { - if (primaryResource == null) throw new ArgumentNullException(nameof(primaryResource)); + ArgumentGuard.NotNull(primaryResource, nameof(primaryResource)); var includeElements = _targetedFields.Relationships .Select(relationship => new IncludeElementExpression(relationship)).ToArray(); @@ -370,7 +377,7 @@ public QueryLayer ComposeForHasMany(HasManyAttribute hasManyRelationship, T protected virtual IReadOnlyCollection GetIncludeElements(IReadOnlyCollection includeElements, ResourceContext resourceContext) { - if (resourceContext == null) throw new ArgumentNullException(nameof(resourceContext)); + ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); includeElements = _resourceDefinitionAccessor.OnApplyIncludes(resourceContext.ResourceType, includeElements); return includeElements; @@ -378,8 +385,8 @@ protected virtual IReadOnlyCollection GetIncludeElemen protected virtual FilterExpression GetFilter(IReadOnlyCollection expressionsInScope, ResourceContext resourceContext) { - if (expressionsInScope == null) throw new ArgumentNullException(nameof(expressionsInScope)); - if (resourceContext == null) throw new ArgumentNullException(nameof(resourceContext)); + ArgumentGuard.NotNull(expressionsInScope, nameof(expressionsInScope)); + ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); var filters = expressionsInScope.OfType().ToArray(); @@ -392,8 +399,8 @@ protected virtual FilterExpression GetFilter(IReadOnlyCollection expressionsInScope, ResourceContext resourceContext) { - if (expressionsInScope == null) throw new ArgumentNullException(nameof(expressionsInScope)); - if (resourceContext == null) throw new ArgumentNullException(nameof(resourceContext)); + ArgumentGuard.NotNull(expressionsInScope, nameof(expressionsInScope)); + ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); var sort = expressionsInScope.OfType().FirstOrDefault(); @@ -410,8 +417,8 @@ protected virtual SortExpression GetSort(IReadOnlyCollection ex protected virtual PaginationExpression GetPagination(IReadOnlyCollection expressionsInScope, ResourceContext resourceContext) { - if (expressionsInScope == null) throw new ArgumentNullException(nameof(expressionsInScope)); - if (resourceContext == null) throw new ArgumentNullException(nameof(resourceContext)); + ArgumentGuard.NotNull(expressionsInScope, nameof(expressionsInScope)); + ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); var pagination = expressionsInScope.OfType().FirstOrDefault(); @@ -424,7 +431,7 @@ protected virtual PaginationExpression GetPagination(IReadOnlyCollection GetProjectionForSparseAttributeSet(ResourceContext resourceContext) { - if (resourceContext == null) throw new ArgumentNullException(nameof(resourceContext)); + ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); var fieldSet = _sparseFieldSetCache.GetSparseFieldSetForQuery(resourceContext); if (!fieldSet.Any()) diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs index 09a6f42655..013a434501 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -22,17 +21,18 @@ public IncludeClauseBuilder(Expression source, LambdaScope lambdaScope, Resource IResourceContextProvider resourceContextProvider) : base(lambdaScope) { - _source = source ?? throw new ArgumentNullException(nameof(source)); - _resourceContext = resourceContext ?? throw new ArgumentNullException(nameof(resourceContext)); - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); + ArgumentGuard.NotNull(source, nameof(source)); + ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + + _source = source; + _resourceContext = resourceContext; + _resourceContextProvider = resourceContextProvider; } public Expression ApplyInclude(IncludeExpression include) { - if (include == null) - { - throw new ArgumentNullException(nameof(include)); - } + ArgumentGuard.NotNull(include, nameof(include)); return Visit(include, null); } diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameFactory.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameFactory.cs index 341dd2a23e..4c06e24abf 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameFactory.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameFactory.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using Humanizer; @@ -13,10 +12,7 @@ public sealed class LambdaParameterNameFactory public LambdaParameterNameScope Create(string typeName) { - if (typeName == null) - { - throw new ArgumentNullException(nameof(typeName)); - } + ArgumentGuard.NotNull(typeName, nameof(typeName)); string parameterName = typeName.Camelize(); parameterName = EnsureNameIsUnique(parameterName); diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameScope.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameScope.cs index e443997ca1..f757d864dd 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameScope.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameScope.cs @@ -10,8 +10,11 @@ public sealed class LambdaParameterNameScope : IDisposable public LambdaParameterNameScope(string name, LambdaParameterNameFactory owner) { - _owner = owner ?? throw new ArgumentNullException(nameof(owner)); - Name = name ?? throw new ArgumentNullException(nameof(name)); + ArgumentGuard.NotNull(name, nameof(name)); + ArgumentGuard.NotNull(owner, nameof(owner)); + + Name = name; + _owner = owner; } public void Dispose() diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScope.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScope.cs index 8555fffc43..3f4a65d56a 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScope.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScope.cs @@ -17,8 +17,8 @@ public sealed class LambdaScope : IDisposable public LambdaScope(LambdaParameterNameFactory nameFactory, Type elementType, Expression accessorExpression, HasManyThroughAttribute hasManyThrough) { - if (nameFactory == null) throw new ArgumentNullException(nameof(nameFactory)); - if (elementType == null) throw new ArgumentNullException(nameof(elementType)); + ArgumentGuard.NotNull(nameFactory, nameof(nameFactory)); + ArgumentGuard.NotNull(elementType, nameof(elementType)); _parameterNameScope = nameFactory.Create(elementType.Name); Parameter = Expression.Parameter(elementType, _parameterNameScope.Name); diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScopeFactory.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScopeFactory.cs index b0ae0467b8..dd168506df 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScopeFactory.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScopeFactory.cs @@ -11,16 +11,15 @@ public sealed class LambdaScopeFactory public LambdaScopeFactory(LambdaParameterNameFactory nameFactory, HasManyThroughAttribute hasManyThrough = null) { - _nameFactory = nameFactory ?? throw new ArgumentNullException(nameof(nameFactory)); + ArgumentGuard.NotNull(nameFactory, nameof(nameFactory)); + + _nameFactory = nameFactory; _hasManyThrough = hasManyThrough; } public LambdaScope CreateScope(Type elementType, Expression accessorExpression = null) { - if (elementType == null) - { - throw new ArgumentNullException(nameof(elementType)); - } + ArgumentGuard.NotNull(elementType, nameof(elementType)); return new LambdaScope(_nameFactory, elementType, accessorExpression, _hasManyThrough); } diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs index 2d7d72331e..881fbfb92c 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs @@ -18,16 +18,16 @@ public class OrderClauseBuilder : QueryClauseBuilder public OrderClauseBuilder(Expression source, LambdaScope lambdaScope, Type extensionType) : base(lambdaScope) { - _source = source ?? throw new ArgumentNullException(nameof(source)); - _extensionType = extensionType ?? throw new ArgumentNullException(nameof(extensionType)); + ArgumentGuard.NotNull(source, nameof(source)); + ArgumentGuard.NotNull(extensionType, nameof(extensionType)); + + _source = source; + _extensionType = extensionType; } public Expression ApplyOrderBy(SortExpression expression) { - if (expression == null) - { - throw new ArgumentNullException(nameof(expression)); - } + ArgumentGuard.NotNull(expression, nameof(expression)); return Visit(expression, null); } diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryClauseBuilder.cs index 701a867812..7bb2587be9 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryClauseBuilder.cs @@ -17,7 +17,9 @@ public abstract class QueryClauseBuilder : QueryExpressionVisitor selectors, ResourceContext resourceContext) { - if (selectors == null) - { - throw new ArgumentNullException(nameof(selectors)); - } + ArgumentGuard.NotNull(selectors, nameof(selectors)); if (!selectors.Any()) { @@ -232,18 +236,19 @@ private sealed class PropertySelector public PropertySelector(PropertyInfo property, QueryLayer nextLayer = null) { - Property = property ?? throw new ArgumentNullException(nameof(property)); + ArgumentGuard.NotNull(property, nameof(property)); + + Property = property; NextLayer = nextLayer; } public PropertySelector(ResourceFieldAttribute field, QueryLayer nextLayer = null) { - OriginatingField = field ?? throw new ArgumentNullException(nameof(field)); - NextLayer = nextLayer; + ArgumentGuard.NotNull(field, nameof(field)); - Property = field is HasManyThroughAttribute hasManyThrough - ? hasManyThrough.ThroughProperty - : field.Property; + OriginatingField = field; + NextLayer = nextLayer; + Property = field is HasManyThroughAttribute hasManyThrough ? hasManyThrough.ThroughProperty : field.Property; } public override string ToString() diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SkipTakeClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SkipTakeClauseBuilder.cs index 96c94a9cb6..993d637548 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SkipTakeClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SkipTakeClauseBuilder.cs @@ -16,16 +16,16 @@ public class SkipTakeClauseBuilder : QueryClauseBuilder public SkipTakeClauseBuilder(Expression source, LambdaScope lambdaScope, Type extensionType) : base(lambdaScope) { - _source = source ?? throw new ArgumentNullException(nameof(source)); - _extensionType = extensionType ?? throw new ArgumentNullException(nameof(extensionType)); + ArgumentGuard.NotNull(source, nameof(source)); + ArgumentGuard.NotNull(extensionType, nameof(extensionType)); + + _source = source; + _extensionType = extensionType; } public Expression ApplySkipTake(PaginationExpression expression) { - if (expression == null) - { - throw new ArgumentNullException(nameof(expression)); - } + ArgumentGuard.NotNull(expression, nameof(expression)); return Visit(expression, null); } diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs index 9ed848053f..7c79d24bd6 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs @@ -22,16 +22,16 @@ public class WhereClauseBuilder : QueryClauseBuilder public WhereClauseBuilder(Expression source, LambdaScope lambdaScope, Type extensionType) : base(lambdaScope) { - _source = source ?? throw new ArgumentNullException(nameof(source)); - _extensionType = extensionType ?? throw new ArgumentNullException(nameof(extensionType)); + ArgumentGuard.NotNull(source, nameof(source)); + ArgumentGuard.NotNull(extensionType, nameof(extensionType)); + + _source = source; + _extensionType = extensionType; } public Expression ApplyWhere(FilterExpression filter) { - if (filter == null) - { - throw new ArgumentNullException(nameof(filter)); - } + ArgumentGuard.NotNull(filter, nameof(filter)); Expression body = Visit(filter, null); LambdaExpression lambda = Expression.Lambda(body, LambdaScope.Parameter); diff --git a/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs b/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs index 19333c149c..fc123a7a14 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs @@ -19,9 +19,10 @@ public sealed class SparseFieldSetCache public SparseFieldSetCache(IEnumerable constraintProviders, IResourceDefinitionAccessor resourceDefinitionAccessor) { - if (constraintProviders == null) throw new ArgumentNullException(nameof(constraintProviders)); - _resourceDefinitionAccessor = resourceDefinitionAccessor ?? throw new ArgumentNullException(nameof(resourceDefinitionAccessor)); + ArgumentGuard.NotNull(constraintProviders, nameof(constraintProviders)); + ArgumentGuard.NotNull(resourceDefinitionAccessor, nameof(resourceDefinitionAccessor)); + _resourceDefinitionAccessor = resourceDefinitionAccessor; _lazySourceTable = new Lazy>>(() => BuildSourceTable(constraintProviders)); _visitedTable = new Dictionary>(); } @@ -59,7 +60,7 @@ private static IDictionary> Bui public IReadOnlyCollection GetSparseFieldSetForQuery(ResourceContext resourceContext) { - if (resourceContext == null) throw new ArgumentNullException(nameof(resourceContext)); + ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); if (!_visitedTable.ContainsKey(resourceContext)) { @@ -81,7 +82,7 @@ public IReadOnlyCollection GetSparseFieldSetForQuery(Res public IReadOnlyCollection GetIdAttributeSetForRelationshipQuery(ResourceContext resourceContext) { - if (resourceContext == null) throw new ArgumentNullException(nameof(resourceContext)); + ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); var idAttribute = resourceContext.Attributes.Single(attr => attr.Property.Name == nameof(Identifiable.Id)); var inputExpression = new SparseFieldSetExpression(new []{idAttribute}); @@ -127,7 +128,7 @@ public IReadOnlyCollection GetSparseFieldSetForSerialize private HashSet GetResourceFields(ResourceContext resourceContext) { - if (resourceContext == null) throw new ArgumentNullException(nameof(resourceContext)); + ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); var fieldSet = new HashSet(); diff --git a/src/JsonApiDotNetCore/Queries/QueryLayer.cs b/src/JsonApiDotNetCore/Queries/QueryLayer.cs index 74d8d5f043..bed006b12c 100644 --- a/src/JsonApiDotNetCore/Queries/QueryLayer.cs +++ b/src/JsonApiDotNetCore/Queries/QueryLayer.cs @@ -23,7 +23,9 @@ public sealed class QueryLayer public QueryLayer(ResourceContext resourceContext) { - ResourceContext = resourceContext ?? throw new ArgumentNullException(nameof(resourceContext)); + ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); + + ResourceContext = resourceContext; } public override string ToString() diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/DefaultsQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/DefaultsQueryStringParameterReader.cs index 776b9559cb..c58585f315 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/DefaultsQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/DefaultsQueryStringParameterReader.cs @@ -1,4 +1,3 @@ -using System; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers.Annotations; using JsonApiDotNetCore.Errors; @@ -17,14 +16,16 @@ public class DefaultsQueryStringParameterReader : IDefaultsQueryStringParameterR public DefaultsQueryStringParameterReader(IJsonApiOptions options) { - _options = options ?? throw new ArgumentNullException(nameof(options)); + ArgumentGuard.NotNull(options, nameof(options)); + + _options = options; SerializerDefaultValueHandling = options.SerializerSettings.DefaultValueHandling; } /// public virtual bool IsEnabled(DisableQueryStringAttribute disableQueryStringAttribute) { - if (disableQueryStringAttribute == null) throw new ArgumentNullException(nameof(disableQueryStringAttribute)); + ArgumentGuard.NotNull(disableQueryStringAttribute, nameof(disableQueryStringAttribute)); return _options.AllowQueryStringOverrideForSerializerDefaultValueHandling && !disableQueryStringAttribute.ContainsParameter(StandardQueryStringParameters.Defaults); diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs index e7e2711548..3e90992d39 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs @@ -30,7 +30,9 @@ public FilterQueryStringParameterReader(IJsonApiRequest request, IResourceContextProvider resourceContextProvider, IResourceFactory resourceFactory, IJsonApiOptions options) : base(request, resourceContextProvider) { - _options = options ?? throw new ArgumentNullException(nameof(options)); + ArgumentGuard.NotNull(options, nameof(options)); + + _options = options; _scopeParser = new QueryStringParameterScopeParser(resourceContextProvider, FieldChainRequirements.EndsInToMany); _filterParser = new FilterParser(resourceContextProvider, resourceFactory, ValidateSingleField); } @@ -47,7 +49,7 @@ protected void ValidateSingleField(ResourceFieldAttribute field, ResourceContext /// public virtual bool IsEnabled(DisableQueryStringAttribute disableQueryStringAttribute) { - if (disableQueryStringAttribute == null) throw new ArgumentNullException(nameof(disableQueryStringAttribute)); + ArgumentGuard.NotNull(disableQueryStringAttribute, nameof(disableQueryStringAttribute)); return !IsAtomicOperationsRequest && !disableQueryStringAttribute.ContainsParameter(StandardQueryStringParameters.Filter); diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/IncludeQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/IncludeQueryStringParameterReader.cs index 5b193140ff..c30f8fc7e0 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/IncludeQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/IncludeQueryStringParameterReader.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers.Annotations; @@ -23,7 +22,9 @@ public class IncludeQueryStringParameterReader : QueryStringParameterReader, IIn public IncludeQueryStringParameterReader(IJsonApiRequest request, IResourceContextProvider resourceContextProvider, IJsonApiOptions options) : base(request, resourceContextProvider) { - _options = options ?? throw new ArgumentNullException(nameof(options)); + ArgumentGuard.NotNull(options, nameof(options)); + + _options = options; _includeParser = new IncludeParser(resourceContextProvider, ValidateSingleRelationship); } @@ -42,7 +43,7 @@ protected void ValidateSingleRelationship(RelationshipAttribute relationship, Re /// public virtual bool IsEnabled(DisableQueryStringAttribute disableQueryStringAttribute) { - if (disableQueryStringAttribute == null) throw new ArgumentNullException(nameof(disableQueryStringAttribute)); + ArgumentGuard.NotNull(disableQueryStringAttribute, nameof(disableQueryStringAttribute)); return !IsAtomicOperationsRequest && !disableQueryStringAttribute.ContainsParameter(StandardQueryStringParameters.Include); diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs index efc96e435f..79a657c90e 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs @@ -44,8 +44,8 @@ public IEnumerable ExtractConditions(string parameterName, string parame public (string parameterName, string parameterValue) Convert(string parameterName, string parameterValue) { - if (parameterName == null) throw new ArgumentNullException(nameof(parameterName)); - if (parameterValue == null) throw new ArgumentNullException(nameof(parameterValue)); + ArgumentGuard.NotNull(parameterName, nameof(parameterName)); + ArgumentGuard.NotNull(parameterValue, nameof(parameterValue)); if (parameterValue.StartsWith(ExpressionPrefix, StringComparison.Ordinal)) { diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/NullsQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/NullsQueryStringParameterReader.cs index f181f5777b..ea3236b8e5 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/NullsQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/NullsQueryStringParameterReader.cs @@ -1,4 +1,3 @@ -using System; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers.Annotations; using JsonApiDotNetCore.Errors; @@ -17,14 +16,16 @@ public class NullsQueryStringParameterReader : INullsQueryStringParameterReader public NullsQueryStringParameterReader(IJsonApiOptions options) { - _options = options ?? throw new ArgumentNullException(nameof(options)); + ArgumentGuard.NotNull(options, nameof(options)); + + _options = options; SerializerNullValueHandling = options.SerializerSettings.NullValueHandling; } /// public virtual bool IsEnabled(DisableQueryStringAttribute disableQueryStringAttribute) { - if (disableQueryStringAttribute == null) throw new ArgumentNullException(nameof(disableQueryStringAttribute)); + ArgumentGuard.NotNull(disableQueryStringAttribute, nameof(disableQueryStringAttribute)); return _options.AllowQueryStringOverrideForSerializerNullValueHandling && !disableQueryStringAttribute.ContainsParameter(StandardQueryStringParameters.Nulls); diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/PaginationQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/PaginationQueryStringParameterReader.cs index 7196e9aca1..c30bc66f6b 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/PaginationQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/PaginationQueryStringParameterReader.cs @@ -26,14 +26,16 @@ public class PaginationQueryStringParameterReader : QueryStringParameterReader, public PaginationQueryStringParameterReader(IJsonApiRequest request, IResourceContextProvider resourceContextProvider, IJsonApiOptions options) : base(request, resourceContextProvider) { - _options = options ?? throw new ArgumentNullException(nameof(options)); + ArgumentGuard.NotNull(options, nameof(options)); + + _options = options; _paginationParser = new PaginationParser(resourceContextProvider); } /// public virtual bool IsEnabled(DisableQueryStringAttribute disableQueryStringAttribute) { - if (disableQueryStringAttribute == null) throw new ArgumentNullException(nameof(disableQueryStringAttribute)); + ArgumentGuard.NotNull(disableQueryStringAttribute, nameof(disableQueryStringAttribute)); return !IsAtomicOperationsRequest && !disableQueryStringAttribute.ContainsParameter(StandardQueryStringParameters.Page); diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringParameterReader.cs index 2ba5387f34..496c179fcc 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringParameterReader.cs @@ -1,4 +1,3 @@ -using System; using System.Linq; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; @@ -18,12 +17,10 @@ public abstract class QueryStringParameterReader protected QueryStringParameterReader(IJsonApiRequest request, IResourceContextProvider resourceContextProvider) { - if (request == null) - { - throw new ArgumentNullException(nameof(request)); - } + ArgumentGuard.NotNull(request, nameof(request)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); + _resourceContextProvider = resourceContextProvider; _isCollectionRequest = request.IsCollection; RequestResource = request.SecondaryResource ?? request.PrimaryResource; IsAtomicOperationsRequest = request.Kind == EndpointKind.AtomicOperations; diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringReader.cs index 1716e451ca..22ccfb3f41 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringReader.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using JsonApiDotNetCore.Configuration; @@ -19,12 +18,14 @@ public class QueryStringReader : IQueryStringReader public QueryStringReader(IJsonApiOptions options, IRequestQueryStringAccessor queryStringAccessor, IEnumerable parameterReaders, ILoggerFactory loggerFactory) { - if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); - - _options = options ?? throw new ArgumentNullException(nameof(options)); - _queryStringAccessor = queryStringAccessor ?? throw new ArgumentNullException(nameof(queryStringAccessor)); - _parameterReaders = parameterReaders ?? throw new ArgumentNullException(nameof(parameterReaders)); + ArgumentGuard.NotNull(loggerFactory, nameof(loggerFactory)); + ArgumentGuard.NotNull(options, nameof(options)); + ArgumentGuard.NotNull(queryStringAccessor, nameof(queryStringAccessor)); + ArgumentGuard.NotNull(parameterReaders, nameof(parameterReaders)); + _options = options; + _queryStringAccessor = queryStringAccessor; + _parameterReaders = parameterReaders; _logger = loggerFactory.CreateLogger(); } diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/RequestQueryStringAccessor.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/RequestQueryStringAccessor.cs index 5c2fd09c35..d53d01b054 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/RequestQueryStringAccessor.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/RequestQueryStringAccessor.cs @@ -1,4 +1,3 @@ -using System; using Microsoft.AspNetCore.Http; namespace JsonApiDotNetCore.QueryStrings.Internal @@ -8,12 +7,13 @@ internal sealed class RequestQueryStringAccessor : IRequestQueryStringAccessor { private readonly IHttpContextAccessor _httpContextAccessor; - public QueryString QueryString => _httpContextAccessor.HttpContext.Request.QueryString; public IQueryCollection Query => _httpContextAccessor.HttpContext.Request.Query; public RequestQueryStringAccessor(IHttpContextAccessor httpContextAccessor) { - _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor)); + ArgumentGuard.NotNull(httpContextAccessor, nameof(httpContextAccessor)); + + _httpContextAccessor = httpContextAccessor; } } } diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/ResourceDefinitionQueryableParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/ResourceDefinitionQueryableParameterReader.cs index 3fd55aabb1..9f29d4456a 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/ResourceDefinitionQueryableParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/ResourceDefinitionQueryableParameterReader.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using JsonApiDotNetCore.Controllers.Annotations; using JsonApiDotNetCore.Errors; @@ -19,8 +18,11 @@ public class ResourceDefinitionQueryableParameterReader : IResourceDefinitionQue public ResourceDefinitionQueryableParameterReader(IJsonApiRequest request, IResourceDefinitionAccessor resourceDefinitionAccessor) { - _request = request ?? throw new ArgumentNullException(nameof(request)); - _resourceDefinitionAccessor = resourceDefinitionAccessor ?? throw new ArgumentNullException(nameof(resourceDefinitionAccessor)); + ArgumentGuard.NotNull(request, nameof(request)); + ArgumentGuard.NotNull(resourceDefinitionAccessor, nameof(resourceDefinitionAccessor)); + + _request = request; + _resourceDefinitionAccessor = resourceDefinitionAccessor; } /// diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/SortQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/SortQueryStringParameterReader.cs index 8fa2cba15d..6df27aca86 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/SortQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/SortQueryStringParameterReader.cs @@ -38,7 +38,7 @@ protected void ValidateSingleField(ResourceFieldAttribute field, ResourceContext /// public virtual bool IsEnabled(DisableQueryStringAttribute disableQueryStringAttribute) { - if (disableQueryStringAttribute == null) throw new ArgumentNullException(nameof(disableQueryStringAttribute)); + ArgumentGuard.NotNull(disableQueryStringAttribute, nameof(disableQueryStringAttribute)); return !IsAtomicOperationsRequest && !disableQueryStringAttribute.ContainsParameter(StandardQueryStringParameters.Sort); diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs index d39fd5c774..578e1fe022 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs @@ -39,7 +39,7 @@ protected void ValidateSingleField(ResourceFieldAttribute field, ResourceContext /// public virtual bool IsEnabled(DisableQueryStringAttribute disableQueryStringAttribute) { - if (disableQueryStringAttribute == null) throw new ArgumentNullException(nameof(disableQueryStringAttribute)); + ArgumentGuard.NotNull(disableQueryStringAttribute, nameof(disableQueryStringAttribute)); return !IsAtomicOperationsRequest && !disableQueryStringAttribute.ContainsParameter(StandardQueryStringParameters.Fields); diff --git a/src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs b/src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs index 83a3f77bf3..ac0cc66d46 100644 --- a/src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs +++ b/src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using JsonApiDotNetCore.Resources; @@ -14,8 +13,8 @@ public static class DbContextExtensions /// public static IIdentifiable GetTrackedOrAttach(this DbContext dbContext, IIdentifiable resource) { - if (dbContext == null) throw new ArgumentNullException(nameof(dbContext)); - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(dbContext, nameof(dbContext)); + ArgumentGuard.NotNull(resource, nameof(resource)); var trackedIdentifiable = (IIdentifiable)dbContext.GetTrackedIdentifiable(resource); if (trackedIdentifiable == null) @@ -32,8 +31,8 @@ public static IIdentifiable GetTrackedOrAttach(this DbContext dbContext, IIdenti /// public static object GetTrackedIdentifiable(this DbContext dbContext, IIdentifiable identifiable) { - if (dbContext == null) throw new ArgumentNullException(nameof(dbContext)); - if (identifiable == null) throw new ArgumentNullException(nameof(identifiable)); + ArgumentGuard.NotNull(dbContext, nameof(dbContext)); + ArgumentGuard.NotNull(identifiable, nameof(identifiable)); var entityType = identifiable.GetType(); var entityEntry = dbContext.ChangeTracker @@ -50,7 +49,7 @@ public static object GetTrackedIdentifiable(this DbContext dbContext, IIdentifia /// public static void ResetChangeTracker(this DbContext dbContext) { - if (dbContext == null) throw new ArgumentNullException(nameof(dbContext)); + ArgumentGuard.NotNull(dbContext, nameof(dbContext)); List entriesWithChanges = dbContext.ChangeTracker.Entries().ToList(); diff --git a/src/JsonApiDotNetCore/Repositories/DbContextResolver.cs b/src/JsonApiDotNetCore/Repositories/DbContextResolver.cs index 6a4984b7ab..1cdee231d2 100644 --- a/src/JsonApiDotNetCore/Repositories/DbContextResolver.cs +++ b/src/JsonApiDotNetCore/Repositories/DbContextResolver.cs @@ -1,4 +1,3 @@ -using System; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCore.Repositories @@ -11,7 +10,9 @@ public sealed class DbContextResolver : IDbContextResolver public DbContextResolver(TDbContext context) { - _context = context ?? throw new ArgumentNullException(nameof(context)); + ArgumentGuard.NotNull(context, nameof(context)); + + _context = context; } public DbContext GetContext() => _context; diff --git a/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs b/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs index 53c672f0c7..ed70cb558d 100644 --- a/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs +++ b/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs @@ -43,14 +43,17 @@ public EntityFrameworkCoreRepository( IEnumerable constraintProviders, ILoggerFactory loggerFactory) { - if (contextResolver == null) throw new ArgumentNullException(nameof(contextResolver)); - if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); - - _targetedFields = targetedFields ?? throw new ArgumentNullException(nameof(targetedFields)); - _resourceGraph = resourceGraph ?? throw new ArgumentNullException(nameof(resourceGraph)); - _resourceFactory = resourceFactory ?? throw new ArgumentNullException(nameof(resourceFactory)); - _constraintProviders = constraintProviders ?? throw new ArgumentNullException(nameof(constraintProviders)); - + ArgumentGuard.NotNull(contextResolver, nameof(contextResolver)); + ArgumentGuard.NotNull(loggerFactory, nameof(loggerFactory)); + ArgumentGuard.NotNull(targetedFields, nameof(targetedFields)); + ArgumentGuard.NotNull(resourceGraph, nameof(resourceGraph)); + ArgumentGuard.NotNull(resourceFactory, nameof(resourceFactory)); + ArgumentGuard.NotNull(constraintProviders, nameof(constraintProviders)); + + _targetedFields = targetedFields; + _resourceGraph = resourceGraph; + _resourceFactory = resourceFactory; + _constraintProviders = constraintProviders; _dbContext = contextResolver.GetContext(); _traceWriter = new TraceLogWriter>(loggerFactory); } @@ -59,7 +62,8 @@ public EntityFrameworkCoreRepository( public virtual async Task> GetAsync(QueryLayer layer, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {layer}); - if (layer == null) throw new ArgumentNullException(nameof(layer)); + + ArgumentGuard.NotNull(layer, nameof(layer)); IQueryable query = ApplyQueryLayer(layer); return await query.ToListAsync(cancellationToken); @@ -83,7 +87,8 @@ public virtual async Task CountAsync(FilterExpression topFilter, Cancellati protected virtual IQueryable ApplyQueryLayer(QueryLayer layer) { _traceWriter.LogMethodStart(new {layer}); - if (layer == null) throw new ArgumentNullException(nameof(layer)); + + ArgumentGuard.NotNull(layer, nameof(layer)); if (EntityFrameworkCoreSupport.Version.Major < 5) { @@ -130,8 +135,9 @@ public virtual Task GetForCreateAsync(TId id, CancellationToken cance public virtual async Task CreateAsync(TResource resourceFromRequest, TResource resourceForDatabase, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {resourceFromRequest, resourceForDatabase}); - if (resourceFromRequest == null) throw new ArgumentNullException(nameof(resourceFromRequest)); - if (resourceForDatabase == null) throw new ArgumentNullException(nameof(resourceForDatabase)); + + ArgumentGuard.NotNull(resourceFromRequest, nameof(resourceFromRequest)); + ArgumentGuard.NotNull(resourceForDatabase, nameof(resourceForDatabase)); using var collector = new PlaceholderResourceCollector(_resourceFactory, _dbContext); @@ -163,8 +169,9 @@ public virtual async Task GetForUpdateAsync(QueryLayer queryLayer, Ca public virtual async Task UpdateAsync(TResource resourceFromRequest, TResource resourceFromDatabase, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {resourceFromRequest, resourceFromDatabase}); - if (resourceFromRequest == null) throw new ArgumentNullException(nameof(resourceFromRequest)); - if (resourceFromDatabase == null) throw new ArgumentNullException(nameof(resourceFromDatabase)); + + ArgumentGuard.NotNull(resourceFromRequest, nameof(resourceFromRequest)); + ArgumentGuard.NotNull(resourceFromDatabase, nameof(resourceFromDatabase)); using var collector = new PlaceholderResourceCollector(_resourceFactory, _dbContext); @@ -309,7 +316,8 @@ public virtual async Task SetRelationshipAsync(TResource primaryResource, object public virtual async Task AddToToManyRelationshipAsync(TId primaryId, ISet secondaryResourceIds, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {primaryId, secondaryResourceIds}); - if (secondaryResourceIds == null) throw new ArgumentNullException(nameof(secondaryResourceIds)); + + ArgumentGuard.NotNull(secondaryResourceIds, nameof(secondaryResourceIds)); var relationship = _targetedFields.Relationships.Single(); @@ -328,7 +336,8 @@ public virtual async Task AddToToManyRelationshipAsync(TId primaryId, ISet secondaryResourceIds, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {primaryResource, secondaryResourceIds}); - if (secondaryResourceIds == null) throw new ArgumentNullException(nameof(secondaryResourceIds)); + + ArgumentGuard.NotNull(secondaryResourceIds, nameof(secondaryResourceIds)); var relationship = (HasManyAttribute)_targetedFields.Relationships.Single(); diff --git a/src/JsonApiDotNetCore/Repositories/MemoryLeakDetectionBugRewriter.cs b/src/JsonApiDotNetCore/Repositories/MemoryLeakDetectionBugRewriter.cs index bf26979ad7..e27894ac7a 100644 --- a/src/JsonApiDotNetCore/Repositories/MemoryLeakDetectionBugRewriter.cs +++ b/src/JsonApiDotNetCore/Repositories/MemoryLeakDetectionBugRewriter.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries; @@ -19,7 +18,7 @@ public sealed class MemoryLeakDetectionBugRewriter { public QueryLayer Rewrite(QueryLayer queryLayer) { - if (queryLayer == null) throw new ArgumentNullException(nameof(queryLayer)); + ArgumentGuard.NotNull(queryLayer, nameof(queryLayer)); return RewriteLayer(queryLayer); } diff --git a/src/JsonApiDotNetCore/Repositories/PlaceholderEntityCollector.cs b/src/JsonApiDotNetCore/Repositories/PlaceholderEntityCollector.cs index dfdcf02d91..c29e974efc 100644 --- a/src/JsonApiDotNetCore/Repositories/PlaceholderEntityCollector.cs +++ b/src/JsonApiDotNetCore/Repositories/PlaceholderEntityCollector.cs @@ -18,8 +18,11 @@ public sealed class PlaceholderResourceCollector : IDisposable public PlaceholderResourceCollector(IResourceFactory resourceFactory, DbContext dbContext) { - _resourceFactory = resourceFactory ?? throw new ArgumentNullException(nameof(resourceFactory)); - _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); + ArgumentGuard.NotNull(resourceFactory, nameof(resourceFactory)); + ArgumentGuard.NotNull(dbContext, nameof(dbContext)); + + _resourceFactory = resourceFactory; + _dbContext = dbContext; } /// diff --git a/src/JsonApiDotNetCore/Repositories/ResourceRepositoryAccessor.cs b/src/JsonApiDotNetCore/Repositories/ResourceRepositoryAccessor.cs index cc7af76e18..aafc518106 100644 --- a/src/JsonApiDotNetCore/Repositories/ResourceRepositoryAccessor.cs +++ b/src/JsonApiDotNetCore/Repositories/ResourceRepositoryAccessor.cs @@ -21,9 +21,13 @@ public class ResourceRepositoryAccessor : IResourceRepositoryAccessor public ResourceRepositoryAccessor(IServiceProvider serviceProvider, IResourceContextProvider resourceContextProvider, IJsonApiRequest request) { - _serviceProvider = serviceProvider ?? throw new ArgumentException(nameof(serviceProvider)); - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentException(nameof(serviceProvider)); - _request = request ?? throw new ArgumentNullException(nameof(request)); + ArgumentGuard.NotNull(serviceProvider, nameof(serviceProvider)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + ArgumentGuard.NotNull(request, nameof(request)); + + _serviceProvider = serviceProvider; + _resourceContextProvider = resourceContextProvider; + _request = request; } /// @@ -37,7 +41,7 @@ public async Task> GetAsync(QueryLayer /// public async Task> GetAsync(Type resourceType, QueryLayer layer, CancellationToken cancellationToken) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); dynamic repository = ResolveReadRepository(resourceType); return (IReadOnlyCollection) await repository.GetAsync(layer, cancellationToken); diff --git a/src/JsonApiDotNetCore/Resources/Annotations/AttrAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/AttrAttribute.cs index d31415df57..43f739e113 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/AttrAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/AttrAttribute.cs @@ -38,10 +38,7 @@ public AttrCapabilities Capabilities /// public object GetValue(object resource) { - if (resource == null) - { - throw new ArgumentNullException(nameof(resource)); - } + ArgumentGuard.NotNull(resource, nameof(resource)); if (Property.GetMethod == null) { @@ -56,10 +53,7 @@ public object GetValue(object resource) /// public void SetValue(object resource, object newValue) { - if (resource == null) - { - throw new ArgumentNullException(nameof(resource)); - } + ArgumentGuard.NotNull(resource, nameof(resource)); if (Property.SetMethod == null) { diff --git a/src/JsonApiDotNetCore/Resources/Annotations/HasManyThroughAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/HasManyThroughAttribute.cs index 818017cae8..eab79390f9 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/HasManyThroughAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/HasManyThroughAttribute.cs @@ -123,7 +123,9 @@ public sealed class HasManyThroughAttribute : HasManyAttribute /// The name of the navigation property that will be used to access the join relationship. public HasManyThroughAttribute(string throughPropertyName) { - ThroughPropertyName = throughPropertyName ?? throw new ArgumentNullException(nameof(throughPropertyName)); + ArgumentGuard.NotNull(throughPropertyName, nameof(throughPropertyName)); + + ThroughPropertyName = throughPropertyName; } /// @@ -132,7 +134,7 @@ public HasManyThroughAttribute(string throughPropertyName) /// public override object GetValue(object resource) { - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(resource, nameof(resource)); var throughEntity = ThroughProperty.GetValue(resource); if (throughEntity == null) @@ -153,7 +155,7 @@ public override object GetValue(object resource) /// public override void SetValue(object resource, object newValue) { - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(resource, nameof(resource)); base.SetValue(resource, newValue); diff --git a/src/JsonApiDotNetCore/Resources/Annotations/RelationshipAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/RelationshipAttribute.cs index 4efb72832f..2cdab2a99f 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/RelationshipAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/RelationshipAttribute.cs @@ -73,7 +73,7 @@ public abstract class RelationshipAttribute : ResourceFieldAttribute /// public virtual object GetValue(object resource) { - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(resource, nameof(resource)); return Property.GetValue(resource); } @@ -83,7 +83,7 @@ public virtual object GetValue(object resource) /// public virtual void SetValue(object resource, object newValue) { - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(resource, nameof(resource)); Property.SetValue(resource, newValue); } diff --git a/src/JsonApiDotNetCore/Resources/Annotations/ResourceAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/ResourceAttribute.cs index f3d92fd2a1..f44666f492 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/ResourceAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/ResourceAttribute.cs @@ -16,7 +16,9 @@ public sealed class ResourceAttribute : Attribute public ResourceAttribute(string publicName) { - PublicName = publicName ?? throw new ArgumentNullException(nameof(publicName)); + ArgumentGuard.NotNull(publicName, nameof(publicName)); + + PublicName = publicName; } } } diff --git a/src/JsonApiDotNetCore/Resources/IdentifiableExtensions.cs b/src/JsonApiDotNetCore/Resources/IdentifiableExtensions.cs index 59918a25d9..b89e8ec580 100644 --- a/src/JsonApiDotNetCore/Resources/IdentifiableExtensions.cs +++ b/src/JsonApiDotNetCore/Resources/IdentifiableExtensions.cs @@ -7,8 +7,8 @@ internal static class IdentifiableExtensions { public static object GetTypedId(this IIdentifiable identifiable) { - if (identifiable == null) throw new ArgumentNullException(nameof(identifiable)); - + ArgumentGuard.NotNull(identifiable, nameof(identifiable)); + PropertyInfo property = identifiable.GetType().GetProperty(nameof(Identifiable.Id)); if (property == null) diff --git a/src/JsonApiDotNetCore/Resources/JsonApiResourceDefinition.cs b/src/JsonApiDotNetCore/Resources/JsonApiResourceDefinition.cs index 282ec058ef..bc5778a8b5 100644 --- a/src/JsonApiDotNetCore/Resources/JsonApiResourceDefinition.cs +++ b/src/JsonApiDotNetCore/Resources/JsonApiResourceDefinition.cs @@ -30,7 +30,9 @@ public class JsonApiResourceDefinition : IResourceDefinition @@ -65,10 +67,7 @@ public virtual SortExpression OnApplySort(SortExpression existingSort) /// protected SortExpression CreateSortExpressionFromLambda(PropertySortOrder keySelectors) { - if (keySelectors == null) - { - throw new ArgumentNullException(nameof(keySelectors)); - } + ArgumentGuard.NotNull(keySelectors, nameof(keySelectors)); List sortElements = new List(); diff --git a/src/JsonApiDotNetCore/Resources/OperationContainer.cs b/src/JsonApiDotNetCore/Resources/OperationContainer.cs index ff37241666..a9df285e8f 100644 --- a/src/JsonApiDotNetCore/Resources/OperationContainer.cs +++ b/src/JsonApiDotNetCore/Resources/OperationContainer.cs @@ -17,10 +17,14 @@ public sealed class OperationContainer public OperationContainer(OperationKind kind, IIdentifiable resource, ITargetedFields targetedFields, IJsonApiRequest request) { + ArgumentGuard.NotNull(resource, nameof(resource)); + ArgumentGuard.NotNull(targetedFields, nameof(targetedFields)); + ArgumentGuard.NotNull(request, nameof(request)); + Kind = kind; - Resource = resource ?? throw new ArgumentNullException(nameof(resource)); - TargetedFields = targetedFields ?? throw new ArgumentNullException(nameof(targetedFields)); - Request = request ?? throw new ArgumentNullException(nameof(request)); + Resource = resource; + TargetedFields = targetedFields; + Request = request; } public void SetTransactionId(Guid transactionId) @@ -30,7 +34,7 @@ public void SetTransactionId(Guid transactionId) public OperationContainer WithResource(IIdentifiable resource) { - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(resource, nameof(resource)); return new OperationContainer(Kind, resource, TargetedFields, Request); } diff --git a/src/JsonApiDotNetCore/Resources/ResourceChangeTracker.cs b/src/JsonApiDotNetCore/Resources/ResourceChangeTracker.cs index 701b677c48..24be52dea2 100644 --- a/src/JsonApiDotNetCore/Resources/ResourceChangeTracker.cs +++ b/src/JsonApiDotNetCore/Resources/ResourceChangeTracker.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources.Annotations; @@ -20,15 +19,19 @@ public sealed class ResourceChangeTracker : IResourceChangeTracker public void SetInitiallyStoredAttributeValues(TResource resource) { - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(resource, nameof(resource)); var resourceContext = _resourceContextProvider.GetResourceContext(); _initiallyStoredAttributeValues = CreateAttributeDictionary(resource, resourceContext.Attributes); @@ -37,7 +40,7 @@ public void SetInitiallyStoredAttributeValues(TResource resource) /// public void SetRequestedAttributeValues(TResource resource) { - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(resource, nameof(resource)); _requestedAttributeValues = CreateAttributeDictionary(resource, _targetedFields.Attributes); } @@ -45,7 +48,7 @@ public void SetRequestedAttributeValues(TResource resource) /// public void SetFinallyStoredAttributeValues(TResource resource) { - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(resource, nameof(resource)); var resourceContext = _resourceContextProvider.GetResourceContext(); _finallyStoredAttributeValues = CreateAttributeDictionary(resource, resourceContext.Attributes); diff --git a/src/JsonApiDotNetCore/Resources/ResourceDefinitionAccessor.cs b/src/JsonApiDotNetCore/Resources/ResourceDefinitionAccessor.cs index 44ed85ffe5..bf71e8bfbe 100644 --- a/src/JsonApiDotNetCore/Resources/ResourceDefinitionAccessor.cs +++ b/src/JsonApiDotNetCore/Resources/ResourceDefinitionAccessor.cs @@ -14,14 +14,17 @@ public class ResourceDefinitionAccessor : IResourceDefinitionAccessor public ResourceDefinitionAccessor(IResourceContextProvider resourceContextProvider, IServiceProvider serviceProvider) { - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); - _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + ArgumentGuard.NotNull(serviceProvider, nameof(serviceProvider)); + + _resourceContextProvider = resourceContextProvider; + _serviceProvider = serviceProvider; } /// public IReadOnlyCollection OnApplyIncludes(Type resourceType, IReadOnlyCollection existingIncludes) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return resourceDefinition.OnApplyIncludes(existingIncludes); @@ -30,7 +33,7 @@ public IReadOnlyCollection OnApplyIncludes(Type resour /// public FilterExpression OnApplyFilter(Type resourceType, FilterExpression existingFilter) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return resourceDefinition.OnApplyFilter(existingFilter); @@ -39,7 +42,7 @@ public FilterExpression OnApplyFilter(Type resourceType, FilterExpression existi /// public SortExpression OnApplySort(Type resourceType, SortExpression existingSort) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return resourceDefinition.OnApplySort(existingSort); @@ -48,7 +51,7 @@ public SortExpression OnApplySort(Type resourceType, SortExpression existingSort /// public PaginationExpression OnApplyPagination(Type resourceType, PaginationExpression existingPagination) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return resourceDefinition.OnApplyPagination(existingPagination); @@ -57,7 +60,7 @@ public PaginationExpression OnApplyPagination(Type resourceType, PaginationExpre /// public SparseFieldSetExpression OnApplySparseFieldSet(Type resourceType, SparseFieldSetExpression existingSparseFieldSet) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return resourceDefinition.OnApplySparseFieldSet(existingSparseFieldSet); @@ -66,8 +69,8 @@ public SparseFieldSetExpression OnApplySparseFieldSet(Type resourceType, SparseF /// public object GetQueryableHandlerForQueryStringParameter(Type resourceType, string parameterName) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); - if (parameterName == null) throw new ArgumentNullException(nameof(parameterName)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); + ArgumentGuard.NotNull(parameterName, nameof(parameterName)); dynamic resourceDefinition = ResolveResourceDefinition(resourceType); var handlers = resourceDefinition.OnRegisterQueryableHandlersForQueryStringParameters(); @@ -78,7 +81,7 @@ public object GetQueryableHandlerForQueryStringParameter(Type resourceType, stri /// public IDictionary GetMeta(Type resourceType, IIdentifiable resourceInstance) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return resourceDefinition.GetMeta((dynamic) resourceInstance); diff --git a/src/JsonApiDotNetCore/Resources/ResourceFactory.cs b/src/JsonApiDotNetCore/Resources/ResourceFactory.cs index e0a7a6646e..76e96cb6f5 100644 --- a/src/JsonApiDotNetCore/Resources/ResourceFactory.cs +++ b/src/JsonApiDotNetCore/Resources/ResourceFactory.cs @@ -14,16 +14,15 @@ internal sealed class ResourceFactory : IResourceFactory public ResourceFactory(IServiceProvider serviceProvider) { - _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + ArgumentGuard.NotNull(serviceProvider, nameof(serviceProvider)); + + _serviceProvider = serviceProvider; } /// public IIdentifiable CreateInstance(Type resourceType) { - if (resourceType == null) - { - throw new ArgumentNullException(nameof(resourceType)); - } + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); return InnerCreateInstance(resourceType, _serviceProvider); } @@ -57,7 +56,7 @@ private static IIdentifiable InnerCreateInstance(Type type, IServiceProvider ser /// public NewExpression CreateNewExpression(Type resourceType) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); if (HasSingleConstructorWithoutParameters(resourceType)) { diff --git a/src/JsonApiDotNetCore/Resources/ResourceHooksDefinition.cs b/src/JsonApiDotNetCore/Resources/ResourceHooksDefinition.cs index 4687c5b531..1ab143f43d 100644 --- a/src/JsonApiDotNetCore/Resources/ResourceHooksDefinition.cs +++ b/src/JsonApiDotNetCore/Resources/ResourceHooksDefinition.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Hooks.Internal; @@ -18,7 +17,9 @@ public class ResourceHooksDefinition : IResourceHookContainer diff --git a/src/JsonApiDotNetCore/Serialization/AtomicOperationsResponseSerializer.cs b/src/JsonApiDotNetCore/Serialization/AtomicOperationsResponseSerializer.cs index ba69bc0be6..526db5ffb2 100644 --- a/src/JsonApiDotNetCore/Serialization/AtomicOperationsResponseSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/AtomicOperationsResponseSerializer.cs @@ -28,11 +28,17 @@ public AtomicOperationsResponseSerializer(IResourceObjectBuilder resourceObjectB IJsonApiRequest request, IJsonApiOptions options) : base(resourceObjectBuilder) { - _metaBuilder = metaBuilder ?? throw new ArgumentNullException(nameof(metaBuilder)); - _linkBuilder = linkBuilder ?? throw new ArgumentNullException(nameof(linkBuilder)); - _fieldsToSerialize = fieldsToSerialize ?? throw new ArgumentNullException(nameof(fieldsToSerialize)); - _request = request ?? throw new ArgumentNullException(nameof(request)); - _options = options ?? throw new ArgumentNullException(nameof(options)); + ArgumentGuard.NotNull(metaBuilder, nameof(metaBuilder)); + ArgumentGuard.NotNull(linkBuilder, nameof(linkBuilder)); + ArgumentGuard.NotNull(fieldsToSerialize, nameof(fieldsToSerialize)); + ArgumentGuard.NotNull(request, nameof(request)); + ArgumentGuard.NotNull(options, nameof(options)); + + _metaBuilder = metaBuilder; + _linkBuilder = linkBuilder; + _fieldsToSerialize = fieldsToSerialize; + _request = request; + _options = options; } /// diff --git a/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs b/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs index 0b9626ffc1..82d8ae47bb 100644 --- a/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs +++ b/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs @@ -26,8 +26,11 @@ public abstract class BaseDeserializer protected BaseDeserializer(IResourceContextProvider resourceContextProvider, IResourceFactory resourceFactory) { - ResourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); - ResourceFactory = resourceFactory ?? throw new ArgumentNullException(nameof(resourceFactory)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + ArgumentGuard.NotNull(resourceFactory, nameof(resourceFactory)); + + ResourceContextProvider = resourceContextProvider; + ResourceFactory = resourceFactory; } /// @@ -46,7 +49,7 @@ protected BaseDeserializer(IResourceContextProvider resourceContextProvider, IRe protected object DeserializeBody(string body) { - if (body == null) throw new ArgumentNullException(nameof(body)); + ArgumentGuard.NotNull(body, nameof(body)); var bodyJToken = LoadJToken(body); Document = bodyJToken.ToObject(); @@ -74,8 +77,8 @@ protected object DeserializeBody(string body) /// Exposed attributes for . protected IIdentifiable SetAttributes(IIdentifiable resource, IDictionary attributeValues, IReadOnlyCollection attributes) { - if (resource == null) throw new ArgumentNullException(nameof(resource)); - if (attributes == null) throw new ArgumentNullException(nameof(attributes)); + ArgumentGuard.NotNull(resource, nameof(resource)); + ArgumentGuard.NotNull(attributes, nameof(attributes)); if (attributeValues == null || attributeValues.Count == 0) return resource; @@ -107,8 +110,8 @@ protected IIdentifiable SetAttributes(IIdentifiable resource, IDictionaryExposed relationships for . protected virtual IIdentifiable SetRelationships(IIdentifiable resource, IDictionary relationshipValues, IReadOnlyCollection relationshipAttributes) { - if (resource == null) throw new ArgumentNullException(nameof(resource)); - if (relationshipAttributes == null) throw new ArgumentNullException(nameof(relationshipAttributes)); + ArgumentGuard.NotNull(resource, nameof(resource)); + ArgumentGuard.NotNull(relationshipAttributes, nameof(relationshipAttributes)); if (relationshipValues == null || relationshipValues.Count == 0) { diff --git a/src/JsonApiDotNetCore/Serialization/BaseSerializer.cs b/src/JsonApiDotNetCore/Serialization/BaseSerializer.cs index da61a4b188..c5b0345c3c 100644 --- a/src/JsonApiDotNetCore/Serialization/BaseSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/BaseSerializer.cs @@ -19,7 +19,9 @@ public abstract class BaseSerializer protected BaseSerializer(IResourceObjectBuilder resourceObjectBuilder) { - ResourceObjectBuilder = resourceObjectBuilder ?? throw new ArgumentNullException(nameof(resourceObjectBuilder)); + ArgumentGuard.NotNull(resourceObjectBuilder, nameof(resourceObjectBuilder)); + + ResourceObjectBuilder = resourceObjectBuilder; } /// @@ -48,7 +50,7 @@ protected Document Build(IIdentifiable resource, IReadOnlyCollectionThe resource object that was built. protected Document Build(IReadOnlyCollection resources, IReadOnlyCollection attributes, IReadOnlyCollection relationships) { - if (resources == null) throw new ArgumentNullException(nameof(resources)); + ArgumentGuard.NotNull(resources, nameof(resources)); var data = new List(); foreach (IIdentifiable resource in resources) @@ -59,7 +61,7 @@ protected Document Build(IReadOnlyCollection resources, IReadOnly protected string SerializeObject(object value, JsonSerializerSettings defaultSettings, Action changeSerializer = null) { - if (defaultSettings == null) throw new ArgumentNullException(nameof(defaultSettings)); + ArgumentGuard.NotNull(defaultSettings, nameof(defaultSettings)); JsonSerializer serializer = JsonSerializer.CreateDefault(defaultSettings); changeSerializer?.Invoke(serializer); diff --git a/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs index 2697eb63a2..6b9856a73a 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs @@ -1,4 +1,3 @@ -using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -27,10 +26,15 @@ public IncludedResourceObjectBuilder(IFieldsToSerialize fieldsToSerialize, IResourceObjectBuilderSettingsProvider settingsProvider) : base(resourceContextProvider, settingsProvider.Get()) { + ArgumentGuard.NotNull(fieldsToSerialize, nameof(fieldsToSerialize)); + ArgumentGuard.NotNull(linkBuilder, nameof(linkBuilder)); + ArgumentGuard.NotNull(constraintProviders, nameof(constraintProviders)); + ArgumentGuard.NotNull(resourceDefinitionAccessor, nameof(resourceDefinitionAccessor)); + _included = new HashSet(ResourceIdentifierObjectComparer.Instance); - _fieldsToSerialize = fieldsToSerialize ?? throw new ArgumentNullException(nameof(fieldsToSerialize)); - _linkBuilder = linkBuilder ?? throw new ArgumentNullException(nameof(linkBuilder)); - _resourceDefinitionAccessor = resourceDefinitionAccessor ?? throw new ArgumentNullException(nameof(resourceDefinitionAccessor)); + _fieldsToSerialize = fieldsToSerialize; + _linkBuilder = linkBuilder; + _resourceDefinitionAccessor = resourceDefinitionAccessor; _sparseFieldSetCache = new SparseFieldSetCache(constraintProviders, resourceDefinitionAccessor); } @@ -89,8 +93,8 @@ public override ResourceObject Build(IIdentifiable resource, IReadOnlyCollection /// public void IncludeRelationshipChain(IReadOnlyCollection inclusionChain, IIdentifiable rootResource) { - if (inclusionChain == null) throw new ArgumentNullException(nameof(inclusionChain)); - if (rootResource == null) throw new ArgumentNullException(nameof(rootResource)); + ArgumentGuard.NotNull(inclusionChain, nameof(inclusionChain)); + ArgumentGuard.NotNull(rootResource, nameof(rootResource)); // We don't have to build a resource object for the root resource because // this one is already encoded in the documents primary data, so we process the chain @@ -149,8 +153,8 @@ private List ShiftChain(IReadOnlyCollection protected override RelationshipEntry GetRelationshipData(RelationshipAttribute relationship, IIdentifiable resource) { - if (relationship == null) throw new ArgumentNullException(nameof(relationship)); - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(relationship, nameof(relationship)); + ArgumentGuard.NotNull(resource, nameof(resource)); return new RelationshipEntry { Links = _linkBuilder.GetRelationshipLinks(relationship, resource) }; } diff --git a/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs index fd7b0d7c50..65bf78db94 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs @@ -32,11 +32,17 @@ public LinkBuilder(IJsonApiOptions options, IResourceContextProvider provider, IRequestQueryStringAccessor queryStringAccessor) { - _options = options ?? throw new ArgumentNullException(nameof(options)); - _request = request ?? throw new ArgumentNullException(nameof(request)); - _paginationContext = paginationContext ?? throw new ArgumentNullException(nameof(paginationContext)); - _provider = provider ?? throw new ArgumentNullException(nameof(provider)); - _queryStringAccessor = queryStringAccessor ?? throw new ArgumentNullException(nameof(queryStringAccessor)); + ArgumentGuard.NotNull(options, nameof(options)); + ArgumentGuard.NotNull(request, nameof(request)); + ArgumentGuard.NotNull(paginationContext, nameof(paginationContext)); + ArgumentGuard.NotNull(provider, nameof(provider)); + ArgumentGuard.NotNull(queryStringAccessor, nameof(queryStringAccessor)); + + _options = options; + _request = request; + _paginationContext = paginationContext; + _provider = provider; + _queryStringAccessor = queryStringAccessor; } /// @@ -227,8 +233,8 @@ private List ParsePageSizeExpressio /// public ResourceLinks GetResourceLinks(string resourceName, string id) { - if (resourceName == null) throw new ArgumentNullException(nameof(resourceName)); - if (id == null) throw new ArgumentNullException(nameof(id)); + ArgumentGuard.NotNull(resourceName, nameof(resourceName)); + ArgumentGuard.NotNull(id, nameof(id)); var resourceContext = _provider.GetResourceContext(resourceName); if (ShouldAddResourceLink(resourceContext, LinkTypes.Self)) @@ -242,8 +248,8 @@ public ResourceLinks GetResourceLinks(string resourceName, string id) /// public RelationshipLinks GetRelationshipLinks(RelationshipAttribute relationship, IIdentifiable parent) { - if (relationship == null) throw new ArgumentNullException(nameof(relationship)); - if (parent == null) throw new ArgumentNullException(nameof(parent)); + ArgumentGuard.NotNull(relationship, nameof(relationship)); + ArgumentGuard.NotNull(parent, nameof(parent)); var parentResourceContext = _provider.GetResourceContext(parent.GetType()); var childNavigation = relationship.PublicName; diff --git a/src/JsonApiDotNetCore/Serialization/Building/MetaBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/MetaBuilder.cs index dc455fe50c..8fd323adc4 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/MetaBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/MetaBuilder.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using JsonApiDotNetCore.Configuration; @@ -17,15 +16,19 @@ public class MetaBuilder : IMetaBuilder public MetaBuilder(IPaginationContext paginationContext, IJsonApiOptions options, IResponseMeta responseMeta) { - _paginationContext = paginationContext ?? throw new ArgumentNullException(nameof(paginationContext)); - _options = options ?? throw new ArgumentNullException(nameof(options)); - _responseMeta = responseMeta ?? throw new ArgumentNullException(nameof(responseMeta)); + ArgumentGuard.NotNull(paginationContext, nameof(paginationContext)); + ArgumentGuard.NotNull(options, nameof(options)); + ArgumentGuard.NotNull(responseMeta, nameof(responseMeta)); + + _paginationContext = paginationContext; + _options = options; + _responseMeta = responseMeta; } /// public void Add(IReadOnlyDictionary values) { - if (values == null) throw new ArgumentNullException(nameof(values)); + ArgumentGuard.NotNull(values, nameof(values)); _meta = values.Keys.Union(_meta.Keys) .ToDictionary(key => key, diff --git a/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs index 28808bb6ba..84189ed15b 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using JsonApiDotNetCore.Configuration; @@ -17,14 +16,17 @@ public class ResourceObjectBuilder : IResourceObjectBuilder public ResourceObjectBuilder(IResourceContextProvider resourceContextProvider, ResourceObjectBuilderSettings settings) { - ResourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); - _settings = settings ?? throw new ArgumentNullException(nameof(settings)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + ArgumentGuard.NotNull(settings, nameof(settings)); + + ResourceContextProvider = resourceContextProvider; + _settings = settings; } /// public virtual ResourceObject Build(IIdentifiable resource, IReadOnlyCollection attributes = null, IReadOnlyCollection relationships = null) { - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(resource, nameof(resource)); var resourceContext = ResourceContextProvider.GetResourceContext(resource.GetType()); @@ -51,8 +53,8 @@ public virtual ResourceObject Build(IIdentifiable resource, IReadOnlyCollection< /// protected virtual RelationshipEntry GetRelationshipData(RelationshipAttribute relationship, IIdentifiable resource) { - if (relationship == null) throw new ArgumentNullException(nameof(relationship)); - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(relationship, nameof(relationship)); + ArgumentGuard.NotNull(resource, nameof(resource)); return new RelationshipEntry { Data = GetRelatedResourceLinkage(relationship, resource) }; } @@ -62,8 +64,8 @@ protected virtual RelationshipEntry GetRelationshipData(RelationshipAttribute re /// protected object GetRelatedResourceLinkage(RelationshipAttribute relationship, IIdentifiable resource) { - if (relationship == null) throw new ArgumentNullException(nameof(relationship)); - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(relationship, nameof(relationship)); + ArgumentGuard.NotNull(resource, nameof(resource)); return relationship is HasOneAttribute hasOne ? (object) GetRelatedResourceLinkageForHasOne(hasOne, resource) diff --git a/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilderSettingsProvider.cs b/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilderSettingsProvider.cs index 8b317c3e3e..83422527ed 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilderSettingsProvider.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilderSettingsProvider.cs @@ -1,4 +1,3 @@ -using System; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.QueryStrings; @@ -15,8 +14,11 @@ public sealed class ResourceObjectBuilderSettingsProvider : IResourceObjectBuild public ResourceObjectBuilderSettingsProvider(IDefaultsQueryStringParameterReader defaultsReader, INullsQueryStringParameterReader nullsReader) { - _defaultsReader = defaultsReader ?? throw new ArgumentNullException(nameof(defaultsReader)); - _nullsReader = nullsReader ?? throw new ArgumentNullException(nameof(nullsReader)); + ArgumentGuard.NotNull(defaultsReader, nameof(defaultsReader)); + ArgumentGuard.NotNull(nullsReader, nameof(nullsReader)); + + _defaultsReader = defaultsReader; + _nullsReader = nullsReader; } /// diff --git a/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs index 2da9e21875..239dbdc560 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using JsonApiDotNetCore.Configuration; @@ -29,18 +28,24 @@ public ResponseResourceObjectBuilder(ILinkBuilder linkBuilder, IResourceObjectBuilderSettingsProvider settingsProvider) : base(resourceContextProvider, settingsProvider.Get()) { - _linkBuilder = linkBuilder ?? throw new ArgumentNullException(nameof(linkBuilder)); - _includedBuilder = includedBuilder ?? throw new ArgumentNullException(nameof(includedBuilder)); - _constraintProviders = constraintProviders ?? throw new ArgumentNullException(nameof(constraintProviders)); - _resourceDefinitionAccessor = resourceDefinitionAccessor ?? throw new ArgumentNullException(nameof(resourceDefinitionAccessor)); + ArgumentGuard.NotNull(linkBuilder, nameof(linkBuilder)); + ArgumentGuard.NotNull(includedBuilder, nameof(includedBuilder)); + ArgumentGuard.NotNull(constraintProviders, nameof(constraintProviders)); + ArgumentGuard.NotNull(resourceDefinitionAccessor, nameof(resourceDefinitionAccessor)); + + _linkBuilder = linkBuilder; + _includedBuilder = includedBuilder; + _constraintProviders = constraintProviders; + _resourceDefinitionAccessor = resourceDefinitionAccessor; _sparseFieldSetCache = new SparseFieldSetCache(constraintProviders, resourceDefinitionAccessor); } public RelationshipEntry Build(IIdentifiable resource, RelationshipAttribute requestRelationship) { - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(resource, nameof(resource)); + ArgumentGuard.NotNull(requestRelationship, nameof(requestRelationship)); - _requestRelationship = requestRelationship ?? throw new ArgumentNullException(nameof(requestRelationship)); + _requestRelationship = requestRelationship; return GetRelationshipData(requestRelationship, resource); } @@ -64,8 +69,8 @@ public override ResourceObject Build(IIdentifiable resource, IReadOnlyCollection /// protected override RelationshipEntry GetRelationshipData(RelationshipAttribute relationship, IIdentifiable resource) { - if (relationship == null) throw new ArgumentNullException(nameof(relationship)); - if (resource == null) throw new ArgumentNullException(nameof(resource)); + ArgumentGuard.NotNull(relationship, nameof(relationship)); + ArgumentGuard.NotNull(resource, nameof(resource)); RelationshipEntry relationshipEntry = null; List> relationshipChains = null; diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs index b01ab6f11a..6d7703c002 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs @@ -23,7 +23,9 @@ public RequestSerializer(IResourceGraph resourceGraph, IResourceObjectBuilder resourceObjectBuilder) : base(resourceObjectBuilder) { - _resourceGraph = resourceGraph ?? throw new ArgumentNullException(nameof(resourceGraph)); + ArgumentGuard.NotNull(resourceGraph, nameof(resourceGraph)); + + _resourceGraph = resourceGraph; } /// @@ -45,7 +47,7 @@ public string Serialize(IIdentifiable resource) /// public string Serialize(IReadOnlyCollection resources) { - if (resources == null) throw new ArgumentNullException(nameof(resources)); + ArgumentGuard.NotNull(resources, nameof(resources)); IIdentifiable firstResource = resources.FirstOrDefault(); diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs index 91b6a0392c..46e1073a96 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs @@ -18,7 +18,7 @@ public ResponseDeserializer(IResourceContextProvider resourceContextProvider, IR /// public SingleResponse DeserializeSingle(string body) where TResource : class, IIdentifiable { - if (body == null) throw new ArgumentNullException(nameof(body)); + ArgumentGuard.NotNull(body, nameof(body)); var resource = DeserializeBody(body); return new SingleResponse @@ -34,7 +34,7 @@ public SingleResponse DeserializeSingle(string body) where /// public ManyResponse DeserializeMany(string body) where TResource : class, IIdentifiable { - if (body == null) throw new ArgumentNullException(nameof(body)); + ArgumentGuard.NotNull(body, nameof(body)); var resources = DeserializeBody(body); return new ManyResponse @@ -57,8 +57,8 @@ public ManyResponse DeserializeMany(string body) where TRe /// Relationship data for . Is null when is not a . protected override void AfterProcessField(IIdentifiable resource, ResourceFieldAttribute field, RelationshipEntry data = null) { - if (resource == null) throw new ArgumentNullException(nameof(resource)); - if (field == null) throw new ArgumentNullException(nameof(field)); + ArgumentGuard.NotNull(resource, nameof(resource)); + ArgumentGuard.NotNull(field, nameof(field)); // Client deserializers do not need additional processing for attributes. if (field is AttrAttribute) diff --git a/src/JsonApiDotNetCore/Serialization/FieldsToSerialize.cs b/src/JsonApiDotNetCore/Serialization/FieldsToSerialize.cs index 59abbab7fb..cbbb062769 100644 --- a/src/JsonApiDotNetCore/Serialization/FieldsToSerialize.cs +++ b/src/JsonApiDotNetCore/Serialization/FieldsToSerialize.cs @@ -23,15 +23,18 @@ public FieldsToSerialize( IResourceDefinitionAccessor resourceDefinitionAccessor, IJsonApiRequest request) { - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); - _request = request ?? throw new ArgumentNullException(nameof(request)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + ArgumentGuard.NotNull(request, nameof(request)); + + _resourceContextProvider = resourceContextProvider; + _request = request; _sparseFieldSetCache = new SparseFieldSetCache(constraintProviders, resourceDefinitionAccessor); } /// public IReadOnlyCollection GetAttributes(Type resourceType) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); if (_request.Kind == EndpointKind.Relationship) { @@ -53,7 +56,7 @@ public IReadOnlyCollection GetAttributes(Type resourceType) /// public IReadOnlyCollection GetRelationships(Type resourceType) { - if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); if (_request.Kind == EndpointKind.Relationship) { diff --git a/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs b/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs index 83208e4941..035b5f9e8d 100644 --- a/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs +++ b/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs @@ -32,18 +32,20 @@ public JsonApiReader(IJsonApiDeserializer deserializer, IResourceContextProvider resourceContextProvider, ILoggerFactory loggerFactory) { - if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); - - _deserializer = deserializer ?? throw new ArgumentNullException(nameof(deserializer)); - _request = request ?? throw new ArgumentNullException(nameof(request)); - _resourceContextProvider = resourceContextProvider ?? throw new ArgumentNullException(nameof(resourceContextProvider)); + ArgumentGuard.NotNull(deserializer, nameof(deserializer)); + ArgumentGuard.NotNull(request, nameof(request)); + ArgumentGuard.NotNull(resourceContextProvider, nameof(resourceContextProvider)); + ArgumentGuard.NotNull(loggerFactory, nameof(loggerFactory)); + + _deserializer = deserializer; + _request = request; + _resourceContextProvider = resourceContextProvider; _traceWriter = new TraceLogWriter(loggerFactory); } public async Task ReadAsync(InputFormatterContext context) { - if (context == null) - throw new ArgumentNullException(nameof(context)); + ArgumentGuard.NotNull(context, nameof(context)); string body = await GetRequestBodyAsync(context.HttpContext.Request.Body); diff --git a/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs b/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs index 72ecb569ee..ea97a0e936 100644 --- a/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs +++ b/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs @@ -26,16 +26,18 @@ public class JsonApiWriter : IJsonApiWriter public JsonApiWriter(IJsonApiSerializer serializer, IExceptionHandler exceptionHandler, ILoggerFactory loggerFactory) { - if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); + ArgumentGuard.NotNull(serializer, nameof(serializer)); + ArgumentGuard.NotNull(exceptionHandler, nameof(exceptionHandler)); + ArgumentGuard.NotNull(loggerFactory, nameof(loggerFactory)); - _serializer = serializer ?? throw new ArgumentNullException(nameof(serializer)); - _exceptionHandler = exceptionHandler ?? throw new ArgumentNullException(nameof(exceptionHandler)); + _serializer = serializer; + _exceptionHandler = exceptionHandler; _traceWriter = new TraceLogWriter(loggerFactory); } public async Task WriteAsync(OutputFormatterWriteContext context) { - if (context == null) throw new ArgumentNullException(nameof(context)); + ArgumentGuard.NotNull(context, nameof(context)); var response = context.HttpContext.Response; response.ContentType = _serializer.ContentType; diff --git a/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs b/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs index 34b89596e4..8bd626cb95 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs @@ -21,7 +21,7 @@ public ErrorDocument(Error error) public ErrorDocument(IEnumerable errors) { - if (errors == null) throw new ArgumentNullException(nameof(errors)); + ArgumentGuard.NotNull(errors, nameof(errors)); Errors = errors.ToList(); } diff --git a/src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs b/src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs index e942081d2c..ff90e89bfd 100644 --- a/src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs +++ b/src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs @@ -32,16 +32,21 @@ public RequestDeserializer( IJsonApiOptions options) : base(resourceContextProvider, resourceFactory) { - _targetedFields = targetedFields ?? throw new ArgumentNullException(nameof(targetedFields)); - _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor)); - _request = request ?? throw new ArgumentNullException(nameof(request)); - _options = options ?? throw new ArgumentNullException(nameof(options)); + ArgumentGuard.NotNull(targetedFields, nameof(targetedFields)); + ArgumentGuard.NotNull(httpContextAccessor, nameof(httpContextAccessor)); + ArgumentGuard.NotNull(request, nameof(request)); + ArgumentGuard.NotNull(options, nameof(options)); + + _targetedFields = targetedFields; + _httpContextAccessor = httpContextAccessor; + _request = request; + _options = options; } /// public object Deserialize(string body) { - if (body == null) throw new ArgumentNullException(nameof(body)); + ArgumentGuard.NotNull(body, nameof(body)); if (_request.Kind == EndpointKind.Relationship) { diff --git a/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs b/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs index cef0f45efe..d0e6471939 100644 --- a/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs @@ -25,12 +25,12 @@ namespace JsonApiDotNetCore.Serialization public class ResponseSerializer : BaseSerializer, IJsonApiSerializer where TResource : class, IIdentifiable { - private readonly IFieldsToSerialize _fieldsToSerialize; - private readonly IJsonApiOptions _options; private readonly IMetaBuilder _metaBuilder; - private readonly Type _primaryResourceType; private readonly ILinkBuilder _linkBuilder; private readonly IIncludedResourceObjectBuilder _includedBuilder; + private readonly IFieldsToSerialize _fieldsToSerialize; + private readonly IJsonApiOptions _options; + private readonly Type _primaryResourceType; /// public string ContentType { get; } = HeaderConstants.MediaType; @@ -43,11 +43,17 @@ public ResponseSerializer(IMetaBuilder metaBuilder, IJsonApiOptions options) : base(resourceObjectBuilder) { - _fieldsToSerialize = fieldsToSerialize ?? throw new ArgumentNullException(nameof(fieldsToSerialize)); - _options = options ?? throw new ArgumentNullException(nameof(options)); - _linkBuilder = linkBuilder ?? throw new ArgumentNullException(nameof(linkBuilder)); - _metaBuilder = metaBuilder ?? throw new ArgumentNullException(nameof(metaBuilder)); - _includedBuilder = includedBuilder ?? throw new ArgumentNullException(nameof(includedBuilder)); + ArgumentGuard.NotNull(metaBuilder, nameof(metaBuilder)); + ArgumentGuard.NotNull(linkBuilder, nameof(linkBuilder)); + ArgumentGuard.NotNull(includedBuilder, nameof(includedBuilder)); + ArgumentGuard.NotNull(fieldsToSerialize, nameof(fieldsToSerialize)); + ArgumentGuard.NotNull(options, nameof(options)); + + _metaBuilder = metaBuilder; + _linkBuilder = linkBuilder; + _includedBuilder = includedBuilder; + _fieldsToSerialize = fieldsToSerialize; + _options = options; _primaryResourceType = typeof(TResource); } diff --git a/src/JsonApiDotNetCore/Serialization/ResponseSerializerFactory.cs b/src/JsonApiDotNetCore/Serialization/ResponseSerializerFactory.cs index 386fd2bf8b..0a1722b7be 100644 --- a/src/JsonApiDotNetCore/Serialization/ResponseSerializerFactory.cs +++ b/src/JsonApiDotNetCore/Serialization/ResponseSerializerFactory.cs @@ -16,8 +16,11 @@ public class ResponseSerializerFactory : IJsonApiSerializerFactory public ResponseSerializerFactory(IJsonApiRequest request, IRequestScopedServiceProvider provider) { - _request = request ?? throw new ArgumentNullException(nameof(request)); - _provider = provider ?? throw new ArgumentNullException(nameof(provider)); + ArgumentGuard.NotNull(request, nameof(request)); + ArgumentGuard.NotNull(provider, nameof(provider)); + + _request = request; + _provider = provider; } /// diff --git a/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs b/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs index 0eb6ae09a8..f498579d56 100644 --- a/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs +++ b/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs @@ -42,16 +42,23 @@ public JsonApiResourceService( IResourceChangeTracker resourceChangeTracker, IResourceHookExecutorFacade hookExecutor) { - if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); - - _repositoryAccessor = repositoryAccessor ?? throw new ArgumentNullException(nameof(repositoryAccessor)); - _queryLayerComposer = queryLayerComposer ?? throw new ArgumentNullException(nameof(queryLayerComposer)); - _paginationContext = paginationContext ?? throw new ArgumentNullException(nameof(paginationContext)); - _options = options ?? throw new ArgumentNullException(nameof(options)); + ArgumentGuard.NotNull(repositoryAccessor, nameof(repositoryAccessor)); + ArgumentGuard.NotNull(queryLayerComposer, nameof(queryLayerComposer)); + ArgumentGuard.NotNull(paginationContext, nameof(paginationContext)); + ArgumentGuard.NotNull(options, nameof(options)); + ArgumentGuard.NotNull(loggerFactory, nameof(loggerFactory)); + ArgumentGuard.NotNull(request, nameof(request)); + ArgumentGuard.NotNull(resourceChangeTracker, nameof(resourceChangeTracker)); + ArgumentGuard.NotNull(hookExecutor, nameof(hookExecutor)); + + _repositoryAccessor = repositoryAccessor; + _queryLayerComposer = queryLayerComposer; + _paginationContext = paginationContext; + _options = options; + _request = request; + _resourceChangeTracker = resourceChangeTracker; + _hookExecutor = hookExecutor; _traceWriter = new TraceLogWriter>(loggerFactory); - _request = request ?? throw new ArgumentNullException(nameof(request)); - _resourceChangeTracker = resourceChangeTracker ?? throw new ArgumentNullException(nameof(resourceChangeTracker)); - _hookExecutor = hookExecutor ?? throw new ArgumentNullException(nameof(hookExecutor)); } /// @@ -141,7 +148,8 @@ public virtual async Task GetSecondaryAsync(TId id, string relationshipN public virtual async Task GetRelationshipAsync(TId id, string relationshipName, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {id, relationshipName}); - if (relationshipName == null) throw new ArgumentNullException(nameof(relationshipName)); + + ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); AssertHasRelationship(_request.Relationship, relationshipName); @@ -166,7 +174,8 @@ public virtual async Task GetRelationshipAsync(TId id, string relationsh public virtual async Task CreateAsync(TResource resource, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {resource}); - if (resource == null) throw new ArgumentNullException(nameof(resource)); + + ArgumentGuard.NotNull(resource, nameof(resource)); var resourceFromRequest = resource; _resourceChangeTracker.SetRequestedAttributeValues(resourceFromRequest); @@ -255,8 +264,9 @@ private async IAsyncEnumerable GetMissingRightRes public async Task AddToToManyRelationshipAsync(TId primaryId, string relationshipName, ISet secondaryResourceIds, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {primaryId, secondaryResourceIds}); - if (relationshipName == null) throw new ArgumentNullException(nameof(relationshipName)); - if (secondaryResourceIds == null) throw new ArgumentNullException(nameof(secondaryResourceIds)); + + ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); + ArgumentGuard.NotNull(secondaryResourceIds, nameof(secondaryResourceIds)); AssertHasRelationship(_request.Relationship, relationshipName); @@ -314,7 +324,8 @@ private async Task AssertResourcesExistAsync(ICollection secondar public virtual async Task UpdateAsync(TId id, TResource resource, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {id, resource}); - if (resource == null) throw new ArgumentNullException(nameof(resource)); + + ArgumentGuard.NotNull(resource, nameof(resource)); var resourceFromRequest = resource; _resourceChangeTracker.SetRequestedAttributeValues(resourceFromRequest); @@ -356,7 +367,8 @@ public virtual async Task UpdateAsync(TId id, TResource resource, Can public virtual async Task SetRelationshipAsync(TId primaryId, string relationshipName, object secondaryResourceIds, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {primaryId, relationshipName, secondaryResourceIds}); - if (relationshipName == null) throw new ArgumentNullException(nameof(relationshipName)); + + ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); AssertHasRelationship(_request.Relationship, relationshipName); @@ -402,8 +414,9 @@ public virtual async Task DeleteAsync(TId id, CancellationToken cancellationToke public async Task RemoveFromToManyRelationshipAsync(TId primaryId, string relationshipName, ISet secondaryResourceIds, CancellationToken cancellationToken) { _traceWriter.LogMethodStart(new {primaryId, relationshipName, secondaryResourceIds}); - if (relationshipName == null) throw new ArgumentNullException(nameof(relationshipName)); - if (secondaryResourceIds == null) throw new ArgumentNullException(nameof(secondaryResourceIds)); + + ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); + ArgumentGuard.NotNull(secondaryResourceIds, nameof(secondaryResourceIds)); AssertHasRelationship(_request.Relationship, relationshipName); diff --git a/src/JsonApiDotNetCore/TypeHelper.cs b/src/JsonApiDotNetCore/TypeHelper.cs index 50a0387b47..8ffa4e592f 100644 --- a/src/JsonApiDotNetCore/TypeHelper.cs +++ b/src/JsonApiDotNetCore/TypeHelper.cs @@ -18,10 +18,7 @@ internal static class TypeHelper public static object ConvertType(object value, Type type) { - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } + ArgumentGuard.NotNull(type, nameof(type)); if (value == null) { @@ -288,10 +285,7 @@ public static ICollection ExtractResources(object value) public static object CreateInstance(Type type) { - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } + ArgumentGuard.NotNull(type, nameof(type)); try { @@ -331,8 +325,8 @@ public static IList CopyToList(IEnumerable copyFrom, Type elementType, Converter /// Target collection type, for example: typeof(List{Article}) or typeof(ISet{Person}). public static IEnumerable CopyToTypedCollection(IEnumerable source, Type collectionType) { - if (source == null) throw new ArgumentNullException(nameof(source)); - if (collectionType == null) throw new ArgumentNullException(nameof(collectionType)); + ArgumentGuard.NotNull(source, nameof(source)); + ArgumentGuard.NotNull(collectionType, nameof(collectionType)); var concreteCollectionType = ToConcreteCollectionType(collectionType); dynamic concreteCollectionInstance = CreateInstance(concreteCollectionType); @@ -350,10 +344,7 @@ public static IEnumerable CopyToTypedCollection(IEnumerable source, Type collect /// public static bool IsOrImplementsInterface(Type source, Type interfaceType) { - if (interfaceType == null) - { - throw new ArgumentNullException(nameof(interfaceType)); - } + ArgumentGuard.NotNull(interfaceType, nameof(interfaceType)); if (source == null) { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs index 439cd821b5..90b3602301 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; using Microsoft.AspNetCore.Authentication; @@ -14,7 +15,9 @@ public sealed class MusicTrackReleaseDefinition : JsonApiResourceDefinition OnRegisterQueryableHandlersForQueryStringParameters() diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionDbContext.cs index 2b695dfd45..d274e3ca89 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionDbContext.cs @@ -1,4 +1,4 @@ -using System; +using JsonApiDotNetCore; using Microsoft.AspNetCore.Authentication; using Microsoft.EntityFrameworkCore; @@ -14,7 +14,9 @@ public sealed class InjectionDbContext : DbContext public InjectionDbContext(DbContextOptions options, ISystemClock systemClock) : base(options) { - SystemClock = systemClock ?? throw new ArgumentNullException(nameof(systemClock)); + ArgumentGuard.NotNull(systemClock, nameof(systemClock)); + + SystemClock = systemClock; } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionFakers.cs index 35aea4b060..0b006a4618 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionFakers.cs @@ -1,5 +1,6 @@ using System; using Bogus; +using JsonApiDotNetCore; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; @@ -17,7 +18,9 @@ internal sealed class InjectionFakers : FakerContainer public InjectionFakers(IServiceProvider serviceProvider) { - _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + ArgumentGuard.NotNull(serviceProvider, nameof(serviceProvider)); + + _serviceProvider = serviceProvider; _lazyPostOfficeFaker = new Lazy>(() => new Faker() diff --git a/test/UnitTests/Models/ResourceConstructionTests.cs b/test/UnitTests/Models/ResourceConstructionTests.cs index 0e8077ca79..59af406378 100644 --- a/test/UnitTests/Models/ResourceConstructionTests.cs +++ b/test/UnitTests/Models/ResourceConstructionTests.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel.Design; +using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.Resources; @@ -134,7 +135,9 @@ public class ResourceWithDbContextConstructor : Identifiable public ResourceWithDbContextConstructor(AppDbContext appDbContext) { - AppDbContext = appDbContext ?? throw new ArgumentNullException(nameof(appDbContext)); + ArgumentGuard.NotNull(appDbContext, nameof(appDbContext)); + + AppDbContext = appDbContext; } } @@ -152,7 +155,9 @@ public class ResourceWithStringConstructor : Identifiable public ResourceWithStringConstructor(string text) { - Text = text ?? throw new ArgumentNullException(nameof(text)); + ArgumentGuard.NotNull(text, nameof(text)); + + Text = text; } } } From b9fd0adf85122a7b305eb4508261303ac8ff2348 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Mon, 15 Feb 2021 11:39:31 +0100 Subject: [PATCH 02/60] Added curlies on single-statement branches and loops --- benchmarks/Query/QueryParserBenchmarks.cs | 5 +- .../Configuration/ResourceGraph.cs | 10 ++++ .../Configuration/ResourceGraphBuilder.cs | 16 +++++- .../Configuration/TypeLocator.cs | 2 + .../Controllers/BaseJsonApiController.cs | 57 ++++++++++++++++--- .../Internal/Discovery/HooksDiscovery.cs | 2 + .../Execution/DiffableResourceHashSet.cs | 5 +- .../Internal/Execution/HookExecutorHelper.cs | 45 ++++++++++++--- .../Hooks/Internal/ResourceHookExecutor.cs | 40 +++++++++++-- .../Internal/Traversal/RelationshipProxy.cs | 11 +++- .../Internal/Traversal/TraversalHelper.cs | 24 ++++++-- .../Serialization/BaseDeserializer.cs | 4 ++ .../Serialization/BaseSerializer.cs | 4 ++ .../Building/IncludedResourceObjectBuilder.cs | 17 +++++- .../Building/ResourceObjectBuilder.cs | 6 ++ .../Building/ResponseResourceObjectBuilder.cs | 4 ++ .../Client/Internal/RequestSerializer.cs | 4 ++ .../Client/Internal/ResponseDeserializer.cs | 4 ++ .../Serialization/Objects/ErrorDocument.cs | 2 + .../Serialization/Objects/ExposableData.cs | 14 +++++ src/JsonApiDotNetCore/TypeHelper.cs | 14 ++++- .../ResourceHooks/ResourceHooksTestsSetup.cs | 2 + .../Serialization/DeserializerTestsSetup.cs | 5 +- .../IncludedResourceObjectBuilderTests.cs | 2 + .../Server/ResponseSerializerTests.cs | 3 + 25 files changed, 265 insertions(+), 37 deletions(-) diff --git a/benchmarks/Query/QueryParserBenchmarks.cs b/benchmarks/Query/QueryParserBenchmarks.cs index 990d2a1995..1d7d1b6727 100644 --- a/benchmarks/Query/QueryParserBenchmarks.cs +++ b/benchmarks/Query/QueryParserBenchmarks.cs @@ -100,9 +100,12 @@ public void ComplexQuery() => Run(100, () => _queryStringReaderForAll.ReadAll(null); }); - private void Run(int iterations, Action action) { + private void Run(int iterations, Action action) + { for (int i = 0; i < iterations; i++) + { action(); + } } private sealed class FakeRequestQueryStringAccessor : IRequestQueryStringAccessor diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs index d729e7148f..9fa65a99ac 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs @@ -106,14 +106,22 @@ private IReadOnlyCollection Getter(Expression { IReadOnlyCollection available; if (type == FieldFilterType.Attribute) + { available = GetResourceContext(typeof(TResource)).Attributes; + } else if (type == FieldFilterType.Relationship) + { available = GetResourceContext(typeof(TResource)).Relationships; + } else + { available = GetResourceContext(typeof(TResource)).Fields; + } if (selector == null) + { return available; + } var targeted = new List(); @@ -140,7 +148,9 @@ private IReadOnlyCollection Getter(Expression try { if (newExpression.Members == null) + { return targeted; + } foreach (var member in newExpression.Members) { diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs index e1434ea252..5023bc547d 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs @@ -137,7 +137,9 @@ private IReadOnlyCollection GetAttributes(Type resourceType) } if (attribute == null) + { continue; + } attribute.PublicName ??= FormatPropertyName(property); attribute.Property = property; @@ -161,7 +163,10 @@ private IReadOnlyCollection GetRelationships(Type resourc foreach (var prop in properties) { var attribute = (RelationshipAttribute)prop.GetCustomAttribute(typeof(RelationshipAttribute)); - if (attribute == null) continue; + if (attribute == null) + { + continue; + } attribute.Property = prop; attribute.PublicName ??= FormatPropertyName(prop); @@ -173,11 +178,15 @@ private IReadOnlyCollection GetRelationships(Type resourc { var throughProperty = properties.SingleOrDefault(p => p.Name == hasManyThroughAttribute.ThroughPropertyName); if (throughProperty == null) + { throw new InvalidConfigurationException($"Invalid {nameof(HasManyThroughAttribute)} on '{resourceType}.{attribute.Property.Name}': Resource does not contain a property named '{hasManyThroughAttribute.ThroughPropertyName}'."); + } var throughType = TryGetThroughType(throughProperty); if (throughType == null) + { throw new InvalidConfigurationException($"Invalid {nameof(HasManyThroughAttribute)} on '{resourceType}.{attribute.Property.Name}': Referenced property '{throughProperty.Name}' does not implement 'ICollection'."); + } // ICollection hasManyThroughAttribute.ThroughProperty = throughProperty; @@ -269,7 +278,10 @@ private IReadOnlyCollection GetEagerLoads(Type resourceType, foreach (var property in properties) { var attribute = (EagerLoadAttribute) property.GetCustomAttribute(typeof(EagerLoadAttribute)); - if (attribute == null) continue; + if (attribute == null) + { + continue; + } Type innerType = TypeOrElementType(property.PropertyType); attribute.Children = GetEagerLoads(innerType, recursionDepth + 1); diff --git a/src/JsonApiDotNetCore/Configuration/TypeLocator.cs b/src/JsonApiDotNetCore/Configuration/TypeLocator.cs index f5b7b95d59..bd30429065 100644 --- a/src/JsonApiDotNetCore/Configuration/TypeLocator.cs +++ b/src/JsonApiDotNetCore/Configuration/TypeLocator.cs @@ -118,7 +118,9 @@ public static IEnumerable GetDerivedTypes(Assembly assembly, Type inherite foreach (var type in assembly.GetTypes()) { if (inheritedType.IsAssignableFrom(type)) + { yield return type; + } } } } diff --git a/src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs b/src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs index 8b7f73ed86..ebed4f6beb 100644 --- a/src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs +++ b/src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs @@ -96,7 +96,11 @@ public virtual async Task GetAsync(CancellationToken cancellation { _traceWriter.LogMethodStart(); - if (_getAll == null) throw new RequestMethodNotAllowedException(HttpMethod.Get); + if (_getAll == null) + { + throw new RequestMethodNotAllowedException(HttpMethod.Get); + } + var resources = await _getAll.GetAsync(cancellationToken); return Ok(resources); @@ -110,7 +114,11 @@ public virtual async Task GetAsync(TId id, CancellationToken canc { _traceWriter.LogMethodStart(new {id}); - if (_getById == null) throw new RequestMethodNotAllowedException(HttpMethod.Get); + if (_getById == null) + { + throw new RequestMethodNotAllowedException(HttpMethod.Get); + } + var resource = await _getById.GetAsync(id, cancellationToken); return Ok(resource); @@ -128,7 +136,11 @@ public virtual async Task GetSecondaryAsync(TId id, string relati ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); - if (_getSecondary == null) throw new RequestMethodNotAllowedException(HttpMethod.Get); + if (_getSecondary == null) + { + throw new RequestMethodNotAllowedException(HttpMethod.Get); + } + var relationship = await _getSecondary.GetSecondaryAsync(id, relationshipName, cancellationToken); return Ok(relationship); @@ -145,7 +157,11 @@ public virtual async Task GetRelationshipAsync(TId id, string rel ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); - if (_getRelationship == null) throw new RequestMethodNotAllowedException(HttpMethod.Get); + if (_getRelationship == null) + { + throw new RequestMethodNotAllowedException(HttpMethod.Get); + } + var rightResources = await _getRelationship.GetRelationshipAsync(id, relationshipName, cancellationToken); return Ok(rightResources); @@ -162,10 +178,14 @@ public virtual async Task PostAsync([FromBody] TResource resource ArgumentGuard.NotNull(resource, nameof(resource)); if (_create == null) + { throw new RequestMethodNotAllowedException(HttpMethod.Post); + } if (!_options.AllowClientGeneratedIds && resource.StringId != null) + { throw new ResourceIdInCreateResourceNotAllowedException(); + } if (_options.ValidateModelState && !ModelState.IsValid) { @@ -202,7 +222,11 @@ public virtual async Task PostRelationshipAsync(TId id, string re ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); ArgumentGuard.NotNull(secondaryResourceIds, nameof(secondaryResourceIds)); - if (_addToRelationship == null) throw new RequestMethodNotAllowedException(HttpMethod.Post); + if (_addToRelationship == null) + { + throw new RequestMethodNotAllowedException(HttpMethod.Post); + } + await _addToRelationship.AddToToManyRelationshipAsync(id, relationshipName, secondaryResourceIds, cancellationToken); return NoContent(); @@ -219,7 +243,10 @@ public virtual async Task PatchAsync(TId id, [FromBody] TResource ArgumentGuard.NotNull(resource, nameof(resource)); - if (_update == null) throw new RequestMethodNotAllowedException(HttpMethod.Patch); + if (_update == null) + { + throw new RequestMethodNotAllowedException(HttpMethod.Patch); + } if (_options.ValidateModelState && !ModelState.IsValid) { @@ -246,7 +273,11 @@ public virtual async Task PatchRelationshipAsync(TId id, string r ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); - if (_setRelationship == null) throw new RequestMethodNotAllowedException(HttpMethod.Patch); + if (_setRelationship == null) + { + throw new RequestMethodNotAllowedException(HttpMethod.Patch); + } + await _setRelationship.SetRelationshipAsync(id, relationshipName, secondaryResourceIds, cancellationToken); return NoContent(); @@ -260,7 +291,11 @@ public virtual async Task DeleteAsync(TId id, CancellationToken c { _traceWriter.LogMethodStart(new {id}); - if (_delete == null) throw new RequestMethodNotAllowedException(HttpMethod.Delete); + if (_delete == null) + { + throw new RequestMethodNotAllowedException(HttpMethod.Delete); + } + await _delete.DeleteAsync(id, cancellationToken); return NoContent(); @@ -281,7 +316,11 @@ public virtual async Task DeleteRelationshipAsync(TId id, string ArgumentGuard.NotNull(relationshipName, nameof(relationshipName)); ArgumentGuard.NotNull(secondaryResourceIds, nameof(secondaryResourceIds)); - if (_removeFromRelationship == null) throw new RequestMethodNotAllowedException(HttpMethod.Delete); + if (_removeFromRelationship == null) + { + throw new RequestMethodNotAllowedException(HttpMethod.Delete); + } + await _removeFromRelationship.RemoveFromToManyRelationshipAsync(id, relationshipName, secondaryResourceIds, cancellationToken); return NoContent(); diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs index 95a16007ca..8cb1f6db2e 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs @@ -62,7 +62,9 @@ private void DiscoverImplementedHooks(Type containerType) { var method = containerType.GetMethod(hook.ToString("G")); if (method.DeclaringType == _boundResourceDefinitionType) + { continue; + } implementedHooks.Add(hook); var attr = method.GetCustomAttributes(true).OfType().SingleOrDefault(); diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs index d555e0d412..7f83b6576e 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs @@ -42,7 +42,10 @@ internal DiffableResourceHashSet(IEnumerable requestResources, /// public IEnumerable> GetDiffs() { - if (!_databaseValuesLoaded) ThrowNoDbValuesError(); + if (!_databaseValuesLoaded) + { + ThrowNoDbValuesError(); + } foreach (var resource in this) { diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs index 486146ff6f..d282bf1ed6 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs @@ -49,7 +49,10 @@ public IResourceHookContainer GetResourceHookContainer(RightType targetResource, container = _genericProcessorFactory.Get(typeof(ResourceHooksDefinition<>), targetResource); _hookContainers[targetResource] = container; } - if (container == null) return null; + if (container == null) + { + return null; + } // if there was a container, first check if it implements the hook we // want to use it for. @@ -66,7 +69,10 @@ public IResourceHookContainer GetResourceHookContainer(RightType targetResource, foreach (ResourceHook targetHook in targetHooks) { - if (ShouldExecuteHook(targetResource, targetHook)) return container; + if (ShouldExecuteHook(targetResource, targetHook)) + { + return container; + } } return null; } @@ -86,7 +92,11 @@ public IEnumerable LoadDbValues(LeftType resourceTypeForRepository, IEnumerable var cast = ((IEnumerable)resources).Cast(); var ids = TypeHelper.CopyToList(cast.Select(i => i.GetTypedId()), idType); var values = (IEnumerable)parameterizedGetWhere.Invoke(this, new object[] { ids, relationshipsToNextLayer }); - if (values == null) return null; + if (values == null) + { + return null; + } + return (IEnumerable)Activator.CreateInstance(typeof(HashSet<>).MakeGenericType(resourceTypeForRepository), TypeHelper.CopyToList(values, resourceTypeForRepository)); } @@ -94,7 +104,11 @@ public HashSet LoadDbValues(IEnumerable resourc { var resourceType = typeof(TResource); var dbValues = LoadDbValues(resourceType, resources, hook, relationships)?.Cast(); - if (dbValues == null) return null; + if (dbValues == null) + { + return null; + } + return new HashSet(dbValues); } @@ -102,9 +116,15 @@ public bool ShouldLoadDbValues(Type resourceType, ResourceHook hook) { var discovery = GetHookDiscovery(resourceType); if (discovery.DatabaseValuesDisabledHooks.Contains(hook)) + { return false; + } + if (discovery.DatabaseValuesEnabledHooks.Contains(hook)) + { return true; + } + return _options.LoadDatabaseValues; } @@ -117,8 +137,10 @@ private bool ShouldExecuteHook(RightType resourceType, ResourceHook hook) private void CheckForTargetHookExistence() { if (!_targetedHooksForRelatedResources.Any()) + { throw new InvalidOperationException("Something is not right in the breadth first traversal of resource hook: " + "trying to get meta information when no allowed hooks are set"); + } } private IHooksDiscovery GetHookDiscovery(Type resourceType) @@ -183,7 +205,10 @@ public Dictionary LoadImplicitlyAffected( var implicitlyAffected = new Dictionary(); foreach (var kvp in leftResourcesByRelation) { - if (IsHasManyThrough(kvp, out var lefts, out var relationship)) continue; + if (IsHasManyThrough(kvp, out var lefts, out var relationship)) + { + continue; + } // note that we don't have to check if BeforeImplicitUpdate hook is implemented. If not, it wont ever get here. var includedLefts = LoadDbValues(relationship.LeftType, lefts, ResourceHook.BeforeImplicitUpdateRelationship, relationship); @@ -194,7 +219,10 @@ public Dictionary LoadImplicitlyAffected( var relationshipValue = relationship.GetValue(ip); if (!(relationshipValue is IEnumerable)) { - if (relationshipValue != null) dbRightResourceList.Add(relationshipValue); + if (relationshipValue != null) + { + dbRightResourceList.Add(relationshipValue); + } } else { @@ -205,7 +233,10 @@ public Dictionary LoadImplicitlyAffected( } var dbRightResourceListCast = dbRightResourceList.Cast().ToList(); - if (existingRightResources != null) dbRightResourceListCast = dbRightResourceListCast.Except(existingRightResources.Cast(), _comparer).ToList(); + if (existingRightResources != null) + { + dbRightResourceListCast = dbRightResourceListCast.Except(existingRightResources.Cast(), _comparer).ToList(); + } if (dbRightResourceListCast.Any()) { diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs index ecd62c521e..c6d1afa3c9 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs @@ -206,12 +206,20 @@ private bool GetHook(ResourceHook target, IEnumerable reso /// private void Traverse(NodeLayer currentLayer, ResourceHook target, Action action) { - if (!currentLayer.AnyResources()) return; + if (!currentLayer.AnyResources()) + { + return; + } + foreach (IResourceNode node in currentLayer) { var resourceType = node.ResourceType; var hookContainer = _executorHelper.GetResourceHookContainer(resourceType, target); - if (hookContainer == null) continue; + if (hookContainer == null) + { + continue; + } + action(hookContainer, node); } @@ -231,11 +239,15 @@ private void RecursiveBeforeRead(List relationshipChain, calledContainers.Add(relationship.RightType); var container = _executorHelper.GetResourceHookContainer(relationship.RightType, ResourceHook.BeforeRead); if (container != null) + { CallHook(container, ResourceHook.BeforeRead, new object[] { pipeline, true, null }); + } } relationshipChain.RemoveAt(0); if (relationshipChain.Any()) + { RecursiveBeforeRead(relationshipChain, pipeline, calledContainers); + } } /// @@ -345,9 +357,17 @@ private Dictionary ReplaceKeysWithInverseRel private void FireForAffectedImplicits(Type resourceTypeToInclude, Dictionary implicitsTarget, ResourcePipeline pipeline, IEnumerable existingImplicitResources = null) { var container = _executorHelper.GetResourceHookContainer(resourceTypeToInclude, ResourceHook.BeforeImplicitUpdateRelationship); - if (container == null) return; + if (container == null) + { + return; + } + var implicitAffected = _executorHelper.LoadImplicitlyAffected(implicitsTarget, existingImplicitResources); - if (!implicitAffected.Any()) return; + if (!implicitAffected.Any()) + { + return; + } + var inverse = implicitAffected.ToDictionary(kvp => _resourceGraph.GetInverseRelationship(kvp.Key), kvp => kvp.Value); var resourcesByRelationship = CreateRelationshipHelper(resourceTypeToInclude, inverse); CallHook(container, ResourceHook.BeforeImplicitUpdateRelationship, new object[] { resourcesByRelationship, pipeline}); @@ -402,7 +422,11 @@ private object ThrowJsonApiExceptionOnError(Func action) /// The relationship helper. private IRelationshipsDictionary CreateRelationshipHelper(RightType resourceType, Dictionary prevLayerRelationships, IEnumerable dbValues = null) { - if (dbValues != null) prevLayerRelationships = ReplaceWithDbValues(prevLayerRelationships, dbValues.Cast()); + if (dbValues != null) + { + prevLayerRelationships = ReplaceWithDbValues(prevLayerRelationships, dbValues.Cast()); + } + return (IRelationshipsDictionary)TypeHelper.CreateInstanceOfOpenType(typeof(RelationshipsDictionary<>), resourceType, true, prevLayerRelationships); } @@ -443,7 +467,11 @@ private IEnumerable LoadDbValues(Type resourceType, IEnumerable uniqueResources, { // We only need to load database values if the target hook of this hook execution // cycle is compatible with displaying database values and has this option enabled. - if (!_executorHelper.ShouldLoadDbValues(resourceType, targetHook)) return null; + if (!_executorHelper.ShouldLoadDbValues(resourceType, targetHook)) + { + return null; + } + return _executorHelper.LoadDbValues(resourceType, uniqueResources, targetHook, relationshipsToNextLayer); } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs index 054d4c155c..e088e7523b 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs @@ -60,12 +60,19 @@ public object GetValue(IIdentifiable resource) } var collection = new List(); var throughResources = (IEnumerable)hasManyThrough.ThroughProperty.GetValue(resource); - if (throughResources == null) return null; + if (throughResources == null) + { + return null; + } foreach (var throughResource in throughResources) { var rightResource = (IIdentifiable)hasManyThrough.RightProperty.GetValue(throughResource); - if (rightResource == null) continue; + if (rightResource == null) + { + continue; + } + collection.Add(rightResource); } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs index bf6a1234c5..ca4d4db7f0 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs @@ -134,13 +134,21 @@ private Dictionary attributes, IReadOnlyCollection relationships) { if (resource == null) + { return new Document(); + } return new Document { Data = ResourceObjectBuilder.Build(resource, attributes, relationships) }; } @@ -54,7 +56,9 @@ protected Document Build(IReadOnlyCollection resources, IReadOnly var data = new List(); foreach (IIdentifiable resource in resources) + { data.Add(ResourceObjectBuilder.Build(resource, attributes, relationships)); + } return new Document { Data = data }; } diff --git a/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs index 6b9856a73a..8749121f6b 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs @@ -61,7 +61,11 @@ public IList Build() // removes relationship entries (s) if they're completely empty. var pruned = resourceObject.Relationships.Where(p => p.Value.IsPopulated || p.Value.Links != null).ToDictionary(p => p.Key, p => p.Value); - if (!pruned.Any()) pruned = null; + if (!pruned.Any()) + { + pruned = null; + } + resourceObject.Relationships = pruned; } resourceObject.Links = _linkBuilder.GetResourceLinks(resourceObject.Type, resourceObject.Id); @@ -108,10 +112,16 @@ public void IncludeRelationshipChain(IReadOnlyCollection private void ProcessChain(object related, List inclusionChain) { if (related is IEnumerable children) + { foreach (IIdentifiable child in children) + { ProcessRelationship(child, inclusionChain); + } + } else + { ProcessRelationship((IIdentifiable)related, inclusionChain); + } } private void ProcessRelationship(IIdentifiable parent, List inclusionChain) @@ -119,7 +129,10 @@ private void ProcessRelationship(IIdentifiable parent, List attr.Property.Name != nameof(Identifiable.Id)).ToArray()).Any()) + { ProcessAttributes(resource, attributes, resourceObject); + } // populating the top-level "relationship" member of a resource object. if (relationships != null) + { ProcessRelationships(resource, relationships, resourceObject); + } return resourceObject; } @@ -129,7 +133,9 @@ private void ProcessRelationships(IIdentifiable resource, IEnumerable()).Add(rel.PublicName, relData); + } } } diff --git a/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs index 239dbdc560..ac61ddf545 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs @@ -78,9 +78,13 @@ protected override RelationshipEntry GetRelationshipData(RelationshipAttribute r { relationshipEntry = base.GetRelationshipData(relationship, resource); if (relationshipChains != null && relationshipEntry.HasResource) + { foreach (var chain in relationshipChains) + { // traverses (recursively) and extracts all (nested) related resources for the current inclusion chain. _includedBuilder.IncludeRelationshipChain(chain, resource); + } + } } if (!IsRelationshipInSparseFieldSet(relationship)) diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs index 6d7703c002..b96cc81700 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs @@ -83,12 +83,16 @@ private IReadOnlyCollection GetAttributesToSerialize(IIdentifiabl { var currentResourceType = resource.GetType(); if (_currentTargetedResource != currentResourceType) + { // We're dealing with a relationship that is being serialized, for which // we never want to include any attributes in the request body. return new List(); + } if (AttributesToSerialize == null) + { return _resourceGraph.GetAttributes(currentResourceType); + } return AttributesToSerialize; } diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs index 46e1073a96..efac073c73 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs @@ -62,11 +62,15 @@ protected override void AfterProcessField(IIdentifiable resource, ResourceFieldA // Client deserializers do not need additional processing for attributes. if (field is AttrAttribute) + { return; + } // if the included property is empty or absent, there is no additional data to be parsed. if (Document.Included == null || Document.Included.Count == 0) + { return; + } if (field is HasOneAttribute hasOneAttr) { diff --git a/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs b/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs index 8bd626cb95..d63f2e0a60 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs @@ -34,7 +34,9 @@ public HttpStatusCode GetErrorStatusCode() .ToArray(); if (statusCodes.Length == 1) + { return (HttpStatusCode)statusCodes[0]; + } var statusCode = int.Parse(statusCodes.Max().ToString()[0] + "00"); return (HttpStatusCode)statusCode; diff --git a/src/JsonApiDotNetCore/Serialization/Objects/ExposableData.cs b/src/JsonApiDotNetCore/Serialization/Objects/ExposableData.cs index aa2b603406..06ba76ba39 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/ExposableData.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/ExposableData.cs @@ -28,7 +28,10 @@ public object Data public bool ShouldSerializeData() { if (GetType() == typeof(RelationshipEntry)) + { return IsPopulated; + } + return true; } @@ -70,7 +73,10 @@ public bool ShouldSerializeData() protected object GetPrimaryData() { if (IsManyData) + { return ManyData; + } + return SingleData; } @@ -81,16 +87,24 @@ protected void SetPrimaryData(object value) { IsPopulated = true; if (value is JObject jObject) + { SingleData = jObject.ToObject(); + } else if (value is TResource ro) + { SingleData = ro; + } else if (value != null) { IsManyData = true; if (value is JArray jArray) + { ManyData = jArray.ToObject>(); + } else + { ManyData = (List)value; + } } } } diff --git a/src/JsonApiDotNetCore/TypeHelper.cs b/src/JsonApiDotNetCore/TypeHelper.cs index 8ffa4e592f..361b6edaef 100644 --- a/src/JsonApiDotNetCore/TypeHelper.cs +++ b/src/JsonApiDotNetCore/TypeHelper.cs @@ -189,10 +189,14 @@ public static object CreateInstanceOfOpenType(Type openType, Type parameter, par public static object CreateInstanceOfOpenType(Type openType, Type parameter, bool hasInternalConstructor, params object[] constructorArguments) { Type[] parameters = {parameter}; - if (!hasInternalConstructor) return CreateInstanceOfOpenType(openType, parameters, constructorArguments); + if (!hasInternalConstructor) + { + return CreateInstanceOfOpenType(openType, parameters, constructorArguments); + } + var parameterizedType = openType.MakeGenericType(parameters); // note that if for whatever reason the constructor of AffectedResource is set from - // internal to public, this will throw an error, as it is looking for a no + // internal to public, this will throw an error, as it is looking for a non-public one. return Activator.CreateInstance(parameterizedType, BindingFlags.NonPublic | BindingFlags.Instance, null, constructorArguments, null); } @@ -259,7 +263,11 @@ public static bool TypeCanContainHashSet(Type collectionType) public static Type GetIdType(Type resourceType) { var property = resourceType.GetProperty(nameof(Identifiable.Id)); - if (property == null) throw new ArgumentException("Type does not have 'Id' property."); + if (property == null) + { + throw new ArgumentException("Type does not have 'Id' property."); + } + return property.PropertyType; } diff --git a/test/UnitTests/ResourceHooks/ResourceHooksTestsSetup.cs b/test/UnitTests/ResourceHooks/ResourceHooksTestsSetup.cs index ef87eb4f4a..ffe2e24497 100644 --- a/test/UnitTests/ResourceHooks/ResourceHooksTestsSetup.cs +++ b/test/UnitTests/ResourceHooks/ResourceHooksTestsSetup.cs @@ -397,7 +397,9 @@ protected List> GetIncludedRelationshipsChains(param var parsedChains = new List>(); foreach (var chain in chains) + { parsedChains.Add(GetIncludedRelationshipsChain(chain)); + } return parsedChains; } diff --git a/test/UnitTests/Serialization/DeserializerTestsSetup.cs b/test/UnitTests/Serialization/DeserializerTestsSetup.cs index 2f8d4a053f..72e880f7f3 100644 --- a/test/UnitTests/Serialization/DeserializerTestsSetup.cs +++ b/test/UnitTests/Serialization/DeserializerTestsSetup.cs @@ -58,7 +58,10 @@ protected RelationshipEntry CreateRelationshipData(string relatedType = null, bo if (isToManyData) { data.Data = new List(); - if (relatedType != null) ((List)data.Data).Add(rio); + if (relatedType != null) + { + ((List)data.Data).Add(rio); + } } else { diff --git a/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs b/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs index 00886e89cd..54249216f7 100644 --- a/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs +++ b/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs @@ -80,7 +80,9 @@ public void BuildIncluded_OverlappingDeeplyNestedCircularChains_CanBuild() var nonOverlappingBlogs = result.Where(ro => ro.Type == "blogs" && ro.Id != sharedBlog.StringId).ToList(); foreach (var blog in nonOverlappingBlogs) + { Assert.Single(blog.Relationships.Keys); + } Assert.Equal(authorSong.StringId, sharedBlogAuthor.FavoriteSong.StringId); Assert.Equal(reviewerFood.StringId, sharedBlogAuthor.FavoriteFood.StringId); diff --git a/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs b/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs index 9749d95ac9..74a642ec02 100644 --- a/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs +++ b/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs @@ -152,7 +152,10 @@ public void SerializeSingle_ResourceWithDeeplyIncludedRelationships_CanSerialize { var chain = new List {r}; if (r.PublicName != "populatedToManies") + { return new List {r}; + } + chain.AddRange(_resourceGraph.GetRelationships()); return chain; }).ToList(); From a0820819d452616814435071b72cea591a9367db Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Mon, 15 Feb 2021 11:43:31 +0100 Subject: [PATCH 03/60] Normalize blank lines around SaveChangesAsync in tests --- ...tomicCreateResourceWithClientGeneratedIdTests.cs | 1 - .../QueryStrings/AtomicQueryStringTests.cs | 1 - .../IdObfuscation/IdObfuscationTests.cs | 3 --- .../ModelStateValidationTests.cs | 3 --- .../QueryStrings/Filtering/FilterDepthTests.cs | 1 - .../QueryStrings/Filtering/FilterTests.cs | 1 - .../QueryStrings/Includes/IncludeTests.cs | 3 --- .../Pagination/PaginationWithTotalCountTests.cs | 3 --- .../QueryStrings/Pagination/RangeValidationTests.cs | 1 - .../QueryStrings/Sorting/SortTests.cs | 3 --- .../CreateResourceWithClientGeneratedIdTests.cs | 1 - .../ResourceDefinitionQueryCallbackTests.cs | 13 ------------- .../ResourceInheritance/InheritanceTests.cs | 6 ------ .../SoftDeletion/SoftDeletionTests.cs | 10 ---------- 14 files changed, 50 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs index 4befbd34db..e8ef9e06de 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs @@ -140,7 +140,6 @@ public async Task Cannot_create_resource_for_existing_client_generated_ID() await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.TextLanguages.Add(languageToCreate); - await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs index f20ec15e37..32c684807b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs @@ -274,7 +274,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.MusicTracks.AddRange(musicTracks); - await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs index 9b5bde276a..27d4fa10fa 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs @@ -30,7 +30,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.BankAccounts.AddRange(bankAccounts); - await dbContext.SaveChangesAsync(); }); @@ -56,7 +55,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.BankAccounts.AddRange(bankAccounts); - await dbContext.SaveChangesAsync(); }); @@ -150,7 +148,6 @@ public async Task Can_include_resource_with_sparse_fieldset() await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.BankAccounts.Add(bankAccount); - await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateValidationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateValidationTests.cs index 50a489f9d9..6920f40574 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateValidationTests.cs @@ -211,7 +211,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.Directories.AddRange(parentDirectory, subdirectory); dbContext.Files.Add(file); - await dbContext.SaveChangesAsync(); }); @@ -602,7 +601,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.Directories.AddRange(directory, otherParent, otherSubdirectory); dbContext.Files.Add(otherFile); - await dbContext.SaveChangesAsync(); }); @@ -853,7 +851,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.Directories.Add(directory); dbContext.Files.Add(otherFile); - await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs index 1d79f68e10..0c9f15bdf3 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs @@ -422,7 +422,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Posts.AddRange(posts); - await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterTests.cs index 4b4d0cd836..041ca5fae1 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterTests.cs @@ -91,7 +91,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Accounts.AddRange(accounts); - await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Includes/IncludeTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Includes/IncludeTests.cs index 7d798f5c5d..d520dff2ce 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Includes/IncludeTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Includes/IncludeTests.cs @@ -37,7 +37,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Posts.Add(post); - await dbContext.SaveChangesAsync(); }); @@ -101,7 +100,6 @@ public async Task Can_include_in_secondary_resource() await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.Blogs.Add(blog); - await dbContext.SaveChangesAsync(); }); @@ -537,7 +535,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Posts.AddRange(posts); - await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs index 0e5a7c98ac..113cfdba47 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs @@ -45,7 +45,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Posts.AddRange(posts); - await dbContext.SaveChangesAsync(); }); @@ -340,7 +339,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Posts.Add(post); - await dbContext.SaveChangesAsync(); }); @@ -536,7 +534,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Posts.AddRange(posts); - await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs index a6cb5e6cc6..ca5afde779 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs @@ -89,7 +89,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Blogs.AddRange(blogs); - await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs index 25b26b798b..36f4a1f9bf 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs @@ -35,7 +35,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Posts.AddRange(posts); - await dbContext.SaveChangesAsync(); }); @@ -193,7 +192,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Posts.AddRange(posts); - await dbContext.SaveChangesAsync(); }); @@ -574,7 +572,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Accounts.AddRange(accounts); - await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs index a82338667a..e6ef1f914f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs @@ -214,7 +214,6 @@ public async Task Cannot_create_resource_for_existing_client_generated_ID() await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.RgbColors.Add(existingColor); - await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs index 5c54c0e658..1841175d32 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs @@ -48,7 +48,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.CallableResources.Add(resource); - await dbContext.SaveChangesAsync(); }); @@ -97,7 +96,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); - await dbContext.SaveChangesAsync(); }); @@ -148,7 +146,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); - await dbContext.SaveChangesAsync(); }); @@ -196,7 +193,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); - await dbContext.SaveChangesAsync(); }); @@ -244,7 +240,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); - await dbContext.SaveChangesAsync(); }); @@ -277,7 +272,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); - await dbContext.SaveChangesAsync(); }); @@ -305,7 +299,6 @@ public async Task Attribute_inclusion_from_resource_definition_is_applied_for_em await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.CallableResources.Add(resource); - await dbContext.SaveChangesAsync(); }); @@ -336,7 +329,6 @@ public async Task Attribute_inclusion_from_resource_definition_is_applied_for_no await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.CallableResources.Add(resource); - await dbContext.SaveChangesAsync(); }); @@ -369,7 +361,6 @@ public async Task Attribute_exclusion_from_resource_definition_is_applied_for_em await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.CallableResources.Add(resource); - await dbContext.SaveChangesAsync(); }); @@ -400,7 +391,6 @@ public async Task Attribute_exclusion_from_resource_definition_is_applied_for_no await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.CallableResources.Add(resource); - await dbContext.SaveChangesAsync(); }); @@ -451,7 +441,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); - await dbContext.SaveChangesAsync(); }); @@ -500,7 +489,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.CallableResources.AddRange(resources); - await dbContext.SaveChangesAsync(); }); @@ -539,7 +527,6 @@ public async Task Queryable_parameter_handler_from_resource_definition_is_not_ap await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.CallableResources.Add(resource); - await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs index 602600b2b4..a844ddec8e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs @@ -82,7 +82,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.CompanyHealthInsurances.Add(existingInsurance); - await dbContext.SaveChangesAsync(); }); @@ -198,7 +197,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTablesAsync(); dbContext.AddRange(existingMan, existingInsurance); - await dbContext.SaveChangesAsync(); }); @@ -243,7 +241,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTablesAsync(); dbContext.Humans.AddRange(existingFather, existingMother); - await dbContext.SaveChangesAsync(); }); @@ -309,7 +306,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTablesAsync(); dbContext.Humans.AddRange(existingChild, existingFather, existingMother); - await dbContext.SaveChangesAsync(); }); @@ -363,7 +359,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTablesAsync(); dbContext.ContentItems.AddRange(existingBook, existingVideo); - await dbContext.SaveChangesAsync(); }); @@ -430,7 +425,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTablesAsync(); dbContext.AddRange(existingBook, existingVideo, existingMan); - await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs index 2dcd98ea40..60c810531a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs @@ -48,7 +48,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Departments.AddRange(departments); - await dbContext.SaveChangesAsync(); }); @@ -89,7 +88,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Departments.AddRange(departments); - await dbContext.SaveChangesAsync(); }); @@ -118,7 +116,6 @@ public async Task Cannot_get_deleted_primary_resource_by_ID() await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.Departments.Add(department); - await dbContext.SaveChangesAsync(); }); @@ -160,7 +157,6 @@ public async Task Can_get_secondary_resources() await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.Companies.Add(company); - await dbContext.SaveChangesAsync(); }); @@ -195,7 +191,6 @@ public async Task Cannot_get_secondary_resources_for_deleted_parent() await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.Companies.Add(company); - await dbContext.SaveChangesAsync(); }); @@ -254,7 +249,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); dbContext.Companies.AddRange(companies); - await dbContext.SaveChangesAsync(); }); @@ -298,7 +292,6 @@ public async Task Can_get_relationship() await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.Companies.Add(company); - await dbContext.SaveChangesAsync(); }); @@ -333,7 +326,6 @@ public async Task Cannot_get_relationship_for_deleted_parent() await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.Companies.Add(company); - await dbContext.SaveChangesAsync(); }); @@ -364,7 +356,6 @@ public async Task Cannot_update_deleted_resource() await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.Companies.Add(company); - await dbContext.SaveChangesAsync(); }); @@ -415,7 +406,6 @@ public async Task Cannot_update_relationship_for_deleted_parent() await _testContext.RunOnDatabaseAsync(async dbContext => { dbContext.Companies.Add(company); - await dbContext.SaveChangesAsync(); }); From c87a9969e7c9b6139460b7c7cf1c5086310de54e Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Mon, 15 Feb 2021 12:13:39 +0100 Subject: [PATCH 04/60] use const --- .../Services/WorkItemService.cs | 3 +- ...micConstrainedOperationsControllerTests.cs | 8 +-- .../Creating/AtomicCreateResourceTests.cs | 32 +++++----- ...reateResourceWithClientGeneratedIdTests.cs | 10 +-- ...eateResourceWithToManyRelationshipTests.cs | 20 +++--- ...reateResourceWithToOneRelationshipTests.cs | 20 +++--- .../Deleting/AtomicDeleteResourceTests.cs | 28 ++++----- .../Links/AtomicAbsoluteLinksTests.cs | 2 +- .../AtomicRelativeLinksWithNamespaceTests.cs | 2 +- .../LocalIds/AtomicLocalIdTests.cs | 56 ++++++++--------- .../Meta/AtomicResourceMetaTests.cs | 4 +- .../Meta/AtomicResponseMetaTests.cs | 4 +- .../Mixed/AtomicRequestBodyTests.cs | 10 +-- .../Mixed/MaximumOperationsPerRequestTests.cs | 6 +- .../AtomicModelStateValidationTests.cs | 16 ++--- .../QueryStrings/AtomicQueryStringTests.cs | 20 +++--- ...icSparseFieldSetResourceDefinitionTests.cs | 4 +- .../Transactions/AtomicRollbackTests.cs | 2 +- .../AtomicTransactionConsistencyTests.cs | 6 +- .../AtomicAddToToManyRelationshipTests.cs | 38 ++++++------ ...AtomicRemoveFromToManyRelationshipTests.cs | 36 +++++------ .../AtomicReplaceToManyRelationshipTests.cs | 40 ++++++------ .../AtomicUpdateToOneRelationshipTests.cs | 50 +++++++-------- .../AtomicReplaceToManyRelationshipTests.cs | 22 +++---- .../Resources/AtomicUpdateResourceTests.cs | 62 +++++++++---------- .../AtomicUpdateToOneRelationshipTests.cs | 32 +++++----- .../CompositeKeys/CompositeKeyTests.cs | 8 +-- .../ContentNegotiation/AcceptHeaderTests.cs | 22 +++---- .../ContentTypeHeaderTests.cs | 40 ++++++------ .../ApiControllerAttributeTests.cs | 2 +- .../CustomRoutes/CustomRouteTests.cs | 2 +- .../EagerLoading/EagerLoadingTests.cs | 2 +- .../IdObfuscation/IdObfuscationTests.cs | 6 +- .../Links/AbsoluteLinksWithNamespaceTests.cs | 4 +- .../AbsoluteLinksWithoutNamespaceTests.cs | 4 +- .../Links/RelativeLinksWithNamespaceTests.cs | 4 +- .../RelativeLinksWithoutNamespaceTests.cs | 4 +- .../IntegrationTests/Logging/LoggingTests.cs | 8 +-- .../Meta/ResourceMetaTests.cs | 2 +- .../Meta/ResponseMetaTests.cs | 2 +- .../Meta/TopLevelCountTests.cs | 6 +- .../ModelStateValidationTests.cs | 14 ++--- .../NoModelStateValidationTests.cs | 2 +- .../NamingConventions/KebabCasingTests.cs | 8 +-- .../Filtering/FilterDataTypeTests.cs | 2 +- .../Filtering/FilterDepthTests.cs | 26 ++++---- .../Filtering/FilterOperatorTests.cs | 16 ++--- .../QueryStrings/Filtering/FilterTests.cs | 6 +- .../QueryStrings/Includes/IncludeTests.cs | 14 ++--- .../PaginationWithTotalCountTests.cs | 16 ++--- .../PaginationWithoutTotalCountTests.cs | 10 +-- .../Pagination/RangeValidationTests.cs | 14 ++--- .../RangeValidationWithMaximumTests.cs | 2 +- .../QueryStrings/QueryStringTests.cs | 4 +- .../SerializerDefaultValueHandlingTests.cs | 2 +- .../SerializerNullValueHandlingTests.cs | 2 +- .../QueryStrings/Sorting/SortTests.cs | 28 ++++----- .../SparseFieldSets/SparseFieldSetTests.cs | 10 +-- .../ReadWrite/Creating/CreateResourceTests.cs | 39 ++++++------ ...reateResourceWithClientGeneratedIdTests.cs | 10 +-- ...eateResourceWithToManyRelationshipTests.cs | 26 ++++---- ...reateResourceWithToOneRelationshipTests.cs | 26 ++++---- .../ReadWrite/Deleting/DeleteResourceTests.cs | 2 +- .../Fetching/FetchRelationshipTests.cs | 4 +- .../ReadWrite/Fetching/FetchResourceTests.cs | 12 ++-- .../AddToToManyRelationshipTests.cs | 2 +- .../RemoveFromToManyRelationshipTests.cs | 2 +- .../ReplaceToManyRelationshipTests.cs | 2 +- .../UpdateToOneRelationshipTests.cs | 2 +- .../Updating/Resources/UpdateResourceTests.cs | 4 +- .../DefaultBehaviorTests.cs | 4 +- .../ResourceInjectionTests.cs | 4 +- .../ResourceDefinitionQueryCallbackTests.cs | 16 ++--- .../ResourceHooks/ResourceHookTests.cs | 22 +++---- .../ResourceInheritance/InheritanceTests.cs | 10 +-- .../DisableQueryStringTests.cs | 6 +- .../HttpReadOnlyTests.cs | 4 +- .../NoHttpDeleteTests.cs | 4 +- .../RestrictedControllers/NoHttpPatchTests.cs | 4 +- .../RestrictedControllers/NoHttpPostTests.cs | 4 +- .../Serialization/SerializationTests.cs | 4 +- .../SoftDeletion/SoftDeletionTests.cs | 6 +- .../ZeroKeys/EmptyGuidAsKeyTests.cs | 10 +-- .../ZeroKeys/ZeroAsKeyTests.cs | 10 +-- test/MultiDbContextTests/ResourceTests.cs | 4 +- test/NoEntityFrameworkTests/WorkItemTests.cs | 4 +- test/UnitTests/Internal/TypeHelper_Tests.cs | 8 +-- .../Middleware/JsonApiMiddlewareTests.cs | 6 +- .../UnitTests/Models/RelationshipDataTests.cs | 4 +- .../Client/RequestSerializerTests.cs | 24 +++---- .../Client/ResponseDeserializerTests.cs | 24 +++---- .../Server/ResponseSerializerTests.cs | 18 +++--- 92 files changed, 574 insertions(+), 582 deletions(-) diff --git a/src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs b/src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs index 363db95d4b..edb7d5c0ba 100644 --- a/src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs +++ b/src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs @@ -51,8 +51,7 @@ public async Task CreateAsync(WorkItem resource, CancellationToken can { return (await QueryAsync(async connection => { - var query = - @"insert into ""WorkItems"" (""Title"", ""IsBlocked"", ""DurationInHours"", ""ProjectId"") values " + + const string query = @"insert into ""WorkItems"" (""Title"", ""IsBlocked"", ""DurationInHours"", ""ProjectId"") values " + @"(@title, @isBlocked, @durationInHours, @projectId) returning ""Id"", ""Title"", ""IsBlocked"", ""DurationInHours"", ""ProjectId"""; return await connection.QueryAsync(new CommandDefinition(query, new diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Controllers/AtomicConstrainedOperationsControllerTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Controllers/AtomicConstrainedOperationsControllerTests.cs index 90884f55a3..982aa850aa 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Controllers/AtomicConstrainedOperationsControllerTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Controllers/AtomicConstrainedOperationsControllerTests.cs @@ -59,7 +59,7 @@ public async Task Can_create_resources_for_matching_resource_type() } }; - var route = "/operations/musicTracks/create"; + const string route = "/operations/musicTracks/create"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -92,7 +92,7 @@ public async Task Cannot_create_resource_for_mismatching_resource_type() } }; - var route = "/operations/musicTracks/create"; + const string route = "/operations/musicTracks/create"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -138,7 +138,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations/musicTracks/create"; + const string route = "/operations/musicTracks/create"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -191,7 +191,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations/musicTracks/create"; + const string route = "/operations/musicTracks/create"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs index c073964d81..5cbd5d116a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs @@ -53,7 +53,7 @@ public async Task Can_create_resource() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -113,7 +113,7 @@ public async Task Can_create_resources() atomic__operations = operationElements }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -181,7 +181,7 @@ public async Task Can_create_resource_without_attributes_or_relationships() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -234,7 +234,7 @@ public async Task Can_create_resource_with_unknown_attribute() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -289,7 +289,7 @@ public async Task Can_create_resource_with_unknown_relationship() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -340,7 +340,7 @@ public async Task Cannot_create_resource_with_client_generated_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -371,7 +371,7 @@ public async Task Cannot_create_resource_for_href_element() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -405,7 +405,7 @@ public async Task Cannot_create_resource_for_ref_element() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -435,7 +435,7 @@ public async Task Cannot_create_resource_for_missing_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -471,7 +471,7 @@ public async Task Cannot_create_resource_for_missing_type() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -505,7 +505,7 @@ public async Task Cannot_create_resource_for_unknown_type() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -548,7 +548,7 @@ public async Task Cannot_create_resource_for_array() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -586,7 +586,7 @@ public async Task Cannot_create_resource_attribute_with_blocked_capability() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -627,7 +627,7 @@ public async Task Cannot_create_resource_with_readonly_attribute() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -665,7 +665,7 @@ public async Task Cannot_create_resource_with_incompatible_attribute_value() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -745,7 +745,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs index e8ef9e06de..215f85515e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs @@ -55,7 +55,7 @@ public async Task Can_create_resource_with_client_generated_guid_ID_having_side_ } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -107,7 +107,7 @@ public async Task Can_create_resource_with_client_generated_string_ID_having_no_ } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -163,7 +163,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -203,7 +203,7 @@ public async Task Cannot_create_resource_for_incompatible_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -239,7 +239,7 @@ public async Task Cannot_create_resource_for_ID_and_local_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs index 4c87dfa89f..3af0e39b70 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs @@ -74,7 +74,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -158,7 +158,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -220,7 +220,7 @@ public async Task Cannot_create_for_missing_relationship_type() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -268,7 +268,7 @@ public async Task Cannot_create_for_unknown_relationship_type() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -315,7 +315,7 @@ public async Task Cannot_create_for_missing_relationship_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -374,7 +374,7 @@ public async Task Cannot_create_for_unknown_relationship_IDs() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -428,7 +428,7 @@ public async Task Cannot_create_on_relationship_type_mismatch() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -494,7 +494,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -547,7 +547,7 @@ public async Task Cannot_create_with_null_data_in_HasMany_relationship() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -588,7 +588,7 @@ public async Task Cannot_create_with_null_data_in_HasManyThrough_relationship() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs index d5603ec35a..0784f43771 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs @@ -64,7 +64,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -134,7 +134,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -209,7 +209,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => atomic__operations = operationElements }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -279,7 +279,7 @@ public async Task Cannot_create_for_missing_relationship_type() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -324,7 +324,7 @@ public async Task Cannot_create_for_unknown_relationship_type() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -368,7 +368,7 @@ public async Task Cannot_create_for_missing_relationship_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -413,7 +413,7 @@ public async Task Cannot_create_with_unknown_relationship_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -458,7 +458,7 @@ public async Task Cannot_create_on_relationship_type_mismatch() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -526,7 +526,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var requestBodyText = JsonConvert.SerializeObject(requestBody).Replace("ownedBy_duplicate", "ownedBy"); - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBodyText); @@ -586,7 +586,7 @@ public async Task Cannot_create_with_data_array_in_relationship() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs index 67716414a5..04fda0794a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs @@ -53,7 +53,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -106,7 +106,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => atomic__operations = operationElements }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -154,7 +154,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -207,7 +207,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -260,7 +260,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -316,7 +316,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -356,7 +356,7 @@ public async Task Cannot_delete_resource_for_href_element() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -386,7 +386,7 @@ public async Task Cannot_delete_resource_for_missing_ref_element() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -420,7 +420,7 @@ public async Task Cannot_delete_resource_for_missing_type() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -455,7 +455,7 @@ public async Task Cannot_delete_resource_for_unknown_type() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -489,7 +489,7 @@ public async Task Cannot_delete_resource_for_missing_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -524,7 +524,7 @@ public async Task Cannot_delete_resource_for_unknown_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -561,7 +561,7 @@ public async Task Cannot_delete_resource_for_incompatible_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -597,7 +597,7 @@ public async Task Cannot_delete_resource_for_ID_and_local_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicAbsoluteLinksTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicAbsoluteLinksTests.cs index 21f91eca53..6ca814b583 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicAbsoluteLinksTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicAbsoluteLinksTests.cs @@ -72,7 +72,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicRelativeLinksWithNamespaceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicRelativeLinksWithNamespaceTests.cs index cb3585d95f..c3c864891b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicRelativeLinksWithNamespaceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicRelativeLinksWithNamespaceTests.cs @@ -61,7 +61,7 @@ public async Task Create_resource_with_side_effects_returns_relative_links() } }; - var route = "/api/operations"; + const string route = "/api/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs index 63cc817103..cfc8e7ecaf 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs @@ -76,7 +76,7 @@ public async Task Can_create_resource_with_ToOne_relationship_using_local_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -171,7 +171,7 @@ public async Task Can_create_resource_with_OneToMany_relationship_using_local_ID } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -265,7 +265,7 @@ public async Task Can_create_resource_with_ManyToMany_relationship_using_local_I } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -345,7 +345,7 @@ public async Task Cannot_consume_local_ID_that_is_assigned_in_same_operation() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -409,7 +409,7 @@ public async Task Cannot_reassign_local_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -466,7 +466,7 @@ public async Task Can_update_resource_using_local_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -585,7 +585,7 @@ public async Task Can_update_resource_with_relationships_using_local_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -692,7 +692,7 @@ public async Task Can_create_ToOne_relationship_using_local_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -792,7 +792,7 @@ public async Task Can_create_OneToMany_relationship_using_local_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -892,7 +892,7 @@ public async Task Can_create_ManyToMany_relationship_using_local_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1015,7 +1015,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1137,7 +1137,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1260,7 +1260,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1404,7 +1404,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1560,7 +1560,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1704,7 +1704,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1774,7 +1774,7 @@ public async Task Can_delete_resource_using_local_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1831,7 +1831,7 @@ public async Task Cannot_consume_unassigned_local_ID_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1878,7 +1878,7 @@ public async Task Cannot_consume_unassigned_local_ID_in_data_element() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1939,7 +1939,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1993,7 +1993,7 @@ public async Task Cannot_consume_unassigned_local_ID_in_relationship_data_elemen } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -2050,7 +2050,7 @@ public async Task Cannot_consume_unassigned_local_ID_in_relationship_data_array( } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -2107,7 +2107,7 @@ public async Task Cannot_consume_local_ID_of_different_type_in_same_operation() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -2162,7 +2162,7 @@ public async Task Cannot_consume_local_ID_of_different_type_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -2220,7 +2220,7 @@ public async Task Cannot_consume_local_ID_of_different_type_in_data_element() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -2292,7 +2292,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -2363,7 +2363,7 @@ public async Task Cannot_consume_local_ID_of_different_type_in_relationship_data } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -2431,7 +2431,7 @@ public async Task Cannot_consume_local_ID_of_different_type_in_relationship_data } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResourceMetaTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResourceMetaTests.cs index b366560d13..1541c31151 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResourceMetaTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResourceMetaTests.cs @@ -71,7 +71,7 @@ public async Task Returns_resource_meta_in_create_resource_with_side_effects() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -119,7 +119,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResponseMetaTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResponseMetaTests.cs index 4fa740e292..1ecdfd8602 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResponseMetaTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResponseMetaTests.cs @@ -53,7 +53,7 @@ public async Task Returns_top_level_meta_in_create_resource_with_side_effects() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -105,7 +105,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs index 05d4196a47..dc3a70e818 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs @@ -25,7 +25,7 @@ public AtomicRequestBodyTests(ExampleIntegrationTestContext(route, null); @@ -53,9 +53,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Cannot_process_for_broken_JSON_request_body() { // Arrange - var requestBody = "{\"atomic__operations\":[{\"op\":"; + const string requestBody = "{\"atomic__operations\":[{\"op\":"; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -81,7 +81,7 @@ public async Task Cannot_process_empty_operations_array() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -127,7 +127,7 @@ public async Task Cannot_process_for_unknown_operation_code() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/MaximumOperationsPerRequestTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/MaximumOperationsPerRequestTests.cs index 931af9e668..2615bb1e89 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/MaximumOperationsPerRequestTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/MaximumOperationsPerRequestTests.cs @@ -58,7 +58,7 @@ public async Task Cannot_process_more_operations_than_maximum() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -109,7 +109,7 @@ public async Task Can_process_operations_same_as_maximum() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, _) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -148,7 +148,7 @@ public async Task Can_process_high_number_of_operations_when_unconstrained() atomic__operations = operationElements }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, _) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs index ef7c2d5a14..2b286ab55c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs @@ -45,7 +45,7 @@ public async Task Cannot_create_resource_with_multiple_violations() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -112,7 +112,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -169,7 +169,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -223,7 +223,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -286,7 +286,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -343,7 +343,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -402,7 +402,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -460,7 +460,7 @@ public async Task Validates_all_operations_before_execution_starts() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs index 32c684807b..bd791c54b8 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs @@ -61,7 +61,7 @@ public async Task Cannot_include_on_operations_endpoint() } }; - var route = "/operations?include=recordCompanies"; + const string route = "/operations?include=recordCompanies"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -98,7 +98,7 @@ public async Task Cannot_filter_on_operations_endpoint() } }; - var route = "/operations?filter=equals(id,'1')"; + const string route = "/operations?filter=equals(id,'1')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -135,7 +135,7 @@ public async Task Cannot_sort_on_operations_endpoint() } }; - var route = "/operations?sort=-id"; + const string route = "/operations?sort=-id"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -172,7 +172,7 @@ public async Task Cannot_use_pagination_number_on_operations_endpoint() } }; - var route = "/operations?page[number]=1"; + const string route = "/operations?page[number]=1"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -209,7 +209,7 @@ public async Task Cannot_use_pagination_size_on_operations_endpoint() } }; - var route = "/operations?page[size]=1"; + const string route = "/operations?page[size]=1"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -246,7 +246,7 @@ public async Task Cannot_use_sparse_fieldset_on_operations_endpoint() } }; - var route = "/operations?fields[recordCompanies]=id"; + const string route = "/operations?fields[recordCompanies]=id"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -277,7 +277,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/musicTracks?isRecentlyReleased=true"; + const string route = "/musicTracks?isRecentlyReleased=true"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -314,7 +314,7 @@ public async Task Cannot_use_Queryable_handler_on_operations_endpoint() } }; - var route = "/operations?isRecentlyReleased=true"; + const string route = "/operations?isRecentlyReleased=true"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -356,7 +356,7 @@ public async Task Can_use_defaults_on_operations_endpoint() } }; - var route = "/operations?defaults=false"; + const string route = "/operations?defaults=false"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -399,7 +399,7 @@ public async Task Can_use_nulls_on_operations_endpoint() } }; - var route = "/operations?nulls=false"; + const string route = "/operations?nulls=false"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ResourceDefinitions/AtomicSparseFieldSetResourceDefinitionTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ResourceDefinitions/AtomicSparseFieldSetResourceDefinitionTests.cs index 653ff88a31..01ce190904 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ResourceDefinitions/AtomicSparseFieldSetResourceDefinitionTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ResourceDefinitions/AtomicSparseFieldSetResourceDefinitionTests.cs @@ -73,7 +73,7 @@ public async Task Hides_text_in_create_resource_with_side_effects() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -139,7 +139,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs index 60f6818305..ede29b7907 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs @@ -81,7 +81,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicTransactionConsistencyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicTransactionConsistencyTests.cs index 6097ca1ccd..55b78ec6b2 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicTransactionConsistencyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicTransactionConsistencyTests.cs @@ -58,7 +58,7 @@ public async Task Cannot_use_non_transactional_repository() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -95,7 +95,7 @@ public async Task Cannot_use_transactional_repository_without_active_transaction } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -132,7 +132,7 @@ public async Task Cannot_use_distributed_transaction() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs index 303632937e..e3829573e3 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs @@ -59,7 +59,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -132,7 +132,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -220,7 +220,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -260,7 +260,7 @@ public async Task Cannot_add_for_href_element() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -295,7 +295,7 @@ public async Task Cannot_add_for_missing_type_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -331,7 +331,7 @@ public async Task Cannot_add_for_unknown_type_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -366,7 +366,7 @@ public async Task Cannot_add_for_missing_ID_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -418,7 +418,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -455,7 +455,7 @@ public async Task Cannot_add_for_ID_and_local_ID_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -490,7 +490,7 @@ public async Task Cannot_add_for_missing_relationship_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -526,7 +526,7 @@ public async Task Cannot_add_for_unknown_relationship_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -571,7 +571,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -614,7 +614,7 @@ public async Task Cannot_add_for_missing_type_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -658,7 +658,7 @@ public async Task Cannot_add_for_unknown_type_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -701,7 +701,7 @@ public async Task Cannot_add_for_missing_ID_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -746,7 +746,7 @@ public async Task Cannot_add_for_ID_and_local_ID_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -804,7 +804,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -862,7 +862,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -908,7 +908,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs index c7e77fa4e3..1f87b3ff9f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs @@ -59,7 +59,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -130,7 +130,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -225,7 +225,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -266,7 +266,7 @@ public async Task Cannot_remove_for_href_element() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -301,7 +301,7 @@ public async Task Cannot_remove_for_missing_type_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -337,7 +337,7 @@ public async Task Cannot_remove_for_unknown_type_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -372,7 +372,7 @@ public async Task Cannot_remove_for_missing_ID_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -424,7 +424,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -461,7 +461,7 @@ public async Task Cannot_remove_for_ID_and_local_ID_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -497,7 +497,7 @@ public async Task Cannot_remove_for_unknown_relationship_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -542,7 +542,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -585,7 +585,7 @@ public async Task Cannot_remove_for_missing_type_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -629,7 +629,7 @@ public async Task Cannot_remove_for_unknown_type_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -672,7 +672,7 @@ public async Task Cannot_remove_for_missing_ID_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -717,7 +717,7 @@ public async Task Cannot_remove_for_ID_and_local_ID_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -775,7 +775,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -833,7 +833,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -880,7 +880,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs index bb87d19f2c..c2a6c4bb5b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs @@ -56,7 +56,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -121,7 +121,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -192,7 +192,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -270,7 +270,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -312,7 +312,7 @@ public async Task Cannot_replace_for_href_element() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -347,7 +347,7 @@ public async Task Cannot_replace_for_missing_type_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -383,7 +383,7 @@ public async Task Cannot_replace_for_unknown_type_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -418,7 +418,7 @@ public async Task Cannot_replace_for_missing_ID_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -470,7 +470,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -524,7 +524,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -561,7 +561,7 @@ public async Task Cannot_replace_for_ID_and_local_ID_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -597,7 +597,7 @@ public async Task Cannot_replace_for_unknown_relationship_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -642,7 +642,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -685,7 +685,7 @@ public async Task Cannot_replace_for_missing_type_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -729,7 +729,7 @@ public async Task Cannot_replace_for_unknown_type_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -772,7 +772,7 @@ public async Task Cannot_replace_for_missing_ID_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -817,7 +817,7 @@ public async Task Cannot_replace_for_ID_and_local_ID_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -875,7 +875,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -933,7 +933,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -985,7 +985,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs index 2cae0afafa..f9efe3177a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs @@ -55,7 +55,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -110,7 +110,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -165,7 +165,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -223,7 +223,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -278,7 +278,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -333,7 +333,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -391,7 +391,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -452,7 +452,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -513,7 +513,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -552,7 +552,7 @@ public async Task Cannot_create_for_href_element() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -587,7 +587,7 @@ public async Task Cannot_create_for_missing_type_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -623,7 +623,7 @@ public async Task Cannot_create_for_unknown_type_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -658,7 +658,7 @@ public async Task Cannot_create_for_missing_ID_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -709,7 +709,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -758,7 +758,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -795,7 +795,7 @@ public async Task Cannot_create_for_ID_and_local_ID_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -831,7 +831,7 @@ public async Task Cannot_create_for_unknown_relationship_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -883,7 +883,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -923,7 +923,7 @@ public async Task Cannot_create_for_missing_type_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -964,7 +964,7 @@ public async Task Cannot_create_for_unknown_type_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1004,7 +1004,7 @@ public async Task Cannot_create_for_missing_ID_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1046,7 +1046,7 @@ public async Task Cannot_create_for_ID_and_local_ID_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1095,7 +1095,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1144,7 +1144,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1193,7 +1193,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs index e8bdb8db3a..44c4a5a7ca 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs @@ -61,7 +61,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -131,7 +131,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -207,7 +207,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -290,7 +290,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -351,7 +351,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -399,7 +399,7 @@ public async Task Cannot_replace_for_missing_type_in_relationship_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -448,7 +448,7 @@ public async Task Cannot_replace_for_unknown_type_in_relationship_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -496,7 +496,7 @@ public async Task Cannot_replace_for_missing_ID_in_relationship_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -546,7 +546,7 @@ public async Task Cannot_replace_for_ID_and_local_ID_relationship_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -609,7 +609,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -672,7 +672,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs index 3529dd3e66..526edc8c86 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs @@ -65,7 +65,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => atomic__operations = operationElements }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -127,7 +127,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -185,7 +185,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -243,7 +243,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -289,7 +289,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -356,7 +356,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -415,7 +415,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -468,7 +468,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -498,7 +498,7 @@ public async Task Cannot_update_resource_for_href_element() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -551,7 +551,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -601,7 +601,7 @@ public async Task Cannot_update_resource_for_missing_type_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -646,7 +646,7 @@ public async Task Cannot_update_resource_for_missing_ID_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -693,7 +693,7 @@ public async Task Cannot_update_resource_for_ID_and_local_ID_in_ref() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -723,7 +723,7 @@ public async Task Cannot_update_resource_for_missing_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -763,7 +763,7 @@ public async Task Cannot_update_resource_for_missing_type_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -803,7 +803,7 @@ public async Task Cannot_update_resource_for_missing_ID_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -845,7 +845,7 @@ public async Task Cannot_update_resource_for_ID_and_local_ID_in_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -895,7 +895,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -941,7 +941,7 @@ public async Task Cannot_update_on_resource_type_mismatch_between_ref_and_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -987,7 +987,7 @@ public async Task Cannot_update_on_resource_ID_mismatch_between_ref_and_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1033,7 +1033,7 @@ public async Task Cannot_update_on_resource_local_ID_mismatch_between_ref_and_da } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1079,7 +1079,7 @@ public async Task Cannot_update_on_mixture_of_ID_and_local_ID_between_ref_and_da } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1125,7 +1125,7 @@ public async Task Cannot_update_on_mixture_of_local_ID_and_ID_between_ref_and_da } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1166,7 +1166,7 @@ public async Task Cannot_update_resource_for_unknown_type() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1207,7 +1207,7 @@ public async Task Cannot_update_resource_for_unknown_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1252,7 +1252,7 @@ public async Task Cannot_update_resource_for_incompatible_ID() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1299,7 +1299,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1346,7 +1346,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1393,7 +1393,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1440,7 +1440,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -1526,7 +1526,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs index 708ad40fbf..03fb1e26fb 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs @@ -60,7 +60,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -120,7 +120,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -180,7 +180,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -243,7 +243,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -303,7 +303,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -363,7 +363,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -426,7 +426,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -492,7 +492,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -558,7 +558,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -623,7 +623,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -668,7 +668,7 @@ public async Task Cannot_create_for_missing_type_in_relationship_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -714,7 +714,7 @@ public async Task Cannot_create_for_unknown_type_in_relationship_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -759,7 +759,7 @@ public async Task Cannot_create_for_missing_ID_in_relationship_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -806,7 +806,7 @@ public async Task Cannot_create_for_ID_and_local_ID_in_relationship_data() } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -860,7 +860,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -914,7 +914,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAtomicAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeKeyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeKeyTests.cs index ac382e46ae..6f9de732a1 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeKeyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeKeyTests.cs @@ -48,7 +48,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/cars?filter=any(id,'123:AA-BB-11','999:XX-YY-22')"; + const string route = "/cars?filter=any(id,'123:AA-BB-11','999:XX-YY-22')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -106,7 +106,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/cars?sort=id"; + const string route = "/cars?sort=id"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -135,7 +135,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/cars?fields[cars]=id"; + const string route = "/cars?fields[cars]=id"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -169,7 +169,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/cars"; + const string route = "/cars"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/AcceptHeaderTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/AcceptHeaderTests.cs index f1f9cbbb89..f76eaff0cc 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/AcceptHeaderTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/AcceptHeaderTests.cs @@ -26,7 +26,7 @@ public AcceptHeaderTests(ExampleIntegrationTestContext(route); @@ -58,7 +58,7 @@ public async Task Returns_JsonApi_ContentType_header_with_AtomicOperations_exten } }; - var route = "/operations"; + const string route = "/operations"; // Act var (httpResponse, _) = await _testContext.ExecutePostAtomicAsync(route, requestBody); @@ -84,8 +84,8 @@ public async Task Denies_unknown_ContentType_header() } }; - var route = "/policies"; - var contentType = "text/html"; + const string route = "/policies"; + const string contentType = "text/html"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody, contentType); @@ -115,8 +115,8 @@ public async Task Permits_JsonApi_ContentType_header() } }; - var route = "/policies"; - var contentType = HeaderConstants.MediaType; + const string route = "/policies"; + const string contentType = HeaderConstants.MediaType; // Act var (httpResponse, _) = await _testContext.ExecutePostAsync(route, requestBody, contentType); @@ -148,8 +148,8 @@ public async Task Permits_JsonApi_ContentType_header_with_AtomicOperations_exten } }; - var route = "/operations"; - var contentType = HeaderConstants.AtomicOperationsMediaType; + const string route = "/operations"; + const string contentType = HeaderConstants.AtomicOperationsMediaType; // Act var (httpResponse, _) = await _testContext.ExecutePostAsync(route, requestBody, contentType); @@ -174,8 +174,8 @@ public async Task Denies_JsonApi_ContentType_header_with_profile() } }; - var route = "/policies"; - var contentType = HeaderConstants.MediaType + "; profile=something"; + const string route = "/policies"; + const string contentType = HeaderConstants.MediaType + "; profile=something"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody, contentType); @@ -205,8 +205,8 @@ public async Task Denies_JsonApi_ContentType_header_with_extension() } }; - var route = "/policies"; - var contentType = HeaderConstants.MediaType + "; ext=something"; + const string route = "/policies"; + const string contentType = HeaderConstants.MediaType + "; ext=something"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody, contentType); @@ -236,8 +236,8 @@ public async Task Denies_JsonApi_ContentType_header_with_AtomicOperations_extens } }; - var route = "/policies"; - var contentType = HeaderConstants.AtomicOperationsMediaType; + const string route = "/policies"; + const string contentType = HeaderConstants.AtomicOperationsMediaType; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody, contentType); @@ -267,8 +267,8 @@ public async Task Denies_JsonApi_ContentType_header_with_CharSet() } }; - var route = "/policies"; - var contentType = HeaderConstants.MediaType + "; charset=ISO-8859-4"; + const string route = "/policies"; + const string contentType = HeaderConstants.MediaType + "; charset=ISO-8859-4"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody, contentType); @@ -298,8 +298,8 @@ public async Task Denies_JsonApi_ContentType_header_with_unknown_parameter() } }; - var route = "/policies"; - var contentType = HeaderConstants.MediaType + "; unknown=unexpected"; + const string route = "/policies"; + const string contentType = HeaderConstants.MediaType + "; unknown=unexpected"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody, contentType); @@ -336,8 +336,8 @@ public async Task Denies_JsonApi_ContentType_header_at_operations_endpoint() } }; - var route = "/operations"; - var contentType = HeaderConstants.MediaType; + const string route = "/operations"; + const string contentType = HeaderConstants.MediaType; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody, contentType); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/ApiControllerAttributeTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/ApiControllerAttributeTests.cs index f124fe6ae6..19c7660191 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/ApiControllerAttributeTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/ApiControllerAttributeTests.cs @@ -22,7 +22,7 @@ public ApiControllerAttributeTests(ExampleIntegrationTestContext(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteTests.cs index 5978ae3b4c..05141c83a9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteTests.cs @@ -65,7 +65,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/world-api/civilization/popular/towns/largest-5"; + const string route = "/world-api/civilization/popular/towns/largest-5"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingTests.cs index 76d7d9a972..4529e06313 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingTests.cs @@ -224,7 +224,7 @@ public async Task Can_create_resource() } }; - var route = "/buildings"; + const string route = "/buildings"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs index 27d4fa10fa..17a552bf58 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs @@ -74,7 +74,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Cannot_get_primary_resource_for_invalid_ID() { // Arrange - var route = "/bankAccounts/not-a-hex-value"; + const string route = "/bankAccounts/not-a-hex-value"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -229,8 +229,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } } }; - - var route = "/debitCards"; + + const string route = "/debitCards"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithNamespaceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithNamespaceTests.cs index a5fa5e1f26..2f0a0fa216 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithNamespaceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithNamespaceTests.cs @@ -78,7 +78,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/api/photoAlbums?include=photos"; + const string route = "/api/photoAlbums?include=photos"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -272,7 +272,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/api/photoAlbums?include=photos"; + const string route = "/api/photoAlbums?include=photos"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithoutNamespaceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithoutNamespaceTests.cs index 7de9adbaee..9af1cdf987 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithoutNamespaceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithoutNamespaceTests.cs @@ -78,7 +78,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/photoAlbums?include=photos"; + const string route = "/photoAlbums?include=photos"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -272,7 +272,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/photoAlbums?include=photos"; + const string route = "/photoAlbums?include=photos"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithNamespaceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithNamespaceTests.cs index e06f78f6a7..b038db1fa0 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithNamespaceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithNamespaceTests.cs @@ -78,7 +78,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/api/photoAlbums?include=photos"; + const string route = "/api/photoAlbums?include=photos"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -272,7 +272,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/api/photoAlbums?include=photos"; + const string route = "/api/photoAlbums?include=photos"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithoutNamespaceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithoutNamespaceTests.cs index dfbffa6123..ad5305a202 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithoutNamespaceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithoutNamespaceTests.cs @@ -78,7 +78,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/photoAlbums?include=photos"; + const string route = "/photoAlbums?include=photos"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -272,7 +272,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/photoAlbums?include=photos"; + const string route = "/photoAlbums?include=photos"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/LoggingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/LoggingTests.cs index 754aedc690..3b99bfbcf1 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/LoggingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/LoggingTests.cs @@ -63,7 +63,7 @@ public async Task Logs_request_body_at_Trace_level() }; // Arrange - var route = "/auditEntries"; + const string route = "/auditEntries"; // Act var (httpResponse, _) = await _testContext.ExecutePostAsync(route, requestBody); @@ -85,7 +85,7 @@ public async Task Logs_response_body_at_Trace_level() loggerFactory.Logger.Clear(); // Arrange - var route = "/auditEntries"; + const string route = "/auditEntries"; // Act var (httpResponse, _) = await _testContext.ExecuteGetAsync(route); @@ -107,9 +107,9 @@ public async Task Logs_invalid_request_body_error_at_Information_level() loggerFactory.Logger.Clear(); // Arrange - var requestBody = "{ \"data\" {"; + const string requestBody = "{ \"data\" {"; - var route = "/auditEntries"; + const string route = "/auditEntries"; // Act var (httpResponse, _) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/ResourceMetaTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/ResourceMetaTests.cs index 6a943c0615..951f752d20 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/ResourceMetaTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/ResourceMetaTests.cs @@ -41,7 +41,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/supportTickets"; + const string route = "/supportTickets"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/ResponseMetaTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/ResponseMetaTests.cs index 71a85c5122..d98fd84e8d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/ResponseMetaTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/ResponseMetaTests.cs @@ -37,7 +37,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.ClearTableAsync(); }); - var route = "/supportTickets"; + const string route = "/supportTickets"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/TopLevelCountTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/TopLevelCountTests.cs index efbab3be27..e2aa06abab 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/TopLevelCountTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/TopLevelCountTests.cs @@ -43,7 +43,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/supportTickets"; + const string route = "/supportTickets"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -64,7 +64,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.ClearTableAsync(); }); - var route = "/supportTickets"; + const string route = "/supportTickets"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -94,7 +94,7 @@ public async Task Hides_resource_count_in_create_resource_response() } }; - var route = "/supportTickets"; + const string route = "/supportTickets"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateValidationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateValidationTests.cs index 6920f40574..92838b2900 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateValidationTests.cs @@ -34,7 +34,7 @@ public async Task Cannot_create_resource_with_omitted_required_attribute() } }; - string route = "/systemDirectories"; + const string route = "/systemDirectories"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -66,7 +66,7 @@ public async Task Cannot_create_resource_with_null_for_required_attribute_value( } }; - string route = "/systemDirectories"; + const string route = "/systemDirectories"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -98,7 +98,7 @@ public async Task Cannot_create_resource_with_invalid_attribute_value() } }; - string route = "/systemDirectories"; + const string route = "/systemDirectories"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -130,7 +130,7 @@ public async Task Can_create_resource_with_valid_attribute_value() } }; - string route = "/systemDirectories"; + const string route = "/systemDirectories"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -159,7 +159,7 @@ public async Task Cannot_create_resource_with_multiple_violations() } }; - string route = "/systemDirectories"; + const string route = "/systemDirectories"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -260,7 +260,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - string route = "/systemDirectories"; + const string route = "/systemDirectories"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -489,7 +489,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - string route = "/systemDirectories/-1"; + const string route = "/systemDirectories/-1"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePatchAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/NoModelStateValidationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/NoModelStateValidationTests.cs index f24da7a5d1..1780d32aba 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/NoModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/NoModelStateValidationTests.cs @@ -34,7 +34,7 @@ public async Task Can_create_resource_with_invalid_attribute_value() } }; - string route = "/systemDirectories"; + const string route = "/systemDirectories"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs index 08d4d28f3f..c01df7bb0c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs @@ -34,7 +34,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/public-api/swimming-pools?include=diving-boards"; + const string route = "/public-api/swimming-pools?include=diving-boards"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -105,7 +105,7 @@ public async Task Can_create_resource() } }; - var route = "/public-api/swimming-pools"; + const string route = "/public-api/swimming-pools"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -138,9 +138,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Applies_casing_convention_on_error_stack_trace() { // Arrange - var requestBody = "{ \"data\": {"; + const string requestBody = "{ \"data\": {"; - var route = "/public-api/swimming-pools"; + const string route = "/public-api/swimming-pools"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs index 528a8339b4..a5e7ac87bb 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs @@ -207,7 +207,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/filterableResources?filter=equals(someInt32,'ABC')"; + const string route = "/filterableResources?filter=equals(someInt32,'ABC')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs index 0c9f15bdf3..009e424ad4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs @@ -45,7 +45,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?filter=equals(caption,'Two')"; + const string route = "/blogPosts?filter=equals(caption,'Two')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -155,7 +155,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?include=author&filter=equals(author.userName,'Smith')"; + const string route = "/blogPosts?include=author&filter=equals(author.userName,'Smith')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -183,7 +183,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogs?filter=greaterThan(count(posts),'0')"; + const string route = "/blogs?filter=greaterThan(count(posts),'0')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -215,7 +215,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?filter=has(labels)"; + const string route = "/blogPosts?filter=has(labels)"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -243,7 +243,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogs?include=posts&filter[posts]=equals(caption,'Two')"; + const string route = "/blogs?include=posts&filter[posts]=equals(caption,'Two')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -322,7 +322,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => options.DisableTopPagination = false; options.DisableChildrenPagination = true; - var route = "/blogPosts?include=labels&filter[labels]=equals(name,'Hot')"; + const string route = "/blogPosts?include=labels&filter[labels]=equals(name,'Hot')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -353,7 +353,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogs?include=owner.posts&filter[owner.posts]=equals(caption,'Two')"; + const string route = "/blogs?include=owner.posts&filter[owner.posts]=equals(caption,'Two')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -384,7 +384,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?filter=equals(caption,'One')&filter=equals(caption,'Three')"; + const string route = "/blogPosts?filter=equals(caption,'One')&filter=equals(caption,'Three')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -425,7 +425,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?filter[author.userName]=John&filter[author.displayName]=Smith"; + const string route = "/blogPosts?filter[author.userName]=John&filter[author.displayName]=Smith"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -460,10 +460,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogs?include=owner.posts.comments&" + - "filter=and(equals(title,'Technology'),has(owner.posts),equals(owner.userName,'Smith'))&" + - "filter[owner.posts]=equals(caption,'Two')&" + - "filter[owner.posts.comments]=greaterThan(createdAt,'2005-05-05')"; + const string route = "/blogs?include=owner.posts.comments&" + + "filter=and(equals(title,'Technology'),has(owner.posts),equals(owner.userName,'Smith'))&" + + "filter[owner.posts]=equals(caption,'Two')&" + + "filter[owner.posts.comments]=greaterThan(createdAt,'2005-05-05')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterOperatorTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterOperatorTests.cs index a8f0485a4b..496184123a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterOperatorTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterOperatorTests.cs @@ -79,7 +79,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/filterableResources?filter=equals(someInt32,otherInt32)"; + const string route = "/filterableResources?filter=equals(someInt32,otherInt32)"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -115,7 +115,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/filterableResources?filter=equals(someNullableInt32,otherNullableInt32)"; + const string route = "/filterableResources?filter=equals(someNullableInt32,otherNullableInt32)"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -151,7 +151,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/filterableResources?filter=equals(someNullableInt32,someInt32)"; + const string route = "/filterableResources?filter=equals(someNullableInt32,someInt32)"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -187,7 +187,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/filterableResources?filter=equals(someInt32,someNullableInt32)"; + const string route = "/filterableResources?filter=equals(someInt32,someNullableInt32)"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -223,7 +223,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/filterableResources?filter=equals(someInt32,someUnsignedInt64)"; + const string route = "/filterableResources?filter=equals(someInt32,someUnsignedInt64)"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -240,7 +240,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Cannot_filter_equality_on_two_attributes_of_incompatible_types() { // Arrange - var route = "/filterableResources?filter=equals(someDouble,someTimeSpan)"; + const string route = "/filterableResources?filter=equals(someDouble,someTimeSpan)"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -470,7 +470,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/filterableResources?filter=has(children)"; + const string route = "/filterableResources?filter=has(children)"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -502,7 +502,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/filterableResources?filter=equals(count(children),'2')"; + const string route = "/filterableResources?filter=equals(count(children),'2')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterTests.cs index 041ca5fae1..4a2554246e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterTests.cs @@ -28,7 +28,7 @@ public FilterTests(ExampleIntegrationTestContext(route); @@ -47,7 +47,7 @@ public async Task Cannot_filter_in_unknown_scope() public async Task Cannot_filter_in_unknown_nested_scope() { // Arrange - var route = "/webAccounts?filter[posts.doesNotExist]=equals(title,null)"; + const string route = "/webAccounts?filter[posts.doesNotExist]=equals(title,null)"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -66,7 +66,7 @@ public async Task Cannot_filter_in_unknown_nested_scope() public async Task Cannot_filter_on_attribute_with_blocked_capability() { // Arrange - var route = "/webAccounts?filter=equals(dateOfBirth,null)"; + const string route = "/webAccounts?filter=equals(dateOfBirth,null)"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Includes/IncludeTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Includes/IncludeTests.cs index d520dff2ce..f132e8f7df 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Includes/IncludeTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Includes/IncludeTests.cs @@ -40,7 +40,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "blogPosts?include=author"; + const string route = "blogPosts?include=author"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -538,7 +538,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?include=author"; + const string route = "/blogPosts?include=author"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -558,7 +558,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Cannot_include_unknown_relationship() { // Arrange - var route = "/webAccounts?include=doesNotExist"; + const string route = "/webAccounts?include=doesNotExist"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -577,7 +577,7 @@ public async Task Cannot_include_unknown_relationship() public async Task Cannot_include_unknown_nested_relationship() { // Arrange - var route = "/blogs?include=posts.doesNotExist"; + const string route = "/blogs?include=posts.doesNotExist"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -596,7 +596,7 @@ public async Task Cannot_include_unknown_nested_relationship() public async Task Cannot_include_relationship_with_blocked_capability() { // Arrange - var route = "/blogPosts?include=parent"; + const string route = "/blogPosts?include=parent"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -625,7 +625,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?include=reviewer.preferences"; + const string route = "/blogPosts?include=reviewer.preferences"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -680,7 +680,7 @@ public async Task Cannot_exceed_configured_maximum_inclusion_depth() var options = (JsonApiOptions) _testContext.Factory.Services.GetRequiredService(); options.MaximumIncludeDepth = 1; - var route = "/blogs/123/owner?include=posts.comments"; + const string route = "/blogs/123/owner?include=posts.comments"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs index 113cfdba47..36520af65a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs @@ -48,7 +48,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?page[number]=2&page[size]=1"; + const string route = "/blogPosts?page[number]=2&page[size]=1"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -168,7 +168,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogs?include=posts&page[number]=posts:2&page[size]=2,posts:1"; + const string route = "/blogs?include=posts&page[number]=posts:2&page[size]=2,posts:1"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -296,7 +296,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => options.DisableTopPagination = true; options.DisableChildrenPagination = false; - var route = "/blogPosts?include=labels&page[number]=labels:2&page[size]=labels:1"; + const string route = "/blogPosts?include=labels&page[number]=labels:2&page[size]=labels:1"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -377,9 +377,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogs?include=owner.posts.comments&" + - "page[size]=1,owner.posts:1,owner.posts.comments:1&" + - "page[number]=2,owner.posts:2,owner.posts.comments:2"; + const string route = "/blogs?include=owner.posts.comments&" + + "page[size]=1,owner.posts:1,owner.posts.comments:1&" + + "page[number]=2,owner.posts:2,owner.posts.comments:2"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -407,7 +407,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Cannot_paginate_in_unknown_scope() { // Arrange - var route = "/webAccounts?page[number]=doesNotExist:1"; + const string route = "/webAccounts?page[number]=doesNotExist:1"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -426,7 +426,7 @@ public async Task Cannot_paginate_in_unknown_scope() public async Task Cannot_paginate_in_unknown_nested_scope() { // Arrange - var route = "/webAccounts?page[size]=posts.doesNotExist:1"; + const string route = "/webAccounts?page[size]=posts.doesNotExist:1"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithoutTotalCountTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithoutTotalCountTests.cs index 9e7c3f7a06..d6abbdb867 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithoutTotalCountTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithoutTotalCountTests.cs @@ -36,7 +36,7 @@ public async Task Hides_pagination_links_when_unconstrained_page_size() var options = (JsonApiOptions) _testContext.Factory.Services.GetRequiredService(); options.DefaultPageSize = null; - var route = "/blogPosts?foo=bar"; + const string route = "/blogPosts?foo=bar"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -65,7 +65,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?page[size]=8&foo=bar"; + const string route = "/blogPosts?page[size]=8&foo=bar"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -91,7 +91,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?page[number]=2&foo=bar"; + const string route = "/blogPosts?page[number]=2&foo=bar"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -120,7 +120,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?foo=bar&page[number]=3"; + const string route = "/blogPosts?foo=bar&page[number]=3"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -151,7 +151,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?page[number]=3&foo=bar"; + const string route = "/blogPosts?page[number]=3&foo=bar"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs index ca5afde779..6625c0af05 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs @@ -32,7 +32,7 @@ public RangeValidationTests(ExampleIntegrationTestContext(route); @@ -51,7 +51,7 @@ public async Task Cannot_use_negative_page_number() public async Task Cannot_use_zero_page_number() { // Arrange - var route = "/blogs?page[number]=0"; + const string route = "/blogs?page[number]=0"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -70,7 +70,7 @@ public async Task Cannot_use_zero_page_number() public async Task Can_use_positive_page_number() { // Arrange - var route = "/blogs?page[number]=20"; + const string route = "/blogs?page[number]=20"; // Act var (httpResponse, _) = await _testContext.ExecuteGetAsync(route); @@ -92,7 +92,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogs?sort=id&page[size]=3&page[number]=2"; + const string route = "/blogs?sort=id&page[size]=3&page[number]=2"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -107,7 +107,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Cannot_use_negative_page_size() { // Arrange - var route = "/blogs?page[size]=-1"; + const string route = "/blogs?page[size]=-1"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -126,7 +126,7 @@ public async Task Cannot_use_negative_page_size() public async Task Can_use_zero_page_size() { // Arrange - var route = "/blogs?page[size]=0"; + const string route = "/blogs?page[size]=0"; // Act var (httpResponse, _) = await _testContext.ExecuteGetAsync(route); @@ -139,7 +139,7 @@ public async Task Can_use_zero_page_size() public async Task Can_use_positive_page_size() { // Arrange - var route = "/blogs?page[size]=50"; + const string route = "/blogs?page[size]=50"; // Act var (httpResponse, _) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationWithMaximumTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationWithMaximumTests.cs index b5731aeaf0..5326c9724a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationWithMaximumTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationWithMaximumTests.cs @@ -80,7 +80,7 @@ public async Task Cannot_use_page_number_over_maximum() public async Task Cannot_use_zero_page_size() { // Arrange - var route = "/blogs?page[size]=0"; + const string route = "/blogs?page[size]=0"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringTests.cs index 1fc4c975d0..82f8436a6e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringTests.cs @@ -27,7 +27,7 @@ public async Task Cannot_use_unknown_query_string_parameter() var options = (JsonApiOptions) _testContext.Factory.Services.GetRequiredService(); options.AllowUnknownQueryStringParameters = false; - var route = "/calendars?foo=bar"; + const string route = "/calendars?foo=bar"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -49,7 +49,7 @@ public async Task Can_use_unknown_query_string_parameter() var options = (JsonApiOptions) _testContext.Factory.Services.GetRequiredService(); options.AllowUnknownQueryStringParameters = true; - var route = "/calendars?foo=bar"; + const string route = "/calendars?foo=bar"; // Act var (httpResponse, _) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerDefaultValueHandlingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerDefaultValueHandlingTests.cs index 898b6b7ad4..017d30628a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerDefaultValueHandlingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerDefaultValueHandlingTests.cs @@ -30,7 +30,7 @@ public async Task Cannot_override_from_query_string() var options = (JsonApiOptions) _testContext.Factory.Services.GetRequiredService(); options.AllowQueryStringOverrideForSerializerDefaultValueHandling = false; - var route = "/calendars?defaults=true"; + const string route = "/calendars?defaults=true"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerNullValueHandlingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerNullValueHandlingTests.cs index 5ee4f490c8..52fdbbc4bc 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerNullValueHandlingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerNullValueHandlingTests.cs @@ -30,7 +30,7 @@ public async Task Cannot_override_from_query_string() var options = (JsonApiOptions) _testContext.Factory.Services.GetRequiredService(); options.AllowQueryStringOverrideForSerializerNullValueHandling = false; - var route = "/calendars?nulls=true"; + const string route = "/calendars?nulls=true"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs index 36f4a1f9bf..4282440241 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs @@ -38,7 +38,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?sort=caption"; + const string route = "/blogPosts?sort=caption"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -151,7 +151,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogs?sort=count(posts)"; + const string route = "/blogs?sort=count(posts)"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -195,7 +195,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?sort=-count(labels)"; + const string route = "/blogPosts?sort=-count(labels)"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -353,7 +353,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogs?include=posts.comments&sort=title&sort[posts]=caption,url&sort[posts.comments]=-createdAt"; + const string route = "/blogs?include=posts.comments&sort=title&sort[posts]=caption,url&sort[posts.comments]=-createdAt"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -407,7 +407,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?sort=-author.displayName"; + const string route = "/blogPosts?sort=-author.displayName"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -444,10 +444,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogs?include=owner.posts.comments&" + - "sort=-title&" + - "sort[owner.posts]=-caption&" + - "sort[owner.posts.comments]=-createdAt"; + const string route = "/blogs?include=owner.posts.comments&" + + "sort=-title&" + + "sort[owner.posts]=-caption&" + + "sort[owner.posts.comments]=-createdAt"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -471,7 +471,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Cannot_sort_in_unknown_scope() { // Arrange - var route = "/webAccounts?sort[doesNotExist]=id"; + const string route = "/webAccounts?sort[doesNotExist]=id"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -490,7 +490,7 @@ public async Task Cannot_sort_in_unknown_scope() public async Task Cannot_sort_in_unknown_nested_scope() { // Arrange - var route = "/webAccounts?sort[posts.doesNotExist]=id"; + const string route = "/webAccounts?sort[posts.doesNotExist]=id"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -509,7 +509,7 @@ public async Task Cannot_sort_in_unknown_nested_scope() public async Task Cannot_sort_on_attribute_with_blocked_capability() { // Arrange - var route = "/webAccounts?sort=dateOfBirth"; + const string route = "/webAccounts?sort=dateOfBirth"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -544,7 +544,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/webAccounts?sort=displayName,-id"; + const string route = "/webAccounts?sort=displayName,-id"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -575,7 +575,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/webAccounts"; + const string route = "/webAccounts"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs index bb46bf65f7..78e1c0cab6 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs @@ -48,7 +48,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?fields[blogPosts]=caption,author"; + const string route = "/blogPosts?fields[blogPosts]=caption,author"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -86,7 +86,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?fields[blogPosts]=caption"; + const string route = "/blogPosts?fields[blogPosts]=caption"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -121,7 +121,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?fields[blogPosts]=author"; + const string route = "/blogPosts?fields[blogPosts]=author"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -554,7 +554,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/blogPosts?fields[blogPosts]=id,caption"; + const string route = "/blogPosts?fields[blogPosts]=id,caption"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -578,7 +578,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Cannot_select_on_unknown_resource_type() { // Arrange - var route = "/webAccounts?fields[doesNotExist]=id"; + const string route = "/webAccounts?fields[doesNotExist]=id"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs index 4e961c5e17..d5e3da1728 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs @@ -47,7 +47,7 @@ public async Task Sets_location_header_for_created_resource() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -84,7 +84,7 @@ public async Task Can_create_resource_with_int_ID() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -132,7 +132,7 @@ public async Task Can_create_resource_with_long_ID() } }; - var route = "/userAccounts"; + const string route = "/userAccounts"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -179,7 +179,7 @@ public async Task Can_create_resource_with_guid_ID() } }; - var route = "/workItemGroups"; + const string route = "/workItemGroups"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -224,7 +224,7 @@ public async Task Can_create_resource_without_attributes_or_relationships() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -269,7 +269,7 @@ public async Task Can_create_resource_with_unknown_attribute() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -316,7 +316,7 @@ public async Task Can_create_resource_with_unknown_relationship() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -357,7 +357,7 @@ public async Task Cannot_create_resource_with_client_generated_ID() } }; - var route = "/rgbColors"; + const string route = "/rgbColors"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -378,7 +378,7 @@ public async Task Cannot_create_resource_for_missing_request_body() // Arrange var requestBody = string.Empty; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -406,7 +406,7 @@ public async Task Cannot_create_resource_for_missing_type() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -435,7 +435,7 @@ public async Task Cannot_create_resource_for_unknown_type() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -464,7 +464,7 @@ public async Task Cannot_create_resource_on_unknown_resource_type_in_url() } }; - var route = "/doesNotExist"; + const string route = "/doesNotExist"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -487,7 +487,8 @@ public async Task Cannot_create_on_resource_type_mismatch_between_url_and_body() id = "0A0B0C" } }; - var route = "/workItems"; + + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -517,7 +518,7 @@ public async Task Cannot_create_resource_attribute_with_blocked_capability() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -547,7 +548,7 @@ public async Task Cannot_create_resource_with_readonly_attribute() } }; - var route = "/workItemGroups"; + const string route = "/workItemGroups"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -565,9 +566,9 @@ public async Task Cannot_create_resource_with_readonly_attribute() public async Task Cannot_create_resource_for_broken_JSON_request_body() { // Arrange - var requestBody = "{ \"data\" {"; + const string requestBody = "{ \"data\" {"; - var route = "/workItemGroups"; + const string route = "/workItemGroups"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -597,7 +598,7 @@ public async Task Cannot_create_resource_with_incompatible_attribute_value() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -672,7 +673,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs index e6ef1f914f..e4236d90e4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs @@ -47,7 +47,7 @@ public async Task Can_create_resource_with_client_generated_guid_ID_having_side_ } }; - var route = "/workItemGroups"; + const string route = "/workItemGroups"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -93,7 +93,7 @@ public async Task Can_create_resource_with_client_generated_guid_ID_having_side_ } }; - var route = "/workItemGroups?fields[workItemGroups]=name"; + const string route = "/workItemGroups?fields[workItemGroups]=name"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -139,7 +139,7 @@ public async Task Can_create_resource_with_client_generated_string_ID_having_no_ } }; - var route = "/rgbColors"; + const string route = "/rgbColors"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -180,7 +180,7 @@ public async Task Can_create_resource_with_client_generated_string_ID_having_no_ } }; - var route = "/rgbColors?fields[rgbColors]=id"; + const string route = "/rgbColors?fields[rgbColors]=id"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -230,7 +230,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/rgbColors"; + const string route = "/rgbColors"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs index 2d9cb8f5fa..d85813fea1 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs @@ -60,7 +60,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -126,7 +126,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/workItems?include=subscribers"; + const string route = "/workItems?include=subscribers"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -199,7 +199,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/workItems?include=subscribers&fields[userAccounts]=firstName"; + const string route = "/workItems?include=subscribers&fields[userAccounts]=firstName"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -283,7 +283,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/workItems?fields[workItems]=priority,tags&include=tags&fields[workTags]=text"; + const string route = "/workItems?fields[workItems]=priority,tags&include=tags&fields[workTags]=text"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -350,7 +350,7 @@ public async Task Cannot_create_for_missing_relationship_type() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -390,7 +390,7 @@ public async Task Cannot_create_for_unknown_relationship_type() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -429,7 +429,7 @@ public async Task Cannot_create_for_missing_relationship_ID() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -474,7 +474,7 @@ public async Task Cannot_create_for_unknown_relationship_IDs() } }; - var route = "/userAccounts"; + const string route = "/userAccounts"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -519,7 +519,7 @@ public async Task Cannot_create_on_relationship_type_mismatch() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -572,7 +572,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/workItems?include=subscribers"; + const string route = "/workItems?include=subscribers"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -620,7 +620,7 @@ public async Task Cannot_create_with_null_data_in_HasMany_relationship() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -653,7 +653,7 @@ public async Task Cannot_create_with_null_data_in_HasManyThrough_relationship() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -696,7 +696,7 @@ public async Task Cannot_create_resource_with_local_ID() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs index 888cea9571..c326fd31f3 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs @@ -59,7 +59,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/workItemGroups"; + const string route = "/workItemGroups"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -102,7 +102,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - string colorId = "0A0B0C"; + const string colorId = "0A0B0C"; var requestBody = new { @@ -124,7 +124,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/rgbColors"; + const string route = "/rgbColors"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -181,7 +181,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/workItems?include=assignee"; + const string route = "/workItems?include=assignee"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -250,7 +250,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/workItems?fields[workItems]=description,assignee&include=assignee"; + const string route = "/workItems?fields[workItems]=description,assignee&include=assignee"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -308,7 +308,7 @@ public async Task Cannot_create_for_missing_relationship_type() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -345,7 +345,7 @@ public async Task Cannot_create_for_unknown_relationship_type() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -381,7 +381,7 @@ public async Task Cannot_create_for_missing_relationship_ID() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -418,7 +418,7 @@ public async Task Cannot_create_with_unknown_relationship_ID() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -455,7 +455,7 @@ public async Task Cannot_create_on_relationship_type_mismatch() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -510,7 +510,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var requestBodyText = JsonConvert.SerializeObject(requestBody).Replace("assignee_duplicate", "assignee"); - var route = "/workItems?include=assignee"; + const string route = "/workItems?include=assignee"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBodyText); @@ -576,7 +576,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -616,7 +616,7 @@ public async Task Cannot_create_resource_with_local_ID() } }; - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs index 3b49693fc3..9605013839 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs @@ -56,7 +56,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Cannot_delete_missing_resource() { // Arrange - var route = "/workItems/99999999"; + const string route = "/workItems/99999999"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteDeleteAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchRelationshipTests.cs index 252539df21..4c01aecd1b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchRelationshipTests.cs @@ -197,7 +197,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => [Fact] public async Task Cannot_get_relationship_for_unknown_primary_type() { - var route = "/doesNotExist/99999999/relationships/assignee"; + const string route = "/doesNotExist/99999999/relationships/assignee"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -211,7 +211,7 @@ public async Task Cannot_get_relationship_for_unknown_primary_type() [Fact] public async Task Cannot_get_relationship_for_unknown_primary_ID() { - var route = "/workItems/99999999/relationships/assignee"; + const string route = "/workItems/99999999/relationships/assignee"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchResourceTests.cs index 6042b9ded4..213674f813 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchResourceTests.cs @@ -34,7 +34,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/workItems"; + const string route = "/workItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -63,7 +63,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Cannot_get_primary_resources_for_unknown_type() { // Arrange - var route = "/doesNotExist"; + const string route = "/doesNotExist"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -107,7 +107,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Cannot_get_primary_resource_for_unknown_type() { // Arrange - var route = "/doesNotExist/99999999"; + const string route = "/doesNotExist/99999999"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -122,7 +122,7 @@ public async Task Cannot_get_primary_resource_for_unknown_type() public async Task Cannot_get_primary_resource_for_unknown_ID() { // Arrange - var route = "/workItems/99999999"; + const string route = "/workItems/99999999"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -322,7 +322,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Cannot_get_secondary_resource_for_unknown_primary_type() { // Arrange - var route = "/doesNotExist/99999999/assignee"; + const string route = "/doesNotExist/99999999/assignee"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -337,7 +337,7 @@ public async Task Cannot_get_secondary_resource_for_unknown_primary_type() public async Task Cannot_get_secondary_resource_for_unknown_primary_ID() { // Arrange - var route = "/workItems/99999999/assignee"; + const string route = "/workItems/99999999/assignee"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs index 1d43cb3a59..0928286a18 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs @@ -482,7 +482,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/workItems/99999999/relationships/subscribers"; + const string route = "/workItems/99999999/relationships/subscribers"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs index 550f020e73..d76ded0470 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs @@ -477,7 +477,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/workItems/99999999/relationships/subscribers"; + const string route = "/workItems/99999999/relationships/subscribers"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteDeleteAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs index 5140bbfeba..c4bf5d1656 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs @@ -520,7 +520,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => data = new object[0] }; - var route = "/workItems/99999999/relationships/subscribers"; + const string route = "/workItems/99999999/relationships/subscribers"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePatchAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs index b86ec9b952..629caf8395 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs @@ -467,7 +467,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/workItems/99999999/relationships/assignee"; + const string route = "/workItems/99999999/relationships/assignee"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePatchAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs index f35fc9477d..ea67424dee 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs @@ -703,7 +703,7 @@ public async Task Cannot_update_resource_on_unknown_resource_ID_in_url() } }; - var route = "/workItems/99999999"; + const string route = "/workItems/99999999"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePatchAsync(route, requestBody); @@ -877,7 +877,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var requestBody = "{ \"data\" {"; + const string requestBody = "{ \"data\" {"; var route = "/workItemGroups/" + existingWorkItem.StringId; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs index 9fda109f2e..5a8df69771 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs @@ -42,7 +42,7 @@ public async Task Cannot_create_dependent_side_of_required_ManyToOne_relationshi } }; - var route = "/orders"; + const string route = "/orders"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -74,7 +74,7 @@ public async Task Cannot_create_dependent_side_of_required_OneToOne_relationship } }; - var route = "/shipments"; + const string route = "/shipments"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs index 92b0783b89..4e598166f9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs @@ -161,7 +161,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/giftCertificates?include=issuer"; + const string route = "/giftCertificates?include=issuer"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -297,7 +297,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Cannot_delete_unknown_resource() { // Arrange - var route = "/postOffices/99999999"; + const string route = "/postOffices/99999999"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteDeleteAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs index 1841175d32..af787d76c7 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs @@ -51,7 +51,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/callableResources?include=owner"; + const string route = "/callableResources?include=owner"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -99,7 +99,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/callableResources"; + const string route = "/callableResources"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -149,7 +149,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/callableResources?filter=equals(label,'B')"; + const string route = "/callableResources?filter=equals(label,'B')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -196,7 +196,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/callableResources"; + const string route = "/callableResources"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -243,7 +243,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/callableResources?sort=-createdAt,modifiedAt"; + const string route = "/callableResources?sort=-createdAt,modifiedAt"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -275,7 +275,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/callableResources?page[size]=8"; + const string route = "/callableResources?page[size]=8"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -444,7 +444,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/callableResources?isHighRisk=true"; + const string route = "/callableResources?isHighRisk=true"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -492,7 +492,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/callableResources?isHighRisk=false&filter=equals(label,'B')"; + const string route = "/callableResources?isHighRisk=false&filter=equals(label,'B')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs index 62bd8491e3..55435a459a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs @@ -55,7 +55,7 @@ public async Task Can_create_user_with_password() var serializer = GetRequestSerializer(p => new {p.Password, p.UserName}); string requestBody = serializer.Serialize(user); - var route = "/api/v1/users"; + const string route = "/api/v1/users"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -118,7 +118,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Can_block_access_to_resource_from_GetSingle_endpoint_using_BeforeRead_hook() { // Arrange - var route = "/api/v1/todoItems/1337"; + const string route = "/api/v1/todoItems/1337"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -136,7 +136,7 @@ public async Task Can_block_access_to_resource_from_GetSingle_endpoint_using_Bef public async Task Can_block_access_to_included_resource_using_BeforeRead_hook() { // Arrange - var route = "/api/v1/people/1?include=passport"; + const string route = "/api/v1/people/1?include=passport"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -182,7 +182,7 @@ public async Task Can_hide_primary_resource_from_result_set_from_GetAll_endpoint { // Arrange var articles = _fakers.Article.Generate(3); - string toBeExcluded = "This should not be included"; + const string toBeExcluded = "This should not be included"; articles[0].Caption = toBeExcluded; await _testContext.RunOnDatabaseAsync(async dbContext => @@ -191,7 +191,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/api/v1/articles"; + const string route = "/api/v1/articles"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -231,7 +231,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Can_hide_secondary_resource_from_ToMany_List_relationship_using_OnReturn_hook() { // Arrange - string toBeExcluded = "This should not be included"; + const string toBeExcluded = "This should not be included"; var author = _fakers.Author.Generate(); author.Articles = _fakers.Article.Generate(3); @@ -258,7 +258,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Can_hide_secondary_resource_from_ToMany_Set_relationship_using_OnReturn_hook() { // Arrange - string toBeExcluded = "This should not be included"; + const string toBeExcluded = "This should not be included"; var person = _fakers.Person.Generate(); person.TodoItems = _fakers.TodoItem.Generate(3).ToHashSet(); @@ -285,7 +285,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Can_hide_resource_from_included_HasManyThrough_relationship_using_OnReturn_hook() { // Arrange - string toBeExcluded = "This should not be included"; + const string toBeExcluded = "This should not be included"; var tags = _fakers.Tag.Generate(2); tags[0].Name = toBeExcluded; @@ -314,7 +314,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => options.DisableTopPagination = false; options.DisableChildrenPagination = true; - var route = "/api/v1/articles?include=tags"; + const string route = "/api/v1/articles?include=tags"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -358,7 +358,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/api/v1/people"; + const string route = "/api/v1/people"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -536,7 +536,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/api/v1/todoItems"; + const string route = "/api/v1/todoItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs index a844ddec8e..6f14d78598 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs @@ -45,7 +45,7 @@ public async Task Can_create_resource_with_inherited_attributes() } }; - var route = "/men"; + const string route = "/men"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -104,7 +104,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/men"; + const string route = "/men"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -271,7 +271,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/men"; + const string route = "/men"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -389,11 +389,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/men"; + const string route = "/men"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); - + // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.Created); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/DisableQueryStringTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/DisableQueryStringTests.cs index 873add19b1..8b4467dec4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/DisableQueryStringTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/DisableQueryStringTests.cs @@ -30,7 +30,7 @@ public DisableQueryStringTests(ExampleIntegrationTestContext(route); @@ -49,7 +49,7 @@ public async Task Cannot_sort_if_query_string_parameter_is_blocked_by_controller public async Task Cannot_paginate_if_query_string_parameter_is_blocked_by_controller() { // Arrange - var route = "/sofas?page[number]=2"; + const string route = "/sofas?page[number]=2"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -68,7 +68,7 @@ public async Task Cannot_paginate_if_query_string_parameter_is_blocked_by_contro public async Task Cannot_use_custom_query_string_parameter_if_blocked_by_controller() { // Arrange - var route = "/beds?skipCache=true"; + const string route = "/beds?skipCache=true"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/HttpReadOnlyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/HttpReadOnlyTests.cs index b2725a9d18..0b4bb3ea0c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/HttpReadOnlyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/HttpReadOnlyTests.cs @@ -23,7 +23,7 @@ public HttpReadOnlyTests(ExampleIntegrationTestContext(route); @@ -47,7 +47,7 @@ public async Task Cannot_create_resource() } }; - var route = "/beds"; + const string route = "/beds"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpDeleteTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpDeleteTests.cs index 26a8036d80..75838184f7 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpDeleteTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpDeleteTests.cs @@ -23,7 +23,7 @@ public NoHttpDeleteTests(ExampleIntegrationTestContext(route); @@ -47,7 +47,7 @@ public async Task Can_create_resource() } }; - var route = "/sofas"; + const string route = "/sofas"; // Act var (httpResponse, _) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPatchTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPatchTests.cs index b3acd90b77..5634052d76 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPatchTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPatchTests.cs @@ -23,7 +23,7 @@ public NoHttpPatchTests(ExampleIntegrationTestContext(route); @@ -47,7 +47,7 @@ public async Task Can_create_resource() } }; - var route = "/chairs"; + const string route = "/chairs"; // Act var (httpResponse, _) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPostTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPostTests.cs index 4486093ca0..de04e4ef2b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPostTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPostTests.cs @@ -23,7 +23,7 @@ public NoHttpPostTests(ExampleIntegrationTestContext(route); @@ -47,7 +47,7 @@ public async Task Cannot_create_resource() } }; - var route = "/tables"; + const string route = "/tables"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationTests.cs index 76d0ccf298..88e083b766 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationTests.cs @@ -49,7 +49,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/meetings?include=attendees"; + const string route = "/meetings?include=attendees"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -457,7 +457,7 @@ public async Task Can_create_resource_with_side_effects() } }; - var route = "/meetings"; + const string route = "/meetings"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs index 60c810531a..779430faa5 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs @@ -51,7 +51,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/departments"; + const string route = "/departments"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -91,7 +91,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/departments?filter=startsWith(name,'S')"; + const string route = "/departments?filter=startsWith(name,'S')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -252,7 +252,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/companies?include=departments"; + const string route = "/companies?include=departments"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs index a4193f46b0..5d81b3b570 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs @@ -42,7 +42,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/maps?filter=equals(id,'00000000-0000-0000-0000-000000000000')"; + const string route = "/maps?filter=equals(id,'00000000-0000-0000-0000-000000000000')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -71,7 +71,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/maps/00000000-0000-0000-0000-000000000000?include=game"; + const string route = "/maps/00000000-0000-0000-0000-000000000000?include=game"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -111,7 +111,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/maps"; + const string route = "/maps"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -162,7 +162,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/maps/00000000-0000-0000-0000-000000000000"; + const string route = "/maps/00000000-0000-0000-0000-000000000000"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePatchAsync(route, requestBody); @@ -572,7 +572,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/maps/00000000-0000-0000-0000-000000000000"; + const string route = "/maps/00000000-0000-0000-0000-000000000000"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteDeleteAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs index a50dec9bc0..010006d9f9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs @@ -41,7 +41,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/games?filter=equals(id,'0')"; + const string route = "/games?filter=equals(id,'0')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -69,7 +69,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/games/0?include=activePlayers"; + const string route = "/games/0?include=activePlayers"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -109,7 +109,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/games"; + const string route = "/games"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -161,7 +161,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/games/0"; + const string route = "/games/0"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePatchAsync(route, requestBody); @@ -573,7 +573,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/games/0"; + const string route = "/games/0"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteDeleteAsync(route); diff --git a/test/MultiDbContextTests/ResourceTests.cs b/test/MultiDbContextTests/ResourceTests.cs index eace446619..7dab27aaf1 100644 --- a/test/MultiDbContextTests/ResourceTests.cs +++ b/test/MultiDbContextTests/ResourceTests.cs @@ -23,7 +23,7 @@ public ResourceTests(WebApplicationFactory factory) public async Task Can_get_ResourceAs() { // Arrange - var route = "/resourceAs"; + const string route = "/resourceAs"; // Act var (httpResponse, responseDocument) = await ExecuteGetAsync(route); @@ -39,7 +39,7 @@ public async Task Can_get_ResourceAs() public async Task Can_get_ResourceBs() { // Arrange - var route = "/resourceBs"; + const string route = "/resourceBs"; // Act var (httpResponse, responseDocument) = await ExecuteGetAsync(route); diff --git a/test/NoEntityFrameworkTests/WorkItemTests.cs b/test/NoEntityFrameworkTests/WorkItemTests.cs index c78119d226..54b8928b58 100644 --- a/test/NoEntityFrameworkTests/WorkItemTests.cs +++ b/test/NoEntityFrameworkTests/WorkItemTests.cs @@ -33,7 +33,7 @@ await RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = "/api/v1/workItems"; + const string route = "/api/v1/workItems"; // Act var (httpResponse, responseDocument) = await ExecuteGetAsync(route); @@ -95,7 +95,7 @@ public async Task Can_create_WorkItem() } }; - var route = "/api/v1/workItems/"; + const string route = "/api/v1/workItems/"; // Act var (httpResponse, responseDocument) = await ExecutePostAsync(route, requestBody); diff --git a/test/UnitTests/Internal/TypeHelper_Tests.cs b/test/UnitTests/Internal/TypeHelper_Tests.cs index 89ec11da09..bf085af33f 100644 --- a/test/UnitTests/Internal/TypeHelper_Tests.cs +++ b/test/UnitTests/Internal/TypeHelper_Tests.cs @@ -26,7 +26,7 @@ public void Can_Convert_DateTimeOffsets() public void Bad_DateTimeOffset_String_Throws() { // Arrange - var formattedString = "this_is_not_a_valid_dto"; + const string formattedString = "this_is_not_a_valid_dto"; // Act // Assert @@ -37,7 +37,7 @@ public void Bad_DateTimeOffset_String_Throws() public void Can_Convert_Enums() { // Arrange - var formattedString = "1"; + const string formattedString = "1"; // Act var result = TypeHelper.ConvertType(formattedString, typeof(TestEnum)); @@ -123,10 +123,10 @@ public void Can_Convert_TimeSpans() } [Fact] - public void Bad_TimeSpanString_Throws() + public void Bad_TimeSpanString_Throws() { // Arrange - var formattedString = "this_is_not_a_valid_timespan"; + const string formattedString = "this_is_not_a_valid_timespan"; // Act/assert Assert.Throws(() => TypeHelper.ConvertType(formattedString, typeof(TimeSpan))); diff --git a/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs b/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs index f11f6b3f27..ab1fd806b5 100644 --- a/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs +++ b/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs @@ -18,7 +18,7 @@ public sealed class JsonApiMiddlewareTests public async Task ParseUrlBase_ObfuscatedIdClass_ShouldSetIdCorrectly() { // Arrange - var id = "ABC123ABC"; + const string id = "ABC123ABC"; var configuration = GetConfiguration($"/obfuscatedIdModel/{id}", action: "GetAsync", id: id); var request = configuration.Request; @@ -33,7 +33,7 @@ public async Task ParseUrlBase_ObfuscatedIdClass_ShouldSetIdCorrectly() public async Task ParseUrlBase_UrlHasPrimaryIdSet_ShouldSetupRequestWithSameId() { // Arrange - var id = "123"; + const string id = "123"; var configuration = GetConfiguration($"/users/{id}", id: id); var request = configuration.Request; @@ -96,7 +96,7 @@ private InvokeConfiguration GetConfiguration(string path, string resourceName = { return Task.Run(() => Console.WriteLine("finished")); }); - var forcedNamespace = "api/v1"; + const string forcedNamespace = "api/v1"; var mockMapping = new Mock(); mockMapping.Setup(x => x.GetResourceTypeForController(It.IsAny())).Returns(typeof(string)); diff --git a/test/UnitTests/Models/RelationshipDataTests.cs b/test/UnitTests/Models/RelationshipDataTests.cs index 4fc3d2f98c..0455c7ee82 100644 --- a/test/UnitTests/Models/RelationshipDataTests.cs +++ b/test/UnitTests/Models/RelationshipDataTests.cs @@ -34,7 +34,7 @@ public void Setting_ExposeData_To_JArray_Sets_ManyData() { // Arrange var relationshipData = new RelationshipEntry(); - var relationshipsJson = @"[ + const string relationshipsJson = @"[ { ""type"": ""authors"", ""id"": ""9"" @@ -78,7 +78,7 @@ public void Setting_ExposeData_To_JObject_Sets_SingleData() { // Arrange var relationshipData = new RelationshipEntry(); - var relationshipJson = @"{ + const string relationshipJson = @"{ ""id"": ""9"", ""type"": ""authors"" }"; diff --git a/test/UnitTests/Serialization/Client/RequestSerializerTests.cs b/test/UnitTests/Serialization/Client/RequestSerializerTests.cs index e5a2d696ce..461ed6ef51 100644 --- a/test/UnitTests/Serialization/Client/RequestSerializerTests.cs +++ b/test/UnitTests/Serialization/Client/RequestSerializerTests.cs @@ -28,8 +28,7 @@ public void SerializeSingle_ResourceWithDefaultTargetFields_CanBuild() string serialized = _serializer.Serialize(resource); // Assert - var expectedFormatted = - @"{ + const string expectedFormatted = @"{ ""data"":{ ""type"":""testResource"", ""id"":""1"", @@ -59,8 +58,7 @@ public void SerializeSingle_ResourceWithTargetedSetAttributes_CanBuild() string serialized = _serializer.Serialize(resource); // Assert - var expectedFormatted = - @"{ + const string expectedFormatted = @"{ ""data"":{ ""type"":""testResource"", ""id"":""1"", @@ -84,8 +82,7 @@ public void SerializeSingle_NoIdWithTargetedSetAttributes_CanBuild() string serialized = _serializer.Serialize(resourceNoId); // Assert - var expectedFormatted = - @"{ + const string expectedFormatted = @"{ ""data"":{ ""type"":""testResource"", ""attributes"":{ @@ -109,8 +106,7 @@ public void SerializeSingle_ResourceWithoutTargetedAttributes_CanBuild() string serialized = _serializer.Serialize(resource); // Assert - var expectedFormatted = - @"{ + const string expectedFormatted = @"{ ""data"":{ ""type"":""testResource"", ""id"":""1"" @@ -135,8 +131,7 @@ public void SerializeSingle_ResourceWithTargetedRelationships_CanBuild() // Act string serialized = _serializer.Serialize(resourceWithRelationships); // Assert - var expectedFormatted = - @"{ + const string expectedFormatted = @"{ ""data"":{ ""type"":""multiPrincipals"", ""attributes"":{ @@ -185,8 +180,7 @@ public void SerializeMany_ResourcesWithTargetedAttributes_CanBuild() string serialized = _serializer.Serialize(resources); // Assert - var expectedFormatted = - @"{ + const string expectedFormatted = @"{ ""data"":[ { ""type"":""testResource"", @@ -218,8 +212,7 @@ public void SerializeSingle_Null_CanBuild() string serialized = _serializer.Serialize((IIdentifiable) null); // Assert - var expectedFormatted = - @"{ + const string expectedFormatted = @"{ ""data"":null }"; var expected = Regex.Replace(expectedFormatted, @"\s+", ""); @@ -237,8 +230,7 @@ public void SerializeMany_EmptyList_CanBuild() string serialized = _serializer.Serialize(resources); // Assert - var expectedFormatted = - @"{ + const string expectedFormatted = @"{ ""data"":[] }"; var expected = Regex.Replace(expectedFormatted, @"\s+", ""); diff --git a/test/UnitTests/Serialization/Client/ResponseDeserializerTests.cs b/test/UnitTests/Serialization/Client/ResponseDeserializerTests.cs index bfe862d0ca..73a8423015 100644 --- a/test/UnitTests/Serialization/Client/ResponseDeserializerTests.cs +++ b/test/UnitTests/Serialization/Client/ResponseDeserializerTests.cs @@ -114,8 +114,8 @@ public void DeserializeSingle_MultipleDependentRelationshipsWithIncluded_CanDese content.SingleData.Relationships.Add("populatedToManies", CreateRelationshipData("oneToManyDependents", isToManyData: true)); content.SingleData.Relationships.Add("emptyToOne", CreateRelationshipData()); content.SingleData.Relationships.Add("emptyToManies", CreateRelationshipData(isToManyData: true)); - var toOneAttributeValue = "populatedToOne member content"; - var toManyAttributeValue = "populatedToManies member content"; + const string toOneAttributeValue = "populatedToOne member content"; + const string toManyAttributeValue = "populatedToManies member content"; content.Included = new List { new ResourceObject @@ -157,8 +157,8 @@ public void DeserializeSingle_MultiplePrincipalRelationshipsWithIncluded_CanDese content.SingleData.Relationships.Add("populatedToMany", CreateRelationshipData("oneToManyPrincipals")); content.SingleData.Relationships.Add("emptyToOne", CreateRelationshipData()); content.SingleData.Relationships.Add("emptyToMany", CreateRelationshipData()); - var toOneAttributeValue = "populatedToOne member content"; - var toManyAttributeValue = "populatedToManies member content"; + const string toOneAttributeValue = "populatedToOne member content"; + const string toManyAttributeValue = "populatedToManies member content"; content.Included = new List { new ResourceObject @@ -196,8 +196,8 @@ public void DeserializeSingle_NestedIncluded_CanDeserialize() // Arrange var content = CreateDocumentWithRelationships("multiPrincipals"); content.SingleData.Relationships.Add("populatedToManies", CreateRelationshipData("oneToManyDependents", isToManyData: true)); - var toManyAttributeValue = "populatedToManies member content"; - var nestedIncludeAttributeValue = "nested include member content"; + const string toManyAttributeValue = "populatedToManies member content"; + const string nestedIncludeAttributeValue = "nested include member content"; content.Included = new List { new ResourceObject @@ -238,9 +238,9 @@ public void DeserializeSingle_DeeplyNestedIncluded_CanDeserialize() // Arrange var content = CreateDocumentWithRelationships("multiPrincipals"); content.SingleData.Relationships.Add("multi", CreateRelationshipData("multiPrincipals")); - var includedAttributeValue = "multi member content"; - var nestedIncludedAttributeValue = "nested include member content"; - var deeplyNestedIncludedAttributeValue = "deeply nested member content"; + const string includedAttributeValue = "multi member content"; + const string nestedIncludedAttributeValue = "nested include member content"; + const string deeplyNestedIncludedAttributeValue = "deeply nested member content"; content.Included = new List { new ResourceObject @@ -289,9 +289,9 @@ public void DeserializeList_DeeplyNestedIncluded_CanDeserialize() // Arrange var content = new Document { Data = new List { CreateDocumentWithRelationships("multiPrincipals").SingleData } }; content.ManyData[0].Relationships.Add("multi", CreateRelationshipData("multiPrincipals")); - var includedAttributeValue = "multi member content"; - var nestedIncludedAttributeValue = "nested include member content"; - var deeplyNestedIncludedAttributeValue = "deeply nested member content"; + const string includedAttributeValue = "multi member content"; + const string nestedIncludedAttributeValue = "nested include member content"; + const string deeplyNestedIncludedAttributeValue = "deeply nested member content"; content.Included = new List { new ResourceObject diff --git a/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs b/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs index 74a642ec02..9bdce57c98 100644 --- a/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs +++ b/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs @@ -23,7 +23,7 @@ public void SerializeSingle_ResourceWithDefaultTargetFields_CanSerialize() string serialized = serializer.SerializeSingle(resource); // Assert - var expectedFormatted = @"{ + const string expectedFormatted = @"{ ""data"":{ ""type"":""testResource"", ""id"":""1"", @@ -55,7 +55,7 @@ public void SerializeMany_ResourceWithDefaultTargetFields_CanSerialize() string serialized = serializer.SerializeMany(new List { resource }); // Assert - var expectedFormatted = @"{ + const string expectedFormatted = @"{ ""data"":[{ ""type"":""testResource"", ""id"":""1"", @@ -92,7 +92,7 @@ public void SerializeSingle_ResourceWithIncludedRelationships_CanSerialize() string serialized = serializer.SerializeSingle(resource); // Assert - var expectedFormatted = @"{ + const string expectedFormatted = @"{ ""data"":{ ""type"":""multiPrincipals"", ""id"":""1"", @@ -166,7 +166,7 @@ public void SerializeSingle_ResourceWithDeeplyIncludedRelationships_CanSerialize string serialized = serializer.SerializeSingle(resource); // Assert - var expectedFormatted = @"{ + const string expectedFormatted = @"{ ""data"":{ ""type"":""multiPrincipals"", ""id"":""10"", @@ -236,7 +236,7 @@ public void SerializeSingle_Null_CanSerialize() string serialized = serializer.SerializeSingle(null); // Assert - var expectedFormatted = @"{ ""data"": null }"; + const string expectedFormatted = @"{ ""data"": null }"; var expected = Regex.Replace(expectedFormatted, @"\s+", ""); Assert.Equal(expected, serialized); } @@ -250,7 +250,7 @@ public void SerializeList_EmptyList_CanSerialize() string serialized = serializer.SerializeMany(new List()); // Assert - var expectedFormatted = @"{ ""data"": [] }"; + const string expectedFormatted = @"{ ""data"": [] }"; var expected = Regex.Replace(expectedFormatted, @"\s+", ""); Assert.Equal(expected, serialized); } @@ -266,7 +266,7 @@ public void SerializeSingle_ResourceWithLinksEnabled_CanSerialize() string serialized = serializer.SerializeSingle(resource); // Assert - var expectedFormatted = @"{ + const string expectedFormatted = @"{ ""links"":{ ""self"":""http://www.dummy.com/dummy-self-link"", ""first"":""http://www.dummy.com/dummy-first-link"", @@ -310,7 +310,7 @@ public void SerializeSingle_ResourceWithMeta_IncludesMetaInResult() string serialized = serializer.SerializeSingle(resource); // Assert - var expectedFormatted = @"{ + const string expectedFormatted = @"{ ""meta"":{ ""test"": ""meta"" }, ""data"":{ ""type"":""oneToManyPrincipals"", @@ -336,7 +336,7 @@ public void SerializeSingle_NullWithLinksAndMeta_StillShowsLinksAndMeta() string serialized = serializer.SerializeSingle(null); // Assert - var expectedFormatted = @"{ + const string expectedFormatted = @"{ ""meta"":{ ""test"": ""meta"" }, ""links"":{ ""self"":""http://www.dummy.com/dummy-self-link"", From 92eb963aa1affb177955bfc791af765c850d0d63 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Mon, 15 Feb 2021 12:18:35 +0100 Subject: [PATCH 05/60] Move types into matching files --- benchmarks/BenchmarkResource.cs | 12 - benchmarks/BenchmarkResourcePublicNames.cs | 8 + benchmarks/SubResource.cs | 11 + ...der.cs => JsonApiModelMetadataProvider.cs} | 0 .../Execution/IRelationshipsDictionary.cs | 15 +- .../Execution/RelationshipsDictionary.cs | 10 - ...tor.cs => PlaceholderResourceCollector.cs} | 0 .../Meta/AtomicResponseMeta.cs | 24 ++ .../Meta/AtomicResponseMetaTests.cs | 19 -- test/UnitTests/Graph/BaseType.cs | 4 + test/UnitTests/Graph/DerivedType.cs | 4 + test/UnitTests/Graph/IGenericInterface.cs | 4 + test/UnitTests/Graph/Implementation.cs | 4 + test/UnitTests/Graph/Model.cs | 6 + test/UnitTests/Graph/TypeLocator_Tests.cs | 9 - .../Models/ResourceConstructionTests.cs | 38 --- .../ResourceWithDbContextConstructor.cs | 18 ++ .../Models/ResourceWithStringConstructor.cs | 17 ++ .../Models/ResourceWithThrowingConstructor.cs | 13 + .../Models/ResourceWithoutConstructor.cs | 8 + test/UnitTests/ResourceHooks/Dummy.cs | 19 ++ .../UnitTests/ResourceHooks/HooksDummyData.cs | 128 ++++++++++ ...eHooksTestsSetup.cs => HooksTestsSetup.cs} | 233 +++++------------- test/UnitTests/ResourceHooks/NotTargeted.cs | 6 + .../RelationshipDictionaryTests.cs | 18 -- ....cs => BeforeDelete_WithDbValues_Tests.cs} | 0 ...narioTests.cs => SameResourceTypeTests.cs} | 0 test/UnitTests/ResourceHooks/ToMany.cs | 6 + test/UnitTests/ResourceHooks/ToOne.cs | 6 + ...erTests.cs => BaseDocumentBuilderTests.cs} | 0 ...serTests.cs => BaseDocumentParserTests.cs} | 0 test/UnitTests/TestModels.cs | 140 ----------- test/UnitTests/TestModels/Article.cs | 14 ++ test/UnitTests/TestModels/BaseModel.cs | 6 + test/UnitTests/TestModels/Blog.cs | 12 + test/UnitTests/TestModels/ComplexType.cs | 7 + .../UnitTests/TestModels/FirstDerivedModel.cs | 9 + test/UnitTests/TestModels/Food.cs | 10 + .../TestModels/IdentifiableWithAttribute.cs | 10 + .../MultipleRelationshipsDependentPart.cs | 16 ++ .../MultipleRelationshipsPrincipalPart.cs | 14 ++ .../TestModels/OneToManyDependent.cs | 10 + .../TestModels/OneToManyPrincipal.cs | 10 + .../TestModels/OneToManyRequiredDependent.cs | 10 + .../UnitTests/TestModels/OneToOneDependent.cs | 10 + .../UnitTests/TestModels/OneToOnePrincipal.cs | 9 + .../TestModels/OneToOneRequiredDependent.cs | 10 + test/UnitTests/TestModels/Person.cs | 14 ++ .../TestModels/SecondDerivedModel.cs | 9 + test/UnitTests/TestModels/Song.cs | 10 + test/UnitTests/TestModels/TestResource.cs | 18 ++ .../TestResourceWithAbstractRelationship.cs | 12 + .../TestModels/TestResourceWithList.cs | 11 + 53 files changed, 588 insertions(+), 423 deletions(-) create mode 100644 benchmarks/BenchmarkResourcePublicNames.cs create mode 100644 benchmarks/SubResource.cs rename src/JsonApiDotNetCore/Configuration/{JsonApiMetadataProvider.cs => JsonApiModelMetadataProvider.cs} (100%) rename src/JsonApiDotNetCore/Repositories/{PlaceholderEntityCollector.cs => PlaceholderResourceCollector.cs} (100%) create mode 100644 test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResponseMeta.cs create mode 100644 test/UnitTests/Graph/BaseType.cs create mode 100644 test/UnitTests/Graph/DerivedType.cs create mode 100644 test/UnitTests/Graph/IGenericInterface.cs create mode 100644 test/UnitTests/Graph/Implementation.cs create mode 100644 test/UnitTests/Graph/Model.cs create mode 100644 test/UnitTests/Models/ResourceWithDbContextConstructor.cs create mode 100644 test/UnitTests/Models/ResourceWithStringConstructor.cs create mode 100644 test/UnitTests/Models/ResourceWithThrowingConstructor.cs create mode 100644 test/UnitTests/Models/ResourceWithoutConstructor.cs create mode 100644 test/UnitTests/ResourceHooks/Dummy.cs create mode 100644 test/UnitTests/ResourceHooks/HooksDummyData.cs rename test/UnitTests/ResourceHooks/{ResourceHooksTestsSetup.cs => HooksTestsSetup.cs} (59%) create mode 100644 test/UnitTests/ResourceHooks/NotTargeted.cs rename test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/{BeforeDelete_WithDbValue_Tests.cs => BeforeDelete_WithDbValues_Tests.cs} (100%) rename test/UnitTests/ResourceHooks/ResourceHookExecutor/{ScenarioTests.cs => SameResourceTypeTests.cs} (100%) create mode 100644 test/UnitTests/ResourceHooks/ToMany.cs create mode 100644 test/UnitTests/ResourceHooks/ToOne.cs rename test/UnitTests/Serialization/Common/{DocumentBuilderTests.cs => BaseDocumentBuilderTests.cs} (100%) rename test/UnitTests/Serialization/Common/{DocumentParserTests.cs => BaseDocumentParserTests.cs} (100%) delete mode 100644 test/UnitTests/TestModels.cs create mode 100644 test/UnitTests/TestModels/Article.cs create mode 100644 test/UnitTests/TestModels/BaseModel.cs create mode 100644 test/UnitTests/TestModels/Blog.cs create mode 100644 test/UnitTests/TestModels/ComplexType.cs create mode 100644 test/UnitTests/TestModels/FirstDerivedModel.cs create mode 100644 test/UnitTests/TestModels/Food.cs create mode 100644 test/UnitTests/TestModels/IdentifiableWithAttribute.cs create mode 100644 test/UnitTests/TestModels/MultipleRelationshipsDependentPart.cs create mode 100644 test/UnitTests/TestModels/MultipleRelationshipsPrincipalPart.cs create mode 100644 test/UnitTests/TestModels/OneToManyDependent.cs create mode 100644 test/UnitTests/TestModels/OneToManyPrincipal.cs create mode 100644 test/UnitTests/TestModels/OneToManyRequiredDependent.cs create mode 100644 test/UnitTests/TestModels/OneToOneDependent.cs create mode 100644 test/UnitTests/TestModels/OneToOnePrincipal.cs create mode 100644 test/UnitTests/TestModels/OneToOneRequiredDependent.cs create mode 100644 test/UnitTests/TestModels/Person.cs create mode 100644 test/UnitTests/TestModels/SecondDerivedModel.cs create mode 100644 test/UnitTests/TestModels/Song.cs create mode 100644 test/UnitTests/TestModels/TestResource.cs create mode 100644 test/UnitTests/TestModels/TestResourceWithAbstractRelationship.cs create mode 100644 test/UnitTests/TestModels/TestResourceWithList.cs diff --git a/benchmarks/BenchmarkResource.cs b/benchmarks/BenchmarkResource.cs index 0353078601..a79ede4675 100644 --- a/benchmarks/BenchmarkResource.cs +++ b/benchmarks/BenchmarkResource.cs @@ -11,16 +11,4 @@ public sealed class BenchmarkResource : Identifiable [HasOne] public SubResource Child { get; set; } } - - public class SubResource : Identifiable - { - [Attr] - public string Value { get; set; } - } - - internal static class BenchmarkResourcePublicNames - { - public const string NameAttr = "full-name"; - public const string Type = "simple-types"; - } } diff --git a/benchmarks/BenchmarkResourcePublicNames.cs b/benchmarks/BenchmarkResourcePublicNames.cs new file mode 100644 index 0000000000..b97db1ea64 --- /dev/null +++ b/benchmarks/BenchmarkResourcePublicNames.cs @@ -0,0 +1,8 @@ +namespace Benchmarks +{ + internal static class BenchmarkResourcePublicNames + { + public const string NameAttr = "full-name"; + public const string Type = "simple-types"; + } +} \ No newline at end of file diff --git a/benchmarks/SubResource.cs b/benchmarks/SubResource.cs new file mode 100644 index 0000000000..71c59b6785 --- /dev/null +++ b/benchmarks/SubResource.cs @@ -0,0 +1,11 @@ +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + +namespace Benchmarks +{ + public class SubResource : Identifiable + { + [Attr] + public string Value { get; set; } + } +} \ No newline at end of file diff --git a/src/JsonApiDotNetCore/Configuration/JsonApiMetadataProvider.cs b/src/JsonApiDotNetCore/Configuration/JsonApiModelMetadataProvider.cs similarity index 100% rename from src/JsonApiDotNetCore/Configuration/JsonApiMetadataProvider.cs rename to src/JsonApiDotNetCore/Configuration/JsonApiModelMetadataProvider.cs diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/IRelationshipsDictionary.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/IRelationshipsDictionary.cs index 1ddd5cbc36..8de79a01ed 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/IRelationshipsDictionary.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/IRelationshipsDictionary.cs @@ -1,7 +1,20 @@ +using System.Collections.Generic; +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + namespace JsonApiDotNetCore.Hooks.Internal.Execution { /// /// A dummy interface used internally by the hook executor. /// public interface IRelationshipsDictionary { } -} \ No newline at end of file + + /// + /// A helper class that provides insights in which relationships have been updated for which resources. + /// + public interface IRelationshipsDictionary : + IRelationshipGetters, + IReadOnlyDictionary>, + IRelationshipsDictionary where TRightResource : class, IIdentifiable + { } +} diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/RelationshipsDictionary.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/RelationshipsDictionary.cs index f624b93aad..9c24206530 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/RelationshipsDictionary.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/RelationshipsDictionary.cs @@ -8,16 +8,6 @@ namespace JsonApiDotNetCore.Hooks.Internal.Execution { - /// - /// A helper class that provides insights in which relationships have been updated for which resources. - /// - public interface IRelationshipsDictionary : - IRelationshipGetters, - IReadOnlyDictionary>, - IRelationshipsDictionary where TRightResource : class, IIdentifiable - { } - - /// /// Implementation of IAffectedRelationships{TRightResource} /// diff --git a/src/JsonApiDotNetCore/Repositories/PlaceholderEntityCollector.cs b/src/JsonApiDotNetCore/Repositories/PlaceholderResourceCollector.cs similarity index 100% rename from src/JsonApiDotNetCore/Repositories/PlaceholderEntityCollector.cs rename to src/JsonApiDotNetCore/Repositories/PlaceholderResourceCollector.cs diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResponseMeta.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResponseMeta.cs new file mode 100644 index 0000000000..65f95ff844 --- /dev/null +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResponseMeta.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using JsonApiDotNetCore.Serialization; + +namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.Meta +{ + public sealed class AtomicResponseMeta : IResponseMeta + { + public IReadOnlyDictionary GetMeta() + { + return new Dictionary + { + ["license"] = "MIT", + ["projectUrl"] = "https://github.com/json-api-dotnet/JsonApiDotNetCore/", + ["versions"] = new[] + { + "v4.0.0", + "v3.1.0", + "v2.5.2", + "v1.3.1" + } + }; + } + } +} \ No newline at end of file diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResponseMetaTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResponseMetaTests.cs index 1ecdfd8602..bb6d147bcc 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResponseMetaTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResponseMetaTests.cs @@ -126,23 +126,4 @@ await _testContext.RunOnDatabaseAsync(async dbContext => versionArray.Should().Contain("v1.3.1"); } } - - public sealed class AtomicResponseMeta : IResponseMeta - { - public IReadOnlyDictionary GetMeta() - { - return new Dictionary - { - ["license"] = "MIT", - ["projectUrl"] = "https://github.com/json-api-dotnet/JsonApiDotNetCore/", - ["versions"] = new[] - { - "v4.0.0", - "v3.1.0", - "v2.5.2", - "v1.3.1" - } - }; - } - } } diff --git a/test/UnitTests/Graph/BaseType.cs b/test/UnitTests/Graph/BaseType.cs new file mode 100644 index 0000000000..e32f521640 --- /dev/null +++ b/test/UnitTests/Graph/BaseType.cs @@ -0,0 +1,4 @@ +namespace UnitTests.Internal +{ + public class BaseType { } +} \ No newline at end of file diff --git a/test/UnitTests/Graph/DerivedType.cs b/test/UnitTests/Graph/DerivedType.cs new file mode 100644 index 0000000000..2250cd9383 --- /dev/null +++ b/test/UnitTests/Graph/DerivedType.cs @@ -0,0 +1,4 @@ +namespace UnitTests.Internal +{ + public sealed class DerivedType : BaseType { } +} \ No newline at end of file diff --git a/test/UnitTests/Graph/IGenericInterface.cs b/test/UnitTests/Graph/IGenericInterface.cs new file mode 100644 index 0000000000..012eec6875 --- /dev/null +++ b/test/UnitTests/Graph/IGenericInterface.cs @@ -0,0 +1,4 @@ +namespace UnitTests.Internal +{ + public interface IGenericInterface { } +} \ No newline at end of file diff --git a/test/UnitTests/Graph/Implementation.cs b/test/UnitTests/Graph/Implementation.cs new file mode 100644 index 0000000000..3bb36176a8 --- /dev/null +++ b/test/UnitTests/Graph/Implementation.cs @@ -0,0 +1,4 @@ +namespace UnitTests.Internal +{ + public sealed class Implementation : IGenericInterface { } +} \ No newline at end of file diff --git a/test/UnitTests/Graph/Model.cs b/test/UnitTests/Graph/Model.cs new file mode 100644 index 0000000000..eef1ed91a7 --- /dev/null +++ b/test/UnitTests/Graph/Model.cs @@ -0,0 +1,6 @@ +using JsonApiDotNetCore.Resources; + +namespace UnitTests.Internal +{ + public sealed class Model : Identifiable { } +} \ No newline at end of file diff --git a/test/UnitTests/Graph/TypeLocator_Tests.cs b/test/UnitTests/Graph/TypeLocator_Tests.cs index a5f5aa1803..497427e863 100644 --- a/test/UnitTests/Graph/TypeLocator_Tests.cs +++ b/test/UnitTests/Graph/TypeLocator_Tests.cs @@ -1,6 +1,5 @@ using System; using JsonApiDotNetCore.Configuration; -using JsonApiDotNetCore.Resources; using Xunit; namespace UnitTests.Internal @@ -108,12 +107,4 @@ public void TryGetResourceDescriptor_Returns_False_If_Type_Is_IIdentifiable() Assert.Null(descriptor); } } - - public interface IGenericInterface { } - public sealed class Implementation : IGenericInterface { } - - public class BaseType { } - public sealed class DerivedType : BaseType { } - - public sealed class Model : Identifiable { } } diff --git a/test/UnitTests/Models/ResourceConstructionTests.cs b/test/UnitTests/Models/ResourceConstructionTests.cs index 59af406378..89c94df18c 100644 --- a/test/UnitTests/Models/ResourceConstructionTests.cs +++ b/test/UnitTests/Models/ResourceConstructionTests.cs @@ -1,11 +1,9 @@ using System; using System.ComponentModel.Design; -using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Serialization; -using JsonApiDotNetCoreExample.Data; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging.Abstractions; using Moq; @@ -124,40 +122,4 @@ public void When_resource_has_constructor_with_string_parameter_it_must_fail() exception.Message); } } - - public class ResourceWithoutConstructor : Identifiable - { - } - - public class ResourceWithDbContextConstructor : Identifiable - { - public AppDbContext AppDbContext { get; } - - public ResourceWithDbContextConstructor(AppDbContext appDbContext) - { - ArgumentGuard.NotNull(appDbContext, nameof(appDbContext)); - - AppDbContext = appDbContext; - } - } - - public class ResourceWithThrowingConstructor : Identifiable - { - public ResourceWithThrowingConstructor() - { - throw new ArgumentException("Failed to initialize."); - } - } - - public class ResourceWithStringConstructor : Identifiable - { - public string Text { get; } - - public ResourceWithStringConstructor(string text) - { - ArgumentGuard.NotNull(text, nameof(text)); - - Text = text; - } - } } diff --git a/test/UnitTests/Models/ResourceWithDbContextConstructor.cs b/test/UnitTests/Models/ResourceWithDbContextConstructor.cs new file mode 100644 index 0000000000..94e81d6f62 --- /dev/null +++ b/test/UnitTests/Models/ResourceWithDbContextConstructor.cs @@ -0,0 +1,18 @@ +using JsonApiDotNetCore; +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCoreExample.Data; + +namespace UnitTests.Models +{ + public class ResourceWithDbContextConstructor : Identifiable + { + public AppDbContext AppDbContext { get; } + + public ResourceWithDbContextConstructor(AppDbContext appDbContext) + { + ArgumentGuard.NotNull(appDbContext, nameof(appDbContext)); + + AppDbContext = appDbContext; + } + } +} \ No newline at end of file diff --git a/test/UnitTests/Models/ResourceWithStringConstructor.cs b/test/UnitTests/Models/ResourceWithStringConstructor.cs new file mode 100644 index 0000000000..ce17fc1db3 --- /dev/null +++ b/test/UnitTests/Models/ResourceWithStringConstructor.cs @@ -0,0 +1,17 @@ +using JsonApiDotNetCore; +using JsonApiDotNetCore.Resources; + +namespace UnitTests.Models +{ + public class ResourceWithStringConstructor : Identifiable + { + public string Text { get; } + + public ResourceWithStringConstructor(string text) + { + ArgumentGuard.NotNull(text, nameof(text)); + + Text = text; + } + } +} \ No newline at end of file diff --git a/test/UnitTests/Models/ResourceWithThrowingConstructor.cs b/test/UnitTests/Models/ResourceWithThrowingConstructor.cs new file mode 100644 index 0000000000..634b9ca5cd --- /dev/null +++ b/test/UnitTests/Models/ResourceWithThrowingConstructor.cs @@ -0,0 +1,13 @@ +using System; +using JsonApiDotNetCore.Resources; + +namespace UnitTests.Models +{ + public class ResourceWithThrowingConstructor : Identifiable + { + public ResourceWithThrowingConstructor() + { + throw new ArgumentException("Failed to initialize."); + } + } +} \ No newline at end of file diff --git a/test/UnitTests/Models/ResourceWithoutConstructor.cs b/test/UnitTests/Models/ResourceWithoutConstructor.cs new file mode 100644 index 0000000000..266f99ef1c --- /dev/null +++ b/test/UnitTests/Models/ResourceWithoutConstructor.cs @@ -0,0 +1,8 @@ +using JsonApiDotNetCore.Resources; + +namespace UnitTests.Models +{ + public class ResourceWithoutConstructor : Identifiable + { + } +} \ No newline at end of file diff --git a/test/UnitTests/ResourceHooks/Dummy.cs b/test/UnitTests/ResourceHooks/Dummy.cs new file mode 100644 index 0000000000..9d84c065ab --- /dev/null +++ b/test/UnitTests/ResourceHooks/Dummy.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.ResourceHooks +{ + public sealed class Dummy : Identifiable + { + public string SomeUpdatedProperty { get; set; } + public string SomeNotUpdatedProperty { get; set; } + + [HasOne] + public ToOne FirstToOne { get; set; } + [HasOne] + public ToOne SecondToOne { get; set; } + [HasMany] + public ISet ToManies { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/ResourceHooks/HooksDummyData.cs b/test/UnitTests/ResourceHooks/HooksDummyData.cs new file mode 100644 index 0000000000..6cea49728a --- /dev/null +++ b/test/UnitTests/ResourceHooks/HooksDummyData.cs @@ -0,0 +1,128 @@ +using System.Collections.Generic; +using System.Linq; +using Bogus; +using JsonApiDotNetCore.Configuration; +using JsonApiDotNetCore.Hooks.Internal.Execution; +using JsonApiDotNetCoreExample.Models; +using Microsoft.Extensions.Logging.Abstractions; +using Person = JsonApiDotNetCoreExample.Models.Person; + +namespace UnitTests.ResourceHooks +{ + public class HooksDummyData + { + protected IResourceGraph _resourceGraph; + protected ResourceHook[] NoHooks = new ResourceHook[0]; + protected ResourceHook[] EnableDbValues = { ResourceHook.BeforeUpdate, ResourceHook.BeforeUpdateRelationship }; + protected ResourceHook[] DisableDbValues = new ResourceHook[0]; + protected readonly Faker _personFaker; + protected readonly Faker _todoFaker; + protected readonly Faker _tagFaker; + protected readonly Faker
_articleFaker; + protected readonly Faker _articleTagFaker; + protected readonly Faker _identifiableArticleTagFaker; + protected readonly Faker _passportFaker; + + public HooksDummyData() + { + _resourceGraph = new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance) + .Add() + .Add() + .Add() + .Add
() + .Add() + .Add() + .Build(); + + _todoFaker = new Faker().Rules((f, i) => i.Id = f.UniqueIndex + 1); + _personFaker = new Faker().Rules((f, i) => i.Id = f.UniqueIndex + 1); + + _articleFaker = new Faker
().Rules((f, i) => i.Id = f.UniqueIndex + 1); + _articleTagFaker = new Faker(); + _identifiableArticleTagFaker = new Faker().Rules((f, i) => i.Id = f.UniqueIndex + 1); + _tagFaker = new Faker() + .Rules((f, i) => i.Id = f.UniqueIndex + 1); + + _passportFaker = new Faker() + .Rules((f, i) => i.Id = f.UniqueIndex + 1); + } + + protected List CreateTodoWithToOnePerson() + { + var todoItem = _todoFaker.Generate(); + var person = _personFaker.Generate(); + var todoList = new List { todoItem }; + person.OneToOneTodoItem = todoItem; + todoItem.OneToOnePerson = person; + return todoList; + } + + protected HashSet CreateTodoWithOwner() + { + var todoItem = _todoFaker.Generate(); + var person = _personFaker.Generate(); + var todoList = new HashSet { todoItem }; + person.AssignedTodoItems = todoList; + todoItem.Owner = person; + return todoList; + } + + protected (List
, List, List) CreateManyToManyData() + { + var tagsSubset = _tagFaker.Generate(3); + var joinsSubSet = _articleTagFaker.Generate(3); + var articleTagsSubset = _articleFaker.Generate(); + articleTagsSubset.ArticleTags = joinsSubSet.ToHashSet(); + for (int i = 0; i < 3; i++) + { + joinsSubSet[i].Article = articleTagsSubset; + joinsSubSet[i].Tag = tagsSubset[i]; + } + + var allTags = _tagFaker.Generate(3).Concat(tagsSubset).ToList(); + var completeJoin = _articleTagFaker.Generate(6); + + var articleWithAllTags = _articleFaker.Generate(); + articleWithAllTags.ArticleTags = completeJoin.ToHashSet(); + + for (int i = 0; i < 6; i++) + { + completeJoin[i].Article = articleWithAllTags; + completeJoin[i].Tag = allTags[i]; + } + + var allJoins = joinsSubSet.Concat(completeJoin).ToList(); + + var articles = new List
{ articleTagsSubset, articleWithAllTags }; + return (articles, allJoins, allTags); + } + + protected (List
, List, List) CreateIdentifiableManyToManyData() + { + var tagsSubset = _tagFaker.Generate(3); + var joinsSubSet = _identifiableArticleTagFaker.Generate(3); + var articleTagsSubset = _articleFaker.Generate(); + articleTagsSubset.IdentifiableArticleTags = joinsSubSet.ToHashSet(); + for (int i = 0; i < 3; i++) + { + joinsSubSet[i].Article = articleTagsSubset; + joinsSubSet[i].Tag = tagsSubset[i]; + } + var allTags = _tagFaker.Generate(3).Concat(tagsSubset).ToList(); + var completeJoin = _identifiableArticleTagFaker.Generate(6); + + var articleWithAllTags = _articleFaker.Generate(); + articleWithAllTags.IdentifiableArticleTags = joinsSubSet.ToHashSet(); + + for (int i = 0; i < 6; i++) + { + completeJoin[i].Article = articleWithAllTags; + completeJoin[i].Tag = allTags[i]; + } + + var allJoins = joinsSubSet.Concat(completeJoin).ToList(); + var articles = new List
{ articleTagsSubset, articleWithAllTags }; + return (articles, allJoins, allTags); + } + } +} diff --git a/test/UnitTests/ResourceHooks/ResourceHooksTestsSetup.cs b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs similarity index 59% rename from test/UnitTests/ResourceHooks/ResourceHooksTestsSetup.cs rename to test/UnitTests/ResourceHooks/HooksTestsSetup.cs index ffe2e24497..9f02ec4c81 100644 --- a/test/UnitTests/ResourceHooks/ResourceHooksTestsSetup.cs +++ b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Bogus; using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Hooks.Internal; @@ -19,127 +18,9 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.Logging.Abstractions; using Moq; -using Person = JsonApiDotNetCoreExample.Models.Person; namespace UnitTests.ResourceHooks { - public class HooksDummyData - { - protected IResourceGraph _resourceGraph; - protected ResourceHook[] NoHooks = new ResourceHook[0]; - protected ResourceHook[] EnableDbValues = { ResourceHook.BeforeUpdate, ResourceHook.BeforeUpdateRelationship }; - protected ResourceHook[] DisableDbValues = new ResourceHook[0]; - protected readonly Faker _personFaker; - protected readonly Faker _todoFaker; - protected readonly Faker _tagFaker; - protected readonly Faker
_articleFaker; - protected readonly Faker _articleTagFaker; - protected readonly Faker _identifiableArticleTagFaker; - protected readonly Faker _passportFaker; - - public HooksDummyData() - { - _resourceGraph = new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance) - .Add() - .Add() - .Add() - .Add
() - .Add() - .Add() - .Build(); - - _todoFaker = new Faker().Rules((f, i) => i.Id = f.UniqueIndex + 1); - _personFaker = new Faker().Rules((f, i) => i.Id = f.UniqueIndex + 1); - - _articleFaker = new Faker
().Rules((f, i) => i.Id = f.UniqueIndex + 1); - _articleTagFaker = new Faker(); - _identifiableArticleTagFaker = new Faker().Rules((f, i) => i.Id = f.UniqueIndex + 1); - _tagFaker = new Faker() - .Rules((f, i) => i.Id = f.UniqueIndex + 1); - - _passportFaker = new Faker() - .Rules((f, i) => i.Id = f.UniqueIndex + 1); - } - - protected List CreateTodoWithToOnePerson() - { - var todoItem = _todoFaker.Generate(); - var person = _personFaker.Generate(); - var todoList = new List { todoItem }; - person.OneToOneTodoItem = todoItem; - todoItem.OneToOnePerson = person; - return todoList; - } - - protected HashSet CreateTodoWithOwner() - { - var todoItem = _todoFaker.Generate(); - var person = _personFaker.Generate(); - var todoList = new HashSet { todoItem }; - person.AssignedTodoItems = todoList; - todoItem.Owner = person; - return todoList; - } - - protected (List
, List, List) CreateManyToManyData() - { - var tagsSubset = _tagFaker.Generate(3); - var joinsSubSet = _articleTagFaker.Generate(3); - var articleTagsSubset = _articleFaker.Generate(); - articleTagsSubset.ArticleTags = joinsSubSet.ToHashSet(); - for (int i = 0; i < 3; i++) - { - joinsSubSet[i].Article = articleTagsSubset; - joinsSubSet[i].Tag = tagsSubset[i]; - } - - var allTags = _tagFaker.Generate(3).Concat(tagsSubset).ToList(); - var completeJoin = _articleTagFaker.Generate(6); - - var articleWithAllTags = _articleFaker.Generate(); - articleWithAllTags.ArticleTags = completeJoin.ToHashSet(); - - for (int i = 0; i < 6; i++) - { - completeJoin[i].Article = articleWithAllTags; - completeJoin[i].Tag = allTags[i]; - } - - var allJoins = joinsSubSet.Concat(completeJoin).ToList(); - - var articles = new List
{ articleTagsSubset, articleWithAllTags }; - return (articles, allJoins, allTags); - } - - protected (List
, List, List) CreateIdentifiableManyToManyData() - { - var tagsSubset = _tagFaker.Generate(3); - var joinsSubSet = _identifiableArticleTagFaker.Generate(3); - var articleTagsSubset = _articleFaker.Generate(); - articleTagsSubset.IdentifiableArticleTags = joinsSubSet.ToHashSet(); - for (int i = 0; i < 3; i++) - { - joinsSubSet[i].Article = articleTagsSubset; - joinsSubSet[i].Tag = tagsSubset[i]; - } - var allTags = _tagFaker.Generate(3).Concat(tagsSubset).ToList(); - var completeJoin = _identifiableArticleTagFaker.Generate(6); - - var articleWithAllTags = _articleFaker.Generate(); - articleWithAllTags.IdentifiableArticleTags = joinsSubSet.ToHashSet(); - - for (int i = 0; i < 6; i++) - { - completeJoin[i].Article = articleWithAllTags; - completeJoin[i].Tag = allTags[i]; - } - - var allJoins = joinsSubSet.Concat(completeJoin).ToList(); - var articles = new List
{ articleTagsSubset, articleWithAllTags }; - return (articles, allJoins, allTags); - } - } - public class HooksTestsSetup : HooksDummyData { private (Mock, Mock>, Mock, IJsonApiOptions) CreateMocks() @@ -173,11 +54,11 @@ public class HooksTestsSetup : HooksDummyData } protected (Mock>, Mock, IResourceHookExecutor, Mock>, Mock>) - CreateTestObjects( - IHooksDiscovery primaryDiscovery = null, - IHooksDiscovery secondaryDiscovery = null, - DbContextOptions repoDbContextOptions = null - ) + CreateTestObjects( + IHooksDiscovery primaryDiscovery = null, + IHooksDiscovery secondaryDiscovery = null, + DbContextOptions repoDbContextOptions = null + ) where TPrimary : class, IIdentifiable where TSecondary : class, IIdentifiable { @@ -206,15 +87,15 @@ public class HooksTestsSetup : HooksDummyData } protected (Mock>, IResourceHookExecutor, Mock>, Mock>, Mock>) - CreateTestObjects( - IHooksDiscovery primaryDiscovery = null, - IHooksDiscovery firstSecondaryDiscovery = null, - IHooksDiscovery secondSecondaryDiscovery = null, - DbContextOptions repoDbContextOptions = null - ) - where TPrimary : class, IIdentifiable - where TFirstSecondary : class, IIdentifiable - where TSecondSecondary : class, IIdentifiable + CreateTestObjects( + IHooksDiscovery primaryDiscovery = null, + IHooksDiscovery firstSecondaryDiscovery = null, + IHooksDiscovery secondSecondaryDiscovery = null, + DbContextOptions repoDbContextOptions = null + ) + where TPrimary : class, IIdentifiable + where TFirstSecondary : class, IIdentifiable + where TSecondSecondary : class, IIdentifiable { // creates the resource definition mock and corresponding for a given set of discoverable hooks var primaryResource = CreateResourceDefinition(primaryDiscovery); @@ -244,19 +125,19 @@ public class HooksTestsSetup : HooksDummyData } protected IHooksDiscovery SetDiscoverableHooks(ResourceHook[] implementedHooks, params ResourceHook[] enableDbValuesHooks) - where TResource : class, IIdentifiable + where TResource : class, IIdentifiable { var mock = new Mock>(); mock.Setup(discovery => discovery.ImplementedHooks) - .Returns(implementedHooks); + .Returns(implementedHooks); if (!enableDbValuesHooks.Any()) { mock.Setup(discovery => discovery.DatabaseValuesDisabledHooks) - .Returns(enableDbValuesHooks); + .Returns(enableDbValuesHooks); } mock.Setup(discovery => discovery.DatabaseValuesEnabledHooks) - .Returns(new[] { ResourceHook.BeforeImplicitUpdateRelationship }.Concat(enableDbValuesHooks).ToArray()); + .Returns(new[] { ResourceHook.BeforeImplicitUpdateRelationship }.Concat(enableDbValuesHooks).ToArray()); return mock.Object; } @@ -286,59 +167,59 @@ protected DbContextOptions InitInMemoryDb(Action seeder private void MockHooks(Mock> resourceDefinition) where TModel : class, IIdentifiable { resourceDefinition - .Setup(rd => rd.BeforeCreate(It.IsAny>(), It.IsAny())) - .Returns, ResourcePipeline>((resources, context) => resources) - .Verifiable(); + .Setup(rd => rd.BeforeCreate(It.IsAny>(), It.IsAny())) + .Returns, ResourcePipeline>((resources, context) => resources) + .Verifiable(); resourceDefinition - .Setup(rd => rd.BeforeRead(It.IsAny(), It.IsAny(), It.IsAny())) - .Verifiable(); + .Setup(rd => rd.BeforeRead(It.IsAny(), It.IsAny(), It.IsAny())) + .Verifiable(); resourceDefinition - .Setup(rd => rd.BeforeUpdate(It.IsAny>(), It.IsAny())) - .Returns, ResourcePipeline>((resources, context) => resources) - .Verifiable(); + .Setup(rd => rd.BeforeUpdate(It.IsAny>(), It.IsAny())) + .Returns, ResourcePipeline>((resources, context) => resources) + .Verifiable(); resourceDefinition - .Setup(rd => rd.BeforeDelete(It.IsAny>(), It.IsAny())) - .Returns, ResourcePipeline>((resources, context) => resources) - .Verifiable(); + .Setup(rd => rd.BeforeDelete(It.IsAny>(), It.IsAny())) + .Returns, ResourcePipeline>((resources, context) => resources) + .Verifiable(); resourceDefinition - .Setup(rd => rd.BeforeUpdateRelationship(It.IsAny>(), It.IsAny>(), It.IsAny())) - .Returns, IRelationshipsDictionary, ResourcePipeline>((ids, context, helper) => ids) - .Verifiable(); + .Setup(rd => rd.BeforeUpdateRelationship(It.IsAny>(), It.IsAny>(), It.IsAny())) + .Returns, IRelationshipsDictionary, ResourcePipeline>((ids, context, helper) => ids) + .Verifiable(); resourceDefinition - .Setup(rd => rd.BeforeImplicitUpdateRelationship(It.IsAny>(), It.IsAny())) - .Verifiable(); + .Setup(rd => rd.BeforeImplicitUpdateRelationship(It.IsAny>(), It.IsAny())) + .Verifiable(); resourceDefinition - .Setup(rd => rd.OnReturn(It.IsAny>(), It.IsAny())) - .Returns, ResourcePipeline>((resources, context) => resources) - .Verifiable(); + .Setup(rd => rd.OnReturn(It.IsAny>(), It.IsAny())) + .Returns, ResourcePipeline>((resources, context) => resources) + .Verifiable(); resourceDefinition - .Setup(rd => rd.AfterCreate(It.IsAny>(), It.IsAny())) - .Verifiable(); + .Setup(rd => rd.AfterCreate(It.IsAny>(), It.IsAny())) + .Verifiable(); resourceDefinition - .Setup(rd => rd.AfterRead(It.IsAny>(), It.IsAny(), It.IsAny())) - .Verifiable(); + .Setup(rd => rd.AfterRead(It.IsAny>(), It.IsAny(), It.IsAny())) + .Verifiable(); resourceDefinition - .Setup(rd => rd.AfterUpdate(It.IsAny>(), It.IsAny())) - .Verifiable(); + .Setup(rd => rd.AfterUpdate(It.IsAny>(), It.IsAny())) + .Verifiable(); resourceDefinition - .Setup(rd => rd.AfterDelete(It.IsAny>(), It.IsAny(), It.IsAny())) - .Verifiable(); + .Setup(rd => rd.AfterDelete(It.IsAny>(), It.IsAny(), It.IsAny())) + .Verifiable(); } private void SetupProcessorFactoryForResourceDefinition( - Mock processorFactory, - IResourceHookContainer modelResource, - IHooksDiscovery discovery, - AppDbContext dbContext = null, - IResourceGraph resourceGraph = null + Mock processorFactory, + IResourceHookContainer modelResource, + IHooksDiscovery discovery, + AppDbContext dbContext = null, + IResourceGraph resourceGraph = null ) - where TModel : class, IIdentifiable + where TModel : class, IIdentifiable { processorFactory.Setup(c => c.Get(typeof(ResourceHooksDefinition<>), typeof(TModel))) - .Returns(modelResource); + .Returns(modelResource); processorFactory.Setup(c => c.Get(typeof(IHooksDiscovery<>), typeof(TModel))) - .Returns(discovery); + .Returns(discovery); if (dbContext != null) { @@ -383,9 +264,9 @@ private void ResolveInverseRelationships(AppDbContext context) } private Mock> CreateResourceDefinition - (IHooksDiscovery discovery - ) - where TModel : class, IIdentifiable + (IHooksDiscovery discovery + ) + where TModel : class, IIdentifiable { var resourceDefinition = new Mock>(); MockHooks(resourceDefinition); @@ -437,4 +318,4 @@ protected IEnumerable ConvertInclusionChains(List ToManies { get; set; } - } - - public class NotTargeted : Identifiable { } - public sealed class ToMany : Identifiable { } - public sealed class ToOne : Identifiable { } - public sealed class RelationshipDictionaryTests { public readonly HasOneAttribute FirstToOneAttr; diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/BeforeDelete_WithDbValue_Tests.cs b/test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/BeforeDelete_WithDbValues_Tests.cs similarity index 100% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/BeforeDelete_WithDbValue_Tests.cs rename to test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/BeforeDelete_WithDbValues_Tests.cs diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/ScenarioTests.cs b/test/UnitTests/ResourceHooks/ResourceHookExecutor/SameResourceTypeTests.cs similarity index 100% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/ScenarioTests.cs rename to test/UnitTests/ResourceHooks/ResourceHookExecutor/SameResourceTypeTests.cs diff --git a/test/UnitTests/ResourceHooks/ToMany.cs b/test/UnitTests/ResourceHooks/ToMany.cs new file mode 100644 index 0000000000..b77442f911 --- /dev/null +++ b/test/UnitTests/ResourceHooks/ToMany.cs @@ -0,0 +1,6 @@ +using JsonApiDotNetCore.Resources; + +namespace UnitTests.ResourceHooks +{ + public sealed class ToMany : Identifiable { } +} \ No newline at end of file diff --git a/test/UnitTests/ResourceHooks/ToOne.cs b/test/UnitTests/ResourceHooks/ToOne.cs new file mode 100644 index 0000000000..06f085aa4b --- /dev/null +++ b/test/UnitTests/ResourceHooks/ToOne.cs @@ -0,0 +1,6 @@ +using JsonApiDotNetCore.Resources; + +namespace UnitTests.ResourceHooks +{ + public sealed class ToOne : Identifiable { } +} \ No newline at end of file diff --git a/test/UnitTests/Serialization/Common/DocumentBuilderTests.cs b/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs similarity index 100% rename from test/UnitTests/Serialization/Common/DocumentBuilderTests.cs rename to test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs diff --git a/test/UnitTests/Serialization/Common/DocumentParserTests.cs b/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs similarity index 100% rename from test/UnitTests/Serialization/Common/DocumentParserTests.cs rename to test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs diff --git a/test/UnitTests/TestModels.cs b/test/UnitTests/TestModels.cs deleted file mode 100644 index 54d23e8458..0000000000 --- a/test/UnitTests/TestModels.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.Collections.Generic; -using JsonApiDotNetCore.Resources; -using JsonApiDotNetCore.Resources.Annotations; - -namespace UnitTests.TestModels -{ - public sealed class TestResource : Identifiable - { - [Attr] public string StringField { get; set; } - [Attr] public DateTime DateTimeField { get; set; } - [Attr] public DateTime? NullableDateTimeField { get; set; } - [Attr] public int IntField { get; set; } - [Attr] public int? NullableIntField { get; set; } - [Attr] public Guid GuidField { get; set; } - [Attr] public ComplexType ComplexField { get; set; } - - } - - public class TestResourceWithList : Identifiable - { - [Attr] public List ComplexFields { get; set; } - } - - public class ComplexType - { - public string CompoundName { get; set; } - } - - public class TestResourceWithAbstractRelationship : Identifiable - { - [HasOne] public BaseModel ToOne { get; set; } - [HasMany] public List ToMany { get; set; } - } - - public abstract class BaseModel : Identifiable { } - - public class FirstDerivedModel : BaseModel - { - [Attr] public bool FirstProperty { get; set; } - } - public class SecondDerivedModel : BaseModel - { - [Attr] public bool SecondProperty { get; set; } - } - - public sealed class OneToOnePrincipal : IdentifiableWithAttribute - { - [HasOne] public OneToOneDependent Dependent { get; set; } - } - - public sealed class OneToOneDependent : IdentifiableWithAttribute - { - [HasOne] public OneToOnePrincipal Principal { get; set; } - public int? PrincipalId { get; set; } - } - - public sealed class OneToOneRequiredDependent : IdentifiableWithAttribute - { - [HasOne] public OneToOnePrincipal Principal { get; set; } - public int PrincipalId { get; set; } - } - - public sealed class OneToManyDependent : IdentifiableWithAttribute - { - [HasOne] public OneToManyPrincipal Principal { get; set; } - public int? PrincipalId { get; set; } - } - - public class OneToManyRequiredDependent : IdentifiableWithAttribute - { - [HasOne] public OneToManyPrincipal Principal { get; set; } - public int PrincipalId { get; set; } - } - - public sealed class OneToManyPrincipal : IdentifiableWithAttribute - { - [HasMany] public ISet Dependents { get; set; } - } - - public class IdentifiableWithAttribute : Identifiable - { - [Attr] public string AttributeMember { get; set; } - } - - public sealed class MultipleRelationshipsPrincipalPart : IdentifiableWithAttribute - { - [HasOne] public OneToOneDependent PopulatedToOne { get; set; } - [HasOne] public OneToOneDependent EmptyToOne { get; set; } - [HasMany] public ISet PopulatedToManies { get; set; } - [HasMany] public ISet EmptyToManies { get; set; } - [HasOne] public MultipleRelationshipsPrincipalPart Multi { get; set; } - } - - public class MultipleRelationshipsDependentPart : IdentifiableWithAttribute - { - [HasOne] public OneToOnePrincipal PopulatedToOne { get; set; } - public int PopulatedToOneId { get; set; } - [HasOne] public OneToOnePrincipal EmptyToOne { get; set; } - public int? EmptyToOneId { get; set; } - [HasOne] public OneToManyPrincipal PopulatedToMany { get; set; } - public int PopulatedToManyId { get; set; } - [HasOne] public OneToManyPrincipal EmptyToMany { get; set; } - public int? EmptyToManyId { get; set; } - } - - public class Article : Identifiable - { - [Attr] public string Title { get; set; } - [HasOne] public Person Reviewer { get; set; } - [HasOne] public Person Author { get; set; } - - [HasOne(CanInclude = false)] public Person CannotInclude { get; set; } - } - - public class Person : Identifiable - { - [Attr] public string Name { get; set; } - [HasMany] public ISet Blogs { get; set; } - [HasOne] public Food FavoriteFood { get; set; } - [HasOne] public Song FavoriteSong { get; set; } - } - - public class Blog : Identifiable - { - [Attr] public string Title { get; set; } - [HasOne] public Person Reviewer { get; set; } - [HasOne] public Person Author { get; set; } - } - - public class Food : Identifiable - { - [Attr] public string Dish { get; set; } - } - - public class Song : Identifiable - { - [Attr] public string Title { get; set; } - } -} diff --git a/test/UnitTests/TestModels/Article.cs b/test/UnitTests/TestModels/Article.cs new file mode 100644 index 0000000000..1bfde88836 --- /dev/null +++ b/test/UnitTests/TestModels/Article.cs @@ -0,0 +1,14 @@ +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public class Article : Identifiable + { + [Attr] public string Title { get; set; } + [HasOne] public Person Reviewer { get; set; } + [HasOne] public Person Author { get; set; } + + [HasOne(CanInclude = false)] public Person CannotInclude { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/BaseModel.cs b/test/UnitTests/TestModels/BaseModel.cs new file mode 100644 index 0000000000..5ec5d635f9 --- /dev/null +++ b/test/UnitTests/TestModels/BaseModel.cs @@ -0,0 +1,6 @@ +using JsonApiDotNetCore.Resources; + +namespace UnitTests.TestModels +{ + public abstract class BaseModel : Identifiable { } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/Blog.cs b/test/UnitTests/TestModels/Blog.cs new file mode 100644 index 0000000000..3d32028cd2 --- /dev/null +++ b/test/UnitTests/TestModels/Blog.cs @@ -0,0 +1,12 @@ +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public class Blog : Identifiable + { + [Attr] public string Title { get; set; } + [HasOne] public Person Reviewer { get; set; } + [HasOne] public Person Author { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/ComplexType.cs b/test/UnitTests/TestModels/ComplexType.cs new file mode 100644 index 0000000000..ee7e62aebf --- /dev/null +++ b/test/UnitTests/TestModels/ComplexType.cs @@ -0,0 +1,7 @@ +namespace UnitTests.TestModels +{ + public class ComplexType + { + public string CompoundName { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/FirstDerivedModel.cs b/test/UnitTests/TestModels/FirstDerivedModel.cs new file mode 100644 index 0000000000..bb77b63137 --- /dev/null +++ b/test/UnitTests/TestModels/FirstDerivedModel.cs @@ -0,0 +1,9 @@ +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public class FirstDerivedModel : BaseModel + { + [Attr] public bool FirstProperty { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/Food.cs b/test/UnitTests/TestModels/Food.cs new file mode 100644 index 0000000000..3397f2138d --- /dev/null +++ b/test/UnitTests/TestModels/Food.cs @@ -0,0 +1,10 @@ +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public class Food : Identifiable + { + [Attr] public string Dish { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/IdentifiableWithAttribute.cs b/test/UnitTests/TestModels/IdentifiableWithAttribute.cs new file mode 100644 index 0000000000..50ff8ec777 --- /dev/null +++ b/test/UnitTests/TestModels/IdentifiableWithAttribute.cs @@ -0,0 +1,10 @@ +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public class IdentifiableWithAttribute : Identifiable + { + [Attr] public string AttributeMember { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/MultipleRelationshipsDependentPart.cs b/test/UnitTests/TestModels/MultipleRelationshipsDependentPart.cs new file mode 100644 index 0000000000..0f172799b6 --- /dev/null +++ b/test/UnitTests/TestModels/MultipleRelationshipsDependentPart.cs @@ -0,0 +1,16 @@ +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public class MultipleRelationshipsDependentPart : IdentifiableWithAttribute + { + [HasOne] public OneToOnePrincipal PopulatedToOne { get; set; } + public int PopulatedToOneId { get; set; } + [HasOne] public OneToOnePrincipal EmptyToOne { get; set; } + public int? EmptyToOneId { get; set; } + [HasOne] public OneToManyPrincipal PopulatedToMany { get; set; } + public int PopulatedToManyId { get; set; } + [HasOne] public OneToManyPrincipal EmptyToMany { get; set; } + public int? EmptyToManyId { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/MultipleRelationshipsPrincipalPart.cs b/test/UnitTests/TestModels/MultipleRelationshipsPrincipalPart.cs new file mode 100644 index 0000000000..6e2a640411 --- /dev/null +++ b/test/UnitTests/TestModels/MultipleRelationshipsPrincipalPart.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public sealed class MultipleRelationshipsPrincipalPart : IdentifiableWithAttribute + { + [HasOne] public OneToOneDependent PopulatedToOne { get; set; } + [HasOne] public OneToOneDependent EmptyToOne { get; set; } + [HasMany] public ISet PopulatedToManies { get; set; } + [HasMany] public ISet EmptyToManies { get; set; } + [HasOne] public MultipleRelationshipsPrincipalPart Multi { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/OneToManyDependent.cs b/test/UnitTests/TestModels/OneToManyDependent.cs new file mode 100644 index 0000000000..c6f87fea67 --- /dev/null +++ b/test/UnitTests/TestModels/OneToManyDependent.cs @@ -0,0 +1,10 @@ +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public sealed class OneToManyDependent : IdentifiableWithAttribute + { + [HasOne] public OneToManyPrincipal Principal { get; set; } + public int? PrincipalId { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/OneToManyPrincipal.cs b/test/UnitTests/TestModels/OneToManyPrincipal.cs new file mode 100644 index 0000000000..eea9d19ec9 --- /dev/null +++ b/test/UnitTests/TestModels/OneToManyPrincipal.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public sealed class OneToManyPrincipal : IdentifiableWithAttribute + { + [HasMany] public ISet Dependents { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/OneToManyRequiredDependent.cs b/test/UnitTests/TestModels/OneToManyRequiredDependent.cs new file mode 100644 index 0000000000..8953aeef58 --- /dev/null +++ b/test/UnitTests/TestModels/OneToManyRequiredDependent.cs @@ -0,0 +1,10 @@ +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public class OneToManyRequiredDependent : IdentifiableWithAttribute + { + [HasOne] public OneToManyPrincipal Principal { get; set; } + public int PrincipalId { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/OneToOneDependent.cs b/test/UnitTests/TestModels/OneToOneDependent.cs new file mode 100644 index 0000000000..e88ed3a852 --- /dev/null +++ b/test/UnitTests/TestModels/OneToOneDependent.cs @@ -0,0 +1,10 @@ +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public sealed class OneToOneDependent : IdentifiableWithAttribute + { + [HasOne] public OneToOnePrincipal Principal { get; set; } + public int? PrincipalId { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/OneToOnePrincipal.cs b/test/UnitTests/TestModels/OneToOnePrincipal.cs new file mode 100644 index 0000000000..a3a183b4c7 --- /dev/null +++ b/test/UnitTests/TestModels/OneToOnePrincipal.cs @@ -0,0 +1,9 @@ +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public sealed class OneToOnePrincipal : IdentifiableWithAttribute + { + [HasOne] public OneToOneDependent Dependent { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/OneToOneRequiredDependent.cs b/test/UnitTests/TestModels/OneToOneRequiredDependent.cs new file mode 100644 index 0000000000..463b3e80a1 --- /dev/null +++ b/test/UnitTests/TestModels/OneToOneRequiredDependent.cs @@ -0,0 +1,10 @@ +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public sealed class OneToOneRequiredDependent : IdentifiableWithAttribute + { + [HasOne] public OneToOnePrincipal Principal { get; set; } + public int PrincipalId { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/Person.cs b/test/UnitTests/TestModels/Person.cs new file mode 100644 index 0000000000..9588c43cee --- /dev/null +++ b/test/UnitTests/TestModels/Person.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public class Person : Identifiable + { + [Attr] public string Name { get; set; } + [HasMany] public ISet Blogs { get; set; } + [HasOne] public Food FavoriteFood { get; set; } + [HasOne] public Song FavoriteSong { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/SecondDerivedModel.cs b/test/UnitTests/TestModels/SecondDerivedModel.cs new file mode 100644 index 0000000000..cec4cb78a5 --- /dev/null +++ b/test/UnitTests/TestModels/SecondDerivedModel.cs @@ -0,0 +1,9 @@ +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public class SecondDerivedModel : BaseModel + { + [Attr] public bool SecondProperty { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/Song.cs b/test/UnitTests/TestModels/Song.cs new file mode 100644 index 0000000000..301f31aa70 --- /dev/null +++ b/test/UnitTests/TestModels/Song.cs @@ -0,0 +1,10 @@ +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public class Song : Identifiable + { + [Attr] public string Title { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/TestResource.cs b/test/UnitTests/TestModels/TestResource.cs new file mode 100644 index 0000000000..bc7922997f --- /dev/null +++ b/test/UnitTests/TestModels/TestResource.cs @@ -0,0 +1,18 @@ +using System; +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public sealed class TestResource : Identifiable + { + [Attr] public string StringField { get; set; } + [Attr] public DateTime DateTimeField { get; set; } + [Attr] public DateTime? NullableDateTimeField { get; set; } + [Attr] public int IntField { get; set; } + [Attr] public int? NullableIntField { get; set; } + [Attr] public Guid GuidField { get; set; } + [Attr] public ComplexType ComplexField { get; set; } + + } +} diff --git a/test/UnitTests/TestModels/TestResourceWithAbstractRelationship.cs b/test/UnitTests/TestModels/TestResourceWithAbstractRelationship.cs new file mode 100644 index 0000000000..e2415af01d --- /dev/null +++ b/test/UnitTests/TestModels/TestResourceWithAbstractRelationship.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public class TestResourceWithAbstractRelationship : Identifiable + { + [HasOne] public BaseModel ToOne { get; set; } + [HasMany] public List ToMany { get; set; } + } +} \ No newline at end of file diff --git a/test/UnitTests/TestModels/TestResourceWithList.cs b/test/UnitTests/TestModels/TestResourceWithList.cs new file mode 100644 index 0000000000..80d7a1ecf7 --- /dev/null +++ b/test/UnitTests/TestModels/TestResourceWithList.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + +namespace UnitTests.TestModels +{ + public class TestResourceWithList : Identifiable + { + [Attr] public List ComplexFields { get; set; } + } +} \ No newline at end of file From 952bcc5a4d5d9bf525bfc3d769f8105fc73534eb Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Mon, 15 Feb 2021 14:11:03 +0100 Subject: [PATCH 06/60] Adapt namespaces to match with directory structure --- src/Examples/JsonApiDotNetCoreExample/Program.cs | 1 + src/Examples/JsonApiDotNetCoreExample/Startups/EmptyStartup.cs | 2 +- src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs | 2 +- .../ExampleIntegrationTestContext.cs | 2 +- .../NonJsonApiControllers/NonJsonApiControllerTests.cs | 2 +- .../ServiceCollectionExtensions.cs | 2 +- test/JsonApiDotNetCoreExampleTests/Startups/TestableStartup.cs | 2 +- test/UnitTests/Builders/ResourceGraphBuilder_Tests.cs | 2 +- test/UnitTests/Controllers/BaseJsonApiController_Tests.cs | 2 +- test/UnitTests/Controllers/CoreJsonApiControllerTests.cs | 2 +- test/UnitTests/Graph/BaseType.cs | 2 +- test/UnitTests/Graph/DerivedType.cs | 2 +- test/UnitTests/Graph/IGenericInterface.cs | 2 +- test/UnitTests/Graph/Implementation.cs | 2 +- test/UnitTests/Graph/Model.cs | 2 +- test/UnitTests/Graph/ResourceDescriptorAssemblyCacheTests.cs | 1 - test/UnitTests/Graph/TypeLocator_Tests.cs | 2 +- .../Create/AfterCreateTests.cs | 2 +- .../Create/BeforeCreateTests.cs | 2 +- .../Create/BeforeCreate_WithDbValues_Tests.cs | 2 +- .../Delete/AfterDeleteTests.cs | 2 +- .../Delete/BeforeDeleteTests.cs | 2 +- .../Delete/BeforeDelete_WithDbValues_Tests.cs | 2 +- .../IdentifiableManyToMany_OnReturnTests.cs | 2 +- .../ManyToMany_OnReturnTests.cs | 2 +- .../{ResourceHookExecutor => Executor}/Read/BeforeReadTests.cs | 2 +- .../Read/IdentifiableManyToMany_AfterReadTests.cs | 2 +- .../Read/ManyToMany_AfterReadTests.cs | 2 +- .../{ResourceHookExecutor => Executor}/SameResourceTypeTests.cs | 2 +- .../Update/AfterUpdateTests.cs | 2 +- .../Update/BeforeUpdateTests.cs | 2 +- .../Update/BeforeUpdate_WithDbValues_Tests.cs | 2 +- test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs | 2 +- test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs | 2 +- .../Serialization/Common/ResourceObjectBuilderTests.cs | 2 +- 35 files changed, 34 insertions(+), 34 deletions(-) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/Create/AfterCreateTests.cs (98%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/Create/BeforeCreateTests.cs (98%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/Create/BeforeCreate_WithDbValues_Tests.cs (99%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/Delete/AfterDeleteTests.cs (96%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/Delete/BeforeDeleteTests.cs (96%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/Delete/BeforeDelete_WithDbValues_Tests.cs (99%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/IdentifiableManyToMany_OnReturnTests.cs (99%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/ManyToMany_OnReturnTests.cs (99%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/Read/BeforeReadTests.cs (99%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/Read/IdentifiableManyToMany_AfterReadTests.cs (99%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/Read/ManyToMany_AfterReadTests.cs (98%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/SameResourceTypeTests.cs (98%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/Update/AfterUpdateTests.cs (98%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/Update/BeforeUpdateTests.cs (98%) rename test/UnitTests/ResourceHooks/{ResourceHookExecutor => Executor}/Update/BeforeUpdate_WithDbValues_Tests.cs (99%) diff --git a/src/Examples/JsonApiDotNetCoreExample/Program.cs b/src/Examples/JsonApiDotNetCoreExample/Program.cs index 8a892fcfe5..faf53829cb 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Program.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Program.cs @@ -1,3 +1,4 @@ +using JsonApiDotNetCoreExample.Startups; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; diff --git a/src/Examples/JsonApiDotNetCoreExample/Startups/EmptyStartup.cs b/src/Examples/JsonApiDotNetCoreExample/Startups/EmptyStartup.cs index 18d40e9ccd..de254cb942 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Startups/EmptyStartup.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Startups/EmptyStartup.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -namespace JsonApiDotNetCoreExample +namespace JsonApiDotNetCoreExample.Startups { /// /// Empty startup class, required for integration tests. diff --git a/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs b/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs index 553ad27999..01e14a2511 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs @@ -10,7 +10,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Converters; -namespace JsonApiDotNetCoreExample +namespace JsonApiDotNetCoreExample.Startups { public class Startup : EmptyStartup { diff --git a/test/JsonApiDotNetCoreExampleTests/ExampleIntegrationTestContext.cs b/test/JsonApiDotNetCoreExampleTests/ExampleIntegrationTestContext.cs index 249b61cad4..319f06f3a9 100644 --- a/test/JsonApiDotNetCoreExampleTests/ExampleIntegrationTestContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/ExampleIntegrationTestContext.cs @@ -1,4 +1,4 @@ -using JsonApiDotNetCoreExample; +using JsonApiDotNetCoreExample.Startups; using Microsoft.EntityFrameworkCore; using TestBuildingBlocks; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NonJsonApiControllers/NonJsonApiControllerTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NonJsonApiControllers/NonJsonApiControllerTests.cs index 768757e43f..0512895c8d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NonJsonApiControllers/NonJsonApiControllerTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NonJsonApiControllers/NonJsonApiControllerTests.cs @@ -3,7 +3,7 @@ using System.Net.Http.Headers; using System.Threading.Tasks; using FluentAssertions; -using JsonApiDotNetCoreExample; +using JsonApiDotNetCoreExample.Startups; using Microsoft.AspNetCore.Mvc.Testing; using TestBuildingBlocks; using Xunit; diff --git a/test/JsonApiDotNetCoreExampleTests/ServiceCollectionExtensions.cs b/test/JsonApiDotNetCoreExampleTests/ServiceCollectionExtensions.cs index e8eb3fa54e..e3edf1f02d 100644 --- a/test/JsonApiDotNetCoreExampleTests/ServiceCollectionExtensions.cs +++ b/test/JsonApiDotNetCoreExampleTests/ServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -using JsonApiDotNetCoreExample; +using JsonApiDotNetCoreExample.Startups; using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.Extensions.DependencyInjection; diff --git a/test/JsonApiDotNetCoreExampleTests/Startups/TestableStartup.cs b/test/JsonApiDotNetCoreExampleTests/Startups/TestableStartup.cs index 3d07ea8187..36cf40c68b 100644 --- a/test/JsonApiDotNetCoreExampleTests/Startups/TestableStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/Startups/TestableStartup.cs @@ -1,5 +1,5 @@ using JsonApiDotNetCore.Configuration; -using JsonApiDotNetCoreExample; +using JsonApiDotNetCoreExample.Startups; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; diff --git a/test/UnitTests/Builders/ResourceGraphBuilder_Tests.cs b/test/UnitTests/Builders/ResourceGraphBuilder_Tests.cs index 34535d9d5c..67a70175b0 100644 --- a/test/UnitTests/Builders/ResourceGraphBuilder_Tests.cs +++ b/test/UnitTests/Builders/ResourceGraphBuilder_Tests.cs @@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Xunit; -namespace UnitTests +namespace UnitTests.Builders { public sealed class ResourceGraphBuilder_Tests { diff --git a/test/UnitTests/Controllers/BaseJsonApiController_Tests.cs b/test/UnitTests/Controllers/BaseJsonApiController_Tests.cs index a2a63c638a..977ab5890f 100644 --- a/test/UnitTests/Controllers/BaseJsonApiController_Tests.cs +++ b/test/UnitTests/Controllers/BaseJsonApiController_Tests.cs @@ -15,7 +15,7 @@ using Moq; using Xunit; -namespace UnitTests +namespace UnitTests.Controllers { public sealed class BaseJsonApiController_Tests { diff --git a/test/UnitTests/Controllers/CoreJsonApiControllerTests.cs b/test/UnitTests/Controllers/CoreJsonApiControllerTests.cs index 9fbe8275f3..bc7f0f5540 100644 --- a/test/UnitTests/Controllers/CoreJsonApiControllerTests.cs +++ b/test/UnitTests/Controllers/CoreJsonApiControllerTests.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Mvc; using Xunit; -namespace UnitTests +namespace UnitTests.Controllers { public sealed class CoreJsonApiControllerTests : CoreJsonApiController { diff --git a/test/UnitTests/Graph/BaseType.cs b/test/UnitTests/Graph/BaseType.cs index e32f521640..45e9b91463 100644 --- a/test/UnitTests/Graph/BaseType.cs +++ b/test/UnitTests/Graph/BaseType.cs @@ -1,4 +1,4 @@ -namespace UnitTests.Internal +namespace UnitTests.Graph { public class BaseType { } } \ No newline at end of file diff --git a/test/UnitTests/Graph/DerivedType.cs b/test/UnitTests/Graph/DerivedType.cs index 2250cd9383..64c0b5fbf6 100644 --- a/test/UnitTests/Graph/DerivedType.cs +++ b/test/UnitTests/Graph/DerivedType.cs @@ -1,4 +1,4 @@ -namespace UnitTests.Internal +namespace UnitTests.Graph { public sealed class DerivedType : BaseType { } } \ No newline at end of file diff --git a/test/UnitTests/Graph/IGenericInterface.cs b/test/UnitTests/Graph/IGenericInterface.cs index 012eec6875..4ab2f68f64 100644 --- a/test/UnitTests/Graph/IGenericInterface.cs +++ b/test/UnitTests/Graph/IGenericInterface.cs @@ -1,4 +1,4 @@ -namespace UnitTests.Internal +namespace UnitTests.Graph { public interface IGenericInterface { } } \ No newline at end of file diff --git a/test/UnitTests/Graph/Implementation.cs b/test/UnitTests/Graph/Implementation.cs index 3bb36176a8..da379b84b9 100644 --- a/test/UnitTests/Graph/Implementation.cs +++ b/test/UnitTests/Graph/Implementation.cs @@ -1,4 +1,4 @@ -namespace UnitTests.Internal +namespace UnitTests.Graph { public sealed class Implementation : IGenericInterface { } } \ No newline at end of file diff --git a/test/UnitTests/Graph/Model.cs b/test/UnitTests/Graph/Model.cs index eef1ed91a7..231f060fa4 100644 --- a/test/UnitTests/Graph/Model.cs +++ b/test/UnitTests/Graph/Model.cs @@ -1,6 +1,6 @@ using JsonApiDotNetCore.Resources; -namespace UnitTests.Internal +namespace UnitTests.Graph { public sealed class Model : Identifiable { } } \ No newline at end of file diff --git a/test/UnitTests/Graph/ResourceDescriptorAssemblyCacheTests.cs b/test/UnitTests/Graph/ResourceDescriptorAssemblyCacheTests.cs index d533400a3e..fc1f6d6543 100644 --- a/test/UnitTests/Graph/ResourceDescriptorAssemblyCacheTests.cs +++ b/test/UnitTests/Graph/ResourceDescriptorAssemblyCacheTests.cs @@ -1,7 +1,6 @@ using System.Linq; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; -using UnitTests.Internal; using Xunit; namespace UnitTests.Graph diff --git a/test/UnitTests/Graph/TypeLocator_Tests.cs b/test/UnitTests/Graph/TypeLocator_Tests.cs index 497427e863..4096b04062 100644 --- a/test/UnitTests/Graph/TypeLocator_Tests.cs +++ b/test/UnitTests/Graph/TypeLocator_Tests.cs @@ -2,7 +2,7 @@ using JsonApiDotNetCore.Configuration; using Xunit; -namespace UnitTests.Internal +namespace UnitTests.Graph { public sealed class TypeLocator_Tests { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Create/AfterCreateTests.cs b/test/UnitTests/ResourceHooks/Executor/Create/AfterCreateTests.cs similarity index 98% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/Create/AfterCreateTests.cs rename to test/UnitTests/ResourceHooks/Executor/Create/AfterCreateTests.cs index 30d391a394..bf4aa9b8f8 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Create/AfterCreateTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Create/AfterCreateTests.cs @@ -4,7 +4,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor.Create { public sealed class AfterCreateTests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Create/BeforeCreateTests.cs b/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateTests.cs similarity index 98% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/Create/BeforeCreateTests.cs rename to test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateTests.cs index 2f580128a9..86623c3370 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Create/BeforeCreateTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateTests.cs @@ -4,7 +4,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor.Create { public sealed class BeforeCreateTests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Create/BeforeCreate_WithDbValues_Tests.cs b/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreate_WithDbValues_Tests.cs similarity index 99% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/Create/BeforeCreate_WithDbValues_Tests.cs rename to test/UnitTests/ResourceHooks/Executor/Create/BeforeCreate_WithDbValues_Tests.cs index b8ad10bd11..bde79dcd93 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Create/BeforeCreate_WithDbValues_Tests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreate_WithDbValues_Tests.cs @@ -7,7 +7,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor.Create { public sealed class BeforeCreate_WithDbValues_Tests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/AfterDeleteTests.cs b/test/UnitTests/ResourceHooks/Executor/Delete/AfterDeleteTests.cs similarity index 96% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/AfterDeleteTests.cs rename to test/UnitTests/ResourceHooks/Executor/Delete/AfterDeleteTests.cs index af85d5d487..adeeb67f1c 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/AfterDeleteTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Delete/AfterDeleteTests.cs @@ -4,7 +4,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor.Delete { public sealed class AfterDeleteTests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/BeforeDeleteTests.cs b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteTests.cs similarity index 96% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/BeforeDeleteTests.cs rename to test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteTests.cs index b904846ec3..2dd9755fdd 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/BeforeDeleteTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteTests.cs @@ -3,7 +3,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor.Delete { public sealed class BeforeDeleteTests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/BeforeDelete_WithDbValues_Tests.cs b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDelete_WithDbValues_Tests.cs similarity index 99% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/BeforeDelete_WithDbValues_Tests.cs rename to test/UnitTests/ResourceHooks/Executor/Delete/BeforeDelete_WithDbValues_Tests.cs index 5500fb9c2a..80b319708a 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Delete/BeforeDelete_WithDbValues_Tests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDelete_WithDbValues_Tests.cs @@ -7,7 +7,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor.Delete { public sealed class BeforeDelete_WithDbValues_Tests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/IdentifiableManyToMany_OnReturnTests.cs b/test/UnitTests/ResourceHooks/Executor/IdentifiableManyToMany_OnReturnTests.cs similarity index 99% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/IdentifiableManyToMany_OnReturnTests.cs rename to test/UnitTests/ResourceHooks/Executor/IdentifiableManyToMany_OnReturnTests.cs index 0b3c0aa874..0a666c83b8 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/IdentifiableManyToMany_OnReturnTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/IdentifiableManyToMany_OnReturnTests.cs @@ -5,7 +5,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor { public sealed class IdentifiableManyToMany_OnReturnTests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/ManyToMany_OnReturnTests.cs b/test/UnitTests/ResourceHooks/Executor/ManyToMany_OnReturnTests.cs similarity index 99% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/ManyToMany_OnReturnTests.cs rename to test/UnitTests/ResourceHooks/Executor/ManyToMany_OnReturnTests.cs index e4db309781..afaa4500dc 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/ManyToMany_OnReturnTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/ManyToMany_OnReturnTests.cs @@ -5,7 +5,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor { public sealed class ManyToMany_OnReturnTests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Read/BeforeReadTests.cs b/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs similarity index 99% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/Read/BeforeReadTests.cs rename to test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs index a967bc2c9d..598d786f07 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Read/BeforeReadTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs @@ -5,7 +5,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor.Read { public sealed class BeforeReadTests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Read/IdentifiableManyToMany_AfterReadTests.cs b/test/UnitTests/ResourceHooks/Executor/Read/IdentifiableManyToMany_AfterReadTests.cs similarity index 99% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/Read/IdentifiableManyToMany_AfterReadTests.cs rename to test/UnitTests/ResourceHooks/Executor/Read/IdentifiableManyToMany_AfterReadTests.cs index e91e3a6ebd..3d9a885fee 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Read/IdentifiableManyToMany_AfterReadTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Read/IdentifiableManyToMany_AfterReadTests.cs @@ -5,7 +5,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor.Read { public sealed class IdentifiableManyToMany_AfterReadTests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Read/ManyToMany_AfterReadTests.cs b/test/UnitTests/ResourceHooks/Executor/Read/ManyToMany_AfterReadTests.cs similarity index 98% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/Read/ManyToMany_AfterReadTests.cs rename to test/UnitTests/ResourceHooks/Executor/Read/ManyToMany_AfterReadTests.cs index 7ca674ea65..a55a94c8e4 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Read/ManyToMany_AfterReadTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Read/ManyToMany_AfterReadTests.cs @@ -5,7 +5,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor.Read { public sealed class ManyToMany_AfterReadTests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/SameResourceTypeTests.cs b/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs similarity index 98% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/SameResourceTypeTests.cs rename to test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs index eb963e38f2..1f210cd67f 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/SameResourceTypeTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs @@ -4,7 +4,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor { public sealed class SameResourceTypeTests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Update/AfterUpdateTests.cs b/test/UnitTests/ResourceHooks/Executor/Update/AfterUpdateTests.cs similarity index 98% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/Update/AfterUpdateTests.cs rename to test/UnitTests/ResourceHooks/Executor/Update/AfterUpdateTests.cs index c4402b809c..c36d19b3ad 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Update/AfterUpdateTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Update/AfterUpdateTests.cs @@ -4,7 +4,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor.Update { public sealed class AfterUpdateTests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Update/BeforeUpdateTests.cs b/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateTests.cs similarity index 98% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/Update/BeforeUpdateTests.cs rename to test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateTests.cs index 7a299416c3..f8307ac346 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Update/BeforeUpdateTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateTests.cs @@ -4,7 +4,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor.Update { public sealed class BeforeUpdateTests : HooksTestsSetup { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Update/BeforeUpdate_WithDbValues_Tests.cs b/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdate_WithDbValues_Tests.cs similarity index 99% rename from test/UnitTests/ResourceHooks/ResourceHookExecutor/Update/BeforeUpdate_WithDbValues_Tests.cs rename to test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdate_WithDbValues_Tests.cs index 83f7f21dbe..9f15b727c8 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/Update/BeforeUpdate_WithDbValues_Tests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdate_WithDbValues_Tests.cs @@ -7,7 +7,7 @@ using Moq; using Xunit; -namespace UnitTests.ResourceHooks +namespace UnitTests.ResourceHooks.Executor.Update { public sealed class BeforeUpdate_WithDbValues_Tests : HooksTestsSetup { diff --git a/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs b/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs index 1023998c15..72272dd019 100644 --- a/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs +++ b/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs @@ -7,7 +7,7 @@ using UnitTests.TestModels; using Xunit; -namespace UnitTests.Serialization.Serializer +namespace UnitTests.Serialization.Common { public sealed class BaseDocumentBuilderTests : SerializerTestsSetup { diff --git a/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs b/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs index 2d02c60c51..e11cdf7178 100644 --- a/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs +++ b/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs @@ -9,7 +9,7 @@ using UnitTests.TestModels; using Xunit; -namespace UnitTests.Serialization.Deserializer +namespace UnitTests.Serialization.Common { public sealed class BaseDocumentParserTests : DeserializerTestsSetup { diff --git a/test/UnitTests/Serialization/Common/ResourceObjectBuilderTests.cs b/test/UnitTests/Serialization/Common/ResourceObjectBuilderTests.cs index a6d06382af..e0572f6d6a 100644 --- a/test/UnitTests/Serialization/Common/ResourceObjectBuilderTests.cs +++ b/test/UnitTests/Serialization/Common/ResourceObjectBuilderTests.cs @@ -6,7 +6,7 @@ using UnitTests.TestModels; using Xunit; -namespace UnitTests.Serialization.Serializer +namespace UnitTests.Serialization.Common { public sealed class ResourceObjectBuilderTests : SerializerTestsSetup { From 36ea3fd5fa88de26ed9519a98ead096d8571da79 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Mon, 15 Feb 2021 14:23:45 +0100 Subject: [PATCH 07/60] Fixed inconsistencies in naming conventions --- .../JsonApiDeserializerBenchmarks.cs | 4 +- .../Discovery/LoadDatabaseValuesAttribute.cs | 2 +- .../Middleware/HttpContextExtensions.cs | 6 +- .../Serialization/Building/LinkBuilder.cs | 16 +-- .../ActionResultTests.cs | 10 +- .../BaseToothbrushesController.cs | 20 ++-- .../ConsumerArticleService.cs | 4 +- .../PaginationWithTotalCountTests.cs | 6 +- .../PaginationWithoutTotalCountTests.cs | 14 +-- .../Pagination/RangeValidationTests.cs | 4 +- .../RangeValidationWithMaximumTests.cs | 24 ++--- .../SkipCacheQueryStringParameterReader.cs | 6 +- ..._Tests.cs => ResourceGraphBuilderTests.cs} | 2 +- ...Tests.cs => BaseJsonApiControllerTests.cs} | 2 +- ...cs => ServiceCollectionExtensionsTests.cs} | 2 +- ...peLocator_Tests.cs => TypeLocatorTests.cs} | 2 +- ...TypeHelper_Tests.cs => TypeHelperTests.cs} | 2 +- .../Middleware/JsonApiMiddlewareTests.cs | 12 +-- .../Executor/Create/BeforeCreateTests.cs | 10 +- ...ts.cs => BeforeCreateWithDbValuesTests.cs} | 26 ++--- .../Executor/Delete/AfterDeleteTests.cs | 4 +- .../Executor/Delete/BeforeDeleteTests.cs | 4 +- ...ts.cs => BeforeDeleteWithDbValuesTests.cs} | 46 ++++----- ...=> IdentifiableManyToManyOnReturnTests.cs} | 30 +++--- ...urnTests.cs => ManyToManyOnReturnTests.cs} | 12 +-- .../Executor/Read/BeforeReadTests.cs | 26 ++--- ...> IdentifiableManyToManyAfterReadTests.cs} | 24 ++--- ...adTests.cs => ManyToManyAfterReadTests.cs} | 12 +-- .../Executor/SameResourceTypeTests.cs | 10 +- .../Executor/Update/AfterUpdateTests.cs | 10 +- .../Executor/Update/BeforeUpdateTests.cs | 10 +- ...ts.cs => BeforeUpdateWithDbValuesTests.cs} | 42 ++++---- .../UnitTests/ResourceHooks/HooksDummyData.cs | 10 +- .../ResourceHooks/HooksTestsSetup.cs | 26 ++--- .../RelationshipDictionaryTests.cs | 97 ++++++++++--------- .../ResponseResourceObjectBuilderTests.cs | 8 +- 36 files changed, 273 insertions(+), 272 deletions(-) rename test/UnitTests/Builders/{ResourceGraphBuilder_Tests.cs => ResourceGraphBuilderTests.cs} (98%) rename test/UnitTests/Controllers/{BaseJsonApiController_Tests.cs => BaseJsonApiControllerTests.cs} (99%) rename test/UnitTests/Extensions/{IServiceCollectionExtensionsTests.cs => ServiceCollectionExtensionsTests.cs} (99%) rename test/UnitTests/Graph/{TypeLocator_Tests.cs => TypeLocatorTests.cs} (98%) rename test/UnitTests/Internal/{TypeHelper_Tests.cs => TypeHelperTests.cs} (99%) rename test/UnitTests/ResourceHooks/Executor/Create/{BeforeCreate_WithDbValues_Tests.cs => BeforeCreateWithDbValuesTests.cs} (91%) rename test/UnitTests/ResourceHooks/Executor/Delete/{BeforeDelete_WithDbValues_Tests.cs => BeforeDeleteWithDbValuesTests.cs} (68%) rename test/UnitTests/ResourceHooks/Executor/{IdentifiableManyToMany_OnReturnTests.cs => IdentifiableManyToManyOnReturnTests.cs} (89%) rename test/UnitTests/ResourceHooks/Executor/{ManyToMany_OnReturnTests.cs => ManyToManyOnReturnTests.cs} (91%) rename test/UnitTests/ResourceHooks/Executor/Read/{IdentifiableManyToMany_AfterReadTests.cs => IdentifiableManyToManyAfterReadTests.cs} (90%) rename test/UnitTests/ResourceHooks/Executor/Read/{ManyToMany_AfterReadTests.cs => ManyToManyAfterReadTests.cs} (89%) rename test/UnitTests/ResourceHooks/Executor/Update/{BeforeUpdate_WithDbValues_Tests.cs => BeforeUpdateWithDbValuesTests.cs} (90%) diff --git a/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs b/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs index 5de48d8604..7be6c06443 100644 --- a/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs +++ b/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs @@ -15,7 +15,7 @@ namespace Benchmarks.Serialization [MarkdownExporter] public class JsonApiDeserializerBenchmarks { - private static readonly string Content = JsonConvert.SerializeObject(new Document + private static readonly string _content = JsonConvert.SerializeObject(new Document { Data = new ResourceObject { @@ -43,6 +43,6 @@ public JsonApiDeserializerBenchmarks() } [Benchmark] - public object DeserializeSimpleObject() => _jsonApiDeserializer.Deserialize(Content); + public object DeserializeSimpleObject() => _jsonApiDeserializer.Deserialize(_content); } } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/LoadDatabaseValuesAttribute.cs b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/LoadDatabaseValuesAttribute.cs index 09a5393e3b..8f688f734e 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/LoadDatabaseValuesAttribute.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/LoadDatabaseValuesAttribute.cs @@ -5,7 +5,7 @@ namespace JsonApiDotNetCore.Hooks.Internal.Discovery [AttributeUsage(AttributeTargets.Method)] public sealed class LoadDatabaseValuesAttribute : Attribute { - public readonly bool Value; + public bool Value { get; } public LoadDatabaseValuesAttribute(bool mode = true) { diff --git a/src/JsonApiDotNetCore/Middleware/HttpContextExtensions.cs b/src/JsonApiDotNetCore/Middleware/HttpContextExtensions.cs index 8bac477581..c8411756ba 100644 --- a/src/JsonApiDotNetCore/Middleware/HttpContextExtensions.cs +++ b/src/JsonApiDotNetCore/Middleware/HttpContextExtensions.cs @@ -4,7 +4,7 @@ namespace JsonApiDotNetCore.Middleware { public static class HttpContextExtensions { - private const string _isJsonApiRequestKey = "JsonApiDotNetCore_IsJsonApiRequest"; + private const string IsJsonApiRequestKey = "JsonApiDotNetCore_IsJsonApiRequest"; /// /// Indicates whether the currently executing HTTP request is being handled by JsonApiDotNetCore. @@ -13,7 +13,7 @@ public static bool IsJsonApiRequest(this HttpContext httpContext) { ArgumentGuard.NotNull(httpContext, nameof(httpContext)); - string value = httpContext.Items[_isJsonApiRequestKey] as string; + string value = httpContext.Items[IsJsonApiRequestKey] as string; return value == bool.TrueString; } @@ -21,7 +21,7 @@ internal static void RegisterJsonApiRequest(this HttpContext httpContext) { ArgumentGuard.NotNull(httpContext, nameof(httpContext)); - httpContext.Items[_isJsonApiRequestKey] = bool.TrueString; + httpContext.Items[IsJsonApiRequestKey] = bool.TrueString; } } } diff --git a/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs index 65bf78db94..4da147a5ae 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs @@ -17,8 +17,8 @@ namespace JsonApiDotNetCore.Serialization.Building { public class LinkBuilder : ILinkBuilder { - private const string _pageSizeParameterName = "page[size]"; - private const string _pageNumberParameterName = "page[number]"; + private const string PageSizeParameterName = "page[size]"; + private const string PageNumberParameterName = "page[number]"; private readonly IResourceContextProvider _provider; private readonly IRequestQueryStringAccessor _queryStringAccessor; @@ -156,8 +156,8 @@ private string GetPageLink(ResourceContext resourceContext, int pageOffset, Page { return GetSelfTopLevelLink(resourceContext, parameters => { - var existingPageSizeParameterValue = parameters.ContainsKey(_pageSizeParameterName) - ? parameters[_pageSizeParameterName] + var existingPageSizeParameterValue = parameters.ContainsKey(PageSizeParameterName) + ? parameters[PageSizeParameterName] : null; PageSize newTopPageSize = Equals(pageSize, _options.DefaultPageSize) ? null : pageSize; @@ -165,20 +165,20 @@ private string GetPageLink(ResourceContext resourceContext, int pageOffset, Page string newPageSizeParameterValue = ChangeTopPageSize(existingPageSizeParameterValue, newTopPageSize); if (newPageSizeParameterValue == null) { - parameters.Remove(_pageSizeParameterName); + parameters.Remove(PageSizeParameterName); } else { - parameters[_pageSizeParameterName] = newPageSizeParameterValue; + parameters[PageSizeParameterName] = newPageSizeParameterValue; } if (pageOffset == 1) { - parameters.Remove(_pageNumberParameterName); + parameters.Remove(PageNumberParameterName); } else { - parameters[_pageNumberParameterName] = pageOffset.ToString(); + parameters[PageNumberParameterName] = pageOffset.ToString(); } }); } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/ActionResultTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/ActionResultTests.cs index 87c091a597..b1f459cf57 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/ActionResultTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/ActionResultTests.cs @@ -46,7 +46,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Converts_empty_ActionResult_to_error_collection() { // Arrange - var route = "/toothbrushes/" + BaseToothbrushesController._emptyActionResultId; + var route = "/toothbrushes/" + BaseToothbrushesController.EmptyActionResultId; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -64,7 +64,7 @@ public async Task Converts_empty_ActionResult_to_error_collection() public async Task Converts_ActionResult_with_error_object_to_error_collection() { // Arrange - var route = "/toothbrushes/" + BaseToothbrushesController._actionResultWithErrorObjectId; + var route = "/toothbrushes/" + BaseToothbrushesController.ActionResultWithErrorObjectId; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -82,7 +82,7 @@ public async Task Converts_ActionResult_with_error_object_to_error_collection() public async Task Cannot_convert_ActionResult_with_string_parameter_to_error_collection() { // Arrange - var route = "/toothbrushes/" + BaseToothbrushesController._actionResultWithStringParameter; + var route = "/toothbrushes/" + BaseToothbrushesController.ActionResultWithStringParameter; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -100,7 +100,7 @@ public async Task Cannot_convert_ActionResult_with_string_parameter_to_error_col public async Task Converts_ObjectResult_with_error_object_to_error_collection() { // Arrange - var route = "/toothbrushes/" + BaseToothbrushesController._objectResultWithErrorObjectId; + var route = "/toothbrushes/" + BaseToothbrushesController.ObjectResultWithErrorObjectId; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -118,7 +118,7 @@ public async Task Converts_ObjectResult_with_error_object_to_error_collection() public async Task Converts_ObjectResult_with_error_objects_to_error_collection() { // Arrange - var route = "/toothbrushes/" + BaseToothbrushesController._objectResultWithErrorCollectionId; + var route = "/toothbrushes/" + BaseToothbrushesController.ObjectResultWithErrorCollectionId; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/BaseToothbrushesController.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/BaseToothbrushesController.cs index 0b03712d62..460ea8cded 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/BaseToothbrushesController.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/BaseToothbrushesController.cs @@ -12,11 +12,11 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ControllerActionResults { public abstract class BaseToothbrushesController : BaseJsonApiController { - public const int _emptyActionResultId = 11111111; - public const int _actionResultWithErrorObjectId = 22222222; - public const int _actionResultWithStringParameter = 33333333; - public const int _objectResultWithErrorObjectId = 44444444; - public const int _objectResultWithErrorCollectionId = 55555555; + public const int EmptyActionResultId = 11111111; + public const int ActionResultWithErrorObjectId = 22222222; + public const int ActionResultWithStringParameter = 33333333; + public const int ObjectResultWithErrorObjectId = 44444444; + public const int ObjectResultWithErrorCollectionId = 55555555; protected BaseToothbrushesController(IJsonApiOptions options, ILoggerFactory loggerFactory, IResourceService resourceService) @@ -26,12 +26,12 @@ protected BaseToothbrushesController(IJsonApiOptions options, ILoggerFactory log public override async Task GetAsync(int id, CancellationToken cancellationToken) { - if (id == _emptyActionResultId) + if (id == EmptyActionResultId) { return NotFound(); } - if (id == _actionResultWithErrorObjectId) + if (id == ActionResultWithErrorObjectId) { return NotFound(new Error(HttpStatusCode.NotFound) { @@ -39,17 +39,17 @@ public override async Task GetAsync(int id, CancellationToken can }); } - if (id == _actionResultWithStringParameter) + if (id == ActionResultWithStringParameter) { return Conflict("Something went wrong."); } - if (id == _objectResultWithErrorObjectId) + if (id == ObjectResultWithErrorObjectId) { return Error(new Error(HttpStatusCode.BadGateway)); } - if (id == _objectResultWithErrorCollectionId) + if (id == ObjectResultWithErrorCollectionId) { var errors = new[] { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs index 2d867ea0f7..d6e498642e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs @@ -15,7 +15,7 @@ public sealed class ConsumerArticleService : JsonApiResourceService GetAsync(int id, CancellationToken c if (consumerArticle.Code.StartsWith(UnavailableArticlePrefix)) { - throw new ConsumerArticleIsNoLongerAvailableException(consumerArticle.Code, _supportEmailAddress); + throw new ConsumerArticleIsNoLongerAvailableException(consumerArticle.Code, SupportEmailAddress); } return consumerArticle; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs index 36520af65a..d629d4b4da 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs @@ -15,7 +15,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings.Pagination public sealed class PaginationWithTotalCountTests : IClassFixture, QueryStringDbContext>> { - private const int _defaultPageSize = 5; + private const int DefaultPageSize = 5; private readonly ExampleIntegrationTestContext, QueryStringDbContext> _testContext; private readonly QueryStringFakers _fakers = new QueryStringFakers(); @@ -26,7 +26,7 @@ public PaginationWithTotalCountTests(ExampleIntegrationTestContext(); options.IncludeTotalResourceCount = true; - options.DefaultPageSize = new PageSize(_defaultPageSize); + options.DefaultPageSize = new PageSize(DefaultPageSize); options.MaximumPageSize = null; options.MaximumPageNumber = null; options.AllowUnknownQueryStringParameters = true; @@ -522,7 +522,7 @@ public async Task Renders_correct_top_level_links_for_page_number(int pageNumber var account = _fakers.WebAccount.Generate(); account.UserName = "&" + account.UserName; - const int totalCount = 3 * _defaultPageSize + 3; + const int totalCount = 3 * DefaultPageSize + 3; var posts = _fakers.BlogPost.Generate(totalCount); foreach (var post in posts) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithoutTotalCountTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithoutTotalCountTests.cs index d6abbdb867..83ee1686e6 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithoutTotalCountTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithoutTotalCountTests.cs @@ -13,7 +13,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings.Pagination public sealed class PaginationWithoutTotalCountTests : IClassFixture, QueryStringDbContext>> { - private const int _defaultPageSize = 5; + private const int DefaultPageSize = 5; private readonly ExampleIntegrationTestContext, QueryStringDbContext> _testContext; private readonly QueryStringFakers _fakers = new QueryStringFakers(); @@ -25,7 +25,7 @@ public PaginationWithoutTotalCountTests(ExampleIntegrationTestContext(); options.IncludeTotalResourceCount = false; - options.DefaultPageSize = new PageSize(_defaultPageSize); + options.DefaultPageSize = new PageSize(DefaultPageSize); options.AllowUnknownQueryStringParameters = true; } @@ -128,7 +128,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.ManyData.Count.Should().BeLessThan(_defaultPageSize); + responseDocument.ManyData.Count.Should().BeLessThan(DefaultPageSize); responseDocument.Links.Should().NotBeNull(); responseDocument.Links.Self.Should().Be("http://localhost/blogPosts?foo=bar&page[number]=3"); @@ -142,7 +142,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Renders_pagination_links_when_page_number_is_specified_in_query_string_with_full_page() { // Arrange - var posts = _fakers.BlogPost.Generate(_defaultPageSize * 3); + var posts = _fakers.BlogPost.Generate(DefaultPageSize * 3); await _testContext.RunOnDatabaseAsync(async dbContext => { @@ -159,7 +159,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.ManyData.Should().HaveCount(_defaultPageSize); + responseDocument.ManyData.Should().HaveCount(DefaultPageSize); responseDocument.Links.Should().NotBeNull(); responseDocument.Links.Self.Should().Be("http://localhost/blogPosts?page[number]=3&foo=bar"); @@ -174,7 +174,7 @@ public async Task Renders_pagination_links_when_page_number_is_specified_in_quer { // Arrange var account = _fakers.WebAccount.Generate(); - account.Posts = _fakers.BlogPost.Generate(_defaultPageSize * 3); + account.Posts = _fakers.BlogPost.Generate(DefaultPageSize * 3); await _testContext.RunOnDatabaseAsync(async dbContext => { @@ -190,7 +190,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.ManyData.Should().HaveCount(_defaultPageSize); + responseDocument.ManyData.Should().HaveCount(DefaultPageSize); responseDocument.Links.Should().NotBeNull(); responseDocument.Links.Self.Should().Be($"http://localhost/webAccounts/{account.StringId}/posts?page[number]=3&foo=bar"); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs index 6625c0af05..1c03d45a4a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs @@ -16,14 +16,14 @@ public sealed class RangeValidationTests private readonly ExampleIntegrationTestContext, QueryStringDbContext> _testContext; private readonly QueryStringFakers _fakers = new QueryStringFakers(); - private const int _defaultPageSize = 5; + private const int DefaultPageSize = 5; public RangeValidationTests(ExampleIntegrationTestContext, QueryStringDbContext> testContext) { _testContext = testContext; var options = (JsonApiOptions) testContext.Factory.Services.GetRequiredService(); - options.DefaultPageSize = new PageSize(_defaultPageSize); + options.DefaultPageSize = new PageSize(DefaultPageSize); options.MaximumPageSize = null; options.MaximumPageNumber = null; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationWithMaximumTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationWithMaximumTests.cs index 5326c9724a..27c863273e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationWithMaximumTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationWithMaximumTests.cs @@ -15,8 +15,8 @@ public sealed class RangeValidationWithMaximumTests { private readonly ExampleIntegrationTestContext, QueryStringDbContext> _testContext; - private const int _maximumPageSize = 15; - private const int _maximumPageNumber = 20; + private const int MaximumPageSize = 15; + private const int MaximumPageNumber = 20; public RangeValidationWithMaximumTests(ExampleIntegrationTestContext, QueryStringDbContext> testContext) { @@ -24,15 +24,15 @@ public RangeValidationWithMaximumTests(ExampleIntegrationTestContext(); options.DefaultPageSize = new PageSize(5); - options.MaximumPageSize = new PageSize(_maximumPageSize); - options.MaximumPageNumber = new PageNumber(_maximumPageNumber); + options.MaximumPageSize = new PageSize(MaximumPageSize); + options.MaximumPageNumber = new PageNumber(MaximumPageNumber); } [Fact] public async Task Can_use_page_number_below_maximum() { // Arrange - const int pageNumber = _maximumPageNumber - 1; + const int pageNumber = MaximumPageNumber - 1; var route = "/blogs?page[number]=" + pageNumber; // Act @@ -46,7 +46,7 @@ public async Task Can_use_page_number_below_maximum() public async Task Can_use_page_number_equal_to_maximum() { // Arrange - const int pageNumber = _maximumPageNumber; + const int pageNumber = MaximumPageNumber; var route = "/blogs?page[number]=" + pageNumber; // Act @@ -60,7 +60,7 @@ public async Task Can_use_page_number_equal_to_maximum() public async Task Cannot_use_page_number_over_maximum() { // Arrange - const int pageNumber = _maximumPageNumber + 1; + const int pageNumber = MaximumPageNumber + 1; var route = "/blogs?page[number]=" + pageNumber; // Act @@ -72,7 +72,7 @@ public async Task Cannot_use_page_number_over_maximum() responseDocument.Errors.Should().HaveCount(1); responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); responseDocument.Errors[0].Title.Should().Be("The specified paging is invalid."); - responseDocument.Errors[0].Detail.Should().Be($"Page number cannot be higher than {_maximumPageNumber}."); + responseDocument.Errors[0].Detail.Should().Be($"Page number cannot be higher than {MaximumPageNumber}."); responseDocument.Errors[0].Source.Parameter.Should().Be("page[number]"); } @@ -99,7 +99,7 @@ public async Task Cannot_use_zero_page_size() public async Task Can_use_page_size_below_maximum() { // Arrange - const int pageSize = _maximumPageSize - 1; + const int pageSize = MaximumPageSize - 1; var route = "/blogs?page[size]=" + pageSize; // Act @@ -113,7 +113,7 @@ public async Task Can_use_page_size_below_maximum() public async Task Can_use_page_size_equal_to_maximum() { // Arrange - const int pageSize = _maximumPageSize; + const int pageSize = MaximumPageSize; var route = "/blogs?page[size]=" + pageSize; // Act @@ -127,7 +127,7 @@ public async Task Can_use_page_size_equal_to_maximum() public async Task Cannot_use_page_size_over_maximum() { // Arrange - const int pageSize = _maximumPageSize + 1; + const int pageSize = MaximumPageSize + 1; var route = "/blogs?page[size]=" + pageSize; // Act @@ -139,7 +139,7 @@ public async Task Cannot_use_page_size_over_maximum() responseDocument.Errors.Should().HaveCount(1); responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); responseDocument.Errors[0].Title.Should().Be("The specified paging is invalid."); - responseDocument.Errors[0].Detail.Should().Be($"Page size cannot be higher than {_maximumPageSize}."); + responseDocument.Errors[0].Detail.Should().Be($"Page size cannot be higher than {MaximumPageSize}."); responseDocument.Errors[0].Source.Parameter.Should().Be("page[size]"); } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/SkipCacheQueryStringParameterReader.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/SkipCacheQueryStringParameterReader.cs index a165357740..53faca19cc 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/SkipCacheQueryStringParameterReader.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/SkipCacheQueryStringParameterReader.cs @@ -8,18 +8,18 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.RestrictedControllers { public sealed class SkipCacheQueryStringParameterReader : IQueryStringParameterReader { - private const string _skipCacheParameterName = "skipCache"; + private const string SkipCacheParameterName = "skipCache"; public bool SkipCache { get; private set; } public bool IsEnabled(DisableQueryStringAttribute disableQueryStringAttribute) { - return !disableQueryStringAttribute.ParameterNames.Contains(_skipCacheParameterName); + return !disableQueryStringAttribute.ParameterNames.Contains(SkipCacheParameterName); } public bool CanRead(string parameterName) { - return parameterName == _skipCacheParameterName; + return parameterName == SkipCacheParameterName; } public void Read(string parameterName, StringValues parameterValue) diff --git a/test/UnitTests/Builders/ResourceGraphBuilder_Tests.cs b/test/UnitTests/Builders/ResourceGraphBuilderTests.cs similarity index 98% rename from test/UnitTests/Builders/ResourceGraphBuilder_Tests.cs rename to test/UnitTests/Builders/ResourceGraphBuilderTests.cs index 67a70175b0..a3ddfb5a31 100644 --- a/test/UnitTests/Builders/ResourceGraphBuilder_Tests.cs +++ b/test/UnitTests/Builders/ResourceGraphBuilderTests.cs @@ -11,7 +11,7 @@ namespace UnitTests.Builders { - public sealed class ResourceGraphBuilder_Tests + public sealed class ResourceGraphBuilderTests { private sealed class NonDbResource : Identifiable { } diff --git a/test/UnitTests/Controllers/BaseJsonApiController_Tests.cs b/test/UnitTests/Controllers/BaseJsonApiControllerTests.cs similarity index 99% rename from test/UnitTests/Controllers/BaseJsonApiController_Tests.cs rename to test/UnitTests/Controllers/BaseJsonApiControllerTests.cs index 977ab5890f..3a4dd66e27 100644 --- a/test/UnitTests/Controllers/BaseJsonApiController_Tests.cs +++ b/test/UnitTests/Controllers/BaseJsonApiControllerTests.cs @@ -17,7 +17,7 @@ namespace UnitTests.Controllers { - public sealed class BaseJsonApiController_Tests + public sealed class BaseJsonApiControllerTests { public sealed class Resource : Identifiable { diff --git a/test/UnitTests/Extensions/IServiceCollectionExtensionsTests.cs b/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs similarity index 99% rename from test/UnitTests/Extensions/IServiceCollectionExtensionsTests.cs rename to test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs index 533e69b5a0..2701e20019 100644 --- a/test/UnitTests/Extensions/IServiceCollectionExtensionsTests.cs +++ b/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs @@ -21,7 +21,7 @@ namespace UnitTests.Extensions { - public sealed class IServiceCollectionExtensionsTests + public sealed class ServiceCollectionExtensionsTests { [Fact] public void AddJsonApiInternals_Adds_All_Required_Services() diff --git a/test/UnitTests/Graph/TypeLocator_Tests.cs b/test/UnitTests/Graph/TypeLocatorTests.cs similarity index 98% rename from test/UnitTests/Graph/TypeLocator_Tests.cs rename to test/UnitTests/Graph/TypeLocatorTests.cs index 4096b04062..fd3bdebd68 100644 --- a/test/UnitTests/Graph/TypeLocator_Tests.cs +++ b/test/UnitTests/Graph/TypeLocatorTests.cs @@ -4,7 +4,7 @@ namespace UnitTests.Graph { - public sealed class TypeLocator_Tests + public sealed class TypeLocatorTests { [Fact] public void GetGenericInterfaceImplementation_Gets_Implementation() diff --git a/test/UnitTests/Internal/TypeHelper_Tests.cs b/test/UnitTests/Internal/TypeHelperTests.cs similarity index 99% rename from test/UnitTests/Internal/TypeHelper_Tests.cs rename to test/UnitTests/Internal/TypeHelperTests.cs index bf085af33f..982b966036 100644 --- a/test/UnitTests/Internal/TypeHelper_Tests.cs +++ b/test/UnitTests/Internal/TypeHelperTests.cs @@ -6,7 +6,7 @@ namespace UnitTests.Internal { - public sealed class TypeHelper_Tests + public sealed class TypeHelperTests { [Fact] public void Can_Convert_DateTimeOffsets() diff --git a/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs b/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs index ab1fd806b5..72228aea78 100644 --- a/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs +++ b/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs @@ -70,12 +70,12 @@ public async Task ParseUrlBase_UrlHasNegativePrimaryIdAndTypeIsInt_ShouldNotThro private sealed class InvokeConfiguration { - public JsonApiMiddleware MiddleWare; - public HttpContext HttpContext; - public Mock ControllerResourceMapping; - public Mock Options; - public JsonApiRequest Request; - public Mock ResourceGraph; + public JsonApiMiddleware MiddleWare { get; set; } + public HttpContext HttpContext { get; set; } + public Mock ControllerResourceMapping { get; set; } + public Mock Options { get; set; } + public JsonApiRequest Request { get; set; } + public Mock ResourceGraph { get; set; } } private Task RunMiddlewareTask(InvokeConfiguration holder) { diff --git a/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateTests.cs b/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateTests.cs index 86623c3370..83aa1bd0bf 100644 --- a/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateTests.cs @@ -8,14 +8,14 @@ namespace UnitTests.ResourceHooks.Executor.Create { public sealed class BeforeCreateTests : HooksTestsSetup { - private readonly ResourceHook[] targetHooks = { ResourceHook.BeforeCreate, ResourceHook.BeforeUpdateRelationship }; + private readonly ResourceHook[] _targetHooks = { ResourceHook.BeforeCreate, ResourceHook.BeforeUpdateRelationship }; [Fact] public void BeforeCreate() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var personDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var personDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, todoResourceMock, ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery); var todoList = CreateTodoWithOwner(); @@ -33,7 +33,7 @@ public void BeforeCreate_Without_Parent_Hook_Implemented() { // Arrange var todoDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); - var personDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var personDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, todoResourceMock, ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery); var todoList = CreateTodoWithOwner(); @@ -49,7 +49,7 @@ public void BeforeCreate_Without_Parent_Hook_Implemented() public void BeforeCreate_Without_Child_Hook_Implemented() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var personDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (_, _, hookExecutor, todoResourceMock, ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery); diff --git a/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreate_WithDbValues_Tests.cs b/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateWithDbValuesTests.cs similarity index 91% rename from test/UnitTests/ResourceHooks/Executor/Create/BeforeCreate_WithDbValues_Tests.cs rename to test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateWithDbValuesTests.cs index bde79dcd93..d6609da6d2 100644 --- a/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreate_WithDbValues_Tests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateWithDbValuesTests.cs @@ -9,30 +9,30 @@ namespace UnitTests.ResourceHooks.Executor.Create { - public sealed class BeforeCreate_WithDbValues_Tests : HooksTestsSetup + public sealed class BeforeCreateWithDbValuesTests : HooksTestsSetup { private readonly ResourceHook[] _targetHooks = { ResourceHook.BeforeCreate, ResourceHook.BeforeImplicitUpdateRelationship, ResourceHook.BeforeUpdateRelationship }; private readonly ResourceHook[] _targetHooksNoImplicit = { ResourceHook.BeforeCreate, ResourceHook.BeforeUpdateRelationship }; - private const string _description = "DESCRIPTION"; - private const string _lastName = "NAME"; + private const string Description = "DESCRIPTION"; + private const string LastName = "NAME"; private readonly string _personId; private readonly List _todoList; private readonly DbContextOptions _options; - public BeforeCreate_WithDbValues_Tests() + public BeforeCreateWithDbValuesTests() { _todoList = CreateTodoWithToOnePerson(); _todoList[0].Id = 0; - _todoList[0].Description = _description; + _todoList[0].Description = Description; var person = _todoList[0].OneToOnePerson; - person.LastName = _lastName; + person.LastName = LastName; _personId = person.Id.ToString(); var implicitTodo = _todoFaker.Generate(); implicitTodo.Id += 1000; implicitTodo.OneToOnePerson = person; - implicitTodo.Description = _description + _description; + implicitTodo.Description = Description + Description; _options = InitInMemoryDb(context => { @@ -56,14 +56,14 @@ public void BeforeCreate() hookExecutor.BeforeCreate(_todoList, ResourcePipeline.Post); // Assert - todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>((resources) => TodoCheck(resources, _description)), ResourcePipeline.Post), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>((resources) => TodoCheck(resources, Description)), ResourcePipeline.Post), Times.Once()); ownerResourceMock.Verify(rd => rd.BeforeUpdateRelationship( It.Is>(ids => PersonIdCheck(ids, _personId)), It.IsAny>(), ResourcePipeline.Post), Times.Once()); todoResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship( - It.Is>(rh => TodoCheckRelationships(rh, _description + _description)), + It.Is>(rh => TodoCheckRelationships(rh, Description + Description)), ResourcePipeline.Post), Times.Once()); VerifyNoOtherCalls(todoResourceMock, ownerResourceMock); @@ -101,9 +101,9 @@ public void BeforeCreate_Without_Child_Hook_Implemented() hookExecutor.BeforeCreate(_todoList, ResourcePipeline.Post); // Assert - todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>((resources) => TodoCheck(resources, _description)), ResourcePipeline.Post), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>((resources) => TodoCheck(resources, Description)), ResourcePipeline.Post), Times.Once()); todoResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship( - It.Is>(rh => TodoCheckRelationships(rh, _description + _description)), + It.Is>(rh => TodoCheckRelationships(rh, Description + Description)), ResourcePipeline.Post), Times.Once()); VerifyNoOtherCalls(todoResourceMock, ownerResourceMock); @@ -121,7 +121,7 @@ public void BeforeCreate_NoImplicit() hookExecutor.BeforeCreate(_todoList, ResourcePipeline.Post); // Assert - todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>((resources) => TodoCheck(resources, _description)), ResourcePipeline.Post), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>((resources) => TodoCheck(resources, Description)), ResourcePipeline.Post), Times.Once()); ownerResourceMock.Verify(rd => rd.BeforeUpdateRelationship( It.Is>(ids => PersonIdCheck(ids, _personId)), It.IsAny>(), @@ -162,7 +162,7 @@ public void BeforeCreate_NoImplicit_Without_Child_Hook_Implemented() hookExecutor.BeforeCreate(_todoList, ResourcePipeline.Post); // Assert - todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>((resources) => TodoCheck(resources, _description)), ResourcePipeline.Post), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>((resources) => TodoCheck(resources, Description)), ResourcePipeline.Post), Times.Once()); VerifyNoOtherCalls(todoResourceMock, ownerResourceMock); } diff --git a/test/UnitTests/ResourceHooks/Executor/Delete/AfterDeleteTests.cs b/test/UnitTests/ResourceHooks/Executor/Delete/AfterDeleteTests.cs index adeeb67f1c..e8f9f30f73 100644 --- a/test/UnitTests/ResourceHooks/Executor/Delete/AfterDeleteTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Delete/AfterDeleteTests.cs @@ -8,13 +8,13 @@ namespace UnitTests.ResourceHooks.Executor.Delete { public sealed class AfterDeleteTests : HooksTestsSetup { - private readonly ResourceHook[] targetHooks = { ResourceHook.AfterDelete }; + private readonly ResourceHook[] _targetHooks = { ResourceHook.AfterDelete }; [Fact] public void AfterDelete() { // Arrange - var discovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var discovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, hookExecutor, resourceDefinitionMock) = CreateTestObjects(discovery); var todoList = CreateTodoWithOwner(); diff --git a/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteTests.cs b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteTests.cs index 2dd9755fdd..0dfd223ad7 100644 --- a/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteTests.cs @@ -7,13 +7,13 @@ namespace UnitTests.ResourceHooks.Executor.Delete { public sealed class BeforeDeleteTests : HooksTestsSetup { - private readonly ResourceHook[] targetHooks = { ResourceHook.BeforeDelete }; + private readonly ResourceHook[] _targetHooks = { ResourceHook.BeforeDelete }; [Fact] public void BeforeDelete() { // Arrange - var discovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var discovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, hookExecutor, resourceDefinitionMock) = CreateTestObjects(discovery); var todoList = CreateTodoWithOwner(); diff --git a/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDelete_WithDbValues_Tests.cs b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs similarity index 68% rename from test/UnitTests/ResourceHooks/Executor/Delete/BeforeDelete_WithDbValues_Tests.cs rename to test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs index 80b319708a..6ab1a45d67 100644 --- a/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDelete_WithDbValues_Tests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs @@ -9,25 +9,25 @@ namespace UnitTests.ResourceHooks.Executor.Delete { - public sealed class BeforeDelete_WithDbValues_Tests : HooksTestsSetup + public sealed class BeforeDeleteWithDbValuesTests : HooksTestsSetup { - private readonly ResourceHook[] targetHooks = { ResourceHook.BeforeDelete, ResourceHook.BeforeImplicitUpdateRelationship, ResourceHook.BeforeUpdateRelationship }; + private readonly ResourceHook[] _targetHooks = { ResourceHook.BeforeDelete, ResourceHook.BeforeImplicitUpdateRelationship, ResourceHook.BeforeUpdateRelationship }; - private readonly DbContextOptions options; - private readonly Person person; - public BeforeDelete_WithDbValues_Tests() + private readonly DbContextOptions _options; + private readonly Person _person; + public BeforeDeleteWithDbValuesTests() { - person = _personFaker.Generate(); + _person = _personFaker.Generate(); var todo1 = _todoFaker.Generate(); var todo2 = _todoFaker.Generate(); var passport = _passportFaker.Generate(); - person.Passport = passport; - person.TodoItems = new HashSet { todo1 }; - person.StakeHolderTodoItem = todo2; - options = InitInMemoryDb(context => + _person.Passport = passport; + _person.TodoItems = new HashSet { todo1 }; + _person.StakeHolderTodoItem = todo2; + _options = InitInMemoryDb(context => { - context.Set().Add(person); + context.Set().Add(_person); context.SaveChanges(); }); } @@ -36,13 +36,13 @@ public BeforeDelete_WithDbValues_Tests() public void BeforeDelete() { // Arrange - var personDiscovery = SetDiscoverableHooks(targetHooks, EnableDbValues); - var todoDiscovery = SetDiscoverableHooks(targetHooks, EnableDbValues); - var passportDiscovery = SetDiscoverableHooks(targetHooks, EnableDbValues); - var (_, hookExecutor, personResourceMock, todoResourceMock, passportResourceMock) = CreateTestObjects(personDiscovery, todoDiscovery, passportDiscovery, repoDbContextOptions: options); + var personDiscovery = SetDiscoverableHooks(_targetHooks, EnableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, EnableDbValues); + var passportDiscovery = SetDiscoverableHooks(_targetHooks, EnableDbValues); + var (_, hookExecutor, personResourceMock, todoResourceMock, passportResourceMock) = CreateTestObjects(personDiscovery, todoDiscovery, passportDiscovery, repoDbContextOptions: _options); // Act - hookExecutor.BeforeDelete(new List { person }, ResourcePipeline.Delete); + hookExecutor.BeforeDelete(new List { _person }, ResourcePipeline.Delete); // Assert personResourceMock.Verify(rd => rd.BeforeDelete(It.IsAny>(), It.IsAny()), Times.Once()); @@ -56,12 +56,12 @@ public void BeforeDelete_No_Parent_Hooks() { // Arrange var personDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); - var todoDiscovery = SetDiscoverableHooks(targetHooks, EnableDbValues); - var passportDiscovery = SetDiscoverableHooks(targetHooks, EnableDbValues); - var (_, hookExecutor, personResourceMock, todoResourceMock, passportResourceMock) = CreateTestObjects(personDiscovery, todoDiscovery, passportDiscovery, repoDbContextOptions: options); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, EnableDbValues); + var passportDiscovery = SetDiscoverableHooks(_targetHooks, EnableDbValues); + var (_, hookExecutor, personResourceMock, todoResourceMock, passportResourceMock) = CreateTestObjects(personDiscovery, todoDiscovery, passportDiscovery, repoDbContextOptions: _options); // Act - hookExecutor.BeforeDelete(new List { person }, ResourcePipeline.Delete); + hookExecutor.BeforeDelete(new List { _person }, ResourcePipeline.Delete); // Assert todoResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship(It.Is>(rh => CheckImplicitTodos(rh)), ResourcePipeline.Delete), Times.Once()); @@ -73,13 +73,13 @@ public void BeforeDelete_No_Parent_Hooks() public void BeforeDelete_No_Children_Hooks() { // Arrange - var personDiscovery = SetDiscoverableHooks(targetHooks, EnableDbValues); + var personDiscovery = SetDiscoverableHooks(_targetHooks, EnableDbValues); var todoDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var passportDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); - var (_, hookExecutor, personResourceMock, todoResourceMock, passportResourceMock) = CreateTestObjects(personDiscovery, todoDiscovery, passportDiscovery, repoDbContextOptions: options); + var (_, hookExecutor, personResourceMock, todoResourceMock, passportResourceMock) = CreateTestObjects(personDiscovery, todoDiscovery, passportDiscovery, repoDbContextOptions: _options); // Act - hookExecutor.BeforeDelete(new List { person }, ResourcePipeline.Delete); + hookExecutor.BeforeDelete(new List { _person }, ResourcePipeline.Delete); // Assert personResourceMock.Verify(rd => rd.BeforeDelete(It.IsAny>(), It.IsAny()), Times.Once()); diff --git a/test/UnitTests/ResourceHooks/Executor/IdentifiableManyToMany_OnReturnTests.cs b/test/UnitTests/ResourceHooks/Executor/IdentifiableManyToManyOnReturnTests.cs similarity index 89% rename from test/UnitTests/ResourceHooks/Executor/IdentifiableManyToMany_OnReturnTests.cs rename to test/UnitTests/ResourceHooks/Executor/IdentifiableManyToManyOnReturnTests.cs index 0a666c83b8..e71649214e 100644 --- a/test/UnitTests/ResourceHooks/Executor/IdentifiableManyToMany_OnReturnTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/IdentifiableManyToManyOnReturnTests.cs @@ -7,17 +7,17 @@ namespace UnitTests.ResourceHooks.Executor { - public sealed class IdentifiableManyToMany_OnReturnTests : HooksTestsSetup + public sealed class IdentifiableManyToManyOnReturnTests : HooksTestsSetup { - private readonly ResourceHook[] targetHooks = { ResourceHook.OnReturn }; + private readonly ResourceHook[] _targetHooks = { ResourceHook.OnReturn }; [Fact] public void OnReturn() { // Arrange - var articleDiscovery = SetDiscoverableHooks
(targetHooks, DisableDbValues); - var joinDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var tagDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var articleDiscovery = SetDiscoverableHooks
(_targetHooks, DisableDbValues); + var joinDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, hookExecutor, articleResourceMock, joinResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, joinDiscovery, tagDiscovery); var (articles, joins, tags) = CreateIdentifiableManyToManyData(); @@ -35,9 +35,9 @@ public void OnReturn() public void OnReturn_GetRelationship() { // Arrange - var articleDiscovery = SetDiscoverableHooks
(targetHooks, DisableDbValues); - var joinDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var tagDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var articleDiscovery = SetDiscoverableHooks
(_targetHooks, DisableDbValues); + var joinDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, hookExecutor, articleResourceMock, joinResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, joinDiscovery, tagDiscovery); var (articles, joins, tags) = CreateIdentifiableManyToManyData(); @@ -56,8 +56,8 @@ public void OnReturn_Without_Parent_Hook_Implemented() { // Arrange var articleDiscovery = SetDiscoverableHooks
(NoHooks, DisableDbValues); - var joinDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var tagDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var joinDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, hookExecutor, articleResourceMock, joinResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, joinDiscovery, tagDiscovery); var (articles, joins, tags) = CreateIdentifiableManyToManyData(); @@ -74,9 +74,9 @@ public void OnReturn_Without_Parent_Hook_Implemented() public void OnReturn_Without_Children_Hooks_Implemented() { // Arrange - var articleDiscovery = SetDiscoverableHooks
(targetHooks, DisableDbValues); + var articleDiscovery = SetDiscoverableHooks
(_targetHooks, DisableDbValues); var joinDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); - var tagDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, hookExecutor, articleResourceMock, joinResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, joinDiscovery, tagDiscovery); var (articles, _, tags) = CreateIdentifiableManyToManyData(); @@ -94,8 +94,8 @@ public void OnReturn_Without_Children_Hooks_Implemented() public void OnReturn_Without_Grand_Children_Hooks_Implemented() { // Arrange - var articleDiscovery = SetDiscoverableHooks
(targetHooks, DisableDbValues); - var joinDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var articleDiscovery = SetDiscoverableHooks
(_targetHooks, DisableDbValues); + var joinDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var tagDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (_, hookExecutor, articleResourceMock, joinResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, joinDiscovery, tagDiscovery); var (articles, joins, _) = CreateIdentifiableManyToManyData(); @@ -113,7 +113,7 @@ public void OnReturn_Without_Grand_Children_Hooks_Implemented() public void OnReturn_Without_Any_Descendant_Hooks_Implemented() { // Arrange - var articleDiscovery = SetDiscoverableHooks
(targetHooks, DisableDbValues); + var articleDiscovery = SetDiscoverableHooks
(_targetHooks, DisableDbValues); var joinDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var tagDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (_, hookExecutor, articleResourceMock, joinResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, joinDiscovery, tagDiscovery); diff --git a/test/UnitTests/ResourceHooks/Executor/ManyToMany_OnReturnTests.cs b/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs similarity index 91% rename from test/UnitTests/ResourceHooks/Executor/ManyToMany_OnReturnTests.cs rename to test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs index afaa4500dc..6410f17a34 100644 --- a/test/UnitTests/ResourceHooks/Executor/ManyToMany_OnReturnTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs @@ -7,9 +7,9 @@ namespace UnitTests.ResourceHooks.Executor { - public sealed class ManyToMany_OnReturnTests : HooksTestsSetup + public sealed class ManyToManyOnReturnTests : HooksTestsSetup { - private readonly ResourceHook[] targetHooks = { ResourceHook.OnReturn }; + private readonly ResourceHook[] _targetHooks = { ResourceHook.OnReturn }; private (List
, List, List) CreateDummyData() { @@ -45,8 +45,8 @@ public sealed class ManyToMany_OnReturnTests : HooksTestsSetup public void OnReturn() { // Arrange - var articleDiscovery = SetDiscoverableHooks
(targetHooks, DisableDbValues); - var tagDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var articleDiscovery = SetDiscoverableHooks
(_targetHooks, DisableDbValues); + var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); var (articles, _, tags) = CreateDummyData(); @@ -64,7 +64,7 @@ public void OnReturn_Without_Parent_Hook_Implemented() { // Arrange var articleDiscovery = SetDiscoverableHooks
(NoHooks, DisableDbValues); - var tagDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); var (articles, _, tags) = CreateDummyData(); @@ -80,7 +80,7 @@ public void OnReturn_Without_Parent_Hook_Implemented() public void OnReturn_Without_Children_Hooks_Implemented() { // Arrange - var articleDiscovery = SetDiscoverableHooks
(targetHooks, DisableDbValues); + var articleDiscovery = SetDiscoverableHooks
(_targetHooks, DisableDbValues); var tagDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); var (articles, _, _) = CreateDummyData(); diff --git a/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs b/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs index 598d786f07..1c95e78f03 100644 --- a/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs @@ -9,13 +9,13 @@ namespace UnitTests.ResourceHooks.Executor.Read { public sealed class BeforeReadTests : HooksTestsSetup { - private readonly ResourceHook[] targetHooks = { ResourceHook.BeforeRead }; + private readonly ResourceHook[] _targetHooks = { ResourceHook.BeforeRead }; [Fact] public void BeforeRead() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, hookExecutor, todoResourceMock) = CreateTestObjects(todoDiscovery); // Act @@ -30,8 +30,8 @@ public void BeforeRead() public void BeforeReadWithInclusion() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var personDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var personDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (constraintsMock, _, hookExecutor, todoResourceMock, ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery); @@ -51,9 +51,9 @@ public void BeforeReadWithInclusion() public void BeforeReadWithNestedInclusion() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var personDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var passportDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var personDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var passportDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (constraintsMock, hookExecutor, todoResourceMock, ownerResourceMock, passportResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery, passportDiscovery); @@ -76,8 +76,8 @@ public void BeforeReadWithNestedInclusion_No_Parent_Hook_Implemented() { // Arrange var todoDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); - var personDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var passportDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var personDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var passportDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (constraintsMock, hookExecutor, todoResourceMock, ownerResourceMock, passportResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery, passportDiscovery); @@ -97,9 +97,9 @@ public void BeforeReadWithNestedInclusion_No_Parent_Hook_Implemented() public void BeforeReadWithNestedInclusion_No_Child_Hook_Implemented() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var personDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); - var passportDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var passportDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (constraintsMock, hookExecutor, todoResourceMock, ownerResourceMock, passportResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery, passportDiscovery); @@ -119,8 +119,8 @@ public void BeforeReadWithNestedInclusion_No_Child_Hook_Implemented() public void BeforeReadWithNestedInclusion_No_Grandchild_Hook_Implemented() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var personDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var personDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var passportDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (constraintsMock, hookExecutor, todoResourceMock, ownerResourceMock, passportResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery, passportDiscovery); diff --git a/test/UnitTests/ResourceHooks/Executor/Read/IdentifiableManyToMany_AfterReadTests.cs b/test/UnitTests/ResourceHooks/Executor/Read/IdentifiableManyToManyAfterReadTests.cs similarity index 90% rename from test/UnitTests/ResourceHooks/Executor/Read/IdentifiableManyToMany_AfterReadTests.cs rename to test/UnitTests/ResourceHooks/Executor/Read/IdentifiableManyToManyAfterReadTests.cs index 3d9a885fee..3b3ac5973d 100644 --- a/test/UnitTests/ResourceHooks/Executor/Read/IdentifiableManyToMany_AfterReadTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Read/IdentifiableManyToManyAfterReadTests.cs @@ -7,17 +7,17 @@ namespace UnitTests.ResourceHooks.Executor.Read { - public sealed class IdentifiableManyToMany_AfterReadTests : HooksTestsSetup + public sealed class IdentifiableManyToManyAfterReadTests : HooksTestsSetup { - private readonly ResourceHook[] targetHooks = { ResourceHook.AfterRead }; + private readonly ResourceHook[] _targetHooks = { ResourceHook.AfterRead }; [Fact] public void AfterRead() { // Arrange - var articleDiscovery = SetDiscoverableHooks
(targetHooks, DisableDbValues); - var joinDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var tagDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var articleDiscovery = SetDiscoverableHooks
(_targetHooks, DisableDbValues); + var joinDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, hookExecutor, articleResourceMock, joinResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, joinDiscovery, tagDiscovery); var (articles, joins, tags) = CreateIdentifiableManyToManyData(); @@ -36,8 +36,8 @@ public void AfterRead_Without_Parent_Hook_Implemented() { // Arrange var articleDiscovery = SetDiscoverableHooks
(NoHooks, DisableDbValues); - var joinDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var tagDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var joinDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, hookExecutor, articleResourceMock, joinResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, joinDiscovery, tagDiscovery); var (articles, joins, tags) = CreateIdentifiableManyToManyData(); @@ -54,9 +54,9 @@ public void AfterRead_Without_Parent_Hook_Implemented() public void AfterRead_Without_Children_Hooks_Implemented() { // Arrange - var articleDiscovery = SetDiscoverableHooks
(targetHooks, DisableDbValues); + var articleDiscovery = SetDiscoverableHooks
(_targetHooks, DisableDbValues); var joinDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); - var tagDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, hookExecutor, articleResourceMock, joinResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, joinDiscovery, tagDiscovery); @@ -75,8 +75,8 @@ public void AfterRead_Without_Children_Hooks_Implemented() public void AfterRead_Without_Grand_Children_Hooks_Implemented() { // Arrange - var articleDiscovery = SetDiscoverableHooks
(targetHooks, DisableDbValues); - var joinDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var articleDiscovery = SetDiscoverableHooks
(_targetHooks, DisableDbValues); + var joinDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var tagDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (_, hookExecutor, articleResourceMock, joinResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, joinDiscovery, tagDiscovery); var (articles, joins, _) = CreateIdentifiableManyToManyData(); @@ -94,7 +94,7 @@ public void AfterRead_Without_Grand_Children_Hooks_Implemented() public void AfterRead_Without_Any_Descendant_Hooks_Implemented() { // Arrange - var articleDiscovery = SetDiscoverableHooks
(targetHooks, DisableDbValues); + var articleDiscovery = SetDiscoverableHooks
(_targetHooks, DisableDbValues); var joinDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var tagDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (_, hookExecutor, articleResourceMock, joinResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, joinDiscovery, tagDiscovery); diff --git a/test/UnitTests/ResourceHooks/Executor/Read/ManyToMany_AfterReadTests.cs b/test/UnitTests/ResourceHooks/Executor/Read/ManyToManyAfterReadTests.cs similarity index 89% rename from test/UnitTests/ResourceHooks/Executor/Read/ManyToMany_AfterReadTests.cs rename to test/UnitTests/ResourceHooks/Executor/Read/ManyToManyAfterReadTests.cs index a55a94c8e4..10f169ac2a 100644 --- a/test/UnitTests/ResourceHooks/Executor/Read/ManyToMany_AfterReadTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Read/ManyToManyAfterReadTests.cs @@ -7,16 +7,16 @@ namespace UnitTests.ResourceHooks.Executor.Read { - public sealed class ManyToMany_AfterReadTests : HooksTestsSetup + public sealed class ManyToManyAfterReadTests : HooksTestsSetup { - private readonly ResourceHook[] targetHooks = { ResourceHook.AfterRead }; + private readonly ResourceHook[] _targetHooks = { ResourceHook.AfterRead }; [Fact] public void AfterRead() { // Arrange - var articleDiscovery = SetDiscoverableHooks
(targetHooks, DisableDbValues); - var tagDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var articleDiscovery = SetDiscoverableHooks
(_targetHooks, DisableDbValues); + var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); var (articles, _, tags) = CreateManyToManyData(); @@ -34,7 +34,7 @@ public void AfterRead_Without_Parent_Hook_Implemented() { // Arrange var articleDiscovery = SetDiscoverableHooks
(NoHooks, DisableDbValues); - var tagDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); var (articles, _, tags) = CreateManyToManyData(); @@ -50,7 +50,7 @@ public void AfterRead_Without_Parent_Hook_Implemented() public void AfterRead_Without_Children_Hooks_Implemented() { // Arrange - var articleDiscovery = SetDiscoverableHooks
(targetHooks, DisableDbValues); + var articleDiscovery = SetDiscoverableHooks
(_targetHooks, DisableDbValues); var tagDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); var (articles, _, _) = CreateManyToManyData(); diff --git a/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs b/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs index 1f210cd67f..ffe7d90511 100644 --- a/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs @@ -8,14 +8,14 @@ namespace UnitTests.ResourceHooks.Executor { public sealed class SameResourceTypeTests : HooksTestsSetup { - private readonly ResourceHook[] targetHooks = { ResourceHook.OnReturn }; + private readonly ResourceHook[] _targetHooks = { ResourceHook.OnReturn }; [Fact] public void Resource_Has_Multiple_Relations_To_Same_Type() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var personDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var personDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, todoResourceMock, ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery); var person1 = new Person(); var todo = new TodoItem { Owner = person1 }; @@ -38,7 +38,7 @@ public void Resource_Has_Multiple_Relations_To_Same_Type() public void Resource_Has_Cyclic_Relations() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, hookExecutor, todoResourceMock) = CreateTestObjects(todoDiscovery); var todo = new TodoItem(); todo.ParentTodo = todo; @@ -57,7 +57,7 @@ public void Resource_Has_Cyclic_Relations() public void Resource_Has_Nested_Cyclic_Relations() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, hookExecutor, todoResourceMock) = CreateTestObjects(todoDiscovery); var rootTodo = new TodoItem { Id = 1 }; var child = new TodoItem { ParentTodo = rootTodo, Id = 2 }; diff --git a/test/UnitTests/ResourceHooks/Executor/Update/AfterUpdateTests.cs b/test/UnitTests/ResourceHooks/Executor/Update/AfterUpdateTests.cs index c36d19b3ad..e8a2127335 100644 --- a/test/UnitTests/ResourceHooks/Executor/Update/AfterUpdateTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Update/AfterUpdateTests.cs @@ -8,14 +8,14 @@ namespace UnitTests.ResourceHooks.Executor.Update { public sealed class AfterUpdateTests : HooksTestsSetup { - private readonly ResourceHook[] targetHooks = { ResourceHook.AfterUpdate, ResourceHook.AfterUpdateRelationship }; + private readonly ResourceHook[] _targetHooks = { ResourceHook.AfterUpdate, ResourceHook.AfterUpdateRelationship }; [Fact] public void AfterUpdate() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var personDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var personDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, todoResourceMock, ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery); var todoList = CreateTodoWithOwner(); @@ -33,7 +33,7 @@ public void AfterUpdate_Without_Parent_Hook_Implemented() { // Arrange var todoDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); - var personDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var personDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, todoResourceMock, ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery); var todoList = CreateTodoWithOwner(); @@ -49,7 +49,7 @@ public void AfterUpdate_Without_Parent_Hook_Implemented() public void AfterUpdate_Without_Child_Hook_Implemented() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var personDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (_, _, hookExecutor, todoResourceMock, ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery); var todoList = CreateTodoWithOwner(); diff --git a/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateTests.cs b/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateTests.cs index f8307ac346..6ed75e9d19 100644 --- a/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateTests.cs @@ -8,14 +8,14 @@ namespace UnitTests.ResourceHooks.Executor.Update { public sealed class BeforeUpdateTests : HooksTestsSetup { - private readonly ResourceHook[] targetHooks = { ResourceHook.BeforeUpdate, ResourceHook.BeforeUpdateRelationship }; + private readonly ResourceHook[] _targetHooks = { ResourceHook.BeforeUpdate, ResourceHook.BeforeUpdateRelationship }; [Fact] public void BeforeUpdate() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); - var personDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); + var personDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, todoResourceMock, ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery); var todoList = CreateTodoWithOwner(); @@ -33,7 +33,7 @@ public void BeforeUpdate_Without_Parent_Hook_Implemented() { // Arrange var todoDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); - var personDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var personDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, todoResourceMock, ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery); var todoList = CreateTodoWithOwner(); @@ -49,7 +49,7 @@ public void BeforeUpdate_Without_Parent_Hook_Implemented() public void BeforeUpdate_Without_Child_Hook_Implemented() { // Arrange - var todoDiscovery = SetDiscoverableHooks(targetHooks, DisableDbValues); + var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var personDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (_, _, hookExecutor, todoResourceMock, ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery); diff --git a/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdate_WithDbValues_Tests.cs b/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateWithDbValuesTests.cs similarity index 90% rename from test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdate_WithDbValues_Tests.cs rename to test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateWithDbValuesTests.cs index 9f15b727c8..e691690b18 100644 --- a/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdate_WithDbValues_Tests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateWithDbValuesTests.cs @@ -9,18 +9,18 @@ namespace UnitTests.ResourceHooks.Executor.Update { - public sealed class BeforeUpdate_WithDbValues_Tests : HooksTestsSetup + public sealed class BeforeUpdateWithDbValuesTests : HooksTestsSetup { private readonly ResourceHook[] _targetHooks = { ResourceHook.BeforeUpdate, ResourceHook.BeforeImplicitUpdateRelationship, ResourceHook.BeforeUpdateRelationship }; private readonly ResourceHook[] _targetHooksNoImplicit = { ResourceHook.BeforeUpdate, ResourceHook.BeforeUpdateRelationship }; - private const string _description = "DESCRIPTION"; - private const string _lastName = "NAME"; + private const string Description = "DESCRIPTION"; + private const string LastName = "NAME"; private readonly string _personId; private readonly List _todoList; private readonly DbContextOptions _options; - public BeforeUpdate_WithDbValues_Tests() + public BeforeUpdateWithDbValuesTests() { _todoList = CreateTodoWithToOnePerson(); @@ -31,12 +31,12 @@ public BeforeUpdate_WithDbValues_Tests() var implicitTodo = _todoFaker.Generate(); implicitTodo.Id += 1000; - implicitTodo.OneToOnePerson = new Person {Id = personId, LastName = _lastName}; - implicitTodo.Description = _description + _description; + implicitTodo.OneToOnePerson = new Person {Id = personId, LastName = LastName}; + implicitTodo.Description = Description + Description; _options = InitInMemoryDb(context => { - context.Set().Add(new TodoItem {Id = todoId, OneToOnePerson = new Person {Id = implicitPersonId, LastName = _lastName + _lastName}, Description = _description}); + context.Set().Add(new TodoItem {Id = todoId, OneToOnePerson = new Person {Id = implicitPersonId, LastName = LastName + LastName}, Description = Description}); context.Set().Add(implicitTodo); context.SaveChanges(); }); @@ -54,18 +54,18 @@ public void BeforeUpdate() hookExecutor.BeforeUpdate(_todoList, ResourcePipeline.Patch); // Assert - todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, _description)), ResourcePipeline.Patch), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); ownerResourceMock.Verify(rd => rd.BeforeUpdateRelationship( It.Is>(ids => PersonIdCheck(ids, _personId)), - It.Is>(rh => PersonCheck(_lastName, rh)), + It.Is>(rh => PersonCheck(LastName, rh)), ResourcePipeline.Patch), Times.Once()); ownerResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship( - It.Is>(rh => PersonCheck(_lastName + _lastName, rh)), + It.Is>(rh => PersonCheck(LastName + LastName, rh)), ResourcePipeline.Patch), Times.Once()); todoResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship( - It.Is>(rh => TodoCheck(rh, _description + _description)), + It.Is>(rh => TodoCheck(rh, Description + Description)), ResourcePipeline.Patch), Times.Once()); VerifyNoOtherCalls(todoResourceMock, ownerResourceMock); @@ -80,16 +80,16 @@ public void BeforeUpdate_Deleting_Relationship() var personDiscovery = SetDiscoverableHooks(_targetHooks, EnableDbValues); var (_, ufMock, hookExecutor, todoResourceMock, ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery, repoDbContextOptions: _options); - ufMock.Setup(c => c.Relationships).Returns(_resourceGraph.GetRelationships((TodoItem t) => t.OneToOnePerson).ToHashSet); + ufMock.Setup(c => c.Relationships).Returns(ResourceGraph.GetRelationships((TodoItem t) => t.OneToOnePerson).ToHashSet); // Act var todoList = new List { new TodoItem { Id = _todoList[0].Id } }; hookExecutor.BeforeUpdate(todoList, ResourcePipeline.Patch); // Assert - todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, _description)), ResourcePipeline.Patch), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); ownerResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship( - It.Is>(rh => PersonCheck(_lastName + _lastName, rh)), + It.Is>(rh => PersonCheck(LastName + LastName, rh)), ResourcePipeline.Patch), Times.Once()); VerifyNoOtherCalls(todoResourceMock, ownerResourceMock); @@ -110,11 +110,11 @@ public void BeforeUpdate_Without_Parent_Hook_Implemented() // Assert ownerResourceMock.Verify(rd => rd.BeforeUpdateRelationship( It.Is>(ids => PersonIdCheck(ids, _personId)), - It.Is>(rh => PersonCheck(_lastName, rh)), + It.Is>(rh => PersonCheck(LastName, rh)), ResourcePipeline.Patch), Times.Once()); ownerResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship( - It.Is>(rh => PersonCheck(_lastName + _lastName, rh)), + It.Is>(rh => PersonCheck(LastName + LastName, rh)), ResourcePipeline.Patch), Times.Once()); VerifyNoOtherCalls(todoResourceMock, ownerResourceMock); @@ -132,9 +132,9 @@ public void BeforeUpdate_Without_Child_Hook_Implemented() hookExecutor.BeforeUpdate(_todoList, ResourcePipeline.Patch); // Assert - todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, _description)), ResourcePipeline.Patch), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); todoResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship( - It.Is>(rh => TodoCheck(rh, _description + _description)), + It.Is>(rh => TodoCheck(rh, Description + Description)), ResourcePipeline.Patch), Times.Once()); VerifyNoOtherCalls(todoResourceMock, ownerResourceMock); @@ -152,7 +152,7 @@ public void BeforeUpdate_NoImplicit() hookExecutor.BeforeUpdate(_todoList, ResourcePipeline.Patch); // Assert - todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, _description)), ResourcePipeline.Patch), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); ownerResourceMock.Verify(rd => rd.BeforeUpdateRelationship( It.Is>(ids => PersonIdCheck(ids, _personId)), It.IsAny>(), @@ -175,7 +175,7 @@ public void BeforeUpdate_NoImplicit_Without_Parent_Hook_Implemented() // Assert ownerResourceMock.Verify(rd => rd.BeforeUpdateRelationship( It.Is>(ids => PersonIdCheck(ids, _personId)), - It.Is>(rh => PersonCheck(_lastName, rh)), + It.Is>(rh => PersonCheck(LastName, rh)), ResourcePipeline.Patch), Times.Once()); VerifyNoOtherCalls(todoResourceMock, ownerResourceMock); @@ -193,7 +193,7 @@ public void BeforeUpdate_NoImplicit_Without_Child_Hook_Implemented() hookExecutor.BeforeUpdate(_todoList, ResourcePipeline.Patch); // Assert - todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, _description)), ResourcePipeline.Patch), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); VerifyNoOtherCalls(todoResourceMock, ownerResourceMock); } diff --git a/test/UnitTests/ResourceHooks/HooksDummyData.cs b/test/UnitTests/ResourceHooks/HooksDummyData.cs index 6cea49728a..ba076241e0 100644 --- a/test/UnitTests/ResourceHooks/HooksDummyData.cs +++ b/test/UnitTests/ResourceHooks/HooksDummyData.cs @@ -11,10 +11,10 @@ namespace UnitTests.ResourceHooks { public class HooksDummyData { - protected IResourceGraph _resourceGraph; - protected ResourceHook[] NoHooks = new ResourceHook[0]; - protected ResourceHook[] EnableDbValues = { ResourceHook.BeforeUpdate, ResourceHook.BeforeUpdateRelationship }; - protected ResourceHook[] DisableDbValues = new ResourceHook[0]; + protected IResourceGraph ResourceGraph { get; } + protected ResourceHook[] NoHooks { get; } = new ResourceHook[0]; + protected ResourceHook[] EnableDbValues { get; } = { ResourceHook.BeforeUpdate, ResourceHook.BeforeUpdateRelationship }; + protected ResourceHook[] DisableDbValues { get; } = new ResourceHook[0]; protected readonly Faker _personFaker; protected readonly Faker _todoFaker; protected readonly Faker _tagFaker; @@ -25,7 +25,7 @@ public class HooksDummyData public HooksDummyData() { - _resourceGraph = new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance) + ResourceGraph = new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance) .Add() .Add() .Add() diff --git a/test/UnitTests/ResourceHooks/HooksTestsSetup.cs b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs index 9f02ec4c81..f1a7ca5578 100644 --- a/test/UnitTests/ResourceHooks/HooksTestsSetup.cs +++ b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs @@ -46,9 +46,9 @@ public class HooksTestsSetup : HooksDummyData SetupProcessorFactoryForResourceDefinition(gpfMock, primaryResource.Object, primaryDiscovery); - var execHelper = new HookExecutorHelper(gpfMock.Object, _resourceGraph, options); - var traversalHelper = new TraversalHelper(_resourceGraph, ufMock.Object); - var hookExecutor = new ResourceHookExecutor(execHelper, traversalHelper, ufMock.Object, constraintsMock.Object, _resourceGraph); + var execHelper = new HookExecutorHelper(gpfMock.Object, ResourceGraph, options); + var traversalHelper = new TraversalHelper(ResourceGraph, ufMock.Object); + var hookExecutor = new ResourceHookExecutor(execHelper, traversalHelper, ufMock.Object, constraintsMock.Object, ResourceGraph); return (constraintsMock, hookExecutor, primaryResource); } @@ -79,9 +79,9 @@ public class HooksTestsSetup : HooksDummyData SetupProcessorFactoryForResourceDefinition(gpfMock, primaryResource.Object, primaryDiscovery, dbContext, resourceGraph); SetupProcessorFactoryForResourceDefinition(gpfMock, secondaryResource.Object, secondaryDiscovery, dbContext, resourceGraph); - var execHelper = new HookExecutorHelper(gpfMock.Object, _resourceGraph, options); - var traversalHelper = new TraversalHelper(_resourceGraph, ufMock.Object); - var hookExecutor = new ResourceHookExecutor(execHelper, traversalHelper, ufMock.Object, constraintsMock.Object, _resourceGraph); + var execHelper = new HookExecutorHelper(gpfMock.Object, ResourceGraph, options); + var traversalHelper = new TraversalHelper(ResourceGraph, ufMock.Object); + var hookExecutor = new ResourceHookExecutor(execHelper, traversalHelper, ufMock.Object, constraintsMock.Object, ResourceGraph); return (constraintsMock, ufMock, hookExecutor, primaryResource, secondaryResource); } @@ -117,9 +117,9 @@ public class HooksTestsSetup : HooksDummyData SetupProcessorFactoryForResourceDefinition(gpfMock, firstSecondaryResource.Object, firstSecondaryDiscovery, dbContext, resourceGraph); SetupProcessorFactoryForResourceDefinition(gpfMock, secondSecondaryResource.Object, secondSecondaryDiscovery, dbContext, resourceGraph); - var execHelper = new HookExecutorHelper(gpfMock.Object, _resourceGraph, options); - var traversalHelper = new TraversalHelper(_resourceGraph, ufMock.Object); - var hookExecutor = new ResourceHookExecutor(execHelper, traversalHelper, ufMock.Object, constraintsMock.Object, _resourceGraph); + var execHelper = new HookExecutorHelper(gpfMock.Object, ResourceGraph, options); + var traversalHelper = new TraversalHelper(ResourceGraph, ufMock.Object); + var hookExecutor = new ResourceHookExecutor(execHelper, traversalHelper, ufMock.Object, constraintsMock.Object, ResourceGraph); return (constraintsMock, hookExecutor, primaryResource, firstSecondaryResource, secondSecondaryResource); } @@ -259,7 +259,7 @@ private IDbContextResolver CreateTestDbResolver(AppDbContext dbContext) private void ResolveInverseRelationships(AppDbContext context) { var dbContextResolvers = new[] {new DbContextResolver(context)}; - var inverseRelationships = new InverseNavigationResolver(_resourceGraph, dbContextResolvers); + var inverseRelationships = new InverseNavigationResolver(ResourceGraph, dbContextResolvers); inverseRelationships.Resolve(); } @@ -288,13 +288,13 @@ protected List> GetIncludedRelationshipsChains(param protected List GetIncludedRelationshipsChain(string chain) { var parsedChain = new List(); - var resourceContext = _resourceGraph.GetResourceContext(); + var resourceContext = ResourceGraph.GetResourceContext(); var splitPath = chain.Split('.'); foreach (var requestedRelationship in splitPath) { var relationship = resourceContext.Relationships.Single(r => r.PublicName == requestedRelationship); parsedChain.Add(relationship); - resourceContext = _resourceGraph.GetResourceContext(relationship.RightType); + resourceContext = ResourceGraph.GetResourceContext(relationship.RightType); } return parsedChain; } @@ -318,4 +318,4 @@ protected IEnumerable ConvertInclusionChains(List> Relationships = new Dictionary>(); - public readonly HashSet FirstToOnesResources = new HashSet { new Dummy { Id = 1 }, new Dummy { Id = 2 }, new Dummy { Id = 3 } }; - public readonly HashSet SecondToOnesResources = new HashSet { new Dummy { Id = 4 }, new Dummy { Id = 5 }, new Dummy { Id = 6 } }; - public readonly HashSet ToManiesResources = new HashSet { new Dummy { Id = 7 }, new Dummy { Id = 8 }, new Dummy { Id = 9 } }; - public readonly HashSet NoRelationshipsResources = new HashSet { new Dummy { Id = 10 }, new Dummy { Id = 11 }, new Dummy { Id = 12 } }; - public readonly HashSet AllResources; + private readonly HasOneAttribute _firstToOneAttr; + private readonly HasOneAttribute _secondToOneAttr; + private readonly HasManyAttribute _toManyAttr; + + private readonly Dictionary> _relationships = new Dictionary>(); + private readonly HashSet _firstToOnesResources = new HashSet { new Dummy { Id = 1 }, new Dummy { Id = 2 }, new Dummy { Id = 3 } }; + private readonly HashSet _secondToOnesResources = new HashSet { new Dummy { Id = 4 }, new Dummy { Id = 5 }, new Dummy { Id = 6 } }; + private readonly HashSet _toManiesResources = new HashSet { new Dummy { Id = 7 }, new Dummy { Id = 8 }, new Dummy { Id = 9 } }; + private readonly HashSet _noRelationshipsResources = new HashSet { new Dummy { Id = 10 }, new Dummy { Id = 11 }, new Dummy { Id = 12 } }; + private readonly HashSet _allResources; + public RelationshipDictionaryTests() { - FirstToOneAttr = new HasOneAttribute + _firstToOneAttr = new HasOneAttribute { PublicName = "firstToOne", LeftType = typeof(Dummy), RightType = typeof(ToOne), Property = typeof(Dummy).GetProperty(nameof(Dummy.FirstToOne)) }; - SecondToOneAttr = new HasOneAttribute + _secondToOneAttr = new HasOneAttribute { PublicName = "secondToOne", LeftType = typeof(Dummy), RightType = typeof(ToOne), Property = typeof(Dummy).GetProperty(nameof(Dummy.SecondToOne)) }; - ToManyAttr = new HasManyAttribute + _toManyAttr = new HasManyAttribute { PublicName = "toManies", LeftType = typeof(Dummy), RightType = typeof(ToMany), Property = typeof(Dummy).GetProperty(nameof(Dummy.ToManies)) }; - Relationships.Add(FirstToOneAttr, FirstToOnesResources); - Relationships.Add(SecondToOneAttr, SecondToOnesResources); - Relationships.Add(ToManyAttr, ToManiesResources); - AllResources = new HashSet(FirstToOnesResources.Union(SecondToOnesResources).Union(ToManiesResources).Union(NoRelationshipsResources)); + _relationships.Add(_firstToOneAttr, _firstToOnesResources); + _relationships.Add(_secondToOneAttr, _secondToOnesResources); + _relationships.Add(_toManyAttr, _toManiesResources); + _allResources = new HashSet(_firstToOnesResources.Union(_secondToOnesResources).Union(_toManiesResources).Union(_noRelationshipsResources)); } [Fact] public void RelationshipsDictionary_GetByRelationships() { // Arrange - RelationshipsDictionary relationshipsDictionary = new RelationshipsDictionary(Relationships); + RelationshipsDictionary relationshipsDictionary = new RelationshipsDictionary(_relationships); // Act Dictionary> toOnes = relationshipsDictionary.GetByRelationship(); @@ -67,7 +68,7 @@ public void RelationshipsDictionary_GetByRelationships() public void RelationshipsDictionary_GetAffected() { // Arrange - RelationshipsDictionary relationshipsDictionary = new RelationshipsDictionary(Relationships); + RelationshipsDictionary relationshipsDictionary = new RelationshipsDictionary(_relationships); // Act var affectedThroughFirstToOne = relationshipsDictionary.GetAffected(d => d.FirstToOne).ToList(); @@ -75,16 +76,16 @@ public void RelationshipsDictionary_GetAffected() var affectedThroughToMany = relationshipsDictionary.GetAffected(d => d.ToManies).ToList(); // Assert - affectedThroughFirstToOne.ForEach(resource => Assert.Contains(resource, FirstToOnesResources)); - affectedThroughSecondToOne.ForEach(resource => Assert.Contains(resource, SecondToOnesResources)); - affectedThroughToMany.ForEach(resource => Assert.Contains(resource, ToManiesResources)); + affectedThroughFirstToOne.ForEach(resource => Assert.Contains(resource, _firstToOnesResources)); + affectedThroughSecondToOne.ForEach(resource => Assert.Contains(resource, _secondToOnesResources)); + affectedThroughToMany.ForEach(resource => Assert.Contains(resource, _toManiesResources)); } [Fact] public void ResourceHashSet_GetByRelationships() { // Arrange - ResourceHashSet resources = new ResourceHashSet(AllResources, Relationships); + ResourceHashSet resources = new ResourceHashSet(_allResources, _relationships); // Act Dictionary> toOnes = resources.GetByRelationship(); @@ -95,7 +96,7 @@ public void ResourceHashSet_GetByRelationships() // Assert AssertRelationshipDictionaryGetters(allRelationships, toOnes, toManies, notTargeted); var allResourcesWithAffectedRelationships = allRelationships.SelectMany(kvp => kvp.Value).ToList(); - NoRelationshipsResources.ToList().ForEach(e => + _noRelationshipsResources.ToList().ForEach(e => { Assert.DoesNotContain(e, allResourcesWithAffectedRelationships); }); @@ -105,8 +106,8 @@ public void ResourceHashSet_GetByRelationships() public void ResourceDiff_GetByRelationships() { // Arrange - var dbResources = new HashSet(AllResources.Select(e => new Dummy { Id = e.Id }).ToList()); - DiffableResourceHashSet diffs = new DiffableResourceHashSet(AllResources, dbResources, Relationships, null); + var dbResources = new HashSet(_allResources.Select(e => new Dummy { Id = e.Id }).ToList()); + DiffableResourceHashSet diffs = new DiffableResourceHashSet(_allResources, dbResources, _relationships, null); // Act Dictionary> toOnes = diffs.GetByRelationship(); @@ -117,7 +118,7 @@ public void ResourceDiff_GetByRelationships() // Assert AssertRelationshipDictionaryGetters(allRelationships, toOnes, toManies, notTargeted); var allResourcesWithAffectedRelationships = allRelationships.SelectMany(kvp => kvp.Value).ToList(); - NoRelationshipsResources.ToList().ForEach(e => + _noRelationshipsResources.ToList().ForEach(e => { Assert.DoesNotContain(e, allResourcesWithAffectedRelationships); }); @@ -125,7 +126,7 @@ public void ResourceDiff_GetByRelationships() var requestResourcesFromDiff = diffs; requestResourcesFromDiff.ToList().ForEach(e => { - Assert.Contains(e, AllResources); + Assert.Contains(e, _allResources); }); var databaseResourcesFromDiff = diffs.GetDiffs().Select(d => d.DatabaseValue); databaseResourcesFromDiff.ToList().ForEach(e => @@ -138,15 +139,15 @@ public void ResourceDiff_GetByRelationships() public void ResourceDiff_Loops_Over_Diffs() { // Arrange - var dbResources = new HashSet(AllResources.Select(e => new Dummy { Id = e.Id })); - DiffableResourceHashSet diffs = new DiffableResourceHashSet(AllResources, dbResources, Relationships, null); + var dbResources = new HashSet(_allResources.Select(e => new Dummy { Id = e.Id })); + DiffableResourceHashSet diffs = new DiffableResourceHashSet(_allResources, dbResources, _relationships, null); // Assert & act foreach (ResourceDiffPair diff in diffs.GetDiffs()) { Assert.Equal(diff.Resource.Id, diff.DatabaseValue.Id); Assert.NotEqual(diff.Resource, diff.DatabaseValue); - Assert.Contains(diff.Resource, AllResources); + Assert.Contains(diff.Resource, _allResources); Assert.Contains(diff.DatabaseValue, dbResources); } } @@ -155,8 +156,8 @@ public void ResourceDiff_Loops_Over_Diffs() public void ResourceDiff_GetAffected_Relationships() { // Arrange - var dbResources = new HashSet(AllResources.Select(e => new Dummy { Id = e.Id })); - DiffableResourceHashSet diffs = new DiffableResourceHashSet(AllResources, dbResources, Relationships, null); + var dbResources = new HashSet(_allResources.Select(e => new Dummy { Id = e.Id })); + DiffableResourceHashSet diffs = new DiffableResourceHashSet(_allResources, dbResources, _relationships, null); // Act var affectedThroughFirstToOne = diffs.GetAffected(d => d.FirstToOne).ToList(); @@ -164,21 +165,21 @@ public void ResourceDiff_GetAffected_Relationships() var affectedThroughToMany = diffs.GetAffected(d => d.ToManies).ToList(); // Assert - affectedThroughFirstToOne.ForEach(resource => Assert.Contains(resource, FirstToOnesResources)); - affectedThroughSecondToOne.ForEach(resource => Assert.Contains(resource, SecondToOnesResources)); - affectedThroughToMany.ForEach(resource => Assert.Contains(resource, ToManiesResources)); + affectedThroughFirstToOne.ForEach(resource => Assert.Contains(resource, _firstToOnesResources)); + affectedThroughSecondToOne.ForEach(resource => Assert.Contains(resource, _secondToOnesResources)); + affectedThroughToMany.ForEach(resource => Assert.Contains(resource, _toManiesResources)); } [Fact] public void ResourceDiff_GetAffected_Attributes() { // Arrange - var dbResources = new HashSet(AllResources.Select(e => new Dummy { Id = e.Id })); + var dbResources = new HashSet(_allResources.Select(e => new Dummy { Id = e.Id })); var updatedAttributes = new Dictionary> { - { typeof(Dummy).GetProperty("SomeUpdatedProperty"), AllResources } + { typeof(Dummy).GetProperty("SomeUpdatedProperty"), _allResources } }; - DiffableResourceHashSet diffs = new DiffableResourceHashSet(AllResources, dbResources, Relationships, updatedAttributes); + DiffableResourceHashSet diffs = new DiffableResourceHashSet(_allResources, dbResources, _relationships, updatedAttributes); // Act var affectedThroughSomeUpdatedProperty = diffs.GetAffected(d => d.SomeUpdatedProperty); @@ -194,24 +195,24 @@ private void AssertRelationshipDictionaryGetters(Dictionary> toManies, Dictionary> notTargeted) { - Assert.Contains(FirstToOneAttr, toOnes.Keys); - Assert.Contains(SecondToOneAttr, toOnes.Keys); - Assert.Contains(ToManyAttr, toManies.Keys); + Assert.Contains(_firstToOneAttr, toOnes.Keys); + Assert.Contains(_secondToOneAttr, toOnes.Keys); + Assert.Contains(_toManyAttr, toManies.Keys); Assert.Equal(relationshipsDictionary.Keys.Count, toOnes.Keys.Count + toManies.Keys.Count + notTargeted.Keys.Count); - toOnes[FirstToOneAttr].ToList().ForEach(resource => + toOnes[_firstToOneAttr].ToList().ForEach(resource => { - Assert.Contains(resource, FirstToOnesResources); + Assert.Contains(resource, _firstToOnesResources); }); - toOnes[SecondToOneAttr].ToList().ForEach(resource => + toOnes[_secondToOneAttr].ToList().ForEach(resource => { - Assert.Contains(resource, SecondToOnesResources); + Assert.Contains(resource, _secondToOnesResources); }); - toManies[ToManyAttr].ToList().ForEach(resource => + toManies[_toManyAttr].ToList().ForEach(resource => { - Assert.Contains(resource, ToManiesResources); + Assert.Contains(resource, _toManiesResources); }); Assert.Empty(notTargeted); } diff --git a/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs b/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs index bc50c2ec93..ce4d6cdff3 100644 --- a/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs +++ b/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs @@ -9,7 +9,7 @@ namespace UnitTests.Serialization.Server public sealed class ResponseResourceObjectBuilderTests : SerializerTestsSetup { private readonly List _relationshipsForBuild; - private const string _relationshipName = "dependents"; + private const string RelationshipName = "dependents"; public ResponseResourceObjectBuilderTests() { @@ -27,7 +27,7 @@ public void Build_RelationshipNotIncludedAndLinksEnabled_RelationshipEntryWithLi var resourceObject = builder.Build(resource, relationships: _relationshipsForBuild); // Assert - Assert.True(resourceObject.Relationships.TryGetValue(_relationshipName, out var entry)); + Assert.True(resourceObject.Relationships.TryGetValue(RelationshipName, out var entry)); Assert.Equal("http://www.dummy.com/dummy-relationship-self-link", entry.Links.Self); Assert.Equal("http://www.dummy.com/dummy-relationship-related-link", entry.Links.Related); Assert.False(entry.IsPopulated); @@ -58,7 +58,7 @@ public void Build_RelationshipIncludedAndLinksDisabled_RelationshipEntryWithData var resourceObject = builder.Build(resource, relationships: _relationshipsForBuild); // Assert - Assert.True(resourceObject.Relationships.TryGetValue(_relationshipName, out var entry)); + Assert.True(resourceObject.Relationships.TryGetValue(RelationshipName, out var entry)); Assert.Null(entry.Links); Assert.True(entry.IsPopulated); Assert.Equal("20", entry.ManyData.Single().Id); @@ -75,7 +75,7 @@ public void Build_RelationshipIncludedAndLinksEnabled_RelationshipEntryWithDataA var resourceObject = builder.Build(resource, relationships: _relationshipsForBuild); // Assert - Assert.True(resourceObject.Relationships.TryGetValue(_relationshipName, out var entry)); + Assert.True(resourceObject.Relationships.TryGetValue(RelationshipName, out var entry)); Assert.Equal("http://www.dummy.com/dummy-relationship-self-link", entry.Links.Self); Assert.Equal("http://www.dummy.com/dummy-relationship-related-link", entry.Links.Related); Assert.True(entry.IsPopulated); From 2c26e6011b6486fb69a79aa660ceadd057d9cee3 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Mon, 15 Feb 2021 14:26:31 +0100 Subject: [PATCH 08/60] Remove redundant parenthesis --- .../Builders/ResourceGraphBuilderTests.cs | 2 +- test/UnitTests/ResourceHooks/DiscoveryTests.cs | 2 +- .../Create/BeforeCreateWithDbValuesTests.cs | 8 ++++---- .../IdentifiableManyToManyOnReturnTests.cs | 18 +++++++++--------- .../Executor/ManyToManyOnReturnTests.cs | 4 ++-- .../IdentifiableManyToManyAfterReadTests.cs | 12 ++++++------ .../Executor/Read/ManyToManyAfterReadTests.cs | 4 ++-- .../Update/BeforeUpdateWithDbValuesTests.cs | 10 +++++----- 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/test/UnitTests/Builders/ResourceGraphBuilderTests.cs b/test/UnitTests/Builders/ResourceGraphBuilderTests.cs index a3ddfb5a31..6bd6ea1bfe 100644 --- a/test/UnitTests/Builders/ResourceGraphBuilderTests.cs +++ b/test/UnitTests/Builders/ResourceGraphBuilderTests.cs @@ -75,7 +75,7 @@ public void Attrs_Without_Names_Specified_Will_Use_Configured_Formatter() // Assert var resource = resourceGraph.GetResourceContext(typeof(TestResource)); - Assert.Contains(resource.Attributes, (i) => i.PublicName == "compoundAttribute"); + Assert.Contains(resource.Attributes, i => i.PublicName == "compoundAttribute"); } [Fact] diff --git a/test/UnitTests/ResourceHooks/DiscoveryTests.cs b/test/UnitTests/ResourceHooks/DiscoveryTests.cs index 3985ba327e..b38fe013ee 100644 --- a/test/UnitTests/ResourceHooks/DiscoveryTests.cs +++ b/test/UnitTests/ResourceHooks/DiscoveryTests.cs @@ -25,7 +25,7 @@ public override void AfterDelete(HashSet resources, ResourcePipeline pipe private IServiceProvider MockProvider(object service) where TResource : class, IIdentifiable { var services = new ServiceCollection(); - services.AddScoped((_) => (ResourceHooksDefinition)service); + services.AddScoped(_ => (ResourceHooksDefinition)service); return services.BuildServiceProvider(); } diff --git a/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateWithDbValuesTests.cs b/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateWithDbValuesTests.cs index d6609da6d2..9249ff0a68 100644 --- a/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateWithDbValuesTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateWithDbValuesTests.cs @@ -56,7 +56,7 @@ public void BeforeCreate() hookExecutor.BeforeCreate(_todoList, ResourcePipeline.Post); // Assert - todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>((resources) => TodoCheck(resources, Description)), ResourcePipeline.Post), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>(resources => TodoCheck(resources, Description)), ResourcePipeline.Post), Times.Once()); ownerResourceMock.Verify(rd => rd.BeforeUpdateRelationship( It.Is>(ids => PersonIdCheck(ids, _personId)), It.IsAny>(), @@ -101,7 +101,7 @@ public void BeforeCreate_Without_Child_Hook_Implemented() hookExecutor.BeforeCreate(_todoList, ResourcePipeline.Post); // Assert - todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>((resources) => TodoCheck(resources, Description)), ResourcePipeline.Post), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>(resources => TodoCheck(resources, Description)), ResourcePipeline.Post), Times.Once()); todoResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship( It.Is>(rh => TodoCheckRelationships(rh, Description + Description)), ResourcePipeline.Post), @@ -121,7 +121,7 @@ public void BeforeCreate_NoImplicit() hookExecutor.BeforeCreate(_todoList, ResourcePipeline.Post); // Assert - todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>((resources) => TodoCheck(resources, Description)), ResourcePipeline.Post), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>(resources => TodoCheck(resources, Description)), ResourcePipeline.Post), Times.Once()); ownerResourceMock.Verify(rd => rd.BeforeUpdateRelationship( It.Is>(ids => PersonIdCheck(ids, _personId)), It.IsAny>(), @@ -162,7 +162,7 @@ public void BeforeCreate_NoImplicit_Without_Child_Hook_Implemented() hookExecutor.BeforeCreate(_todoList, ResourcePipeline.Post); // Assert - todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>((resources) => TodoCheck(resources, Description)), ResourcePipeline.Post), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeCreate(It.Is>(resources => TodoCheck(resources, Description)), ResourcePipeline.Post), Times.Once()); VerifyNoOtherCalls(todoResourceMock, ownerResourceMock); } diff --git a/test/UnitTests/ResourceHooks/Executor/IdentifiableManyToManyOnReturnTests.cs b/test/UnitTests/ResourceHooks/Executor/IdentifiableManyToManyOnReturnTests.cs index e71649214e..faf79c8c34 100644 --- a/test/UnitTests/ResourceHooks/Executor/IdentifiableManyToManyOnReturnTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/IdentifiableManyToManyOnReturnTests.cs @@ -26,8 +26,8 @@ public void OnReturn() // Assert articleResourceMock.Verify(rd => rd.OnReturn(It.IsAny>(), ResourcePipeline.Get), Times.Once()); - joinResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(joins).Any()), ResourcePipeline.Get), Times.Once()); - tagResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(tags).Any()), ResourcePipeline.Get), Times.Once()); + joinResourceMock.Verify(rd => rd.OnReturn(It.Is>(collection => !collection.Except(joins).Any()), ResourcePipeline.Get), Times.Once()); + tagResourceMock.Verify(rd => rd.OnReturn(It.Is>(collection => !collection.Except(tags).Any()), ResourcePipeline.Get), Times.Once()); VerifyNoOtherCalls(articleResourceMock, joinResourceMock, tagResourceMock); } @@ -45,9 +45,9 @@ public void OnReturn_GetRelationship() hookExecutor.OnReturn(articles, ResourcePipeline.GetRelationship); // Assert - articleResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(articles).Any()), ResourcePipeline.GetRelationship), Times.Once()); - joinResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(joins).Any()), ResourcePipeline.GetRelationship), Times.Once()); - tagResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(tags).Any()), ResourcePipeline.GetRelationship), Times.Once()); + articleResourceMock.Verify(rd => rd.OnReturn(It.Is>(collection => !collection.Except(articles).Any()), ResourcePipeline.GetRelationship), Times.Once()); + joinResourceMock.Verify(rd => rd.OnReturn(It.Is>(collection => !collection.Except(joins).Any()), ResourcePipeline.GetRelationship), Times.Once()); + tagResourceMock.Verify(rd => rd.OnReturn(It.Is>(collection => !collection.Except(tags).Any()), ResourcePipeline.GetRelationship), Times.Once()); VerifyNoOtherCalls(articleResourceMock, joinResourceMock, tagResourceMock); } @@ -65,8 +65,8 @@ public void OnReturn_Without_Parent_Hook_Implemented() hookExecutor.OnReturn(articles, ResourcePipeline.Get); // Assert - joinResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(joins).Any()), ResourcePipeline.Get), Times.Once()); - tagResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(tags).Any()), ResourcePipeline.Get), Times.Once()); + joinResourceMock.Verify(rd => rd.OnReturn(It.Is>(collection => !collection.Except(joins).Any()), ResourcePipeline.Get), Times.Once()); + tagResourceMock.Verify(rd => rd.OnReturn(It.Is>(collection => !collection.Except(tags).Any()), ResourcePipeline.Get), Times.Once()); VerifyNoOtherCalls(articleResourceMock, joinResourceMock, tagResourceMock); } @@ -86,7 +86,7 @@ public void OnReturn_Without_Children_Hooks_Implemented() // Assert articleResourceMock.Verify(rd => rd.OnReturn(It.IsAny>(), ResourcePipeline.Get), Times.Once()); - tagResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(tags).Any()), ResourcePipeline.Get), Times.Once()); + tagResourceMock.Verify(rd => rd.OnReturn(It.Is>(collection => !collection.Except(tags).Any()), ResourcePipeline.Get), Times.Once()); VerifyNoOtherCalls(articleResourceMock, joinResourceMock, tagResourceMock); } @@ -105,7 +105,7 @@ public void OnReturn_Without_Grand_Children_Hooks_Implemented() // Assert articleResourceMock.Verify(rd => rd.OnReturn(It.IsAny>(), ResourcePipeline.Get), Times.Once()); - joinResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(joins).Any()), ResourcePipeline.Get), Times.Once()); + joinResourceMock.Verify(rd => rd.OnReturn(It.Is>(collection => !collection.Except(joins).Any()), ResourcePipeline.Get), Times.Once()); VerifyNoOtherCalls(articleResourceMock, joinResourceMock, tagResourceMock); } diff --git a/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs b/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs index 6410f17a34..85767a9e03 100644 --- a/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs @@ -55,7 +55,7 @@ public void OnReturn() // Assert articleResourceMock.Verify(rd => rd.OnReturn(It.IsAny>(), ResourcePipeline.Get), Times.Once()); - tagResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(tags).Any()), ResourcePipeline.Get), Times.Once()); + tagResourceMock.Verify(rd => rd.OnReturn(It.Is>(collection => !collection.Except(tags).Any()), ResourcePipeline.Get), Times.Once()); VerifyNoOtherCalls(articleResourceMock, tagResourceMock); } @@ -72,7 +72,7 @@ public void OnReturn_Without_Parent_Hook_Implemented() hookExecutor.OnReturn(articles, ResourcePipeline.Get); // Assert - tagResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(tags).Any()), ResourcePipeline.Get), Times.Once()); + tagResourceMock.Verify(rd => rd.OnReturn(It.Is>(collection => !collection.Except(tags).Any()), ResourcePipeline.Get), Times.Once()); VerifyNoOtherCalls(articleResourceMock, tagResourceMock); } diff --git a/test/UnitTests/ResourceHooks/Executor/Read/IdentifiableManyToManyAfterReadTests.cs b/test/UnitTests/ResourceHooks/Executor/Read/IdentifiableManyToManyAfterReadTests.cs index 3b3ac5973d..beaaff4faa 100644 --- a/test/UnitTests/ResourceHooks/Executor/Read/IdentifiableManyToManyAfterReadTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Read/IdentifiableManyToManyAfterReadTests.cs @@ -26,8 +26,8 @@ public void AfterRead() // Assert articleResourceMock.Verify(rd => rd.AfterRead(It.IsAny>(), ResourcePipeline.Get, false), Times.Once()); - joinResourceMock.Verify(rd => rd.AfterRead(It.Is>((collection) => !collection.Except(joins).Any()), ResourcePipeline.Get, true), Times.Once()); - tagResourceMock.Verify(rd => rd.AfterRead(It.Is>((collection) => !collection.Except(tags).Any()), ResourcePipeline.Get, true), Times.Once()); + joinResourceMock.Verify(rd => rd.AfterRead(It.Is>(collection => !collection.Except(joins).Any()), ResourcePipeline.Get, true), Times.Once()); + tagResourceMock.Verify(rd => rd.AfterRead(It.Is>(collection => !collection.Except(tags).Any()), ResourcePipeline.Get, true), Times.Once()); VerifyNoOtherCalls(articleResourceMock, joinResourceMock, tagResourceMock); } @@ -45,8 +45,8 @@ public void AfterRead_Without_Parent_Hook_Implemented() hookExecutor.AfterRead(articles, ResourcePipeline.Get); // Assert - joinResourceMock.Verify(rd => rd.AfterRead(It.Is>((collection) => !collection.Except(joins).Any()), ResourcePipeline.Get, true), Times.Once()); - tagResourceMock.Verify(rd => rd.AfterRead(It.Is>((collection) => !collection.Except(tags).Any()), ResourcePipeline.Get, true), Times.Once()); + joinResourceMock.Verify(rd => rd.AfterRead(It.Is>(collection => !collection.Except(joins).Any()), ResourcePipeline.Get, true), Times.Once()); + tagResourceMock.Verify(rd => rd.AfterRead(It.Is>(collection => !collection.Except(tags).Any()), ResourcePipeline.Get, true), Times.Once()); VerifyNoOtherCalls(articleResourceMock, joinResourceMock, tagResourceMock); } @@ -67,7 +67,7 @@ public void AfterRead_Without_Children_Hooks_Implemented() // Assert articleResourceMock.Verify(rd => rd.AfterRead(It.IsAny>(), ResourcePipeline.Get, false), Times.Once()); - tagResourceMock.Verify(rd => rd.AfterRead(It.Is>((collection) => !collection.Except(tags).Any()), ResourcePipeline.Get, true), Times.Once()); + tagResourceMock.Verify(rd => rd.AfterRead(It.Is>(collection => !collection.Except(tags).Any()), ResourcePipeline.Get, true), Times.Once()); VerifyNoOtherCalls(articleResourceMock, joinResourceMock, tagResourceMock); } @@ -86,7 +86,7 @@ public void AfterRead_Without_Grand_Children_Hooks_Implemented() // Assert articleResourceMock.Verify(rd => rd.AfterRead(It.IsAny>(), ResourcePipeline.Get, false), Times.Once()); - joinResourceMock.Verify(rd => rd.AfterRead(It.Is>((collection) => !collection.Except(joins).Any()), ResourcePipeline.Get, true), Times.Once()); + joinResourceMock.Verify(rd => rd.AfterRead(It.Is>(collection => !collection.Except(joins).Any()), ResourcePipeline.Get, true), Times.Once()); VerifyNoOtherCalls(articleResourceMock, joinResourceMock, tagResourceMock); } diff --git a/test/UnitTests/ResourceHooks/Executor/Read/ManyToManyAfterReadTests.cs b/test/UnitTests/ResourceHooks/Executor/Read/ManyToManyAfterReadTests.cs index 10f169ac2a..fd1f8f4644 100644 --- a/test/UnitTests/ResourceHooks/Executor/Read/ManyToManyAfterReadTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Read/ManyToManyAfterReadTests.cs @@ -25,7 +25,7 @@ public void AfterRead() // Assert articleResourceMock.Verify(rd => rd.AfterRead(It.IsAny>(), ResourcePipeline.Get, false), Times.Once()); - tagResourceMock.Verify(rd => rd.AfterRead(It.Is>((collection) => !collection.Except(tags).Any()), ResourcePipeline.Get, true), Times.Once()); + tagResourceMock.Verify(rd => rd.AfterRead(It.Is>(collection => !collection.Except(tags).Any()), ResourcePipeline.Get, true), Times.Once()); VerifyNoOtherCalls(articleResourceMock, tagResourceMock); } @@ -42,7 +42,7 @@ public void AfterRead_Without_Parent_Hook_Implemented() hookExecutor.AfterRead(articles, ResourcePipeline.Get); // Assert - tagResourceMock.Verify(rd => rd.AfterRead(It.Is>((collection) => !collection.Except(tags).Any()), ResourcePipeline.Get, true), Times.Once()); + tagResourceMock.Verify(rd => rd.AfterRead(It.Is>(collection => !collection.Except(tags).Any()), ResourcePipeline.Get, true), Times.Once()); VerifyNoOtherCalls(articleResourceMock, tagResourceMock); } diff --git a/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateWithDbValuesTests.cs b/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateWithDbValuesTests.cs index e691690b18..632633ca77 100644 --- a/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateWithDbValuesTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateWithDbValuesTests.cs @@ -54,7 +54,7 @@ public void BeforeUpdate() hookExecutor.BeforeUpdate(_todoList, ResourcePipeline.Patch); // Assert - todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>(diff => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); ownerResourceMock.Verify(rd => rd.BeforeUpdateRelationship( It.Is>(ids => PersonIdCheck(ids, _personId)), It.Is>(rh => PersonCheck(LastName, rh)), @@ -87,7 +87,7 @@ public void BeforeUpdate_Deleting_Relationship() hookExecutor.BeforeUpdate(todoList, ResourcePipeline.Patch); // Assert - todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>(diff => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); ownerResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship( It.Is>(rh => PersonCheck(LastName + LastName, rh)), ResourcePipeline.Patch), @@ -132,7 +132,7 @@ public void BeforeUpdate_Without_Child_Hook_Implemented() hookExecutor.BeforeUpdate(_todoList, ResourcePipeline.Patch); // Assert - todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>(diff => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); todoResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship( It.Is>(rh => TodoCheck(rh, Description + Description)), ResourcePipeline.Patch), @@ -152,7 +152,7 @@ public void BeforeUpdate_NoImplicit() hookExecutor.BeforeUpdate(_todoList, ResourcePipeline.Patch); // Assert - todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>(diff => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); ownerResourceMock.Verify(rd => rd.BeforeUpdateRelationship( It.Is>(ids => PersonIdCheck(ids, _personId)), It.IsAny>(), @@ -193,7 +193,7 @@ public void BeforeUpdate_NoImplicit_Without_Child_Hook_Implemented() hookExecutor.BeforeUpdate(_todoList, ResourcePipeline.Patch); // Assert - todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>((diff) => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeUpdate(It.Is>(diff => TodoCheckDiff(diff, Description)), ResourcePipeline.Patch), Times.Once()); VerifyNoOtherCalls(todoResourceMock, ownerResourceMock); } From 4089e2c5cf2dc98145b4469d899a06465e4778ce Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Mon, 15 Feb 2021 14:31:32 +0100 Subject: [PATCH 09/60] Fixed culture-specific string comparisons --- .../ExceptionHandling/ConsumerArticleService.cs | 3 ++- .../IntegrationTests/IdObfuscation/HexadecimalCodec.cs | 3 ++- .../IntegrationTests/Logging/LoggingTests.cs | 5 +++-- .../IntegrationTests/Meta/SupportTicketDefinition.cs | 3 ++- .../IntegrationTests/QueryStrings/Blog.cs | 3 ++- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs index d6e498642e..b59e95b5c5 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs @@ -1,3 +1,4 @@ +using System; using System.Threading; using System.Threading.Tasks; using JsonApiDotNetCore.Configuration; @@ -30,7 +31,7 @@ public override async Task GetAsync(int id, CancellationToken c { var consumerArticle = await base.GetAsync(id, cancellationToken); - if (consumerArticle.Code.StartsWith(UnavailableArticlePrefix)) + if (consumerArticle.Code.StartsWith(UnavailableArticlePrefix, StringComparison.Ordinal)) { throw new ConsumerArticleIsNoLongerAvailableException(consumerArticle.Code, SupportEmailAddress); } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/HexadecimalCodec.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/HexadecimalCodec.cs index 9a73263aa2..cc563b5f4b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/HexadecimalCodec.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/HexadecimalCodec.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Globalization; using System.Net; @@ -16,7 +17,7 @@ public static int Decode(string value) return 0; } - if (!value.StartsWith("x")) + if (!value.StartsWith("x", StringComparison.Ordinal)) { throw new JsonApiException(new Error(HttpStatusCode.BadRequest) { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/LoggingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/LoggingTests.cs index 3b99bfbcf1..92dc28d1a0 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/LoggingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/LoggingTests.cs @@ -1,3 +1,4 @@ +using System; using System.Net; using System.Threading.Tasks; using FluentAssertions; @@ -74,7 +75,7 @@ public async Task Logs_request_body_at_Trace_level() loggerFactory.Logger.Messages.Should().NotBeEmpty(); loggerFactory.Logger.Messages.Should().ContainSingle(message => message.LogLevel == LogLevel.Trace && - message.Text.StartsWith("Received request at 'http://localhost/auditEntries' with body: <<")); + message.Text.StartsWith("Received request at 'http://localhost/auditEntries' with body: <<", StringComparison.Ordinal)); } [Fact] @@ -96,7 +97,7 @@ public async Task Logs_response_body_at_Trace_level() loggerFactory.Logger.Messages.Should().NotBeEmpty(); loggerFactory.Logger.Messages.Should().ContainSingle(message => message.LogLevel == LogLevel.Trace && - message.Text.StartsWith("Sending 200 response for request at 'http://localhost/auditEntries' with body: <<")); + message.Text.StartsWith("Sending 200 response for request at 'http://localhost/auditEntries' with body: <<", StringComparison.Ordinal)); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportTicketDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportTicketDefinition.cs index 3b7b945dae..1261d09d9f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportTicketDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportTicketDefinition.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; @@ -12,7 +13,7 @@ public SupportTicketDefinition(IResourceGraph resourceGraph) : base(resourceGrap public override IDictionary GetMeta(SupportTicket resource) { - if (resource.Description != null && resource.Description.StartsWith("Critical:")) + if (resource.Description != null && resource.Description.StartsWith("Critical:", StringComparison.Ordinal)) { return new Dictionary { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Blog.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Blog.cs index cc1e1765e9..d1ae74e810 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Blog.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Blog.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; @@ -13,7 +14,7 @@ public sealed class Blog : Identifiable public string PlatformName { get; set; } [Attr(Capabilities = AttrCapabilities.All & ~(AttrCapabilities.AllowCreate | AttrCapabilities.AllowChange))] - public bool ShowAdvertisements => PlatformName.EndsWith("(using free account)"); + public bool ShowAdvertisements => PlatformName.EndsWith("(using free account)", StringComparison.Ordinal); [HasMany] public IList Posts { get; set; } From feaffab4cf6410baf9fb12c14a0fce081b0eaed9 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 17 Feb 2021 15:24:06 +0100 Subject: [PATCH 10/60] Use newer syntax for dictionary initializers --- .../Client/ResponseDeserializerTests.cs | 42 +++++++++---------- .../Common/BaseDocumentParserTests.cs | 15 +++++-- .../Serialization/DeserializerTestsSetup.cs | 10 ++--- .../Server/ResponseSerializerTests.cs | 4 +- 4 files changed, 40 insertions(+), 31 deletions(-) diff --git a/test/UnitTests/Serialization/Client/ResponseDeserializerTests.cs b/test/UnitTests/Serialization/Client/ResponseDeserializerTests.cs index 73a8423015..e7c5ffcc3a 100644 --- a/test/UnitTests/Serialization/Client/ResponseDeserializerTests.cs +++ b/test/UnitTests/Serialization/Client/ResponseDeserializerTests.cs @@ -29,7 +29,7 @@ public void DeserializeSingle_EmptyResponseWithMeta_CanDeserialize() // Arrange var content = new Document { - Meta = new Dictionary { { "foo", "bar" } } + Meta = new Dictionary { ["foo"] = "bar" } }; var body = JsonConvert.SerializeObject(content); @@ -122,13 +122,13 @@ public void DeserializeSingle_MultipleDependentRelationshipsWithIncluded_CanDese { Type = "oneToOneDependents", Id = "10", - Attributes = new Dictionary { {"attributeMember", toOneAttributeValue } } + Attributes = new Dictionary { ["attributeMember"] = toOneAttributeValue } }, new ResourceObject { Type = "oneToManyDependents", Id = "10", - Attributes = new Dictionary { {"attributeMember", toManyAttributeValue } } + Attributes = new Dictionary { ["attributeMember"] = toManyAttributeValue } } }; var body = JsonConvert.SerializeObject(content); @@ -165,13 +165,13 @@ public void DeserializeSingle_MultiplePrincipalRelationshipsWithIncluded_CanDese { Type = "oneToOnePrincipals", Id = "10", - Attributes = new Dictionary { {"attributeMember", toOneAttributeValue } } + Attributes = new Dictionary { ["attributeMember"] = toOneAttributeValue } }, new ResourceObject { Type = "oneToManyPrincipals", Id = "10", - Attributes = new Dictionary { {"attributeMember", toManyAttributeValue } } + Attributes = new Dictionary { ["attributeMember"] = toManyAttributeValue } } }; var body = JsonConvert.SerializeObject(content); @@ -204,14 +204,14 @@ public void DeserializeSingle_NestedIncluded_CanDeserialize() { Type = "oneToManyDependents", Id = "10", - Attributes = new Dictionary { {"attributeMember", toManyAttributeValue } }, - Relationships = new Dictionary { { "principal", CreateRelationshipData("oneToManyPrincipals") } } + Attributes = new Dictionary { ["attributeMember"] = toManyAttributeValue }, + Relationships = new Dictionary { ["principal"] = CreateRelationshipData("oneToManyPrincipals") } }, new ResourceObject { Type = "oneToManyPrincipals", Id = "10", - Attributes = new Dictionary { {"attributeMember", nestedIncludeAttributeValue } } + Attributes = new Dictionary { ["attributeMember"] = nestedIncludeAttributeValue } } }; var body = JsonConvert.SerializeObject(content); @@ -247,21 +247,21 @@ public void DeserializeSingle_DeeplyNestedIncluded_CanDeserialize() { Type = "multiPrincipals", Id = "10", - Attributes = new Dictionary { {"attributeMember", includedAttributeValue } }, - Relationships = new Dictionary { { "populatedToManies", CreateRelationshipData("oneToManyDependents", isToManyData: true) } } + Attributes = new Dictionary { ["attributeMember"] = includedAttributeValue }, + Relationships = new Dictionary { ["populatedToManies"] = CreateRelationshipData("oneToManyDependents", isToManyData: true) } }, new ResourceObject { Type = "oneToManyDependents", Id = "10", - Attributes = new Dictionary { {"attributeMember", nestedIncludedAttributeValue } }, - Relationships = new Dictionary { { "principal", CreateRelationshipData("oneToManyPrincipals") } } + Attributes = new Dictionary { ["attributeMember"] = nestedIncludedAttributeValue }, + Relationships = new Dictionary { ["principal"] = CreateRelationshipData("oneToManyPrincipals") } }, new ResourceObject { Type = "oneToManyPrincipals", Id = "10", - Attributes = new Dictionary { {"attributeMember", deeplyNestedIncludedAttributeValue } } + Attributes = new Dictionary { ["attributeMember"] = deeplyNestedIncludedAttributeValue } } }; var body = JsonConvert.SerializeObject(content); @@ -298,21 +298,21 @@ public void DeserializeList_DeeplyNestedIncluded_CanDeserialize() { Type = "multiPrincipals", Id = "10", - Attributes = new Dictionary { {"attributeMember", includedAttributeValue } }, - Relationships = new Dictionary { { "populatedToManies", CreateRelationshipData("oneToManyDependents", isToManyData: true) } } + Attributes = new Dictionary { ["attributeMember"] = includedAttributeValue }, + Relationships = new Dictionary { ["populatedToManies"] = CreateRelationshipData("oneToManyDependents", isToManyData: true) } }, new ResourceObject { Type = "oneToManyDependents", Id = "10", - Attributes = new Dictionary { {"attributeMember", nestedIncludedAttributeValue } }, - Relationships = new Dictionary { { "principal", CreateRelationshipData("oneToManyPrincipals") } } + Attributes = new Dictionary { ["attributeMember"] = nestedIncludedAttributeValue }, + Relationships = new Dictionary { ["principal"] = CreateRelationshipData("oneToManyPrincipals") } }, new ResourceObject { Type = "oneToManyPrincipals", Id = "10", - Attributes = new Dictionary { {"attributeMember", deeplyNestedIncludedAttributeValue } } + Attributes = new Dictionary { ["attributeMember"] = deeplyNestedIncludedAttributeValue } } }; var body = JsonConvert.SerializeObject(content); @@ -348,19 +348,19 @@ public void DeserializeSingle_ResourceWithInheritanceAndInclusions_CanDeserializ { Type = "firstDerivedModels", Id = "10", - Attributes = new Dictionary { { "firstProperty", "true" } } + Attributes = new Dictionary { ["firstProperty"] = "true" } }, new ResourceObject { Type = "secondDerivedModels", Id = "11", - Attributes = new Dictionary { { "secondProperty", "false" } } + Attributes = new Dictionary { ["secondProperty"] = "false" } }, new ResourceObject { Type = "firstDerivedModels", Id = "20", - Attributes = new Dictionary { { "firstProperty", "true" } } + Attributes = new Dictionary { ["firstProperty"] = "true" } } }; var body = JsonConvert.SerializeObject(content); diff --git a/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs b/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs index e11cdf7178..08c0f89ca4 100644 --- a/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs +++ b/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs @@ -116,7 +116,7 @@ public void DeserializeAttributes_VariousDataTypes_CanDeserialize(string member, Id = "1", Attributes = new Dictionary { - { member, value } + [member] = value } } }; @@ -174,7 +174,10 @@ public void DeserializeAttributes_ComplexType_CanDeserialize() Id = "1", Attributes = new Dictionary { - { "complexField", new Dictionary { {"compoundName", "testName" } } } // this is not right + ["complexField"] = new Dictionary + { + ["compoundName"] = "testName" + } } } }; @@ -200,7 +203,13 @@ public void DeserializeAttributes_ComplexListType_CanDeserialize() Id = "1", Attributes = new Dictionary { - { "complexFields", new [] { new Dictionary { {"compoundName", "testName" } } } } + ["complexFields"] = new [] + { + new Dictionary + { + ["compoundName"] = "testName" + } + } } } }; diff --git a/test/UnitTests/Serialization/DeserializerTestsSetup.cs b/test/UnitTests/Serialization/DeserializerTestsSetup.cs index 72e880f7f3..e3a6b9a45b 100644 --- a/test/UnitTests/Serialization/DeserializerTestsSetup.cs +++ b/test/UnitTests/Serialization/DeserializerTestsSetup.cs @@ -80,11 +80,11 @@ protected Document CreateTestResourceDocument() Id = "1", Attributes = new Dictionary { - { "stringField", "some string" }, - { "intField", 1 }, - { "nullableIntField", null }, - { "guidField", "1a68be43-cc84-4924-a421-7f4d614b7781" }, - { "dateTimeField", "9/11/2019 11:41:40 AM" } + ["stringField"] = "some string", + ["intField"] = 1, + ["nullableIntField"] = null, + ["guidField"] = "1a68be43-cc84-4924-a421-7f4d614b7781", + ["dateTimeField"] = "9/11/2019 11:41:40 AM" } } }; diff --git a/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs b/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs index 9bdce57c98..f9f51548a7 100644 --- a/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs +++ b/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs @@ -302,7 +302,7 @@ public void SerializeSingle_ResourceWithLinksEnabled_CanSerialize() public void SerializeSingle_ResourceWithMeta_IncludesMetaInResult() { // Arrange - var meta = new Dictionary { { "test", "meta" } }; + var meta = new Dictionary { ["test"] = "meta" }; var resource = new OneToManyPrincipal { Id = 10 }; var serializer = GetResponseSerializer(metaDict: meta); @@ -329,7 +329,7 @@ public void SerializeSingle_ResourceWithMeta_IncludesMetaInResult() public void SerializeSingle_NullWithLinksAndMeta_StillShowsLinksAndMeta() { // Arrange - var meta = new Dictionary { { "test", "meta" } }; + var meta = new Dictionary { ["test"] = "meta" }; var serializer = GetResponseSerializer(metaDict: meta, topLinks: _dummyTopLevelLinks, relationshipLinks: _dummyRelationshipLinks, resourceLinks: _dummyResourceLinks); // Act From e97cad2b748ac75fa10ab6f67016a17cbf028aa9 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Mon, 15 Feb 2021 17:51:37 +0100 Subject: [PATCH 11/60] Various additional cleanups --- .../Data/AppDbContext.cs | 2 +- .../Definitions/TodoItemHooksDefinition.cs | 4 +- .../Models/TodoItem.cs | 2 +- .../Configuration/ResourceGraph.cs | 17 +++-- .../Execution/DiffableResourceHashSet.cs | 9 ++- .../Hooks/Internal/ResourceHookExecutor.cs | 66 ++++++++++++------- .../Internal/Traversal/ITraversalHelper.cs | 2 +- .../Internal/Traversal/TraversalHelper.cs | 2 +- .../Queries/Internal/QueryLayerComposer.cs | 2 +- .../Serialization/BaseDeserializer.cs | 11 ++-- .../Serialization/BaseSerializer.cs | 6 +- .../Building/ResponseResourceObjectBuilder.cs | 2 +- .../Client/Internal/ResponseDeserializer.cs | 2 +- .../Objects/AtomicOperationObject.cs | 3 +- src/JsonApiDotNetCore/TypeHelper.cs | 16 ++--- .../CreateMusicTrackOperationsController.cs | 3 +- .../Mixed/AtomicRequestBodyTests.cs | 2 - .../CustomRoutes/CiviliansController.cs | 3 +- .../CustomRoutes/TownsController.cs | 3 +- test/UnitTests/Graph/TypeLocatorTests.cs | 3 +- test/UnitTests/Internal/ErrorDocumentTests.cs | 4 +- test/UnitTests/Internal/TypeHelperTests.cs | 2 +- .../Models/ResourceConstructionTests.cs | 6 +- .../ResourceWithDbContextConstructor.cs | 18 ----- .../UnitTests/ResourceHooks/DiscoveryTests.cs | 19 +++--- .../Delete/BeforeDeleteWithDbValuesTests.cs | 10 +-- .../Executor/SameResourceTypeTests.cs | 10 +-- .../ResourceHooks/HooksTestsSetup.cs | 10 +-- .../Client/RequestSerializerTests.cs | 18 ++--- .../Client/ResponseDeserializerTests.cs | 2 +- .../Common/BaseDocumentParserTests.cs | 4 +- .../Common/ResourceObjectBuilderTests.cs | 12 ++-- .../Serialization/DeserializerTestsSetup.cs | 6 +- .../SerializationTestsSetupBase.cs | 4 +- .../Serialization/SerializerTestsSetup.cs | 10 +-- .../IncludedResourceObjectBuilderTests.cs | 6 +- .../Server/RequestDeserializerTests.cs | 2 +- .../ResponseResourceObjectBuilderTests.cs | 2 +- .../Server/ResponseSerializerTests.cs | 6 +- 39 files changed, 157 insertions(+), 154 deletions(-) delete mode 100644 test/UnitTests/Models/ResourceWithDbContextConstructor.cs diff --git a/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs b/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs index 8c063c42d7..dbab48ca35 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs @@ -37,7 +37,7 @@ protected override void OnModelCreating(ModelBuilder builder) .OnDelete(DeleteBehavior.Cascade); builder.Entity() - .HasMany(t => t.ChildrenTodos) + .HasMany(t => t.ChildTodoItems) .WithOne(t => t.ParentTodo); builder.Entity() diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs index f9e15f6547..3d8ef7f1c0 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs @@ -26,8 +26,8 @@ public override void BeforeRead(ResourcePipeline pipeline, bool isIncluded = fal public override void BeforeImplicitUpdateRelationship(IRelationshipsDictionary resourcesByRelationship, ResourcePipeline pipeline) { - List todos = resourcesByRelationship.GetByRelationship().SelectMany(kvp => kvp.Value).ToList(); - DisallowLocked(todos); + List todoItems = resourcesByRelationship.GetByRelationship().SelectMany(kvp => kvp.Value).ToList(); + DisallowLocked(todoItems); } public override IEnumerable OnReturn(HashSet resources, ResourcePipeline pipeline) diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs b/src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs index bc06420ad7..48e76cec8a 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs @@ -28,6 +28,6 @@ public class TodoItem : Identifiable, IIsLockable public TodoItem ParentTodo { get; set; } [HasMany] - public IList ChildrenTodos { get; set; } + public IList ChildTodoItems { get; set; } } } diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs index 9fa65a99ac..e839865dfe 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs @@ -174,10 +174,19 @@ private bool IsLazyLoadingProxyForResourceType(Type resourceType) => _proxyTargetAccessorType?.IsAssignableFrom(resourceType) ?? false; private static Expression RemoveConvert(Expression expression) - => expression is UnaryExpression unaryExpression - && unaryExpression.NodeType == ExpressionType.Convert - ? RemoveConvert(unaryExpression.Operand) - : expression; + { + while (true) + { + if (expression is UnaryExpression { NodeType: ExpressionType.Convert } unaryExpression) + { + expression = unaryExpression.Operand; + } + else + { + return expression; + } + } + } private void ThrowNotExposedError(string memberName, FieldFilterType type) { diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs index 7f83b6576e..37d15c71de 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs @@ -69,11 +69,10 @@ public IEnumerable> GetDiffs() // the navigation action references a relationship. Redirect the call to the relationship dictionary. return base.GetAffected(navigationAction); } - else if (_updatedAttributes.TryGetValue(propertyInfo, out HashSet resources)) - { - return resources; - } - return new HashSet(); + + return _updatedAttributes.TryGetValue(propertyInfo, out HashSet resources) + ? resources + : new HashSet(); } private void ThrowNoDbValuesError() diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs index c6d1afa3c9..fcfc61529b 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs @@ -206,24 +206,28 @@ private bool GetHook(ResourceHook target, IEnumerable reso ///
private void Traverse(NodeLayer currentLayer, ResourceHook target, Action action) { - if (!currentLayer.AnyResources()) + while (true) { - return; - } + if (!currentLayer.AnyResources()) + { + return; + } - foreach (IResourceNode node in currentLayer) - { - var resourceType = node.ResourceType; - var hookContainer = _executorHelper.GetResourceHookContainer(resourceType, target); - if (hookContainer == null) + foreach (IResourceNode node in currentLayer) { - continue; + var resourceType = node.ResourceType; + var hookContainer = _executorHelper.GetResourceHookContainer(resourceType, target); + + if (hookContainer == null) + { + continue; + } + + action(hookContainer, node); } - action(hookContainer, node); + currentLayer = _traversalHelper.CreateNextLayer(currentLayer.ToList()); } - - Traverse(_traversalHelper.CreateNextLayer(currentLayer.ToList()), target, action); } /// @@ -233,20 +237,32 @@ private void Traverse(NodeLayer currentLayer, ResourceHook target, Action private void RecursiveBeforeRead(List relationshipChain, ResourcePipeline pipeline, List calledContainers) { - var relationship = relationshipChain.First(); - if (!calledContainers.Contains(relationship.RightType)) + while (true) { - calledContainers.Add(relationship.RightType); - var container = _executorHelper.GetResourceHookContainer(relationship.RightType, ResourceHook.BeforeRead); - if (container != null) + var relationship = relationshipChain.First(); + + if (!calledContainers.Contains(relationship.RightType)) { - CallHook(container, ResourceHook.BeforeRead, new object[] { pipeline, true, null }); + calledContainers.Add(relationship.RightType); + var container = _executorHelper.GetResourceHookContainer(relationship.RightType, ResourceHook.BeforeRead); + + if (container != null) + { + CallHook(container, ResourceHook.BeforeRead, new object[] + { + pipeline, + true, + null + }); + } + } + + relationshipChain.RemoveAt(0); + + if (!relationshipChain.Any()) + { + break; } - } - relationshipChain.RemoveAt(0); - if (relationshipChain.Any()) - { - RecursiveBeforeRead(relationshipChain, pipeline, calledContainers); } } @@ -325,7 +341,7 @@ private void FireNestedBeforeUpdateHooks(ResourcePipeline pipeline, NodeLayer la // RelationshipAttribute from owner to article, which is the // inverse of HasOneAttribute:owner currentResourcesGroupedInverse = ReplaceKeysWithInverseRelationships(currentResourcesGrouped); - // Note that currently in the JADNC implementation of hooks, + // Note that currently in the JsonApiDotNetCore implementation of hooks, // the root layer is ALWAYS homogenous, so we safely assume // that for every relationship to the previous layer, the // left type is the same. @@ -344,7 +360,7 @@ private Dictionary ReplaceKeysWithInverseRel { // when Article has one Owner (HasOneAttribute:owner) is set, there is no guarantee // that the inverse attribute was also set (Owner has one Article: HasOneAttr:article). - // If it isn't, JADNC currently knows nothing about this relationship pointing back, and it + // If it isn't, JsonApiDotNetCore currently knows nothing about this relationship pointing back, and it // currently cannot fire hooks for resources resolved through inverse relationships. var inversableRelationshipAttributes = resourcesByRelationship.Where(kvp => kvp.Key.InverseNavigationProperty != null); return inversableRelationshipAttributes.ToDictionary(kvp => _resourceGraph.GetInverseRelationship(kvp.Key), kvp => kvp.Value); diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/ITraversalHelper.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/ITraversalHelper.cs index d3e2e2ba6a..4ca6ddfac0 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/ITraversalHelper.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/ITraversalHelper.cs @@ -15,7 +15,7 @@ internal interface ITraversalHelper NodeLayer CreateNextLayer(IEnumerable nodes); /// /// Creates a root node for breadth-first-traversal (BFS). Note that typically, in - /// JADNC, the root layer will be homogeneous. Also, because it is the first layer, + /// JsonApiDotNetCore, the root layer will be homogeneous. Also, because it is the first layer, /// there can be no relationships to previous layers, only to next layers. /// /// The root node. diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs index ca4d4db7f0..fdd84fdd6e 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs @@ -44,7 +44,7 @@ public TraversalHelper( /// /// Creates a root node for breadth-first-traversal. Note that typically, in - /// JADNC, the root layer will be homogeneous. Also, because it is the first layer, + /// JsonApiDotNetCore, the root layer will be homogeneous. Also, because it is the first layer, /// there can be no relationships to previous layers, only to next layers. /// /// The root node. diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs index ca6c888125..8e221bd3b8 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs @@ -40,7 +40,7 @@ public QueryLayerComposer( _options = options; _paginationContext = paginationContext; _targetedFields = targetedFields; - _sparseFieldSetCache = new SparseFieldSetCache(constraintProviders, resourceDefinitionAccessor); + _sparseFieldSetCache = new SparseFieldSetCache(_constraintProviders, resourceDefinitionAccessor); } /// diff --git a/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs b/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs index edc28c471d..26d4d096e3 100644 --- a/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs +++ b/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs @@ -143,14 +143,13 @@ protected virtual IIdentifiable SetRelationships(IIdentifiable resource, IDictio protected JToken LoadJToken(string body) { - JToken jToken; - using (JsonReader jsonReader = new JsonTextReader(new StringReader(body))) + using JsonReader jsonReader = new JsonTextReader(new StringReader(body)) { // https://github.com/json-api-dotnet/JsonApiDotNetCore/issues/509 - jsonReader.DateParseHandling = DateParseHandling.None; - jToken = JToken.Load(jsonReader); - } - return jToken; + DateParseHandling = DateParseHandling.None + }; + + return JToken.Load(jsonReader); } /// diff --git a/src/JsonApiDotNetCore/Serialization/BaseSerializer.cs b/src/JsonApiDotNetCore/Serialization/BaseSerializer.cs index 8fc6c5dce1..d9248c56d7 100644 --- a/src/JsonApiDotNetCore/Serialization/BaseSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/BaseSerializer.cs @@ -71,11 +71,9 @@ protected string SerializeObject(object value, JsonSerializerSettings defaultSet changeSerializer?.Invoke(serializer); using var stringWriter = new StringWriter(); - using (var jsonWriter = new JsonTextWriter(stringWriter)) - { - serializer.Serialize(jsonWriter, value); - } + using var jsonWriter = new JsonTextWriter(stringWriter); + serializer.Serialize(jsonWriter, value); return stringWriter.ToString(); } } diff --git a/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs index ac61ddf545..f160e7d46e 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs @@ -37,7 +37,7 @@ public ResponseResourceObjectBuilder(ILinkBuilder linkBuilder, _includedBuilder = includedBuilder; _constraintProviders = constraintProviders; _resourceDefinitionAccessor = resourceDefinitionAccessor; - _sparseFieldSetCache = new SparseFieldSetCache(constraintProviders, resourceDefinitionAccessor); + _sparseFieldSetCache = new SparseFieldSetCache(_constraintProviders, resourceDefinitionAccessor); } public RelationshipEntry Build(IIdentifiable resource, RelationshipAttribute requestRelationship) diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs index efac073c73..201e2681c4 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs @@ -80,7 +80,7 @@ protected override void AfterProcessField(IIdentifiable resource, ResourceFieldA } else if (field is HasManyAttribute hasManyAttr) { // add attributes and relationships of a parsed HasMany relationship - var items = data.ManyData.Select(rio => ParseIncludedRelationship(rio)); + var items = data.ManyData.Select(ParseIncludedRelationship); var values = TypeHelper.CopyToTypedCollection(items, hasManyAttr.Property.PropertyType); hasManyAttr.SetValue(resource, values); } diff --git a/src/JsonApiDotNetCore/Serialization/Objects/AtomicOperationObject.cs b/src/JsonApiDotNetCore/Serialization/Objects/AtomicOperationObject.cs index baa787aed0..b6b4a134b8 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/AtomicOperationObject.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/AtomicOperationObject.cs @@ -12,7 +12,8 @@ public sealed class AtomicOperationObject : ExposableData [JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)] public Dictionary Meta { get; set; } - [JsonProperty("op"), JsonConverter(typeof(StringEnumConverter))] + [JsonProperty("op")] + [JsonConverter(typeof(StringEnumConverter))] public AtomicOperationCode Code { get; set; } [JsonProperty("ref", NullValueHandling = NullValueHandling.Ignore)] diff --git a/src/JsonApiDotNetCore/TypeHelper.cs b/src/JsonApiDotNetCore/TypeHelper.cs index 361b6edaef..c36d585958 100644 --- a/src/JsonApiDotNetCore/TypeHelper.cs +++ b/src/JsonApiDotNetCore/TypeHelper.cs @@ -184,7 +184,7 @@ public static object CreateInstanceOfOpenType(Type openType, Type parameter, par } /// - /// Use this overload if you need to instantiate a type that has a internal constructor + /// Use this overload if you need to instantiate a type that has an internal constructor /// public static object CreateInstanceOfOpenType(Type openType, Type parameter, bool hasInternalConstructor, params object[] constructorArguments) { @@ -204,18 +204,18 @@ public static object CreateInstanceOfOpenType(Type openType, Type parameter, boo /// Reflectively instantiates a list of a certain type. /// /// The list of the target type - /// The target type - public static IList CreateListFor(Type type) + /// The target type + public static IList CreateListFor(Type elementType) { - return (IList)CreateInstanceOfOpenType(typeof(List<>), type); + return (IList)CreateInstanceOfOpenType(typeof(List<>), elementType); } /// /// Reflectively instantiates a hashset of a certain type. /// - public static IEnumerable CreateHashSetFor(Type type, object elements = null) + public static IEnumerable CreateHashSetFor(Type type, object elements) { - return (IEnumerable)CreateInstanceOfOpenType(typeof(HashSet<>), type, elements ?? new object()); + return (IEnumerable)CreateInstanceOfOpenType(typeof(HashSet<>), type, elements); } /// @@ -258,14 +258,14 @@ public static bool TypeCanContainHashSet(Type collectionType) } /// - /// Gets the type (Guid or int) of the Id of a type that implements IIdentifiable + /// Gets the type (such as Guid or int) of the Id property on a type that implements . /// public static Type GetIdType(Type resourceType) { var property = resourceType.GetProperty(nameof(Identifiable.Id)); if (property == null) { - throw new ArgumentException("Type does not have 'Id' property."); + throw new ArgumentException($"Type '{resourceType.Name}' does not have 'Id' property."); } return property.PropertyType; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Controllers/CreateMusicTrackOperationsController.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Controllers/CreateMusicTrackOperationsController.cs index 1a3db3a952..d4a69eb31a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Controllers/CreateMusicTrackOperationsController.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Controllers/CreateMusicTrackOperationsController.cs @@ -15,7 +15,8 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.Controllers { - [DisableRoutingConvention, Route("/operations/musicTracks/create")] + [DisableRoutingConvention] + [Route("/operations/musicTracks/create")] public sealed class CreateMusicTrackOperationsController : JsonApiOperationsController { public CreateMusicTrackOperationsController(IJsonApiOptions options, ILoggerFactory loggerFactory, diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs index dc3a70e818..e6731c7d31 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs @@ -77,8 +77,6 @@ public async Task Cannot_process_empty_operations_array() var requestBody = new { atomic__operations = new object[0] - { - } }; const string route = "/operations"; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CiviliansController.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CiviliansController.cs index dd2df9b6d6..e8a730e15c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CiviliansController.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CiviliansController.cs @@ -9,7 +9,8 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CustomRoutes { [ApiController] - [DisableRoutingConvention, Route("world-civilians")] + [DisableRoutingConvention] + [Route("world-civilians")] public sealed class CiviliansController : JsonApiController { public CiviliansController(IJsonApiOptions options, ILoggerFactory loggerFactory, diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/TownsController.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/TownsController.cs index af390bd683..a39b9c96c9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/TownsController.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/TownsController.cs @@ -11,7 +11,8 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CustomRoutes { - [DisableRoutingConvention, Route("world-api/civilization/popular/towns")] + [DisableRoutingConvention] + [Route("world-api/civilization/popular/towns")] public sealed class TownsController : JsonApiController { private readonly CustomRouteDbContext _dbContext; diff --git a/test/UnitTests/Graph/TypeLocatorTests.cs b/test/UnitTests/Graph/TypeLocatorTests.cs index fd3bdebd68..4c3c055b64 100644 --- a/test/UnitTests/Graph/TypeLocatorTests.cs +++ b/test/UnitTests/Graph/TypeLocatorTests.cs @@ -1,4 +1,3 @@ -using System; using JsonApiDotNetCore.Configuration; using Xunit; @@ -98,7 +97,7 @@ public void TryGetResourceDescriptor_Returns_Type_If_Type_Is_IIdentifiable() public void TryGetResourceDescriptor_Returns_False_If_Type_Is_IIdentifiable() { // Arrange - var resourceType = typeof(String); + var resourceType = typeof(string); // Act var descriptor = TypeLocator.TryGetResourceDescriptor(resourceType); diff --git a/test/UnitTests/Internal/ErrorDocumentTests.cs b/test/UnitTests/Internal/ErrorDocumentTests.cs index 4a7dd40a24..40a958b1ae 100644 --- a/test/UnitTests/Internal/ErrorDocumentTests.cs +++ b/test/UnitTests/Internal/ErrorDocumentTests.cs @@ -10,10 +10,8 @@ public sealed class ErrorDocumentTests [Fact] public void Can_GetStatusCode() { - List errors = new List(); - // Add First 422 error - errors.Add(new Error(HttpStatusCode.UnprocessableEntity) {Title = "Something wrong"}); + var errors = new List { new Error(HttpStatusCode.UnprocessableEntity) { Title = "Something wrong" } }; Assert.Equal(HttpStatusCode.UnprocessableEntity, new ErrorDocument(errors).GetErrorStatusCode()); // Add a second 422 error diff --git a/test/UnitTests/Internal/TypeHelperTests.cs b/test/UnitTests/Internal/TypeHelperTests.cs index 982b966036..044b270fff 100644 --- a/test/UnitTests/Internal/TypeHelperTests.cs +++ b/test/UnitTests/Internal/TypeHelperTests.cs @@ -12,7 +12,7 @@ public sealed class TypeHelperTests public void Can_Convert_DateTimeOffsets() { // Arrange - var dto = new DateTimeOffset(new DateTime(2002, 2,2), TimeSpan.FromHours(4));; + var dto = new DateTimeOffset(new DateTime(2002, 2, 2), TimeSpan.FromHours(4)); var formattedString = dto.ToString("O"); // Act diff --git a/test/UnitTests/Models/ResourceConstructionTests.cs b/test/UnitTests/Models/ResourceConstructionTests.cs index 89c94df18c..0265fbb659 100644 --- a/test/UnitTests/Models/ResourceConstructionTests.cs +++ b/test/UnitTests/Models/ResourceConstructionTests.cs @@ -14,9 +14,9 @@ namespace UnitTests.Models { public sealed class ResourceConstructionTests { - public Mock _requestMock; - public Mock _mockHttpContextAccessor; - + private readonly Mock _requestMock; + private readonly Mock _mockHttpContextAccessor; + public ResourceConstructionTests() { _mockHttpContextAccessor = new Mock(); diff --git a/test/UnitTests/Models/ResourceWithDbContextConstructor.cs b/test/UnitTests/Models/ResourceWithDbContextConstructor.cs deleted file mode 100644 index 94e81d6f62..0000000000 --- a/test/UnitTests/Models/ResourceWithDbContextConstructor.cs +++ /dev/null @@ -1,18 +0,0 @@ -using JsonApiDotNetCore; -using JsonApiDotNetCore.Resources; -using JsonApiDotNetCoreExample.Data; - -namespace UnitTests.Models -{ - public class ResourceWithDbContextConstructor : Identifiable - { - public AppDbContext AppDbContext { get; } - - public ResourceWithDbContextConstructor(AppDbContext appDbContext) - { - ArgumentGuard.NotNull(appDbContext, nameof(appDbContext)); - - AppDbContext = appDbContext; - } - } -} \ No newline at end of file diff --git a/test/UnitTests/ResourceHooks/DiscoveryTests.cs b/test/UnitTests/ResourceHooks/DiscoveryTests.cs index b38fe013ee..34ae7a5ebc 100644 --- a/test/UnitTests/ResourceHooks/DiscoveryTests.cs +++ b/test/UnitTests/ResourceHooks/DiscoveryTests.cs @@ -32,8 +32,9 @@ private IServiceProvider MockProvider(object service) where TResource [Fact] public void HookDiscovery_StandardResourceDefinition_CanDiscover() { - // Arrange & act + // Act var hookConfig = new HooksDiscovery(MockProvider(new DummyResourceDefinition())); + // Assert Assert.Contains(ResourceHook.BeforeDelete, hookConfig.ImplementedHooks); Assert.Contains(ResourceHook.AfterDelete, hookConfig.ImplementedHooks); @@ -55,8 +56,9 @@ public AnotherDummyResourceDefinition() : base(new ResourceGraphBuilder(new Json [Fact] public void HookDiscovery_InheritanceSubclass_CanDiscover() { - // Arrange & act + // Act var hookConfig = new HooksDiscovery(MockProvider(new AnotherDummyResourceDefinition())); + // Assert Assert.Contains(ResourceHook.BeforeDelete, hookConfig.ImplementedHooks); Assert.Contains(ResourceHook.AfterDelete, hookConfig.ImplementedHooks); @@ -76,18 +78,17 @@ public override void AfterDelete(HashSet resources, ResourcePip [Fact] public void HookDiscovery_WronglyUsedLoadDatabaseValueAttribute_ThrowsJsonApiSetupException() { - // assert - Assert.Throws(() => - { - // Arrange & act - new HooksDiscovery(MockProvider(new YetAnotherDummyResourceDefinition())); - }); + // Act + Action action = () => _ = new HooksDiscovery(MockProvider(new YetAnotherDummyResourceDefinition())); + + // Assert + Assert.Throws(action); } [Fact] public void HookDiscovery_InheritanceWithGenericSubclass_CanDiscover() { - // Arrange & act + // Act var hookConfig = new HooksDiscovery(MockProvider(new GenericDummyResourceDefinition())); // Assert diff --git a/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs index 6ab1a45d67..b56d3a2cc6 100644 --- a/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs @@ -46,7 +46,7 @@ public void BeforeDelete() // Assert personResourceMock.Verify(rd => rd.BeforeDelete(It.IsAny>(), It.IsAny()), Times.Once()); - todoResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship(It.Is>(rh => CheckImplicitTodos(rh)), ResourcePipeline.Delete), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship(It.Is>(rh => CheckImplicitTodoItems(rh)), ResourcePipeline.Delete), Times.Once()); passportResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship(It.Is>(rh => CheckImplicitPassports(rh)), ResourcePipeline.Delete), Times.Once()); VerifyNoOtherCalls(personResourceMock, todoResourceMock, passportResourceMock); } @@ -64,7 +64,7 @@ public void BeforeDelete_No_Parent_Hooks() hookExecutor.BeforeDelete(new List { _person }, ResourcePipeline.Delete); // Assert - todoResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship(It.Is>(rh => CheckImplicitTodos(rh)), ResourcePipeline.Delete), Times.Once()); + todoResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship(It.Is>(rh => CheckImplicitTodoItems(rh)), ResourcePipeline.Delete), Times.Once()); passportResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship(It.Is>(rh => CheckImplicitPassports(rh)), ResourcePipeline.Delete), Times.Once()); VerifyNoOtherCalls(personResourceMock, todoResourceMock, passportResourceMock); } @@ -86,10 +86,10 @@ public void BeforeDelete_No_Children_Hooks() VerifyNoOtherCalls(personResourceMock, todoResourceMock, passportResourceMock); } - private bool CheckImplicitTodos(IRelationshipsDictionary rh) + private bool CheckImplicitTodoItems(IRelationshipsDictionary rh) { - var todos = rh.GetByRelationship(); - return todos.Count == 2; + var todoItems = rh.GetByRelationship(); + return todoItems.Count == 2; } private bool CheckImplicitPassports(IRelationshipsDictionary rh) diff --git a/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs b/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs index ffe7d90511..986011e7b2 100644 --- a/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs @@ -42,7 +42,7 @@ public void Resource_Has_Cyclic_Relations() var (_, hookExecutor, todoResourceMock) = CreateTestObjects(todoDiscovery); var todo = new TodoItem(); todo.ParentTodo = todo; - todo.ChildrenTodos = new List { todo }; + todo.ChildTodoItems = new List { todo }; var todoList = new List { todo }; // Act @@ -61,12 +61,12 @@ public void Resource_Has_Nested_Cyclic_Relations() var (_, hookExecutor, todoResourceMock) = CreateTestObjects(todoDiscovery); var rootTodo = new TodoItem { Id = 1 }; var child = new TodoItem { ParentTodo = rootTodo, Id = 2 }; - rootTodo.ChildrenTodos = new List { child }; + rootTodo.ChildTodoItems = new List { child }; var grandChild = new TodoItem { ParentTodo = child, Id = 3 }; - child.ChildrenTodos = new List { grandChild }; + child.ChildTodoItems = new List { grandChild }; var greatGrandChild = new TodoItem { ParentTodo = grandChild, Id = 4 }; - grandChild.ChildrenTodos = new List { greatGrandChild }; - greatGrandChild.ChildrenTodos = new List { rootTodo }; + grandChild.ChildTodoItems = new List { greatGrandChild }; + greatGrandChild.ChildTodoItems = new List { rootTodo }; var todoList = new List { rootTodo }; // Act diff --git a/test/UnitTests/ResourceHooks/HooksTestsSetup.cs b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs index f1a7ca5578..d189544d3a 100644 --- a/test/UnitTests/ResourceHooks/HooksTestsSetup.cs +++ b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs @@ -156,11 +156,11 @@ protected DbContextOptions InitInMemoryDb(Action seeder .UseInMemoryDatabase(databaseName: "repository_mock") .Options; - using (var context = new AppDbContext(options)) - { - seeder(context); - ResolveInverseRelationships(context); - } + using var context = new AppDbContext(options); + + seeder(context); + ResolveInverseRelationships(context); + return options; } diff --git a/test/UnitTests/Serialization/Client/RequestSerializerTests.cs b/test/UnitTests/Serialization/Client/RequestSerializerTests.cs index 461ed6ef51..f2bb1fb654 100644 --- a/test/UnitTests/Serialization/Client/RequestSerializerTests.cs +++ b/test/UnitTests/Serialization/Client/RequestSerializerTests.cs @@ -14,8 +14,8 @@ public sealed class RequestSerializerTests : SerializerTestsSetup public RequestSerializerTests() { - var builder = new ResourceObjectBuilder(_resourceGraph, new ResourceObjectBuilderSettings()); - _serializer = new RequestSerializer(_resourceGraph, builder); + var builder = new ResourceObjectBuilder(ResourceGraph, new ResourceObjectBuilderSettings()); + _serializer = new RequestSerializer(ResourceGraph, builder); } [Fact] @@ -52,7 +52,7 @@ public void SerializeSingle_ResourceWithTargetedSetAttributes_CanBuild() { // Arrange var resource = new TestResource { Id = 1, StringField = "value", NullableIntField = 123 }; - _serializer.AttributesToSerialize = _resourceGraph.GetAttributes(tr => tr.StringField); + _serializer.AttributesToSerialize = ResourceGraph.GetAttributes(tr => tr.StringField); // Act string serialized = _serializer.Serialize(resource); @@ -76,7 +76,7 @@ public void SerializeSingle_NoIdWithTargetedSetAttributes_CanBuild() { // Arrange var resourceNoId = new TestResource { Id = 0, StringField = "value", NullableIntField = 123 }; - _serializer.AttributesToSerialize = _resourceGraph.GetAttributes(tr => tr.StringField); + _serializer.AttributesToSerialize = ResourceGraph.GetAttributes(tr => tr.StringField); // Act string serialized = _serializer.Serialize(resourceNoId); @@ -100,7 +100,7 @@ public void SerializeSingle_ResourceWithoutTargetedAttributes_CanBuild() { // Arrange var resource = new TestResource { Id = 1, StringField = "value", NullableIntField = 123 }; - _serializer.AttributesToSerialize = _resourceGraph.GetAttributes(tr => new { }); + _serializer.AttributesToSerialize = ResourceGraph.GetAttributes(tr => new { }); // Act string serialized = _serializer.Serialize(resource); @@ -126,7 +126,7 @@ public void SerializeSingle_ResourceWithTargetedRelationships_CanBuild() PopulatedToOne = new OneToOneDependent { Id = 10 }, PopulatedToManies = new HashSet { new OneToManyDependent { Id = 20 } } }; - _serializer.RelationshipsToSerialize = _resourceGraph.GetRelationships(tr => new { tr.EmptyToOne, tr.EmptyToManies, tr.PopulatedToOne, tr.PopulatedToManies }); + _serializer.RelationshipsToSerialize = ResourceGraph.GetRelationships(tr => new { tr.EmptyToOne, tr.EmptyToManies, tr.PopulatedToOne, tr.PopulatedToManies }); // Act string serialized = _serializer.Serialize(resourceWithRelationships); @@ -174,7 +174,7 @@ public void SerializeMany_ResourcesWithTargetedAttributes_CanBuild() new TestResource { Id = 1, StringField = "value1", NullableIntField = 123 }, new TestResource { Id = 2, StringField = "value2", NullableIntField = 123 } }; - _serializer.AttributesToSerialize = _resourceGraph.GetAttributes(tr => tr.StringField); + _serializer.AttributesToSerialize = ResourceGraph.GetAttributes(tr => tr.StringField); // Act string serialized = _serializer.Serialize(resources); @@ -206,7 +206,7 @@ public void SerializeMany_ResourcesWithTargetedAttributes_CanBuild() public void SerializeSingle_Null_CanBuild() { // Arrange - _serializer.AttributesToSerialize = _resourceGraph.GetAttributes(tr => tr.StringField); + _serializer.AttributesToSerialize = ResourceGraph.GetAttributes(tr => tr.StringField); // Act string serialized = _serializer.Serialize((IIdentifiable) null); @@ -224,7 +224,7 @@ public void SerializeMany_EmptyList_CanBuild() { // Arrange var resources = new List(); - _serializer.AttributesToSerialize = _resourceGraph.GetAttributes(tr => tr.StringField); + _serializer.AttributesToSerialize = ResourceGraph.GetAttributes(tr => tr.StringField); // Act string serialized = _serializer.Serialize(resources); diff --git a/test/UnitTests/Serialization/Client/ResponseDeserializerTests.cs b/test/UnitTests/Serialization/Client/ResponseDeserializerTests.cs index e7c5ffcc3a..7573a6ff9a 100644 --- a/test/UnitTests/Serialization/Client/ResponseDeserializerTests.cs +++ b/test/UnitTests/Serialization/Client/ResponseDeserializerTests.cs @@ -17,7 +17,7 @@ public sealed class ResponseDeserializerTests : DeserializerTestsSetup public ResponseDeserializerTests() { - _deserializer = new ResponseDeserializer(_resourceGraph, new ResourceFactory(new ServiceContainer())); + _deserializer = new ResponseDeserializer(ResourceGraph, new ResourceFactory(new ServiceContainer())); _linkValues.Add("self", "http://example.com/articles"); _linkValues.Add("next", "http://example.com/articles?page[number]=2"); _linkValues.Add("last", "http://example.com/articles?page[number]=10"); diff --git a/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs b/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs index 08c0f89ca4..bea75b9bf1 100644 --- a/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs +++ b/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs @@ -17,7 +17,7 @@ public sealed class BaseDocumentParserTests : DeserializerTestsSetup public BaseDocumentParserTests() { - _deserializer = new TestDeserializer(_resourceGraph, new ResourceFactory(new ServiceContainer())); + _deserializer = new TestDeserializer(ResourceGraph, new ResourceFactory(new ServiceContainer())); } [Fact] @@ -133,7 +133,7 @@ public void DeserializeAttributes_VariousDataTypes_CanDeserialize(string member, var resource = (TestResource)_deserializer.Deserialize(body); // Assert - var pi = _resourceGraph.GetResourceContext("testResource").Attributes.Single(attr => attr.PublicName == member).Property; + var pi = ResourceGraph.GetResourceContext("testResource").Attributes.Single(attr => attr.PublicName == member).Property; var deserializedValue = pi.GetValue(resource); if (member == "intField") diff --git a/test/UnitTests/Serialization/Common/ResourceObjectBuilderTests.cs b/test/UnitTests/Serialization/Common/ResourceObjectBuilderTests.cs index e0572f6d6a..95168a31d6 100644 --- a/test/UnitTests/Serialization/Common/ResourceObjectBuilderTests.cs +++ b/test/UnitTests/Serialization/Common/ResourceObjectBuilderTests.cs @@ -14,7 +14,7 @@ public sealed class ResourceObjectBuilderTests : SerializerTestsSetup public ResourceObjectBuilderTests() { - _builder = new ResourceObjectBuilder(_resourceGraph, new ResourceObjectBuilderSettings()); + _builder = new ResourceObjectBuilder(ResourceGraph, new ResourceObjectBuilderSettings()); } [Fact] @@ -56,7 +56,7 @@ public void ResourceToResourceObject_ResourceWithIncludedAttrs_CanBuild(string s { // Arrange var resource = new TestResource { StringField = stringFieldValue, NullableIntField = intFieldValue }; - var attrs = _resourceGraph.GetAttributes(tr => new { tr.StringField, tr.NullableIntField }); + var attrs = ResourceGraph.GetAttributes(tr => new { tr.StringField, tr.NullableIntField }); // Act var resourceObject = _builder.Build(resource, attrs); @@ -112,7 +112,7 @@ public void ResourceWithRelationshipsToResourceObject_WithIncludedRelationshipsA PopulatedToOne = new OneToOneDependent { Id = 10 }, PopulatedToManies = new HashSet { new OneToManyDependent { Id = 20 } } }; - var relationships = _resourceGraph.GetRelationships(tr => new { tr.PopulatedToManies, tr.PopulatedToOne, tr.EmptyToOne, tr.EmptyToManies }); + var relationships = ResourceGraph.GetRelationships(tr => new { tr.PopulatedToManies, tr.PopulatedToOne, tr.EmptyToOne, tr.EmptyToManies }); // Act var resourceObject = _builder.Build(resource, relationships: relationships); @@ -136,7 +136,7 @@ public void ResourceWithRelationshipsToResourceObject_DeviatingForeignKeyWhileRe { // Arrange var resource = new OneToOneDependent { Principal = new OneToOnePrincipal { Id = 10 }, PrincipalId = 123 }; - var relationships = _resourceGraph.GetRelationships(tr => tr.Principal); + var relationships = ResourceGraph.GetRelationships(tr => tr.Principal); // Act var resourceObject = _builder.Build(resource, relationships: relationships); @@ -153,7 +153,7 @@ public void ResourceWithRelationshipsToResourceObject_DeviatingForeignKeyAndNoNa { // Arrange var resource = new OneToOneDependent { Principal = null, PrincipalId = 123 }; - var relationships = _resourceGraph.GetRelationships(tr => tr.Principal); + var relationships = ResourceGraph.GetRelationships(tr => tr.Principal); // Act var resourceObject = _builder.Build(resource, relationships: relationships); @@ -167,7 +167,7 @@ public void ResourceWithRequiredRelationshipsToResourceObject_DeviatingForeignKe { // Arrange var resource = new OneToOneRequiredDependent { Principal = new OneToOnePrincipal { Id = 10 }, PrincipalId = 123 }; - var relationships = _resourceGraph.GetRelationships(tr => tr.Principal); + var relationships = ResourceGraph.GetRelationships(tr => tr.Principal); // Act var resourceObject = _builder.Build(resource, relationships: relationships); diff --git a/test/UnitTests/Serialization/DeserializerTestsSetup.cs b/test/UnitTests/Serialization/DeserializerTestsSetup.cs index e3a6b9a45b..4785b346af 100644 --- a/test/UnitTests/Serialization/DeserializerTestsSetup.cs +++ b/test/UnitTests/Serialization/DeserializerTestsSetup.cs @@ -11,12 +11,12 @@ namespace UnitTests.Serialization { public class DeserializerTestsSetup : SerializationTestsSetupBase { - public Mock _mockHttpContextAccessor; + protected Mock MockHttpContextAccessor { get; } public DeserializerTestsSetup() { - _mockHttpContextAccessor = new Mock(); - _mockHttpContextAccessor.Setup(mock => mock.HttpContext).Returns(new DefaultHttpContext()); + MockHttpContextAccessor = new Mock(); + MockHttpContextAccessor.Setup(mock => mock.HttpContext).Returns(new DefaultHttpContext()); } protected sealed class TestDeserializer : BaseDeserializer { diff --git a/test/UnitTests/Serialization/SerializationTestsSetupBase.cs b/test/UnitTests/Serialization/SerializationTestsSetupBase.cs index 03685f31dc..2e2fd2e174 100644 --- a/test/UnitTests/Serialization/SerializationTestsSetupBase.cs +++ b/test/UnitTests/Serialization/SerializationTestsSetupBase.cs @@ -8,7 +8,7 @@ namespace UnitTests.Serialization { public class SerializationTestsSetupBase { - protected IResourceGraph _resourceGraph; + protected IResourceGraph ResourceGraph { get; } protected readonly Faker _foodFaker; protected readonly Faker _songFaker; protected readonly Faker
_articleFaker; @@ -17,7 +17,7 @@ public class SerializationTestsSetupBase public SerializationTestsSetupBase() { - _resourceGraph = BuildGraph(); + ResourceGraph = BuildGraph(); _articleFaker = new Faker
() .RuleFor(f => f.Title, f => f.Hacker.Phrase()) .RuleFor(f => f.Id, f => f.UniqueIndex + 1); diff --git a/test/UnitTests/Serialization/SerializerTestsSetup.cs b/test/UnitTests/Serialization/SerializerTestsSetup.cs index 7251e2fbe1..1f0e4b9fc4 100644 --- a/test/UnitTests/Serialization/SerializerTestsSetup.cs +++ b/test/UnitTests/Serialization/SerializerTestsSetup.cs @@ -46,7 +46,7 @@ protected ResponseSerializer GetResponseSerializer(List(meta, link, includedBuilder, fieldsToSerialize, resourceObjectBuilder, new JsonApiOptions()); } @@ -55,12 +55,12 @@ protected ResponseResourceObjectBuilder GetResponseResourceObjectBuilder(List
  • (), GetResourceDefinitionAccessor(), GetSerializerSettingsProvider()); + return new IncludedResourceObjectBuilder(GetSerializableFields(), GetLinkBuilder(), ResourceGraph, Enumerable.Empty(), GetResourceDefinitionAccessor(), GetSerializerSettingsProvider()); } protected IResourceObjectBuilderSettingsProvider GetSerializerSettingsProvider() @@ -95,8 +95,8 @@ protected ILinkBuilder GetLinkBuilder(TopLevelLinks top = null, ResourceLinks re protected IFieldsToSerialize GetSerializableFields() { var mock = new Mock(); - mock.Setup(m => m.GetAttributes(It.IsAny())).Returns(t => _resourceGraph.GetResourceContext(t).Attributes); - mock.Setup(m => m.GetRelationships(It.IsAny())).Returns(t => _resourceGraph.GetResourceContext(t).Relationships); + mock.Setup(m => m.GetAttributes(It.IsAny())).Returns(t => ResourceGraph.GetResourceContext(t).Attributes); + mock.Setup(m => m.GetRelationships(It.IsAny())).Returns(t => ResourceGraph.GetResourceContext(t).Relationships); return mock.Object; } diff --git a/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs b/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs index 54249216f7..754303a712 100644 --- a/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs +++ b/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs @@ -157,13 +157,13 @@ public void BuildIncluded_DuplicateChildrenMultipleChains_OnceInOutput() private List GetIncludedRelationshipsChain(string chain) { var parsedChain = new List(); - var resourceContext = _resourceGraph.GetResourceContext
    (); + var resourceContext = ResourceGraph.GetResourceContext
    (); var splitPath = chain.Split('.'); foreach (var requestedRelationship in splitPath) { var relationship = resourceContext.Relationships.Single(r => r.PublicName == requestedRelationship); parsedChain.Add(relationship); - resourceContext = _resourceGraph.GetResourceContext(relationship.RightType); + resourceContext = ResourceGraph.GetResourceContext(relationship.RightType); } return parsedChain; } @@ -174,7 +174,7 @@ private IncludedResourceObjectBuilder GetBuilder() var links = GetLinkBuilder(); var accessor = new Mock().Object; - return new IncludedResourceObjectBuilder(fields, links, _resourceGraph, Enumerable.Empty(), accessor, GetSerializerSettingsProvider()); + return new IncludedResourceObjectBuilder(fields, links, ResourceGraph, Enumerable.Empty(), accessor, GetSerializerSettingsProvider()); } } } diff --git a/test/UnitTests/Serialization/Server/RequestDeserializerTests.cs b/test/UnitTests/Serialization/Server/RequestDeserializerTests.cs index da492a2938..295b13fdb3 100644 --- a/test/UnitTests/Serialization/Server/RequestDeserializerTests.cs +++ b/test/UnitTests/Serialization/Server/RequestDeserializerTests.cs @@ -19,7 +19,7 @@ public sealed class RequestDeserializerTests : DeserializerTestsSetup private readonly Mock _requestMock = new Mock(); public RequestDeserializerTests() { - _deserializer = new RequestDeserializer(_resourceGraph, new ResourceFactory(new ServiceContainer()), _fieldsManagerMock.Object, _mockHttpContextAccessor.Object, _requestMock.Object, new JsonApiOptions()); + _deserializer = new RequestDeserializer(ResourceGraph, new ResourceFactory(new ServiceContainer()), _fieldsManagerMock.Object, MockHttpContextAccessor.Object, _requestMock.Object, new JsonApiOptions()); } [Fact] diff --git a/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs b/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs index ce4d6cdff3..97d0b363e1 100644 --- a/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs +++ b/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs @@ -13,7 +13,7 @@ public sealed class ResponseResourceObjectBuilderTests : SerializerTestsSetup public ResponseResourceObjectBuilderTests() { - _relationshipsForBuild = _resourceGraph.GetRelationships(e => new { e.Dependents }).ToList(); + _relationshipsForBuild = ResourceGraph.GetRelationships(e => new { e.Dependents }).ToList(); } [Fact] diff --git a/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs b/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs index f9f51548a7..874b50d4c8 100644 --- a/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs +++ b/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs @@ -85,7 +85,7 @@ public void SerializeSingle_ResourceWithIncludedRelationships_CanSerialize() PopulatedToOne = new OneToOneDependent { Id = 10 }, PopulatedToManies = new HashSet { new OneToManyDependent { Id = 20 } } }; - var chain = _resourceGraph.GetRelationships().Select(r => new List { r }).ToList(); + var chain = ResourceGraph.GetRelationships().Select(r => new List { r }).ToList(); var serializer = GetResponseSerializer(inclusionChains: chain); // Act @@ -147,7 +147,7 @@ public void SerializeSingle_ResourceWithDeeplyIncludedRelationships_CanSerialize PopulatedToManies = new HashSet { includedResource } }; - var chains = _resourceGraph.GetRelationships() + var chains = ResourceGraph.GetRelationships() .Select(r => { var chain = new List {r}; @@ -156,7 +156,7 @@ public void SerializeSingle_ResourceWithDeeplyIncludedRelationships_CanSerialize return new List {r}; } - chain.AddRange(_resourceGraph.GetRelationships()); + chain.AddRange(ResourceGraph.GetRelationships()); return chain; }).ToList(); From bf2cc2080d736a56c5c99ba67b401874faaac2b2 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Mon, 15 Feb 2021 18:08:57 +0100 Subject: [PATCH 12/60] Manual code cleanups in preparation for reformat --- benchmarks/Query/QueryParserBenchmarks.cs | 5 ++- .../JsonApiDeserializerBenchmarks.cs | 5 +-- .../Data/AppDbContext.cs | 2 + .../Definitions/LockableHooksDefinition.cs | 3 +- .../Services/WorkItemService.cs | 45 ++++++++++--------- .../JsonApiApplicationBuilder.cs | 37 ++++++++------- .../Configuration/ResourceGraphBuilder.cs | 6 ++- .../Configuration/TypeLocator.cs | 9 ++-- ...annotClearRequiredRelationshipException.cs | 3 +- .../MissingTransactionSupportException.cs | 3 +- .../Errors/NonSharedTransactionException.cs | 3 +- .../Errors/ResourceIdMismatchException.cs | 3 +- .../Errors/ResourceTypeMismatchException.cs | 3 +- .../Execution/DiffableResourceHashSet.cs | 2 +- .../Hooks/Internal/ResourceHookExecutor.cs | 17 +++++-- .../Hooks/Internal/Traversal/ChildNode.cs | 8 ++-- .../Internal/Traversal/RelationshipProxy.cs | 5 ++- .../Internal/Traversal/TraversalHelper.cs | 7 ++- .../IAsyncConvertEmptyActionResultFilter.cs | 6 ++- .../Middleware/IJsonApiRequest.cs | 2 + .../Middleware/JsonApiMiddleware.cs | 3 +- .../Middleware/JsonApiRoutingConvention.cs | 16 +++---- .../Expressions/IncludeChainConverter.cs | 10 ++++- .../Internal/Parsing/SparseFieldTypeParser.cs | 4 +- .../Queries/Internal/QueryLayerComposer.cs | 42 +++++++++++++++-- .../QueryableBuilding/OrderClauseBuilder.cs | 25 ++++++++--- .../QueryableBuilding/WhereClauseBuilder.cs | 11 +++-- .../Queries/Internal/SparseFieldSetCache.cs | 6 +++ .../Repositories/DbContextExtensions.cs | 17 ++++--- .../EntityFrameworkCoreRepository.cs | 8 +++- .../Resources/Annotations/AttrAttribute.cs | 3 +- .../Building/ResponseResourceObjectBuilder.cs | 8 +++- .../Serialization/ResponseSerializer.cs | 13 +++--- src/JsonApiDotNetCore/TypeHelper.cs | 2 +- 34 files changed, 230 insertions(+), 112 deletions(-) diff --git a/benchmarks/Query/QueryParserBenchmarks.cs b/benchmarks/Query/QueryParserBenchmarks.cs index 1d7d1b6727..362637df1c 100644 --- a/benchmarks/Query/QueryParserBenchmarks.cs +++ b/benchmarks/Query/QueryParserBenchmarks.cs @@ -94,7 +94,10 @@ public void DescendingSort() [Benchmark] public void ComplexQuery() => Run(100, () => { - var queryString = $"?filter[{BenchmarkResourcePublicNames.NameAttr}]=abc,eq:abc&sort=-{BenchmarkResourcePublicNames.NameAttr}&include=child&page[size]=1&fields[{BenchmarkResourcePublicNames.Type}]={BenchmarkResourcePublicNames.NameAttr}"; + const string resourceName = BenchmarkResourcePublicNames.Type; + const string attrName = BenchmarkResourcePublicNames.NameAttr; + + var queryString = $"?filter[{attrName}]=abc,eq:abc&sort=-{attrName}&include=child&page[size]=1&fields[{resourceName}]={attrName}"; _queryStringAccessor.SetQueryString(queryString); _queryStringReaderForAll.ReadAll(null); diff --git a/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs b/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs index 7be6c06443..e8449f4c4c 100644 --- a/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs +++ b/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs @@ -23,10 +23,7 @@ public class JsonApiDeserializerBenchmarks Id = "1", Attributes = new Dictionary { - { - "name", - Guid.NewGuid().ToString() - } + ["name"] = Guid.NewGuid().ToString() } } }); diff --git a/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs b/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs index dbab48ca35..052338711a 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs @@ -1,6 +1,8 @@ using JsonApiDotNetCoreExample.Models; using Microsoft.EntityFrameworkCore; +// @formatter:wrap_chained_method_calls chop_always + namespace JsonApiDotNetCoreExample.Data { public sealed class AppDbContext : DbContext diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/LockableHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/LockableHooksDefinition.cs index 19c0708ba2..845fc61eea 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/LockableHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/LockableHooksDefinition.cs @@ -25,7 +25,8 @@ protected void DisallowLocked(IEnumerable resources) { throw new JsonApiException(new Error(HttpStatusCode.Forbidden) { - Title = $"You are not allowed to update fields or relationships of locked resource of type '{_resourceGraph.GetResourceContext().PublicName}'." + Title = "You are not allowed to update fields or relationships of " + + $"locked resource of type '{_resourceGraph.GetResourceContext().PublicName}'." }); } } diff --git a/src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs b/src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs index edb7d5c0ba..c2927ecb99 100644 --- a/src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs +++ b/src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs @@ -25,16 +25,19 @@ public WorkItemService(IConfiguration configuration) public async Task> GetAsync(CancellationToken cancellationToken) { - return (await QueryAsync(async connection => - await connection.QueryAsync(new CommandDefinition(@"select * from ""WorkItems""", cancellationToken: cancellationToken)))).ToList(); + const string commandText = @"select * from ""WorkItems"""; + var commandDefinition = new CommandDefinition(commandText, cancellationToken: cancellationToken); + + return await QueryAsync(async connection => await connection.QueryAsync(commandDefinition)); } public async Task GetAsync(int id, CancellationToken cancellationToken) { - var query = await QueryAsync(async connection => - await connection.QueryAsync(new CommandDefinition(@"select * from ""WorkItems"" where ""Id""=@id", new {id}, cancellationToken: cancellationToken))); + const string commandText = @"select * from ""WorkItems"" where ""Id""=@id"; + var commandDefinition = new CommandDefinition(commandText, new {id}, cancellationToken: cancellationToken); - return query.Single(); + var workItems = await QueryAsync(async connection => await connection.QueryAsync(commandDefinition)); + return workItems.Single(); } public Task GetSecondaryAsync(int id, string relationshipName, CancellationToken cancellationToken) @@ -49,16 +52,16 @@ public Task GetRelationshipAsync(int id, string relationshipName, Cancel public async Task CreateAsync(WorkItem resource, CancellationToken cancellationToken) { - return (await QueryAsync(async connection => + const string commandText = @"insert into ""WorkItems"" (""Title"", ""IsBlocked"", ""DurationInHours"", ""ProjectId"") values " + + @"(@title, @isBlocked, @durationInHours, @projectId) returning ""Id"", ""Title"", ""IsBlocked"", ""DurationInHours"", ""ProjectId"""; + + var commandDefinition = new CommandDefinition(commandText, new { - const string query = @"insert into ""WorkItems"" (""Title"", ""IsBlocked"", ""DurationInHours"", ""ProjectId"") values " + - @"(@title, @isBlocked, @durationInHours, @projectId) returning ""Id"", ""Title"", ""IsBlocked"", ""DurationInHours"", ""ProjectId"""; - - return await connection.QueryAsync(new CommandDefinition(query, new - { - title = resource.Title, isBlocked = resource.IsBlocked, durationInHours = resource.DurationInHours, projectId = resource.ProjectId - }, cancellationToken: cancellationToken)); - })).SingleOrDefault(); + title = resource.Title, isBlocked = resource.IsBlocked, durationInHours = resource.DurationInHours, projectId = resource.ProjectId + }, cancellationToken: cancellationToken); + + var workItems = await QueryAsync(async connection => await connection.QueryAsync(commandDefinition)); + return workItems.Single(); } public Task AddToToManyRelationshipAsync(int primaryId, string relationshipName, ISet secondaryResourceIds, CancellationToken cancellationToken) @@ -78,8 +81,10 @@ public Task SetRelationshipAsync(int primaryId, string relationshipName, object public async Task DeleteAsync(int id, CancellationToken cancellationToken) { + const string commandText = @"delete from ""WorkItems"" where ""Id""=@id"; + await QueryAsync(async connection => - await connection.QueryAsync(new CommandDefinition(@"delete from ""WorkItems"" where ""Id""=@id", new {id}, cancellationToken: cancellationToken))); + await connection.QueryAsync(new CommandDefinition(commandText, new {id}, cancellationToken: cancellationToken))); } public Task RemoveFromToManyRelationshipAsync(int primaryId, string relationshipName, ISet secondaryResourceIds, CancellationToken cancellationToken) @@ -87,13 +92,13 @@ public Task RemoveFromToManyRelationshipAsync(int primaryId, string relationship throw new NotImplementedException(); } - private async Task> QueryAsync(Func>> query) + private async Task> QueryAsync(Func>> query) { - using IDbConnection dbConnection = GetConnection; + using IDbConnection dbConnection = new NpgsqlConnection(_connectionString); dbConnection.Open(); - return await query(dbConnection); - } - private IDbConnection GetConnection => new NpgsqlConnection(_connectionString); + IEnumerable resources = await query(dbConnection); + return resources.ToList(); + } } } diff --git a/src/JsonApiDotNetCore/Configuration/JsonApiApplicationBuilder.cs b/src/JsonApiDotNetCore/Configuration/JsonApiApplicationBuilder.cs index 0c0c12b54f..43c0413001 100644 --- a/src/JsonApiDotNetCore/Configuration/JsonApiApplicationBuilder.cs +++ b/src/JsonApiDotNetCore/Configuration/JsonApiApplicationBuilder.cs @@ -228,26 +228,33 @@ private void AddQueryStringLayer() _services.AddScoped(); _services.AddScoped(); - _services.AddScoped(sp => sp.GetRequiredService()); - _services.AddScoped(sp => sp.GetRequiredService()); - _services.AddScoped(sp => sp.GetRequiredService()); - _services.AddScoped(sp => sp.GetRequiredService()); - _services.AddScoped(sp => sp.GetRequiredService()); - _services.AddScoped(sp => sp.GetRequiredService()); - _services.AddScoped(sp => sp.GetRequiredService()); - _services.AddScoped(sp => sp.GetRequiredService()); - - _services.AddScoped(sp => sp.GetRequiredService()); - _services.AddScoped(sp => sp.GetRequiredService()); - _services.AddScoped(sp => sp.GetRequiredService()); - _services.AddScoped(sp => sp.GetRequiredService()); - _services.AddScoped(sp => sp.GetRequiredService()); - _services.AddScoped(sp => sp.GetRequiredService()); + RegisterDependentService(); + RegisterDependentService(); + RegisterDependentService(); + RegisterDependentService(); + RegisterDependentService(); + RegisterDependentService(); + RegisterDependentService(); + RegisterDependentService(); + + RegisterDependentService(); + RegisterDependentService(); + RegisterDependentService(); + RegisterDependentService(); + RegisterDependentService(); + RegisterDependentService(); _services.AddScoped(); _services.AddSingleton(); } + private void RegisterDependentService() + where TCollectionElement : class + where TElementToAdd : TCollectionElement + { + _services.AddScoped(serviceProvider => serviceProvider.GetRequiredService()); + } + private void AddResourceHooks() { if (_options.EnableResourceHooks) diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs index 5023bc547d..fbf4d75f57 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs @@ -179,13 +179,15 @@ private IReadOnlyCollection GetRelationships(Type resourc var throughProperty = properties.SingleOrDefault(p => p.Name == hasManyThroughAttribute.ThroughPropertyName); if (throughProperty == null) { - throw new InvalidConfigurationException($"Invalid {nameof(HasManyThroughAttribute)} on '{resourceType}.{attribute.Property.Name}': Resource does not contain a property named '{hasManyThroughAttribute.ThroughPropertyName}'."); + throw new InvalidConfigurationException($"Invalid {nameof(HasManyThroughAttribute)} on '{resourceType}.{attribute.Property.Name}': " + + $"Resource does not contain a property named '{hasManyThroughAttribute.ThroughPropertyName}'."); } var throughType = TryGetThroughType(throughProperty); if (throughType == null) { - throw new InvalidConfigurationException($"Invalid {nameof(HasManyThroughAttribute)} on '{resourceType}.{attribute.Property.Name}': Referenced property '{throughProperty.Name}' does not implement 'ICollection'."); + throw new InvalidConfigurationException($"Invalid {nameof(HasManyThroughAttribute)} on '{resourceType}.{attribute.Property.Name}': " + + $"Referenced property '{throughProperty.Name}' does not implement 'ICollection'."); } // ICollection diff --git a/src/JsonApiDotNetCore/Configuration/TypeLocator.cs b/src/JsonApiDotNetCore/Configuration/TypeLocator.cs index bd30429065..057c3ef918 100644 --- a/src/JsonApiDotNetCore/Configuration/TypeLocator.cs +++ b/src/JsonApiDotNetCore/Configuration/TypeLocator.cs @@ -57,14 +57,17 @@ public static (Type implementation, Type registrationInterface)? GetGenericInter if (!openGenericInterface.IsInterface || !openGenericInterface.IsGenericType || openGenericInterface != openGenericInterface.GetGenericTypeDefinition()) { - throw new ArgumentException($"Specified type '{openGenericInterface.FullName}' is not an open generic interface.", nameof(openGenericInterface)); + throw new ArgumentException( + $"Specified type '{openGenericInterface.FullName}' " + "is not an open generic interface.", + nameof(openGenericInterface)); } if (interfaceGenericTypeArguments.Length != openGenericInterface.GetGenericArguments().Length) { throw new ArgumentException( - $"Interface '{openGenericInterface.FullName}' requires {openGenericInterface.GetGenericArguments().Length} type parameters instead of {interfaceGenericTypeArguments.Length}.", - nameof(interfaceGenericTypeArguments)); + $"Interface '{openGenericInterface.FullName}' " + + $"requires {openGenericInterface.GetGenericArguments().Length} type parameters " + + $"instead of {interfaceGenericTypeArguments.Length}.", nameof(interfaceGenericTypeArguments)); } foreach (var nextType in assembly.GetTypes()) diff --git a/src/JsonApiDotNetCore/Errors/CannotClearRequiredRelationshipException.cs b/src/JsonApiDotNetCore/Errors/CannotClearRequiredRelationshipException.cs index cc5e9f036f..36105a3252 100644 --- a/src/JsonApiDotNetCore/Errors/CannotClearRequiredRelationshipException.cs +++ b/src/JsonApiDotNetCore/Errors/CannotClearRequiredRelationshipException.cs @@ -12,7 +12,8 @@ public CannotClearRequiredRelationshipException(string relationshipName, string string resourceType) : base(new Error(HttpStatusCode.BadRequest) { Title = "Failed to clear a required relationship.", - Detail = $"The relationship '{relationshipName}' of resource type '{resourceType}' with ID '{resourceId}' cannot be cleared because it is a required relationship." + Detail = $"The relationship '{relationshipName}' of resource type '{resourceType}' " + + $"with ID '{resourceId}' cannot be cleared because it is a required relationship." }) { } diff --git a/src/JsonApiDotNetCore/Errors/MissingTransactionSupportException.cs b/src/JsonApiDotNetCore/Errors/MissingTransactionSupportException.cs index 088db9300d..85339f7252 100644 --- a/src/JsonApiDotNetCore/Errors/MissingTransactionSupportException.cs +++ b/src/JsonApiDotNetCore/Errors/MissingTransactionSupportException.cs @@ -13,7 +13,8 @@ public MissingTransactionSupportException(string resourceType) : base(new Error(HttpStatusCode.UnprocessableEntity) { Title = "Unsupported resource type in atomic:operations request.", - Detail = $"Operations on resources of type '{resourceType}' cannot be used because transaction support is unavailable." + Detail = $"Operations on resources of type '{resourceType}' " + + "cannot be used because transaction support is unavailable." }) { } diff --git a/src/JsonApiDotNetCore/Errors/NonSharedTransactionException.cs b/src/JsonApiDotNetCore/Errors/NonSharedTransactionException.cs index d0bcd69505..9753d765ca 100644 --- a/src/JsonApiDotNetCore/Errors/NonSharedTransactionException.cs +++ b/src/JsonApiDotNetCore/Errors/NonSharedTransactionException.cs @@ -13,7 +13,8 @@ public NonSharedTransactionException() : base(new Error(HttpStatusCode.UnprocessableEntity) { Title = "Unsupported combination of resource types in atomic:operations request.", - Detail = "All operations need to participate in a single shared transaction, which is not the case for this request." + Detail = "All operations need to participate in a single shared transaction, " + + "which is not the case for this request." }) { } diff --git a/src/JsonApiDotNetCore/Errors/ResourceIdMismatchException.cs b/src/JsonApiDotNetCore/Errors/ResourceIdMismatchException.cs index b463bbee0d..427dfa583c 100644 --- a/src/JsonApiDotNetCore/Errors/ResourceIdMismatchException.cs +++ b/src/JsonApiDotNetCore/Errors/ResourceIdMismatchException.cs @@ -12,7 +12,8 @@ public ResourceIdMismatchException(string bodyId, string endpointId, string requ : base(new Error(HttpStatusCode.Conflict) { Title = "Resource ID mismatch between request body and endpoint URL.", - Detail = $"Expected resource ID '{endpointId}' in PATCH request body at endpoint '{requestPath}', instead of '{bodyId}'." + Detail = $"Expected resource ID '{endpointId}' in PATCH request body " + + $"at endpoint '{requestPath}', instead of '{bodyId}'." }) { } diff --git a/src/JsonApiDotNetCore/Errors/ResourceTypeMismatchException.cs b/src/JsonApiDotNetCore/Errors/ResourceTypeMismatchException.cs index 5edec07bb3..851895fbd9 100644 --- a/src/JsonApiDotNetCore/Errors/ResourceTypeMismatchException.cs +++ b/src/JsonApiDotNetCore/Errors/ResourceTypeMismatchException.cs @@ -14,7 +14,8 @@ public ResourceTypeMismatchException(HttpMethod method, string requestPath, Reso : base(new Error(HttpStatusCode.Conflict) { Title = "Resource type mismatch between request body and endpoint URL.", - Detail = $"Expected resource of type '{expected.PublicName}' in {method} request body at endpoint '{requestPath}', instead of '{actual?.PublicName}'." + Detail = $"Expected resource of type '{expected.PublicName}' in {method} " + + $"request body at endpoint '{requestPath}', instead of '{actual?.PublicName}'." }) { } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs index 37d15c71de..1983969061 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs @@ -35,7 +35,7 @@ internal DiffableResourceHashSet(IEnumerable requestResources, Dictionary relationships, ITargetedFields targetedFields) : this((HashSet)requestResources, (HashSet)databaseResources, TypeHelper.ConvertRelationshipDictionary(relationships), - TypeHelper.ConvertAttributeDictionary(targetedFields.Attributes, (HashSet)requestResources)) + targetedFields.Attributes == null ? null : TypeHelper.ConvertAttributeDictionary(targetedFields.Attributes, (HashSet)requestResources)) { } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs index fcfc61529b..03b7d32f84 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs @@ -45,12 +45,18 @@ public void BeforeRead(ResourcePipeline pipeline, string stringId = n hookContainer?.BeforeRead(pipeline, false, stringId); var calledContainers = new List { typeof(TResource) }; + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var includes = _constraintProviders - .SelectMany(p => p.GetConstraints()) + .SelectMany(provider => provider.GetConstraints()) .Select(expressionInScope => expressionInScope.Expression) .OfType() .ToArray(); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + foreach (var chain in includes.SelectMany(IncludeChainConverter.GetRelationshipChains)) { RecursiveBeforeRead(chain.Fields.Cast().ToList(), pipeline, calledContainers); @@ -399,8 +405,8 @@ private void ValidateHookResponse(IEnumerable returnedList, ResourcePipeli { if (pipeline == ResourcePipeline.GetSingle && returnedList.Count() > 1) { - throw new ApplicationException("The returned collection from this hook may contain at most one item in the case of the" + - pipeline.ToString("G") + "pipeline"); + throw new ApplicationException("The returned collection from this hook may contain at most one item in the case of the " + + pipeline.ToString("G") + " pipeline"); } } @@ -454,7 +460,10 @@ private Dictionary ReplaceWithDbValues(Dicti { foreach (var key in prevLayerRelationships.Keys.ToList()) { - var replaced = TypeHelper.CopyToList(prevLayerRelationships[key].Cast().Select(resource => dbValues.Single(dbResource => dbResource.StringId == resource.StringId)), key.LeftType); + var source = prevLayerRelationships[key].Cast().Select(resource => + dbValues.Single(dbResource => dbResource.StringId == resource.StringId)); + + var replaced = TypeHelper.CopyToList(source, key.LeftType); prevLayerRelationships[key] = TypeHelper.CreateHashSetFor(key.LeftType, replaced); } return prevLayerRelationships; diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/ChildNode.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/ChildNode.cs index f35540e7d4..045d068150 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/ChildNode.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/ChildNode.cs @@ -13,10 +13,14 @@ namespace JsonApiDotNetCore.Hooks.Internal.Traversal internal sealed class ChildNode : IResourceNode where TResource : class, IIdentifiable { private readonly IdentifiableComparer _comparer = IdentifiableComparer.Instance; + private readonly RelationshipsFromPreviousLayer _relationshipsFromPreviousLayer; + /// public RightType ResourceType { get; } + /// public RelationshipProxy[] RelationshipsToNextLayer { get; } + /// public IEnumerable UniqueResources { @@ -29,8 +33,6 @@ public IEnumerable UniqueResources /// public IRelationshipsFromPreviousLayer RelationshipsFromPreviousLayer => _relationshipsFromPreviousLayer; - private readonly RelationshipsFromPreviousLayer _relationshipsFromPreviousLayer; - public ChildNode(RelationshipProxy[] nextLayerRelationships, RelationshipsFromPreviousLayer prevLayerRelationships) { ResourceType = typeof(TResource); @@ -39,7 +41,7 @@ public ChildNode(RelationshipProxy[] nextLayerRelationships, RelationshipsFromPr } /// - public void UpdateUnique(IEnumerable updated) + public void UpdateUnique(IEnumerable updated) { List cast = updated.Cast().ToList(); foreach (var group in _relationshipsFromPreviousLayer) diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs index e088e7523b..6b6a6aa391 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs @@ -21,6 +21,8 @@ internal sealed class RelationshipProxy { private readonly bool _skipThroughType; + public Type LeftType => Attribute.LeftType; + /// /// The target type for this relationship attribute. /// For HasOne has HasMany this is trivial: just the right-hand side. @@ -28,10 +30,11 @@ internal sealed class RelationshipProxy /// Identifiable) or it is the right-hand side (when the through resource is not identifiable) /// public Type RightType { get; } - public Type LeftType => Attribute.LeftType; + public bool IsContextRelation { get; } public RelationshipAttribute Attribute { get; set; } + public RelationshipProxy(RelationshipAttribute attr, Type relatedType, bool isContextRelation) { RightType = relatedType; diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs index fdd84fdd6e..fc3ab804ab 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs @@ -121,8 +121,11 @@ private Dictionary private (Dictionary>, Dictionary>) ExtractResources(IEnumerable leftNodes) { - var leftResourcesGrouped = new Dictionary>(); // RelationshipAttr_prevLayer->currentLayer => prevLayerResources - var rightResourcesGrouped = new Dictionary>(); // RelationshipAttr_prevLayer->currentLayer => currentLayerResources + // RelationshipAttr_prevLayer->currentLayer => prevLayerResources + var leftResourcesGrouped = new Dictionary>(); + + // RelationshipAttr_prevLayer->currentLayer => currentLayerResources + var rightResourcesGrouped = new Dictionary>(); foreach (var node in leftNodes) { diff --git a/src/JsonApiDotNetCore/Middleware/IAsyncConvertEmptyActionResultFilter.cs b/src/JsonApiDotNetCore/Middleware/IAsyncConvertEmptyActionResultFilter.cs index cc1983ae4f..6b860d625b 100644 --- a/src/JsonApiDotNetCore/Middleware/IAsyncConvertEmptyActionResultFilter.cs +++ b/src/JsonApiDotNetCore/Middleware/IAsyncConvertEmptyActionResultFilter.cs @@ -4,7 +4,11 @@ namespace JsonApiDotNetCore.Middleware { /// /// Converts action result without parameters into action result with null parameter. - /// For example: return NotFound() -> return NotFound(null) + /// + /// return NotFound(null) + /// ]]> + /// /// This ensures our formatter is invoked, where we'll build a JSON:API compliant response. /// For details, see: https://github.com/dotnet/aspnetcore/issues/16969 /// diff --git a/src/JsonApiDotNetCore/Middleware/IJsonApiRequest.cs b/src/JsonApiDotNetCore/Middleware/IJsonApiRequest.cs index ecabf6d8eb..84e56e1941 100644 --- a/src/JsonApiDotNetCore/Middleware/IJsonApiRequest.cs +++ b/src/JsonApiDotNetCore/Middleware/IJsonApiRequest.cs @@ -18,8 +18,10 @@ public interface IJsonApiRequest /// The request URL prefix. This may be an absolute or relative path, depending on . /// /// + /// /// string BasePath { get; } diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs index 5e007236f3..7b6d3f4412 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs @@ -100,7 +100,8 @@ private static async Task ValidateContentTypeHeaderAsync(string allowedCon await FlushResponseAsync(httpContext.Response, serializerSettings, new Error(HttpStatusCode.UnsupportedMediaType) { Title = "The specified Content-Type header value is not supported.", - Detail = $"Please specify '{allowedContentType}' instead of '{contentType}' for the Content-Type header value." + Detail = $"Please specify '{allowedContentType}' instead of '{contentType}' " + + "for the Content-Type header value." }); return false; } diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs b/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs index c124806889..dfb0057ea1 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs @@ -33,9 +33,7 @@ public class JsonApiRoutingConvention : IJsonApiRoutingConvention private readonly IJsonApiOptions _options; private readonly IResourceContextProvider _resourceContextProvider; private readonly HashSet _registeredTemplates = new HashSet(); - - private readonly Dictionary _registeredResources = - new Dictionary(); + private readonly Dictionary _registeredResources = new Dictionary(); public JsonApiRoutingConvention(IJsonApiOptions options, IResourceContextProvider resourceContextProvider) { @@ -82,7 +80,7 @@ public void Apply(ApplicationModel application) } } - if (!RoutingConventionDisabled(controller)) + if (!IsRoutingConventionEnabled(controller)) { continue; } @@ -98,14 +96,10 @@ public void Apply(ApplicationModel application) } } - /// - /// Verifies if routing convention should be enabled for this controller. - /// - private bool RoutingConventionDisabled(ControllerModel controller) + private bool IsRoutingConventionEnabled(ControllerModel controller) { - var type = controller.ControllerType; - var notDisabled = type.GetCustomAttribute() == null; - return notDisabled && type.IsSubclassOf(typeof(CoreJsonApiController)); + return controller.ControllerType.IsSubclassOf(typeof(CoreJsonApiController)) && + controller.ControllerType.GetCustomAttribute() == null; } /// diff --git a/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs b/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs index 86158d0efa..27de23ddfd 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs @@ -15,6 +15,7 @@ internal static class IncludeChainConverter /// /// /// Input tree: + /// /// Output chains: + /// Blog, /// Article -> Revisions -> Author + /// ]]> /// public static IReadOnlyCollection GetRelationshipChains(IncludeExpression include) { @@ -43,10 +46,12 @@ public static IReadOnlyCollection GetRelationshipC /// /// /// Input chains: + /// Blog, /// Article -> Revisions -> Author - /// + /// ]]> /// Output tree: + /// GetRelationshipC /// Author /// } /// } + /// ]]> /// public static IncludeExpression FromRelationshipChains(IReadOnlyCollection chains) { diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldTypeParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldTypeParser.cs index f1fd91b18b..9f6e2d4dac 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldTypeParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldTypeParser.cs @@ -19,11 +19,11 @@ public ResourceContext Parse(string source) { Tokenize(source); - var expression = ParseSparseFieldTarget(); + var resourceContext = ParseSparseFieldTarget(); AssertTokenStackIsEmpty(); - return expression; + return resourceContext; } private ResourceContext ParseSparseFieldTarget() diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs index 8e221bd3b8..3334331d6f 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs @@ -48,12 +48,18 @@ public FilterExpression GetTopFilterFromConstraints(ResourceContext resourceCont { var constraints = _constraintProviders.SelectMany(provider => provider.GetConstraints()).ToArray(); + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var filtersInTopScope = constraints .Where(constraint => constraint.Scope == null) .Select(constraint => constraint.Expression) .OfType() .ToArray(); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + return GetFilter(filtersInTopScope, resourceContext); } @@ -72,11 +78,17 @@ public QueryLayer ComposeFromConstraints(ResourceContext requestResource) private QueryLayer ComposeTopLayer(IEnumerable constraints, ResourceContext resourceContext) { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var expressionsInTopScope = constraints .Where(constraint => constraint.Scope == null) .Select(constraint => constraint.Expression) .ToArray(); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + var topPagination = GetPagination(expressionsInTopScope, resourceContext); if (topPagination != null) { @@ -95,12 +107,18 @@ private QueryLayer ComposeTopLayer(IEnumerable constraints, R private IncludeExpression ComposeChildren(QueryLayer topLayer, ICollection constraints) { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var include = constraints .Where(constraint => constraint.Scope == null) .Select(constraint => constraint.Expression) .OfType() .FirstOrDefault() ?? IncludeExpression.Empty; + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + var includeElements = ProcessIncludeSet(include.Elements, topLayer, new List(), constraints); @@ -127,12 +145,18 @@ private IReadOnlyCollection ProcessIncludeSet(IReadOnl includeElement.Relationship }; + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var expressionsInCurrentScope = constraints .Where(constraint => constraint.Scope != null && constraint.Scope.Fields.SequenceEqual(relationshipChain)) .Select(constraint => constraint.Expression) .ToArray(); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + var resourceContext = _resourceContextProvider.GetResourceContext(includeElement.Relationship.RightType); @@ -187,7 +211,7 @@ public QueryLayer ComposeForGetById(TId id, ResourceContext resourceContext var queryLayer = ComposeFromConstraints(resourceContext); queryLayer.Sort = null; queryLayer.Pagination = null; - queryLayer.Filter = CreateFilterByIds(new[] {id}, idAttribute, queryLayer.Filter); + queryLayer.Filter = CreateFilterById(id, idAttribute, queryLayer.Filter); if (fieldSelection == TopFieldSelection.OnlyIdAttribute) { @@ -247,7 +271,7 @@ public QueryLayer WrapLayerForSecondaryEndpoint(QueryLayer secondaryLayer, return new QueryLayer(primaryResourceContext) { Include = RewriteIncludeForSecondaryEndpoint(innerInclude, secondaryRelationship), - Filter = CreateFilterByIds(new[] {primaryId}, primaryIdAttribute, primaryFilter), + Filter = CreateFilterById(primaryId, primaryIdAttribute, primaryFilter), Projection = primaryProjection }; } @@ -261,6 +285,12 @@ private IncludeExpression RewriteIncludeForSecondaryEndpoint(IncludeExpression r return new IncludeExpression(new[] {parentElement}); } + private FilterExpression CreateFilterById(TId id, AttrAttribute idAttribute, FilterExpression existingFilter) + { + var ids = new[] { id }; + return CreateFilterByIds(ids, idAttribute, existingFilter); + } + private FilterExpression CreateFilterByIds(ICollection ids, AttrAttribute idAttribute, FilterExpression existingFilter) { var idChain = new ResourceFieldChainExpression(idAttribute); @@ -278,11 +308,15 @@ private FilterExpression CreateFilterByIds(ICollection ids, AttrAttrib filter = new EqualsAnyOfExpression(idChain, constants); } + // @formatter:keep_existing_linebreaks true + return filter == null ? existingFilter : existingFilter == null ? filter : new LogicalExpression(LogicalOperator.And, new[] {filter, existingFilter}); + + // @formatter:keep_existing_linebreaks restore } /// @@ -299,7 +333,7 @@ public QueryLayer ComposeForUpdate(TId id, ResourceContext primaryResource) primaryLayer.Include = includeElements.Any() ? new IncludeExpression(includeElements) : IncludeExpression.Empty; primaryLayer.Sort = null; primaryLayer.Pagination = null; - primaryLayer.Filter = CreateFilterByIds(new[] {id}, primaryIdAttribute, primaryLayer.Filter); + primaryLayer.Filter = CreateFilterById(id, primaryIdAttribute, primaryLayer.Filter); primaryLayer.Projection = null; return primaryLayer; @@ -353,7 +387,7 @@ public QueryLayer ComposeForHasMany(HasManyAttribute hasManyRelationship, T var rightIdAttribute = GetIdAttribute(rightResourceContext); var rightTypedIds = rightResourceIds.Select(resource => resource.GetTypedId()).ToArray(); - var leftFilter = CreateFilterByIds(new[] {leftId}, leftIdAttribute, null); + var leftFilter = CreateFilterById(leftId, leftIdAttribute, null); var rightFilter = CreateFilterByIds(rightTypedIds, rightIdAttribute, null); return new QueryLayer(leftResourceContext) diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs index 881fbfb92c..addc02a88d 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs @@ -52,13 +52,21 @@ public override Expression VisitSortElement(SortElementExpression expression, Ex LambdaExpression lambda = Expression.Lambda(body, LambdaScope.Parameter); - string operationName = previousExpression == null ? - expression.IsAscending ? "OrderBy" : "OrderByDescending" : - expression.IsAscending ? "ThenBy" : "ThenByDescending"; + string operationName = GetOperationName(previousExpression != null, expression.IsAscending); return ExtensionMethodCall(previousExpression ?? _source, operationName, body.Type, lambda); } + private static string GetOperationName(bool hasPrecedingSort, bool isAscending) + { + if (hasPrecedingSort) + { + return isAscending ? "ThenBy" : "ThenByDescending"; + } + + return isAscending ? "OrderBy" : "OrderByDescending"; + } + private Expression ExtensionMethodCall(Expression source, string operationName, Type keyType, LambdaExpression keySelector) { @@ -71,11 +79,14 @@ private Expression ExtensionMethodCall(Expression source, string operationName, protected override MemberExpression CreatePropertyExpressionForFieldChain(IReadOnlyCollection chain, Expression source) { - var components = chain.Select(field => - // In case of a HasManyThrough access (from count() function), we only need to look at the number of entries in the join table. - field is HasManyThroughAttribute hasManyThrough ? hasManyThrough.ThroughProperty.Name : field.Property.Name).ToArray(); - + var components = chain.Select(GetPropertyName).ToArray(); return CreatePropertyExpressionFromComponents(LambdaScope.Accessor, components); } + + private static string GetPropertyName(ResourceFieldAttribute field) + { + // In case of a HasManyThrough access (from count() function), we only need to look at the number of entries in the join table. + return field is HasManyThroughAttribute hasManyThrough ? hasManyThrough.ThroughProperty.Name : field.Property.Name; + } } } diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs index 7c79d24bd6..e70a57caa5 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs @@ -278,11 +278,14 @@ private static object ConvertTextToTargetType(string text, Type targetType) protected override MemberExpression CreatePropertyExpressionForFieldChain(IReadOnlyCollection chain, Expression source) { - var components = chain.Select(field => - // In case of a HasManyThrough access (from count() or has() function), we only need to look at the number of entries in the join table. - field is HasManyThroughAttribute hasManyThrough ? hasManyThrough.ThroughProperty.Name : field.Property.Name).ToArray(); - + var components = chain.Select(GetPropertyName).ToArray(); return CreatePropertyExpressionFromComponents(LambdaScope.Accessor, components); } + + private static string GetPropertyName(ResourceFieldAttribute field) + { + // In case of a HasManyThrough access (from count() or has() function), we only need to look at the number of entries in the join table. + return field is HasManyThroughAttribute hasManyThrough ? hasManyThrough.ThroughProperty.Name : field.Property.Name; + } } } diff --git a/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs b/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs index fc123a7a14..6adfe180a3 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs @@ -29,6 +29,9 @@ public SparseFieldSetCache(IEnumerable constraintProvi private static IDictionary> BuildSourceTable(IEnumerable constraintProviders) { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var sparseFieldTables = constraintProviders .SelectMany(provider => provider.GetConstraints()) .Where(constraint => constraint.Scope == null) @@ -37,6 +40,9 @@ private static IDictionary> Bui .Select(expression => expression.Table) .ToArray(); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + var mergedTable = new Dictionary>(); foreach (var sparseFieldTable in sparseFieldTables) diff --git a/src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs b/src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs index ac0cc66d46..ffe1a399e1 100644 --- a/src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs +++ b/src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using JsonApiDotNetCore.Resources; @@ -34,16 +35,20 @@ public static object GetTrackedIdentifiable(this DbContext dbContext, IIdentifia ArgumentGuard.NotNull(dbContext, nameof(dbContext)); ArgumentGuard.NotNull(identifiable, nameof(identifiable)); - var entityType = identifiable.GetType(); - var entityEntry = dbContext.ChangeTracker - .Entries() - .FirstOrDefault(entry => - entry.Entity.GetType() == entityType && - ((IIdentifiable) entry.Entity).StringId == identifiable.StringId); + var resourceType = identifiable.GetType(); + string stringId = identifiable.StringId; + + var entityEntry = dbContext.ChangeTracker.Entries() + .FirstOrDefault(entry => IsResource(entry, resourceType, stringId)); return entityEntry?.Entity; } + private static bool IsResource(EntityEntry entry, Type resourceType, string stringId) + { + return entry.Entity.GetType() == resourceType && ((IIdentifiable) entry.Entity).StringId == stringId; + } + /// /// Detaches all entities from the change tracker. /// diff --git a/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs b/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs index ed70cb558d..420e8c21a6 100644 --- a/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs +++ b/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs @@ -98,13 +98,19 @@ protected virtual IQueryable ApplyQueryLayer(QueryLayer layer) IQueryable source = GetAll(); + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var queryableHandlers = _constraintProviders - .SelectMany(p => p.GetConstraints()) + .SelectMany(provider => provider.GetConstraints()) .Where(expressionInScope => expressionInScope.Scope == null) .Select(expressionInScope => expressionInScope.Expression) .OfType() .ToArray(); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + foreach (var queryableHandler in queryableHandlers) { source = queryableHandler.Apply(source); diff --git a/src/JsonApiDotNetCore/Resources/Annotations/AttrAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/AttrAttribute.cs index 43f739e113..f2e11ac449 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/AttrAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/AttrAttribute.cs @@ -33,8 +33,7 @@ public AttrCapabilities Capabilities /// /// Get the value of the attribute for the given object. - /// Returns null if the attribute does not belong to the - /// provided object. + /// Throws if the attribute does not belong to the provided object. /// public object GetValue(object resource) { diff --git a/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs index f160e7d46e..9e6c9e9f39 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs @@ -119,13 +119,19 @@ private bool IsRelationshipInSparseFieldSet(RelationshipAttribute relationship) /// private bool ShouldInclude(RelationshipAttribute relationship, out List> inclusionChain) { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var chains = _constraintProviders - .SelectMany(p => p.GetConstraints()) + .SelectMany(provider => provider.GetConstraints()) .Select(expressionInScope => expressionInScope.Expression) .OfType() .SelectMany(IncludeChainConverter.GetRelationshipChains) .ToArray(); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + inclusionChain = new List>(); foreach (var chain in chains) diff --git a/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs b/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs index d0e6471939..830edd74e7 100644 --- a/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs @@ -91,7 +91,9 @@ private string SerializeErrorDocument(ErrorDocument errorDocument) /// internal string SerializeSingle(IIdentifiable resource) { - var (attributes, relationships) = GetFieldsToSerialize(); + var attributes = _fieldsToSerialize.GetAttributes(_primaryResourceType); + var relationships = _fieldsToSerialize.GetRelationships(_primaryResourceType); + var document = Build(resource, attributes, relationships); var resourceObject = document.SingleData; if (resourceObject != null) @@ -104,11 +106,6 @@ internal string SerializeSingle(IIdentifiable resource) return SerializeObject(document, _options.SerializerSettings, serializer => { serializer.NullValueHandling = NullValueHandling.Include; }); } - private (IReadOnlyCollection, IReadOnlyCollection) GetFieldsToSerialize() - { - return (_fieldsToSerialize.GetAttributes(_primaryResourceType), _fieldsToSerialize.GetRelationships(_primaryResourceType)); - } - /// /// Converts a collection of resources into a serialized . /// @@ -117,7 +114,9 @@ internal string SerializeSingle(IIdentifiable resource) /// internal string SerializeMany(IReadOnlyCollection resources) { - var (attributes, relationships) = GetFieldsToSerialize(); + var attributes = _fieldsToSerialize.GetAttributes(_primaryResourceType); + var relationships = _fieldsToSerialize.GetRelationships(_primaryResourceType); + var document = Build(resources, attributes, relationships); foreach (ResourceObject resourceObject in document.ManyData) { diff --git a/src/JsonApiDotNetCore/TypeHelper.cs b/src/JsonApiDotNetCore/TypeHelper.cs index c36d585958..d1ed13562e 100644 --- a/src/JsonApiDotNetCore/TypeHelper.cs +++ b/src/JsonApiDotNetCore/TypeHelper.cs @@ -168,7 +168,7 @@ public static Dictionary> ConvertRelat /// public static Dictionary> ConvertAttributeDictionary(IEnumerable attributes, HashSet resources) { - return attributes?.ToDictionary(attr => attr.Property, attr => resources); + return attributes.ToDictionary(attr => attr.Property, attr => resources); } /// From c564f9a507ed544752a180dce83b0fdf9176eab9 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 17 Feb 2021 12:33:07 +0100 Subject: [PATCH 13/60] Extract variable on errors in tests to reduce assertion line length --- ...micConstrainedOperationsControllerTests.cs | 30 ++- .../Creating/AtomicCreateResourceTests.cs | 100 +++++---- ...reateResourceWithClientGeneratedIdTests.cs | 30 ++- ...eateResourceWithToManyRelationshipTests.cs | 80 ++++--- ...reateResourceWithToOneRelationshipTests.cs | 60 +++-- .../Deleting/AtomicDeleteResourceTests.cs | 80 ++++--- .../LocalIds/AtomicLocalIdTests.cs | 130 ++++++----- .../Mixed/AtomicRequestBodyTests.cs | 40 ++-- .../Mixed/MaximumOperationsPerRequestTests.cs | 10 +- .../AtomicModelStateValidationTests.cs | 71 +++--- .../QueryStrings/AtomicQueryStringTests.cs | 70 +++--- .../Transactions/AtomicRollbackTests.cs | 10 +- .../AtomicTransactionConsistencyTests.cs | 30 ++- .../AtomicAddToToManyRelationshipTests.cs | 168 ++++++++------ ...AtomicRemoveFromToManyRelationshipTests.cs | 158 +++++++------ .../AtomicReplaceToManyRelationshipTests.cs | 170 ++++++++------ .../AtomicUpdateToOneRelationshipTests.cs | 160 +++++++------ .../AtomicReplaceToManyRelationshipTests.cs | 80 ++++--- .../Resources/AtomicUpdateResourceTests.cs | 210 +++++++++++------- .../AtomicUpdateToOneRelationshipTests.cs | 70 +++--- .../CompositeKeys/CompositeKeyTests.cs | 8 +- .../ContentNegotiation/AcceptHeaderTests.cs | 16 +- .../ContentTypeHeaderTests.cs | 56 +++-- .../ActionResultTests.cs | 53 +++-- .../ApiControllerAttributeTests.cs | 4 +- .../ExceptionHandlerTests.cs | 20 +- .../IdObfuscation/IdObfuscationTests.cs | 18 +- .../ModelStateValidationTests.cs | 103 +++++---- .../NamingConventions/KebabCasingTests.cs | 18 +- .../Filtering/FilterDataTypeTests.cs | 10 +- .../Filtering/FilterDepthTests.cs | 20 +- .../Filtering/FilterOperatorTests.cs | 10 +- .../QueryStrings/Filtering/FilterTests.cs | 30 ++- .../QueryStrings/Includes/IncludeTests.cs | 40 ++-- .../PaginationWithTotalCountTests.cs | 40 ++-- .../Pagination/RangeValidationTests.cs | 30 ++- .../RangeValidationWithMaximumTests.cs | 30 ++- .../QueryStrings/QueryStringTests.cs | 20 +- .../SerializerDefaultValueHandlingTests.cs | 10 +- .../SerializerNullValueHandlingTests.cs | 10 +- .../QueryStrings/Sorting/SortTests.cs | 50 +++-- .../SparseFieldSets/SparseFieldSetTests.cs | 20 +- .../ReadWrite/Creating/CreateResourceTests.cs | 74 +++--- ...reateResourceWithClientGeneratedIdTests.cs | 8 +- ...eateResourceWithToManyRelationshipTests.cs | 70 +++--- ...reateResourceWithToOneRelationshipTests.cs | 56 +++-- .../ReadWrite/Deleting/DeleteResourceTests.cs | 8 +- .../Fetching/FetchRelationshipTests.cs | 16 +- .../ReadWrite/Fetching/FetchResourceTests.cs | 24 +- .../AddToToManyRelationshipTests.cs | 108 +++++---- .../RemoveFromToManyRelationshipTests.cs | 108 +++++---- .../ReplaceToManyRelationshipTests.cs | 100 +++++---- .../UpdateToOneRelationshipTests.cs | 72 +++--- .../ReplaceToManyRelationshipTests.cs | 82 ++++--- .../Updating/Resources/UpdateResourceTests.cs | 96 +++++--- .../Resources/UpdateToOneRelationshipTests.cs | 48 ++-- .../DefaultBehaviorTests.cs | 72 +++--- .../ResourceInjectionTests.cs | 8 +- .../ResourceDefinitionQueryCallbackTests.cs | 17 +- .../ResourceHooks/ResourceHookTests.cs | 80 ++++--- .../DisableQueryStringTests.cs | 30 ++- .../HttpReadOnlyTests.cs | 24 +- .../NoHttpDeleteTests.cs | 8 +- .../RestrictedControllers/NoHttpPatchTests.cs | 8 +- .../RestrictedControllers/NoHttpPostTests.cs | 8 +- .../SoftDeletion/SoftDeletionTests.cs | 50 +++-- 66 files changed, 2140 insertions(+), 1408 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Controllers/AtomicConstrainedOperationsControllerTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Controllers/AtomicConstrainedOperationsControllerTests.cs index 982aa850aa..bcd75da764 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Controllers/AtomicConstrainedOperationsControllerTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Controllers/AtomicConstrainedOperationsControllerTests.cs @@ -101,10 +101,12 @@ public async Task Cannot_create_resource_for_mismatching_resource_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Unsupported combination of operation code and resource type at this endpoint."); - responseDocument.Errors[0].Detail.Should().Be("This endpoint can only be used to create resources of type 'musicTracks'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Unsupported combination of operation code and resource type at this endpoint."); + error.Detail.Should().Be("This endpoint can only be used to create resources of type 'musicTracks'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -147,10 +149,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Unsupported combination of operation code and resource type at this endpoint."); - responseDocument.Errors[0].Detail.Should().Be("This endpoint can only be used to create resources of type 'musicTracks'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Unsupported combination of operation code and resource type at this endpoint."); + error.Detail.Should().Be("This endpoint can only be used to create resources of type 'musicTracks'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -200,10 +204,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Unsupported combination of operation code and resource type at this endpoint."); - responseDocument.Errors[0].Detail.Should().Be("This endpoint can only be used to create resources of type 'musicTracks'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Unsupported combination of operation code and resource type at this endpoint."); + error.Detail.Should().Be("This endpoint can only be used to create resources of type 'musicTracks'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs index 5cbd5d116a..a826fdcfd3 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs @@ -349,10 +349,12 @@ public async Task Cannot_create_resource_with_client_generated_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("Specifying the resource ID in operations that create a resource is not allowed."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]/data/id"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("Specifying the resource ID in operations that create a resource is not allowed."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]/data/id"); } [Fact] @@ -380,10 +382,12 @@ public async Task Cannot_create_resource_for_href_element() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -414,10 +418,12 @@ public async Task Cannot_create_resource_for_ref_element() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.relationship' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.relationship' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -444,10 +450,12 @@ public async Task Cannot_create_resource_for_missing_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -480,10 +488,12 @@ public async Task Cannot_create_resource_for_missing_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data.type' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data.type' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -514,10 +524,12 @@ public async Task Cannot_create_resource_for_unknown_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -557,10 +569,12 @@ public async Task Cannot_create_resource_for_array() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected single data element for create/update resource operation."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected single data element for create/update resource operation."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -595,10 +609,12 @@ public async Task Cannot_create_resource_attribute_with_blocked_capability() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Setting the initial value of the requested attribute is not allowed."); - responseDocument.Errors[0].Detail.Should().Be("Setting the initial value of 'createdAt' is not allowed."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Setting the initial value of the requested attribute is not allowed."); + error.Detail.Should().Be("Setting the initial value of 'createdAt' is not allowed."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -636,10 +652,12 @@ public async Task Cannot_create_resource_with_readonly_attribute() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Attribute is read-only."); - responseDocument.Errors[0].Detail.Should().Be("Attribute 'isArchived' is read-only."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Attribute is read-only."); + error.Detail.Should().Be("Attribute 'isArchived' is read-only."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -674,10 +692,12 @@ public async Task Cannot_create_resource_with_incompatible_attribute_value() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().StartWith("Failed to convert 'not-a-valid-time' of type 'String' to type 'DateTimeOffset'. - Request body:"); - responseDocument.Errors[0].Source.Pointer.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().StartWith("Failed to convert 'not-a-valid-time' of type 'String' to type 'DateTimeOffset'. - Request body:"); + error.Source.Pointer.Should().BeNull(); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs index 215f85515e..5a0790d38c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs @@ -172,10 +172,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Conflict); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Conflict); - responseDocument.Errors[0].Title.Should().Be("Another resource with the specified ID already exists."); - responseDocument.Errors[0].Detail.Should().Be($"Another resource of type 'textLanguages' with ID '{languageToCreate.StringId}' already exists."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Conflict); + error.Title.Should().Be("Another resource with the specified ID already exists."); + error.Detail.Should().Be($"Another resource of type 'textLanguages' with ID '{languageToCreate.StringId}' already exists."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -212,10 +214,12 @@ public async Task Cannot_create_resource_for_incompatible_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().Be($"Failed to convert '{guid}' of type 'String' to type 'Int32'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().Be($"Failed to convert '{guid}' of type 'String' to type 'Int32'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -248,10 +252,12 @@ public async Task Cannot_create_resource_for_ID_and_local_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data.id' or 'data.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data.id' or 'data.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs index 3af0e39b70..8a17a44155 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs @@ -229,10 +229,12 @@ public async Task Cannot_create_for_missing_relationship_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected 'type' element in 'performers' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().Be("Expected 'type' element in 'performers' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -277,10 +279,12 @@ public async Task Cannot_create_for_unknown_relationship_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -324,10 +328,12 @@ public async Task Cannot_create_for_missing_relationship_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' or 'lid' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected 'id' or 'lid' element in 'performers' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' or 'lid' element."); + error.Detail.Should().Be("Expected 'id' or 'lid' element in 'performers' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -384,15 +390,17 @@ public async Task Cannot_create_for_unknown_relationship_IDs() responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'performers' with ID '12345678' in relationship 'performers' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); - - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[1].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[1].Detail.Should().Be("Related resource of type 'performers' with ID '87654321' in relationship 'performers' does not exist."); - responseDocument.Errors[1].Source.Pointer.Should().Be("/atomic:operations[0]"); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.NotFound); + error1.Title.Should().Be("A related resource does not exist."); + error1.Detail.Should().Be("Related resource of type 'performers' with ID '12345678' in relationship 'performers' does not exist."); + error1.Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.NotFound); + error2.Title.Should().Be("A related resource does not exist."); + error2.Detail.Should().Be("Related resource of type 'performers' with ID '87654321' in relationship 'performers' does not exist."); + error2.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -437,10 +445,12 @@ public async Task Cannot_create_on_relationship_type_mismatch() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'performers' contains incompatible resource type 'playlists'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); + error.Detail.Should().Be("Relationship 'performers' contains incompatible resource type 'playlists'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -556,10 +566,12 @@ public async Task Cannot_create_with_null_data_in_HasMany_relationship() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().Be("Expected data[] element for 'performers' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().Be("Expected data[] element for 'performers' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -597,10 +609,12 @@ public async Task Cannot_create_with_null_data_in_HasManyThrough_relationship() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().Be("Expected data[] element for 'tracks' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().Be("Expected data[] element for 'tracks' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs index 0784f43771..64cb1ce7d9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs @@ -288,10 +288,12 @@ public async Task Cannot_create_for_missing_relationship_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected 'type' element in 'lyric' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().Be("Expected 'type' element in 'lyric' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -333,10 +335,12 @@ public async Task Cannot_create_for_unknown_relationship_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -377,10 +381,12 @@ public async Task Cannot_create_for_missing_relationship_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' or 'lid' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected 'id' or 'lid' element in 'lyric' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' or 'lid' element."); + error.Detail.Should().Be("Expected 'id' or 'lid' element in 'lyric' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -422,10 +428,12 @@ public async Task Cannot_create_with_unknown_relationship_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'lyrics' with ID '12345678' in relationship 'lyric' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("A related resource does not exist."); + error.Detail.Should().Be("Related resource of type 'lyrics' with ID '12345678' in relationship 'lyric' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -467,10 +475,12 @@ public async Task Cannot_create_on_relationship_type_mismatch() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'lyric' contains incompatible resource type 'playlists'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); + error.Detail.Should().Be("Relationship 'lyric' contains incompatible resource type 'playlists'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -595,10 +605,12 @@ public async Task Cannot_create_with_data_array_in_relationship() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected single data element for to-one relationship."); - responseDocument.Errors[0].Detail.Should().Be("Expected single data element for 'lyric' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected single data element for to-one relationship."); + error.Detail.Should().Be("Expected single data element for 'lyric' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs index 04fda0794a..3ac37603f5 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs @@ -365,10 +365,12 @@ public async Task Cannot_delete_resource_for_href_element() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -395,10 +397,12 @@ public async Task Cannot_delete_resource_for_missing_ref_element() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -429,10 +433,12 @@ public async Task Cannot_delete_resource_for_missing_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.type' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.type' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -464,10 +470,12 @@ public async Task Cannot_delete_resource_for_unknown_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -498,10 +506,12 @@ public async Task Cannot_delete_resource_for_missing_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -533,10 +543,12 @@ public async Task Cannot_delete_resource_for_unknown_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'performers' with ID '99999999' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'performers' with ID '99999999' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -570,10 +582,12 @@ public async Task Cannot_delete_resource_for_incompatible_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().Be($"Failed to convert '{guid}' of type 'String' to type 'Int64'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().Be($"Failed to convert '{guid}' of type 'String' to type 'Int64'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -606,10 +620,12 @@ public async Task Cannot_delete_resource_for_ID_and_local_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs index cfc8e7ecaf..21042ece0b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs @@ -354,10 +354,12 @@ public async Task Cannot_consume_local_ID_that_is_assigned_in_same_operation() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Local ID cannot be both defined and used within the same operation."); - responseDocument.Errors[0].Detail.Should().Be("Local ID 'company-1' cannot be both defined and used within the same operation."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[1]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Local ID cannot be both defined and used within the same operation."); + error.Detail.Should().Be("Local ID 'company-1' cannot be both defined and used within the same operation."); + error.Source.Pointer.Should().Be("/atomic:operations[1]"); } [Fact] @@ -418,10 +420,12 @@ public async Task Cannot_reassign_local_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Another local ID with the same name is already defined at this point."); - responseDocument.Errors[0].Detail.Should().Be("Another local ID with name 'playlist-1' is already defined at this point."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[2]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Another local ID with the same name is already defined at this point."); + error.Detail.Should().Be("Another local ID with name 'playlist-1' is already defined at this point."); + error.Source.Pointer.Should().Be("/atomic:operations[2]"); } [Fact] @@ -1840,10 +1844,12 @@ public async Task Cannot_consume_unassigned_local_ID_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Server-generated value for local ID is not available at this point."); - responseDocument.Errors[0].Detail.Should().Be("Server-generated value for local ID 'doesNotExist' is not available at this point."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[1]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Server-generated value for local ID is not available at this point."); + error.Detail.Should().Be("Server-generated value for local ID 'doesNotExist' is not available at this point."); + error.Source.Pointer.Should().Be("/atomic:operations[1]"); } [Fact] @@ -1887,10 +1893,12 @@ public async Task Cannot_consume_unassigned_local_ID_in_data_element() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Server-generated value for local ID is not available at this point."); - responseDocument.Errors[0].Detail.Should().Be("Server-generated value for local ID 'doesNotExist' is not available at this point."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[1]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Server-generated value for local ID is not available at this point."); + error.Detail.Should().Be("Server-generated value for local ID 'doesNotExist' is not available at this point."); + error.Source.Pointer.Should().Be("/atomic:operations[1]"); } [Fact] @@ -1948,10 +1956,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Server-generated value for local ID is not available at this point."); - responseDocument.Errors[0].Detail.Should().Be("Server-generated value for local ID 'doesNotExist' is not available at this point."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[1]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Server-generated value for local ID is not available at this point."); + error.Detail.Should().Be("Server-generated value for local ID 'doesNotExist' is not available at this point."); + error.Source.Pointer.Should().Be("/atomic:operations[1]"); } [Fact] @@ -2002,10 +2012,12 @@ public async Task Cannot_consume_unassigned_local_ID_in_relationship_data_elemen httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Server-generated value for local ID is not available at this point."); - responseDocument.Errors[0].Detail.Should().Be("Server-generated value for local ID 'doesNotExist' is not available at this point."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[1]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Server-generated value for local ID is not available at this point."); + error.Detail.Should().Be("Server-generated value for local ID 'doesNotExist' is not available at this point."); + error.Source.Pointer.Should().Be("/atomic:operations[1]"); } [Fact] @@ -2059,10 +2071,12 @@ public async Task Cannot_consume_unassigned_local_ID_in_relationship_data_array( httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Server-generated value for local ID is not available at this point."); - responseDocument.Errors[0].Detail.Should().Be("Server-generated value for local ID 'doesNotExist' is not available at this point."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[1]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Server-generated value for local ID is not available at this point."); + error.Detail.Should().Be("Server-generated value for local ID 'doesNotExist' is not available at this point."); + error.Source.Pointer.Should().Be("/atomic:operations[1]"); } [Fact] @@ -2116,10 +2130,12 @@ public async Task Cannot_consume_local_ID_of_different_type_in_same_operation() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Type mismatch in local ID usage."); - responseDocument.Errors[0].Detail.Should().Be("Local ID 'track-1' belongs to resource type 'musicTracks' instead of 'recordCompanies'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[1]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Type mismatch in local ID usage."); + error.Detail.Should().Be("Local ID 'track-1' belongs to resource type 'musicTracks' instead of 'recordCompanies'."); + error.Source.Pointer.Should().Be("/atomic:operations[1]"); } [Fact] @@ -2171,10 +2187,12 @@ public async Task Cannot_consume_local_ID_of_different_type_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Type mismatch in local ID usage."); - responseDocument.Errors[0].Detail.Should().Be("Local ID 'company-1' belongs to resource type 'recordCompanies' instead of 'musicTracks'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[2]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Type mismatch in local ID usage."); + error.Detail.Should().Be("Local ID 'company-1' belongs to resource type 'recordCompanies' instead of 'musicTracks'."); + error.Source.Pointer.Should().Be("/atomic:operations[2]"); } [Fact] @@ -2229,10 +2247,12 @@ public async Task Cannot_consume_local_ID_of_different_type_in_data_element() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Type mismatch in local ID usage."); - responseDocument.Errors[0].Detail.Should().Be("Local ID 'performer-1' belongs to resource type 'performers' instead of 'playlists'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[2]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Type mismatch in local ID usage."); + error.Detail.Should().Be("Local ID 'performer-1' belongs to resource type 'performers' instead of 'playlists'."); + error.Source.Pointer.Should().Be("/atomic:operations[2]"); } [Fact] @@ -2301,10 +2321,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Type mismatch in local ID usage."); - responseDocument.Errors[0].Detail.Should().Be("Local ID 'company-1' belongs to resource type 'recordCompanies' instead of 'performers'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[2]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Type mismatch in local ID usage."); + error.Detail.Should().Be("Local ID 'company-1' belongs to resource type 'recordCompanies' instead of 'performers'."); + error.Source.Pointer.Should().Be("/atomic:operations[2]"); } [Fact] @@ -2372,10 +2394,12 @@ public async Task Cannot_consume_local_ID_of_different_type_in_relationship_data httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Type mismatch in local ID usage."); - responseDocument.Errors[0].Detail.Should().Be("Local ID 'playlist-1' belongs to resource type 'playlists' instead of 'recordCompanies'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[2]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Type mismatch in local ID usage."); + error.Detail.Should().Be("Local ID 'playlist-1' belongs to resource type 'playlists' instead of 'recordCompanies'."); + error.Source.Pointer.Should().Be("/atomic:operations[2]"); } [Fact] @@ -2440,10 +2464,12 @@ public async Task Cannot_consume_local_ID_of_different_type_in_relationship_data httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Type mismatch in local ID usage."); - responseDocument.Errors[0].Detail.Should().Be("Local ID 'performer-1' belongs to resource type 'performers' instead of 'musicTracks'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[2]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Type mismatch in local ID usage."); + error.Detail.Should().Be("Local ID 'performer-1' belongs to resource type 'performers' instead of 'musicTracks'."); + error.Source.Pointer.Should().Be("/atomic:operations[2]"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs index e6731c7d31..7468352626 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs @@ -34,10 +34,12 @@ public async Task Cannot_process_for_missing_request_body() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Missing request body."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Missing request body."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().BeNull(); await _testContext.RunOnDatabaseAsync(async dbContext => { @@ -64,10 +66,12 @@ public async Task Cannot_process_for_broken_JSON_request_body() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().StartWith("Unexpected end of content while loading JObject."); - responseDocument.Errors[0].Source.Pointer.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().StartWith("Unexpected end of content while loading JObject."); + error.Source.Pointer.Should().BeNull(); } [Fact] @@ -88,10 +92,12 @@ public async Task Cannot_process_empty_operations_array() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: No operations found."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: No operations found."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().BeNull(); await _testContext.RunOnDatabaseAsync(async dbContext => { @@ -134,10 +140,12 @@ public async Task Cannot_process_for_unknown_operation_code() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().StartWith("Error converting value \"merge\" to type"); - responseDocument.Errors[0].Source.Pointer.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().StartWith("Error converting value \"merge\" to type"); + error.Source.Pointer.Should().BeNull(); await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/MaximumOperationsPerRequestTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/MaximumOperationsPerRequestTests.cs index 2615bb1e89..2d497077c4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/MaximumOperationsPerRequestTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Mixed/MaximumOperationsPerRequestTests.cs @@ -67,10 +67,12 @@ public async Task Cannot_process_more_operations_than_maximum() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request exceeds the maximum number of operations."); - responseDocument.Errors[0].Detail.Should().Be("The number of operations in this request (3) is higher than 2."); - responseDocument.Errors[0].Source.Pointer.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request exceeds the maximum number of operations."); + error.Detail.Should().Be("The number of operations in this request (3) is higher than 2."); + error.Source.Pointer.Should().BeNull(); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs index 2b286ab55c..e81789c80b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs @@ -55,15 +55,17 @@ public async Task Cannot_create_resource_with_multiple_violations() responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Input validation failed."); - responseDocument.Errors[0].Detail.Should().Be("The Title field is required."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/title"); - - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[1].Title.Should().Be("Input validation failed."); - responseDocument.Errors[1].Detail.Should().Be("The field LengthInSeconds must be between 1 and 1440."); - responseDocument.Errors[1].Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/lengthInSeconds"); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error1.Title.Should().Be("Input validation failed."); + error1.Detail.Should().Be("The Title field is required."); + error1.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/title"); + + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error2.Title.Should().Be("Input validation failed."); + error2.Detail.Should().Be("The field LengthInSeconds must be between 1 and 1440."); + error2.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/lengthInSeconds"); } [Fact] @@ -179,15 +181,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Input validation failed."); - responseDocument.Errors[0].Detail.Should().Be("The Title field is required."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/title"); - - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[1].Title.Should().Be("Input validation failed."); - responseDocument.Errors[1].Detail.Should().Be("The field LengthInSeconds must be between 1 and 1440."); - responseDocument.Errors[1].Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/lengthInSeconds"); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error1.Title.Should().Be("Input validation failed."); + error1.Detail.Should().Be("The Title field is required."); + error1.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/title"); + + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error2.Title.Should().Be("Input validation failed."); + error2.Detail.Should().Be("The field LengthInSeconds must be between 1 and 1440."); + error2.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/lengthInSeconds"); } [Fact] @@ -470,20 +474,23 @@ public async Task Validates_all_operations_before_execution_starts() responseDocument.Errors.Should().HaveCount(3); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Input validation failed."); - responseDocument.Errors[0].Detail.Should().Be("The Name field is required."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/name"); - - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[1].Title.Should().Be("Input validation failed."); - responseDocument.Errors[1].Detail.Should().Be("The Title field is required."); - responseDocument.Errors[1].Source.Pointer.Should().Be("/atomic:operations[1]/data/attributes/title"); - - responseDocument.Errors[2].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[2].Title.Should().Be("Input validation failed."); - responseDocument.Errors[2].Detail.Should().Be("The field LengthInSeconds must be between 1 and 1440."); - responseDocument.Errors[2].Source.Pointer.Should().Be("/atomic:operations[1]/data/attributes/lengthInSeconds"); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error1.Title.Should().Be("Input validation failed."); + error1.Detail.Should().Be("The Name field is required."); + error1.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/name"); + + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error2.Title.Should().Be("Input validation failed."); + error2.Detail.Should().Be("The Title field is required."); + error2.Source.Pointer.Should().Be("/atomic:operations[1]/data/attributes/title"); + + var error3 = responseDocument.Errors[2]; + error3.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error3.Title.Should().Be("Input validation failed."); + error3.Detail.Should().Be("The field LengthInSeconds must be between 1 and 1440."); + error3.Source.Pointer.Should().Be("/atomic:operations[1]/data/attributes/lengthInSeconds"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs index bd791c54b8..bc5afd4f47 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs @@ -70,10 +70,12 @@ public async Task Cannot_include_on_operations_endpoint() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); - responseDocument.Errors[0].Detail.Should().Be("The parameter 'include' cannot be used at this endpoint."); - responseDocument.Errors[0].Source.Parameter.Should().Be("include"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); + error.Detail.Should().Be("The parameter 'include' cannot be used at this endpoint."); + error.Source.Parameter.Should().Be("include"); } [Fact] @@ -107,10 +109,12 @@ public async Task Cannot_filter_on_operations_endpoint() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); - responseDocument.Errors[0].Detail.Should().Be("The parameter 'filter' cannot be used at this endpoint."); - responseDocument.Errors[0].Source.Parameter.Should().Be("filter"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); + error.Detail.Should().Be("The parameter 'filter' cannot be used at this endpoint."); + error.Source.Parameter.Should().Be("filter"); } [Fact] @@ -144,10 +148,12 @@ public async Task Cannot_sort_on_operations_endpoint() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); - responseDocument.Errors[0].Detail.Should().Be("The parameter 'sort' cannot be used at this endpoint."); - responseDocument.Errors[0].Source.Parameter.Should().Be("sort"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); + error.Detail.Should().Be("The parameter 'sort' cannot be used at this endpoint."); + error.Source.Parameter.Should().Be("sort"); } [Fact] @@ -181,10 +187,12 @@ public async Task Cannot_use_pagination_number_on_operations_endpoint() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); - responseDocument.Errors[0].Detail.Should().Be("The parameter 'page[number]' cannot be used at this endpoint."); - responseDocument.Errors[0].Source.Parameter.Should().Be("page[number]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); + error.Detail.Should().Be("The parameter 'page[number]' cannot be used at this endpoint."); + error.Source.Parameter.Should().Be("page[number]"); } [Fact] @@ -218,10 +226,12 @@ public async Task Cannot_use_pagination_size_on_operations_endpoint() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); - responseDocument.Errors[0].Detail.Should().Be("The parameter 'page[size]' cannot be used at this endpoint."); - responseDocument.Errors[0].Source.Parameter.Should().Be("page[size]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); + error.Detail.Should().Be("The parameter 'page[size]' cannot be used at this endpoint."); + error.Source.Parameter.Should().Be("page[size]"); } [Fact] @@ -255,10 +265,12 @@ public async Task Cannot_use_sparse_fieldset_on_operations_endpoint() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); - responseDocument.Errors[0].Detail.Should().Be("The parameter 'fields[recordCompanies]' cannot be used at this endpoint."); - responseDocument.Errors[0].Source.Parameter.Should().Be("fields[recordCompanies]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); + error.Detail.Should().Be("The parameter 'fields[recordCompanies]' cannot be used at this endpoint."); + error.Source.Parameter.Should().Be("fields[recordCompanies]"); } [Fact] @@ -323,10 +335,12 @@ public async Task Cannot_use_Queryable_handler_on_operations_endpoint() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Unknown query string parameter."); - responseDocument.Errors[0].Detail.Should().Be("Query string parameter 'isRecentlyReleased' is unknown. Set 'AllowUnknownQueryStringParameters' to 'true' in options to ignore unknown parameters."); - responseDocument.Errors[0].Source.Parameter.Should().Be("isRecentlyReleased"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Unknown query string parameter."); + error.Detail.Should().Be("Query string parameter 'isRecentlyReleased' is unknown. Set 'AllowUnknownQueryStringParameters' to 'true' in options to ignore unknown parameters."); + error.Source.Parameter.Should().Be("isRecentlyReleased"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs index ede29b7907..ad624f6189 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicRollbackTests.cs @@ -90,10 +90,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'performers' with ID '99999999' in relationship 'performers' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[1]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("A related resource does not exist."); + error.Detail.Should().Be("Related resource of type 'performers' with ID '99999999' in relationship 'performers' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[1]"); await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicTransactionConsistencyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicTransactionConsistencyTests.cs index 55b78ec6b2..4b18f53178 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicTransactionConsistencyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/AtomicTransactionConsistencyTests.cs @@ -67,10 +67,12 @@ public async Task Cannot_use_non_transactional_repository() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Unsupported resource type in atomic:operations request."); - responseDocument.Errors[0].Detail.Should().Be("Operations on resources of type 'performers' cannot be used because transaction support is unavailable."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Unsupported resource type in atomic:operations request."); + error.Detail.Should().Be("Operations on resources of type 'performers' cannot be used because transaction support is unavailable."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -104,10 +106,12 @@ public async Task Cannot_use_transactional_repository_without_active_transaction httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Unsupported combination of resource types in atomic:operations request."); - responseDocument.Errors[0].Detail.Should().Be("All operations need to participate in a single shared transaction, which is not the case for this request."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Unsupported combination of resource types in atomic:operations request."); + error.Detail.Should().Be("All operations need to participate in a single shared transaction, which is not the case for this request."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -141,10 +145,12 @@ public async Task Cannot_use_distributed_transaction() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Unsupported combination of resource types in atomic:operations request."); - responseDocument.Errors[0].Detail.Should().Be("All operations need to participate in a single shared transaction, which is not the case for this request."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Unsupported combination of resource types in atomic:operations request."); + error.Detail.Should().Be("All operations need to participate in a single shared transaction, which is not the case for this request."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs index e3829573e3..180d2bda7b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs @@ -68,9 +68,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Only to-many relationships can be targeted in 'add' operations."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'ownedBy' must be a to-many relationship."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Only to-many relationships can be targeted in 'add' operations."); + error.Detail.Should().Be("Relationship 'ownedBy' must be a to-many relationship."); } [Fact] @@ -269,10 +271,12 @@ public async Task Cannot_add_for_href_element() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -304,10 +308,12 @@ public async Task Cannot_add_for_missing_type_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.type' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.type' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -340,10 +346,12 @@ public async Task Cannot_add_for_unknown_type_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -375,10 +383,12 @@ public async Task Cannot_add_for_missing_ID_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -427,10 +437,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'recordCompanies' with ID '9999' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'recordCompanies' with ID '9999' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -464,10 +476,12 @@ public async Task Cannot_add_for_ID_and_local_ID_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -499,10 +513,12 @@ public async Task Cannot_add_for_missing_relationship_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.relationship' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.relationship' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -535,10 +551,12 @@ public async Task Cannot_add_for_unknown_relationship_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The referenced relationship does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'performers' does not contain a relationship named 'doesNotExist'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The referenced relationship does not exist."); + error.Detail.Should().Be("Resource of type 'performers' does not contain a relationship named 'doesNotExist'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -580,10 +598,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().Be("Expected data[] element for 'performers' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().Be("Expected data[] element for 'performers' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -623,10 +643,12 @@ public async Task Cannot_add_for_missing_type_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data[].type' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data[].type' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -667,10 +689,12 @@ public async Task Cannot_add_for_unknown_type_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -710,10 +734,12 @@ public async Task Cannot_add_for_missing_ID_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data[].id' or 'data[].lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data[].id' or 'data[].lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -755,10 +781,12 @@ public async Task Cannot_add_for_ID_and_local_ID_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data[].id' or 'data[].lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data[].id' or 'data[].lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -814,15 +842,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[0]}' in relationship 'tracks' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); - - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[1].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[1].Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[1]}' in relationship 'tracks' does not exist."); - responseDocument.Errors[1].Source.Pointer.Should().Be("/atomic:operations[0]"); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.NotFound); + error1.Title.Should().Be("A related resource does not exist."); + error1.Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[0]}' in relationship 'tracks' does not exist."); + error1.Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.NotFound); + error2.Title.Should().Be("A related resource does not exist."); + error2.Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[1]}' in relationship 'tracks' does not exist."); + error2.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -871,10 +901,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Resource type mismatch between 'ref.relationship' and 'data[].type' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected resource of type 'performers' in 'data[].type', instead of 'playlists'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Resource type mismatch between 'ref.relationship' and 'data[].type' element."); + error.Detail.Should().Be("Expected resource of type 'performers' in 'data[].type', instead of 'playlists'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs index 1f87b3ff9f..9a51ede546 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs @@ -68,9 +68,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Only to-many relationships can be targeted in 'remove' operations."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'ownedBy' must be a to-many relationship."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Only to-many relationships can be targeted in 'remove' operations."); + error.Detail.Should().Be("Relationship 'ownedBy' must be a to-many relationship."); } [Fact] @@ -275,10 +277,12 @@ public async Task Cannot_remove_for_href_element() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -310,10 +314,12 @@ public async Task Cannot_remove_for_missing_type_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.type' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.type' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -346,10 +352,12 @@ public async Task Cannot_remove_for_unknown_type_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -381,10 +389,12 @@ public async Task Cannot_remove_for_missing_ID_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -433,10 +443,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'recordCompanies' with ID '9999' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'recordCompanies' with ID '9999' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -470,10 +482,12 @@ public async Task Cannot_remove_for_ID_and_local_ID_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -506,10 +520,12 @@ public async Task Cannot_remove_for_unknown_relationship_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The referenced relationship does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'performers' does not contain a relationship named 'doesNotExist'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The referenced relationship does not exist."); + error.Detail.Should().Be("Resource of type 'performers' does not contain a relationship named 'doesNotExist'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -551,10 +567,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().Be("Expected data[] element for 'performers' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().Be("Expected data[] element for 'performers' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -594,10 +612,12 @@ public async Task Cannot_remove_for_missing_type_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data[].type' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data[].type' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -638,10 +658,12 @@ public async Task Cannot_remove_for_unknown_type_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -681,10 +703,12 @@ public async Task Cannot_remove_for_missing_ID_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data[].id' or 'data[].lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data[].id' or 'data[].lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -726,10 +750,12 @@ public async Task Cannot_remove_for_ID_and_local_ID_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data[].id' or 'data[].lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data[].id' or 'data[].lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -785,15 +811,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[0]}' in relationship 'tracks' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); - - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[1].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[1].Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[1]}' in relationship 'tracks' does not exist."); - responseDocument.Errors[1].Source.Pointer.Should().Be("/atomic:operations[0]"); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.NotFound); + error1.Title.Should().Be("A related resource does not exist."); + error1.Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[0]}' in relationship 'tracks' does not exist."); + error1.Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.NotFound); + error2.Title.Should().Be("A related resource does not exist."); + error2.Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[1]}' in relationship 'tracks' does not exist."); + error2.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -842,10 +870,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Resource type mismatch between 'ref.relationship' and 'data[].type' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected resource of type 'performers' in 'data[].type', instead of 'playlists'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Resource type mismatch between 'ref.relationship' and 'data[].type' element."); + error.Detail.Should().Be("Expected resource of type 'performers' in 'data[].type', instead of 'playlists'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs index c2a6c4bb5b..dee693b505 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs @@ -321,10 +321,12 @@ public async Task Cannot_replace_for_href_element() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -356,10 +358,12 @@ public async Task Cannot_replace_for_missing_type_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.type' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.type' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -392,10 +396,12 @@ public async Task Cannot_replace_for_unknown_type_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -427,10 +433,12 @@ public async Task Cannot_replace_for_missing_ID_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -479,10 +487,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'recordCompanies' with ID '9999' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'recordCompanies' with ID '9999' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -533,10 +543,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().Be($"Failed to convert '{guid}' of type 'String' to type 'Int16'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().Be($"Failed to convert '{guid}' of type 'String' to type 'Int16'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -570,10 +582,12 @@ public async Task Cannot_replace_for_ID_and_local_ID_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -606,10 +620,12 @@ public async Task Cannot_replace_for_unknown_relationship_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The referenced relationship does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'performers' does not contain a relationship named 'doesNotExist'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The referenced relationship does not exist."); + error.Detail.Should().Be("Resource of type 'performers' does not contain a relationship named 'doesNotExist'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -651,10 +667,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().Be("Expected data[] element for 'performers' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().Be("Expected data[] element for 'performers' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -694,10 +712,12 @@ public async Task Cannot_replace_for_missing_type_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data[].type' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data[].type' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -738,10 +758,12 @@ public async Task Cannot_replace_for_unknown_type_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -781,10 +803,12 @@ public async Task Cannot_replace_for_missing_ID_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data[].id' or 'data[].lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data[].id' or 'data[].lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -826,10 +850,12 @@ public async Task Cannot_replace_for_ID_and_local_ID_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data[].id' or 'data[].lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data[].id' or 'data[].lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -885,15 +911,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[0]}' in relationship 'tracks' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); - - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[1].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[1].Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[1]}' in relationship 'tracks' does not exist."); - responseDocument.Errors[1].Source.Pointer.Should().Be("/atomic:operations[0]"); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.NotFound); + error1.Title.Should().Be("A related resource does not exist."); + error1.Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[0]}' in relationship 'tracks' does not exist."); + error1.Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.NotFound); + error2.Title.Should().Be("A related resource does not exist."); + error2.Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[1]}' in relationship 'tracks' does not exist."); + error2.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -942,10 +970,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().Be("Failed to convert 'invalid-guid' of type 'String' to type 'Guid'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().Be("Failed to convert 'invalid-guid' of type 'String' to type 'Guid'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -994,10 +1024,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Resource type mismatch between 'ref.relationship' and 'data[].type' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected resource of type 'performers' in 'data[].type', instead of 'playlists'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Resource type mismatch between 'ref.relationship' and 'data[].type' element."); + error.Detail.Should().Be("Expected resource of type 'performers' in 'data[].type', instead of 'playlists'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs index f9efe3177a..1c5aa3454d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs @@ -561,10 +561,12 @@ public async Task Cannot_create_for_href_element() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -596,10 +598,12 @@ public async Task Cannot_create_for_missing_type_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.type' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.type' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -632,10 +636,12 @@ public async Task Cannot_create_for_unknown_type_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -667,10 +673,12 @@ public async Task Cannot_create_for_missing_ID_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -718,10 +726,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be($"Resource of type 'musicTracks' with ID '{missingTrackId}' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be($"Resource of type 'musicTracks' with ID '{missingTrackId}' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -767,10 +777,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().Be("Failed to convert 'invalid-guid' of type 'String' to type 'Guid'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().Be("Failed to convert 'invalid-guid' of type 'String' to type 'Guid'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -804,10 +816,12 @@ public async Task Cannot_create_for_ID_and_local_ID_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -840,10 +854,12 @@ public async Task Cannot_create_for_unknown_relationship_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The referenced relationship does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'performers' does not contain a relationship named 'doesNotExist'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The referenced relationship does not exist."); + error.Detail.Should().Be("Resource of type 'performers' does not contain a relationship named 'doesNotExist'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -892,10 +908,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected single data element for to-one relationship."); - responseDocument.Errors[0].Detail.Should().Be("Expected single data element for 'lyric' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected single data element for to-one relationship."); + error.Detail.Should().Be("Expected single data element for 'lyric' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -932,10 +950,12 @@ public async Task Cannot_create_for_missing_type_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data.type' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data.type' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -973,10 +993,12 @@ public async Task Cannot_create_for_unknown_type_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1013,10 +1035,12 @@ public async Task Cannot_create_for_missing_ID_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data.id' or 'data.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data.id' or 'data.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1055,10 +1079,12 @@ public async Task Cannot_create_for_ID_and_local_ID_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data.id' or 'data.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data.id' or 'data.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1104,10 +1130,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'lyrics' with ID '99999999' in relationship 'lyric' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("A related resource does not exist."); + error.Detail.Should().Be("Related resource of type 'lyrics' with ID '99999999' in relationship 'lyric' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1153,10 +1181,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().Be("Failed to convert 'invalid-guid' of type 'String' to type 'Guid'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().Be("Failed to convert 'invalid-guid' of type 'String' to type 'Guid'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1202,10 +1232,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Resource type mismatch between 'ref.relationship' and 'data.type' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected resource of type 'lyrics' in 'data.type', instead of 'playlists'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Resource type mismatch between 'ref.relationship' and 'data.type' element."); + error.Detail.Should().Be("Expected resource of type 'lyrics' in 'data.type', instead of 'playlists'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs index 44c4a5a7ca..37a0efa8e4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs @@ -360,10 +360,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().Be("Expected data[] element for 'performers' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().Be("Expected data[] element for 'performers' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -408,10 +410,12 @@ public async Task Cannot_replace_for_missing_type_in_relationship_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected 'type' element in 'tracks' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().Be("Expected 'type' element in 'tracks' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -457,10 +461,12 @@ public async Task Cannot_replace_for_unknown_type_in_relationship_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -505,10 +511,12 @@ public async Task Cannot_replace_for_missing_ID_in_relationship_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' or 'lid' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected 'id' or 'lid' element in 'performers' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' or 'lid' element."); + error.Detail.Should().Be("Expected 'id' or 'lid' element in 'performers' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -555,10 +563,12 @@ public async Task Cannot_replace_for_ID_and_local_ID_relationship_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' or 'lid' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected 'id' or 'lid' element in 'performers' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' or 'lid' element."); + error.Detail.Should().Be("Expected 'id' or 'lid' element in 'performers' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -619,15 +629,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[0]}' in relationship 'tracks' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); - - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[1].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[1].Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[1]}' in relationship 'tracks' does not exist."); - responseDocument.Errors[1].Source.Pointer.Should().Be("/atomic:operations[0]"); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.NotFound); + error1.Title.Should().Be("A related resource does not exist."); + error1.Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[0]}' in relationship 'tracks' does not exist."); + error1.Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.NotFound); + error2.Title.Should().Be("A related resource does not exist."); + error2.Detail.Should().Be($"Related resource of type 'musicTracks' with ID '{trackIds[1]}' in relationship 'tracks' does not exist."); + error2.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -681,10 +693,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'performers' contains incompatible resource type 'playlists'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); + error.Detail.Should().Be("Relationship 'performers' contains incompatible resource type 'playlists'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs index 526edc8c86..80f4a70bfc 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs @@ -507,10 +507,12 @@ public async Task Cannot_update_resource_for_href_element() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Usage of the 'href' element is not supported."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -610,10 +612,12 @@ public async Task Cannot_update_resource_for_missing_type_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.type' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.type' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -655,10 +659,12 @@ public async Task Cannot_update_resource_for_missing_ID_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -702,10 +708,12 @@ public async Task Cannot_update_resource_for_ID_and_local_ID_in_ref() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'ref.id' or 'ref.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -732,10 +740,12 @@ public async Task Cannot_update_resource_for_missing_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -772,10 +782,12 @@ public async Task Cannot_update_resource_for_missing_type_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data.type' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data.type' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -812,10 +824,12 @@ public async Task Cannot_update_resource_for_missing_ID_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data.id' or 'data.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data.id' or 'data.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -854,10 +868,12 @@ public async Task Cannot_update_resource_for_ID_and_local_ID_in_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: The 'data.id' or 'data.lid' element is required."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: The 'data.id' or 'data.lid' element is required."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -904,10 +920,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected single data element for create/update resource operation."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected single data element for create/update resource operation."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -950,10 +968,12 @@ public async Task Cannot_update_on_resource_type_mismatch_between_ref_and_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Resource type mismatch between 'ref.type' and 'data.type' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected resource of type 'performers' in 'data.type', instead of 'playlists'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Resource type mismatch between 'ref.type' and 'data.type' element."); + error.Detail.Should().Be("Expected resource of type 'performers' in 'data.type', instead of 'playlists'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -996,10 +1016,12 @@ public async Task Cannot_update_on_resource_ID_mismatch_between_ref_and_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Resource ID mismatch between 'ref.id' and 'data.id' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected resource with ID '12345678' in 'data.id', instead of '87654321'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Resource ID mismatch between 'ref.id' and 'data.id' element."); + error.Detail.Should().Be("Expected resource with ID '12345678' in 'data.id', instead of '87654321'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1042,10 +1064,12 @@ public async Task Cannot_update_on_resource_local_ID_mismatch_between_ref_and_da httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Resource local ID mismatch between 'ref.lid' and 'data.lid' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected resource with local ID 'local-1' in 'data.lid', instead of 'local-2'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Resource local ID mismatch between 'ref.lid' and 'data.lid' element."); + error.Detail.Should().Be("Expected resource with local ID 'local-1' in 'data.lid', instead of 'local-2'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1088,10 +1112,12 @@ public async Task Cannot_update_on_mixture_of_ID_and_local_ID_between_ref_and_da httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Resource identity mismatch between 'ref.id' and 'data.lid' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected resource with ID '12345678' in 'data.id', instead of 'local-1' in 'data.lid'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Resource identity mismatch between 'ref.id' and 'data.lid' element."); + error.Detail.Should().Be("Expected resource with ID '12345678' in 'data.id', instead of 'local-1' in 'data.lid'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1134,10 +1160,12 @@ public async Task Cannot_update_on_mixture_of_local_ID_and_ID_between_ref_and_da httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Resource identity mismatch between 'ref.lid' and 'data.id' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected resource with local ID 'local-1' in 'data.lid', instead of '12345678' in 'data.id'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Resource identity mismatch between 'ref.lid' and 'data.id' element."); + error.Detail.Should().Be("Expected resource with local ID 'local-1' in 'data.lid', instead of '12345678' in 'data.id'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1175,10 +1203,12 @@ public async Task Cannot_update_resource_for_unknown_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1216,10 +1246,12 @@ public async Task Cannot_update_resource_for_unknown_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'performers' with ID '99999999' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'performers' with ID '99999999' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1261,10 +1293,12 @@ public async Task Cannot_update_resource_for_incompatible_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().Be($"Failed to convert '{guid}' of type 'String' to type 'Int32'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().Be($"Failed to convert '{guid}' of type 'String' to type 'Int32'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1308,10 +1342,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Changing the value of the requested attribute is not allowed."); - responseDocument.Errors[0].Detail.Should().Be("Changing the value of 'createdAt' is not allowed."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Changing the value of the requested attribute is not allowed."); + error.Detail.Should().Be("Changing the value of 'createdAt' is not allowed."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1355,10 +1391,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Attribute is read-only."); - responseDocument.Errors[0].Detail.Should().Be("Attribute 'isArchived' is read-only."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Attribute is read-only."); + error.Detail.Should().Be("Attribute 'isArchived' is read-only."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1402,10 +1440,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Resource ID is read-only."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Resource ID is read-only."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -1449,10 +1489,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().StartWith("Failed to convert 'not-a-valid-time' of type 'String' to type 'DateTimeOffset'. - Request body:"); - responseDocument.Errors[0].Source.Pointer.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().StartWith("Failed to convert 'not-a-valid-time' of type 'String' to type 'DateTimeOffset'. - Request body:"); + error.Source.Pointer.Should().BeNull(); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs index 03fb1e26fb..c62aa3b51b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs @@ -632,10 +632,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected single data element for to-one relationship."); - responseDocument.Errors[0].Detail.Should().Be("Expected single data element for 'lyric' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected single data element for to-one relationship."); + error.Detail.Should().Be("Expected single data element for 'lyric' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -677,10 +679,12 @@ public async Task Cannot_create_for_missing_type_in_relationship_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected 'type' element in 'track' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().Be("Expected 'type' element in 'track' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -723,10 +727,12 @@ public async Task Cannot_create_for_unknown_type_in_relationship_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -768,10 +774,12 @@ public async Task Cannot_create_for_missing_ID_in_relationship_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' or 'lid' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected 'id' or 'lid' element in 'lyric' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' or 'lid' element."); + error.Detail.Should().Be("Expected 'id' or 'lid' element in 'lyric' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -815,10 +823,12 @@ public async Task Cannot_create_for_ID_and_local_ID_in_relationship_data() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' or 'lid' element."); - responseDocument.Errors[0].Detail.Should().Be("Expected 'id' or 'lid' element in 'lyric' relationship."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' or 'lid' element."); + error.Detail.Should().Be("Expected 'id' or 'lid' element in 'lyric' relationship."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -869,10 +879,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'lyrics' with ID '99999999' in relationship 'lyric' does not exist."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("A related resource does not exist."); + error.Detail.Should().Be("Related resource of type 'lyrics' with ID '99999999' in relationship 'lyric' does not exist."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } [Fact] @@ -923,10 +935,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'lyric' contains incompatible resource type 'playlists'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/atomic:operations[0]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); + error.Detail.Should().Be("Relationship 'lyric' contains incompatible resource type 'playlists'."); + error.Source.Pointer.Should().Be("/atomic:operations[0]"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeKeyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeKeyTests.cs index 6f9de732a1..952cba65f5 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeKeyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeKeyTests.cs @@ -536,9 +536,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'cars' with ID '999:XX-YY-22' in relationship 'inventory' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("A related resource does not exist."); + error.Detail.Should().Be("Related resource of type 'cars' with ID '999:XX-YY-22' in relationship 'inventory' does not exist."); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/AcceptHeaderTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/AcceptHeaderTests.cs index f76eaff0cc..a892129ddc 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/AcceptHeaderTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/AcceptHeaderTests.cs @@ -196,9 +196,11 @@ public async Task Denies_JsonApi_with_parameters_in_Accept_headers() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotAcceptable); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotAcceptable); - responseDocument.Errors[0].Title.Should().Be("The specified Accept header value does not contain any supported media types."); - responseDocument.Errors[0].Detail.Should().Be("Please include 'application/vnd.api+json' in the Accept header values."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotAcceptable); + error.Title.Should().Be("The specified Accept header value does not contain any supported media types."); + error.Detail.Should().Be("Please include 'application/vnd.api+json' in the Accept header values."); } [Fact] @@ -239,9 +241,11 @@ public async Task Denies_JsonApi_in_Accept_headers_at_operations_endpoint() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotAcceptable); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotAcceptable); - responseDocument.Errors[0].Title.Should().Be("The specified Accept header value does not contain any supported media types."); - responseDocument.Errors[0].Detail.Should().Be("Please include 'application/vnd.api+json; ext=\"https://jsonapi.org/ext/atomic\"' in the Accept header values."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotAcceptable); + error.Title.Should().Be("The specified Accept header value does not contain any supported media types."); + error.Detail.Should().Be("Please include 'application/vnd.api+json; ext=\"https://jsonapi.org/ext/atomic\"' in the Accept header values."); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/ContentTypeHeaderTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/ContentTypeHeaderTests.cs index 27c517b84e..532a67c7a2 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/ContentTypeHeaderTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/ContentTypeHeaderTests.cs @@ -94,9 +94,11 @@ public async Task Denies_unknown_ContentType_header() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnsupportedMediaType); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); - responseDocument.Errors[0].Title.Should().Be("The specified Content-Type header value is not supported."); - responseDocument.Errors[0].Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'text/html' for the Content-Type header value."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); + error.Title.Should().Be("The specified Content-Type header value is not supported."); + error.Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'text/html' for the Content-Type header value."); } [Fact] @@ -184,9 +186,11 @@ public async Task Denies_JsonApi_ContentType_header_with_profile() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnsupportedMediaType); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); - responseDocument.Errors[0].Title.Should().Be("The specified Content-Type header value is not supported."); - responseDocument.Errors[0].Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; profile=something' for the Content-Type header value."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); + error.Title.Should().Be("The specified Content-Type header value is not supported."); + error.Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; profile=something' for the Content-Type header value."); } [Fact] @@ -215,9 +219,11 @@ public async Task Denies_JsonApi_ContentType_header_with_extension() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnsupportedMediaType); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); - responseDocument.Errors[0].Title.Should().Be("The specified Content-Type header value is not supported."); - responseDocument.Errors[0].Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; ext=something' for the Content-Type header value."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); + error.Title.Should().Be("The specified Content-Type header value is not supported."); + error.Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; ext=something' for the Content-Type header value."); } [Fact] @@ -246,9 +252,11 @@ public async Task Denies_JsonApi_ContentType_header_with_AtomicOperations_extens httpResponse.Should().HaveStatusCode(HttpStatusCode.UnsupportedMediaType); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); - responseDocument.Errors[0].Title.Should().Be("The specified Content-Type header value is not supported."); - responseDocument.Errors[0].Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; ext=\"https://jsonapi.org/ext/atomic\"' for the Content-Type header value."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); + error.Title.Should().Be("The specified Content-Type header value is not supported."); + error.Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; ext=\"https://jsonapi.org/ext/atomic\"' for the Content-Type header value."); } [Fact] @@ -277,9 +285,11 @@ public async Task Denies_JsonApi_ContentType_header_with_CharSet() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnsupportedMediaType); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); - responseDocument.Errors[0].Title.Should().Be("The specified Content-Type header value is not supported."); - responseDocument.Errors[0].Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; charset=ISO-8859-4' for the Content-Type header value."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); + error.Title.Should().Be("The specified Content-Type header value is not supported."); + error.Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; charset=ISO-8859-4' for the Content-Type header value."); } [Fact] @@ -308,9 +318,11 @@ public async Task Denies_JsonApi_ContentType_header_with_unknown_parameter() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnsupportedMediaType); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); - responseDocument.Errors[0].Title.Should().Be("The specified Content-Type header value is not supported."); - responseDocument.Errors[0].Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; unknown=unexpected' for the Content-Type header value."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); + error.Title.Should().Be("The specified Content-Type header value is not supported."); + error.Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; unknown=unexpected' for the Content-Type header value."); } [Fact] @@ -346,9 +358,11 @@ public async Task Denies_JsonApi_ContentType_header_at_operations_endpoint() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnsupportedMediaType); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); - responseDocument.Errors[0].Title.Should().Be("The specified Content-Type header value is not supported."); - responseDocument.Errors[0].Detail.Should().Be("Please specify 'application/vnd.api+json; ext=\"https://jsonapi.org/ext/atomic\"' instead of 'application/vnd.api+json' for the Content-Type header value."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); + error.Title.Should().Be("The specified Content-Type header value is not supported."); + error.Detail.Should().Be("Please specify 'application/vnd.api+json; ext=\"https://jsonapi.org/ext/atomic\"' instead of 'application/vnd.api+json' for the Content-Type header value."); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/ActionResultTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/ActionResultTests.cs index b1f459cf57..daffab38a9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/ActionResultTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/ActionResultTests.cs @@ -55,9 +55,11 @@ public async Task Converts_empty_ActionResult_to_error_collection() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("NotFound"); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("NotFound"); + error.Detail.Should().BeNull(); } [Fact] @@ -73,9 +75,11 @@ public async Task Converts_ActionResult_with_error_object_to_error_collection() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("No toothbrush with that ID exists."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("No toothbrush with that ID exists."); + error.Detail.Should().BeNull(); } [Fact] @@ -91,9 +95,11 @@ public async Task Cannot_convert_ActionResult_with_string_parameter_to_error_col httpResponse.Should().HaveStatusCode(HttpStatusCode.InternalServerError); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.InternalServerError); - responseDocument.Errors[0].Title.Should().Be("An unhandled error occurred while processing this request."); - responseDocument.Errors[0].Detail.Should().Be("Data being returned must be errors or resources."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.InternalServerError); + error.Title.Should().Be("An unhandled error occurred while processing this request."); + error.Detail.Should().Be("Data being returned must be errors or resources."); } [Fact] @@ -109,9 +115,11 @@ public async Task Converts_ObjectResult_with_error_object_to_error_collection() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadGateway); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadGateway); - responseDocument.Errors[0].Title.Should().BeNull(); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadGateway); + error.Title.Should().BeNull(); + error.Detail.Should().BeNull(); } [Fact] @@ -128,17 +136,20 @@ public async Task Converts_ObjectResult_with_error_objects_to_error_collection() responseDocument.Errors.Should().HaveCount(3); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.PreconditionFailed); - responseDocument.Errors[0].Title.Should().BeNull(); - responseDocument.Errors[0].Detail.Should().BeNull(); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.PreconditionFailed); + error1.Title.Should().BeNull(); + error1.Detail.Should().BeNull(); - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.Unauthorized); - responseDocument.Errors[1].Title.Should().BeNull(); - responseDocument.Errors[1].Detail.Should().BeNull(); + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.Unauthorized); + error2.Title.Should().BeNull(); + error2.Detail.Should().BeNull(); - responseDocument.Errors[2].StatusCode.Should().Be(HttpStatusCode.ExpectationFailed); - responseDocument.Errors[2].Title.Should().Be("This is not a very great request."); - responseDocument.Errors[2].Detail.Should().BeNull(); + var error3 = responseDocument.Errors[2]; + error3.StatusCode.Should().Be(HttpStatusCode.ExpectationFailed); + error3.Title.Should().Be("This is not a very great request."); + error3.Detail.Should().BeNull(); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/ApiControllerAttributeTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/ApiControllerAttributeTests.cs index 19c7660191..494a9b66e0 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/ApiControllerAttributeTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/ApiControllerAttributeTests.cs @@ -31,7 +31,9 @@ public async Task ApiController_attribute_transforms_NotFound_action_result_with httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].Links.About.Should().Be("https://tools.ietf.org/html/rfc7231#section-6.5.4"); + + var error = responseDocument.Errors[0]; + error.Links.About.Should().Be("https://tools.ietf.org/html/rfc7231#section-6.5.4"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ExceptionHandlerTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ExceptionHandlerTests.cs index 6b1dd941ed..b86bd84787 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ExceptionHandlerTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ExceptionHandlerTests.cs @@ -76,10 +76,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Gone); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Gone); - responseDocument.Errors[0].Title.Should().Be("The requested article is no longer available."); - responseDocument.Errors[0].Detail.Should().Be("Article with code 'X123' is no longer available."); - responseDocument.Errors[0].Meta.Data["support"].Should().Be("Please contact us for info about similar articles at company@email.com."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Gone); + error.Title.Should().Be("The requested article is no longer available."); + error.Detail.Should().Be("Article with code 'X123' is no longer available."); + error.Meta.Data["support"].Should().Be("Please contact us for info about similar articles at company@email.com."); loggerFactory.Logger.Messages.Should().HaveCount(1); loggerFactory.Logger.Messages.Single().LogLevel.Should().Be(LogLevel.Warning); @@ -110,13 +112,13 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.InternalServerError); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.InternalServerError); - responseDocument.Errors[0].Title.Should().Be("An unhandled error occurred while processing this request."); - responseDocument.Errors[0].Detail.Should().Be("Exception has been thrown by the target of an invocation."); - var stackTraceLines = - ((JArray) responseDocument.Errors[0].Meta.Data["stackTrace"]).Select(token => token.Value()); + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.InternalServerError); + error.Title.Should().Be("An unhandled error occurred while processing this request."); + error.Detail.Should().Be("Exception has been thrown by the target of an invocation."); + var stackTraceLines = ((JArray) error.Meta.Data["stackTrace"]).Select(token => token.Value()); stackTraceLines.Should().ContainMatch("* System.InvalidOperationException: Article status could not be determined.*"); loggerFactory.Logger.Messages.Should().HaveCount(1); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs index 17a552bf58..3223f5f5a0 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs @@ -83,9 +83,11 @@ public async Task Cannot_get_primary_resource_for_invalid_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Invalid ID value."); - responseDocument.Errors[0].Detail.Should().Be("The value 'not-a-hex-value' is not a valid hexadecimal value."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Invalid ID value."); + error.Detail.Should().Be("The value 'not-a-hex-value' is not a valid hexadecimal value."); } [Fact] @@ -467,10 +469,12 @@ public async Task Cannot_delete_missing_resource() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be($"Resource of type 'bankAccounts' with ID '{stringId}' does not exist."); - responseDocument.Errors[0].Source.Parameter.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be($"Resource of type 'bankAccounts' with ID '{stringId}' does not exist."); + error.Source.Parameter.Should().BeNull(); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateValidationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateValidationTests.cs index 92838b2900..337caf9c9a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateValidationTests.cs @@ -43,10 +43,12 @@ public async Task Cannot_create_resource_with_omitted_required_attribute() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Input validation failed."); - responseDocument.Errors[0].Detail.Should().Be("The Name field is required."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/data/attributes/name"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Input validation failed."); + error.Detail.Should().Be("The Name field is required."); + error.Source.Pointer.Should().Be("/data/attributes/name"); } [Fact] @@ -75,10 +77,12 @@ public async Task Cannot_create_resource_with_null_for_required_attribute_value( httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Input validation failed."); - responseDocument.Errors[0].Detail.Should().Be("The Name field is required."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/data/attributes/name"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Input validation failed."); + error.Detail.Should().Be("The Name field is required."); + error.Source.Pointer.Should().Be("/data/attributes/name"); } [Fact] @@ -107,10 +111,12 @@ public async Task Cannot_create_resource_with_invalid_attribute_value() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Input validation failed."); - responseDocument.Errors[0].Detail.Should().Be("The field Name must match the regular expression '^[\\w\\s]+$'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/data/attributes/name"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Input validation failed."); + error.Detail.Should().Be("The field Name must match the regular expression '^[\\w\\s]+$'."); + error.Source.Pointer.Should().Be("/data/attributes/name"); } [Fact] @@ -169,20 +175,23 @@ public async Task Cannot_create_resource_with_multiple_violations() responseDocument.Errors.Should().HaveCount(3); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Input validation failed."); - responseDocument.Errors[0].Detail.Should().Be("The Name field is required."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/data/attributes/name"); - - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[1].Title.Should().Be("Input validation failed."); - responseDocument.Errors[1].Detail.Should().Be("The field SizeInBytes must be between 0 and 9223372036854775807."); - responseDocument.Errors[1].Source.Pointer.Should().Be("/data/attributes/sizeInBytes"); - - responseDocument.Errors[2].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[2].Title.Should().Be("Input validation failed."); - responseDocument.Errors[2].Detail.Should().Be("The IsCaseSensitive field is required."); - responseDocument.Errors[2].Source.Pointer.Should().Be("/data/attributes/isCaseSensitive"); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error1.Title.Should().Be("Input validation failed."); + error1.Detail.Should().Be("The Name field is required."); + error1.Source.Pointer.Should().Be("/data/attributes/name"); + + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error2.Title.Should().Be("Input validation failed."); + error2.Detail.Should().Be("The field SizeInBytes must be between 0 and 9223372036854775807."); + error2.Source.Pointer.Should().Be("/data/attributes/sizeInBytes"); + + var error3 = responseDocument.Errors[2]; + error3.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error3.Title.Should().Be("Input validation failed."); + error3.Detail.Should().Be("The IsCaseSensitive field is required."); + error3.Source.Pointer.Should().Be("/data/attributes/isCaseSensitive"); } [Fact] @@ -396,10 +405,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Input validation failed."); - responseDocument.Errors[0].Detail.Should().Be("The Name field is required."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/data/attributes/name"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Input validation failed."); + error.Detail.Should().Be("The Name field is required."); + error.Source.Pointer.Should().Be("/data/attributes/name"); } [Fact] @@ -440,10 +451,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Input validation failed."); - responseDocument.Errors[0].Detail.Should().Be("The field Name must match the regular expression '^[\\w\\s]+$'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/data/attributes/name"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Input validation failed."); + error.Detail.Should().Be("The field Name must match the regular expression '^[\\w\\s]+$'."); + error.Source.Pointer.Should().Be("/data/attributes/name"); } [Fact] @@ -498,16 +511,18 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(2); - - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Input validation failed."); - responseDocument.Errors[0].Detail.Should().Be("The field Id must match the regular expression '^[0-9]+$'."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/data/attributes/id"); - - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[1].Title.Should().Be("Input validation failed."); - responseDocument.Errors[1].Detail.Should().Be("The field Id must match the regular expression '^[0-9]+$'."); - responseDocument.Errors[1].Source.Pointer.Should().Be("/data/attributes/Subdirectories[0].Id"); + + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error1.Title.Should().Be("Input validation failed."); + error1.Detail.Should().Be("The field Id must match the regular expression '^[0-9]+$'."); + error1.Source.Pointer.Should().Be("/data/attributes/id"); + + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error2.Title.Should().Be("Input validation failed."); + error2.Detail.Should().Be("The field Id must match the regular expression '^[0-9]+$'."); + error2.Source.Pointer.Should().Be("/data/attributes/Subdirectories[0].Id"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs index c01df7bb0c..798456e27d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs @@ -149,9 +149,11 @@ public async Task Applies_casing_convention_on_error_stack_trace() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Meta.Data.Should().ContainKey("stack-trace"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Meta.Data.Should().ContainKey("stack-trace"); } [Fact] @@ -188,10 +190,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Input validation failed."); - responseDocument.Errors[0].Detail.Should().Be("The field HeightInMeters must be between 1 and 20."); - responseDocument.Errors[0].Source.Pointer.Should().Be("/data/attributes/height-in-meters"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Input validation failed."); + error.Detail.Should().Be("The field HeightInMeters must be between 1 and 20."); + error.Source.Pointer.Should().Be("/data/attributes/height-in-meters"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs index a5e7ac87bb..38ff0d200d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs @@ -216,10 +216,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Query creation failed due to incompatible types."); - responseDocument.Errors[0].Detail.Should().Be("Failed to convert 'ABC' of type 'String' to type 'Int32'."); - responseDocument.Errors[0].Source.Parameter.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Query creation failed due to incompatible types."); + error.Detail.Should().Be("Failed to convert 'ABC' of type 'String' to type 'Int32'."); + error.Source.Parameter.Should().BeNull(); } [Theory] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs index 009e424ad4..ca8d127be7 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs @@ -78,10 +78,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified filter is invalid."); - responseDocument.Errors[0].Detail.Should().Be("This query string parameter can only be used on a collection of resources (not on a single resource)."); - responseDocument.Errors[0].Source.Parameter.Should().Be("filter"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified filter is invalid."); + error.Detail.Should().Be("This query string parameter can only be used on a collection of resources (not on a single resource)."); + error.Source.Parameter.Should().Be("filter"); } [Fact] @@ -132,10 +134,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified filter is invalid."); - responseDocument.Errors[0].Detail.Should().Be("This query string parameter can only be used on a collection of resources (not on a single resource)."); - responseDocument.Errors[0].Source.Parameter.Should().Be("filter"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified filter is invalid."); + error.Detail.Should().Be("This query string parameter can only be used on a collection of resources (not on a single resource)."); + error.Source.Parameter.Should().Be("filter"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterOperatorTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterOperatorTests.cs index 496184123a..082fa1d34c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterOperatorTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterOperatorTests.cs @@ -249,10 +249,12 @@ public async Task Cannot_filter_equality_on_two_attributes_of_incompatible_types httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Query creation failed due to incompatible types."); - responseDocument.Errors[0].Detail.Should().Be("No coercion operator is defined between types 'System.TimeSpan' and 'System.Double'."); - responseDocument.Errors[0].Source.Parameter.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Query creation failed due to incompatible types."); + error.Detail.Should().Be("No coercion operator is defined between types 'System.TimeSpan' and 'System.Double'."); + error.Source.Parameter.Should().BeNull(); } [Theory] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterTests.cs index 4a2554246e..db289c5ffd 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterTests.cs @@ -37,10 +37,12 @@ public async Task Cannot_filter_in_unknown_scope() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified filter is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'doesNotExist' does not exist on resource 'webAccounts'."); - responseDocument.Errors[0].Source.Parameter.Should().Be("filter[doesNotExist]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified filter is invalid."); + error.Detail.Should().Be("Relationship 'doesNotExist' does not exist on resource 'webAccounts'."); + error.Source.Parameter.Should().Be("filter[doesNotExist]"); } [Fact] @@ -56,10 +58,12 @@ public async Task Cannot_filter_in_unknown_nested_scope() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified filter is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'doesNotExist' in 'posts.doesNotExist' does not exist on resource 'blogPosts'."); - responseDocument.Errors[0].Source.Parameter.Should().Be("filter[posts.doesNotExist]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified filter is invalid."); + error.Detail.Should().Be("Relationship 'doesNotExist' in 'posts.doesNotExist' does not exist on resource 'blogPosts'."); + error.Source.Parameter.Should().Be("filter[posts.doesNotExist]"); } [Fact] @@ -75,10 +79,12 @@ public async Task Cannot_filter_on_attribute_with_blocked_capability() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Filtering on the requested attribute is not allowed."); - responseDocument.Errors[0].Detail.Should().Be("Filtering on attribute 'dateOfBirth' is not allowed."); - responseDocument.Errors[0].Source.Parameter.Should().Be("filter"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Filtering on the requested attribute is not allowed."); + error.Detail.Should().Be("Filtering on attribute 'dateOfBirth' is not allowed."); + error.Source.Parameter.Should().Be("filter"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Includes/IncludeTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Includes/IncludeTests.cs index f132e8f7df..132270d951 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Includes/IncludeTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Includes/IncludeTests.cs @@ -567,10 +567,12 @@ public async Task Cannot_include_unknown_relationship() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified include is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'doesNotExist' does not exist on resource 'webAccounts'."); - responseDocument.Errors[0].Source.Parameter.Should().Be("include"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified include is invalid."); + error.Detail.Should().Be("Relationship 'doesNotExist' does not exist on resource 'webAccounts'."); + error.Source.Parameter.Should().Be("include"); } [Fact] @@ -586,10 +588,12 @@ public async Task Cannot_include_unknown_nested_relationship() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified include is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'doesNotExist' in 'posts.doesNotExist' does not exist on resource 'blogPosts'."); - responseDocument.Errors[0].Source.Parameter.Should().Be("include"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified include is invalid."); + error.Detail.Should().Be("Relationship 'doesNotExist' in 'posts.doesNotExist' does not exist on resource 'blogPosts'."); + error.Source.Parameter.Should().Be("include"); } [Fact] @@ -605,10 +609,12 @@ public async Task Cannot_include_relationship_with_blocked_capability() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Including the requested relationship is not allowed."); - responseDocument.Errors[0].Detail.Should().Be("Including the relationship 'parent' on 'blogPosts' is not allowed."); - responseDocument.Errors[0].Source.Parameter.Should().Be("include"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Including the requested relationship is not allowed."); + error.Detail.Should().Be("Including the relationship 'parent' on 'blogPosts' is not allowed."); + error.Source.Parameter.Should().Be("include"); } [Fact] @@ -689,10 +695,12 @@ public async Task Cannot_exceed_configured_maximum_inclusion_depth() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified include is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Including 'posts.comments' exceeds the maximum inclusion depth of 1."); - responseDocument.Errors[0].Source.Parameter.Should().Be("include"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified include is invalid."); + error.Detail.Should().Be("Including 'posts.comments' exceeds the maximum inclusion depth of 1."); + error.Source.Parameter.Should().Be("include"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs index d629d4b4da..f51e346307 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs @@ -88,10 +88,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified paging is invalid."); - responseDocument.Errors[0].Detail.Should().Be("This query string parameter can only be used on a collection of resources (not on a single resource)."); - responseDocument.Errors[0].Source.Parameter.Should().Be("page[number]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified paging is invalid."); + error.Detail.Should().Be("This query string parameter can only be used on a collection of resources (not on a single resource)."); + error.Source.Parameter.Should().Be("page[number]"); } [Fact] @@ -147,10 +149,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified paging is invalid."); - responseDocument.Errors[0].Detail.Should().Be("This query string parameter can only be used on a collection of resources (not on a single resource)."); - responseDocument.Errors[0].Source.Parameter.Should().Be("page[size]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified paging is invalid."); + error.Detail.Should().Be("This query string parameter can only be used on a collection of resources (not on a single resource)."); + error.Source.Parameter.Should().Be("page[size]"); } [Fact] @@ -416,10 +420,12 @@ public async Task Cannot_paginate_in_unknown_scope() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified paging is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'doesNotExist' does not exist on resource 'webAccounts'."); - responseDocument.Errors[0].Source.Parameter.Should().Be("page[number]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified paging is invalid."); + error.Detail.Should().Be("Relationship 'doesNotExist' does not exist on resource 'webAccounts'."); + error.Source.Parameter.Should().Be("page[number]"); } [Fact] @@ -435,10 +441,12 @@ public async Task Cannot_paginate_in_unknown_nested_scope() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified paging is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'doesNotExist' in 'posts.doesNotExist' does not exist on resource 'blogPosts'."); - responseDocument.Errors[0].Source.Parameter.Should().Be("page[size]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified paging is invalid."); + error.Detail.Should().Be("Relationship 'doesNotExist' in 'posts.doesNotExist' does not exist on resource 'blogPosts'."); + error.Source.Parameter.Should().Be("page[size]"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs index 1c03d45a4a..22eddc7d1c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationTests.cs @@ -41,10 +41,12 @@ public async Task Cannot_use_negative_page_number() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified paging is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Page number cannot be negative or zero."); - responseDocument.Errors[0].Source.Parameter.Should().Be("page[number]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified paging is invalid."); + error.Detail.Should().Be("Page number cannot be negative or zero."); + error.Source.Parameter.Should().Be("page[number]"); } [Fact] @@ -60,10 +62,12 @@ public async Task Cannot_use_zero_page_number() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified paging is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Page number cannot be negative or zero."); - responseDocument.Errors[0].Source.Parameter.Should().Be("page[number]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified paging is invalid."); + error.Detail.Should().Be("Page number cannot be negative or zero."); + error.Source.Parameter.Should().Be("page[number]"); } [Fact] @@ -116,10 +120,12 @@ public async Task Cannot_use_negative_page_size() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified paging is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Page size cannot be negative."); - responseDocument.Errors[0].Source.Parameter.Should().Be("page[size]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified paging is invalid."); + error.Detail.Should().Be("Page size cannot be negative."); + error.Source.Parameter.Should().Be("page[size]"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationWithMaximumTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationWithMaximumTests.cs index 27c863273e..e5c03bd1c6 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationWithMaximumTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/RangeValidationWithMaximumTests.cs @@ -70,10 +70,12 @@ public async Task Cannot_use_page_number_over_maximum() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified paging is invalid."); - responseDocument.Errors[0].Detail.Should().Be($"Page number cannot be higher than {MaximumPageNumber}."); - responseDocument.Errors[0].Source.Parameter.Should().Be("page[number]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified paging is invalid."); + error.Detail.Should().Be($"Page number cannot be higher than {MaximumPageNumber}."); + error.Source.Parameter.Should().Be("page[number]"); } [Fact] @@ -89,10 +91,12 @@ public async Task Cannot_use_zero_page_size() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified paging is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Page size cannot be unconstrained."); - responseDocument.Errors[0].Source.Parameter.Should().Be("page[size]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified paging is invalid."); + error.Detail.Should().Be("Page size cannot be unconstrained."); + error.Source.Parameter.Should().Be("page[size]"); } [Fact] @@ -137,10 +141,12 @@ public async Task Cannot_use_page_size_over_maximum() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified paging is invalid."); - responseDocument.Errors[0].Detail.Should().Be($"Page size cannot be higher than {MaximumPageSize}."); - responseDocument.Errors[0].Source.Parameter.Should().Be("page[size]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified paging is invalid."); + error.Detail.Should().Be($"Page size cannot be higher than {MaximumPageSize}."); + error.Source.Parameter.Should().Be("page[size]"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringTests.cs index 82f8436a6e..90445961f5 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringTests.cs @@ -36,10 +36,12 @@ public async Task Cannot_use_unknown_query_string_parameter() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Unknown query string parameter."); - responseDocument.Errors[0].Detail.Should().Be("Query string parameter 'foo' is unknown. Set 'AllowUnknownQueryStringParameters' to 'true' in options to ignore unknown parameters."); - responseDocument.Errors[0].Source.Parameter.Should().Be("foo"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Unknown query string parameter."); + error.Detail.Should().Be("Query string parameter 'foo' is unknown. Set 'AllowUnknownQueryStringParameters' to 'true' in options to ignore unknown parameters."); + error.Source.Parameter.Should().Be("foo"); } [Fact] @@ -81,10 +83,12 @@ public async Task Cannot_use_empty_query_string_parameter_value(string parameter httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Missing query string parameter value."); - responseDocument.Errors[0].Detail.Should().Be($"Missing value for '{parameterName}' query string parameter."); - responseDocument.Errors[0].Source.Parameter.Should().Be(parameterName); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Missing query string parameter value."); + error.Detail.Should().Be($"Missing value for '{parameterName}' query string parameter."); + error.Source.Parameter.Should().Be(parameterName); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerDefaultValueHandlingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerDefaultValueHandlingTests.cs index 017d30628a..da5ecb4de2 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerDefaultValueHandlingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerDefaultValueHandlingTests.cs @@ -39,10 +39,12 @@ public async Task Cannot_override_from_query_string() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); - responseDocument.Errors[0].Detail.Should().Be("The parameter 'defaults' cannot be used at this endpoint."); - responseDocument.Errors[0].Source.Parameter.Should().Be("defaults"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); + error.Detail.Should().Be("The parameter 'defaults' cannot be used at this endpoint."); + error.Source.Parameter.Should().Be("defaults"); } [Theory] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerNullValueHandlingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerNullValueHandlingTests.cs index 52fdbbc4bc..dc76bfd36b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerNullValueHandlingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SerializerNullValueHandlingTests.cs @@ -39,10 +39,12 @@ public async Task Cannot_override_from_query_string() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); - responseDocument.Errors[0].Detail.Should().Be("The parameter 'nulls' cannot be used at this endpoint."); - responseDocument.Errors[0].Source.Parameter.Should().Be("nulls"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); + error.Detail.Should().Be("The parameter 'nulls' cannot be used at this endpoint."); + error.Source.Parameter.Should().Be("nulls"); } [Theory] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs index 4282440241..0ae93689c9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs @@ -73,10 +73,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified sort is invalid."); - responseDocument.Errors[0].Detail.Should().Be("This query string parameter can only be used on a collection of resources (not on a single resource)."); - responseDocument.Errors[0].Source.Parameter.Should().Be("sort"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified sort is invalid."); + error.Detail.Should().Be("This query string parameter can only be used on a collection of resources (not on a single resource)."); + error.Source.Parameter.Should().Be("sort"); } [Fact] @@ -130,10 +132,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified sort is invalid."); - responseDocument.Errors[0].Detail.Should().Be("This query string parameter can only be used on a collection of resources (not on a single resource)."); - responseDocument.Errors[0].Source.Parameter.Should().Be("sort"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified sort is invalid."); + error.Detail.Should().Be("This query string parameter can only be used on a collection of resources (not on a single resource)."); + error.Source.Parameter.Should().Be("sort"); } [Fact] @@ -480,10 +484,12 @@ public async Task Cannot_sort_in_unknown_scope() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified sort is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'doesNotExist' does not exist on resource 'webAccounts'."); - responseDocument.Errors[0].Source.Parameter.Should().Be("sort[doesNotExist]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified sort is invalid."); + error.Detail.Should().Be("Relationship 'doesNotExist' does not exist on resource 'webAccounts'."); + error.Source.Parameter.Should().Be("sort[doesNotExist]"); } [Fact] @@ -499,10 +505,12 @@ public async Task Cannot_sort_in_unknown_nested_scope() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified sort is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'doesNotExist' in 'posts.doesNotExist' does not exist on resource 'blogPosts'."); - responseDocument.Errors[0].Source.Parameter.Should().Be("sort[posts.doesNotExist]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified sort is invalid."); + error.Detail.Should().Be("Relationship 'doesNotExist' in 'posts.doesNotExist' does not exist on resource 'blogPosts'."); + error.Source.Parameter.Should().Be("sort[posts.doesNotExist]"); } [Fact] @@ -518,10 +526,12 @@ public async Task Cannot_sort_on_attribute_with_blocked_capability() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Sorting on the requested attribute is not allowed."); - responseDocument.Errors[0].Detail.Should().Be("Sorting on attribute 'dateOfBirth' is not allowed."); - responseDocument.Errors[0].Source.Parameter.Should().Be("sort"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Sorting on the requested attribute is not allowed."); + error.Detail.Should().Be("Sorting on attribute 'dateOfBirth' is not allowed."); + error.Source.Parameter.Should().Be("sort"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs index 78e1c0cab6..49d7264e88 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs @@ -587,10 +587,12 @@ public async Task Cannot_select_on_unknown_resource_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("The specified fieldset is invalid."); - responseDocument.Errors[0].Detail.Should().Be("Resource type 'doesNotExist' does not exist."); - responseDocument.Errors[0].Source.Parameter.Should().Be("fields[doesNotExist]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("The specified fieldset is invalid."); + error.Detail.Should().Be("Resource type 'doesNotExist' does not exist."); + error.Source.Parameter.Should().Be("fields[doesNotExist]"); } [Fact] @@ -608,10 +610,12 @@ public async Task Cannot_select_attribute_with_blocked_capability() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Retrieving the requested attribute is not allowed."); - responseDocument.Errors[0].Detail.Should().Be("Retrieving the attribute 'password' is not allowed."); - responseDocument.Errors[0].Source.Parameter.Should().Be("fields[webAccounts]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Retrieving the requested attribute is not allowed."); + error.Detail.Should().Be("Retrieving the attribute 'password' is not allowed."); + error.Source.Parameter.Should().Be("fields[webAccounts]"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs index d5e3da1728..425404563c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs @@ -366,10 +366,12 @@ public async Task Cannot_create_resource_with_client_generated_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("Specifying the resource ID in POST requests is not allowed."); - responseDocument.Errors[0].Detail.Should().BeNull(); - responseDocument.Errors[0].Source.Pointer.Should().Be("/data/id"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("Specifying the resource ID in POST requests is not allowed."); + error.Detail.Should().BeNull(); + error.Source.Pointer.Should().Be("/data/id"); } [Fact] @@ -387,9 +389,11 @@ public async Task Cannot_create_resource_for_missing_request_body() httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Missing request body."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Missing request body."); + error.Detail.Should().BeNull(); } [Fact] @@ -415,9 +419,11 @@ public async Task Cannot_create_resource_for_missing_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'type' element in 'data' element. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().StartWith("Expected 'type' element in 'data' element. - Request body: <<"); } [Fact] @@ -444,9 +450,11 @@ public async Task Cannot_create_resource_for_unknown_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); } [Fact] @@ -497,9 +505,11 @@ public async Task Cannot_create_on_resource_type_mismatch_between_url_and_body() httpResponse.Should().HaveStatusCode(HttpStatusCode.Conflict); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Conflict); - responseDocument.Errors[0].Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - responseDocument.Errors[0].Detail.Should().Be("Expected resource of type 'workItems' in POST request body at endpoint '/workItems', instead of 'rgbColors'."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Conflict); + error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); + error.Detail.Should().Be("Expected resource of type 'workItems' in POST request body at endpoint '/workItems', instead of 'rgbColors'."); } [Fact] @@ -527,9 +537,11 @@ public async Task Cannot_create_resource_attribute_with_blocked_capability() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Setting the initial value of the requested attribute is not allowed."); - responseDocument.Errors[0].Detail.Should().StartWith("Setting the initial value of 'concurrencyToken' is not allowed. - Request body:"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Setting the initial value of the requested attribute is not allowed."); + error.Detail.Should().StartWith("Setting the initial value of 'concurrencyToken' is not allowed. - Request body:"); } [Fact] @@ -557,9 +569,11 @@ public async Task Cannot_create_resource_with_readonly_attribute() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Attribute is read-only."); - responseDocument.Errors[0].Detail.Should().StartWith("Attribute 'concurrencyToken' is read-only. - Request body:"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Attribute is read-only."); + error.Detail.Should().StartWith("Attribute 'concurrencyToken' is read-only. - Request body:"); } [Fact] @@ -577,9 +591,11 @@ public async Task Cannot_create_resource_for_broken_JSON_request_body() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().StartWith("Invalid character after parsing"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().StartWith("Invalid character after parsing"); } [Fact] @@ -607,9 +623,11 @@ public async Task Cannot_create_resource_with_incompatible_attribute_value() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().StartWith("Failed to convert 'not-a-valid-time' of type 'String' to type 'Nullable`1'. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().StartWith("Failed to convert 'not-a-valid-time' of type 'String' to type 'Nullable`1'. - Request body: <<"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs index e4236d90e4..cb1141eaa9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs @@ -239,9 +239,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Conflict); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Conflict); - responseDocument.Errors[0].Title.Should().Be("Another resource with the specified ID already exists."); - responseDocument.Errors[0].Detail.Should().Be($"Another resource of type 'rgbColors' with ID '{existingColor.StringId}' already exists."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Conflict); + error.Title.Should().Be("Another resource with the specified ID already exists."); + error.Detail.Should().Be($"Another resource of type 'rgbColors' with ID '{existingColor.StringId}' already exists."); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs index d85813fea1..ba40c1c284 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs @@ -359,9 +359,11 @@ public async Task Cannot_create_for_missing_relationship_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'type' element in 'subscribers' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().StartWith("Expected 'type' element in 'subscribers' relationship. - Request body: <<"); } [Fact] @@ -399,9 +401,11 @@ public async Task Cannot_create_for_unknown_relationship_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); } [Fact] @@ -438,9 +442,11 @@ public async Task Cannot_create_for_missing_relationship_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'id' element in 'subscribers' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); + error.Detail.Should().StartWith("Expected 'id' element in 'subscribers' relationship. - Request body: <<"); } [Fact] @@ -484,13 +490,15 @@ public async Task Cannot_create_for_unknown_relationship_IDs() responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'workItems' with ID '12345678' in relationship 'assignedItems' does not exist."); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.NotFound); + error1.Title.Should().Be("A related resource does not exist."); + error1.Detail.Should().Be("Related resource of type 'workItems' with ID '12345678' in relationship 'assignedItems' does not exist."); - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[1].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[1].Detail.Should().Be("Related resource of type 'workItems' with ID '87654321' in relationship 'assignedItems' does not exist."); + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.NotFound); + error2.Title.Should().Be("A related resource does not exist."); + error2.Detail.Should().Be("Related resource of type 'workItems' with ID '87654321' in relationship 'assignedItems' does not exist."); } [Fact] @@ -528,9 +536,11 @@ public async Task Cannot_create_on_relationship_type_mismatch() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Relationship 'subscribers' contains incompatible resource type 'rgbColors'. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); + error.Detail.Should().StartWith("Relationship 'subscribers' contains incompatible resource type 'rgbColors'. - Request body: <<"); } [Fact] @@ -629,9 +639,11 @@ public async Task Cannot_create_with_null_data_in_HasMany_relationship() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected data[] element for 'subscribers' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().StartWith("Expected data[] element for 'subscribers' relationship. - Request body: <<"); } [Fact] @@ -662,9 +674,11 @@ public async Task Cannot_create_with_null_data_in_HasManyThrough_relationship() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected data[] element for 'tags' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().StartWith("Expected data[] element for 'tags' relationship. - Request body: <<"); } [Fact] @@ -705,9 +719,11 @@ public async Task Cannot_create_resource_with_local_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Local IDs cannot be used at this endpoint."); - responseDocument.Errors[0].Detail.Should().StartWith("Local IDs cannot be used at this endpoint. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Local IDs cannot be used at this endpoint."); + error.Detail.Should().StartWith("Local IDs cannot be used at this endpoint. - Request body: <<"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs index c326fd31f3..6bdfd7d80e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs @@ -317,9 +317,11 @@ public async Task Cannot_create_for_missing_relationship_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'type' element in 'assignee' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().StartWith("Expected 'type' element in 'assignee' relationship. - Request body: <<"); } [Fact] @@ -354,9 +356,11 @@ public async Task Cannot_create_for_unknown_relationship_type() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); } [Fact] @@ -390,9 +394,11 @@ public async Task Cannot_create_for_missing_relationship_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'id' element in 'assignee' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); + error.Detail.Should().StartWith("Expected 'id' element in 'assignee' relationship. - Request body: <<"); } [Fact] @@ -427,9 +433,11 @@ public async Task Cannot_create_with_unknown_relationship_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'userAccounts' with ID '12345678' in relationship 'assignee' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("A related resource does not exist."); + error.Detail.Should().Be("Related resource of type 'userAccounts' with ID '12345678' in relationship 'assignee' does not exist."); } [Fact] @@ -464,9 +472,11 @@ public async Task Cannot_create_on_relationship_type_mismatch() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Relationship 'assignee' contains incompatible resource type 'rgbColors'. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); + error.Detail.Should().StartWith("Relationship 'assignee' contains incompatible resource type 'rgbColors'. - Request body: <<"); } [Fact] @@ -585,9 +595,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected single data element for to-one relationship."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected single data element for 'assignee' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected single data element for to-one relationship."); + error.Detail.Should().StartWith("Expected single data element for 'assignee' relationship. - Request body: <<"); } [Fact] @@ -625,9 +637,11 @@ public async Task Cannot_create_resource_with_local_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Local IDs cannot be used at this endpoint."); - responseDocument.Errors[0].Detail.Should().StartWith("Local IDs cannot be used at this endpoint. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Local IDs cannot be used at this endpoint."); + error.Detail.Should().StartWith("Local IDs cannot be used at this endpoint. - Request body: <<"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs index 9605013839..4b516ee6cc 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs @@ -65,9 +65,11 @@ public async Task Cannot_delete_missing_resource() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchRelationshipTests.cs index 4c01aecd1b..d75f538a2f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchRelationshipTests.cs @@ -220,9 +220,11 @@ public async Task Cannot_get_relationship_for_unknown_primary_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); } [Fact] @@ -245,9 +247,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested relationship does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' does not contain a relationship named 'doesNotExist'."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested relationship does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' does not contain a relationship named 'doesNotExist'."); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchResourceTests.cs index 213674f813..fee5589a9a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Fetching/FetchResourceTests.cs @@ -131,9 +131,11 @@ public async Task Cannot_get_primary_resource_for_unknown_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); } [Fact] @@ -346,9 +348,11 @@ public async Task Cannot_get_secondary_resource_for_unknown_primary_ID() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); } [Fact] @@ -373,9 +377,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested relationship does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' does not contain a relationship named 'doesNotExist'."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested relationship does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' does not contain a relationship named 'doesNotExist'."); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs index 0928286a18..6108d04f81 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs @@ -53,9 +53,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("Only to-many relationships can be updated through this endpoint."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'assignee' must be a to-many relationship."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("Only to-many relationships can be updated through this endpoint."); + error.Detail.Should().Be("Relationship 'assignee' must be a to-many relationship."); } [Fact] @@ -209,9 +211,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Missing request body."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Missing request body."); + error.Detail.Should().BeNull(); } [Fact] @@ -246,9 +250,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'type' element in 'data' element. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().StartWith("Expected 'type' element in 'data' element. - Request body: <<"); } [Fact] @@ -284,9 +290,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); } [Fact] @@ -321,9 +329,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); + error.Detail.Should().StartWith("Request body: <<"); } [Fact] @@ -365,13 +375,15 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'userAccounts' with ID '88888888' in relationship 'subscribers' does not exist."); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.NotFound); + error1.Title.Should().Be("A related resource does not exist."); + error1.Detail.Should().Be("Related resource of type 'userAccounts' with ID '88888888' in relationship 'subscribers' does not exist."); - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[1].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[1].Detail.Should().Be("Related resource of type 'userAccounts' with ID '99999999' in relationship 'subscribers' does not exist."); + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.NotFound); + error2.Title.Should().Be("A related resource does not exist."); + error2.Detail.Should().Be("Related resource of type 'userAccounts' with ID '99999999' in relationship 'subscribers' does not exist."); } [Fact] @@ -413,13 +425,15 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'workTags' with ID '88888888' in relationship 'tags' does not exist."); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.NotFound); + error1.Title.Should().Be("A related resource does not exist."); + error1.Detail.Should().Be("Related resource of type 'workTags' with ID '88888888' in relationship 'tags' does not exist."); - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[1].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[1].Detail.Should().Be("Related resource of type 'workTags' with ID '99999999' in relationship 'tags' does not exist."); + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.NotFound); + error2.Title.Should().Be("A related resource does not exist."); + error2.Detail.Should().Be("Related resource of type 'workTags' with ID '99999999' in relationship 'tags' does not exist."); } [Fact] @@ -491,9 +505,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); } [Fact] @@ -529,9 +545,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested relationship does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' does not contain a relationship named 'doesNotExist'."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested relationship does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' does not contain a relationship named 'doesNotExist'."); } [Fact] @@ -568,9 +586,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Conflict); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Conflict); - responseDocument.Errors[0].Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - responseDocument.Errors[0].Detail.Should().Be($"Expected resource of type 'workTags' in POST request body at endpoint '/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Conflict); + error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); + error.Detail.Should().Be($"Expected resource of type 'workTags' in POST request body at endpoint '/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); } [Fact] @@ -687,9 +707,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected data[] element for 'subscribers' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().StartWith("Expected data[] element for 'subscribers' relationship. - Request body: <<"); } [Fact] @@ -718,9 +740,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected data[] element for 'tags' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().StartWith("Expected data[] element for 'tags' relationship. - Request body: <<"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs index d76ded0470..0516488857 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs @@ -53,9 +53,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("Only to-many relationships can be updated through this endpoint."); - responseDocument.Errors[0].Detail.Should().Be("Relationship 'assignee' must be a to-many relationship."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("Only to-many relationships can be updated through this endpoint."); + error.Detail.Should().Be("Relationship 'assignee' must be a to-many relationship."); } [Fact] @@ -204,9 +206,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Missing request body."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Missing request body."); + error.Detail.Should().BeNull(); } [Fact] @@ -242,9 +246,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'type' element in 'data' element. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().StartWith("Expected 'type' element in 'data' element. - Request body: <<"); } [Fact] @@ -280,9 +286,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); } [Fact] @@ -317,9 +325,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); + error.Detail.Should().StartWith("Request body: <<"); } [Fact] @@ -361,13 +371,15 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'userAccounts' with ID '88888888' in relationship 'subscribers' does not exist."); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.NotFound); + error1.Title.Should().Be("A related resource does not exist."); + error1.Detail.Should().Be("Related resource of type 'userAccounts' with ID '88888888' in relationship 'subscribers' does not exist."); - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[1].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[1].Detail.Should().Be("Related resource of type 'userAccounts' with ID '99999999' in relationship 'subscribers' does not exist."); + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.NotFound); + error2.Title.Should().Be("A related resource does not exist."); + error2.Detail.Should().Be("Related resource of type 'userAccounts' with ID '99999999' in relationship 'subscribers' does not exist."); } [Fact] @@ -409,13 +421,15 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'workTags' with ID '88888888' in relationship 'tags' does not exist."); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.NotFound); + error1.Title.Should().Be("A related resource does not exist."); + error1.Detail.Should().Be("Related resource of type 'workTags' with ID '88888888' in relationship 'tags' does not exist."); - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[1].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[1].Detail.Should().Be("Related resource of type 'workTags' with ID '99999999' in relationship 'tags' does not exist."); + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.NotFound); + error2.Title.Should().Be("A related resource does not exist."); + error2.Detail.Should().Be("Related resource of type 'workTags' with ID '99999999' in relationship 'tags' does not exist."); } [Fact] @@ -486,9 +500,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); } [Fact] @@ -524,9 +540,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested relationship does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' does not contain a relationship named 'doesNotExist'."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested relationship does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' does not contain a relationship named 'doesNotExist'."); } [Fact] @@ -563,9 +581,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Conflict); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Conflict); - responseDocument.Errors[0].Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - responseDocument.Errors[0].Detail.Should().Be($"Expected resource of type 'workTags' in DELETE request body at endpoint '/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Conflict); + error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); + error.Detail.Should().Be($"Expected resource of type 'workTags' in DELETE request body at endpoint '/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); } [Fact] @@ -684,9 +704,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected data[] element for 'subscribers' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().StartWith("Expected data[] element for 'subscribers' relationship. - Request body: <<"); } [Fact] @@ -715,9 +737,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected data[] element for 'tags' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().StartWith("Expected data[] element for 'tags' relationship. - Request body: <<"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs index c4bf5d1656..201973ef01 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs @@ -254,9 +254,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Missing request body."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Missing request body."); + error.Detail.Should().BeNull(); } [Fact] @@ -291,9 +293,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'type' element in 'data' element. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().StartWith("Expected 'type' element in 'data' element. - Request body: <<"); } [Fact] @@ -329,9 +333,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); } [Fact] @@ -366,9 +372,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); + error.Detail.Should().StartWith("Request body: <<"); } [Fact] @@ -410,13 +418,15 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'userAccounts' with ID '88888888' in relationship 'subscribers' does not exist."); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.NotFound); + error1.Title.Should().Be("A related resource does not exist."); + error1.Detail.Should().Be("Related resource of type 'userAccounts' with ID '88888888' in relationship 'subscribers' does not exist."); - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[1].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[1].Detail.Should().Be("Related resource of type 'userAccounts' with ID '99999999' in relationship 'subscribers' does not exist."); + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.NotFound); + error2.Title.Should().Be("A related resource does not exist."); + error2.Detail.Should().Be("Related resource of type 'userAccounts' with ID '99999999' in relationship 'subscribers' does not exist."); } [Fact] @@ -458,13 +468,15 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Errors.Should().HaveCount(2); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'workTags' with ID '88888888' in relationship 'tags' does not exist."); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.NotFound); + error1.Title.Should().Be("A related resource does not exist."); + error1.Detail.Should().Be("Related resource of type 'workTags' with ID '88888888' in relationship 'tags' does not exist."); - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[1].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[1].Detail.Should().Be("Related resource of type 'workTags' with ID '99999999' in relationship 'tags' does not exist."); + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.NotFound); + error2.Title.Should().Be("A related resource does not exist."); + error2.Detail.Should().Be("Related resource of type 'workTags' with ID '99999999' in relationship 'tags' does not exist."); } [Fact] @@ -529,9 +541,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); } [Fact] @@ -567,9 +581,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested relationship does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' does not contain a relationship named 'doesNotExist'."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested relationship does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' does not contain a relationship named 'doesNotExist'."); } [Fact] @@ -606,9 +622,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Conflict); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Conflict); - responseDocument.Errors[0].Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - responseDocument.Errors[0].Detail.Should().Be($"Expected resource of type 'workTags' in PATCH request body at endpoint '/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Conflict); + error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); + error.Detail.Should().Be($"Expected resource of type 'workTags' in PATCH request body at endpoint '/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); } [Fact] @@ -690,9 +708,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected data[] element for 'subscribers' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().StartWith("Expected data[] element for 'subscribers' relationship. - Request body: <<"); } [Fact] @@ -721,9 +741,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected data[] element for 'tags' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().StartWith("Expected data[] element for 'tags' relationship. - Request body: <<"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs index 629caf8395..1ba7a51671 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs @@ -270,9 +270,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Missing request body."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Missing request body."); + error.Detail.Should().BeNull(); } [Fact] @@ -304,9 +306,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'type' element in 'data' element. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().StartWith("Expected 'type' element in 'data' element. - Request body: <<"); } [Fact] @@ -339,9 +343,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); } [Fact] @@ -373,9 +379,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); + error.Detail.Should().StartWith("Request body: <<"); } [Fact] @@ -408,9 +416,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'userAccounts' with ID '99999999' in relationship 'assignee' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("A related resource does not exist."); + error.Detail.Should().Be("Related resource of type 'userAccounts' with ID '99999999' in relationship 'assignee' does not exist."); } [Fact] @@ -476,9 +486,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); } [Fact] @@ -511,9 +523,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested relationship does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' does not contain a relationship named 'doesNotExist'."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested relationship does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' does not contain a relationship named 'doesNotExist'."); } [Fact] @@ -547,9 +561,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Conflict); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Conflict); - responseDocument.Errors[0].Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - responseDocument.Errors[0].Detail.Should().Be($"Expected resource of type 'userAccounts' in PATCH request body at endpoint '/workItems/{existingWorkItem.StringId}/relationships/assignee', instead of 'rgbColors'."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Conflict); + error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); + error.Detail.Should().Be($"Expected resource of type 'userAccounts' in PATCH request body at endpoint '/workItems/{existingWorkItem.StringId}/relationships/assignee', instead of 'rgbColors'."); } [Fact] @@ -586,9 +602,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected single data element for to-one relationship."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected single data element for 'assignee' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected single data element for to-one relationship."); + error.Detail.Should().StartWith("Expected single data element for 'assignee' relationship. - Request body: <<"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs index 310d833ed5..09f39f6e14 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs @@ -460,9 +460,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'type' element in 'subscribers' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().StartWith("Expected 'type' element in 'subscribers' relationship. - Request body: <<"); } [Fact] @@ -509,9 +511,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); } [Fact] @@ -557,9 +561,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'id' element in 'subscribers' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); + error.Detail.Should().StartWith("Expected 'id' element in 'subscribers' relationship. - Request body: <<"); } [Fact] @@ -628,21 +634,25 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Errors.Should().HaveCount(4); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'userAccounts' with ID '88888888' in relationship 'subscribers' does not exist."); - - responseDocument.Errors[1].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[1].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[1].Detail.Should().Be("Related resource of type 'userAccounts' with ID '99999999' in relationship 'subscribers' does not exist."); - - responseDocument.Errors[2].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[2].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[2].Detail.Should().Be("Related resource of type 'workTags' with ID '88888888' in relationship 'tags' does not exist."); - - responseDocument.Errors[3].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[3].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[3].Detail.Should().Be("Related resource of type 'workTags' with ID '99999999' in relationship 'tags' does not exist."); + var error1 = responseDocument.Errors[0]; + error1.StatusCode.Should().Be(HttpStatusCode.NotFound); + error1.Title.Should().Be("A related resource does not exist."); + error1.Detail.Should().Be("Related resource of type 'userAccounts' with ID '88888888' in relationship 'subscribers' does not exist."); + + var error2 = responseDocument.Errors[1]; + error2.StatusCode.Should().Be(HttpStatusCode.NotFound); + error2.Title.Should().Be("A related resource does not exist."); + error2.Detail.Should().Be("Related resource of type 'userAccounts' with ID '99999999' in relationship 'subscribers' does not exist."); + + var error3 = responseDocument.Errors[2]; + error3.StatusCode.Should().Be(HttpStatusCode.NotFound); + error3.Title.Should().Be("A related resource does not exist."); + error3.Detail.Should().Be("Related resource of type 'workTags' with ID '88888888' in relationship 'tags' does not exist."); + + var error4 = responseDocument.Errors[3]; + error4.StatusCode.Should().Be(HttpStatusCode.NotFound); + error4.Title.Should().Be("A related resource does not exist."); + error4.Detail.Should().Be("Related resource of type 'workTags' with ID '99999999' in relationship 'tags' does not exist."); } [Fact] @@ -689,9 +699,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Relationship 'subscribers' contains incompatible resource type 'rgbColors'. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); + error.Detail.Should().StartWith("Relationship 'subscribers' contains incompatible resource type 'rgbColors'. - Request body: <<"); } [Fact] @@ -795,9 +807,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected data[] element for 'subscribers' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().StartWith("Expected data[] element for 'subscribers' relationship. - Request body: <<"); } [Fact] @@ -837,9 +851,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected data[] element for 'tags' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected data[] element for to-many relationship."); + error.Detail.Should().StartWith("Expected data[] element for 'tags' relationship. - Request body: <<"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs index ea67424dee..92c2cd8e95 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs @@ -550,9 +550,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Missing request body."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Missing request body."); + error.Detail.Should().BeNull(); } [Fact] @@ -584,9 +586,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'type' element in 'data' element. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().StartWith("Expected 'type' element in 'data' element. - Request body: <<"); } [Fact] @@ -619,9 +623,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); } [Fact] @@ -653,9 +659,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); + error.Detail.Should().StartWith("Request body: <<"); } [Fact] @@ -712,9 +720,11 @@ public async Task Cannot_update_resource_on_unknown_resource_ID_in_url() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'workItems' with ID '99999999' does not exist."); } [Fact] @@ -747,9 +757,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Conflict); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Conflict); - responseDocument.Errors[0].Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - responseDocument.Errors[0].Detail.Should().Be($"Expected resource of type 'workItems' in PATCH request body at endpoint '/workItems/{existingWorkItem.StringId}', instead of 'rgbColors'."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Conflict); + error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); + error.Detail.Should().Be($"Expected resource of type 'workItems' in PATCH request body at endpoint '/workItems/{existingWorkItem.StringId}', instead of 'rgbColors'."); } [Fact] @@ -782,9 +794,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Conflict); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Conflict); - responseDocument.Errors[0].Title.Should().Be("Resource ID mismatch between request body and endpoint URL."); - responseDocument.Errors[0].Detail.Should().Be($"Expected resource ID '{existingWorkItems[1].StringId}' in PATCH request body at endpoint '/workItems/{existingWorkItems[1].StringId}', instead of '{existingWorkItems[0].StringId}'."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Conflict); + error.Title.Should().Be("Resource ID mismatch between request body and endpoint URL."); + error.Detail.Should().Be($"Expected resource ID '{existingWorkItems[1].StringId}' in PATCH request body at endpoint '/workItems/{existingWorkItems[1].StringId}', instead of '{existingWorkItems[0].StringId}'."); } [Fact] @@ -821,9 +835,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Changing the value of the requested attribute is not allowed."); - responseDocument.Errors[0].Detail.Should().StartWith("Changing the value of 'concurrencyToken' is not allowed. - Request body:"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Changing the value of the requested attribute is not allowed."); + error.Detail.Should().StartWith("Changing the value of 'concurrencyToken' is not allowed. - Request body:"); } [Fact] @@ -860,9 +876,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Attribute is read-only."); - responseDocument.Errors[0].Detail.Should().StartWith("Attribute 'concurrencyToken' is read-only. - Request body:"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Attribute is read-only."); + error.Detail.Should().StartWith("Attribute 'concurrencyToken' is read-only. - Request body:"); } [Fact] @@ -888,9 +906,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().StartWith("Invalid character after parsing"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().StartWith("Invalid character after parsing"); } [Fact] @@ -927,9 +947,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Resource ID is read-only."); - responseDocument.Errors[0].Detail.Should().StartWith("Resource ID is read-only. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Resource ID is read-only."); + error.Detail.Should().StartWith("Resource ID is read-only. - Request body: <<"); } [Fact] @@ -966,9 +988,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body."); - responseDocument.Errors[0].Detail.Should().StartWith("Failed to convert 'not-a-valid-time' of type 'String' to type 'Nullable`1'. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body."); + error.Detail.Should().StartWith("Failed to convert 'not-a-valid-time' of type 'String' to type 'Nullable`1'. - Request body: <<"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs index 87c84d4327..6541000a47 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs @@ -476,9 +476,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'type' element in 'assignee' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'type' element."); + error.Detail.Should().StartWith("Expected 'type' element in 'assignee' relationship. - Request body: <<"); } [Fact] @@ -522,9 +524,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body includes unknown resource type."); + error.Detail.Should().StartWith("Resource type 'doesNotExist' does not exist. - Request body: <<"); } [Fact] @@ -567,9 +571,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected 'id' element in 'assignee' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Request body must include 'id' element."); + error.Detail.Should().StartWith("Expected 'id' element in 'assignee' relationship. - Request body: <<"); } [Fact] @@ -613,9 +619,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("A related resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Related resource of type 'userAccounts' with ID '99999999' in relationship 'assignee' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("A related resource does not exist."); + error.Detail.Should().Be("Related resource of type 'userAccounts' with ID '99999999' in relationship 'assignee' does not exist."); } [Fact] @@ -659,9 +667,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); - responseDocument.Errors[0].Detail.Should().StartWith("Relationship 'assignee' contains incompatible resource type 'rgbColors'. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Relationship contains incompatible resource type."); + error.Detail.Should().StartWith("Relationship 'assignee' contains incompatible resource type 'rgbColors'. - Request body: <<"); } [Fact] @@ -709,9 +719,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); - responseDocument.Errors[0].Title.Should().Be("Failed to deserialize request body: Expected single data element for to-one relationship."); - responseDocument.Errors[0].Detail.Should().StartWith("Expected single data element for 'assignee' relationship. - Request body: <<"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); + error.Title.Should().Be("Failed to deserialize request body: Expected single data element for to-one relationship."); + error.Detail.Should().StartWith("Expected single data element for 'assignee' relationship. - Request body: <<"); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs index 5a8df69771..12bb83a0ae 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs @@ -50,10 +50,12 @@ public async Task Cannot_create_dependent_side_of_required_ManyToOne_relationshi // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.InternalServerError); - responseDocument.GetErrorStatusCode().Should().Be(HttpStatusCode.InternalServerError); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].Title.Should().Be("An unhandled error occurred while processing this request."); - responseDocument.Errors[0].Detail.Should().Be("Failed to persist changes in the underlying data store."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.InternalServerError); + error.Title.Should().Be("An unhandled error occurred while processing this request."); + error.Detail.Should().Be("Failed to persist changes in the underlying data store."); } [Fact] @@ -82,10 +84,12 @@ public async Task Cannot_create_dependent_side_of_required_OneToOne_relationship // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.InternalServerError); - responseDocument.GetErrorStatusCode().Should().Be(HttpStatusCode.InternalServerError); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].Title.Should().Be("An unhandled error occurred while processing this request."); - responseDocument.Errors[0].Detail.Should().Be("Failed to persist changes in the underlying data store."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.InternalServerError); + error.Title.Should().Be("An unhandled error occurred while processing this request."); + error.Detail.Should().Be("Failed to persist changes in the underlying data store."); } [Fact] @@ -196,10 +200,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); - responseDocument.GetErrorStatusCode().Should().Be(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].Title.Should().Be("Failed to clear a required relationship."); - responseDocument.Errors[0].Detail.Should().Be($"The relationship 'customer' of resource type 'orders' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Failed to clear a required relationship."); + error.Detail.Should().Be($"The relationship 'customer' of resource type 'orders' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); } [Fact] @@ -229,10 +235,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); - responseDocument.GetErrorStatusCode().Should().Be(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].Title.Should().Be("Failed to clear a required relationship."); - responseDocument.Errors[0].Detail.Should().Be($"The relationship 'customer' of resource type 'orders' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Failed to clear a required relationship."); + error.Detail.Should().Be($"The relationship 'customer' of resource type 'orders' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); } [Fact] @@ -273,10 +281,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); - responseDocument.GetErrorStatusCode().Should().Be(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].Title.Should().Be("Failed to clear a required relationship."); - responseDocument.Errors[0].Detail.Should().Be($"The relationship 'orders' of resource type 'customers' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Failed to clear a required relationship."); + error.Detail.Should().Be($"The relationship 'orders' of resource type 'customers' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); } [Fact] @@ -306,10 +316,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); - responseDocument.GetErrorStatusCode().Should().Be(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].Title.Should().Be("Failed to clear a required relationship."); - responseDocument.Errors[0].Detail.Should().Be($"The relationship 'orders' of resource type 'customers' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Failed to clear a required relationship."); + error.Detail.Should().Be($"The relationship 'orders' of resource type 'customers' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); } [Fact] @@ -346,10 +358,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); - responseDocument.GetErrorStatusCode().Should().Be(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].Title.Should().Be("Failed to clear a required relationship."); - responseDocument.Errors[0].Detail.Should().Be($"The relationship 'orders' of resource type 'customers' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Failed to clear a required relationship."); + error.Detail.Should().Be($"The relationship 'orders' of resource type 'customers' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); } [Fact] @@ -397,10 +411,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.InternalServerError); - responseDocument.GetErrorStatusCode().Should().Be(HttpStatusCode.InternalServerError); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].Title.Should().Be("An unhandled error occurred while processing this request."); - responseDocument.Errors[0].Detail.Should().StartWith("The property 'Id' on entity type 'Shipment' is part of a key and so cannot be modified or marked as modified."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.InternalServerError); + error.Title.Should().Be("An unhandled error occurred while processing this request."); + error.Detail.Should().StartWith("The property 'Id' on entity type 'Shipment' is part of a key and so cannot be modified or marked as modified."); } [Fact] @@ -437,10 +453,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.InternalServerError); - responseDocument.GetErrorStatusCode().Should().Be(HttpStatusCode.InternalServerError); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].Title.Should().Be("An unhandled error occurred while processing this request."); - responseDocument.Errors[0].Detail.Should().StartWith("The property 'Id' on entity type 'Shipment' is part of a key and so cannot be modified or marked as modified."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.InternalServerError); + error.Title.Should().Be("An unhandled error occurred while processing this request."); + error.Detail.Should().StartWith("The property 'Id' on entity type 'Shipment' is part of a key and so cannot be modified or marked as modified."); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs index 4e598166f9..5c2bcd29fa 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs @@ -306,9 +306,11 @@ public async Task Cannot_delete_unknown_resource() httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be("Resource of type 'postOffices' with ID '99999999' does not exist."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be("Resource of type 'postOffices' with ID '99999999' does not exist."); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs index af787d76c7..5157569799 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs @@ -60,8 +60,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Including owner is not permitted."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Including owner is not permitted."); + error.Detail.Should().BeNull(); } [Fact] @@ -539,10 +542,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Custom query string parameters cannot be used on nested resource endpoints."); - responseDocument.Errors[0].Detail.Should().Be("Query string parameter 'isHighRisk' cannot be used on a nested resource endpoint."); - responseDocument.Errors[0].Source.Parameter.Should().Be("isHighRisk"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Custom query string parameters cannot be used on nested resource endpoints."); + error.Detail.Should().Be("Query string parameter 'isHighRisk' cannot be used on a nested resource endpoint."); + error.Source.Parameter.Should().Be("isHighRisk"); } private sealed class FakeUserRolesService : IUserRolesService diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs index 55435a459a..ae857cf749 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs @@ -127,9 +127,11 @@ public async Task Can_block_access_to_resource_from_GetSingle_endpoint_using_Bef httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("You are not allowed to update the author of todo items."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("You are not allowed to update the author of todo items."); + error.Detail.Should().BeNull(); } [Fact] @@ -145,9 +147,11 @@ public async Task Can_block_access_to_included_resource_using_BeforeRead_hook() httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("You are not allowed to include passports on individual persons."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("You are not allowed to include passports on individual persons."); + error.Detail.Should().BeNull(); } [Fact] @@ -172,9 +176,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("You are not allowed to see this article."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("You are not allowed to see this article."); + error.Detail.Should().BeNull(); } [Fact] @@ -367,9 +373,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'people'."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'people'."); + error.Detail.Should().BeNull(); } [Fact] @@ -416,9 +424,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'passports'."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'passports'."); + error.Detail.Should().BeNull(); } [Fact] @@ -461,9 +471,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'passports'."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'passports'."); + error.Detail.Should().BeNull(); } [Fact] @@ -489,9 +501,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'people'."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'people'."); + error.Detail.Should().BeNull(); } [Fact] @@ -545,9 +559,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'todoItems'."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'todoItems'."); + error.Detail.Should().BeNull(); } [Fact] @@ -605,9 +621,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'todoItems'."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'todoItems'."); + error.Detail.Should().BeNull(); } [Fact] @@ -634,9 +652,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.Forbidden); - responseDocument.Errors[0].Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'todoItems'."); - responseDocument.Errors[0].Detail.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.Forbidden); + error.Title.Should().Be("You are not allowed to update fields or relationships of locked resource of type 'todoItems'."); + error.Detail.Should().BeNull(); } private IRequestSerializer GetRequestSerializer(Expression> attributes = null, diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/DisableQueryStringTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/DisableQueryStringTests.cs index 8b4467dec4..f6ec44d781 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/DisableQueryStringTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/DisableQueryStringTests.cs @@ -39,10 +39,12 @@ public async Task Cannot_sort_if_query_string_parameter_is_blocked_by_controller httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); - responseDocument.Errors[0].Detail.Should().Be("The parameter 'sort' cannot be used at this endpoint."); - responseDocument.Errors[0].Source.Parameter.Should().Be("sort"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); + error.Detail.Should().Be("The parameter 'sort' cannot be used at this endpoint."); + error.Source.Parameter.Should().Be("sort"); } [Fact] @@ -58,10 +60,12 @@ public async Task Cannot_paginate_if_query_string_parameter_is_blocked_by_contro httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); - responseDocument.Errors[0].Detail.Should().Be("The parameter 'page[number]' cannot be used at this endpoint."); - responseDocument.Errors[0].Source.Parameter.Should().Be("page[number]"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); + error.Detail.Should().Be("The parameter 'page[number]' cannot be used at this endpoint."); + error.Source.Parameter.Should().Be("page[number]"); } [Fact] @@ -77,10 +81,12 @@ public async Task Cannot_use_custom_query_string_parameter_if_blocked_by_control httpResponse.Should().HaveStatusCode(HttpStatusCode.BadRequest); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.BadRequest); - responseDocument.Errors[0].Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); - responseDocument.Errors[0].Detail.Should().Be("The parameter 'skipCache' cannot be used at this endpoint."); - responseDocument.Errors[0].Source.Parameter.Should().Be("skipCache"); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.BadRequest); + error.Title.Should().Be("Usage of one or more query string parameters is not allowed at the requested endpoint."); + error.Detail.Should().Be("The parameter 'skipCache' cannot be used at this endpoint."); + error.Source.Parameter.Should().Be("skipCache"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/HttpReadOnlyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/HttpReadOnlyTests.cs index 0b4bb3ea0c..47547faa57 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/HttpReadOnlyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/HttpReadOnlyTests.cs @@ -56,9 +56,11 @@ public async Task Cannot_create_resource() httpResponse.Should().HaveStatusCode(HttpStatusCode.MethodNotAllowed); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed); - responseDocument.Errors[0].Title.Should().Be("The request method is not allowed."); - responseDocument.Errors[0].Detail.Should().Be("Resource does not support POST requests."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed); + error.Title.Should().Be("The request method is not allowed."); + error.Detail.Should().Be("Resource does not support POST requests."); } [Fact] @@ -94,9 +96,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.MethodNotAllowed); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed); - responseDocument.Errors[0].Title.Should().Be("The request method is not allowed."); - responseDocument.Errors[0].Detail.Should().Be("Resource does not support PATCH requests."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed); + error.Title.Should().Be("The request method is not allowed."); + error.Detail.Should().Be("Resource does not support PATCH requests."); } [Fact] @@ -120,9 +124,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.MethodNotAllowed); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed); - responseDocument.Errors[0].Title.Should().Be("The request method is not allowed."); - responseDocument.Errors[0].Detail.Should().Be("Resource does not support DELETE requests."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed); + error.Title.Should().Be("The request method is not allowed."); + error.Detail.Should().Be("Resource does not support DELETE requests."); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpDeleteTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpDeleteTests.cs index 75838184f7..b2626252bc 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpDeleteTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpDeleteTests.cs @@ -110,9 +110,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.MethodNotAllowed); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed); - responseDocument.Errors[0].Title.Should().Be("The request method is not allowed."); - responseDocument.Errors[0].Detail.Should().Be("Resource does not support DELETE requests."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed); + error.Title.Should().Be("The request method is not allowed."); + error.Detail.Should().Be("Resource does not support DELETE requests."); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPatchTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPatchTests.cs index 5634052d76..3a421083d3 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPatchTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPatchTests.cs @@ -89,9 +89,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.MethodNotAllowed); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed); - responseDocument.Errors[0].Title.Should().Be("The request method is not allowed."); - responseDocument.Errors[0].Detail.Should().Be("Resource does not support PATCH requests."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed); + error.Title.Should().Be("The request method is not allowed."); + error.Detail.Should().Be("Resource does not support PATCH requests."); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPostTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPostTests.cs index de04e4ef2b..cff7168f62 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPostTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/NoHttpPostTests.cs @@ -56,9 +56,11 @@ public async Task Cannot_create_resource() httpResponse.Should().HaveStatusCode(HttpStatusCode.MethodNotAllowed); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed); - responseDocument.Errors[0].Title.Should().Be("The request method is not allowed."); - responseDocument.Errors[0].Detail.Should().Be("Resource does not support POST requests."); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed); + error.Title.Should().Be("The request method is not allowed."); + error.Detail.Should().Be("Resource does not support POST requests."); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs index 779430faa5..93b4d68c18 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionTests.cs @@ -128,10 +128,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be($"Resource of type 'departments' with ID '{department.StringId}' does not exist."); - responseDocument.Errors[0].Source.Parameter.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be($"Resource of type 'departments' with ID '{department.StringId}' does not exist."); + error.Source.Parameter.Should().BeNull(); } [Fact] @@ -203,10 +205,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be($"Resource of type 'companies' with ID '{company.StringId}' does not exist."); - responseDocument.Errors[0].Source.Parameter.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be($"Resource of type 'companies' with ID '{company.StringId}' does not exist."); + error.Source.Parameter.Should().BeNull(); } [Fact] @@ -338,10 +342,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be($"Resource of type 'companies' with ID '{company.StringId}' does not exist."); - responseDocument.Errors[0].Source.Parameter.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be($"Resource of type 'companies' with ID '{company.StringId}' does not exist."); + error.Source.Parameter.Should().BeNull(); } [Fact] @@ -381,10 +387,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be($"Resource of type 'companies' with ID '{company.StringId}' does not exist."); - responseDocument.Errors[0].Source.Parameter.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be($"Resource of type 'companies' with ID '{company.StringId}' does not exist."); + error.Source.Parameter.Should().BeNull(); } [Fact] @@ -423,10 +431,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.NotFound); responseDocument.Errors.Should().HaveCount(1); - responseDocument.Errors[0].StatusCode.Should().Be(HttpStatusCode.NotFound); - responseDocument.Errors[0].Title.Should().Be("The requested resource does not exist."); - responseDocument.Errors[0].Detail.Should().Be($"Resource of type 'companies' with ID '{company.StringId}' does not exist."); - responseDocument.Errors[0].Source.Parameter.Should().BeNull(); + + var error = responseDocument.Errors[0]; + error.StatusCode.Should().Be(HttpStatusCode.NotFound); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be($"Resource of type 'companies' with ID '{company.StringId}' does not exist."); + error.Source.Parameter.Should().BeNull(); } } } From b3aaae6b56f1a0dc53f974d6afe2ebfe42ad373c Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 17 Feb 2021 13:26:11 +0100 Subject: [PATCH 14/60] Hide decimal precision from tests --- .../Creating/AtomicCreateResourceTests.cs | 18 ++++++++------- ...reateResourceWithClientGeneratedIdTests.cs | 2 +- .../QueryStrings/AtomicQueryStringTests.cs | 4 ++-- .../NamingConventions/KebabCasingTests.cs | 2 +- .../ObjectAssertionsExtensions.cs | 22 +++++++++++++++++++ 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs index a826fdcfd3..3d938ca5f2 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs @@ -125,13 +125,15 @@ public async Task Can_create_resources() for (int index = 0; index < elementCount; index++) { - responseDocument.Results[index].SingleData.Should().NotBeNull(); - responseDocument.Results[index].SingleData.Type.Should().Be("musicTracks"); - responseDocument.Results[index].SingleData.Attributes["title"].Should().Be(newTracks[index].Title); - responseDocument.Results[index].SingleData.Attributes["lengthInSeconds"].As().Should().BeApproximately(newTracks[index].LengthInSeconds, 0.00000000001M); - responseDocument.Results[index].SingleData.Attributes["genre"].Should().Be(newTracks[index].Genre); - responseDocument.Results[index].SingleData.Attributes["releasedAt"].Should().BeCloseTo(newTracks[index].ReleasedAt); - responseDocument.Results[0].SingleData.Relationships.Should().NotBeEmpty(); + var singleData = responseDocument.Results[index].SingleData; + + singleData.Should().NotBeNull(); + singleData.Type.Should().Be("musicTracks"); + singleData.Attributes["title"].Should().Be(newTracks[index].Title); + singleData.Attributes["lengthInSeconds"].As().Should().BeApproximately(newTracks[index].LengthInSeconds); + singleData.Attributes["genre"].Should().Be(newTracks[index].Genre); + singleData.Attributes["releasedAt"].Should().BeCloseTo(newTracks[index].ReleasedAt); + singleData.Relationships.Should().NotBeEmpty(); } var newTrackIds = responseDocument.Results.Select(result => Guid.Parse(result.SingleData.Id)); @@ -149,7 +151,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var trackInDatabase = tracksInDatabase.Single(musicTrack => musicTrack.Id == Guid.Parse(responseDocument.Results[index].SingleData.Id)); trackInDatabase.Title.Should().Be(newTracks[index].Title); - trackInDatabase.LengthInSeconds.Should().BeApproximately(newTracks[index].LengthInSeconds, 0.00000000001M); + trackInDatabase.LengthInSeconds.Should().BeApproximately(newTracks[index].LengthInSeconds); trackInDatabase.Genre.Should().Be(newTracks[index].Genre); trackInDatabase.ReleasedAt.Should().BeCloseTo(newTracks[index].ReleasedAt); } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs index 5a0790d38c..c88b46ddcd 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs @@ -123,7 +123,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => .FirstAsync(musicTrack => musicTrack.Id == newTrack.Id); trackInDatabase.Title.Should().Be(newTrack.Title); - trackInDatabase.LengthInSeconds.Should().BeApproximately(newTrack.LengthInSeconds, 0.00000000001M); + trackInDatabase.LengthInSeconds.Should().BeApproximately(newTrack.LengthInSeconds); }); } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs index bc5afd4f47..0a2038f393 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs @@ -383,7 +383,7 @@ public async Task Can_use_defaults_on_operations_endpoint() responseDocument.Results[0].SingleData.Type.Should().Be("musicTracks"); responseDocument.Results[0].SingleData.Attributes.Should().HaveCount(2); responseDocument.Results[0].SingleData.Attributes["title"].Should().Be(newTrackTitle); - responseDocument.Results[0].SingleData.Attributes["lengthInSeconds"].As().Should().BeApproximately(newTrackLength, 0.00000000001M); + responseDocument.Results[0].SingleData.Attributes["lengthInSeconds"].As().Should().BeApproximately(newTrackLength); } [Fact] @@ -426,7 +426,7 @@ public async Task Can_use_nulls_on_operations_endpoint() responseDocument.Results[0].SingleData.Type.Should().Be("musicTracks"); responseDocument.Results[0].SingleData.Attributes.Should().HaveCount(2); responseDocument.Results[0].SingleData.Attributes["title"].Should().Be(newTrackTitle); - responseDocument.Results[0].SingleData.Attributes["lengthInSeconds"].As().Should().BeApproximately(newTrackLength, 0.00000000001M); + responseDocument.Results[0].SingleData.Attributes["lengthInSeconds"].As().Should().BeApproximately(newTrackLength); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs index 798456e27d..64cf57ee1c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs @@ -51,7 +51,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Included.Should().HaveCount(1); responseDocument.Included[0].Type.Should().Be("diving-boards"); responseDocument.Included[0].Id.Should().Be(pools[1].DivingBoards[0].StringId); - responseDocument.Included[0].Attributes["height-in-meters"].As().Should().BeApproximately(pools[1].DivingBoards[0].HeightInMeters, 0.00000000001M); + responseDocument.Included[0].Attributes["height-in-meters"].As().Should().BeApproximately(pools[1].DivingBoards[0].HeightInMeters); responseDocument.Included[0].Relationships.Should().BeNull(); responseDocument.Included[0].Links.Self.Should().Be($"/public-api/diving-boards/{pools[1].DivingBoards[0].StringId}"); diff --git a/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs b/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs index d13759e1b6..eadb4f3055 100644 --- a/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs +++ b/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs @@ -1,5 +1,6 @@ using System; using FluentAssertions; +using FluentAssertions.Numeric; using FluentAssertions.Primitives; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -8,6 +9,8 @@ namespace TestBuildingBlocks { public static class ObjectAssertionsExtensions { + private const decimal NumericPrecision = 0.00000000001M; + private static readonly JsonSerializerSettings _deserializationSettings = new JsonSerializerSettings { Formatting = Formatting.Indented @@ -37,6 +40,25 @@ public static void BeCloseTo(this ObjectAssertions source, DateTimeOffset? expec } } + /// + /// Same as , but with default precision. + /// + public static AndConstraint> BeApproximately(this NumericAssertions parent, + decimal expectedValue, string because = "", params object[] becauseArgs) + { + return parent.BeApproximately(expectedValue, NumericPrecision, because, becauseArgs); + } + + /// + /// Same as , but with default precision. + /// + public static AndConstraint> BeApproximately( + this NullableNumericAssertions parent, decimal? expectedValue, string because = "", + params object[] becauseArgs) + { + return parent.BeApproximately(expectedValue, NumericPrecision, because, becauseArgs); + } + /// /// Used to assert on a JSON-formatted string, ignoring differences in insignificant whitespace and line endings. /// From 33cb16d2f722f5ff36873b2705002a42afd3a8b7 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 17 Feb 2021 16:08:32 +0100 Subject: [PATCH 15/60] Rewrite ResponseStatusCode tests using Theory --- .../Controllers/CoreJsonApiControllerTests.cs | 53 ------------------- test/UnitTests/Internal/ErrorDocumentTests.cs | 30 +++++------ 2 files changed, 14 insertions(+), 69 deletions(-) delete mode 100644 test/UnitTests/Controllers/CoreJsonApiControllerTests.cs diff --git a/test/UnitTests/Controllers/CoreJsonApiControllerTests.cs b/test/UnitTests/Controllers/CoreJsonApiControllerTests.cs deleted file mode 100644 index bc7f0f5540..0000000000 --- a/test/UnitTests/Controllers/CoreJsonApiControllerTests.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Collections.Generic; -using System.Net; -using JsonApiDotNetCore.Controllers; -using JsonApiDotNetCore.Serialization.Objects; -using Microsoft.AspNetCore.Mvc; -using Xunit; - -namespace UnitTests.Controllers -{ - public sealed class CoreJsonApiControllerTests : CoreJsonApiController - { - [Fact] - public void Errors_Correctly_Infers_Status_Code() - { - // Arrange - var errors422 = new List - { - new Error(HttpStatusCode.UnprocessableEntity) {Title = "bad specific"}, - new Error(HttpStatusCode.UnprocessableEntity) {Title = "bad other specific"} - }; - - var errors400 = new List - { - new Error(HttpStatusCode.OK) {Title = "weird"}, - new Error(HttpStatusCode.BadRequest) {Title = "bad"}, - new Error(HttpStatusCode.UnprocessableEntity) {Title = "bad specific"} - }; - - var errors500 = new List - { - new Error(HttpStatusCode.OK) {Title = "weird"}, - new Error(HttpStatusCode.BadRequest) {Title = "bad"}, - new Error(HttpStatusCode.UnprocessableEntity) {Title = "bad specific"}, - new Error(HttpStatusCode.InternalServerError) {Title = "really bad"}, - new Error(HttpStatusCode.BadGateway) {Title = "really bad specific"} - }; - - // Act - var result422 = Error(errors422); - var result400 = Error(errors400); - var result500 = Error(errors500); - - // Assert - var response422 = Assert.IsType(result422); - var response400 = Assert.IsType(result400); - var response500 = Assert.IsType(result500); - - Assert.Equal((int)HttpStatusCode.UnprocessableEntity, response422.StatusCode); - Assert.Equal((int)HttpStatusCode.BadRequest, response400.StatusCode); - Assert.Equal((int)HttpStatusCode.InternalServerError, response500.StatusCode); - } - } -} diff --git a/test/UnitTests/Internal/ErrorDocumentTests.cs b/test/UnitTests/Internal/ErrorDocumentTests.cs index 40a958b1ae..ada75aa29b 100644 --- a/test/UnitTests/Internal/ErrorDocumentTests.cs +++ b/test/UnitTests/Internal/ErrorDocumentTests.cs @@ -1,5 +1,6 @@ -using System.Collections.Generic; +using System.Linq; using System.Net; +using FluentAssertions; using JsonApiDotNetCore.Serialization.Objects; using Xunit; @@ -7,24 +8,21 @@ namespace UnitTests.Internal { public sealed class ErrorDocumentTests { - [Fact] - public void Can_GetStatusCode() + [Theory] + [InlineData(new[] { HttpStatusCode.UnprocessableEntity }, HttpStatusCode.UnprocessableEntity)] + [InlineData(new[] { HttpStatusCode.UnprocessableEntity, HttpStatusCode.UnprocessableEntity }, HttpStatusCode.UnprocessableEntity)] + [InlineData(new[] { HttpStatusCode.UnprocessableEntity, HttpStatusCode.Unauthorized }, HttpStatusCode.BadRequest)] + [InlineData(new[] { HttpStatusCode.UnprocessableEntity, HttpStatusCode.BadGateway }, HttpStatusCode.InternalServerError)] + public void ErrorDocument_GetErrorStatusCode_IsCorrect(HttpStatusCode[] errorCodes, HttpStatusCode expected) { - // Add First 422 error - var errors = new List { new Error(HttpStatusCode.UnprocessableEntity) { Title = "Something wrong" } }; - Assert.Equal(HttpStatusCode.UnprocessableEntity, new ErrorDocument(errors).GetErrorStatusCode()); + // Arrange + var document = new ErrorDocument(errorCodes.Select(code => new Error(code))); - // Add a second 422 error - errors.Add(new Error(HttpStatusCode.UnprocessableEntity) {Title = "Something else wrong"}); - Assert.Equal(HttpStatusCode.UnprocessableEntity, new ErrorDocument(errors).GetErrorStatusCode()); + // Act + var status = document.GetErrorStatusCode(); - // Add 4xx error not 422 - errors.Add(new Error(HttpStatusCode.Unauthorized) {Title = "Unauthorized"}); - Assert.Equal(HttpStatusCode.BadRequest, new ErrorDocument(errors).GetErrorStatusCode()); - - // Add 5xx error not 4xx - errors.Add(new Error(HttpStatusCode.BadGateway) {Title = "Not good"}); - Assert.Equal(HttpStatusCode.InternalServerError, new ErrorDocument(errors).GetErrorStatusCode()); + // Assert + status.Should().Be(expected); } } } From 3a7a0bce0f45ed1ad95727a940476ed8c16b5a12 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 17 Feb 2021 16:59:43 +0100 Subject: [PATCH 16/60] Fixed naming inconsistencies in tests --- .../ResourceHooks/ResourceHookTests.cs | 28 +++++++++---------- .../ResourceInheritance/InheritanceTests.cs | 22 +++++++-------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs index ae857cf749..eb6d2d92bb 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs @@ -50,10 +50,10 @@ public ResourceHookTests(ExampleIntegrationTestContext(p => new {p.Password, p.UserName}); - string requestBody = serializer.Serialize(user); + string requestBody = serializer.Serialize(newUser); const string route = "/api/v1/users"; @@ -67,14 +67,14 @@ public async Task Can_create_user_with_password() var document = JsonConvert.DeserializeObject(responseDocument); document.SingleData.Attributes.Should().NotContainKey("password"); - document.SingleData.Attributes["userName"].Should().Be(user.UserName); + document.SingleData.Attributes["userName"].Should().Be(newUser.UserName); await _testContext.RunOnDatabaseAsync(async dbContext => { - var userInDatabase = await dbContext.Users.FirstAsync(u => u.Id == responseUser.Id); + var userInDatabase = await dbContext.Users.FirstAsync(user => user.Id == responseUser.Id); - userInDatabase.UserName.Should().Be(user.UserName); - userInDatabase.Password.Should().Be(user.Password); + userInDatabase.UserName.Should().Be(newUser.UserName); + userInDatabase.Password.Should().Be(newUser.Password); }); } @@ -82,20 +82,20 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Can_update_user_password() { // Arrange - var user = _fakers.User.Generate(); + var existingUser = _fakers.User.Generate(); await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.Users.Add(user); + dbContext.Users.Add(existingUser); await dbContext.SaveChangesAsync(); }); - user.Password = _fakers.User.Generate().Password; + existingUser.Password = _fakers.User.Generate().Password; var serializer = GetRequestSerializer(p => new {p.Password}); - string requestBody = serializer.Serialize(user); + string requestBody = serializer.Serialize(existingUser); - var route = $"/api/v1/users/{user.Id}"; + var route = $"/api/v1/users/{existingUser.Id}"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePatchAsync(route, requestBody); @@ -104,13 +104,13 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); responseDocument.SingleData.Attributes.Should().NotContainKey("password"); - responseDocument.SingleData.Attributes["userName"].Should().Be(user.UserName); + responseDocument.SingleData.Attributes["userName"].Should().Be(existingUser.UserName); await _testContext.RunOnDatabaseAsync(async dbContext => { - var userInDatabase = await dbContext.Users.FirstAsync(u => u.Id == user.Id); + var userInDatabase = await dbContext.Users.FirstAsync(user => user.Id == existingUser.Id); - userInDatabase.Password.Should().Be(user.Password); + userInDatabase.Password.Should().Be(existingUser.Password); }); } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs index 6f14d78598..fc8d4fcbfa 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs @@ -24,7 +24,7 @@ public InheritanceTests(ExampleIntegrationTestContext { var manInDatabase = await dbContext.Men - .FirstAsync(m => m.Id == newManId); + .FirstAsync(man => man.Id == newManId); - manInDatabase.FamilyName.Should().Be(man.FamilyName); - manInDatabase.IsRetired.Should().Be(man.IsRetired); - manInDatabase.HasBeard.Should().Be(man.HasBeard); + manInDatabase.FamilyName.Should().Be(newMan.FamilyName); + manInDatabase.IsRetired.Should().Be(newMan.IsRetired); + manInDatabase.HasBeard.Should().Be(newMan.HasBeard); }); } From b7d3f059140e40fd58770ccd3c488f2ee5de4012 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 17 Feb 2021 17:13:34 +0100 Subject: [PATCH 17/60] Replace FindAsync usage for consistency with other tests --- .../RequiredRelationships/DefaultBehaviorTests.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs index 12bb83a0ae..e04fbd4117 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs @@ -4,6 +4,7 @@ using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Serialization.Objects; using JsonApiDotNetCoreExampleTests.Startups; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; using Xunit; @@ -117,10 +118,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var existingCustomerInDatabase = await dbContext.Customers.FindAsync(existingOrder.Customer.Id); + var existingCustomerInDatabase = await dbContext.Customers.FirstOrDefaultAsync(customer => customer.Id == existingOrder.Customer.Id); existingCustomerInDatabase.Should().BeNull(); - var existingOrderInDatabase = await dbContext.Orders.FindAsync(existingOrder.Id); + var existingOrderInDatabase = await dbContext.Orders.FirstOrDefaultAsync(order => order.Id == existingOrder.Id); existingOrderInDatabase.Should().BeNull(); }); } @@ -151,13 +152,13 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var existingOrderInDatabase = await dbContext.Orders.FindAsync(existingOrder.Id); + var existingOrderInDatabase = await dbContext.Orders.FirstOrDefaultAsync(order => order.Id == existingOrder.Id); existingOrderInDatabase.Should().BeNull(); - var existingShipmentInDatabase = await dbContext.Shipments.FindAsync(existingOrder.Shipment.Id); + var existingShipmentInDatabase = await dbContext.Shipments.FirstOrDefaultAsync(shipment => shipment.Id == existingOrder.Shipment.Id); existingShipmentInDatabase.Should().BeNull(); - var existingCustomerInDatabase = await dbContext.Customers.FindAsync(existingOrder.Customer.Id); + var existingCustomerInDatabase = await dbContext.Customers.FirstOrDefaultAsync(customer => customer.Id == existingOrder.Customer.Id); existingCustomerInDatabase.Should().NotBeNull(); }); } From 9b9ba14ce15e1a83b8368b396b69caa68102d973 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 17 Feb 2021 14:05:02 +0100 Subject: [PATCH 18/60] Added formatter directives on fakers --- .../ExampleFakers.cs | 3 + .../AtomicOperations/OperationsFakers.cs | 3 + .../CustomRoutes/CustomRouteFakers.cs | 3 + .../EagerLoading/EagerLoadingFakers.cs | 3 + .../IdObfuscation/ObfuscationFakers.cs | 3 + .../IntegrationTests/Links/LinksFakers.cs | 3 + .../IntegrationTests/Logging/AuditFakers.cs | 3 + .../IntegrationTests/Meta/SupportFakers.cs | 3 + .../NamingConventions/SwimmingFakers.cs | 3 + .../QueryStrings/QueryStringFakers.cs | 5 +- .../ReadWrite/ReadWriteFakers.cs | 3 + .../DefaultBehaviorFakers.cs | 12 ++-- .../InjectionFakers.cs | 3 + .../RestrictionFakers.cs | 3 + .../Serialization/SerializationFakers.cs | 3 + .../ZeroKeys/ZeroKeyFakers.cs | 3 + .../UnitTests/ResourceHooks/HooksDummyData.cs | 32 ++++++++--- .../SerializationTestsSetupBase.cs | 55 +++++++++++-------- .../IncludedResourceObjectBuilderTests.cs | 28 +++++----- 19 files changed, 122 insertions(+), 52 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/ExampleFakers.cs b/test/JsonApiDotNetCoreExampleTests/ExampleFakers.cs index 1b9718ca7e..a67c525537 100644 --- a/test/JsonApiDotNetCoreExampleTests/ExampleFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/ExampleFakers.cs @@ -4,6 +4,9 @@ using TestBuildingBlocks; using Person = JsonApiDotNetCoreExample.Models.Person; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests { internal sealed class ExampleFakers : FakerContainer diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsFakers.cs index 63734c5523..75c9eef737 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsFakers.cs @@ -5,6 +5,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations { internal sealed class OperationsFakers : FakerContainer diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteFakers.cs index 0fa5c5d008..2c15eb3e30 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteFakers.cs @@ -2,6 +2,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CustomRoutes { internal sealed class CustomRouteFakers : FakerContainer diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingFakers.cs index 80ae5c9d14..5910102644 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingFakers.cs @@ -2,6 +2,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.EagerLoading { internal sealed class EagerLoadingFakers : FakerContainer diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/ObfuscationFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/ObfuscationFakers.cs index 06fd5ac9ab..d6a08114e4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/ObfuscationFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/ObfuscationFakers.cs @@ -2,6 +2,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.IdObfuscation { internal sealed class ObfuscationFakers : FakerContainer diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/LinksFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/LinksFakers.cs index 2bd9552fa4..b0ade264dc 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/LinksFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/LinksFakers.cs @@ -2,6 +2,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Links { internal sealed class LinksFakers : FakerContainer diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/AuditFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/AuditFakers.cs index 214fcd9bda..ea3e4c79a4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/AuditFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/AuditFakers.cs @@ -2,6 +2,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Logging { internal sealed class AuditFakers : FakerContainer diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportFakers.cs index 9fd4704cdd..59de00b55c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportFakers.cs @@ -2,6 +2,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Meta { internal sealed class SupportFakers : FakerContainer diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/SwimmingFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/SwimmingFakers.cs index 8636078884..86ecc8d1ad 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/SwimmingFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/SwimmingFakers.cs @@ -2,6 +2,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.NamingConventions { internal sealed class SwimmingFakers : FakerContainer diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringFakers.cs index 2d535d00d4..f4640f076c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringFakers.cs @@ -2,6 +2,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings { internal sealed class QueryStringFakers : FakerContainer @@ -55,7 +58,7 @@ internal sealed class QueryStringFakers : FakerContainer .UseSeed(GetFakerSeed()) .RuleFor(appointment => appointment.Title, f => f.Random.Word()) .RuleFor(appointment => appointment.StartTime, f => f.Date.FutureOffset()) - .RuleFor(appointment => appointment.EndTime, (f, appointment) => appointment.StartTime.AddHours(f.Random.Double(1, 4)))); + .RuleFor(appointment => appointment.EndTime,(f, appointment) => appointment.StartTime.AddHours(f.Random.Double(1, 4)))); public Faker Blog => _lazyBlogFaker.Value; public Faker BlogPost => _lazyBlogPostFaker.Value; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/ReadWriteFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/ReadWriteFakers.cs index cab209819c..17a8dfdb4f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/ReadWriteFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/ReadWriteFakers.cs @@ -2,6 +2,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ReadWrite { internal sealed class ReadWriteFakers : FakerContainer diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorFakers.cs index 0363ddda5b..05431b5d55 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorFakers.cs @@ -2,6 +2,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.RequiredRelationships { internal sealed class DefaultBehaviorFakers : FakerContainer @@ -9,21 +12,18 @@ internal sealed class DefaultBehaviorFakers : FakerContainer private readonly Lazy> _orderFaker = new Lazy>(() => new Faker() .UseSeed(GetFakerSeed()) - .RuleFor(order => order.Amount, f => f.Finance.Amount()) - ); + .RuleFor(order => order.Amount, f => f.Finance.Amount())); private readonly Lazy> _customerFaker = new Lazy>(() => new Faker() .UseSeed(GetFakerSeed()) - .RuleFor(customer => customer.EmailAddress, f => f.Person.Email) - ); + .RuleFor(customer => customer.EmailAddress, f => f.Person.Email)); private readonly Lazy> _shipmentFaker = new Lazy>(() => new Faker() .UseSeed(GetFakerSeed()) .RuleFor(shipment => shipment.TrackAndTraceCode, f => f.Commerce.Ean13()) - .RuleFor(shipment => shipment.ShippedAt, f => f.Date.Past()) - ); + .RuleFor(shipment => shipment.ShippedAt, f => f.Date.Past())); public Faker Orders => _orderFaker.Value; public Faker Customers => _customerFaker.Value; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionFakers.cs index 0b006a4618..54df54c48f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionFakers.cs @@ -4,6 +4,9 @@ using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceConstructorInjection { internal sealed class InjectionFakers : FakerContainer diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/RestrictionFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/RestrictionFakers.cs index b81d66dda5..2f8e844154 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/RestrictionFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/RestrictionFakers.cs @@ -2,6 +2,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.RestrictedControllers { internal sealed class RestrictionFakers : FakerContainer diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationFakers.cs index 1bda09f4ae..8b6414e70f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationFakers.cs @@ -2,6 +2,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Serialization { internal sealed class SerializationFakers : FakerContainer diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroKeyFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroKeyFakers.cs index 300e76382b..9db5425952 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroKeyFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroKeyFakers.cs @@ -2,6 +2,9 @@ using Bogus; using TestBuildingBlocks; +// @formatter:wrap_chained_method_calls chop_always +// @formatter:keep_existing_linebreaks true + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ZeroKeys { internal sealed class ZeroKeyFakers : FakerContainer diff --git a/test/UnitTests/ResourceHooks/HooksDummyData.cs b/test/UnitTests/ResourceHooks/HooksDummyData.cs index ba076241e0..48f30be3a9 100644 --- a/test/UnitTests/ResourceHooks/HooksDummyData.cs +++ b/test/UnitTests/ResourceHooks/HooksDummyData.cs @@ -15,10 +15,10 @@ public class HooksDummyData protected ResourceHook[] NoHooks { get; } = new ResourceHook[0]; protected ResourceHook[] EnableDbValues { get; } = { ResourceHook.BeforeUpdate, ResourceHook.BeforeUpdateRelationship }; protected ResourceHook[] DisableDbValues { get; } = new ResourceHook[0]; - protected readonly Faker _personFaker; protected readonly Faker _todoFaker; - protected readonly Faker _tagFaker; + protected readonly Faker _personFaker; protected readonly Faker
    _articleFaker; + protected readonly Faker _tagFaker; protected readonly Faker _articleTagFaker; protected readonly Faker _identifiableArticleTagFaker; protected readonly Faker _passportFaker; @@ -34,17 +34,31 @@ public HooksDummyData() .Add() .Build(); - _todoFaker = new Faker().Rules((f, i) => i.Id = f.UniqueIndex + 1); - _personFaker = new Faker().Rules((f, i) => i.Id = f.UniqueIndex + 1); + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + + _todoFaker = new Faker() + .RuleFor(x => x.Id, f => f.UniqueIndex + 1); + + _personFaker = new Faker() + .RuleFor(x => x.Id, f => f.UniqueIndex + 1); + + _articleFaker = new Faker
    () + .RuleFor(x => x.Id, f => f.UniqueIndex + 1); - _articleFaker = new Faker
    ().Rules((f, i) => i.Id = f.UniqueIndex + 1); - _articleTagFaker = new Faker(); - _identifiableArticleTagFaker = new Faker().Rules((f, i) => i.Id = f.UniqueIndex + 1); _tagFaker = new Faker() - .Rules((f, i) => i.Id = f.UniqueIndex + 1); + .RuleFor(x => x.Id, f => f.UniqueIndex + 1); + + _articleTagFaker = new Faker(); + + _identifiableArticleTagFaker = new Faker() + .RuleFor(x => x.Id, f => f.UniqueIndex + 1); _passportFaker = new Faker() - .Rules((f, i) => i.Id = f.UniqueIndex + 1); + .RuleFor(x => x.Id, f => f.UniqueIndex + 1); + + // @formatter:wrap_chained_method_calls restore + // @formatter:keep_existing_linebreaks restore } protected List CreateTodoWithToOnePerson() diff --git a/test/UnitTests/Serialization/SerializationTestsSetupBase.cs b/test/UnitTests/Serialization/SerializationTestsSetupBase.cs index 2e2fd2e174..841237ce34 100644 --- a/test/UnitTests/Serialization/SerializationTestsSetupBase.cs +++ b/test/UnitTests/Serialization/SerializationTestsSetupBase.cs @@ -9,30 +9,41 @@ namespace UnitTests.Serialization public class SerializationTestsSetupBase { protected IResourceGraph ResourceGraph { get; } - protected readonly Faker _foodFaker; - protected readonly Faker _songFaker; - protected readonly Faker
    _articleFaker; - protected readonly Faker _blogFaker; - protected readonly Faker _personFaker; + protected Faker FoodFaker { get; } + protected Faker SongFaker { get; } + protected Faker
    ArticleFaker { get; } + protected Faker BlogFaker { get; } + protected Faker PersonFaker { get; } public SerializationTestsSetupBase() { ResourceGraph = BuildGraph(); - _articleFaker = new Faker
    () - .RuleFor(f => f.Title, f => f.Hacker.Phrase()) - .RuleFor(f => f.Id, f => f.UniqueIndex + 1); - _personFaker = new Faker() - .RuleFor(f => f.Name, f => f.Person.FullName) - .RuleFor(f => f.Id, f => f.UniqueIndex + 1); - _blogFaker = new Faker() - .RuleFor(f => f.Title, f => f.Hacker.Phrase()) - .RuleFor(f => f.Id, f => f.UniqueIndex + 1); - _songFaker = new Faker() - .RuleFor(f => f.Title, f => f.Lorem.Sentence()) - .RuleFor(f => f.Id, f => f.UniqueIndex + 1); - _foodFaker = new Faker() - .RuleFor(f => f.Dish, f => f.Lorem.Sentence()) - .RuleFor(f => f.Id, f => f.UniqueIndex + 1); + + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + + ArticleFaker = new Faker
    () + .RuleFor(f => f.Title, f => f.Hacker.Phrase()) + .RuleFor(f => f.Id, f => f.UniqueIndex + 1); + + PersonFaker = new Faker() + .RuleFor(f => f.Name, f => f.Person.FullName) + .RuleFor(f => f.Id, f => f.UniqueIndex + 1); + + BlogFaker = new Faker() + .RuleFor(f => f.Title, f => f.Hacker.Phrase()) + .RuleFor(f => f.Id, f => f.UniqueIndex + 1); + + SongFaker = new Faker() + .RuleFor(f => f.Title, f => f.Lorem.Sentence()) + .RuleFor(f => f.Id, f => f.UniqueIndex + 1); + + FoodFaker = new Faker() + .RuleFor(f => f.Dish, f => f.Lorem.Sentence()) + .RuleFor(f => f.Id, f => f.UniqueIndex + 1); + + // @formatter:wrap_chained_method_calls restore + // @formatter:keep_existing_linebreaks restore } protected IResourceGraph BuildGraph() @@ -62,8 +73,8 @@ protected IResourceGraph BuildGraph() resourceGraphBuilder.Add(); resourceGraphBuilder.Add(); resourceGraphBuilder.Add(); - + return resourceGraphBuilder.Build(); } - } + } } diff --git a/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs b/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs index 754303a712..228d51fa42 100644 --- a/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs +++ b/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs @@ -41,7 +41,7 @@ public void BuildIncluded_DeeplyNestedCircularChainOfManyData_BuildsWithoutDupli { // Arrange var (article, author, _, _, _) = GetAuthorChainInstances(); - var secondArticle = _articleFaker.Generate(); + var secondArticle = ArticleFaker.Generate(); secondArticle.Author = author; var builder = GetBuilder(); @@ -90,22 +90,22 @@ public void BuildIncluded_OverlappingDeeplyNestedCircularChains_CanBuild() private (Person, Song, Person, Song) GetReviewerChainInstances(Article article, Blog sharedBlog, Person sharedBlogAuthor) { - var reviewer = _personFaker.Generate(); + var reviewer = PersonFaker.Generate(); article.Reviewer = reviewer; - var blogs = _blogFaker.Generate(1); + var blogs = BlogFaker.Generate(1); blogs.Add(sharedBlog); reviewer.Blogs = blogs.ToHashSet(); blogs[0].Author = reviewer; - var author = _personFaker.Generate(); + var author = PersonFaker.Generate(); blogs[1].Author = sharedBlogAuthor; - var authorSong = _songFaker.Generate(); + var authorSong = SongFaker.Generate(); author.FavoriteSong = authorSong; sharedBlogAuthor.FavoriteSong = authorSong; - var reviewerSong = _songFaker.Generate(); + var reviewerSong = SongFaker.Generate(); reviewer.FavoriteSong = reviewerSong; return (reviewer, reviewerSong, author, authorSong); @@ -113,20 +113,20 @@ public void BuildIncluded_OverlappingDeeplyNestedCircularChains_CanBuild() private (Article, Person, Food, Person, Food) GetAuthorChainInstances() { - var article = _articleFaker.Generate(); - var author = _personFaker.Generate(); + var article = ArticleFaker.Generate(); + var author = PersonFaker.Generate(); article.Author = author; - var blogs = _blogFaker.Generate(2); + var blogs = BlogFaker.Generate(2); author.Blogs = blogs.ToHashSet(); blogs[0].Reviewer = author; - var reviewer = _personFaker.Generate(); + var reviewer = PersonFaker.Generate(); blogs[1].Reviewer = reviewer; - var authorFood = _foodFaker.Generate(); + var authorFood = FoodFaker.Generate(); author.FavoriteFood = authorFood; - var reviewerFood = _foodFaker.Generate(); + var reviewerFood = FoodFaker.Generate(); reviewer.FavoriteFood = reviewerFood; return (article, author, authorFood, reviewer, reviewerFood); @@ -135,8 +135,8 @@ public void BuildIncluded_OverlappingDeeplyNestedCircularChains_CanBuild() [Fact] public void BuildIncluded_DuplicateChildrenMultipleChains_OnceInOutput() { - var person = _personFaker.Generate(); - var articles = _articleFaker.Generate(5); + var person = PersonFaker.Generate(); + var articles = ArticleFaker.Generate(5); articles.ForEach(a => a.Author = person); articles.ForEach(a => a.Reviewer = person); var builder = GetBuilder(); From b93a8d539081c327b6f0f5c64d9cb0bebcad62ac Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 17 Feb 2021 16:45:06 +0100 Subject: [PATCH 19/60] Added formatter directives on DbContext types --- .../IntegrationTests/AtomicOperations/OperationsDbContext.cs | 2 ++ .../IntegrationTests/CompositeKeys/CompositeDbContext.cs | 2 ++ .../IntegrationTests/EagerLoading/EagerLoadingDbContext.cs | 2 ++ .../IntegrationTests/Links/LinksDbContext.cs | 2 ++ .../ModelStateValidation/ModelStateDbContext.cs | 2 ++ .../IntegrationTests/QueryStrings/QueryStringDbContext.cs | 2 ++ .../IntegrationTests/ReadWrite/ReadWriteDbContext.cs | 2 ++ .../RequiredRelationships/DefaultBehaviorDbContext.cs | 2 ++ .../ResourceInheritance/InheritanceDbContext.cs | 2 ++ .../IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs | 4 ++-- 10 files changed, 20 insertions(+), 2 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs index 0e8ab53cdf..bde4cec990 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore; +// @formatter:wrap_chained_method_calls chop_always + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations { public sealed class OperationsDbContext : DbContext diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs index 0f64043bd8..545f2c380f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore; +// @formatter:wrap_chained_method_calls chop_always + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CompositeKeys { public sealed class CompositeDbContext : DbContext diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs index fb60ddb51e..4058533637 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore; +// @formatter:wrap_chained_method_calls chop_always + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.EagerLoading { public sealed class EagerLoadingDbContext : DbContext diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/LinksDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/LinksDbContext.cs index 8f1e638891..810eb4be48 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/LinksDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/LinksDbContext.cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore; +// @formatter:wrap_chained_method_calls chop_always + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Links { public sealed class LinksDbContext : DbContext diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateDbContext.cs index 6add39c7b0..b3de2e1cbd 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateDbContext.cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore; +// @formatter:wrap_chained_method_calls chop_always + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ModelStateValidation { public sealed class ModelStateDbContext : DbContext diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs index 2551765272..962babc0b7 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore; +// @formatter:wrap_chained_method_calls chop_always + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings { public sealed class QueryStringDbContext : DbContext diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs index ea18e26788..7cb3517453 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore; +// @formatter:wrap_chained_method_calls chop_always + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ReadWrite { public sealed class ReadWriteDbContext : DbContext diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs index 406be13587..96331a0aeb 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore; +// @formatter:wrap_chained_method_calls chop_always + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.RequiredRelationships { public sealed class DefaultBehaviorDbContext : DbContext diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceDbContext.cs index 904b840c90..770d739ccf 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceDbContext.cs @@ -1,6 +1,8 @@ using JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance.Models; using Microsoft.EntityFrameworkCore; +// @formatter:wrap_chained_method_calls chop_always + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance { public sealed class InheritanceDbContext : DbContext diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs index b119f7e26a..b9a1de31ca 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore; +// @formatter:wrap_chained_method_calls chop_always + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ZeroKeys { public sealed class ZeroKeyDbContext : DbContext @@ -14,8 +16,6 @@ public ZeroKeyDbContext(DbContextOptions options) : base(optio protected override void OnModelCreating(ModelBuilder builder) { - base.OnModelCreating(builder); - builder.Entity() .HasMany(game => game.Maps) .WithOne(map => map.Game); From 01ffbb84daaee1e6d88e7a31a8eb07033b103156 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Thu, 18 Feb 2021 17:16:50 +0100 Subject: [PATCH 20/60] Added FirstWithIdAsync / FirstWithIdOrDefaultAsync to reduce line length on database queries in tests --- .../Creating/AtomicCreateResourceTests.cs | 14 +++----- ...reateResourceWithClientGeneratedIdTests.cs | 6 ++-- ...eateResourceWithToManyRelationshipTests.cs | 6 ++-- ...reateResourceWithToOneRelationshipTests.cs | 6 ++-- .../Deleting/AtomicDeleteResourceTests.cs | 21 ++++-------- .../LocalIds/AtomicLocalIdTests.cs | 32 +++++++++---------- .../AtomicModelStateValidationTests.cs | 11 +++---- .../AtomicAddToToManyRelationshipTests.cs | 6 ++-- ...AtomicRemoveFromToManyRelationshipTests.cs | 6 ++-- .../AtomicReplaceToManyRelationshipTests.cs | 8 ++--- .../AtomicUpdateToOneRelationshipTests.cs | 18 +++++------ .../AtomicReplaceToManyRelationshipTests.cs | 8 ++--- .../Resources/AtomicUpdateResourceTests.cs | 17 ++++------ .../AtomicUpdateToOneRelationshipTests.cs | 18 +++++------ .../CompositeKeys/CompositeKeyTests.cs | 10 +++--- .../EagerLoading/EagerLoadingTests.cs | 9 +++--- .../IdObfuscation/IdObfuscationTests.cs | 10 +++--- .../NamingConventions/KebabCasingTests.cs | 3 +- .../ReadWrite/Creating/CreateResourceTests.cs | 20 ++++-------- ...reateResourceWithClientGeneratedIdTests.cs | 12 +++---- ...eateResourceWithToManyRelationshipTests.cs | 10 +++--- ...reateResourceWithToOneRelationshipTests.cs | 6 ++-- .../ReadWrite/Deleting/DeleteResourceTests.cs | 21 ++++-------- .../AddToToManyRelationshipTests.cs | 10 +++--- .../RemoveFromToManyRelationshipTests.cs | 12 +++---- .../ReplaceToManyRelationshipTests.cs | 18 +++++------ .../UpdateToOneRelationshipTests.cs | 12 ++++--- .../ReplaceToManyRelationshipTests.cs | 22 ++++++------- .../Updating/Resources/UpdateResourceTests.cs | 28 ++++++---------- .../Resources/UpdateToOneRelationshipTests.cs | 16 ++++++---- .../DefaultBehaviorTests.cs | 10 +++--- .../ResourceInjectionTests.cs | 9 +++--- .../ResourceHooks/ResourceHookTests.cs | 4 +-- .../ResourceInheritance/InheritanceTests.cs | 14 ++++---- .../ZeroKeys/EmptyGuidAsKeyTests.cs | 25 +++++++-------- .../ZeroKeys/ZeroAsKeyTests.cs | 25 +++++++-------- .../TestBuildingBlocks/QueryableExtensions.cs | 25 +++++++++++++++ 37 files changed, 241 insertions(+), 267 deletions(-) create mode 100644 test/TestBuildingBlocks/QueryableExtensions.cs diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs index 3d938ca5f2..16afe533b1 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs @@ -72,8 +72,7 @@ public async Task Can_create_resource() await _testContext.RunOnDatabaseAsync(async dbContext => { - var performerInDatabase = await dbContext.Performers - .FirstAsync(performer => performer.Id == newPerformerId); + var performerInDatabase = await dbContext.Performers.FirstWithIdAsync(newPerformerId); performerInDatabase.ArtistName.Should().Be(newArtistName); performerInDatabase.BornAt.Should().BeCloseTo(newBornAt); @@ -202,8 +201,7 @@ public async Task Can_create_resource_without_attributes_or_relationships() await _testContext.RunOnDatabaseAsync(async dbContext => { - var performerInDatabase = await dbContext.Performers - .FirstAsync(performer => performer.Id == newPerformerId); + var performerInDatabase = await dbContext.Performers.FirstWithIdAsync(newPerformerId); performerInDatabase.ArtistName.Should().BeNull(); performerInDatabase.BornAt.Should().Be(default); @@ -254,8 +252,7 @@ public async Task Can_create_resource_with_unknown_attribute() await _testContext.RunOnDatabaseAsync(async dbContext => { - var performerInDatabase = await dbContext.Playlists - .FirstAsync(playlist => playlist.Id == newPlaylistId); + var performerInDatabase = await dbContext.Playlists.FirstWithIdAsync(newPlaylistId); performerInDatabase.Name.Should().Be(newName); }); @@ -309,8 +306,7 @@ public async Task Can_create_resource_with_unknown_relationship() await _testContext.RunOnDatabaseAsync(async dbContext => { - var lyricInDatabase = await dbContext.Lyrics - .FirstAsync(lyric => lyric.Id == newLyricId); + var lyricInDatabase = await dbContext.Lyrics.FirstWithIdAsync(newLyricId); lyricInDatabase.Should().NotBeNull(); }); @@ -789,7 +785,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => .Include(musicTrack => musicTrack.Lyric) .Include(musicTrack => musicTrack.OwnedBy) .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + .FirstWithIdAsync(newTrackId); trackInDatabase.Title.Should().Be(newTitle); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs index c88b46ddcd..cd15f69a76 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs @@ -72,8 +72,7 @@ public async Task Can_create_resource_with_client_generated_guid_ID_having_side_ await _testContext.RunOnDatabaseAsync(async dbContext => { - var languageInDatabase = await dbContext.TextLanguages - .FirstAsync(language => language.Id == newLanguage.Id); + var languageInDatabase = await dbContext.TextLanguages.FirstWithIdAsync(newLanguage.Id); languageInDatabase.IsoCode.Should().Be(newLanguage.IsoCode); }); @@ -119,8 +118,7 @@ public async Task Can_create_resource_with_client_generated_string_ID_having_no_ await _testContext.RunOnDatabaseAsync(async dbContext => { - var trackInDatabase = await dbContext.MusicTracks - .FirstAsync(musicTrack => musicTrack.Id == newTrack.Id); + var trackInDatabase = await dbContext.MusicTracks.FirstWithIdAsync(newTrack.Id); trackInDatabase.Title.Should().Be(newTrack.Title); trackInDatabase.LengthInSeconds.Should().BeApproximately(newTrack.LengthInSeconds); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs index 8a17a44155..a7909fab5d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs @@ -94,7 +94,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + .FirstWithIdAsync(newTrackId); trackInDatabase.Performers.Should().HaveCount(2); trackInDatabase.Performers.Should().ContainSingle(performer => performer.Id == existingPerformers[0].Id); @@ -179,7 +179,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == newPlaylistId); + .FirstWithIdAsync(newPlaylistId); playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(3); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[0].Id); @@ -524,7 +524,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + .FirstWithIdAsync(newTrackId); trackInDatabase.Performers.Should().HaveCount(1); trackInDatabase.Performers[0].Id.Should().Be(existingPerformer.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs index 64cb1ce7d9..23c4d1a718 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs @@ -84,7 +84,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var lyricInDatabase = await dbContext.Lyrics .Include(lyric => lyric.Track) - .FirstAsync(lyric => lyric.Id == newLyricId); + .FirstWithIdAsync(newLyricId); lyricInDatabase.Track.Should().NotBeNull(); lyricInDatabase.Track.Id.Should().Be(existingTrack.Id); @@ -154,7 +154,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Lyric) - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + .FirstWithIdAsync(newTrackId); trackInDatabase.Lyric.Should().NotBeNull(); trackInDatabase.Lyric.Id.Should().Be(existingLyric.Id); @@ -556,7 +556,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + .FirstWithIdAsync(newTrackId); trackInDatabase.OwnedBy.Should().NotBeNull(); trackInDatabase.OwnedBy.Id.Should().Be(existingCompany.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs index 3ac37603f5..14464a777b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs @@ -65,8 +65,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var performerInDatabase = await dbContext.Performers - .FirstOrDefaultAsync(performer => performer.Id == existingPerformer.Id); + var performerInDatabase = await dbContext.Performers.FirstWithIdOrDefaultAsync(existingPerformer.Id); performerInDatabase.Should().BeNull(); }); @@ -166,13 +165,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var lyricsInDatabase = await dbContext.Lyrics - .FirstOrDefaultAsync(lyric => lyric.Id == existingLyric.Id); + var lyricsInDatabase = await dbContext.Lyrics.FirstWithIdOrDefaultAsync(existingLyric.Id); lyricsInDatabase.Should().BeNull(); - var trackInDatabase = await dbContext.MusicTracks - .FirstAsync(musicTrack => musicTrack.Id == existingLyric.Track.Id); + var trackInDatabase = await dbContext.MusicTracks.FirstWithIdAsync(existingLyric.Track.Id); trackInDatabase.Lyric.Should().BeNull(); }); @@ -219,13 +216,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var tracksInDatabase = await dbContext.MusicTracks - .FirstOrDefaultAsync(musicTrack => musicTrack.Id == existingTrack.Id); + var tracksInDatabase = await dbContext.MusicTracks.FirstWithIdOrDefaultAsync(existingTrack.Id); tracksInDatabase.Should().BeNull(); - var lyricInDatabase = await dbContext.Lyrics - .FirstAsync(lyric => lyric.Id == existingTrack.Lyric.Id); + var lyricInDatabase = await dbContext.Lyrics.FirstWithIdAsync(existingTrack.Lyric.Id); lyricInDatabase.Track.Should().BeNull(); }); @@ -272,8 +267,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var trackInDatabase = await dbContext.MusicTracks - .FirstOrDefaultAsync(musicTrack => musicTrack.Id == existingTrack.Id); + var trackInDatabase = await dbContext.MusicTracks.FirstWithIdOrDefaultAsync(existingTrack.Id); trackInDatabase.Should().BeNull(); @@ -328,8 +322,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var playlistInDatabase = await dbContext.Playlists - .FirstOrDefaultAsync(playlist => playlist.Id == existingPlaylistMusicTrack.Playlist.Id); + var playlistInDatabase = await dbContext.Playlists.FirstWithIdOrDefaultAsync(existingPlaylistMusicTrack.Playlist.Id); playlistInDatabase.Should().BeNull(); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs index 21042ece0b..62072be5e1 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs @@ -104,7 +104,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + .FirstWithIdAsync(newTrackId); trackInDatabase.Title.Should().Be(newTrackTitle); @@ -199,7 +199,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + .FirstWithIdAsync(newTrackId); trackInDatabase.Title.Should().Be(newTrackTitle); @@ -293,7 +293,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == newPlaylistId); + .FirstWithIdAsync(newPlaylistId); playlistInDatabase.Name.Should().Be(newPlaylistName); @@ -492,8 +492,7 @@ public async Task Can_update_resource_using_local_ID() await _testContext.RunOnDatabaseAsync(async dbContext => { - var trackInDatabase = await dbContext.MusicTracks - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + var trackInDatabase = await dbContext.MusicTracks.FirstWithIdAsync(newTrackId); trackInDatabase.Title.Should().Be(newTrackTitle); trackInDatabase.Genre.Should().Be(newTrackGenre); @@ -625,7 +624,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + .FirstWithIdAsync(newTrackId); trackInDatabase.Title.Should().Be(newTrackTitle); @@ -725,7 +724,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + .FirstWithIdAsync(newTrackId); trackInDatabase.Title.Should().Be(newTrackTitle); @@ -825,7 +824,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + .FirstWithIdAsync(newTrackId); trackInDatabase.Title.Should().Be(newTrackTitle); @@ -926,7 +925,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == newPlaylistId); + .FirstWithIdAsync(newPlaylistId); playlistInDatabase.Name.Should().Be(newPlaylistName); @@ -1048,7 +1047,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + .FirstWithIdAsync(newTrackId); trackInDatabase.Title.Should().Be(newTrackTitle); @@ -1171,7 +1170,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == newPlaylistId); + .FirstWithIdAsync(newPlaylistId); playlistInDatabase.Name.Should().Be(newPlaylistName); @@ -1293,7 +1292,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + .FirstWithIdAsync(newTrackId); trackInDatabase.Title.Should().Be(newTrackTitle); @@ -1440,7 +1439,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == newPlaylistId); + .FirstWithIdAsync(newPlaylistId); playlistInDatabase.Name.Should().Be(newPlaylistName); @@ -1597,7 +1596,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == newTrackId); + .FirstWithIdAsync(newTrackId); trackInDatabase.Title.Should().Be(newTrackTitle); @@ -1734,7 +1733,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == existingPlaylist.Id); + .FirstWithIdAsync(existingPlaylist.Id); playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1); playlistInDatabase.PlaylistMusicTracks[0].MusicTrack.Id.Should().Be(existingPlaylist.PlaylistMusicTracks[0].MusicTrack.Id); @@ -1799,8 +1798,7 @@ public async Task Can_delete_resource_using_local_ID() await _testContext.RunOnDatabaseAsync(async dbContext => { - var trackInDatabase = await dbContext.MusicTracks - .FirstOrDefaultAsync(musicTrack => musicTrack.Id == newTrackId); + var trackInDatabase = await dbContext.MusicTracks.FirstWithIdOrDefaultAsync(newTrackId); trackInDatabase.Should().BeNull(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs index e81789c80b..017d7f0b0d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs @@ -131,7 +131,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == newPlaylistId); + .FirstWithIdAsync(newPlaylistId); playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1); playlistInDatabase.PlaylistMusicTracks[0].MusicTrack.Id.Should().Be(existingTrack.Id); @@ -239,8 +239,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var trackInDatabase = await dbContext.MusicTracks - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + var trackInDatabase = await dbContext.MusicTracks.FirstWithIdAsync(existingTrack.Id); trackInDatabase.Title.Should().Be(existingTrack.Title); trackInDatabase.Genre.Should().Be(newTrackGenre); @@ -305,7 +304,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == existingPlaylist.Id); + .FirstWithIdAsync(existingPlaylist.Id); playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1); playlistInDatabase.PlaylistMusicTracks[0].MusicTrack.Id.Should().Be(existingTrack.Id); @@ -361,7 +360,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.OwnedBy.Should().NotBeNull(); trackInDatabase.OwnedBy.Id.Should().Be(existingCompany.Id); @@ -421,7 +420,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == existingPlaylist.Id); + .FirstWithIdAsync(existingPlaylist.Id); playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1); playlistInDatabase.PlaylistMusicTracks[0].MusicTrack.Id.Should().Be(existingTrack.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs index 180d2bda7b..55e1bdcb80 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs @@ -148,7 +148,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Performers.Should().HaveCount(3); trackInDatabase.Performers.Should().ContainSingle(performer => performer.Id == existingTrack.Performers[0].Id); @@ -237,7 +237,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == existingPlaylist.Id); + .FirstWithIdAsync(existingPlaylist.Id); playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(3); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingPlaylist.PlaylistMusicTracks[0].MusicTrack.Id); @@ -954,7 +954,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Performers.Should().HaveCount(1); trackInDatabase.Performers[0].Id.Should().Be(existingTrack.Performers[0].Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs index 9a51ede546..99f9a650cb 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs @@ -146,7 +146,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Performers.Should().HaveCount(1); trackInDatabase.Performers[0].Id.Should().Be(existingTrack.Performers[1].Id); @@ -242,7 +242,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == existingPlaylist.Id); + .FirstWithIdAsync(existingPlaylist.Id); playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1); playlistInDatabase.PlaylistMusicTracks[0].MusicTrack.Id.Should().Be(existingPlaylist.PlaylistMusicTracks[1].MusicTrack.Id); @@ -924,7 +924,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Performers.Should().HaveCount(1); trackInDatabase.Performers[0].Id.Should().Be(existingTrack.Performers[0].Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs index dee693b505..3c9eac6512 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs @@ -70,7 +70,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Performers.Should().BeEmpty(); @@ -136,7 +136,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == existingPlaylist.Id); + .FirstWithIdAsync(existingPlaylist.Id); playlistInDatabase.PlaylistMusicTracks.Should().BeEmpty(); @@ -206,7 +206,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Performers.Should().HaveCount(2); trackInDatabase.Performers.Should().ContainSingle(performer => performer.Id == existingPerformers[0].Id); @@ -285,7 +285,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == existingPlaylist.Id); + .FirstWithIdAsync(existingPlaylist.Id); playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(2); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[0].Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs index 1c5aa3454d..216878d00e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs @@ -69,7 +69,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var lyricInDatabase = await dbContext.Lyrics .Include(lyric => lyric.Track) - .FirstAsync(lyric => lyric.Id == existingLyric.Id); + .FirstWithIdAsync(existingLyric.Id); lyricInDatabase.Track.Should().BeNull(); @@ -124,7 +124,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Lyric) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Lyric.Should().BeNull(); @@ -179,7 +179,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.OwnedBy.Should().BeNull(); @@ -237,7 +237,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var lyricInDatabase = await dbContext.Lyrics .Include(lyric => lyric.Track) - .FirstAsync(lyric => lyric.Id == existingLyric.Id); + .FirstWithIdAsync(existingLyric.Id); lyricInDatabase.Track.Id.Should().Be(existingTrack.Id); }); @@ -292,7 +292,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Lyric) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Lyric.Id.Should().Be(existingLyric.Id); }); @@ -347,7 +347,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.OwnedBy.Id.Should().Be(existingCompany.Id); }); @@ -405,7 +405,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var lyricInDatabase = await dbContext.Lyrics .Include(lyric => lyric.Track) - .FirstAsync(lyric => lyric.Id == existingLyric.Id); + .FirstWithIdAsync(existingLyric.Id); lyricInDatabase.Track.Id.Should().Be(existingTrack.Id); @@ -466,7 +466,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Lyric) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Lyric.Id.Should().Be(existingLyric.Id); @@ -527,7 +527,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.OwnedBy.Id.Should().Be(existingCompany.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs index 37a0efa8e4..552729557c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs @@ -75,7 +75,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Performers.Should().BeEmpty(); @@ -146,7 +146,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == existingPlaylist.Id); + .FirstWithIdAsync(existingPlaylist.Id); playlistInDatabase.PlaylistMusicTracks.Should().BeEmpty(); @@ -221,7 +221,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Performers.Should().HaveCount(2); trackInDatabase.Performers.Should().ContainSingle(performer => performer.Id == existingPerformers[0].Id); @@ -305,7 +305,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) - .FirstAsync(playlist => playlist.Id == existingPlaylist.Id); + .FirstWithIdAsync(existingPlaylist.Id); playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(2); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[0].Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs index 80f4a70bfc..1c7fb688e3 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs @@ -141,7 +141,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Title.Should().Be(existingTrack.Title); trackInDatabase.Genre.Should().Be(existingTrack.Genre); @@ -197,8 +197,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var trackInDatabase = await dbContext.MusicTracks - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + var trackInDatabase = await dbContext.MusicTracks.FirstWithIdAsync(existingTrack.Id); trackInDatabase.Title.Should().Be(newTitle); }); @@ -303,7 +302,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Title.Should().Be(existingTrack.Title); trackInDatabase.LengthInSeconds.Should().Be(existingTrack.LengthInSeconds); @@ -370,7 +369,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Title.Should().Be(newTitle); trackInDatabase.LengthInSeconds.Should().Be(newLengthInSeconds); @@ -432,8 +431,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var languageInDatabase = await dbContext.TextLanguages - .FirstAsync(language => language.Id == existingLanguage.Id); + var languageInDatabase = await dbContext.TextLanguages.FirstWithIdAsync(existingLanguage.Id); languageInDatabase.IsoCode.Should().Be(newIsoCode); }); @@ -565,8 +563,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var performerInDatabase = await dbContext.Performers - .FirstAsync(performer => performer.Id == existingPerformer.Id); + var performerInDatabase = await dbContext.Performers.FirstWithIdAsync(existingPerformer.Id); performerInDatabase.ArtistName.Should().Be(newArtistName); performerInDatabase.BornAt.Should().BeCloseTo(existingPerformer.BornAt); @@ -1584,7 +1581,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => .Include(musicTrack => musicTrack.Lyric) .Include(musicTrack => musicTrack.OwnedBy) .Include(musicTrack => musicTrack.Performers) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Title.Should().Be(existingTrack.Title); trackInDatabase.Genre.Should().Be(newGenre); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs index c62aa3b51b..f3069f8f07 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs @@ -74,7 +74,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var lyricInDatabase = await dbContext.Lyrics .Include(lyric => lyric.Track) - .FirstAsync(lyric => lyric.Id == existingLyric.Id); + .FirstWithIdAsync(existingLyric.Id); lyricInDatabase.Track.Should().BeNull(); @@ -134,7 +134,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Lyric) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Lyric.Should().BeNull(); @@ -194,7 +194,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.OwnedBy.Should().BeNull(); @@ -257,7 +257,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var lyricInDatabase = await dbContext.Lyrics .Include(lyric => lyric.Track) - .FirstAsync(lyric => lyric.Id == existingLyric.Id); + .FirstWithIdAsync(existingLyric.Id); lyricInDatabase.Track.Id.Should().Be(existingTrack.Id); }); @@ -317,7 +317,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Lyric) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Lyric.Id.Should().Be(existingLyric.Id); }); @@ -377,7 +377,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.OwnedBy.Id.Should().Be(existingCompany.Id); }); @@ -440,7 +440,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var lyricInDatabase = await dbContext.Lyrics .Include(lyric => lyric.Track) - .FirstAsync(lyric => lyric.Id == existingLyric.Id); + .FirstWithIdAsync(existingLyric.Id); lyricInDatabase.Track.Id.Should().Be(existingTrack.Id); @@ -506,7 +506,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Lyric) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.Lyric.Id.Should().Be(existingLyric.Id); @@ -572,7 +572,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) - .FirstAsync(musicTrack => musicTrack.Id == existingTrack.Id); + .FirstWithIdAsync(existingTrack.Id); trackInDatabase.OwnedBy.Id.Should().Be(existingCompany.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeKeyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeKeyTests.cs index 952cba65f5..b8a74e6232 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeKeyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeKeyTests.cs @@ -245,7 +245,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var engineInDatabase = await dbContext.Engines .Include(engine => engine.Car) - .FirstAsync(engine => engine.Id == existingEngine.Id); + .FirstWithIdAsync(existingEngine.Id); engineInDatabase.Car.Should().NotBeNull(); engineInDatabase.Car.Id.Should().Be(existingCar.StringId); @@ -303,7 +303,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var engineInDatabase = await dbContext.Engines .Include(engine => engine.Car) - .FirstAsync(engine => engine.Id == existingEngine.Id); + .FirstWithIdAsync(existingEngine.Id); engineInDatabase.Car.Should().BeNull(); }); @@ -364,7 +364,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var dealershipInDatabase = await dbContext.Dealerships .Include(dealership => dealership.Inventory) - .FirstOrDefaultAsync(dealership => dealership.Id == existingDealership.Id); + .FirstWithIdOrDefaultAsync(existingDealership.Id); dealershipInDatabase.Inventory.Should().HaveCount(1); dealershipInDatabase.Inventory.Should().ContainSingle(car => car.Id == existingDealership.Inventory.ElementAt(1).Id); @@ -418,7 +418,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var dealershipInDatabase = await dbContext.Dealerships .Include(dealership => dealership.Inventory) - .FirstOrDefaultAsync(dealership => dealership.Id == existingDealership.Id); + .FirstWithIdOrDefaultAsync(existingDealership.Id); dealershipInDatabase.Inventory.Should().HaveCount(1); dealershipInDatabase.Inventory.Should().ContainSingle(car => car.Id == existingCar.Id); @@ -491,7 +491,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var dealershipInDatabase = await dbContext.Dealerships .Include(dealership => dealership.Inventory) - .FirstOrDefaultAsync(dealership => dealership.Id == existingDealership.Id); + .FirstWithIdOrDefaultAsync(existingDealership.Id); dealershipInDatabase.Inventory.Should().HaveCount(2); dealershipInDatabase.Inventory.Should().ContainSingle(car => car.Id == existingCar.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingTests.cs index 4529e06313..bb8ee2fe4f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingTests.cs @@ -238,7 +238,7 @@ public async Task Can_create_resource() responseDocument.SingleData.Attributes["primaryDoorColor"].Should().BeNull(); responseDocument.SingleData.Attributes["secondaryDoorColor"].Should().BeNull(); - var newId = int.Parse(responseDocument.SingleData.Id); + var newBuildingId = int.Parse(responseDocument.SingleData.Id); await _testContext.RunOnDatabaseAsync(async dbContext => { @@ -246,7 +246,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => .Include(building => building.PrimaryDoor) .Include(building => building.SecondaryDoor) .Include(building => building.Windows) - .FirstOrDefaultAsync(building => building.Id == newId); + .FirstWithIdOrDefaultAsync(newBuildingId); buildingInDatabase.Should().NotBeNull(); buildingInDatabase.Number.Should().Be(newBuilding.Number); @@ -304,7 +304,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => .Include(building => building.PrimaryDoor) .Include(building => building.SecondaryDoor) .Include(building => building.Windows) - .FirstOrDefaultAsync(building => building.Id == existingBuilding.Id); + .FirstWithIdOrDefaultAsync(existingBuilding.Id); buildingInDatabase.Should().NotBeNull(); buildingInDatabase.Number.Should().Be(newBuildingNumber); @@ -340,8 +340,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var buildingInDatabase = await dbContext.Buildings - .FirstOrDefaultAsync(building => building.Id == existingBuilding.Id); + var buildingInDatabase = await dbContext.Buildings.FirstWithIdOrDefaultAsync(existingBuilding.Id); buildingInDatabase.Should().BeNull(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs index 3223f5f5a0..626f9e2c7e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs @@ -249,7 +249,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var debitCardInDatabase = await dbContext.DebitCards .Include(debitCard => debitCard.Account) - .FirstAsync(debitCard => debitCard.Id == newDebitCardId); + .FirstWithIdAsync(newDebitCardId); debitCardInDatabase.OwnerName.Should().Be(newDebitCard.OwnerName); debitCardInDatabase.PinCode.Should().Be(newDebitCard.PinCode); @@ -318,7 +318,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var bankAccountInDatabase = await dbContext.BankAccounts .Include(bankAccount => bankAccount.Cards) - .FirstAsync(bankAccount => bankAccount.Id == existingBankAccount.Id); + .FirstWithIdAsync(existingBankAccount.Id); bankAccountInDatabase.Iban.Should().Be(newIban); @@ -370,7 +370,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var bankAccountInDatabase = await dbContext.BankAccounts .Include(bankAccount => bankAccount.Cards) - .FirstAsync(bankAccount => bankAccount.Id == existingBankAccount.Id); + .FirstWithIdAsync(existingBankAccount.Id); bankAccountInDatabase.Cards.Should().HaveCount(2); }); @@ -415,7 +415,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var bankAccountInDatabase = await dbContext.BankAccounts .Include(bankAccount => bankAccount.Cards) - .FirstAsync(bankAccount => bankAccount.Id == existingBankAccount.Id); + .FirstWithIdAsync(existingBankAccount.Id); bankAccountInDatabase.Cards.Should().HaveCount(1); }); @@ -448,7 +448,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var bankAccountInDatabase = await dbContext.BankAccounts .Include(bankAccount => bankAccount.Cards) - .FirstOrDefaultAsync(bankAccount => bankAccount.Id == existingBankAccount.Id); + .FirstWithIdOrDefaultAsync(existingBankAccount.Id); bankAccountInDatabase.Should().BeNull(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs index 64cf57ee1c..7b225af336 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs @@ -127,8 +127,7 @@ public async Task Can_create_resource() await _testContext.RunOnDatabaseAsync(async dbContext => { - var poolInDatabase = await dbContext.SwimmingPools - .FirstAsync(pool => pool.Id == newPoolId); + var poolInDatabase = await dbContext.SwimmingPools.FirstWithIdAsync(newPoolId); poolInDatabase.IsIndoor.Should().Be(newPool.IsIndoor); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs index 425404563c..f15402de58 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs @@ -102,8 +102,7 @@ public async Task Can_create_resource_with_int_ID() await _testContext.RunOnDatabaseAsync(async dbContext => { - var workItemInDatabase = await dbContext.WorkItems - .FirstAsync(workItem => workItem.Id == newWorkItemId); + var workItemInDatabase = await dbContext.WorkItems.FirstWithIdAsync(newWorkItemId); workItemInDatabase.Description.Should().Be(newWorkItem.Description); workItemInDatabase.DueAt.Should().Be(newWorkItem.DueAt); @@ -150,8 +149,7 @@ public async Task Can_create_resource_with_long_ID() await _testContext.RunOnDatabaseAsync(async dbContext => { - var userAccountInDatabase = await dbContext.UserAccounts - .FirstAsync(userAccount => userAccount.Id == newUserAccountId); + var userAccountInDatabase = await dbContext.UserAccounts.FirstWithIdAsync(newUserAccountId); userAccountInDatabase.FirstName.Should().Be(newUserAccount.FirstName); userAccountInDatabase.LastName.Should().Be(newUserAccount.LastName); @@ -196,8 +194,7 @@ public async Task Can_create_resource_with_guid_ID() await _testContext.RunOnDatabaseAsync(async dbContext => { - var groupInDatabase = await dbContext.Groups - .FirstAsync(group => group.Id == newGroupId); + var groupInDatabase = await dbContext.Groups.FirstWithIdAsync(newGroupId); groupInDatabase.Name.Should().Be(newGroup.Name); }); @@ -242,8 +239,7 @@ public async Task Can_create_resource_without_attributes_or_relationships() await _testContext.RunOnDatabaseAsync(async dbContext => { - var workItemInDatabase = await dbContext.WorkItems - .FirstAsync(workItem => workItem.Id == newWorkItemId); + var workItemInDatabase = await dbContext.WorkItems.FirstWithIdAsync(newWorkItemId); workItemInDatabase.Description.Should().BeNull(); workItemInDatabase.DueAt.Should().BeNull(); @@ -286,8 +282,7 @@ public async Task Can_create_resource_with_unknown_attribute() await _testContext.RunOnDatabaseAsync(async dbContext => { - var workItemInDatabase = await dbContext.WorkItems - .FirstAsync(workItem => workItem.Id == newWorkItemId); + var workItemInDatabase = await dbContext.WorkItems.FirstWithIdAsync(newWorkItemId); workItemInDatabase.Description.Should().Be(newWorkItem.Description); }); @@ -333,8 +328,7 @@ public async Task Can_create_resource_with_unknown_relationship() await _testContext.RunOnDatabaseAsync(async dbContext => { - var workItemInDatabase = await dbContext.WorkItems - .FirstOrDefaultAsync(workItem => workItem.Id == newWorkItemId); + var workItemInDatabase = await dbContext.WorkItems.FirstWithIdOrDefaultAsync(newWorkItemId); workItemInDatabase.Should().NotBeNull(); }); @@ -712,7 +706,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => .Include(workItem => workItem.Subscribers) .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) - .FirstAsync(workItem => workItem.Id == newWorkItemId); + .FirstWithIdAsync(newWorkItemId); workItemInDatabase.Description.Should().Be(newDescription); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs index cb1141eaa9..eb63565446 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs @@ -63,8 +63,7 @@ public async Task Can_create_resource_with_client_generated_guid_ID_having_side_ await _testContext.RunOnDatabaseAsync(async dbContext => { - var groupInDatabase = await dbContext.Groups - .FirstAsync(group => group.Id == newGroup.Id); + var groupInDatabase = await dbContext.Groups.FirstWithIdAsync(newGroup.Id); groupInDatabase.Name.Should().Be(newGroup.Name); }); @@ -110,8 +109,7 @@ public async Task Can_create_resource_with_client_generated_guid_ID_having_side_ await _testContext.RunOnDatabaseAsync(async dbContext => { - var groupInDatabase = await dbContext.Groups - .FirstAsync(group => group.Id == newGroup.Id); + var groupInDatabase = await dbContext.Groups.FirstWithIdAsync(newGroup.Id); groupInDatabase.Name.Should().Be(newGroup.Name); }); @@ -151,8 +149,7 @@ public async Task Can_create_resource_with_client_generated_string_ID_having_no_ await _testContext.RunOnDatabaseAsync(async dbContext => { - var colorInDatabase = await dbContext.RgbColors - .FirstAsync(color => color.Id == newColor.Id); + var colorInDatabase = await dbContext.RgbColors.FirstWithIdAsync(newColor.Id); colorInDatabase.DisplayName.Should().Be(newColor.DisplayName); }); @@ -192,8 +189,7 @@ public async Task Can_create_resource_with_client_generated_string_ID_having_no_ await _testContext.RunOnDatabaseAsync(async dbContext => { - var colorInDatabase = await dbContext.RgbColors - .FirstAsync(color => color.Id == newColor.Id); + var colorInDatabase = await dbContext.RgbColors.FirstWithIdAsync(newColor.Id); colorInDatabase.DisplayName.Should().Be(newColor.DisplayName); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs index ba40c1c284..2e6788e33f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs @@ -79,7 +79,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == newWorkItemId); + .FirstWithIdAsync(newWorkItemId); workItemInDatabase.Subscribers.Should().HaveCount(2); workItemInDatabase.Subscribers.Should().ContainSingle(subscriber => subscriber.Id == existingUserAccounts[0].Id); @@ -152,7 +152,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == newWorkItemId); + .FirstWithIdAsync(newWorkItemId); workItemInDatabase.Subscribers.Should().HaveCount(2); workItemInDatabase.Subscribers.Should().ContainSingle(userAccount => userAccount.Id == existingUserAccounts[0].Id); @@ -225,7 +225,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == newWorkItemId); + .FirstWithIdAsync(newWorkItemId); workItemInDatabase.Subscribers.Should().HaveCount(2); workItemInDatabase.Subscribers.Should().ContainSingle(userAccount => userAccount.Id == existingUserAccounts[0].Id); @@ -316,7 +316,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) - .FirstAsync(workItem => workItem.Id == newWorkItemId); + .FirstWithIdAsync(newWorkItemId); workItemInDatabase.WorkItemTags.Should().HaveCount(3); workItemInDatabase.WorkItemTags.Should().ContainSingle(workItemTag => workItemTag.Tag.Id == existingTags[0].Id); @@ -604,7 +604,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == newWorkItemId); + .FirstWithIdAsync(newWorkItemId); workItemInDatabase.Subscribers.Should().HaveCount(1); workItemInDatabase.Subscribers.Single().Id.Should().Be(existingUserAccount.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs index 6bdfd7d80e..f743459eed 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs @@ -206,7 +206,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Assignee) - .FirstAsync(workItem => workItem.Id == newWorkItemId); + .FirstWithIdAsync(newWorkItemId); workItemInDatabase.Assignee.Should().NotBeNull(); workItemInDatabase.Assignee.Id.Should().Be(existingUserAccount.Id); @@ -277,7 +277,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Assignee) - .FirstAsync(workItem => workItem.Id == newWorkItemId); + .FirstWithIdAsync(newWorkItemId); workItemInDatabase.Description.Should().Be(newWorkItem.Description); workItemInDatabase.Priority.Should().Be(newWorkItem.Priority); @@ -545,7 +545,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Assignee) - .FirstAsync(workItem => workItem.Id == newWorkItemId); + .FirstWithIdAsync(newWorkItemId); workItemInDatabase.Assignee.Should().NotBeNull(); workItemInDatabase.Assignee.Id.Should().Be(existingUserAccounts[1].Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs index 4b516ee6cc..cd3ed15de7 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Deleting/DeleteResourceTests.cs @@ -45,8 +45,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var workItemsInDatabase = await dbContext.WorkItems - .FirstOrDefaultAsync(workItem => workItem.Id == existingWorkItem.Id); + var workItemsInDatabase = await dbContext.WorkItems.FirstWithIdOrDefaultAsync(existingWorkItem.Id); workItemsInDatabase.Should().BeNull(); }); @@ -97,13 +96,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var colorsInDatabase = await dbContext.RgbColors - .FirstOrDefaultAsync(color => color.Id == existingColor.Id); + var colorsInDatabase = await dbContext.RgbColors.FirstWithIdOrDefaultAsync(existingColor.Id); colorsInDatabase.Should().BeNull(); - var groupInDatabase = await dbContext.Groups - .FirstAsync(group => group.Id == existingColor.Group.Id); + var groupInDatabase = await dbContext.Groups.FirstWithIdAsync(existingColor.Group.Id); groupInDatabase.Color.Should().BeNull(); }); @@ -134,13 +131,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var groupsInDatabase = await dbContext.Groups - .FirstOrDefaultAsync(group => group.Id == existingGroup.Id); + var groupsInDatabase = await dbContext.Groups.FirstWithIdOrDefaultAsync(existingGroup.Id); groupsInDatabase.Should().BeNull(); - var colorInDatabase = await dbContext.RgbColors - .FirstOrDefaultAsync(color => color.Id == existingGroup.Color.Id); + var colorInDatabase = await dbContext.RgbColors.FirstWithIdOrDefaultAsync(existingGroup.Color.Id); colorInDatabase.Should().NotBeNull(); colorInDatabase.Group.Should().BeNull(); @@ -172,8 +167,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var workItemInDatabase = await dbContext.WorkItems - .FirstOrDefaultAsync(workItem => workItem.Id == existingWorkItem.Id); + var workItemInDatabase = await dbContext.WorkItems.FirstWithIdOrDefaultAsync(existingWorkItem.Id); workItemInDatabase.Should().BeNull(); @@ -212,8 +206,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var workItemsInDatabase = await dbContext.WorkItems - .FirstOrDefaultAsync(workItem => workItem.Id == existingWorkItemTag.Item.Id); + var workItemsInDatabase = await dbContext.WorkItems.FirstWithIdOrDefaultAsync(existingWorkItemTag.Item.Id); workItemsInDatabase.Should().BeNull(); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs index 6108d04f81..7689a8b788 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs @@ -106,7 +106,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Subscribers.Should().HaveCount(3); workItemInDatabase.Subscribers.Should().ContainSingle(subscriber => subscriber.Id == existingWorkItem.Subscribers.ElementAt(0).Id); @@ -637,7 +637,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Subscribers.Should().HaveCount(1); workItemInDatabase.Subscribers.Single().Id.Should().Be(existingSubscriber.Id); @@ -675,7 +675,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Subscribers.Should().HaveCount(0); }); @@ -786,7 +786,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Children) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Children.Should().HaveCount(2); workItemInDatabase.Children.Should().ContainSingle(workItem => workItem.Id == existingWorkItem.Children[0].Id); @@ -840,7 +840,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.RelatedToItems) .ThenInclude(workItemToWorkItem => workItemToWorkItem.ToItem) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.RelatedToItems.Should().HaveCount(2); workItemInDatabase.RelatedToItems.Should().OnlyContain(workItemToWorkItem => workItemToWorkItem.FromItem.Id == existingWorkItem.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs index 0516488857..0bc10db0a3 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs @@ -106,7 +106,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Subscribers.Should().HaveCount(1); workItemInDatabase.Subscribers.Single().Id.Should().Be(existingWorkItem.Subscribers.ElementAt(1).Id); @@ -173,7 +173,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.WorkItemTags.Should().HaveCount(1); workItemInDatabase.WorkItemTags.Single().Tag.Id.Should().Be(existingWorkItem.WorkItemTags.ElementAt(0).Tag.Id); @@ -632,7 +632,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Subscribers.Should().HaveCount(1); workItemInDatabase.Subscribers.Single().Id.Should().Be(existingWorkItem.Subscribers.ElementAt(1).Id); @@ -671,7 +671,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Subscribers.Should().HaveCount(1); workItemInDatabase.Subscribers.Single().Id.Should().Be(existingWorkItem.Subscribers.ElementAt(0).Id); @@ -786,7 +786,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Children) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Children.Should().HaveCount(1); workItemInDatabase.Children[0].Id.Should().Be(existingWorkItem.Children[0].Id); @@ -845,7 +845,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.RelatedFromItems) .ThenInclude(workItemToWorkItem => workItemToWorkItem.FromItem) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.RelatedFromItems.Should().HaveCount(1); workItemInDatabase.RelatedFromItems[0].FromItem.Id.Should().Be(existingWorkItem.RelatedFromItems[0].FromItem.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs index 201973ef01..d8cc7418aa 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs @@ -54,7 +54,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Subscribers.Should().BeEmpty(); }); @@ -99,7 +99,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.WorkItemTags.Should().BeEmpty(); }); @@ -151,7 +151,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Subscribers.Should().HaveCount(2); workItemInDatabase.Subscribers.Should().ContainSingle(userAccount => userAccount.Id == existingWorkItem.Subscribers.ElementAt(1).Id); @@ -222,7 +222,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.WorkItemTags.Should().HaveCount(3); workItemInDatabase.WorkItemTags.Should().ContainSingle(workItemTag => workItemTag.Tag.Id == existingWorkItem.WorkItemTags.ElementAt(0).Tag.Id); @@ -675,7 +675,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Subscribers.Should().HaveCount(1); workItemInDatabase.Subscribers.Single().Id.Should().Be(existingSubscriber.Id); @@ -785,7 +785,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Children) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Children.Should().BeEmpty(); }); @@ -832,7 +832,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.RelatedFromItems) .ThenInclude(workItemToWorkItem => workItemToWorkItem.FromItem) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.RelatedFromItems.Should().BeEmpty(); }); @@ -876,7 +876,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Children) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Children.Should().HaveCount(1); workItemInDatabase.Children[0].Id.Should().Be(existingWorkItem.Id); @@ -922,7 +922,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.RelatedToItems) .ThenInclude(workItemToWorkItem => workItemToWorkItem.ToItem) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.RelatedToItems.Should().HaveCount(1); workItemInDatabase.RelatedToItems[0].FromItem.Id.Should().Be(existingWorkItem.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs index 1ba7a51671..e172e6a1e6 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs @@ -53,7 +53,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Assignee) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Assignee.Should().BeNull(); }); @@ -91,7 +91,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var groupInDatabase = await dbContext.Groups .Include(group => group.Color) - .FirstOrDefaultAsync(group => group.Id == existingGroup.Id); + .FirstWithIdOrDefaultAsync(existingGroup.Id); groupInDatabase.Color.Should().BeNull(); }); @@ -238,9 +238,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + int itemId = existingUserAccounts[0].AssignedItems.ElementAt(1).Id; + var workItemInDatabase2 = await dbContext.WorkItems .Include(workItem => workItem.Assignee) - .FirstAsync(workItem => workItem.Id == existingUserAccounts[0].AssignedItems.ElementAt(1).Id); + .FirstWithIdAsync(itemId); workItemInDatabase2.Assignee.Should().NotBeNull(); workItemInDatabase2.Assignee.Id.Should().Be(existingUserAccounts[1].Id); @@ -643,7 +645,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Parent) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Parent.Should().BeNull(); }); @@ -684,7 +686,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Parent) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Parent.Should().NotBeNull(); workItemInDatabase.Parent.Id.Should().Be(existingWorkItem.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs index 09f39f6e14..b4aa461aec 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs @@ -65,7 +65,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Subscribers.Should().BeEmpty(); }); @@ -121,7 +121,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.WorkItemTags.Should().BeEmpty(); }); @@ -184,7 +184,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Subscribers.Should().HaveCount(2); workItemInDatabase.Subscribers.Should().ContainSingle(userAccount => userAccount.Id == existingWorkItem.Subscribers.ElementAt(1).Id); @@ -266,7 +266,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.WorkItemTags.Should().HaveCount(3); workItemInDatabase.WorkItemTags.Should().ContainSingle(workItemTag => workItemTag.Tag.Id == existingWorkItem.WorkItemTags.ElementAt(0).Tag.Id); @@ -336,7 +336,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Subscribers.Should().HaveCount(1); workItemInDatabase.Subscribers.Single().Id.Should().Be(existingUserAccount.Id); @@ -410,7 +410,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) - .FirstAsync(workItem => workItem.Id == newWorkItemId); + .FirstWithIdAsync(newWorkItemId); workItemInDatabase.WorkItemTags.Should().HaveCount(1); workItemInDatabase.WorkItemTags.Single().Tag.Id.Should().Be(existingTag.Id); @@ -763,7 +763,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Subscribers) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Subscribers.Should().HaveCount(1); workItemInDatabase.Subscribers.Single().Id.Should().Be(existingSubscriber.Id); @@ -906,7 +906,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Children) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Children.Should().BeEmpty(); }); @@ -964,7 +964,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.RelatedFromItems) .ThenInclude(workItemToWorkItem => workItemToWorkItem.FromItem) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.RelatedFromItems.Should().BeEmpty(); }); @@ -1019,7 +1019,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Children) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Children.Should().HaveCount(1); workItemInDatabase.Children[0].Id.Should().Be(existingWorkItem.Id); @@ -1076,7 +1076,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.RelatedToItems) .ThenInclude(workItemToWorkItem => workItemToWorkItem.ToItem) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.RelatedToItems.Should().HaveCount(1); workItemInDatabase.RelatedToItems[0].FromItem.Id.Should().Be(existingWorkItem.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs index 92c2cd8e95..02ee7851ac 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs @@ -63,8 +63,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var userAccountInDatabase = await dbContext.UserAccounts - .FirstAsync(userAccount => userAccount.Id == existingUserAccount.Id); + var userAccountInDatabase = await dbContext.UserAccounts.FirstWithIdAsync(existingUserAccount.Id); userAccountInDatabase.FirstName.Should().Be(existingUserAccount.FirstName); userAccountInDatabase.LastName.Should().Be(existingUserAccount.LastName); @@ -110,8 +109,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var userAccountInDatabase = await dbContext.UserAccounts - .FirstAsync(userAccount => userAccount.Id == existingUserAccount.Id); + var userAccountInDatabase = await dbContext.UserAccounts.FirstWithIdAsync(existingUserAccount.Id); userAccountInDatabase.FirstName.Should().Be(newFirstName); userAccountInDatabase.LastName.Should().Be(existingUserAccount.LastName); @@ -204,8 +202,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var groupInDatabase = await dbContext.Groups - .FirstAsync(group => group.Id == existingGroup.Id); + var groupInDatabase = await dbContext.Groups.FirstWithIdAsync(existingGroup.Id); groupInDatabase.Name.Should().Be(newName); groupInDatabase.IsPublic.Should().Be(existingGroup.IsPublic); @@ -253,8 +250,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var colorInDatabase = await dbContext.RgbColors - .FirstAsync(color => color.Id == existingColor.Id); + var colorInDatabase = await dbContext.RgbColors.FirstWithIdAsync(existingColor.Id); colorInDatabase.DisplayName.Should().Be(newDisplayName); }); @@ -302,8 +298,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var userAccountInDatabase = await dbContext.UserAccounts - .FirstAsync(userAccount => userAccount.Id == existingUserAccount.Id); + var userAccountInDatabase = await dbContext.UserAccounts.FirstWithIdAsync(existingUserAccount.Id); userAccountInDatabase.FirstName.Should().Be(newUserAccount.FirstName); userAccountInDatabase.LastName.Should().Be(newUserAccount.LastName); @@ -356,8 +351,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var workItemInDatabase = await dbContext.WorkItems - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + var workItemInDatabase = await dbContext.WorkItems.FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Description.Should().Be(newDescription); workItemInDatabase.DueAt.Should().BeNull(); @@ -410,8 +404,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var workItemInDatabase = await dbContext.WorkItems - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + var workItemInDatabase = await dbContext.WorkItems.FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Description.Should().Be(newDescription); workItemInDatabase.DueAt.Should().BeNull(); @@ -481,8 +474,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var workItemInDatabase = await dbContext.WorkItems - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + var workItemInDatabase = await dbContext.WorkItems.FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Description.Should().Be(newDescription); workItemInDatabase.DueAt.Should().BeNull(); @@ -1087,7 +1079,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => .Include(workItem => workItem.Subscribers) .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Description.Should().Be(newDescription); @@ -1182,7 +1174,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => .Include(workItem => workItem.Children) .Include(workItem => workItem.RelatedToItems) .ThenInclude(workItemToWorkItem => workItemToWorkItem.ToItem) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Parent.Should().NotBeNull(); workItemInDatabase.Parent.Id.Should().Be(existingWorkItem.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs index 6541000a47..8d461c2c0f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs @@ -64,7 +64,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Assignee) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Assignee.Should().BeNull(); }); @@ -243,7 +243,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var colorInDatabase = await dbContext.RgbColors .Include(color => color.Group) - .FirstOrDefaultAsync(color => color.Id == existingColor.Id); + .FirstWithIdOrDefaultAsync(existingColor.Id); colorInDatabase.Group.Should().BeNull(); }); @@ -293,9 +293,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + int itemId = existingUserAccounts[0].AssignedItems.ElementAt(1).Id; + var workItemInDatabase2 = await dbContext.WorkItems .Include(workItem => workItem.Assignee) - .FirstAsync(workItem => workItem.Id == existingUserAccounts[0].AssignedItems.ElementAt(1).Id); + .FirstWithIdAsync(itemId); workItemInDatabase2.Assignee.Should().NotBeNull(); workItemInDatabase2.Assignee.Id.Should().Be(existingUserAccounts[1].Id); @@ -360,7 +362,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Assignee) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Assignee.Should().NotBeNull(); workItemInDatabase.Assignee.Id.Should().Be(existingUserAccount.Id); @@ -429,7 +431,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Assignee) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Assignee.Should().NotBeNull(); workItemInDatabase.Assignee.Id.Should().Be(existingUserAccount.Id); @@ -771,7 +773,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Parent) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Parent.Should().BeNull(); }); @@ -823,7 +825,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Parent) - .FirstAsync(workItem => workItem.Id == existingWorkItem.Id); + .FirstWithIdAsync(existingWorkItem.Id); workItemInDatabase.Parent.Should().NotBeNull(); workItemInDatabase.Parent.Id.Should().Be(existingWorkItem.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs index e04fbd4117..3f06344a9e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs @@ -118,10 +118,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var existingCustomerInDatabase = await dbContext.Customers.FirstOrDefaultAsync(customer => customer.Id == existingOrder.Customer.Id); + var existingCustomerInDatabase = await dbContext.Customers.FirstWithIdOrDefaultAsync(existingOrder.Customer.Id); existingCustomerInDatabase.Should().BeNull(); - var existingOrderInDatabase = await dbContext.Orders.FirstOrDefaultAsync(order => order.Id == existingOrder.Id); + var existingOrderInDatabase = await dbContext.Orders.FirstWithIdOrDefaultAsync(existingOrder.Id); existingOrderInDatabase.Should().BeNull(); }); } @@ -152,13 +152,13 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var existingOrderInDatabase = await dbContext.Orders.FirstOrDefaultAsync(order => order.Id == existingOrder.Id); + var existingOrderInDatabase = await dbContext.Orders.FirstWithIdOrDefaultAsync(existingOrder.Id); existingOrderInDatabase.Should().BeNull(); - var existingShipmentInDatabase = await dbContext.Shipments.FirstOrDefaultAsync(shipment => shipment.Id == existingOrder.Shipment.Id); + var existingShipmentInDatabase = await dbContext.Shipments.FirstWithIdOrDefaultAsync(existingOrder.Shipment.Id); existingShipmentInDatabase.Should().BeNull(); - var existingCustomerInDatabase = await dbContext.Customers.FirstOrDefaultAsync(customer => customer.Id == existingOrder.Customer.Id); + var existingCustomerInDatabase = await dbContext.Customers.FirstWithIdOrDefaultAsync(existingOrder.Customer.Id); existingCustomerInDatabase.Should().NotBeNull(); }); } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs index 5c2bcd29fa..240805b95c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs @@ -185,7 +185,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var certificateInDatabase = await dbContext.GiftCertificates .Include(giftCertificate => giftCertificate.Issuer) - .FirstAsync(giftCertificate => giftCertificate.Id == newCertificateId); + .FirstWithIdAsync(newCertificateId); certificateInDatabase.IssueDate.Should().Be(newIssueDate); @@ -253,7 +253,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var officeInDatabase = await dbContext.PostOffice .Include(postOffice => postOffice.GiftCertificates) - .FirstAsync(postOffice => postOffice.Id == existingOffice.Id); + .FirstWithIdAsync(existingOffice.Id); officeInDatabase.Address.Should().Be(newAddress); @@ -286,8 +286,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var officeInDatabase = await dbContext.PostOffice - .FirstOrDefaultAsync(postOffice => postOffice.Id == existingOffice.Id); + var officeInDatabase = await dbContext.PostOffice.FirstWithIdOrDefaultAsync(existingOffice.Id); officeInDatabase.Should().BeNull(); }); @@ -354,7 +353,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var officeInDatabase = await dbContext.PostOffice .Include(postOffice => postOffice.GiftCertificates) - .FirstAsync(postOffice => postOffice.Id == existingOffice.Id); + .FirstWithIdAsync(existingOffice.Id); officeInDatabase.GiftCertificates.Should().HaveCount(2); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs index eb6d2d92bb..b519f6c977 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs @@ -71,7 +71,7 @@ public async Task Can_create_user_with_password() await _testContext.RunOnDatabaseAsync(async dbContext => { - var userInDatabase = await dbContext.Users.FirstAsync(user => user.Id == responseUser.Id); + var userInDatabase = await dbContext.Users.FirstWithIdAsync(responseUser.Id); userInDatabase.UserName.Should().Be(newUser.UserName); userInDatabase.Password.Should().Be(newUser.Password); @@ -108,7 +108,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var userInDatabase = await dbContext.Users.FirstAsync(user => user.Id == existingUser.Id); + var userInDatabase = await dbContext.Users.FirstWithIdAsync(existingUser.Id); userInDatabase.Password.Should().Be(existingUser.Password); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs index fc8d4fcbfa..441e7fa78f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs @@ -63,8 +63,7 @@ public async Task Can_create_resource_with_inherited_attributes() await _testContext.RunOnDatabaseAsync(async dbContext => { - var manInDatabase = await dbContext.Men - .FirstAsync(man => man.Id == newManId); + var manInDatabase = await dbContext.Men.FirstWithIdAsync(newManId); manInDatabase.FamilyName.Should().Be(newMan.FamilyName); manInDatabase.IsRetired.Should().Be(newMan.IsRetired); @@ -119,7 +118,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var manInDatabase = await dbContext.Men .Include(man => man.HealthInsurance) - .FirstAsync(man => man.Id == newManId); + .FirstWithIdAsync(newManId); manInDatabase.HealthInsurance.Should().BeOfType(); manInDatabase.HealthInsurance.Id.Should().Be(existingInsurance.Id); @@ -177,8 +176,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var manInDatabase = await dbContext.Men - .FirstAsync(man => man.Id == existingMan.Id); + var manInDatabase = await dbContext.Men.FirstWithIdAsync(existingMan.Id); manInDatabase.FamilyName.Should().Be(newMan.FamilyName); manInDatabase.IsRetired.Should().Be(newMan.IsRetired); @@ -223,7 +221,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var manInDatabase = await dbContext.Men .Include(man => man.HealthInsurance) - .FirstAsync(man => man.Id == existingMan.Id); + .FirstWithIdAsync(existingMan.Id); manInDatabase.HealthInsurance.Should().BeOfType(); manInDatabase.HealthInsurance.Id.Should().Be(existingInsurance.Id); @@ -286,7 +284,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var manInDatabase = await dbContext.Men .Include(man => man.Parents) - .FirstAsync(man => man.Id == newManId); + .FirstWithIdAsync(newManId); manInDatabase.Parents.Should().HaveCount(2); manInDatabase.Parents.Should().ContainSingle(human => human is Man); @@ -340,7 +338,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var manInDatabase = await dbContext.Men .Include(man => man.Parents) - .FirstAsync(man => man.Id == existingChild.Id); + .FirstWithIdAsync(existingChild.Id); manInDatabase.Parents.Should().HaveCount(2); manInDatabase.Parents.Should().ContainSingle(human => human is Man); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs index 5d81b3b570..713f3b6280 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/EmptyGuidAsKeyTests.cs @@ -125,8 +125,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var mapInDatabase = await dbContext.Maps - .FirstAsync(map => map.Id == Guid.Empty); + var mapInDatabase = await dbContext.Maps.FirstWithIdAsync((Guid?)Guid.Empty); mapInDatabase.Should().NotBeNull(); mapInDatabase.Name.Should().Be(newName); @@ -174,8 +173,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var mapInDatabase = await dbContext.Maps - .FirstAsync(game => game.Id == Guid.Empty); + var mapInDatabase = await dbContext.Maps.FirstWithIdAsync((Guid?)Guid.Empty); mapInDatabase.Should().NotBeNull(); mapInDatabase.Name.Should().Be(newName); @@ -216,7 +214,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var gameInDatabase = await dbContext.Games .Include(game => game.ActiveMap) - .FirstAsync(game => game.Id == existingGame.Id); + .FirstWithIdAsync(existingGame.Id); gameInDatabase.Should().NotBeNull(); gameInDatabase.ActiveMap.Should().BeNull(); @@ -262,7 +260,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var gameInDatabase = await dbContext.Games .Include(game => game.ActiveMap) - .FirstAsync(game => game.Id == existingGame.Id); + .FirstWithIdAsync(existingGame.Id); gameInDatabase.Should().NotBeNull(); gameInDatabase.ActiveMap.Id.Should().Be(Guid.Empty); @@ -309,7 +307,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var gameInDatabase = await dbContext.Games .Include(game => game.ActiveMap) - .FirstAsync(game => game.Id == existingGame.Id); + .FirstWithIdAsync(existingGame.Id); gameInDatabase.Should().NotBeNull(); gameInDatabase.ActiveMap.Id.Should().Be(Guid.Empty); @@ -350,7 +348,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var gameInDatabase = await dbContext.Games .Include(game => game.Maps) - .FirstAsync(game => game.Id == existingGame.Id); + .FirstWithIdAsync(existingGame.Id); gameInDatabase.Should().NotBeNull(); gameInDatabase.Maps.Should().BeEmpty(); @@ -399,7 +397,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var gameInDatabase = await dbContext.Games .Include(game => game.Maps) - .FirstAsync(game => game.Id == existingGame.Id); + .FirstWithIdAsync(existingGame.Id); gameInDatabase.Should().NotBeNull(); gameInDatabase.Maps.Should().HaveCount(1); @@ -450,7 +448,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var gameInDatabase = await dbContext.Games .Include(game => game.Maps) - .FirstAsync(game => game.Id == existingGame.Id); + .FirstWithIdAsync(existingGame.Id); gameInDatabase.Should().NotBeNull(); gameInDatabase.Maps.Should().HaveCount(1); @@ -501,7 +499,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var gameInDatabase = await dbContext.Games .Include(game => game.Maps) - .FirstAsync(game => game.Id == existingGame.Id); + .FirstWithIdAsync(existingGame.Id); gameInDatabase.Should().NotBeNull(); gameInDatabase.Maps.Should().HaveCount(2); @@ -550,7 +548,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var gameInDatabase = await dbContext.Games .Include(game => game.Maps) - .FirstAsync(game => game.Id == existingGame.Id); + .FirstWithIdAsync(existingGame.Id); gameInDatabase.Should().NotBeNull(); gameInDatabase.Maps.Should().HaveCount(1); @@ -584,8 +582,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var gameInDatabase = await dbContext.Maps - .FirstOrDefaultAsync(map => map.Id == existingMap.Id); + var gameInDatabase = await dbContext.Maps.FirstWithIdOrDefaultAsync(existingMap.Id); gameInDatabase.Should().BeNull(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs index 010006d9f9..0939ce692a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroAsKeyTests.cs @@ -124,8 +124,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var gameInDatabase = await dbContext.Games - .FirstAsync(game => game.Id == 0); + var gameInDatabase = await dbContext.Games.FirstWithIdAsync((int?)0); gameInDatabase.Should().NotBeNull(); gameInDatabase.Title.Should().Be(newTitle); @@ -175,8 +174,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var gameInDatabase = await dbContext.Games - .FirstAsync(game => game.Id == 0); + var gameInDatabase = await dbContext.Games.FirstWithIdAsync((int?)0); gameInDatabase.Should().NotBeNull(); gameInDatabase.Title.Should().Be(newTitle); @@ -217,7 +215,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var playerInDatabase = await dbContext.Players .Include(player => player.ActiveGame) - .FirstAsync(player => player.Id == existingPlayer.Id); + .FirstWithIdAsync(existingPlayer.Id); playerInDatabase.Should().NotBeNull(); playerInDatabase.ActiveGame.Should().BeNull(); @@ -263,7 +261,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var playerInDatabase = await dbContext.Players .Include(player => player.ActiveGame) - .FirstAsync(player => player.Id == existingPlayer.Id); + .FirstWithIdAsync(existingPlayer.Id); playerInDatabase.Should().NotBeNull(); playerInDatabase.ActiveGame.Id.Should().Be(0); @@ -310,7 +308,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var playerInDatabase = await dbContext.Players .Include(player => player.ActiveGame) - .FirstAsync(player => player.Id == existingPlayer.Id); + .FirstWithIdAsync(existingPlayer.Id); playerInDatabase.Should().NotBeNull(); playerInDatabase.ActiveGame.Id.Should().Be(0); @@ -351,7 +349,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var playerInDatabase = await dbContext.Players .Include(player => player.RecentlyPlayed) - .FirstAsync(player => player.Id == existingPlayer.Id); + .FirstWithIdAsync(existingPlayer.Id); playerInDatabase.Should().NotBeNull(); playerInDatabase.RecentlyPlayed.Should().BeEmpty(); @@ -400,7 +398,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var playerInDatabase = await dbContext.Players .Include(player => player.RecentlyPlayed) - .FirstAsync(player => player.Id == existingPlayer.Id); + .FirstWithIdAsync(existingPlayer.Id); playerInDatabase.Should().NotBeNull(); playerInDatabase.RecentlyPlayed.Should().HaveCount(1); @@ -451,7 +449,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var playerInDatabase = await dbContext.Players .Include(player => player.RecentlyPlayed) - .FirstAsync(player => player.Id == existingPlayer.Id); + .FirstWithIdAsync(existingPlayer.Id); playerInDatabase.Should().NotBeNull(); playerInDatabase.RecentlyPlayed.Should().HaveCount(1); @@ -502,7 +500,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var playerInDatabase = await dbContext.Players .Include(player => player.RecentlyPlayed) - .FirstAsync(player => player.Id == existingPlayer.Id); + .FirstWithIdAsync(existingPlayer.Id); playerInDatabase.Should().NotBeNull(); playerInDatabase.RecentlyPlayed.Should().HaveCount(2); @@ -551,7 +549,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => { var playerInDatabase = await dbContext.Players .Include(player => player.RecentlyPlayed) - .FirstAsync(player => player.Id == existingPlayer.Id); + .FirstWithIdAsync(existingPlayer.Id); playerInDatabase.Should().NotBeNull(); playerInDatabase.RecentlyPlayed.Should().HaveCount(1); @@ -585,8 +583,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var gameInDatabase = await dbContext.Games - .FirstOrDefaultAsync(game => game.Id == existingGame.Id); + var gameInDatabase = await dbContext.Games.FirstWithIdOrDefaultAsync(existingGame.Id); gameInDatabase.Should().BeNull(); }); diff --git a/test/TestBuildingBlocks/QueryableExtensions.cs b/test/TestBuildingBlocks/QueryableExtensions.cs new file mode 100644 index 0000000000..7fb767cdce --- /dev/null +++ b/test/TestBuildingBlocks/QueryableExtensions.cs @@ -0,0 +1,25 @@ +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using JsonApiDotNetCore.Resources; +using Microsoft.EntityFrameworkCore; + +namespace TestBuildingBlocks +{ + public static class QueryableExtensions + { + public static Task FirstWithIdAsync(this IQueryable resources, TId id, + CancellationToken cancellationToken = default) + where TResource : IIdentifiable + { + return resources.FirstAsync(resource => Equals(resource.Id, id), cancellationToken); + } + + public static Task FirstWithIdOrDefaultAsync(this IQueryable resources, TId id, + CancellationToken cancellationToken = default) + where TResource : IIdentifiable + { + return resources.FirstOrDefaultAsync(resource => Equals(resource.Id, id), cancellationToken); + } + } +} From f95b8e6b01813159956b668e4742453d10c42f2f Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 17 Feb 2021 17:49:57 +0100 Subject: [PATCH 21/60] Added formatting directives on long database queries in tests --- .../Serialization/ResponseSerializer.cs | 1 - .../Creating/AtomicCreateResourceTests.cs | 6 ++++ ...eateResourceWithToManyRelationshipTests.cs | 6 ++++ ...reateResourceWithToOneRelationshipTests.cs | 6 ++++ .../LocalIds/AtomicLocalIdTests.cs | 36 +++++++++++++++++++ .../AtomicModelStateValidationTests.cs | 18 ++++++++++ .../AtomicAddToToManyRelationshipTests.cs | 6 ++++ ...AtomicRemoveFromToManyRelationshipTests.cs | 6 ++++ .../AtomicReplaceToManyRelationshipTests.cs | 12 +++++++ .../AtomicReplaceToManyRelationshipTests.cs | 12 +++++++ .../Resources/AtomicUpdateResourceTests.cs | 6 ++++ .../EagerLoading/EagerLoadingTests.cs | 12 +++++++ .../ReadWrite/Creating/CreateResourceTests.cs | 6 ++++ ...eateResourceWithToManyRelationshipTests.cs | 6 ++++ .../AddToToManyRelationshipTests.cs | 12 +++++++ .../RemoveFromToManyRelationshipTests.cs | 12 +++++++ .../ReplaceToManyRelationshipTests.cs | 24 +++++++++++++ .../ReplaceToManyRelationshipTests.cs | 30 ++++++++++++++++ .../Updating/Resources/UpdateResourceTests.cs | 12 +++++++ .../CallableResourceDefinition.cs | 4 +++ .../ResourceInheritance/InheritanceTests.cs | 12 +++++++ .../QueryStringParameters/BaseParseTests.cs | 6 ++++ 22 files changed, 250 insertions(+), 1 deletion(-) diff --git a/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs b/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs index 830edd74e7..be3141c8b3 100644 --- a/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs @@ -4,7 +4,6 @@ using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.Resources; -using JsonApiDotNetCore.Resources.Annotations; using JsonApiDotNetCore.Serialization.Building; using JsonApiDotNetCore.Serialization.Objects; using Newtonsoft.Json; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs index 16afe533b1..7c008892e3 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs @@ -781,12 +781,18 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Lyric) .Include(musicTrack => musicTrack.OwnedBy) .Include(musicTrack => musicTrack.Performers) .FirstWithIdAsync(newTrackId); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + trackInDatabase.Title.Should().Be(newTitle); trackInDatabase.Lyric.Should().NotBeNull(); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs index a7909fab5d..bbaedf4faa 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs @@ -176,11 +176,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(newPlaylistId); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(3); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[0].Id); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[1].Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs index 23c4d1a718..999e214e5c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs @@ -230,11 +230,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var tracksInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) .Where(musicTrack => newTrackIds.Contains(musicTrack.Id)) .ToListAsync(); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + tracksInDatabase.Should().HaveCount(elementCount); for (int index = 0; index < elementCount; index++) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs index 62072be5e1..197c8f51ed 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/LocalIds/AtomicLocalIdTests.cs @@ -290,11 +290,17 @@ public async Task Can_create_resource_with_ManyToMany_relationship_using_local_I await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(newPlaylistId); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.Name.Should().Be(newPlaylistName); playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1); @@ -621,11 +627,17 @@ public async Task Can_update_resource_with_relationships_using_local_ID() await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.OwnedBy) .Include(musicTrack => musicTrack.Performers) .FirstWithIdAsync(newTrackId); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + trackInDatabase.Title.Should().Be(newTrackTitle); trackInDatabase.OwnedBy.Should().NotBeNull(); @@ -922,11 +934,17 @@ public async Task Can_create_ManyToMany_relationship_using_local_ID() await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(newPlaylistId); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.Name.Should().Be(newPlaylistName); playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1); @@ -1167,11 +1185,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(newPlaylistId); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.Name.Should().Be(newPlaylistName); playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1); @@ -1436,11 +1460,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(newPlaylistId); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.Name.Should().Be(newPlaylistName); playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(3); @@ -1730,11 +1760,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(existingPlaylist.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1); playlistInDatabase.PlaylistMusicTracks[0].MusicTrack.Id.Should().Be(existingPlaylist.PlaylistMusicTracks[0].MusicTrack.Id); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs index 017d7f0b0d..5f6e19fc92 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ModelStateValidation/AtomicModelStateValidationTests.cs @@ -128,11 +128,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(newPlaylistId); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1); playlistInDatabase.PlaylistMusicTracks[0].MusicTrack.Id.Should().Be(existingTrack.Id); }); @@ -301,11 +307,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(existingPlaylist.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1); playlistInDatabase.PlaylistMusicTracks[0].MusicTrack.Id.Should().Be(existingTrack.Id); }); @@ -417,11 +429,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(existingPlaylist.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1); playlistInDatabase.PlaylistMusicTracks[0].MusicTrack.Id.Should().Be(existingTrack.Id); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs index 55e1bdcb80..1574abd4d1 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs @@ -234,11 +234,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(existingPlaylist.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(3); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingPlaylist.PlaylistMusicTracks[0].MusicTrack.Id); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[0].Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs index 99f9a650cb..c12f2cdb74 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs @@ -239,11 +239,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(existingPlaylist.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(1); playlistInDatabase.PlaylistMusicTracks[0].MusicTrack.Id.Should().Be(existingPlaylist.PlaylistMusicTracks[1].MusicTrack.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs index 3c9eac6512..9002bea652 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs @@ -133,11 +133,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(existingPlaylist.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.PlaylistMusicTracks.Should().BeEmpty(); var tracksInDatabase = await dbContext.MusicTracks.ToListAsync(); @@ -282,11 +288,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(existingPlaylist.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(2); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[0].Id); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[1].Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs index 552729557c..c68a421394 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs @@ -143,11 +143,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(existingPlaylist.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.PlaylistMusicTracks.Should().BeEmpty(); var tracksInDatabase = await dbContext.MusicTracks.ToListAsync(); @@ -302,11 +308,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var playlistInDatabase = await dbContext.Playlists .Include(playlist => playlist.PlaylistMusicTracks) .ThenInclude(playlistMusicTrack => playlistMusicTrack.MusicTrack) .FirstWithIdAsync(existingPlaylist.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(2); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[0].Id); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[1].Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs index 1c7fb688e3..626fa31e02 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs @@ -1577,12 +1577,18 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var trackInDatabase = await dbContext.MusicTracks .Include(musicTrack => musicTrack.Lyric) .Include(musicTrack => musicTrack.OwnedBy) .Include(musicTrack => musicTrack.Performers) .FirstWithIdAsync(existingTrack.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + trackInDatabase.Title.Should().Be(existingTrack.Title); trackInDatabase.Genre.Should().Be(newGenre); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingTests.cs index bb8ee2fe4f..2acabc76c4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingTests.cs @@ -242,12 +242,18 @@ public async Task Can_create_resource() await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var buildingInDatabase = await dbContext.Buildings .Include(building => building.PrimaryDoor) .Include(building => building.SecondaryDoor) .Include(building => building.Windows) .FirstWithIdOrDefaultAsync(newBuildingId); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + buildingInDatabase.Should().NotBeNull(); buildingInDatabase.Number.Should().Be(newBuilding.Number); buildingInDatabase.PrimaryDoor.Should().NotBeNull(); @@ -300,12 +306,18 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var buildingInDatabase = await dbContext.Buildings .Include(building => building.PrimaryDoor) .Include(building => building.SecondaryDoor) .Include(building => building.Windows) .FirstWithIdOrDefaultAsync(existingBuilding.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + buildingInDatabase.Should().NotBeNull(); buildingInDatabase.Number.Should().Be(newBuildingNumber); buildingInDatabase.PrimaryDoor.Should().NotBeNull(); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs index f15402de58..722f6a0302 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs @@ -701,6 +701,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Assignee) .Include(workItem => workItem.Subscribers) @@ -708,6 +711,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => .ThenInclude(workItemTag => workItemTag.Tag) .FirstWithIdAsync(newWorkItemId); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.Description.Should().Be(newDescription); workItemInDatabase.Assignee.Should().NotBeNull(); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs index 2e6788e33f..5596546a99 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs @@ -313,11 +313,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) .FirstWithIdAsync(newWorkItemId); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.WorkItemTags.Should().HaveCount(3); workItemInDatabase.WorkItemTags.Should().ContainSingle(workItemTag => workItemTag.Tag.Id == existingTags[0].Id); workItemInDatabase.WorkItemTags.Should().ContainSingle(workItemTag => workItemTag.Tag.Id == existingTags[1].Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs index 7689a8b788..fae2970761 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs @@ -170,11 +170,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemsInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) .ToListAsync(); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + var workItemInDatabase1 = workItemsInDatabase.Single(workItem => workItem.Id == existingWorkItems[0].Id); workItemInDatabase1.WorkItemTags.Should().HaveCount(2); @@ -837,11 +843,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.RelatedToItems) .ThenInclude(workItemToWorkItem => workItemToWorkItem.ToItem) .FirstWithIdAsync(existingWorkItem.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.RelatedToItems.Should().HaveCount(2); workItemInDatabase.RelatedToItems.Should().OnlyContain(workItemToWorkItem => workItemToWorkItem.FromItem.Id == existingWorkItem.Id); workItemInDatabase.RelatedToItems.Should().ContainSingle(workItemToWorkItem => workItemToWorkItem.ToItem.Id == existingWorkItem.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs index 0bc10db0a3..9acb820add 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs @@ -170,11 +170,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) .FirstWithIdAsync(existingWorkItem.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.WorkItemTags.Should().HaveCount(1); workItemInDatabase.WorkItemTags.Single().Tag.Id.Should().Be(existingWorkItem.WorkItemTags.ElementAt(0).Tag.Id); @@ -842,11 +848,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.RelatedFromItems) .ThenInclude(workItemToWorkItem => workItemToWorkItem.FromItem) .FirstWithIdAsync(existingWorkItem.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.RelatedFromItems.Should().HaveCount(1); workItemInDatabase.RelatedFromItems[0].FromItem.Id.Should().Be(existingWorkItem.RelatedFromItems[0].FromItem.Id); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs index d8cc7418aa..4201e23f16 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs @@ -96,11 +96,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) .FirstWithIdAsync(existingWorkItem.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.WorkItemTags.Should().BeEmpty(); }); } @@ -219,11 +225,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) .FirstWithIdAsync(existingWorkItem.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.WorkItemTags.Should().HaveCount(3); workItemInDatabase.WorkItemTags.Should().ContainSingle(workItemTag => workItemTag.Tag.Id == existingWorkItem.WorkItemTags.ElementAt(0).Tag.Id); workItemInDatabase.WorkItemTags.Should().ContainSingle(workItemTag => workItemTag.Tag.Id == existingTags[0].Id); @@ -829,11 +841,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.RelatedFromItems) .ThenInclude(workItemToWorkItem => workItemToWorkItem.FromItem) .FirstWithIdAsync(existingWorkItem.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.RelatedFromItems.Should().BeEmpty(); }); } @@ -919,11 +937,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.RelatedToItems) .ThenInclude(workItemToWorkItem => workItemToWorkItem.ToItem) .FirstWithIdAsync(existingWorkItem.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.RelatedToItems.Should().HaveCount(1); workItemInDatabase.RelatedToItems[0].FromItem.Id.Should().Be(existingWorkItem.Id); workItemInDatabase.RelatedToItems[0].ToItem.Id.Should().Be(existingWorkItem.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs index b4aa461aec..c81ec7b9c2 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs @@ -118,11 +118,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) .FirstWithIdAsync(existingWorkItem.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.WorkItemTags.Should().BeEmpty(); }); } @@ -263,11 +269,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) .FirstWithIdAsync(existingWorkItem.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.WorkItemTags.Should().HaveCount(3); workItemInDatabase.WorkItemTags.Should().ContainSingle(workItemTag => workItemTag.Tag.Id == existingWorkItem.WorkItemTags.ElementAt(0).Tag.Id); workItemInDatabase.WorkItemTags.Should().ContainSingle(workItemTag => workItemTag.Tag.Id == existingTags[0].Id); @@ -407,11 +419,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.WorkItemTags) .ThenInclude(workItemTag => workItemTag.Tag) .FirstWithIdAsync(newWorkItemId); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.WorkItemTags.Should().HaveCount(1); workItemInDatabase.WorkItemTags.Single().Tag.Id.Should().Be(existingTag.Id); }); @@ -961,11 +979,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.RelatedFromItems) .ThenInclude(workItemToWorkItem => workItemToWorkItem.FromItem) .FirstWithIdAsync(existingWorkItem.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.RelatedFromItems.Should().BeEmpty(); }); } @@ -1073,11 +1097,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.RelatedToItems) .ThenInclude(workItemToWorkItem => workItemToWorkItem.ToItem) .FirstWithIdAsync(existingWorkItem.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.RelatedToItems.Should().HaveCount(1); workItemInDatabase.RelatedToItems[0].FromItem.Id.Should().Be(existingWorkItem.Id); workItemInDatabase.RelatedToItems[0].ToItem.Id.Should().Be(existingWorkItem.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs index 02ee7851ac..090d31452f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs @@ -1074,6 +1074,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Assignee) .Include(workItem => workItem.Subscribers) @@ -1081,6 +1084,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => .ThenInclude(workItemTag => workItemTag.Tag) .FirstWithIdAsync(existingWorkItem.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.Description.Should().Be(newDescription); workItemInDatabase.Assignee.Should().NotBeNull(); @@ -1169,6 +1175,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var workItemInDatabase = await dbContext.WorkItems .Include(workItem => workItem.Parent) .Include(workItem => workItem.Children) @@ -1176,6 +1185,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => .ThenInclude(workItemToWorkItem => workItemToWorkItem.ToItem) .FirstWithIdAsync(existingWorkItem.Id); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + workItemInDatabase.Parent.Should().NotBeNull(); workItemInDatabase.Parent.Id.Should().Be(existingWorkItem.Id); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs index 7cfb920377..a1b4eae3da 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs @@ -88,9 +88,13 @@ public override SparseFieldSetExpression OnApplySparseFieldSet(SparseFieldSetExp { // Use case: always retrieve percentageComplete and never include riskLevel in responses. + // @formatter:keep_existing_linebreaks true + return existingSparseFieldSet .Including(resource => resource.PercentageComplete, ResourceGraph) .Excluding(resource => resource.RiskLevel, ResourceGraph); + + // @formatter:keep_existing_linebreaks restore } public override QueryStringParameterHandlers OnRegisterQueryableHandlersForQueryStringParameters() diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs index 441e7fa78f..1542000fd5 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceTests.cs @@ -400,11 +400,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var contentItems = await dbContext.HumanFavoriteContentItems .Where(favorite => favorite.Human.Id == newManId) .Select(favorite => favorite.ContentItem) .ToListAsync(); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + contentItems.Should().HaveCount(2); contentItems.Should().ContainSingle(item => item is Book); contentItems.Should().ContainSingle(item => item is Video); @@ -455,11 +461,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + var contentItems = await dbContext.HumanFavoriteContentItems .Where(favorite => favorite.Human.Id == existingMan.Id) .Select(favorite => favorite.ContentItem) .ToListAsync(); + // @formatter:keep_existing_linebreaks restore + // @formatter:wrap_chained_method_calls restore + contentItems.Should().HaveCount(2); contentItems.Should().ContainSingle(item => item is Book); contentItems.Should().ContainSingle(item => item is Video); diff --git a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/BaseParseTests.cs b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/BaseParseTests.cs index 1c4be2a4ca..8eee4e52d5 100644 --- a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/BaseParseTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/BaseParseTests.cs @@ -15,6 +15,9 @@ protected BaseParseTests() { Options = new JsonApiOptions(); + // @formatter:wrap_chained_method_calls chop_always + // @formatter:keep_existing_linebreaks true + ResourceGraph = new ResourceGraphBuilder(Options, NullLoggerFactory.Instance) .Add() .Add() @@ -24,6 +27,9 @@ protected BaseParseTests() .Add() .Build(); + // @formatter:wrap_chained_method_calls restore + // @formatter:keep_existing_linebreaks restore + Request = new JsonApiRequest { PrimaryResource = ResourceGraph.GetResourceContext(), From a1800d969bde2d023625ea08096c8032a589712e Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Thu, 18 Feb 2021 14:57:31 +0100 Subject: [PATCH 22/60] Reduced line length for links assertions --- .../Links/AtomicAbsoluteLinksTests.cs | 38 ++++--- .../AtomicRelativeLinksWithNamespaceTests.cs | 18 ++-- .../CustomRoutes/CustomRouteTests.cs | 10 +- .../Links/AbsoluteLinksWithNamespaceTests.cs | 101 ++++++++++-------- .../AbsoluteLinksWithoutNamespaceTests.cs | 101 ++++++++++-------- .../Links/RelativeLinksWithNamespaceTests.cs | 95 +++++++++------- .../RelativeLinksWithoutNamespaceTests.cs | 95 +++++++++------- .../NamingConventions/KebabCasingTests.cs | 9 +- .../PaginationWithTotalCountTests.cs | 55 +++++----- .../PaginationWithoutTotalCountTests.cs | 35 +++--- 10 files changed, 314 insertions(+), 243 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicAbsoluteLinksTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicAbsoluteLinksTests.cs index 6ca814b583..f2f9ccdc25 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicAbsoluteLinksTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicAbsoluteLinksTests.cs @@ -13,6 +13,8 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.Links public sealed class AtomicAbsoluteLinksTests : IClassFixture, OperationsDbContext>> { + private const string HostPrefix = "http://localhost"; + private readonly ExampleIntegrationTestContext, OperationsDbContext> _testContext; private readonly OperationsFakers _fakers = new OperationsFakers(); @@ -82,21 +84,27 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Results.Should().HaveCount(2); - responseDocument.Results[0].SingleData.Should().NotBeNull(); - responseDocument.Results[0].SingleData.Links.Should().NotBeNull(); - responseDocument.Results[0].SingleData.Links.Self.Should().Be("http://localhost/textLanguages/" + existingLanguage.StringId); - responseDocument.Results[0].SingleData.Relationships.Should().NotBeEmpty(); - responseDocument.Results[0].SingleData.Relationships["lyrics"].Links.Should().NotBeNull(); - responseDocument.Results[0].SingleData.Relationships["lyrics"].Links.Self.Should().Be($"http://localhost/textLanguages/{existingLanguage.StringId}/relationships/lyrics"); - responseDocument.Results[0].SingleData.Relationships["lyrics"].Links.Related.Should().Be($"http://localhost/textLanguages/{existingLanguage.StringId}/lyrics"); - - responseDocument.Results[1].SingleData.Should().NotBeNull(); - responseDocument.Results[1].SingleData.Links.Should().NotBeNull(); - responseDocument.Results[1].SingleData.Links.Self.Should().Be("http://localhost/recordCompanies/" + existingCompany.StringId); - responseDocument.Results[1].SingleData.Relationships.Should().NotBeEmpty(); - responseDocument.Results[1].SingleData.Relationships["tracks"].Links.Should().NotBeNull(); - responseDocument.Results[1].SingleData.Relationships["tracks"].Links.Self.Should().Be($"http://localhost/recordCompanies/{existingCompany.StringId}/relationships/tracks"); - responseDocument.Results[1].SingleData.Relationships["tracks"].Links.Related.Should().Be($"http://localhost/recordCompanies/{existingCompany.StringId}/tracks"); + string languageLink = HostPrefix + "/textLanguages/" + existingLanguage.StringId; + + var singleData1 = responseDocument.Results[0].SingleData; + singleData1.Should().NotBeNull(); + singleData1.Links.Should().NotBeNull(); + singleData1.Links.Self.Should().Be(languageLink); + singleData1.Relationships.Should().NotBeEmpty(); + singleData1.Relationships["lyrics"].Links.Should().NotBeNull(); + singleData1.Relationships["lyrics"].Links.Self.Should().Be(languageLink + "/relationships/lyrics"); + singleData1.Relationships["lyrics"].Links.Related.Should().Be(languageLink + "/lyrics"); + + string companyLink = HostPrefix + "/recordCompanies/" + existingCompany.StringId; + + var singleData2 = responseDocument.Results[1].SingleData; + singleData2.Should().NotBeNull(); + singleData2.Links.Should().NotBeNull(); + singleData2.Links.Self.Should().Be(companyLink); + singleData2.Relationships.Should().NotBeEmpty(); + singleData2.Relationships["tracks"].Links.Should().NotBeNull(); + singleData2.Relationships["tracks"].Links.Self.Should().Be(companyLink + "/relationships/tracks"); + singleData2.Relationships["tracks"].Links.Related.Should().Be(companyLink + "/tracks"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicRelativeLinksWithNamespaceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicRelativeLinksWithNamespaceTests.cs index c3c864891b..1931b4725d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicRelativeLinksWithNamespaceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Links/AtomicRelativeLinksWithNamespaceTests.cs @@ -72,26 +72,26 @@ public async Task Create_resource_with_side_effects_returns_relative_links() responseDocument.Results.Should().HaveCount(2); responseDocument.Results[0].SingleData.Should().NotBeNull(); - - var newLanguageId = Guid.Parse(responseDocument.Results[0].SingleData.Id); + + string languageLink = "/api/textLanguages/" + Guid.Parse(responseDocument.Results[0].SingleData.Id); responseDocument.Results[0].SingleData.Links.Should().NotBeNull(); - responseDocument.Results[0].SingleData.Links.Self.Should().Be("/api/textLanguages/" + newLanguageId); + responseDocument.Results[0].SingleData.Links.Self.Should().Be(languageLink); responseDocument.Results[0].SingleData.Relationships.Should().NotBeEmpty(); responseDocument.Results[0].SingleData.Relationships["lyrics"].Links.Should().NotBeNull(); - responseDocument.Results[0].SingleData.Relationships["lyrics"].Links.Self.Should().Be($"/api/textLanguages/{newLanguageId}/relationships/lyrics"); - responseDocument.Results[0].SingleData.Relationships["lyrics"].Links.Related.Should().Be($"/api/textLanguages/{newLanguageId}/lyrics"); + responseDocument.Results[0].SingleData.Relationships["lyrics"].Links.Self.Should().Be(languageLink + "/relationships/lyrics"); + responseDocument.Results[0].SingleData.Relationships["lyrics"].Links.Related.Should().Be(languageLink + "/lyrics"); responseDocument.Results[1].SingleData.Should().NotBeNull(); - var newCompanyId = short.Parse(responseDocument.Results[1].SingleData.Id); + string companyLink = "/api/recordCompanies/" + short.Parse(responseDocument.Results[1].SingleData.Id); responseDocument.Results[1].SingleData.Links.Should().NotBeNull(); - responseDocument.Results[1].SingleData.Links.Self.Should().Be("/api/recordCompanies/" + newCompanyId); + responseDocument.Results[1].SingleData.Links.Self.Should().Be(companyLink); responseDocument.Results[1].SingleData.Relationships.Should().NotBeEmpty(); responseDocument.Results[1].SingleData.Relationships["tracks"].Links.Should().NotBeNull(); - responseDocument.Results[1].SingleData.Relationships["tracks"].Links.Self.Should().Be($"/api/recordCompanies/{newCompanyId}/relationships/tracks"); - responseDocument.Results[1].SingleData.Relationships["tracks"].Links.Related.Should().Be($"/api/recordCompanies/{newCompanyId}/tracks"); + responseDocument.Results[1].SingleData.Relationships["tracks"].Links.Self.Should().Be(companyLink + "/relationships/tracks"); + responseDocument.Results[1].SingleData.Relationships["tracks"].Links.Related.Should().Be(companyLink + "/tracks"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteTests.cs index 05141c83a9..aaebbce763 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteTests.cs @@ -12,6 +12,8 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CustomRoutes public sealed class CustomRouteTests : IClassFixture, CustomRouteDbContext>> { + private const string HostPrefix = "http://localhost"; + private readonly ExampleIntegrationTestContext, CustomRouteDbContext> _testContext; private readonly CustomRouteFakers _fakers = new CustomRouteFakers(); @@ -46,10 +48,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.SingleData.Attributes["name"].Should().Be(town.Name); responseDocument.SingleData.Attributes["latitude"].Should().Be(town.Latitude); responseDocument.SingleData.Attributes["longitude"].Should().Be(town.Longitude); - responseDocument.SingleData.Relationships["civilians"].Links.Self.Should().Be($"http://localhost/world-api/civilization/popular/towns/{town.Id}/relationships/civilians"); - responseDocument.SingleData.Relationships["civilians"].Links.Related.Should().Be($"http://localhost/world-api/civilization/popular/towns/{town.Id}/civilians"); - responseDocument.SingleData.Links.Self.Should().Be($"http://localhost/world-api/civilization/popular/towns/{town.Id}"); - responseDocument.Links.Self.Should().Be($"http://localhost/world-api/civilization/popular/towns/{town.Id}"); + responseDocument.SingleData.Relationships["civilians"].Links.Self.Should().Be(HostPrefix + route + "/relationships/civilians"); + responseDocument.SingleData.Relationships["civilians"].Links.Related.Should().Be(HostPrefix + route + "/civilians"); + responseDocument.SingleData.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.Self.Should().Be(HostPrefix + route); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithNamespaceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithNamespaceTests.cs index 2f0a0fa216..36ca78da28 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithNamespaceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithNamespaceTests.cs @@ -15,6 +15,8 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Links public sealed class AbsoluteLinksWithNamespaceTests : IClassFixture, LinksDbContext>> { + private const string HostPrefix = "http://localhost"; + private readonly ExampleIntegrationTestContext, LinksDbContext> _testContext; private readonly LinksFakers _fakers = new LinksFakers(); @@ -51,7 +53,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"http://localhost/api/photoAlbums/{album.StringId}"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); @@ -59,9 +61,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Links.Next.Should().BeNull(); responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"http://localhost/api/photoAlbums/{album.StringId}"); - responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be($"http://localhost/api/photoAlbums/{album.StringId}/relationships/photos"); - responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be($"http://localhost/api/photoAlbums/{album.StringId}/photos"); + responseDocument.SingleData.Links.Self.Should().Be(HostPrefix + route); + responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be(HostPrefix + route + "/relationships/photos"); + responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be(HostPrefix + route + "/photos"); } [Fact] @@ -86,22 +88,26 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be("http://localhost/api/photoAlbums?include=photos"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.Related.Should().BeNull(); - responseDocument.Links.First.Should().Be("http://localhost/api/photoAlbums?include=photos"); - responseDocument.Links.Last.Should().Be("http://localhost/api/photoAlbums?include=photos"); + responseDocument.Links.First.Should().Be(HostPrefix + route); + responseDocument.Links.Last.Should().Be(HostPrefix + route); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string albumLink = HostPrefix + $"/api/photoAlbums/{album.StringId}"; + responseDocument.ManyData.Should().HaveCount(1); - responseDocument.ManyData[0].Links.Self.Should().Be($"http://localhost/api/photoAlbums/{album.StringId}"); - responseDocument.ManyData[0].Relationships["photos"].Links.Self.Should().Be($"http://localhost/api/photoAlbums/{album.StringId}/relationships/photos"); - responseDocument.ManyData[0].Relationships["photos"].Links.Related.Should().Be($"http://localhost/api/photoAlbums/{album.StringId}/photos"); + responseDocument.ManyData[0].Links.Self.Should().Be(albumLink); + responseDocument.ManyData[0].Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.ManyData[0].Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); + + string photoLink = HostPrefix + $"/api/photos/{album.Photos.ElementAt(0).StringId}"; responseDocument.Included.Should().HaveCount(1); - responseDocument.Included[0].Links.Self.Should().Be($"http://localhost/api/photos/{album.Photos.ElementAt(0).StringId}"); - responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be($"http://localhost/api/photos/{album.Photos.ElementAt(0).StringId}/relationships/album"); - responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be($"http://localhost/api/photos/{album.Photos.ElementAt(0).StringId}/album"); + responseDocument.Included[0].Links.Self.Should().Be(photoLink); + responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); } [Fact] @@ -125,17 +131,19 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"http://localhost/api/photos/{photo.StringId}/album"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string albumLink = HostPrefix + $"/api/photoAlbums/{photo.Album.StringId}"; + responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"http://localhost/api/photoAlbums/{photo.Album.StringId}"); - responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be($"http://localhost/api/photoAlbums/{photo.Album.StringId}/relationships/photos"); - responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be($"http://localhost/api/photoAlbums/{photo.Album.StringId}/photos"); + responseDocument.SingleData.Links.Self.Should().Be(albumLink); + responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); } [Fact] @@ -159,17 +167,19 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"http://localhost/api/photoAlbums/{album.StringId}/photos"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.Related.Should().BeNull(); - responseDocument.Links.First.Should().Be($"http://localhost/api/photoAlbums/{album.StringId}/photos"); + responseDocument.Links.First.Should().Be(HostPrefix + route); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string photoLink = HostPrefix + $"/api/photos/{album.Photos.ElementAt(0).StringId}"; + responseDocument.ManyData.Should().HaveCount(1); - responseDocument.ManyData[0].Links.Self.Should().Be($"http://localhost/api/photos/{album.Photos.ElementAt(0).StringId}"); - responseDocument.ManyData[0].Relationships["album"].Links.Self.Should().Be($"http://localhost/api/photos/{album.Photos.ElementAt(0).StringId}/relationships/album"); - responseDocument.ManyData[0].Relationships["album"].Links.Related.Should().Be($"http://localhost/api/photos/{album.Photos.ElementAt(0).StringId}/album"); + responseDocument.ManyData[0].Links.Self.Should().Be(photoLink); + responseDocument.ManyData[0].Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.ManyData[0].Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); } [Fact] @@ -193,8 +203,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"http://localhost/api/photos/{photo.StringId}/relationships/album"); - responseDocument.Links.Related.Should().Be($"http://localhost/api/photos/{photo.StringId}/album"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.Related.Should().Be(HostPrefix + $"/api/photos/{photo.StringId}/album"); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); @@ -226,9 +236,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"http://localhost/api/photoAlbums/{album.StringId}/relationships/photos"); - responseDocument.Links.Related.Should().Be($"http://localhost/api/photoAlbums/{album.StringId}/photos"); - responseDocument.Links.First.Should().Be($"http://localhost/api/photoAlbums/{album.StringId}/relationships/photos"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.Related.Should().Be(HostPrefix + $"/api/photoAlbums/{album.StringId}/photos"); + responseDocument.Links.First.Should().Be(HostPrefix + route); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); @@ -280,24 +290,25 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.Created); - responseDocument.Links.Self.Should().Be("http://localhost/api/photoAlbums?include=photos"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); - var newAlbumId = responseDocument.SingleData.Id; + string albumLink = HostPrefix + $"/api/photoAlbums/{responseDocument.SingleData.Id}"; - responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"http://localhost/api/photoAlbums/{newAlbumId}"); - responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be($"http://localhost/api/photoAlbums/{newAlbumId}/relationships/photos"); - responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be($"http://localhost/api/photoAlbums/{newAlbumId}/photos"); + responseDocument.SingleData.Links.Self.Should().Be(albumLink); + responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); + + string photoLink = HostPrefix + $"/api/photos/{existingPhoto.StringId}"; responseDocument.Included.Should().HaveCount(1); - responseDocument.Included[0].Links.Self.Should().Be($"http://localhost/api/photos/{existingPhoto.StringId}"); - responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be($"http://localhost/api/photos/{existingPhoto.StringId}/relationships/album"); - responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be($"http://localhost/api/photos/{existingPhoto.StringId}/album"); + responseDocument.Included[0].Links.Self.Should().Be(photoLink); + responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); } [Fact] @@ -341,22 +352,26 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"http://localhost/api/photos/{existingPhoto.StringId}?include=album"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string photoLink = HostPrefix + $"/api/photos/{existingPhoto.StringId}"; + responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"http://localhost/api/photos/{existingPhoto.StringId}"); - responseDocument.SingleData.Relationships["album"].Links.Self.Should().Be($"http://localhost/api/photos/{existingPhoto.StringId}/relationships/album"); - responseDocument.SingleData.Relationships["album"].Links.Related.Should().Be($"http://localhost/api/photos/{existingPhoto.StringId}/album"); + responseDocument.SingleData.Links.Self.Should().Be(photoLink); + responseDocument.SingleData.Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.SingleData.Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); + + string albumLink = HostPrefix + $"/api/photoAlbums/{existingAlbum.StringId}"; responseDocument.Included.Should().HaveCount(1); - responseDocument.Included[0].Links.Self.Should().Be($"http://localhost/api/photoAlbums/{existingAlbum.StringId}"); - responseDocument.Included[0].Relationships["photos"].Links.Self.Should().Be($"http://localhost/api/photoAlbums/{existingAlbum.StringId}/relationships/photos"); - responseDocument.Included[0].Relationships["photos"].Links.Related.Should().Be($"http://localhost/api/photoAlbums/{existingAlbum.StringId}/photos"); + responseDocument.Included[0].Links.Self.Should().Be(albumLink); + responseDocument.Included[0].Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.Included[0].Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithoutNamespaceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithoutNamespaceTests.cs index 9af1cdf987..37faa2c92a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithoutNamespaceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/AbsoluteLinksWithoutNamespaceTests.cs @@ -15,6 +15,8 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Links public sealed class AbsoluteLinksWithoutNamespaceTests : IClassFixture, LinksDbContext>> { + private const string HostPrefix = "http://localhost"; + private readonly ExampleIntegrationTestContext, LinksDbContext> _testContext; private readonly LinksFakers _fakers = new LinksFakers(); @@ -51,7 +53,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"http://localhost/photoAlbums/{album.StringId}"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); @@ -59,9 +61,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Links.Next.Should().BeNull(); responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"http://localhost/photoAlbums/{album.StringId}"); - responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be($"http://localhost/photoAlbums/{album.StringId}/relationships/photos"); - responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be($"http://localhost/photoAlbums/{album.StringId}/photos"); + responseDocument.SingleData.Links.Self.Should().Be(HostPrefix + route); + responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be(HostPrefix + route + "/relationships/photos"); + responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be(HostPrefix + route + "/photos"); } [Fact] @@ -86,22 +88,26 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be("http://localhost/photoAlbums?include=photos"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.Related.Should().BeNull(); - responseDocument.Links.First.Should().Be("http://localhost/photoAlbums?include=photos"); - responseDocument.Links.Last.Should().Be("http://localhost/photoAlbums?include=photos"); + responseDocument.Links.First.Should().Be(HostPrefix + route); + responseDocument.Links.Last.Should().Be(HostPrefix + route); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string albumLink = HostPrefix + $"/photoAlbums/{album.StringId}"; + responseDocument.ManyData.Should().HaveCount(1); - responseDocument.ManyData[0].Links.Self.Should().Be($"http://localhost/photoAlbums/{album.StringId}"); - responseDocument.ManyData[0].Relationships["photos"].Links.Self.Should().Be($"http://localhost/photoAlbums/{album.StringId}/relationships/photos"); - responseDocument.ManyData[0].Relationships["photos"].Links.Related.Should().Be($"http://localhost/photoAlbums/{album.StringId}/photos"); + responseDocument.ManyData[0].Links.Self.Should().Be(albumLink); + responseDocument.ManyData[0].Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.ManyData[0].Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); + + string photoLink = HostPrefix + $"/photos/{album.Photos.ElementAt(0).StringId}"; responseDocument.Included.Should().HaveCount(1); - responseDocument.Included[0].Links.Self.Should().Be($"http://localhost/photos/{album.Photos.ElementAt(0).StringId}"); - responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be($"http://localhost/photos/{album.Photos.ElementAt(0).StringId}/relationships/album"); - responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be($"http://localhost/photos/{album.Photos.ElementAt(0).StringId}/album"); + responseDocument.Included[0].Links.Self.Should().Be(photoLink); + responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); } [Fact] @@ -125,17 +131,19 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"http://localhost/photos/{photo.StringId}/album"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string albumLink = HostPrefix + $"/photoAlbums/{photo.Album.StringId}"; + responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"http://localhost/photoAlbums/{photo.Album.StringId}"); - responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be($"http://localhost/photoAlbums/{photo.Album.StringId}/relationships/photos"); - responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be($"http://localhost/photoAlbums/{photo.Album.StringId}/photos"); + responseDocument.SingleData.Links.Self.Should().Be(albumLink); + responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); } [Fact] @@ -159,17 +167,19 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"http://localhost/photoAlbums/{album.StringId}/photos"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.Related.Should().BeNull(); - responseDocument.Links.First.Should().Be($"http://localhost/photoAlbums/{album.StringId}/photos"); + responseDocument.Links.First.Should().Be(HostPrefix + route); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string photoLink = HostPrefix + $"/photos/{album.Photos.ElementAt(0).StringId}"; + responseDocument.ManyData.Should().HaveCount(1); - responseDocument.ManyData[0].Links.Self.Should().Be($"http://localhost/photos/{album.Photos.ElementAt(0).StringId}"); - responseDocument.ManyData[0].Relationships["album"].Links.Self.Should().Be($"http://localhost/photos/{album.Photos.ElementAt(0).StringId}/relationships/album"); - responseDocument.ManyData[0].Relationships["album"].Links.Related.Should().Be($"http://localhost/photos/{album.Photos.ElementAt(0).StringId}/album"); + responseDocument.ManyData[0].Links.Self.Should().Be(photoLink); + responseDocument.ManyData[0].Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.ManyData[0].Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); } [Fact] @@ -193,8 +203,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"http://localhost/photos/{photo.StringId}/relationships/album"); - responseDocument.Links.Related.Should().Be($"http://localhost/photos/{photo.StringId}/album"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.Related.Should().Be(HostPrefix + $"/photos/{photo.StringId}/album"); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); @@ -226,9 +236,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"http://localhost/photoAlbums/{album.StringId}/relationships/photos"); - responseDocument.Links.Related.Should().Be($"http://localhost/photoAlbums/{album.StringId}/photos"); - responseDocument.Links.First.Should().Be($"http://localhost/photoAlbums/{album.StringId}/relationships/photos"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.Related.Should().Be(HostPrefix + $"/photoAlbums/{album.StringId}/photos"); + responseDocument.Links.First.Should().Be(HostPrefix + route); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); @@ -280,24 +290,25 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.Created); - responseDocument.Links.Self.Should().Be("http://localhost/photoAlbums?include=photos"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); - var newAlbumId = responseDocument.SingleData.Id; + string albumLink = HostPrefix + $"/photoAlbums/{responseDocument.SingleData.Id}"; - responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"http://localhost/photoAlbums/{newAlbumId}"); - responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be($"http://localhost/photoAlbums/{newAlbumId}/relationships/photos"); - responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be($"http://localhost/photoAlbums/{newAlbumId}/photos"); + responseDocument.SingleData.Links.Self.Should().Be(albumLink); + responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); + + string photoLink = HostPrefix + $"/photos/{existingPhoto.StringId}"; responseDocument.Included.Should().HaveCount(1); - responseDocument.Included[0].Links.Self.Should().Be($"http://localhost/photos/{existingPhoto.StringId}"); - responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be($"http://localhost/photos/{existingPhoto.StringId}/relationships/album"); - responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be($"http://localhost/photos/{existingPhoto.StringId}/album"); + responseDocument.Included[0].Links.Self.Should().Be(photoLink); + responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); } [Fact] @@ -341,22 +352,26 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"http://localhost/photos/{existingPhoto.StringId}?include=album"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string photoLink = HostPrefix + $"/photos/{existingPhoto.StringId}"; + responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"http://localhost/photos/{existingPhoto.StringId}"); - responseDocument.SingleData.Relationships["album"].Links.Self.Should().Be($"http://localhost/photos/{existingPhoto.StringId}/relationships/album"); - responseDocument.SingleData.Relationships["album"].Links.Related.Should().Be($"http://localhost/photos/{existingPhoto.StringId}/album"); + responseDocument.SingleData.Links.Self.Should().Be(photoLink); + responseDocument.SingleData.Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.SingleData.Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); + + string albumLink = HostPrefix + $"/photoAlbums/{existingAlbum.StringId}"; responseDocument.Included.Should().HaveCount(1); - responseDocument.Included[0].Links.Self.Should().Be($"http://localhost/photoAlbums/{existingAlbum.StringId}"); - responseDocument.Included[0].Relationships["photos"].Links.Self.Should().Be($"http://localhost/photoAlbums/{existingAlbum.StringId}/relationships/photos"); - responseDocument.Included[0].Relationships["photos"].Links.Related.Should().Be($"http://localhost/photoAlbums/{existingAlbum.StringId}/photos"); + responseDocument.Included[0].Links.Self.Should().Be(albumLink); + responseDocument.Included[0].Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.Included[0].Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithNamespaceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithNamespaceTests.cs index b038db1fa0..7dbd40ae0f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithNamespaceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithNamespaceTests.cs @@ -51,7 +51,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"/api/photoAlbums/{album.StringId}"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); @@ -59,9 +59,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Links.Next.Should().BeNull(); responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"/api/photoAlbums/{album.StringId}"); - responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be($"/api/photoAlbums/{album.StringId}/relationships/photos"); - responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be($"/api/photoAlbums/{album.StringId}/photos"); + responseDocument.SingleData.Links.Self.Should().Be(route); + responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be(route + "/relationships/photos"); + responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be(route + "/photos"); } [Fact] @@ -86,22 +86,26 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be("/api/photoAlbums?include=photos"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().BeNull(); - responseDocument.Links.First.Should().Be("/api/photoAlbums?include=photos"); - responseDocument.Links.Last.Should().Be("/api/photoAlbums?include=photos"); + responseDocument.Links.First.Should().Be(route); + responseDocument.Links.Last.Should().Be(route); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string albumLink = $"/api/photoAlbums/{album.StringId}"; + responseDocument.ManyData.Should().HaveCount(1); - responseDocument.ManyData[0].Links.Self.Should().Be($"/api/photoAlbums/{album.StringId}"); - responseDocument.ManyData[0].Relationships["photos"].Links.Self.Should().Be($"/api/photoAlbums/{album.StringId}/relationships/photos"); - responseDocument.ManyData[0].Relationships["photos"].Links.Related.Should().Be($"/api/photoAlbums/{album.StringId}/photos"); + responseDocument.ManyData[0].Links.Self.Should().Be(albumLink); + responseDocument.ManyData[0].Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.ManyData[0].Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); + + string photoLink = $"/api/photos/{album.Photos.ElementAt(0).StringId}"; responseDocument.Included.Should().HaveCount(1); - responseDocument.Included[0].Links.Self.Should().Be($"/api/photos/{album.Photos.ElementAt(0).StringId}"); - responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be($"/api/photos/{album.Photos.ElementAt(0).StringId}/relationships/album"); - responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be($"/api/photos/{album.Photos.ElementAt(0).StringId}/album"); + responseDocument.Included[0].Links.Self.Should().Be(photoLink); + responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); } [Fact] @@ -125,17 +129,19 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"/api/photos/{photo.StringId}/album"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string albumLink = $"/api/photoAlbums/{photo.Album.StringId}"; + responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"/api/photoAlbums/{photo.Album.StringId}"); - responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be($"/api/photoAlbums/{photo.Album.StringId}/relationships/photos"); - responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be($"/api/photoAlbums/{photo.Album.StringId}/photos"); + responseDocument.SingleData.Links.Self.Should().Be(albumLink); + responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); } [Fact] @@ -159,17 +165,19 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"/api/photoAlbums/{album.StringId}/photos"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().BeNull(); - responseDocument.Links.First.Should().Be($"/api/photoAlbums/{album.StringId}/photos"); + responseDocument.Links.First.Should().Be(route); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string photoLink = $"/api/photos/{album.Photos.ElementAt(0).StringId}"; + responseDocument.ManyData.Should().HaveCount(1); - responseDocument.ManyData[0].Links.Self.Should().Be($"/api/photos/{album.Photos.ElementAt(0).StringId}"); - responseDocument.ManyData[0].Relationships["album"].Links.Self.Should().Be($"/api/photos/{album.Photos.ElementAt(0).StringId}/relationships/album"); - responseDocument.ManyData[0].Relationships["album"].Links.Related.Should().Be($"/api/photos/{album.Photos.ElementAt(0).StringId}/album"); + responseDocument.ManyData[0].Links.Self.Should().Be(photoLink); + responseDocument.ManyData[0].Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.ManyData[0].Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); } [Fact] @@ -193,7 +201,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"/api/photos/{photo.StringId}/relationships/album"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().Be($"/api/photos/{photo.StringId}/album"); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); @@ -226,9 +234,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"/api/photoAlbums/{album.StringId}/relationships/photos"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().Be($"/api/photoAlbums/{album.StringId}/photos"); - responseDocument.Links.First.Should().Be($"/api/photoAlbums/{album.StringId}/relationships/photos"); + responseDocument.Links.First.Should().Be(route); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); @@ -280,24 +288,25 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.Created); - responseDocument.Links.Self.Should().Be("/api/photoAlbums?include=photos"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); - var newAlbumId = responseDocument.SingleData.Id; + string albumLink = $"/api/photoAlbums/{responseDocument.SingleData.Id}"; - responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"/api/photoAlbums/{newAlbumId}"); - responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be($"/api/photoAlbums/{newAlbumId}/relationships/photos"); - responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be($"/api/photoAlbums/{newAlbumId}/photos"); + responseDocument.SingleData.Links.Self.Should().Be(albumLink); + responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); + + string photoLink = $"/api/photos/{existingPhoto.StringId}"; responseDocument.Included.Should().HaveCount(1); - responseDocument.Included[0].Links.Self.Should().Be($"/api/photos/{existingPhoto.StringId}"); - responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be($"/api/photos/{existingPhoto.StringId}/relationships/album"); - responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be($"/api/photos/{existingPhoto.StringId}/album"); + responseDocument.Included[0].Links.Self.Should().Be(photoLink); + responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); } [Fact] @@ -341,22 +350,26 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"/api/photos/{existingPhoto.StringId}?include=album"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string photoLink = $"/api/photos/{existingPhoto.StringId}"; + responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"/api/photos/{existingPhoto.StringId}"); - responseDocument.SingleData.Relationships["album"].Links.Self.Should().Be($"/api/photos/{existingPhoto.StringId}/relationships/album"); - responseDocument.SingleData.Relationships["album"].Links.Related.Should().Be($"/api/photos/{existingPhoto.StringId}/album"); + responseDocument.SingleData.Links.Self.Should().Be(photoLink); + responseDocument.SingleData.Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.SingleData.Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); + + string albumLink = $"/api/photoAlbums/{existingAlbum.StringId}"; responseDocument.Included.Should().HaveCount(1); - responseDocument.Included[0].Links.Self.Should().Be($"/api/photoAlbums/{existingAlbum.StringId}"); - responseDocument.Included[0].Relationships["photos"].Links.Self.Should().Be($"/api/photoAlbums/{existingAlbum.StringId}/relationships/photos"); - responseDocument.Included[0].Relationships["photos"].Links.Related.Should().Be($"/api/photoAlbums/{existingAlbum.StringId}/photos"); + responseDocument.Included[0].Links.Self.Should().Be(albumLink); + responseDocument.Included[0].Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.Included[0].Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithoutNamespaceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithoutNamespaceTests.cs index ad5305a202..b42f2b8c1b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithoutNamespaceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/RelativeLinksWithoutNamespaceTests.cs @@ -51,7 +51,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"/photoAlbums/{album.StringId}"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); @@ -59,9 +59,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Links.Next.Should().BeNull(); responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"/photoAlbums/{album.StringId}"); - responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be($"/photoAlbums/{album.StringId}/relationships/photos"); - responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be($"/photoAlbums/{album.StringId}/photos"); + responseDocument.SingleData.Links.Self.Should().Be(route); + responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be(route + "/relationships/photos"); + responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be(route + "/photos"); } [Fact] @@ -86,22 +86,26 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be("/photoAlbums?include=photos"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().BeNull(); - responseDocument.Links.First.Should().Be("/photoAlbums?include=photos"); - responseDocument.Links.Last.Should().Be("/photoAlbums?include=photos"); + responseDocument.Links.First.Should().Be(route); + responseDocument.Links.Last.Should().Be(route); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string albumLink = $"/photoAlbums/{album.StringId}"; + responseDocument.ManyData.Should().HaveCount(1); - responseDocument.ManyData[0].Links.Self.Should().Be($"/photoAlbums/{album.StringId}"); - responseDocument.ManyData[0].Relationships["photos"].Links.Self.Should().Be($"/photoAlbums/{album.StringId}/relationships/photos"); - responseDocument.ManyData[0].Relationships["photos"].Links.Related.Should().Be($"/photoAlbums/{album.StringId}/photos"); + responseDocument.ManyData[0].Links.Self.Should().Be(albumLink); + responseDocument.ManyData[0].Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.ManyData[0].Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); + + string photoLink = $"/photos/{album.Photos.ElementAt(0).StringId}"; responseDocument.Included.Should().HaveCount(1); - responseDocument.Included[0].Links.Self.Should().Be($"/photos/{album.Photos.ElementAt(0).StringId}"); - responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be($"/photos/{album.Photos.ElementAt(0).StringId}/relationships/album"); - responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be($"/photos/{album.Photos.ElementAt(0).StringId}/album"); + responseDocument.Included[0].Links.Self.Should().Be(photoLink); + responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); } [Fact] @@ -125,17 +129,19 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"/photos/{photo.StringId}/album"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string albumLink = $"/photoAlbums/{photo.Album.StringId}"; + responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"/photoAlbums/{photo.Album.StringId}"); - responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be($"/photoAlbums/{photo.Album.StringId}/relationships/photos"); - responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be($"/photoAlbums/{photo.Album.StringId}/photos"); + responseDocument.SingleData.Links.Self.Should().Be(albumLink); + responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); } [Fact] @@ -159,17 +165,19 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"/photoAlbums/{album.StringId}/photos"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().BeNull(); - responseDocument.Links.First.Should().Be($"/photoAlbums/{album.StringId}/photos"); + responseDocument.Links.First.Should().Be(route); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string photoLink = $"/photos/{album.Photos.ElementAt(0).StringId}"; + responseDocument.ManyData.Should().HaveCount(1); - responseDocument.ManyData[0].Links.Self.Should().Be($"/photos/{album.Photos.ElementAt(0).StringId}"); - responseDocument.ManyData[0].Relationships["album"].Links.Self.Should().Be($"/photos/{album.Photos.ElementAt(0).StringId}/relationships/album"); - responseDocument.ManyData[0].Relationships["album"].Links.Related.Should().Be($"/photos/{album.Photos.ElementAt(0).StringId}/album"); + responseDocument.ManyData[0].Links.Self.Should().Be(photoLink); + responseDocument.ManyData[0].Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.ManyData[0].Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); } [Fact] @@ -193,7 +201,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"/photos/{photo.StringId}/relationships/album"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().Be($"/photos/{photo.StringId}/album"); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); @@ -226,9 +234,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"/photoAlbums/{album.StringId}/relationships/photos"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().Be($"/photoAlbums/{album.StringId}/photos"); - responseDocument.Links.First.Should().Be($"/photoAlbums/{album.StringId}/relationships/photos"); + responseDocument.Links.First.Should().Be(route); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); @@ -280,24 +288,25 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.Created); - responseDocument.Links.Self.Should().Be("/photoAlbums?include=photos"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); - var newAlbumId = responseDocument.SingleData.Id; + string albumLink = $"/photoAlbums/{responseDocument.SingleData.Id}"; - responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"/photoAlbums/{newAlbumId}"); - responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be($"/photoAlbums/{newAlbumId}/relationships/photos"); - responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be($"/photoAlbums/{newAlbumId}/photos"); + responseDocument.SingleData.Links.Self.Should().Be(albumLink); + responseDocument.SingleData.Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.SingleData.Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); + + string photoLink = $"/photos/{existingPhoto.StringId}"; responseDocument.Included.Should().HaveCount(1); - responseDocument.Included[0].Links.Self.Should().Be($"/photos/{existingPhoto.StringId}"); - responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be($"/photos/{existingPhoto.StringId}/relationships/album"); - responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be($"/photos/{existingPhoto.StringId}/album"); + responseDocument.Included[0].Links.Self.Should().Be(photoLink); + responseDocument.Included[0].Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.Included[0].Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); } [Fact] @@ -341,22 +350,26 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be($"/photos/{existingPhoto.StringId}?include=album"); + responseDocument.Links.Self.Should().Be(route); responseDocument.Links.Related.Should().BeNull(); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); + string photoLink = $"/photos/{existingPhoto.StringId}"; + responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Links.Self.Should().Be($"/photos/{existingPhoto.StringId}"); - responseDocument.SingleData.Relationships["album"].Links.Self.Should().Be($"/photos/{existingPhoto.StringId}/relationships/album"); - responseDocument.SingleData.Relationships["album"].Links.Related.Should().Be($"/photos/{existingPhoto.StringId}/album"); + responseDocument.SingleData.Links.Self.Should().Be(photoLink); + responseDocument.SingleData.Relationships["album"].Links.Self.Should().Be(photoLink + "/relationships/album"); + responseDocument.SingleData.Relationships["album"].Links.Related.Should().Be(photoLink + "/album"); + + string albumLink = $"/photoAlbums/{existingAlbum.StringId}"; responseDocument.Included.Should().HaveCount(1); - responseDocument.Included[0].Links.Self.Should().Be($"/photoAlbums/{existingAlbum.StringId}"); - responseDocument.Included[0].Relationships["photos"].Links.Self.Should().Be($"/photoAlbums/{existingAlbum.StringId}/relationships/photos"); - responseDocument.Included[0].Relationships["photos"].Links.Related.Should().Be($"/photoAlbums/{existingAlbum.StringId}/photos"); + responseDocument.Included[0].Links.Self.Should().Be(albumLink); + responseDocument.Included[0].Relationships["photos"].Links.Self.Should().Be(albumLink + "/relationships/photos"); + responseDocument.Included[0].Relationships["photos"].Links.Related.Should().Be(albumLink + "/photos"); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs index 7b225af336..d19b2e1d8f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs @@ -118,12 +118,13 @@ public async Task Can_create_resource() responseDocument.SingleData.Attributes["is-indoor"].Should().Be(newPool.IsIndoor); var newPoolId = int.Parse(responseDocument.SingleData.Id); + string poolLink = route + $"/{newPoolId}"; responseDocument.SingleData.Relationships.Should().NotBeEmpty(); - responseDocument.SingleData.Relationships["water-slides"].Links.Self.Should().Be($"/public-api/swimming-pools/{newPoolId}/relationships/water-slides"); - responseDocument.SingleData.Relationships["water-slides"].Links.Related.Should().Be($"/public-api/swimming-pools/{newPoolId}/water-slides"); - responseDocument.SingleData.Relationships["diving-boards"].Links.Self.Should().Be($"/public-api/swimming-pools/{newPoolId}/relationships/diving-boards"); - responseDocument.SingleData.Relationships["diving-boards"].Links.Related.Should().Be($"/public-api/swimming-pools/{newPoolId}/diving-boards"); + responseDocument.SingleData.Relationships["water-slides"].Links.Self.Should().Be(poolLink + "/relationships/water-slides"); + responseDocument.SingleData.Relationships["water-slides"].Links.Related.Should().Be(poolLink + "/water-slides"); + responseDocument.SingleData.Relationships["diving-boards"].Links.Self.Should().Be(poolLink + "/relationships/diving-boards"); + responseDocument.SingleData.Relationships["diving-boards"].Links.Related.Should().Be(poolLink + "/diving-boards"); await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs index f51e346307..89b574d492 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs @@ -15,6 +15,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings.Pagination public sealed class PaginationWithTotalCountTests : IClassFixture, QueryStringDbContext>> { + private const string HostPrefix = "http://localhost"; private const int DefaultPageSize = 5; private readonly ExampleIntegrationTestContext, QueryStringDbContext> _testContext; @@ -60,8 +61,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.ManyData[0].Id.Should().Be(posts[1].StringId); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost" + route); - responseDocument.Links.First.Should().Be("http://localhost/blogPosts?page[size]=1"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.First.Should().Be(HostPrefix + "/blogPosts?page[size]=1"); responseDocument.Links.Last.Should().Be(responseDocument.Links.Self); responseDocument.Links.Prev.Should().Be(responseDocument.Links.First); responseDocument.Links.Next.Should().BeNull(); @@ -121,11 +122,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.ManyData[0].Id.Should().Be(blog.Posts[1].StringId); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost" + route); - responseDocument.Links.First.Should().Be($"http://localhost/blogs/{blog.StringId}/posts?page[size]=1"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.First.Should().Be(HostPrefix + $"/blogs/{blog.StringId}/posts?page[size]=1"); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().Be(responseDocument.Links.First); - responseDocument.Links.Next.Should().Be($"http://localhost/blogs/{blog.StringId}/posts?page[number]=3&page[size]=1"); + responseDocument.Links.Next.Should().Be(HostPrefix + $"/blogs/{blog.StringId}/posts?page[number]=3&page[size]=1"); } [Fact] @@ -187,9 +188,9 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Included[1].Id.Should().Be(blogs[1].Posts[1].StringId); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost" + route); - responseDocument.Links.First.Should().Be("http://localhost/blogs?include=posts&page[size]=2,posts:1"); - responseDocument.Links.Last.Should().Be("http://localhost/blogs?include=posts&page[number]=2&page[size]=2,posts:1"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.First.Should().Be(HostPrefix + "/blogs?include=posts&page[size]=2,posts:1"); + responseDocument.Links.Last.Should().Be(HostPrefix + "/blogs?include=posts&page[number]=2&page[size]=2,posts:1"); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().Be(responseDocument.Links.Last); } @@ -221,7 +222,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Included[0].Id.Should().Be(blog.Owner.Posts[1].StringId); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost" + route); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); @@ -253,8 +254,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.ManyData[0].Id.Should().Be(blog.Posts[1].StringId); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost" + route); - responseDocument.Links.First.Should().Be($"http://localhost/blogs/{blog.StringId}/relationships/posts?page[size]=1"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.First.Should().Be(HostPrefix + $"/blogs/{blog.StringId}/relationships/posts?page[size]=1"); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().Be(responseDocument.Links.First); responseDocument.Links.Next.Should().BeNull(); @@ -315,8 +316,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Included[1].Id.Should().Be(posts[1].BlogPostLabels.Skip(1).First().Label.StringId); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost" + route); - responseDocument.Links.First.Should().Be("http://localhost/blogPosts?include=labels&page[size]=labels:1"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.First.Should().Be(HostPrefix + "/blogPosts?include=labels&page[size]=labels:1"); responseDocument.Links.Last.Should().Be(responseDocument.Links.First); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); @@ -358,8 +359,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.ManyData[0].Id.Should().Be(post.BlogPostLabels.ElementAt(1).Label.StringId); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost" + route); - responseDocument.Links.First.Should().Be($"http://localhost/blogPosts/{post.StringId}/relationships/labels?page[size]=1"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.First.Should().Be(HostPrefix + $"/blogPosts/{post.StringId}/relationships/labels?page[size]=1"); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().Be(responseDocument.Links.First); responseDocument.Links.Next.Should().BeNull(); @@ -399,10 +400,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Included[1].Id.Should().Be(blogs[1].Owner.Posts[1].StringId); responseDocument.Included[2].Id.Should().Be(blogs[1].Owner.Posts[1].Comments.Skip(1).First().StringId); + const string linkPrefix = HostPrefix + "/blogs?include=owner.posts.comments"; + responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost" + route); - responseDocument.Links.First.Should().Be("http://localhost/blogs?include=owner.posts.comments&page[size]=1,owner.posts:1,owner.posts.comments:1"); - responseDocument.Links.Last.Should().Be("http://localhost/blogs?include=owner.posts.comments&page[size]=1,owner.posts:1,owner.posts.comments:1&page[number]=2"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.First.Should().Be(linkPrefix + "&page[size]=1,owner.posts:1,owner.posts.comments:1"); + responseDocument.Links.Last.Should().Be(linkPrefix + "&page[size]=1,owner.posts:1,owner.posts.comments:1&page[number]=2"); responseDocument.Links.Prev.Should().Be(responseDocument.Links.First); responseDocument.Links.Next.Should().BeNull(); } @@ -478,11 +481,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.ManyData[1].Id.Should().Be(blog.Posts[1].StringId); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost" + route); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.First.Should().Be(responseDocument.Links.Self); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); - responseDocument.Links.Next.Should().Be($"http://localhost/blogs/{blog.StringId}/posts?page[number]=2"); + responseDocument.Links.Next.Should().Be(HostPrefix + $"/blogs/{blog.StringId}/posts?page[number]=2"); } [Fact] @@ -512,7 +515,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.ManyData.Should().HaveCount(25); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost" + route); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); @@ -555,11 +558,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); - responseDocument.Links.Self.Should().Be("http://localhost" + route); + responseDocument.Links.Self.Should().Be(HostPrefix + route); if (firstLink != null) { - var expected = "http://localhost" + SetPageNumberInUrl(routePrefix, firstLink.Value); + var expected = HostPrefix + SetPageNumberInUrl(routePrefix, firstLink.Value); responseDocument.Links.First.Should().Be(expected); } else @@ -569,7 +572,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => if (prevLink != null) { - var expected = "http://localhost" + SetPageNumberInUrl(routePrefix, prevLink.Value); + var expected = HostPrefix + SetPageNumberInUrl(routePrefix, prevLink.Value); responseDocument.Links.Prev.Should().Be(expected); } else @@ -579,7 +582,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => if (nextLink != null) { - var expected = "http://localhost" + SetPageNumberInUrl(routePrefix, nextLink.Value); + var expected = HostPrefix + SetPageNumberInUrl(routePrefix, nextLink.Value); responseDocument.Links.Next.Should().Be(expected); } else @@ -589,7 +592,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => if (lastLink != null) { - var expected = "http://localhost" + SetPageNumberInUrl(routePrefix, lastLink.Value); + var expected = HostPrefix + SetPageNumberInUrl(routePrefix, lastLink.Value); responseDocument.Links.Last.Should().Be(expected); } else diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithoutTotalCountTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithoutTotalCountTests.cs index 83ee1686e6..831859cace 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithoutTotalCountTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithoutTotalCountTests.cs @@ -13,6 +13,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings.Pagination public sealed class PaginationWithoutTotalCountTests : IClassFixture, QueryStringDbContext>> { + private const string HostPrefix = "http://localhost"; private const int DefaultPageSize = 5; private readonly ExampleIntegrationTestContext, QueryStringDbContext> _testContext; @@ -45,7 +46,7 @@ public async Task Hides_pagination_links_when_unconstrained_page_size() httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost/blogPosts?foo=bar"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); responseDocument.Links.First.Should().BeNull(); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); @@ -74,8 +75,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost/blogPosts?page[size]=8&foo=bar"); - responseDocument.Links.First.Should().Be("http://localhost/blogPosts?page[size]=8&foo=bar"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.First.Should().Be(HostPrefix + route); responseDocument.Links.Last.Should().BeNull(); responseDocument.Links.Prev.Should().BeNull(); responseDocument.Links.Next.Should().BeNull(); @@ -100,10 +101,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost/blogPosts?page[number]=2&foo=bar"); - responseDocument.Links.First.Should().Be("http://localhost/blogPosts?foo=bar"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.First.Should().Be(HostPrefix + "/blogPosts?foo=bar"); responseDocument.Links.Last.Should().BeNull(); - responseDocument.Links.Prev.Should().Be("http://localhost/blogPosts?foo=bar"); + responseDocument.Links.Prev.Should().Be(HostPrefix + "/blogPosts?foo=bar"); responseDocument.Links.Next.Should().BeNull(); } @@ -131,10 +132,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.ManyData.Count.Should().BeLessThan(DefaultPageSize); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost/blogPosts?foo=bar&page[number]=3"); - responseDocument.Links.First.Should().Be("http://localhost/blogPosts?foo=bar"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.First.Should().Be(HostPrefix + "/blogPosts?foo=bar"); responseDocument.Links.Last.Should().BeNull(); - responseDocument.Links.Prev.Should().Be("http://localhost/blogPosts?foo=bar&page[number]=2"); + responseDocument.Links.Prev.Should().Be(HostPrefix + "/blogPosts?foo=bar&page[number]=2"); responseDocument.Links.Next.Should().BeNull(); } @@ -162,11 +163,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.ManyData.Should().HaveCount(DefaultPageSize); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be("http://localhost/blogPosts?page[number]=3&foo=bar"); - responseDocument.Links.First.Should().Be("http://localhost/blogPosts?foo=bar"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.First.Should().Be(HostPrefix + "/blogPosts?foo=bar"); responseDocument.Links.Last.Should().BeNull(); - responseDocument.Links.Prev.Should().Be("http://localhost/blogPosts?page[number]=2&foo=bar"); - responseDocument.Links.Next.Should().Be("http://localhost/blogPosts?page[number]=4&foo=bar"); + responseDocument.Links.Prev.Should().Be(HostPrefix + "/blogPosts?page[number]=2&foo=bar"); + responseDocument.Links.Next.Should().Be(HostPrefix + "/blogPosts?page[number]=4&foo=bar"); } [Fact] @@ -193,11 +194,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.ManyData.Should().HaveCount(DefaultPageSize); responseDocument.Links.Should().NotBeNull(); - responseDocument.Links.Self.Should().Be($"http://localhost/webAccounts/{account.StringId}/posts?page[number]=3&foo=bar"); - responseDocument.Links.First.Should().Be($"http://localhost/webAccounts/{account.StringId}/posts?foo=bar"); + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.First.Should().Be(HostPrefix + $"/webAccounts/{account.StringId}/posts?foo=bar"); responseDocument.Links.Last.Should().BeNull(); - responseDocument.Links.Prev.Should().Be($"http://localhost/webAccounts/{account.StringId}/posts?page[number]=2&foo=bar"); - responseDocument.Links.Next.Should().Be($"http://localhost/webAccounts/{account.StringId}/posts?page[number]=4&foo=bar"); + responseDocument.Links.Prev.Should().Be(HostPrefix + $"/webAccounts/{account.StringId}/posts?page[number]=2&foo=bar"); + responseDocument.Links.Next.Should().Be(HostPrefix + $"/webAccounts/{account.StringId}/posts?page[number]=4&foo=bar"); } } } From 2091d07a3a43155b50d27edf8163ae62826825f7 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Thu, 18 Feb 2021 17:51:19 +0100 Subject: [PATCH 23/60] Variable naming consistency --- .../IdObfuscation/IdObfuscationTests.cs | 170 +++++++++--------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs index 626f9e2c7e..71e130bb4b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/IdObfuscationTests.cs @@ -24,16 +24,16 @@ public IdObfuscationTests(ExampleIntegrationTestContext { await dbContext.ClearTableAsync(); - dbContext.BankAccounts.AddRange(bankAccounts); + dbContext.BankAccounts.AddRange(accounts); await dbContext.SaveChangesAsync(); }); - var route = $"/bankAccounts?filter=equals(id,'{bankAccounts[1].StringId}')"; + var route = $"/bankAccounts?filter=equals(id,'{accounts[1].StringId}')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -42,23 +42,23 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); responseDocument.ManyData.Should().HaveCount(1); - responseDocument.ManyData[0].Id.Should().Be(bankAccounts[1].StringId); + responseDocument.ManyData[0].Id.Should().Be(accounts[1].StringId); } [Fact] public async Task Can_filter_any_in_primary_resources() { // Arrange - var bankAccounts = _fakers.BankAccount.Generate(2); + var accounts = _fakers.BankAccount.Generate(2); await _testContext.RunOnDatabaseAsync(async dbContext => { await dbContext.ClearTableAsync(); - dbContext.BankAccounts.AddRange(bankAccounts); + dbContext.BankAccounts.AddRange(accounts); await dbContext.SaveChangesAsync(); }); - var route = $"/bankAccounts?filter=any(id,'{bankAccounts[1].StringId}','{HexadecimalCodec.Encode(99999999)}')"; + var route = $"/bankAccounts?filter=any(id,'{accounts[1].StringId}','{HexadecimalCodec.Encode(99999999)}')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -67,7 +67,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); responseDocument.ManyData.Should().HaveCount(1); - responseDocument.ManyData[0].Id.Should().Be(bankAccounts[1].StringId); + responseDocument.ManyData[0].Id.Should().Be(accounts[1].StringId); } [Fact] @@ -94,15 +94,15 @@ public async Task Cannot_get_primary_resource_for_invalid_ID() public async Task Can_get_primary_resource_by_ID() { // Arrange - var debitCard = _fakers.DebitCard.Generate(); + var card = _fakers.DebitCard.Generate(); await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.DebitCards.Add(debitCard); + dbContext.DebitCards.Add(card); await dbContext.SaveChangesAsync(); }); - var route = "/debitCards/" + debitCard.StringId; + var route = "/debitCards/" + card.StringId; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -111,23 +111,23 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Id.Should().Be(debitCard.StringId); + responseDocument.SingleData.Id.Should().Be(card.StringId); } [Fact] public async Task Can_get_secondary_resources() { // Arrange - var bankAccount = _fakers.BankAccount.Generate(); - bankAccount.Cards = _fakers.DebitCard.Generate(2); + var account = _fakers.BankAccount.Generate(); + account.Cards = _fakers.DebitCard.Generate(2); await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.BankAccounts.Add(bankAccount); + dbContext.BankAccounts.Add(account); await dbContext.SaveChangesAsync(); }); - var route = $"/bankAccounts/{bankAccount.StringId}/cards"; + var route = $"/bankAccounts/{account.StringId}/cards"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -136,24 +136,24 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); responseDocument.ManyData.Should().HaveCount(2); - responseDocument.ManyData[0].Id.Should().Be(bankAccount.Cards[0].StringId); - responseDocument.ManyData[1].Id.Should().Be(bankAccount.Cards[1].StringId); + responseDocument.ManyData[0].Id.Should().Be(account.Cards[0].StringId); + responseDocument.ManyData[1].Id.Should().Be(account.Cards[1].StringId); } [Fact] public async Task Can_include_resource_with_sparse_fieldset() { // Arrange - var bankAccount = _fakers.BankAccount.Generate(); - bankAccount.Cards = _fakers.DebitCard.Generate(1); + var account = _fakers.BankAccount.Generate(); + account.Cards = _fakers.DebitCard.Generate(1); await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.BankAccounts.Add(bankAccount); + dbContext.BankAccounts.Add(account); await dbContext.SaveChangesAsync(); }); - var route = $"/bankAccounts/{bankAccount.StringId}?include=cards&fields[debitCards]=ownerName"; + var route = $"/bankAccounts/{account.StringId}?include=cards&fields[debitCards]=ownerName"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -162,10 +162,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); responseDocument.SingleData.Should().NotBeNull(); - responseDocument.SingleData.Id.Should().Be(bankAccount.StringId); + responseDocument.SingleData.Id.Should().Be(account.StringId); responseDocument.Included.Should().HaveCount(1); - responseDocument.Included[0].Id.Should().Be(bankAccount.Cards[0].StringId); + responseDocument.Included[0].Id.Should().Be(account.Cards[0].StringId); responseDocument.Included[0].Attributes.Should().HaveCount(1); responseDocument.Included[0].Relationships.Should().BeNull(); } @@ -174,16 +174,16 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Can_get_relationship() { // Arrange - var bankAccount = _fakers.BankAccount.Generate(); - bankAccount.Cards = _fakers.DebitCard.Generate(1); + var account = _fakers.BankAccount.Generate(); + account.Cards = _fakers.DebitCard.Generate(1); await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.BankAccounts.Add(bankAccount); + dbContext.BankAccounts.Add(account); await dbContext.SaveChangesAsync(); }); - var route = $"/bankAccounts/{bankAccount.StringId}/relationships/cards"; + var route = $"/bankAccounts/{account.StringId}/relationships/cards"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); @@ -192,19 +192,19 @@ await _testContext.RunOnDatabaseAsync(async dbContext => httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); responseDocument.ManyData.Should().HaveCount(1); - responseDocument.ManyData[0].Id.Should().Be(bankAccount.Cards[0].StringId); + responseDocument.ManyData[0].Id.Should().Be(account.Cards[0].StringId); } [Fact] public async Task Can_create_resource_with_relationship() { // Arrange - var existingBankAccount = _fakers.BankAccount.Generate(); - var newDebitCard = _fakers.DebitCard.Generate(); + var existingAccount = _fakers.BankAccount.Generate(); + var newCard = _fakers.DebitCard.Generate(); await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.BankAccounts.Add(existingBankAccount); + dbContext.BankAccounts.Add(existingAccount); await dbContext.SaveChangesAsync(); }); @@ -215,8 +215,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => type = "debitCards", attributes = new { - ownerName = newDebitCard.OwnerName, - pinCode = newDebitCard.PinCode + ownerName = newCard.OwnerName, + pinCode = newCard.PinCode }, relationships = new { @@ -225,7 +225,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => data = new { type = "bankAccounts", - id = existingBankAccount.StringId + id = existingAccount.StringId } } } @@ -240,23 +240,23 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // Assert httpResponse.Should().HaveStatusCode(HttpStatusCode.Created); - responseDocument.SingleData.Attributes["ownerName"].Should().Be(newDebitCard.OwnerName); - responseDocument.SingleData.Attributes["pinCode"].Should().Be(newDebitCard.PinCode); + responseDocument.SingleData.Attributes["ownerName"].Should().Be(newCard.OwnerName); + responseDocument.SingleData.Attributes["pinCode"].Should().Be(newCard.PinCode); - var newDebitCardId = HexadecimalCodec.Decode(responseDocument.SingleData.Id); + var newCardId = HexadecimalCodec.Decode(responseDocument.SingleData.Id); await _testContext.RunOnDatabaseAsync(async dbContext => { - var debitCardInDatabase = await dbContext.DebitCards - .Include(debitCard => debitCard.Account) - .FirstWithIdAsync(newDebitCardId); + var cardInDatabase = await dbContext.DebitCards + .Include(card => card.Account) + .FirstWithIdAsync(newCardId); - debitCardInDatabase.OwnerName.Should().Be(newDebitCard.OwnerName); - debitCardInDatabase.PinCode.Should().Be(newDebitCard.PinCode); + cardInDatabase.OwnerName.Should().Be(newCard.OwnerName); + cardInDatabase.PinCode.Should().Be(newCard.PinCode); - debitCardInDatabase.Account.Should().NotBeNull(); - debitCardInDatabase.Account.Id.Should().Be(existingBankAccount.Id); - debitCardInDatabase.Account.StringId.Should().Be(existingBankAccount.StringId); + cardInDatabase.Account.Should().NotBeNull(); + cardInDatabase.Account.Id.Should().Be(existingAccount.Id); + cardInDatabase.Account.StringId.Should().Be(existingAccount.StringId); }); } @@ -264,16 +264,16 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Can_update_resource_with_relationship() { // Arrange - var existingBankAccount = _fakers.BankAccount.Generate(); - existingBankAccount.Cards = _fakers.DebitCard.Generate(1); + var existingAccount = _fakers.BankAccount.Generate(); + existingAccount.Cards = _fakers.DebitCard.Generate(1); - var existingDebitCard = _fakers.DebitCard.Generate(); + var existingCard = _fakers.DebitCard.Generate(); var newIban = _fakers.BankAccount.Generate().Iban; await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.AddRange(existingBankAccount, existingDebitCard); + dbContext.AddRange(existingAccount, existingCard); await dbContext.SaveChangesAsync(); }); @@ -282,7 +282,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => data = new { type = "bankAccounts", - id = existingBankAccount.StringId, + id = existingAccount.StringId, attributes = new { iban = newIban @@ -296,7 +296,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => new { type = "debitCards", - id = existingDebitCard.StringId + id = existingCard.StringId } } } @@ -304,7 +304,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = "/bankAccounts/" + existingBankAccount.StringId; + var route = "/bankAccounts/" + existingAccount.StringId; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePatchAsync(route, requestBody); @@ -316,15 +316,15 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var bankAccountInDatabase = await dbContext.BankAccounts - .Include(bankAccount => bankAccount.Cards) - .FirstWithIdAsync(existingBankAccount.Id); + var accountInDatabase = await dbContext.BankAccounts + .Include(account => account.Cards) + .FirstWithIdAsync(existingAccount.Id); - bankAccountInDatabase.Iban.Should().Be(newIban); + accountInDatabase.Iban.Should().Be(newIban); - bankAccountInDatabase.Cards.Should().HaveCount(1); - bankAccountInDatabase.Cards[0].Id.Should().Be(existingDebitCard.Id); - bankAccountInDatabase.Cards[0].StringId.Should().Be(existingDebitCard.StringId); + accountInDatabase.Cards.Should().HaveCount(1); + accountInDatabase.Cards[0].Id.Should().Be(existingCard.Id); + accountInDatabase.Cards[0].StringId.Should().Be(existingCard.StringId); }); } @@ -333,14 +333,14 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Can_add_to_ToMany_relationship() { // Arrange - var existingBankAccount = _fakers.BankAccount.Generate(); - existingBankAccount.Cards = _fakers.DebitCard.Generate(1); + var existingAccount = _fakers.BankAccount.Generate(); + existingAccount.Cards = _fakers.DebitCard.Generate(1); var existingDebitCard = _fakers.DebitCard.Generate(); await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.AddRange(existingBankAccount, existingDebitCard); + dbContext.AddRange(existingAccount, existingDebitCard); await dbContext.SaveChangesAsync(); }); @@ -356,7 +356,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } }; - var route = $"/bankAccounts/{existingBankAccount.StringId}/relationships/cards"; + var route = $"/bankAccounts/{existingAccount.StringId}/relationships/cards"; // Act var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody); @@ -368,11 +368,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var bankAccountInDatabase = await dbContext.BankAccounts - .Include(bankAccount => bankAccount.Cards) - .FirstWithIdAsync(existingBankAccount.Id); + var accountInDatabase = await dbContext.BankAccounts + .Include(account => account.Cards) + .FirstWithIdAsync(existingAccount.Id); - bankAccountInDatabase.Cards.Should().HaveCount(2); + accountInDatabase.Cards.Should().HaveCount(2); }); } @@ -380,12 +380,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Can_remove_from_ToMany_relationship() { // Arrange - var existingBankAccount = _fakers.BankAccount.Generate(); - existingBankAccount.Cards = _fakers.DebitCard.Generate(2); + var existingAccount = _fakers.BankAccount.Generate(); + existingAccount.Cards = _fakers.DebitCard.Generate(2); await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.BankAccounts.Add(existingBankAccount); + dbContext.BankAccounts.Add(existingAccount); await dbContext.SaveChangesAsync(); }); @@ -396,12 +396,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => new { type = "debitCards", - id = existingBankAccount.Cards[0].StringId + id = existingAccount.Cards[0].StringId } } }; - var route = $"/bankAccounts/{existingBankAccount.StringId}/relationships/cards"; + var route = $"/bankAccounts/{existingAccount.StringId}/relationships/cards"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteDeleteAsync(route, requestBody); @@ -413,11 +413,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var bankAccountInDatabase = await dbContext.BankAccounts - .Include(bankAccount => bankAccount.Cards) - .FirstWithIdAsync(existingBankAccount.Id); + var accountInDatabase = await dbContext.BankAccounts + .Include(account => account.Cards) + .FirstWithIdAsync(existingAccount.Id); - bankAccountInDatabase.Cards.Should().HaveCount(1); + accountInDatabase.Cards.Should().HaveCount(1); }); } @@ -425,16 +425,16 @@ await _testContext.RunOnDatabaseAsync(async dbContext => public async Task Can_delete_resource() { // Arrange - var existingBankAccount = _fakers.BankAccount.Generate(); - existingBankAccount.Cards = _fakers.DebitCard.Generate(1); + var existingAccount = _fakers.BankAccount.Generate(); + existingAccount.Cards = _fakers.DebitCard.Generate(1); await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.BankAccounts.Add(existingBankAccount); + dbContext.BankAccounts.Add(existingAccount); await dbContext.SaveChangesAsync(); }); - var route = "/bankAccounts/" + existingBankAccount.StringId; + var route = "/bankAccounts/" + existingAccount.StringId; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteDeleteAsync(route); @@ -446,11 +446,11 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { - var bankAccountInDatabase = await dbContext.BankAccounts - .Include(bankAccount => bankAccount.Cards) - .FirstWithIdOrDefaultAsync(existingBankAccount.Id); + var accountInDatabase = await dbContext.BankAccounts + .Include(account => account.Cards) + .FirstWithIdOrDefaultAsync(existingAccount.Id); - bankAccountInDatabase.Should().BeNull(); + accountInDatabase.Should().BeNull(); }); } From 4fbadc68ecaf5a7c73e767d8da731dab7591ddee Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 17 Feb 2021 17:51:16 +0100 Subject: [PATCH 24/60] Break up long strings to steer formatter --- .../QueryStrings/AtomicQueryStringTests.cs | 3 ++- .../AtomicAddToToManyRelationshipTests.cs | 4 +++- .../ContentNegotiation/ContentTypeHeaderTests.cs | 10 +++++----- .../NamingConventions/KebabCasingTests.cs | 3 ++- .../QueryStrings/Filtering/FilterDepthTests.cs | 4 ++++ .../Filtering/FilterOperatorTests.cs | 3 ++- .../Pagination/PaginationWithTotalCountTests.cs | 3 +-- .../QueryStrings/QueryStringTests.cs | 3 ++- .../QueryStrings/Sorting/SortTests.cs | 5 +---- .../AddToToManyRelationshipTests.cs | 16 +++++++++++----- .../RemoveFromToManyRelationshipTests.cs | 3 ++- .../ReplaceToManyRelationshipTests.cs | 3 ++- .../UpdateToOneRelationshipTests.cs | 3 ++- .../Updating/Resources/UpdateResourceTests.cs | 6 ++++-- .../DefaultBehaviorTests.cs | 15 ++++++++++----- .../ResourceInjectionTests.cs | 2 +- .../Models/HumanFavoriteContentItem.cs | 2 -- 17 files changed, 54 insertions(+), 34 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs index 0a2038f393..744db2d73b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs @@ -339,7 +339,8 @@ public async Task Cannot_use_Queryable_handler_on_operations_endpoint() var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.BadRequest); error.Title.Should().Be("Unknown query string parameter."); - error.Detail.Should().Be("Query string parameter 'isRecentlyReleased' is unknown. Set 'AllowUnknownQueryStringParameters' to 'true' in options to ignore unknown parameters."); + error.Detail.Should().Be("Query string parameter 'isRecentlyReleased' is unknown. " + + "Set 'AllowUnknownQueryStringParameters' to 'true' in options to ignore unknown parameters."); error.Source.Parameter.Should().Be("isRecentlyReleased"); } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs index 1574abd4d1..8bbddb4681 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs @@ -245,8 +245,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // @formatter:keep_existing_linebreaks restore // @formatter:wrap_chained_method_calls restore + Guid initialTrackId = existingPlaylist.PlaylistMusicTracks[0].MusicTrack.Id; + playlistInDatabase.PlaylistMusicTracks.Should().HaveCount(3); - playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingPlaylist.PlaylistMusicTracks[0].MusicTrack.Id); + playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == initialTrackId); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[0].Id); playlistInDatabase.PlaylistMusicTracks.Should().ContainSingle(playlistMusicTrack => playlistMusicTrack.MusicTrack.Id == existingTracks[1].Id); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/ContentTypeHeaderTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/ContentTypeHeaderTests.cs index 532a67c7a2..83bdf991b2 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/ContentTypeHeaderTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/ContentTypeHeaderTests.cs @@ -190,7 +190,7 @@ public async Task Denies_JsonApi_ContentType_header_with_profile() var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); error.Title.Should().Be("The specified Content-Type header value is not supported."); - error.Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; profile=something' for the Content-Type header value."); + error.Detail.Should().Be($"Please specify 'application/vnd.api+json' instead of '{contentType}' for the Content-Type header value."); } [Fact] @@ -223,7 +223,7 @@ public async Task Denies_JsonApi_ContentType_header_with_extension() var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); error.Title.Should().Be("The specified Content-Type header value is not supported."); - error.Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; ext=something' for the Content-Type header value."); + error.Detail.Should().Be($"Please specify 'application/vnd.api+json' instead of '{contentType}' for the Content-Type header value."); } [Fact] @@ -256,7 +256,7 @@ public async Task Denies_JsonApi_ContentType_header_with_AtomicOperations_extens var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); error.Title.Should().Be("The specified Content-Type header value is not supported."); - error.Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; ext=\"https://jsonapi.org/ext/atomic\"' for the Content-Type header value."); + error.Detail.Should().Be($"Please specify 'application/vnd.api+json' instead of '{contentType}' for the Content-Type header value."); } [Fact] @@ -289,7 +289,7 @@ public async Task Denies_JsonApi_ContentType_header_with_CharSet() var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); error.Title.Should().Be("The specified Content-Type header value is not supported."); - error.Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; charset=ISO-8859-4' for the Content-Type header value."); + error.Detail.Should().Be($"Please specify 'application/vnd.api+json' instead of '{contentType}' for the Content-Type header value."); } [Fact] @@ -322,7 +322,7 @@ public async Task Denies_JsonApi_ContentType_header_with_unknown_parameter() var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); error.Title.Should().Be("The specified Content-Type header value is not supported."); - error.Detail.Should().Be("Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; unknown=unexpected' for the Content-Type header value."); + error.Detail.Should().Be($"Please specify 'application/vnd.api+json' instead of '{contentType}' for the Content-Type header value."); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs index d19b2e1d8f..c6aafdba6e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs @@ -73,7 +73,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = $"/public-api/swimming-pools/{pool.StringId}/water-slides?filter=greaterThan(length-in-meters,'1')&fields[water-slides]=length-in-meters"; + var route = $"/public-api/swimming-pools/{pool.StringId}/water-slides" + + "?filter=greaterThan(length-in-meters,'1')&fields[water-slides]=length-in-meters"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs index ca8d127be7..e3904fa095 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDepthTests.cs @@ -464,11 +464,15 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); + // @formatter:keep_existing_linebreaks true + const string route = "/blogs?include=owner.posts.comments&" + "filter=and(equals(title,'Technology'),has(owner.posts),equals(owner.userName,'Smith'))&" + "filter[owner.posts]=equals(caption,'Two')&" + "filter[owner.posts.comments]=greaterThan(createdAt,'2005-05-05')"; + // @formatter:keep_existing_linebreaks restore + // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterOperatorTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterOperatorTests.cs index 082fa1d34c..4604a8d658 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterOperatorTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterOperatorTests.cs @@ -368,7 +368,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - var route = $"/filterableResources?filter={filterOperator.ToString().Camelize()}(someDateTime,'{DateTime.ParseExact(filterDateTime, "yyyy-MM-dd", null)}')"; + var route = $"/filterableResources?filter={filterOperator.ToString().Camelize()}(someDateTime," + + $"'{DateTime.ParseExact(filterDateTime, "yyyy-MM-dd", null)}')"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs index 89b574d492..d8a07d9473 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs @@ -382,8 +382,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - const string route = "/blogs?include=owner.posts.comments&" + - "page[size]=1,owner.posts:1,owner.posts.comments:1&" + + const string route = "/blogs?include=owner.posts.comments&page[size]=1,owner.posts:1,owner.posts.comments:1&" + "page[number]=2,owner.posts:2,owner.posts.comments:2"; // Act diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringTests.cs index 90445961f5..eda5933b70 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringTests.cs @@ -40,7 +40,8 @@ public async Task Cannot_use_unknown_query_string_parameter() var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.BadRequest); error.Title.Should().Be("Unknown query string parameter."); - error.Detail.Should().Be("Query string parameter 'foo' is unknown. Set 'AllowUnknownQueryStringParameters' to 'true' in options to ignore unknown parameters."); + error.Detail.Should().Be("Query string parameter 'foo' is unknown. " + + "Set 'AllowUnknownQueryStringParameters' to 'true' in options to ignore unknown parameters."); error.Source.Parameter.Should().Be("foo"); } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs index 0ae93689c9..ded585645b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Sorting/SortTests.cs @@ -448,10 +448,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await dbContext.SaveChangesAsync(); }); - const string route = "/blogs?include=owner.posts.comments&" + - "sort=-title&" + - "sort[owner.posts]=-caption&" + - "sort[owner.posts.comments]=-createdAt"; + const string route = "/blogs?include=owner.posts.comments&sort=-title&sort[owner.posts]=-caption&sort[owner.posts.comments]=-createdAt"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs index fae2970761..b9196de726 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs @@ -183,14 +183,17 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var workItemInDatabase1 = workItemsInDatabase.Single(workItem => workItem.Id == existingWorkItems[0].Id); + int tagId1 = existingWorkItems[0].WorkItemTags.ElementAt(0).Tag.Id; + int tagId2 = existingWorkItems[1].WorkItemTags.ElementAt(0).Tag.Id; + workItemInDatabase1.WorkItemTags.Should().HaveCount(2); - workItemInDatabase1.WorkItemTags.Should().ContainSingle(workItemTag => workItemTag.Tag.Id == existingWorkItems[0].WorkItemTags.ElementAt(0).Tag.Id); - workItemInDatabase1.WorkItemTags.Should().ContainSingle(workItemTag => workItemTag.Tag.Id == existingWorkItems[1].WorkItemTags.ElementAt(0).Tag.Id); + workItemInDatabase1.WorkItemTags.Should().ContainSingle(workItemTag => workItemTag.Tag.Id == tagId1); + workItemInDatabase1.WorkItemTags.Should().ContainSingle(workItemTag => workItemTag.Tag.Id == tagId2); var workItemInDatabase2 = workItemsInDatabase.Single(workItem => workItem.Id == existingWorkItems[1].Id); workItemInDatabase2.WorkItemTags.Should().HaveCount(1); - workItemInDatabase2.WorkItemTags.ElementAt(0).Tag.Id.Should().Be(existingWorkItems[1].WorkItemTags.ElementAt(0).Tag.Id); + workItemInDatabase2.WorkItemTags.ElementAt(0).Tag.Id.Should().Be(tagId2); }); } @@ -596,7 +599,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.Conflict); error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - error.Detail.Should().Be($"Expected resource of type 'workTags' in POST request body at endpoint '/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); + error.Detail.Should().Be($"Expected resource of type 'workTags' in POST request body at endpoint " + + $"'/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); } [Fact] @@ -854,10 +858,12 @@ await _testContext.RunOnDatabaseAsync(async dbContext => // @formatter:keep_existing_linebreaks restore // @formatter:wrap_chained_method_calls restore + int toItemId = existingWorkItem.RelatedToItems[0].ToItem.Id; + workItemInDatabase.RelatedToItems.Should().HaveCount(2); workItemInDatabase.RelatedToItems.Should().OnlyContain(workItemToWorkItem => workItemToWorkItem.FromItem.Id == existingWorkItem.Id); workItemInDatabase.RelatedToItems.Should().ContainSingle(workItemToWorkItem => workItemToWorkItem.ToItem.Id == existingWorkItem.Id); - workItemInDatabase.RelatedToItems.Should().ContainSingle(workItemToWorkItem => workItemToWorkItem.ToItem.Id == existingWorkItem.RelatedToItems[0].ToItem.Id); + workItemInDatabase.RelatedToItems.Should().ContainSingle(workItemToWorkItem => workItemToWorkItem.ToItem.Id == toItemId); }); } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs index 9acb820add..7e9a5a37a0 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs @@ -591,7 +591,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.Conflict); error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - error.Detail.Should().Be($"Expected resource of type 'workTags' in DELETE request body at endpoint '/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); + error.Detail.Should().Be($"Expected resource of type 'workTags' in DELETE request body at endpoint " + + $"'/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs index 4201e23f16..5283429787 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs @@ -638,7 +638,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.Conflict); error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - error.Detail.Should().Be($"Expected resource of type 'workTags' in PATCH request body at endpoint '/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); + error.Detail.Should().Be($"Expected resource of type 'workTags' in PATCH request body at endpoint " + + $"'/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs index e172e6a1e6..fd232b653d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs @@ -567,7 +567,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.Conflict); error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - error.Detail.Should().Be($"Expected resource of type 'userAccounts' in PATCH request body at endpoint '/workItems/{existingWorkItem.StringId}/relationships/assignee', instead of 'rgbColors'."); + error.Detail.Should().Be($"Expected resource of type 'userAccounts' in PATCH request body at endpoint " + + $"'/workItems/{existingWorkItem.StringId}/relationships/assignee', instead of 'rgbColors'."); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs index 090d31452f..ca346683fb 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs @@ -753,7 +753,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.Conflict); error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - error.Detail.Should().Be($"Expected resource of type 'workItems' in PATCH request body at endpoint '/workItems/{existingWorkItem.StringId}', instead of 'rgbColors'."); + error.Detail.Should().Be($"Expected resource of type 'workItems' in PATCH request body at endpoint " + + $"'/workItems/{existingWorkItem.StringId}', instead of 'rgbColors'."); } [Fact] @@ -790,7 +791,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.Conflict); error.Title.Should().Be("Resource ID mismatch between request body and endpoint URL."); - error.Detail.Should().Be($"Expected resource ID '{existingWorkItems[1].StringId}' in PATCH request body at endpoint '/workItems/{existingWorkItems[1].StringId}', instead of '{existingWorkItems[0].StringId}'."); + error.Detail.Should().Be($"Expected resource ID '{existingWorkItems[1].StringId}' in PATCH request body at endpoint " + + $"'/workItems/{existingWorkItems[1].StringId}', instead of '{existingWorkItems[0].StringId}'."); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs index 3f06344a9e..8ccc21b3e2 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs @@ -206,7 +206,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.BadRequest); error.Title.Should().Be("Failed to clear a required relationship."); - error.Detail.Should().Be($"The relationship 'customer' of resource type 'orders' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); + error.Detail.Should().Be($"The relationship 'customer' of resource type 'orders' with ID '{existingOrder.StringId}' " + + "cannot be cleared because it is a required relationship."); } [Fact] @@ -241,7 +242,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.BadRequest); error.Title.Should().Be("Failed to clear a required relationship."); - error.Detail.Should().Be($"The relationship 'customer' of resource type 'orders' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); + error.Detail.Should().Be($"The relationship 'customer' of resource type 'orders' with ID '{existingOrder.StringId}' " + + "cannot be cleared because it is a required relationship."); } [Fact] @@ -287,7 +289,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.BadRequest); error.Title.Should().Be("Failed to clear a required relationship."); - error.Detail.Should().Be($"The relationship 'orders' of resource type 'customers' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); + error.Detail.Should().Be($"The relationship 'orders' of resource type 'customers' with ID '{existingOrder.StringId}' " + + "cannot be cleared because it is a required relationship."); } [Fact] @@ -322,7 +325,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.BadRequest); error.Title.Should().Be("Failed to clear a required relationship."); - error.Detail.Should().Be($"The relationship 'orders' of resource type 'customers' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); + error.Detail.Should().Be($"The relationship 'orders' of resource type 'customers' with ID '{existingOrder.StringId}' " + + "cannot be cleared because it is a required relationship."); } [Fact] @@ -364,7 +368,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.BadRequest); error.Title.Should().Be("Failed to clear a required relationship."); - error.Detail.Should().Be($"The relationship 'orders' of resource type 'customers' with ID '{existingOrder.StringId}' cannot be cleared because it is a required relationship."); + error.Detail.Should().Be($"The relationship 'orders' of resource type 'customers' with ID '{existingOrder.StringId}' " + + "cannot be cleared because it is a required relationship."); } [Fact] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs index 240805b95c..f487f65bb7 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/ResourceInjectionTests.cs @@ -184,7 +184,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => await _testContext.RunOnDatabaseAsync(async dbContext => { var certificateInDatabase = await dbContext.GiftCertificates - .Include(giftCertificate => giftCertificate.Issuer) + .Include(certificate => certificate.Issuer) .FirstWithIdAsync(newCertificateId); certificateInDatabase.IssueDate.Should().Be(newIssueDate); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/HumanFavoriteContentItem.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/HumanFavoriteContentItem.cs index 4fbbf6b698..1494b8912e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/HumanFavoriteContentItem.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/HumanFavoriteContentItem.cs @@ -3,11 +3,9 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance.Mod public sealed class HumanFavoriteContentItem { public int ContentItemId { get; set; } - public ContentItem ContentItem { get; set; } public int HumanId { get; set; } - public Human Human { get; set; } } } From 6a9174cf6ce289261440a29031b6c6388514e7b8 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Fri, 19 Feb 2021 12:22:04 +0100 Subject: [PATCH 25/60] Extract constant --- .../AtomicOperations/Meta/AtomicResourceMetaTests.cs | 2 +- .../AtomicOperations/Meta/TextLanguageMetaDefinition.cs | 4 +++- .../ContentNegotiation/ContentTypeHeaderTests.cs | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResourceMetaTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResourceMetaTests.cs index 1541c31151..ecbfb911e2 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResourceMetaTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/AtomicResourceMetaTests.cs @@ -129,7 +129,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Results.Should().HaveCount(1); responseDocument.Results[0].SingleData.Meta.Should().HaveCount(1); - responseDocument.Results[0].SingleData.Meta["Notice"].Should().Be("See https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes for ISO 639-1 language codes."); + responseDocument.Results[0].SingleData.Meta["Notice"].Should().Be(TextLanguageMetaDefinition.NoticeText); } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/TextLanguageMetaDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/TextLanguageMetaDefinition.cs index e0fd3f9f78..93f4b6888e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/TextLanguageMetaDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/TextLanguageMetaDefinition.cs @@ -7,6 +7,8 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.Meta { public sealed class TextLanguageMetaDefinition : JsonApiResourceDefinition { + internal const string NoticeText = "See https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes for ISO 639-1 language codes."; + public TextLanguageMetaDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } @@ -15,7 +17,7 @@ public override IDictionary GetMeta(TextLanguage resource) { return new Dictionary { - ["Notice"] = "See https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes for ISO 639-1 language codes." + ["Notice"] = NoticeText }; } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/ContentTypeHeaderTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/ContentTypeHeaderTests.cs index 83bdf991b2..f32001e4a1 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/ContentTypeHeaderTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/ContentTypeHeaderTests.cs @@ -121,6 +121,7 @@ public async Task Permits_JsonApi_ContentType_header() const string contentType = HeaderConstants.MediaType; // Act + // ReSharper disable once RedundantArgumentDefaultValue var (httpResponse, _) = await _testContext.ExecutePostAsync(route, requestBody, contentType); // Assert @@ -352,6 +353,7 @@ public async Task Denies_JsonApi_ContentType_header_at_operations_endpoint() const string contentType = HeaderConstants.MediaType; // Act + // ReSharper disable once RedundantArgumentDefaultValue var (httpResponse, responseDocument) = await _testContext.ExecutePostAsync(route, requestBody, contentType); // Assert @@ -359,10 +361,12 @@ public async Task Denies_JsonApi_ContentType_header_at_operations_endpoint() responseDocument.Errors.Should().HaveCount(1); + string detail = $"Please specify '{HeaderConstants.AtomicOperationsMediaType}' instead of '{contentType}' for the Content-Type header value."; + var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType); error.Title.Should().Be("The specified Content-Type header value is not supported."); - error.Detail.Should().Be("Please specify 'application/vnd.api+json; ext=\"https://jsonapi.org/ext/atomic\"' instead of 'application/vnd.api+json' for the Content-Type header value."); + error.Detail.Should().Be(detail); } } } From d0bfb0b0881b86b09518ff332b8483f6f2c31804 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Mon, 22 Feb 2021 16:26:26 +0100 Subject: [PATCH 26/60] cleanup method --- benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs b/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs index e8449f4c4c..66c273030b 100644 --- a/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs +++ b/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs @@ -36,7 +36,10 @@ public JsonApiDeserializerBenchmarks() IResourceGraph resourceGraph = DependencyFactory.CreateResourceGraph(options); var targetedFields = new TargetedFields(); var request = new JsonApiRequest(); - _jsonApiDeserializer = new RequestDeserializer(resourceGraph, new ResourceFactory(new ServiceContainer()), targetedFields, new HttpContextAccessor(), request, options); + var resourceFactory = new ResourceFactory(new ServiceContainer()); + var httpContextAccessor = new HttpContextAccessor(); + + _jsonApiDeserializer = new RequestDeserializer(resourceGraph, resourceFactory, targetedFields, httpContextAccessor, request, options); } [Benchmark] From 2adff3cc040dd368e1bd4816e18e7ba4ba905df3 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Fri, 19 Feb 2021 16:44:02 +0100 Subject: [PATCH 27/60] Fixed naming conventions Resharper was set to auto-detect, making it ignore configured rules --- .../JsonApiDeserializerBenchmarks.cs | 4 +- .../JsonApiSerializerBenchmarks.cs | 4 +- .../Startups/Startup.cs | 4 +- .../Configuration/ResourceGraph.cs | 4 +- .../Errors/JsonApiException.cs | 4 +- .../Middleware/JsonApiMiddleware.cs | 8 +-- .../QueryableBuilding/SelectClauseBuilder.cs | 6 +- .../QueryableBuilding/WhereClauseBuilder.cs | 4 +- .../FilterQueryStringParameterReader.cs | 6 +- .../Internal/LegacyFilterNotationConverter.cs | 4 +- src/JsonApiDotNetCore/TypeHelper.cs | 4 +- .../ServiceDiscoveryFacadeTests.cs | 18 +++--- .../AtomicOperations/OperationsFakers.cs | 4 +- .../QueryStrings/AtomicQueryStringTests.cs | 10 ++-- .../CallableResourceDefinition.cs | 6 +- .../Serialization/SerializationFakers.cs | 4 +- test/TestBuildingBlocks/FrozenSystemClock.cs | 4 +- .../ObjectAssertionsExtensions.cs | 6 +- .../Create/BeforeCreateWithDbValuesTests.cs | 2 +- .../Delete/BeforeDeleteWithDbValuesTests.cs | 8 +-- .../Executor/ManyToManyOnReturnTests.cs | 12 ++-- .../Update/BeforeUpdateWithDbValuesTests.cs | 2 +- .../UnitTests/ResourceHooks/HooksDummyData.cs | 60 +++++++++---------- .../Serialization/SerializerTestsSetup.cs | 12 ++-- .../ResponseResourceObjectBuilderTests.cs | 4 +- .../Server/ResponseSerializerTests.cs | 4 +- 26 files changed, 104 insertions(+), 104 deletions(-) diff --git a/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs b/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs index 66c273030b..81a6622880 100644 --- a/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs +++ b/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs @@ -15,7 +15,7 @@ namespace Benchmarks.Serialization [MarkdownExporter] public class JsonApiDeserializerBenchmarks { - private static readonly string _content = JsonConvert.SerializeObject(new Document + private static readonly string Content = JsonConvert.SerializeObject(new Document { Data = new ResourceObject { @@ -43,6 +43,6 @@ public JsonApiDeserializerBenchmarks() } [Benchmark] - public object DeserializeSimpleObject() => _jsonApiDeserializer.Deserialize(_content); + public object DeserializeSimpleObject() => _jsonApiDeserializer.Deserialize(Content); } } diff --git a/benchmarks/Serialization/JsonApiSerializerBenchmarks.cs b/benchmarks/Serialization/JsonApiSerializerBenchmarks.cs index f9f294c26b..6407a2ccdf 100644 --- a/benchmarks/Serialization/JsonApiSerializerBenchmarks.cs +++ b/benchmarks/Serialization/JsonApiSerializerBenchmarks.cs @@ -14,7 +14,7 @@ namespace Benchmarks.Serialization [MarkdownExporter] public class JsonApiSerializerBenchmarks { - private static readonly BenchmarkResource _content = new BenchmarkResource + private static readonly BenchmarkResource Content = new BenchmarkResource { Id = 123, Name = Guid.NewGuid().ToString() @@ -53,6 +53,6 @@ private static FieldsToSerialize CreateFieldsToSerialize(IResourceGraph resource } [Benchmark] - public object SerializeSimpleObject() => _jsonApiSerializer.Serialize(_content); + public object SerializeSimpleObject() => _jsonApiSerializer.Serialize(Content); } } diff --git a/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs b/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs index 01e14a2511..9586e0ac17 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs @@ -14,7 +14,7 @@ namespace JsonApiDotNetCoreExample.Startups { public class Startup : EmptyStartup { - private static readonly Version _postgresCiBuildVersion = new Version(9, 6); + private static readonly Version PostgresCiBuildVersion = new Version(9, 6); private readonly string _connectionString; public Startup(IConfiguration configuration) @@ -31,7 +31,7 @@ public override void ConfigureServices(IServiceCollection services) services.AddDbContext(options => { options.EnableSensitiveDataLogging(); - options.UseNpgsql(_connectionString, postgresOptions => postgresOptions.SetPostgresVersion(_postgresCiBuildVersion)); + options.UseNpgsql(_connectionString, postgresOptions => postgresOptions.SetPostgresVersion(PostgresCiBuildVersion)); }); services.AddJsonApi(ConfigureJsonApiOptions, discovery => discovery.AddCurrentAssembly()); diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs index e839865dfe..f1d457d2ec 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs @@ -11,7 +11,7 @@ namespace JsonApiDotNetCore.Configuration public class ResourceGraph : IResourceGraph { private readonly IReadOnlyCollection _resources; - private static readonly Type _proxyTargetAccessorType = Type.GetType("Castle.DynamicProxy.IProxyTargetAccessor, Castle.Core"); + private static readonly Type ProxyTargetAccessorType = Type.GetType("Castle.DynamicProxy.IProxyTargetAccessor, Castle.Core"); public ResourceGraph(IReadOnlyCollection resources) { @@ -171,7 +171,7 @@ private IReadOnlyCollection Getter(Expression } private bool IsLazyLoadingProxyForResourceType(Type resourceType) => - _proxyTargetAccessorType?.IsAssignableFrom(resourceType) ?? false; + ProxyTargetAccessorType?.IsAssignableFrom(resourceType) ?? false; private static Expression RemoveConvert(Expression expression) { diff --git a/src/JsonApiDotNetCore/Errors/JsonApiException.cs b/src/JsonApiDotNetCore/Errors/JsonApiException.cs index 18e28f37b6..db40a7eb90 100644 --- a/src/JsonApiDotNetCore/Errors/JsonApiException.cs +++ b/src/JsonApiDotNetCore/Errors/JsonApiException.cs @@ -11,7 +11,7 @@ namespace JsonApiDotNetCore.Errors ///
    public class JsonApiException : Exception { - private static readonly JsonSerializerSettings _errorSerializerSettings = new JsonSerializerSettings + private static readonly JsonSerializerSettings ErrorSerializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented @@ -40,6 +40,6 @@ public JsonApiException(IEnumerable errors, Exception innerException = nu } } - public override string Message => "Errors = " + JsonConvert.SerializeObject(Errors, _errorSerializerSettings); + public override string Message => "Errors = " + JsonConvert.SerializeObject(Errors, ErrorSerializerSettings); } } diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs index 7b6d3f4412..82b8712219 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs @@ -23,8 +23,8 @@ namespace JsonApiDotNetCore.Middleware /// public sealed class JsonApiMiddleware { - private static readonly MediaTypeHeaderValue _mediaType = MediaTypeHeaderValue.Parse(HeaderConstants.MediaType); - private static readonly MediaTypeHeaderValue _atomicOperationsMediaType = MediaTypeHeaderValue.Parse(HeaderConstants.AtomicOperationsMediaType); + private static readonly MediaTypeHeaderValue MediaType = MediaTypeHeaderValue.Parse(HeaderConstants.MediaType); + private static readonly MediaTypeHeaderValue AtomicOperationsMediaType = MediaTypeHeaderValue.Parse(HeaderConstants.AtomicOperationsMediaType); private readonly RequestDelegate _next; @@ -51,7 +51,7 @@ public async Task Invoke(HttpContext httpContext, if (primaryResourceContext != null) { if (!await ValidateContentTypeHeaderAsync(HeaderConstants.MediaType, httpContext, options.SerializerSettings) || - !await ValidateAcceptHeaderAsync(_mediaType, httpContext, options.SerializerSettings)) + !await ValidateAcceptHeaderAsync(MediaType, httpContext, options.SerializerSettings)) { return; } @@ -63,7 +63,7 @@ public async Task Invoke(HttpContext httpContext, else if (IsOperationsRequest(routeValues)) { if (!await ValidateContentTypeHeaderAsync(HeaderConstants.AtomicOperationsMediaType, httpContext, options.SerializerSettings) || - !await ValidateAcceptHeaderAsync(_atomicOperationsMediaType, httpContext, options.SerializerSettings)) + !await ValidateAcceptHeaderAsync(AtomicOperationsMediaType, httpContext, options.SerializerSettings)) { return; } diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs index add410375e..71fd79a3d8 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs @@ -18,7 +18,7 @@ namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding /// public class SelectClauseBuilder : QueryClauseBuilder { - private static readonly ConstantExpression _nullConstant = Expression.Constant(null); + private static readonly ConstantExpression NullConstant = Expression.Constant(null); private readonly Expression _source; private readonly IModel _entityModel; @@ -207,8 +207,8 @@ private Expression CreateCollectionInitializer(LambdaScope lambdaScope, Property private static Expression TestForNull(Expression expressionToTest, Expression ifFalseExpression) { - BinaryExpression equalsNull = Expression.Equal(expressionToTest, _nullConstant); - return Expression.Condition(equalsNull, Expression.Convert(_nullConstant, expressionToTest.Type), ifFalseExpression); + BinaryExpression equalsNull = Expression.Equal(expressionToTest, NullConstant); + return Expression.Condition(equalsNull, Expression.Convert(NullConstant, expressionToTest.Type), ifFalseExpression); } private static Expression CopyCollectionExtensionMethodCall(Expression source, string operationName, Type elementType) diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs index e70a57caa5..5c1a063172 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs @@ -14,7 +14,7 @@ namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding /// public class WhereClauseBuilder : QueryClauseBuilder { - private static readonly ConstantExpression _nullConstant = Expression.Constant(null); + private static readonly ConstantExpression NullConstant = Expression.Constant(null); private readonly Expression _source; private readonly Type _extensionType; @@ -252,7 +252,7 @@ private static Expression WrapInConvert(Expression expression, Type targetType) public override Expression VisitNullConstant(NullConstantExpression expression, Type expressionType) { - return _nullConstant; + return NullConstant; } public override Expression VisitLiteralConstant(LiteralConstantExpression expression, Type expressionType) diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs index 3e90992d39..30160003b6 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs @@ -16,7 +16,7 @@ namespace JsonApiDotNetCore.QueryStrings.Internal { public class FilterQueryStringParameterReader : QueryStringParameterReader, IFilterQueryStringParameterReader { - private static readonly LegacyFilterNotationConverter _legacyConverter = new LegacyFilterNotationConverter(); + private static readonly LegacyFilterNotationConverter LegacyConverter = new LegacyFilterNotationConverter(); private readonly IJsonApiOptions _options; private readonly QueryStringParameterScopeParser _scopeParser; @@ -79,7 +79,7 @@ private IEnumerable ExtractParameterValues(string parameterName, StringV { if (_options.EnableLegacyFilterNotation) { - foreach (string condition in _legacyConverter.ExtractConditions(parameterName, parameterValue)) + foreach (string condition in LegacyConverter.ExtractConditions(parameterName, parameterValue)) { yield return condition; } @@ -97,7 +97,7 @@ private void ReadSingleValue(string parameterName, string parameterValue) { if (_options.EnableLegacyFilterNotation) { - (parameterName, parameterValue) = _legacyConverter.Convert(parameterName, parameterValue); + (parameterName, parameterValue) = LegacyConverter.Convert(parameterName, parameterValue); } ResourceFieldChainExpression scope = GetScope(parameterName); diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs index 79a657c90e..4b110f74c7 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs @@ -15,7 +15,7 @@ public sealed class LegacyFilterNotationConverter private const string InPrefix = "in:"; private const string NotInPrefix = "nin:"; - private static readonly Dictionary _prefixConversionTable = new Dictionary + private static readonly Dictionary PrefixConversionTable = new Dictionary { ["eq:"] = Keywords.Equals, ["lt:"] = Keywords.LessThan, @@ -55,7 +55,7 @@ public IEnumerable ExtractConditions(string parameterName, string parame var attributeName = ExtractAttributeName(parameterName); - foreach (var (prefix, keyword) in _prefixConversionTable) + foreach (var (prefix, keyword) in PrefixConversionTable) { if (parameterValue.StartsWith(prefix, StringComparison.Ordinal)) { diff --git a/src/JsonApiDotNetCore/TypeHelper.cs b/src/JsonApiDotNetCore/TypeHelper.cs index d1ed13562e..e729e4f2b3 100644 --- a/src/JsonApiDotNetCore/TypeHelper.cs +++ b/src/JsonApiDotNetCore/TypeHelper.cs @@ -11,7 +11,7 @@ namespace JsonApiDotNetCore { internal static class TypeHelper { - private static readonly Type[] _hashSetCompatibleCollectionTypes = + private static readonly Type[] HashSetCompatibleCollectionTypes = { typeof(HashSet<>), typeof(ICollection<>), typeof(ISet<>), typeof(IEnumerable<>), typeof(IReadOnlyCollection<>) }; @@ -251,7 +251,7 @@ public static bool TypeCanContainHashSet(Type collectionType) if (collectionType.IsGenericType) { var openCollectionType = collectionType.GetGenericTypeDefinition(); - return _hashSetCompatibleCollectionTypes.Contains(openCollectionType); + return HashSetCompatibleCollectionTypes.Contains(openCollectionType); } return false; diff --git a/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs b/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs index 6845430880..d3401230d0 100644 --- a/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs +++ b/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs @@ -19,7 +19,7 @@ namespace DiscoveryTests { public sealed class ServiceDiscoveryFacadeTests { - private static readonly NullLoggerFactory _loggerFactory = NullLoggerFactory.Instance; + private static readonly NullLoggerFactory LoggerFactory = NullLoggerFactory.Instance; private readonly IServiceCollection _services = new ServiceCollection(); private readonly JsonApiOptions _options = new JsonApiOptions(); private readonly ResourceGraphBuilder _resourceGraphBuilder; @@ -31,7 +31,7 @@ public ServiceDiscoveryFacadeTests() _services.AddScoped(_ => dbResolverMock.Object); _services.AddSingleton(_options); - _services.AddSingleton(_loggerFactory); + _services.AddSingleton(LoggerFactory); _services.AddScoped(_ => new Mock().Object); _services.AddScoped(_ => new Mock().Object); _services.AddScoped(_ => new Mock().Object); @@ -44,14 +44,14 @@ public ServiceDiscoveryFacadeTests() _services.AddScoped(_ => new Mock().Object); _services.AddScoped(_ => new Mock().Object); - _resourceGraphBuilder = new ResourceGraphBuilder(_options, _loggerFactory); + _resourceGraphBuilder = new ResourceGraphBuilder(_options, LoggerFactory); } [Fact] public void Can_add_resources_from_assembly_to_graph() { // Arrange - var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, _options, _loggerFactory); + var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, _options, LoggerFactory); facade.AddAssembly(typeof(Person).Assembly); // Act @@ -71,7 +71,7 @@ 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, _options, _loggerFactory); + var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, _options, LoggerFactory); facade.AddCurrentAssembly(); // Act @@ -88,7 +88,7 @@ public void Can_add_resource_from_current_assembly_to_graph() public void Can_add_resource_service_from_current_assembly_to_container() { // Arrange - var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, _options, _loggerFactory); + var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, _options, LoggerFactory); facade.AddCurrentAssembly(); // Act @@ -105,7 +105,7 @@ 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, _options, _loggerFactory); + var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, _options, LoggerFactory); facade.AddCurrentAssembly(); // Act @@ -122,7 +122,7 @@ 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, _options, _loggerFactory); + var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, _options, LoggerFactory); facade.AddCurrentAssembly(); // Act @@ -139,7 +139,7 @@ public void Can_add_resource_definition_from_current_assembly_to_container() public void Can_add_resource_hooks_definition_from_current_assembly_to_container() { // Arrange - var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, _options, _loggerFactory); + var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, _options, LoggerFactory); facade.AddCurrentAssembly(); _options.EnableResourceHooks = true; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsFakers.cs index 75c9eef737..d652a8bed5 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsFakers.cs @@ -12,7 +12,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations { internal sealed class OperationsFakers : FakerContainer { - private static readonly Lazy> _lazyLanguageIsoCodes = + private static readonly Lazy> LazyLanguageIsoCodes = new Lazy>(() => CultureInfo .GetCultures(CultureTypes.NeutralCultures) .Where(culture => !string.IsNullOrEmpty(culture.Name)) @@ -41,7 +41,7 @@ internal sealed class OperationsFakers : FakerContainer private readonly Lazy> _lazyTextLanguageFaker = new Lazy>(() => new Faker() .UseSeed(GetFakerSeed()) - .RuleFor(textLanguage => textLanguage.IsoCode, f => f.PickRandom(_lazyLanguageIsoCodes.Value))); + .RuleFor(textLanguage => textLanguage.IsoCode, f => f.PickRandom(LazyLanguageIsoCodes.Value))); private readonly Lazy> _lazyPerformerFaker = new Lazy>(() => new Faker() diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs index 744db2d73b..4b71f7215c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/AtomicQueryStringTests.cs @@ -17,7 +17,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.QueryS public sealed class AtomicQueryStringTests : IClassFixture, OperationsDbContext>> { - private static readonly DateTime _frozenTime = 30.July(2018).At(13, 46, 12); + private static readonly DateTime FrozenTime = 30.July(2018).At(13, 46, 12); private readonly ExampleIntegrationTestContext, OperationsDbContext> _testContext; private readonly OperationsFakers _fakers = new OperationsFakers(); @@ -30,7 +30,7 @@ public AtomicQueryStringTests(ExampleIntegrationTestContext(new FrozenSystemClock {UtcNow = _frozenTime}); + services.AddSingleton(new FrozenSystemClock {UtcNow = FrozenTime}); services.AddScoped, MusicTrackReleaseDefinition>(); }); @@ -278,9 +278,9 @@ public async Task Can_use_Queryable_handler_on_resource_endpoint() { // Arrange var musicTracks = _fakers.MusicTrack.Generate(3); - musicTracks[0].ReleasedAt = _frozenTime.AddMonths(5); - musicTracks[1].ReleasedAt = _frozenTime.AddMonths(-5); - musicTracks[2].ReleasedAt = _frozenTime.AddMonths(-1); + musicTracks[0].ReleasedAt = FrozenTime.AddMonths(5); + musicTracks[1].ReleasedAt = FrozenTime.AddMonths(-5); + musicTracks[2].ReleasedAt = FrozenTime.AddMonths(-1); await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs index a1b4eae3da..1061613f6c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs @@ -14,7 +14,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceDefinitions public sealed class CallableResourceDefinition : JsonApiResourceDefinition { private readonly IUserRolesService _userRolesService; - private static readonly PageSize _maxPageSize = new PageSize(5); + private static readonly PageSize MaxPageSize = new PageSize(5); public CallableResourceDefinition(IResourceGraph resourceGraph, IUserRolesService userRolesService) : base(resourceGraph) { @@ -77,11 +77,11 @@ public override PaginationExpression OnApplyPagination(PaginationExpression exis if (existingPagination != null) { - var pageSize = existingPagination.PageSize?.Value <= _maxPageSize.Value ? existingPagination.PageSize : _maxPageSize; + var pageSize = existingPagination.PageSize?.Value <= MaxPageSize.Value ? existingPagination.PageSize : MaxPageSize; return new PaginationExpression(existingPagination.PageNumber, pageSize); } - return new PaginationExpression(PageNumber.ValueOne, _maxPageSize); + return new PaginationExpression(PageNumber.ValueOne, MaxPageSize); } public override SparseFieldSetExpression OnApplySparseFieldSet(SparseFieldSetExpression existingSparseFieldSet) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationFakers.cs index 8b6414e70f..acaeafa90b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationFakers.cs @@ -9,7 +9,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Serialization { internal sealed class SerializationFakers : FakerContainer { - private static readonly TimeSpan[] _meetingDurations = + private static readonly TimeSpan[] MeetingDurations = { TimeSpan.FromMinutes(15), TimeSpan.FromMinutes(30), @@ -22,7 +22,7 @@ internal sealed class SerializationFakers : FakerContainer .UseSeed(GetFakerSeed()) .RuleFor(meeting => meeting.Title, f => f.Lorem.Word()) .RuleFor(meeting => meeting.StartTime, f => TruncateToWholeMilliseconds(f.Date.FutureOffset())) - .RuleFor(meeting => meeting.Duration, f => f.PickRandom(_meetingDurations)) + .RuleFor(meeting => meeting.Duration, f => f.PickRandom(MeetingDurations)) .RuleFor(meeting => meeting.Latitude, f => f.Address.Latitude()) .RuleFor(meeting => meeting.Longitude, f => f.Address.Longitude())); diff --git a/test/TestBuildingBlocks/FrozenSystemClock.cs b/test/TestBuildingBlocks/FrozenSystemClock.cs index 91a361624e..3cca8ff3be 100644 --- a/test/TestBuildingBlocks/FrozenSystemClock.cs +++ b/test/TestBuildingBlocks/FrozenSystemClock.cs @@ -5,9 +5,9 @@ namespace TestBuildingBlocks { public sealed class FrozenSystemClock : ISystemClock { - private static readonly DateTimeOffset _defaultTime = + private static readonly DateTimeOffset DefaultTime = new DateTimeOffset(new DateTime(2000, 1, 1, 1, 1, 1), TimeSpan.FromHours(1)); - public DateTimeOffset UtcNow { get; set; } = _defaultTime; + public DateTimeOffset UtcNow { get; set; } = DefaultTime; } } diff --git a/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs b/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs index eadb4f3055..f0fe3825ed 100644 --- a/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs +++ b/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs @@ -11,7 +11,7 @@ public static class ObjectAssertionsExtensions { private const decimal NumericPrecision = 0.00000000001M; - private static readonly JsonSerializerSettings _deserializationSettings = new JsonSerializerSettings + private static readonly JsonSerializerSettings DeserializationSettings = new JsonSerializerSettings { Formatting = Formatting.Indented }; @@ -65,8 +65,8 @@ public static AndConstraint> BeApproximately( public static void BeJson(this StringAssertions source, string expected, string because = "", params object[] becauseArgs) { - var sourceToken = JsonConvert.DeserializeObject(source.Subject, _deserializationSettings); - var expectedToken = JsonConvert.DeserializeObject(expected, _deserializationSettings); + var sourceToken = JsonConvert.DeserializeObject(source.Subject, DeserializationSettings); + var expectedToken = JsonConvert.DeserializeObject(expected, DeserializationSettings); string sourceText = sourceToken?.ToString(); string expectedText = expectedToken?.ToString(); diff --git a/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateWithDbValuesTests.cs b/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateWithDbValuesTests.cs index 9249ff0a68..20d2ed0a43 100644 --- a/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateWithDbValuesTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Create/BeforeCreateWithDbValuesTests.cs @@ -29,7 +29,7 @@ public BeforeCreateWithDbValuesTests() var person = _todoList[0].OneToOnePerson; person.LastName = LastName; _personId = person.Id.ToString(); - var implicitTodo = _todoFaker.Generate(); + var implicitTodo = TodoFaker.Generate(); implicitTodo.Id += 1000; implicitTodo.OneToOnePerson = person; implicitTodo.Description = Description + Description; diff --git a/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs index b56d3a2cc6..33eef8a83c 100644 --- a/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs @@ -17,10 +17,10 @@ public sealed class BeforeDeleteWithDbValuesTests : HooksTestsSetup private readonly Person _person; public BeforeDeleteWithDbValuesTests() { - _person = _personFaker.Generate(); - var todo1 = _todoFaker.Generate(); - var todo2 = _todoFaker.Generate(); - var passport = _passportFaker.Generate(); + _person = PersonFaker.Generate(); + var todo1 = TodoFaker.Generate(); + var todo2 = TodoFaker.Generate(); + var passport = PassportFaker.Generate(); _person.Passport = passport; _person.TodoItems = new HashSet { todo1 }; diff --git a/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs b/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs index 85767a9e03..5a08ab777a 100644 --- a/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs @@ -13,9 +13,9 @@ public sealed class ManyToManyOnReturnTests : HooksTestsSetup private (List
    , List, List) CreateDummyData() { - var tagsSubset = _tagFaker.Generate(3); - var joinsSubSet = _articleTagFaker.Generate(3); - var articleTagsSubset = _articleFaker.Generate(); + var tagsSubset = TagFaker.Generate(3); + var joinsSubSet = ArticleTagFaker.Generate(3); + var articleTagsSubset = ArticleFaker.Generate(); articleTagsSubset.ArticleTags = joinsSubSet.ToHashSet(); for (int i = 0; i < 3; i++) { @@ -23,10 +23,10 @@ public sealed class ManyToManyOnReturnTests : HooksTestsSetup joinsSubSet[i].Tag = tagsSubset[i]; } - var allTags = _tagFaker.Generate(3).Concat(tagsSubset).ToList(); - var completeJoin = _articleTagFaker.Generate(6); + var allTags = TagFaker.Generate(3).Concat(tagsSubset).ToList(); + var completeJoin = ArticleTagFaker.Generate(6); - var articleWithAllTags = _articleFaker.Generate(); + var articleWithAllTags = ArticleFaker.Generate(); articleWithAllTags.ArticleTags = completeJoin.ToHashSet(); for (int i = 0; i < 6; i++) diff --git a/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateWithDbValuesTests.cs b/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateWithDbValuesTests.cs index 632633ca77..1e92475a0d 100644 --- a/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateWithDbValuesTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Update/BeforeUpdateWithDbValuesTests.cs @@ -29,7 +29,7 @@ public BeforeUpdateWithDbValuesTests() _personId = personId.ToString(); var implicitPersonId = personId + 10000; - var implicitTodo = _todoFaker.Generate(); + var implicitTodo = TodoFaker.Generate(); implicitTodo.Id += 1000; implicitTodo.OneToOnePerson = new Person {Id = personId, LastName = LastName}; implicitTodo.Description = Description + Description; diff --git a/test/UnitTests/ResourceHooks/HooksDummyData.cs b/test/UnitTests/ResourceHooks/HooksDummyData.cs index 48f30be3a9..158832c14c 100644 --- a/test/UnitTests/ResourceHooks/HooksDummyData.cs +++ b/test/UnitTests/ResourceHooks/HooksDummyData.cs @@ -15,13 +15,13 @@ public class HooksDummyData protected ResourceHook[] NoHooks { get; } = new ResourceHook[0]; protected ResourceHook[] EnableDbValues { get; } = { ResourceHook.BeforeUpdate, ResourceHook.BeforeUpdateRelationship }; protected ResourceHook[] DisableDbValues { get; } = new ResourceHook[0]; - protected readonly Faker _todoFaker; - protected readonly Faker _personFaker; - protected readonly Faker
    _articleFaker; - protected readonly Faker _tagFaker; - protected readonly Faker _articleTagFaker; - protected readonly Faker _identifiableArticleTagFaker; - protected readonly Faker _passportFaker; + protected readonly Faker TodoFaker; + protected readonly Faker PersonFaker; + protected readonly Faker
    ArticleFaker; + protected readonly Faker TagFaker; + protected readonly Faker ArticleTagFaker; + protected readonly Faker IdentifiableArticleTagFaker; + protected readonly Faker PassportFaker; public HooksDummyData() { @@ -37,24 +37,24 @@ public HooksDummyData() // @formatter:wrap_chained_method_calls chop_always // @formatter:keep_existing_linebreaks true - _todoFaker = new Faker() + TodoFaker = new Faker() .RuleFor(x => x.Id, f => f.UniqueIndex + 1); - _personFaker = new Faker() + PersonFaker = new Faker() .RuleFor(x => x.Id, f => f.UniqueIndex + 1); - _articleFaker = new Faker
    () + ArticleFaker = new Faker
    () .RuleFor(x => x.Id, f => f.UniqueIndex + 1); - _tagFaker = new Faker() + TagFaker = new Faker() .RuleFor(x => x.Id, f => f.UniqueIndex + 1); - _articleTagFaker = new Faker(); + ArticleTagFaker = new Faker(); - _identifiableArticleTagFaker = new Faker() + IdentifiableArticleTagFaker = new Faker() .RuleFor(x => x.Id, f => f.UniqueIndex + 1); - _passportFaker = new Faker() + PassportFaker = new Faker() .RuleFor(x => x.Id, f => f.UniqueIndex + 1); // @formatter:wrap_chained_method_calls restore @@ -63,8 +63,8 @@ public HooksDummyData() protected List CreateTodoWithToOnePerson() { - var todoItem = _todoFaker.Generate(); - var person = _personFaker.Generate(); + var todoItem = TodoFaker.Generate(); + var person = PersonFaker.Generate(); var todoList = new List { todoItem }; person.OneToOneTodoItem = todoItem; todoItem.OneToOnePerson = person; @@ -73,8 +73,8 @@ protected List CreateTodoWithToOnePerson() protected HashSet CreateTodoWithOwner() { - var todoItem = _todoFaker.Generate(); - var person = _personFaker.Generate(); + var todoItem = TodoFaker.Generate(); + var person = PersonFaker.Generate(); var todoList = new HashSet { todoItem }; person.AssignedTodoItems = todoList; todoItem.Owner = person; @@ -83,9 +83,9 @@ protected HashSet CreateTodoWithOwner() protected (List
    , List, List) CreateManyToManyData() { - var tagsSubset = _tagFaker.Generate(3); - var joinsSubSet = _articleTagFaker.Generate(3); - var articleTagsSubset = _articleFaker.Generate(); + var tagsSubset = TagFaker.Generate(3); + var joinsSubSet = ArticleTagFaker.Generate(3); + var articleTagsSubset = ArticleFaker.Generate(); articleTagsSubset.ArticleTags = joinsSubSet.ToHashSet(); for (int i = 0; i < 3; i++) { @@ -93,10 +93,10 @@ protected HashSet CreateTodoWithOwner() joinsSubSet[i].Tag = tagsSubset[i]; } - var allTags = _tagFaker.Generate(3).Concat(tagsSubset).ToList(); - var completeJoin = _articleTagFaker.Generate(6); + var allTags = TagFaker.Generate(3).Concat(tagsSubset).ToList(); + var completeJoin = ArticleTagFaker.Generate(6); - var articleWithAllTags = _articleFaker.Generate(); + var articleWithAllTags = ArticleFaker.Generate(); articleWithAllTags.ArticleTags = completeJoin.ToHashSet(); for (int i = 0; i < 6; i++) @@ -113,19 +113,19 @@ protected HashSet CreateTodoWithOwner() protected (List
    , List, List) CreateIdentifiableManyToManyData() { - var tagsSubset = _tagFaker.Generate(3); - var joinsSubSet = _identifiableArticleTagFaker.Generate(3); - var articleTagsSubset = _articleFaker.Generate(); + var tagsSubset = TagFaker.Generate(3); + var joinsSubSet = IdentifiableArticleTagFaker.Generate(3); + var articleTagsSubset = ArticleFaker.Generate(); articleTagsSubset.IdentifiableArticleTags = joinsSubSet.ToHashSet(); for (int i = 0; i < 3; i++) { joinsSubSet[i].Article = articleTagsSubset; joinsSubSet[i].Tag = tagsSubset[i]; } - var allTags = _tagFaker.Generate(3).Concat(tagsSubset).ToList(); - var completeJoin = _identifiableArticleTagFaker.Generate(6); + var allTags = TagFaker.Generate(3).Concat(tagsSubset).ToList(); + var completeJoin = IdentifiableArticleTagFaker.Generate(6); - var articleWithAllTags = _articleFaker.Generate(); + var articleWithAllTags = ArticleFaker.Generate(); articleWithAllTags.IdentifiableArticleTags = joinsSubSet.ToHashSet(); for (int i = 0; i < 6; i++) diff --git a/test/UnitTests/Serialization/SerializerTestsSetup.cs b/test/UnitTests/Serialization/SerializerTestsSetup.cs index 1f0e4b9fc4..a7bd82a8ad 100644 --- a/test/UnitTests/Serialization/SerializerTestsSetup.cs +++ b/test/UnitTests/Serialization/SerializerTestsSetup.cs @@ -15,12 +15,12 @@ namespace UnitTests.Serialization { public class SerializerTestsSetup : SerializationTestsSetupBase { - protected readonly TopLevelLinks _dummyTopLevelLinks; - protected readonly ResourceLinks _dummyResourceLinks; - protected readonly RelationshipLinks _dummyRelationshipLinks; + protected readonly TopLevelLinks DummyTopLevelLinks; + protected readonly ResourceLinks DummyResourceLinks; + protected readonly RelationshipLinks DummyRelationshipLinks; public SerializerTestsSetup() { - _dummyTopLevelLinks = new TopLevelLinks + DummyTopLevelLinks = new TopLevelLinks { Self = "http://www.dummy.com/dummy-self-link", Next = "http://www.dummy.com/dummy-next-link", @@ -28,11 +28,11 @@ public SerializerTestsSetup() First = "http://www.dummy.com/dummy-first-link", Last = "http://www.dummy.com/dummy-last-link" }; - _dummyResourceLinks = new ResourceLinks + DummyResourceLinks = new ResourceLinks { Self = "http://www.dummy.com/dummy-resource-self-link" }; - _dummyRelationshipLinks = new RelationshipLinks + DummyRelationshipLinks = new RelationshipLinks { Related = "http://www.dummy.com/dummy-relationship-related-link", Self = "http://www.dummy.com/dummy-relationship-self-link" diff --git a/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs b/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs index 97d0b363e1..7dcc2acd64 100644 --- a/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs +++ b/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs @@ -21,7 +21,7 @@ public void Build_RelationshipNotIncludedAndLinksEnabled_RelationshipEntryWithLi { // Arrange var resource = new OneToManyPrincipal { Id = 10 }; - var builder = GetResponseResourceObjectBuilder(relationshipLinks: _dummyRelationshipLinks); + var builder = GetResponseResourceObjectBuilder(relationshipLinks: DummyRelationshipLinks); // Act var resourceObject = builder.Build(resource, relationships: _relationshipsForBuild); @@ -69,7 +69,7 @@ public void Build_RelationshipIncludedAndLinksEnabled_RelationshipEntryWithDataA { // Arrange var resource = new OneToManyPrincipal { Id = 10, Dependents = new HashSet { new OneToManyDependent { Id = 20 } } }; - var builder = GetResponseResourceObjectBuilder(inclusionChains: new List> { _relationshipsForBuild }, relationshipLinks: _dummyRelationshipLinks); + var builder = GetResponseResourceObjectBuilder(inclusionChains: new List> { _relationshipsForBuild }, relationshipLinks: DummyRelationshipLinks); // Act var resourceObject = builder.Build(resource, relationships: _relationshipsForBuild); diff --git a/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs b/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs index 874b50d4c8..c1d86e8b62 100644 --- a/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs +++ b/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs @@ -260,7 +260,7 @@ public void SerializeSingle_ResourceWithLinksEnabled_CanSerialize() { // Arrange var resource = new OneToManyPrincipal { Id = 10 }; - var serializer = GetResponseSerializer(topLinks: _dummyTopLevelLinks, relationshipLinks: _dummyRelationshipLinks, resourceLinks: _dummyResourceLinks); + var serializer = GetResponseSerializer(topLinks: DummyTopLevelLinks, relationshipLinks: DummyRelationshipLinks, resourceLinks: DummyResourceLinks); // Act string serialized = serializer.SerializeSingle(resource); @@ -330,7 +330,7 @@ public void SerializeSingle_NullWithLinksAndMeta_StillShowsLinksAndMeta() { // Arrange var meta = new Dictionary { ["test"] = "meta" }; - var serializer = GetResponseSerializer(metaDict: meta, topLinks: _dummyTopLevelLinks, relationshipLinks: _dummyRelationshipLinks, resourceLinks: _dummyResourceLinks); + var serializer = GetResponseSerializer(metaDict: meta, topLinks: DummyTopLevelLinks, relationshipLinks: DummyRelationshipLinks, resourceLinks: DummyResourceLinks); // Act string serialized = serializer.SerializeSingle(null); From 9b544c85a0cba792e9f20eff9a5bc9d0aae8acfd Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Fri, 19 Feb 2021 18:35:35 +0100 Subject: [PATCH 28/60] Additional cleanup based on suggestions from https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ --- src/Examples/GettingStarted/Program.cs | 2 +- .../Definitions/TagHooksDefinition.cs | 4 ++-- src/Examples/JsonApiDotNetCoreExample/Program.cs | 2 +- src/Examples/MultiDbContextExample/Program.cs | 2 +- src/Examples/NoEntityFrameworkExample/Program.cs | 2 +- src/Examples/ReportsExample/Program.cs | 2 +- .../AtomicOperations/LocalIdValidator.cs | 2 ++ .../Discovery/LoadDatabaseValuesAttribute.cs | 4 ++-- .../Internal/Execution/DiffableResourceHashSet.cs | 2 ++ .../Hooks/Internal/Execution/IRelationshipGetters.cs | 4 ++-- .../Internal/Execution/RelationshipsDictionary.cs | 6 ++++-- .../Hooks/Internal/Execution/ResourceHashSet.cs | 4 ++-- .../Hooks/Internal/ResourceHookExecutor.cs | 2 +- src/JsonApiDotNetCore/Middleware/TraceLogWriter.cs | 8 ++++---- .../Expressions/SparseFieldTableExpression.cs | 6 +++--- .../Queries/Internal/QueryLayerComposer.cs | 8 ++++++++ .../Internal/QueryableBuilding/QueryClauseBuilder.cs | 2 +- .../QueryableBuilding/SelectClauseBuilder.cs | 2 +- .../Internal/QueryableBuilding/WhereClauseBuilder.cs | 4 ++-- .../Queries/Internal/SparseFieldSetCache.cs | 2 ++ .../Internal/FilterQueryStringParameterReader.cs | 12 +++++++----- .../Internal/LegacyFilterNotationConverter.cs | 4 +++- .../Internal/SortQueryStringParameterReader.cs | 2 ++ .../SparseFieldSetQueryStringParameterReader.cs | 2 ++ .../Serialization/Building/LinkBuilder.cs | 6 +++--- .../Client/Internal/IRequestSerializer.cs | 4 ++-- .../Client/Internal/RequestSerializer.cs | 4 ++-- .../Objects/ResourceIdentifierObject.cs | 2 +- .../Serialization/ResponseSerializer.cs | 10 +++++----- .../Services/AsyncCollectionExtensions.cs | 5 +++++ src/JsonApiDotNetCore/TypeHelper.cs | 6 ++++-- .../NonJsonApiControllerTests.cs | 12 ++++++------ test/TestBuildingBlocks/IntegrationTest.cs | 2 +- test/UnitTests/ResourceHooks/DiscoveryTests.cs | 4 ++-- 34 files changed, 88 insertions(+), 57 deletions(-) diff --git a/src/Examples/GettingStarted/Program.cs b/src/Examples/GettingStarted/Program.cs index c7d55fcf4d..f58d01afb3 100644 --- a/src/Examples/GettingStarted/Program.cs +++ b/src/Examples/GettingStarted/Program.cs @@ -3,7 +3,7 @@ namespace GettingStarted { - public class Program + public static class Program { public static void Main(string[] args) { diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/TagHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/TagHooksDefinition.cs index 4ff4508bf7..7112924140 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/TagHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/TagHooksDefinition.cs @@ -11,9 +11,9 @@ public class TagHooksDefinition : ResourceHooksDefinition { public TagHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } - public override IEnumerable BeforeCreate(IResourceHashSet affected, ResourcePipeline pipeline) + public override IEnumerable BeforeCreate(IResourceHashSet resources, ResourcePipeline pipeline) { - return base.BeforeCreate(affected, pipeline); + return base.BeforeCreate(resources, pipeline); } public override IEnumerable OnReturn(HashSet resources, ResourcePipeline pipeline) diff --git a/src/Examples/JsonApiDotNetCoreExample/Program.cs b/src/Examples/JsonApiDotNetCoreExample/Program.cs index faf53829cb..4a6647a3f1 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Program.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Program.cs @@ -4,7 +4,7 @@ namespace JsonApiDotNetCoreExample { - public class Program + public static class Program { public static void Main(string[] args) { diff --git a/src/Examples/MultiDbContextExample/Program.cs b/src/Examples/MultiDbContextExample/Program.cs index c6e698750c..1541869cee 100644 --- a/src/Examples/MultiDbContextExample/Program.cs +++ b/src/Examples/MultiDbContextExample/Program.cs @@ -3,7 +3,7 @@ namespace MultiDbContextExample { - public class Program + public static class Program { public static void Main(string[] args) { diff --git a/src/Examples/NoEntityFrameworkExample/Program.cs b/src/Examples/NoEntityFrameworkExample/Program.cs index a4d260e5a6..f455ca9728 100755 --- a/src/Examples/NoEntityFrameworkExample/Program.cs +++ b/src/Examples/NoEntityFrameworkExample/Program.cs @@ -3,7 +3,7 @@ namespace NoEntityFrameworkExample { - public class Program + public static class Program { public static void Main(string[] args) { diff --git a/src/Examples/ReportsExample/Program.cs b/src/Examples/ReportsExample/Program.cs index d2d216af50..049930dc48 100644 --- a/src/Examples/ReportsExample/Program.cs +++ b/src/Examples/ReportsExample/Program.cs @@ -3,7 +3,7 @@ namespace ReportsExample { - public class Program + public static class Program { public static void Main(string[] args) { diff --git a/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs b/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs index 13a03f9139..27f8cbe5e4 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs @@ -25,6 +25,8 @@ public LocalIdValidator(ILocalIdTracker localIdTracker, IResourceContextProvider public void Validate(IEnumerable operations) { + ArgumentGuard.NotNull(operations, nameof(operations)); + _localIdTracker.Reset(); int operationIndex = 0; diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/LoadDatabaseValuesAttribute.cs b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/LoadDatabaseValuesAttribute.cs index 8f688f734e..c44d33469e 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/LoadDatabaseValuesAttribute.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/LoadDatabaseValuesAttribute.cs @@ -7,9 +7,9 @@ public sealed class LoadDatabaseValuesAttribute : Attribute { public bool Value { get; } - public LoadDatabaseValuesAttribute(bool mode = true) + public LoadDatabaseValuesAttribute(bool value = true) { - Value = mode; + Value = value; } } } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs index 1983969061..ebd754b8e3 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs @@ -57,6 +57,8 @@ public IEnumerable> GetDiffs() /// public new HashSet GetAffected(Expression> navigationAction) { + ArgumentGuard.NotNull(navigationAction, nameof(navigationAction)); + var propertyInfo = TypeHelper.ParseNavigationExpression(navigationAction); var propertyType = propertyInfo.PropertyType; if (TypeHelper.IsOrImplementsInterface(propertyType, typeof(IEnumerable))) diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/IRelationshipGetters.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/IRelationshipGetters.cs index ca95ddef87..7f07fc083c 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/IRelationshipGetters.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/IRelationshipGetters.cs @@ -16,9 +16,9 @@ public interface IRelationshipGetters where TLeftResource : class /// Dictionary> GetByRelationship() where TRightResource : class, IIdentifiable; /// - /// Gets a dictionary of all resources that have an affected relationship to type + /// Gets a dictionary of all resources that have an affected relationship to type /// - Dictionary> GetByRelationship(Type relatedResourceType); + Dictionary> GetByRelationship(Type resourceType); /// /// Gets a collection of all the resources for the property within /// has been affected by the request diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/RelationshipsDictionary.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/RelationshipsDictionary.cs index 9c24206530..f593839a7a 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/RelationshipsDictionary.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/RelationshipsDictionary.cs @@ -37,14 +37,16 @@ public Dictionary> GetByRelationship - public Dictionary> GetByRelationship(Type relatedType) + public Dictionary> GetByRelationship(Type resourceType) { - return this.Where(p => p.Key.RightType == relatedType).ToDictionary(p => p.Key, p => p.Value); + return this.Where(p => p.Key.RightType == resourceType).ToDictionary(p => p.Key, p => p.Value); } /// public HashSet GetAffected(Expression> navigationAction) { + ArgumentGuard.NotNull(navigationAction, nameof(navigationAction)); + var property = TypeHelper.ParseNavigationExpression(navigationAction); return this.Where(p => p.Key.Property.Name == property.Name).Select(p => p.Value).SingleOrDefault(); } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceHashSet.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceHashSet.cs index 9b61f57d36..66297ddf18 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceHashSet.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceHashSet.cs @@ -37,9 +37,9 @@ internal ResourceHashSet(IEnumerable resources, /// - public Dictionary> GetByRelationship(Type leftType) + public Dictionary> GetByRelationship(Type resourceType) { - return _relationships.GetByRelationship(leftType); + return _relationships.GetByRelationship(resourceType); } /// diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs index 03b7d32f84..252e5b540d 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs @@ -405,7 +405,7 @@ private void ValidateHookResponse(IEnumerable returnedList, ResourcePipeli { if (pipeline == ResourcePipeline.GetSingle && returnedList.Count() > 1) { - throw new ApplicationException("The returned collection from this hook may contain at most one item in the case of the " + + throw new InvalidOperationException("The returned collection from this hook may contain at most one item in the case of the " + pipeline.ToString("G") + " pipeline"); } } diff --git a/src/JsonApiDotNetCore/Middleware/TraceLogWriter.cs b/src/JsonApiDotNetCore/Middleware/TraceLogWriter.cs index 6e03c521dc..7ba6490547 100644 --- a/src/JsonApiDotNetCore/Middleware/TraceLogWriter.cs +++ b/src/JsonApiDotNetCore/Middleware/TraceLogWriter.cs @@ -42,9 +42,9 @@ private static string FormatMessage(string memberName, object parameters) builder.Append("Entering "); builder.Append(memberName); - builder.Append("("); + builder.Append('('); WriteProperties(builder, parameters); - builder.Append(")"); + builder.Append(')'); return builder.ToString(); } @@ -82,9 +82,9 @@ private static void WriteProperty(StringBuilder builder, PropertyInfo property, } else if (value is string stringValue) { - builder.Append("\""); + builder.Append('"'); builder.Append(stringValue); - builder.Append("\""); + builder.Append('"'); } else { diff --git a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldTableExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldTableExpression.cs index 455b4fc5e9..c9feca96b5 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldTableExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldTableExpression.cs @@ -38,13 +38,13 @@ public override string ToString() { if (builder.Length > 0) { - builder.Append(","); + builder.Append(','); } builder.Append(resource.PublicName); - builder.Append("("); + builder.Append('('); builder.Append(fields); - builder.Append(")"); + builder.Append(')'); } return builder.ToString(); diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs index 3334331d6f..84551a8b47 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs @@ -342,6 +342,8 @@ public QueryLayer ComposeForUpdate(TId id, ResourceContext primaryResource) /// public IEnumerable<(QueryLayer, RelationshipAttribute)> ComposeForGetTargetedSecondaryResourceIds(IIdentifiable primaryResource) { + ArgumentGuard.NotNull(primaryResource, nameof(primaryResource)); + foreach (var relationship in _targetedFields.Relationships) { object rightValue = relationship.GetValue(primaryResource); @@ -358,6 +360,9 @@ public QueryLayer ComposeForUpdate(TId id, ResourceContext primaryResource) /// public QueryLayer ComposeForGetRelationshipRightIds(RelationshipAttribute relationship, ICollection rightResourceIds) { + ArgumentGuard.NotNull(relationship, nameof(relationship)); + ArgumentGuard.NotNull(rightResourceIds, nameof(rightResourceIds)); + var rightResourceContext = _resourceContextProvider.GetResourceContext(relationship.RightType); var rightIdAttribute = GetIdAttribute(rightResourceContext); @@ -380,6 +385,9 @@ public QueryLayer ComposeForGetRelationshipRightIds(RelationshipAttribute relati /// public QueryLayer ComposeForHasMany(HasManyAttribute hasManyRelationship, TId leftId, ICollection rightResourceIds) { + ArgumentGuard.NotNull(hasManyRelationship, nameof(hasManyRelationship)); + ArgumentGuard.NotNull(rightResourceIds, nameof(rightResourceIds)); + var leftResourceContext = _resourceContextProvider.GetResourceContext(hasManyRelationship.LeftType); var leftIdAttribute = GetIdAttribute(leftResourceContext); diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryClauseBuilder.cs index 7bb2587be9..60909aa272 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryClauseBuilder.cs @@ -29,7 +29,7 @@ public override Expression VisitCount(CountExpression expression, TArgument argu var propertyExpression = TryGetCollectionCount(collectionExpression); if (propertyExpression == null) { - throw new Exception($"Field '{expression.TargetCollection}' must be a collection."); + throw new InvalidOperationException($"Field '{expression.TargetCollection}' must be a collection."); } return propertyExpression; diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs index 71fd79a3d8..582816db41 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs @@ -194,7 +194,7 @@ private Expression CreateCollectionInitializer(LambdaScope lambdaScope, Property if (typedCollectionConstructor == null) { - throw new Exception( + throw new InvalidOperationException( $"Constructor on '{typedCollection.Name}' that accepts '{enumerableOfElementType.Name}' not found."); } diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs index 5c1a063172..5c1fb942a8 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs @@ -55,7 +55,7 @@ public override Expression VisitCollectionNotEmpty(CollectionNotEmptyExpression if (elementType == null) { - throw new Exception("Expression must be a collection."); + throw new InvalidOperationException("Expression must be a collection."); } return AnyExtensionMethodCall(elementType, property); @@ -75,7 +75,7 @@ public override Expression VisitMatchText(MatchTextExpression expression, Type a if (property.Type != typeof(string)) { - throw new Exception("Expression must be a string."); + throw new InvalidOperationException("Expression must be a string."); } Expression text = Visit(expression.TextValue, property.Type); diff --git a/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs b/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs index 6adfe180a3..70b95972af 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs @@ -106,6 +106,8 @@ public IReadOnlyCollection GetIdAttributeSetForRelationshipQuery( public IReadOnlyCollection GetSparseFieldSetForSerializer(ResourceContext resourceContext) { + ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); + if (!_visitedTable.ContainsKey(resourceContext)) { var inputFields = _lazySourceTable.Value.ContainsKey(resourceContext) diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs index 30160003b6..c9830348b2 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs @@ -58,28 +58,30 @@ public virtual bool IsEnabled(DisableQueryStringAttribute disableQueryStringAttr /// public virtual bool CanRead(string parameterName) { + ArgumentGuard.NotNull(parameterName, nameof(parameterName)); + var isNested = parameterName.StartsWith("filter[", StringComparison.Ordinal) && parameterName.EndsWith("]", StringComparison.Ordinal); return parameterName == "filter" || isNested; } /// - public virtual void Read(string parameterName, StringValues parameterValues) + public virtual void Read(string parameterName, StringValues parameterValue) { _lastParameterName = parameterName; - foreach (string parameterValue in ExtractParameterValues(parameterName, parameterValues)) + foreach (string value in ExtractParameterValues(parameterValue)) { - ReadSingleValue(parameterName, parameterValue); + ReadSingleValue(parameterName, value); } } - private IEnumerable ExtractParameterValues(string parameterName, StringValues parameterValues) + private IEnumerable ExtractParameterValues(StringValues parameterValues) { foreach (string parameterValue in parameterValues) { if (_options.EnableLegacyFilterNotation) { - foreach (string condition in LegacyConverter.ExtractConditions(parameterName, parameterValue)) + foreach (string condition in LegacyConverter.ExtractConditions(parameterValue)) { yield return condition; } diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs index 4b110f74c7..aa9aba3211 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs @@ -25,8 +25,10 @@ public sealed class LegacyFilterNotationConverter ["like:"] = Keywords.Contains }; - public IEnumerable ExtractConditions(string parameterName, string parameterValue) + public IEnumerable ExtractConditions(string parameterValue) { + ArgumentGuard.NotNull(parameterValue, nameof(parameterValue)); + if (parameterValue.StartsWith(ExpressionPrefix, StringComparison.Ordinal) || parameterValue.StartsWith(InPrefix, StringComparison.Ordinal) || parameterValue.StartsWith(NotInPrefix, StringComparison.Ordinal)) diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/SortQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/SortQueryStringParameterReader.cs index 6df27aca86..af6a56ccad 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/SortQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/SortQueryStringParameterReader.cs @@ -47,6 +47,8 @@ public virtual bool IsEnabled(DisableQueryStringAttribute disableQueryStringAttr /// public virtual bool CanRead(string parameterName) { + ArgumentGuard.NotNull(parameterName, nameof(parameterName)); + var isNested = parameterName.StartsWith("sort[", StringComparison.Ordinal) && parameterName.EndsWith("]", StringComparison.Ordinal); return parameterName == "sort" || isNested; } diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs index 578e1fe022..98bfaf4179 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs @@ -48,6 +48,8 @@ public virtual bool IsEnabled(DisableQueryStringAttribute disableQueryStringAttr /// public virtual bool CanRead(string parameterName) { + ArgumentGuard.NotNull(parameterName, nameof(parameterName)); + return parameterName.StartsWith("fields[", StringComparison.Ordinal) && parameterName.EndsWith("]", StringComparison.Ordinal); } diff --git a/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs index 4da147a5ae..4e5448d944 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs @@ -112,12 +112,12 @@ private string GetSelfTopLevelLink(ResourceContext resourceContext, Action /// to conveniently access the desired instances. /// - public IReadOnlyCollection AttributesToSerialize { set; } + public IReadOnlyCollection AttributesToSerialize { get; set; } /// /// Sets the relationships that will be included in the serialized request body. /// You can use /// to conveniently access the desired instances. /// - public IReadOnlyCollection RelationshipsToSerialize { set; } + public IReadOnlyCollection RelationshipsToSerialize { get; set; } } } diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs index b96cc81700..e980253fc2 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs @@ -69,10 +69,10 @@ public string Serialize(IReadOnlyCollection resources) } /// - public IReadOnlyCollection AttributesToSerialize { private get; set; } + public IReadOnlyCollection AttributesToSerialize { get; set; } /// - public IReadOnlyCollection RelationshipsToSerialize { private get; set; } + public IReadOnlyCollection RelationshipsToSerialize { get; set; } /// /// By default, the client serializer includes all attributes in the result, diff --git a/src/JsonApiDotNetCore/Serialization/Objects/ResourceIdentifierObject.cs b/src/JsonApiDotNetCore/Serialization/Objects/ResourceIdentifierObject.cs index b216011bf7..672255d96e 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/ResourceIdentifierObject.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/ResourceIdentifierObject.cs @@ -43,7 +43,7 @@ protected static void WriteMember(StringBuilder builder, string memberName, stri builder.Append(memberName); builder.Append("=\""); builder.Append(memberValue); - builder.Append("\""); + builder.Append('"'); } } } diff --git a/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs b/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs index be3141c8b3..45711086fd 100644 --- a/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs @@ -57,19 +57,19 @@ public ResponseSerializer(IMetaBuilder metaBuilder, } /// - public string Serialize(object data) + public string Serialize(object content) { - if (data == null || data is IIdentifiable) + if (content == null || content is IIdentifiable) { - return SerializeSingle((IIdentifiable)data); + return SerializeSingle((IIdentifiable)content); } - if (data is IEnumerable collectionOfIdentifiable) + if (content is IEnumerable collectionOfIdentifiable) { return SerializeMany(collectionOfIdentifiable.ToArray()); } - if (data is ErrorDocument errorDocument) + if (content is ErrorDocument errorDocument) { return SerializeErrorDocument(errorDocument); } diff --git a/src/JsonApiDotNetCore/Services/AsyncCollectionExtensions.cs b/src/JsonApiDotNetCore/Services/AsyncCollectionExtensions.cs index 70268bb416..923c473ecf 100644 --- a/src/JsonApiDotNetCore/Services/AsyncCollectionExtensions.cs +++ b/src/JsonApiDotNetCore/Services/AsyncCollectionExtensions.cs @@ -8,6 +8,9 @@ public static class AsyncCollectionExtensions { public static async Task AddRangeAsync(this ICollection source, IAsyncEnumerable elementsToAdd, CancellationToken cancellationToken = default) { + ArgumentGuard.NotNull(source, nameof(source)); + ArgumentGuard.NotNull(elementsToAdd, nameof(elementsToAdd)); + await foreach (var missingResource in elementsToAdd.WithCancellation(cancellationToken)) { source.Add(missingResource); @@ -16,6 +19,8 @@ public static async Task AddRangeAsync(this ICollection source, IAsyncEnum public static async Task> ToListAsync(this IAsyncEnumerable source, CancellationToken cancellationToken = default) { + ArgumentGuard.NotNull(source, nameof(source)); + var list = new List(); await foreach (var element in source.WithCancellation(cancellationToken)) diff --git a/src/JsonApiDotNetCore/TypeHelper.cs b/src/JsonApiDotNetCore/TypeHelper.cs index e729e4f2b3..b9c37b141b 100644 --- a/src/JsonApiDotNetCore/TypeHelper.cs +++ b/src/JsonApiDotNetCore/TypeHelper.cs @@ -116,6 +116,8 @@ public static Type TryGetCollectionElementType(Type type) /// public static PropertyInfo ParseNavigationExpression(Expression> navigationExpression) { + ArgumentGuard.NotNull(navigationExpression, nameof(navigationExpression)); + MemberExpression exp; //this line is necessary, because sometimes the expression comes in as Convert(originalExpression) @@ -127,7 +129,7 @@ public static PropertyInfo ParseNavigationExpression(Expression(Expression factory) public async Task Get_skips_middleware_and_formatters() { // Arrange - var request = new HttpRequestMessage(HttpMethod.Get, "/NonJsonApi"); + using var request = new HttpRequestMessage(HttpMethod.Get, "/NonJsonApi"); var client = _factory.CreateClient(); @@ -42,7 +42,7 @@ public async Task Get_skips_middleware_and_formatters() public async Task Post_skips_middleware_and_formatters() { // Arrange - var request = new HttpRequestMessage(HttpMethod.Post, "/NonJsonApi") + using var request = new HttpRequestMessage(HttpMethod.Post, "/NonJsonApi") { Content = new StringContent("Jack") { @@ -70,7 +70,7 @@ public async Task Post_skips_middleware_and_formatters() public async Task Post_skips_error_handler() { // Arrange - var request = new HttpRequestMessage(HttpMethod.Post, "/NonJsonApi"); + using var request = new HttpRequestMessage(HttpMethod.Post, "/NonJsonApi"); var client = _factory.CreateClient(); @@ -89,7 +89,7 @@ public async Task Post_skips_error_handler() public async Task Put_skips_middleware_and_formatters() { // Arrange - var request = new HttpRequestMessage(HttpMethod.Put, "/NonJsonApi") + using var request = new HttpRequestMessage(HttpMethod.Put, "/NonJsonApi") { Content = new StringContent("\"Jane\"") { @@ -117,7 +117,7 @@ public async Task Put_skips_middleware_and_formatters() public async Task Patch_skips_middleware_and_formatters() { // Arrange - var request = new HttpRequestMessage(HttpMethod.Patch, "/NonJsonApi?name=Janice"); + using var request = new HttpRequestMessage(HttpMethod.Patch, "/NonJsonApi?name=Janice"); var client = _factory.CreateClient(); @@ -136,7 +136,7 @@ public async Task Patch_skips_middleware_and_formatters() public async Task Delete_skips_middleware_and_formatters() { // Arrange - var request = new HttpRequestMessage(HttpMethod.Delete, "/NonJsonApi"); + using var request = new HttpRequestMessage(HttpMethod.Delete, "/NonJsonApi"); var client = _factory.CreateClient(); diff --git a/test/TestBuildingBlocks/IntegrationTest.cs b/test/TestBuildingBlocks/IntegrationTest.cs index 8992bc6997..17e2b8af1a 100644 --- a/test/TestBuildingBlocks/IntegrationTest.cs +++ b/test/TestBuildingBlocks/IntegrationTest.cs @@ -60,7 +60,7 @@ public abstract class IntegrationTest ExecuteRequestAsync(HttpMethod method, string requestUrl, object requestBody, string contentType, IEnumerable acceptHeaders) { - var request = new HttpRequestMessage(method, requestUrl); + using var request = new HttpRequestMessage(method, requestUrl); string requestText = SerializeRequest(requestBody); if (!string.IsNullOrEmpty(requestText)) diff --git a/test/UnitTests/ResourceHooks/DiscoveryTests.cs b/test/UnitTests/ResourceHooks/DiscoveryTests.cs index 34ae7a5ebc..4a6bc0df93 100644 --- a/test/UnitTests/ResourceHooks/DiscoveryTests.cs +++ b/test/UnitTests/ResourceHooks/DiscoveryTests.cs @@ -18,7 +18,7 @@ public sealed class DummyResourceDefinition : ResourceHooksDefinition { public DummyResourceDefinition() : base(new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance).Add().Build()) { } - public override IEnumerable BeforeDelete(IResourceHashSet affected, ResourcePipeline pipeline) { return affected; } + public override IEnumerable BeforeDelete(IResourceHashSet resources, ResourcePipeline pipeline) { return resources; } public override void AfterDelete(HashSet resources, ResourcePipeline pipeline, bool succeeded) { } } @@ -69,7 +69,7 @@ public sealed class YetAnotherDummyResourceDefinition : ResourceHooksDefinition< { public YetAnotherDummyResourceDefinition() : base(new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance).Add().Build()) { } - public override IEnumerable BeforeDelete(IResourceHashSet affected, ResourcePipeline pipeline) { return affected; } + public override IEnumerable BeforeDelete(IResourceHashSet resources, ResourcePipeline pipeline) { return resources; } [LoadDatabaseValues(false)] public override void AfterDelete(HashSet resources, ResourcePipeline pipeline, bool succeeded) { } From 72f3630156ec2102316e489fec45ac9059b2e57a Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Tue, 23 Feb 2021 11:50:35 +0100 Subject: [PATCH 29/60] Use helpers to prevent multiple line breaks in array and list initializers --- benchmarks/Query/QueryParserBenchmarks.cs | 14 +++------- .../ReportsExample/Services/ReportService.cs | 4 +-- src/JsonApiDotNetCore/ArrayFactory.cs | 10 +++++++ .../ServiceCollectionExtensions.cs | 2 +- .../Configuration/ServiceDiscoveryFacade.cs | 5 +++- .../Controllers/CoreJsonApiController.cs | 2 +- .../Errors/JsonApiException.cs | 2 +- .../Internal/Discovery/HooksDiscovery.cs | 2 +- .../Internal/Execution/HookExecutorHelper.cs | 6 ++--- .../Hooks/Internal/ResourceHookExecutor.cs | 12 ++++----- .../Internal/ResourceHookExecutorFacade.cs | 27 ++++++++----------- .../Internal/Traversal/TraversalHelper.cs | 6 ++--- .../Middleware/ExceptionHandler.cs | 14 +++------- src/JsonApiDotNetCore/ObjectExtensions.cs | 22 +++++++++++++++ .../ResourceFieldChainExpression.cs | 2 +- .../Queries/Internal/Parsing/IncludeParser.cs | 5 +--- .../Queries/Internal/Parsing/SortParser.cs | 5 +--- .../Internal/Parsing/SparseFieldSetParser.cs | 2 +- .../Queries/Internal/QueryLayerComposer.cs | 24 +++++++---------- .../QueryableBuilding/IncludeClauseBuilder.cs | 5 +--- .../QueryableBuilding/OrderClauseBuilder.cs | 7 ++--- .../QueryableBuilding/SelectClauseBuilder.cs | 17 +++--------- .../SkipTakeClauseBuilder.cs | 5 +--- .../QueryableBuilding/WhereClauseBuilder.cs | 15 +++-------- .../Queries/Internal/SparseFieldSetCache.cs | 2 +- .../IncludeQueryStringParameterReader.cs | 2 +- ...parseFieldSetQueryStringParameterReader.cs | 5 +--- .../Serialization/Building/LinkBuilder.cs | 2 +- .../Serialization/JsonApiReader.cs | 2 +- .../Serialization/Objects/ErrorDocument.cs | 2 +- src/JsonApiDotNetCore/TypeHelper.cs | 4 +-- ...reateResourceWithClientGeneratedIdTests.cs | 1 - .../AtomicAddToToManyRelationshipTests.cs | 3 ++- ...AtomicRemoveFromToManyRelationshipTests.cs | 3 ++- .../AtomicReplaceToManyRelationshipTests.cs | 3 ++- .../AtomicReplaceToManyRelationshipTests.cs | 3 ++- .../CompositeKeys/CarExpressionRewriter.cs | 3 ++- .../NamingConventions/KebabCasingTests.cs | 1 - ...reateResourceWithClientGeneratedIdTests.cs | 1 - .../ReplaceToManyRelationshipTests.cs | 6 ++--- .../DefaultBehaviorTests.cs | 1 - .../CallableResourceDefinition.cs | 3 ++- .../ResourceHooks/ResourceHookTests.cs | 1 - .../SoftDeletionResourceDefinition.cs | 4 +-- .../UnitTests/Links/LinkInclusionTests.cs | 16 +++-------- .../Delete/BeforeDeleteWithDbValuesTests.cs | 7 ++--- .../Executor/ManyToManyOnReturnTests.cs | 3 ++- .../Executor/Read/BeforeReadTests.cs | 15 +++++------ .../Executor/SameResourceTypeTests.cs | 17 ++++++------ .../UnitTests/ResourceHooks/HooksDummyData.cs | 7 ++--- .../ResourceHooks/HooksTestsSetup.cs | 10 +++---- .../Common/BaseDocumentBuilderTests.cs | 3 ++- .../Common/BaseDocumentParserTests.cs | 2 +- .../Serialization/DeserializerTestsSetup.cs | 13 ++++----- .../Serialization/SerializerTestsSetup.cs | 11 ++++---- .../ResponseResourceObjectBuilderTests.cs | 5 ++-- .../Server/ResponseSerializerTests.cs | 11 ++++---- 57 files changed, 179 insertions(+), 208 deletions(-) create mode 100644 src/JsonApiDotNetCore/ArrayFactory.cs create mode 100644 src/JsonApiDotNetCore/ObjectExtensions.cs diff --git a/benchmarks/Query/QueryParserBenchmarks.cs b/benchmarks/Query/QueryParserBenchmarks.cs index 362637df1c..8ba74abc74 100644 --- a/benchmarks/Query/QueryParserBenchmarks.cs +++ b/benchmarks/Query/QueryParserBenchmarks.cs @@ -1,7 +1,7 @@ using System; -using System.Collections.Generic; using System.ComponentModel.Design; using BenchmarkDotNet.Attributes; +using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.QueryStrings; @@ -43,11 +43,8 @@ private static QueryStringReader CreateQueryParameterDiscoveryForSort(IResourceG JsonApiRequest request, IJsonApiOptions options, FakeRequestQueryStringAccessor queryStringAccessor) { var sortReader = new SortQueryStringParameterReader(request, resourceGraph); - - var readers = new List - { - sortReader - }; + + var readers = sortReader.AsEnumerable(); return new QueryStringReader(options, queryStringAccessor, readers, NullLoggerFactory.Instance); } @@ -65,10 +62,7 @@ private static QueryStringReader CreateQueryParameterDiscoveryForAll(IResourceGr var defaultsReader = new DefaultsQueryStringParameterReader(options); var nullsReader = new NullsQueryStringParameterReader(options); - var readers = new List - { - includeReader, filterReader, sortReader, sparseFieldSetReader, paginationReader, defaultsReader, nullsReader - }; + var readers = ArrayFactory.Create(includeReader, filterReader, sortReader, sparseFieldSetReader, paginationReader, defaultsReader, nullsReader); return new QueryStringReader(options, queryStringAccessor, readers, NullLoggerFactory.Instance); } diff --git a/src/Examples/ReportsExample/Services/ReportService.cs b/src/Examples/ReportsExample/Services/ReportService.cs index 6b13e1f91d..139efe688c 100644 --- a/src/Examples/ReportsExample/Services/ReportService.cs +++ b/src/Examples/ReportsExample/Services/ReportService.cs @@ -21,12 +21,12 @@ public Task> GetAsync(CancellationToken cancellation { _logger.LogInformation("GetAsync"); - IReadOnlyCollection reports = GetReports().ToList(); + var reports = GetReports(); return Task.FromResult(reports); } - private IEnumerable GetReports() + private IReadOnlyCollection GetReports() { return new List { diff --git a/src/JsonApiDotNetCore/ArrayFactory.cs b/src/JsonApiDotNetCore/ArrayFactory.cs new file mode 100644 index 0000000000..44eb3ba3f6 --- /dev/null +++ b/src/JsonApiDotNetCore/ArrayFactory.cs @@ -0,0 +1,10 @@ +namespace JsonApiDotNetCore +{ + internal static class ArrayFactory + { + public static T[] Create(params T[] items) + { + return items; + } + } +} diff --git a/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs b/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs index ccc01d75cf..7166c06873 100644 --- a/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs +++ b/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs @@ -42,7 +42,7 @@ public static IServiceCollection AddJsonApi(this IServiceCollection IMvcCoreBuilder mvcBuilder = null) where TDbContext : DbContext { - return AddJsonApi(services, options, discovery, resources, mvcBuilder, new[] {typeof(TDbContext)}); + return AddJsonApi(services, options, discovery, resources, mvcBuilder, typeof(TDbContext).AsArray()); } private static void SetupApplicationBuilder(IServiceCollection services, Action configureOptions, diff --git a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs index cee27f83b2..39c11d4dca 100644 --- a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs +++ b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs @@ -187,7 +187,10 @@ private void AddResourceDefinitions(Assembly assembly, ResourceDescriptor resour private void RegisterImplementations(Assembly assembly, Type interfaceType, ResourceDescriptor resourceDescriptor) { - var genericArguments = interfaceType.GetTypeInfo().GenericTypeParameters.Length == 2 ? new[] { resourceDescriptor.ResourceType, resourceDescriptor.IdType } : new[] { resourceDescriptor.ResourceType }; + var genericArguments = interfaceType.GetTypeInfo().GenericTypeParameters.Length == 2 + ? ArrayFactory.Create(resourceDescriptor.ResourceType, resourceDescriptor.IdType) + : ArrayFactory.Create(resourceDescriptor.ResourceType); + var result = TypeLocator.GetGenericInterfaceImplementation(assembly, interfaceType, genericArguments); if (result != null) { diff --git a/src/JsonApiDotNetCore/Controllers/CoreJsonApiController.cs b/src/JsonApiDotNetCore/Controllers/CoreJsonApiController.cs index 216b4d0c4f..8406bdb55a 100644 --- a/src/JsonApiDotNetCore/Controllers/CoreJsonApiController.cs +++ b/src/JsonApiDotNetCore/Controllers/CoreJsonApiController.cs @@ -13,7 +13,7 @@ protected IActionResult Error(Error error) { ArgumentGuard.NotNull(error, nameof(error)); - return Error(new[] {error}); + return Error(error.AsEnumerable()); } protected IActionResult Error(IEnumerable errors) diff --git a/src/JsonApiDotNetCore/Errors/JsonApiException.cs b/src/JsonApiDotNetCore/Errors/JsonApiException.cs index db40a7eb90..3a73e8ac9a 100644 --- a/src/JsonApiDotNetCore/Errors/JsonApiException.cs +++ b/src/JsonApiDotNetCore/Errors/JsonApiException.cs @@ -24,7 +24,7 @@ public JsonApiException(Error error, Exception innerException = null) { ArgumentGuard.NotNull(error, nameof(error)); - Errors = new[] {error}; + Errors = error.AsArray(); } public JsonApiException(IEnumerable errors, Exception innerException = null) diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs index 8cb1f6db2e..c09045cbc3 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs @@ -56,7 +56,7 @@ private void DiscoverImplementedHooks(Type containerType) var implementedHooks = new List(); // this hook can only be used with enabled database values - var databaseValuesEnabledHooks = new List { ResourceHook.BeforeImplicitUpdateRelationship }; + var databaseValuesEnabledHooks = ResourceHook.BeforeImplicitUpdateRelationship.AsList(); var databaseValuesDisabledHooks = new List(); foreach (var hook in _allHooks) { diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs index d282bf1ed6..0e4cc4924a 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs @@ -56,7 +56,7 @@ public IResourceHookContainer GetResourceHookContainer(RightType targetResource, // if there was a container, first check if it implements the hook we // want to use it for. - List targetHooks; + IEnumerable targetHooks; if (hook == ResourceHook.None) { CheckForTargetHookExistence(); @@ -64,7 +64,7 @@ public IResourceHookContainer GetResourceHookContainer(RightType targetResource, } else { - targetHooks = new List { hook }; + targetHooks = hook.AsEnumerable(); } foreach (ResourceHook targetHook in targetHooks) @@ -91,7 +91,7 @@ public IEnumerable LoadDbValues(LeftType resourceTypeForRepository, IEnumerable .MakeGenericMethod(resourceTypeForRepository, idType); var cast = ((IEnumerable)resources).Cast(); var ids = TypeHelper.CopyToList(cast.Select(i => i.GetTypedId()), idType); - var values = (IEnumerable)parameterizedGetWhere.Invoke(this, new object[] { ids, relationshipsToNextLayer }); + var values = (IEnumerable)parameterizedGetWhere.Invoke(this, ArrayFactory.Create(ids, relationshipsToNextLayer)); if (values == null) { return null; diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs index 252e5b540d..cbfa1837ee 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs @@ -43,7 +43,7 @@ public void BeforeRead(ResourcePipeline pipeline, string stringId = n { var hookContainer = _executorHelper.GetResourceHookContainer(ResourceHook.BeforeRead); hookContainer?.BeforeRead(pipeline, false, stringId); - var calledContainers = new List { typeof(TResource) }; + var calledContainers = typeof(TResource).AsList(); // @formatter:wrap_chained_method_calls chop_always // @formatter:keep_existing_linebreaks true @@ -134,7 +134,7 @@ public IEnumerable OnReturn(IEnumerable resourc Traverse(_traversalHelper.CreateNextLayer(node), ResourceHook.OnReturn, (nextContainer, nextNode) => { - var filteredUniqueSet = CallHook(nextContainer, ResourceHook.OnReturn, new object[] { nextNode.UniqueResources, pipeline }); + var filteredUniqueSet = CallHook(nextContainer, ResourceHook.OnReturn, ArrayFactory.Create(nextNode.UniqueResources, pipeline)); nextNode.UpdateUnique(filteredUniqueSet); nextNode.Reassign(); }); @@ -151,7 +151,7 @@ public void AfterRead(IEnumerable resources, ResourcePipel Traverse(_traversalHelper.CreateNextLayer(node), ResourceHook.AfterRead, (nextContainer, nextNode) => { - CallHook(nextContainer, ResourceHook.AfterRead, new object[] { nextNode.UniqueResources, pipeline, true }); + CallHook(nextContainer, ResourceHook.AfterRead, ArrayFactory.Create(nextNode.UniqueResources, pipeline, true)); }); } @@ -311,7 +311,7 @@ private void FireNestedBeforeUpdateHooks(ResourcePipeline pipeline, NodeLayer la currentResourcesGroupedInverse = ReplaceKeysWithInverseRelationships(currentResourcesGrouped); var resourcesByRelationship = CreateRelationshipHelper(resourceType, currentResourcesGroupedInverse, dbValues); - var allowedIds = CallHook(nestedHookContainer, ResourceHook.BeforeUpdateRelationship, new object[] { GetIds(uniqueResources), resourcesByRelationship, pipeline }).Cast(); + var allowedIds = CallHook(nestedHookContainer, ResourceHook.BeforeUpdateRelationship, ArrayFactory.Create(GetIds(uniqueResources), resourcesByRelationship, pipeline)).Cast(); var updated = GetAllowedResources(uniqueResources, allowedIds); node.UpdateUnique(updated); node.Reassign(); @@ -392,7 +392,7 @@ private void FireForAffectedImplicits(Type resourceTypeToInclude, Dictionary _resourceGraph.GetInverseRelationship(kvp.Key), kvp => kvp.Value); var resourcesByRelationship = CreateRelationshipHelper(resourceTypeToInclude, inverse); - CallHook(container, ResourceHook.BeforeImplicitUpdateRelationship, new object[] { resourcesByRelationship, pipeline}); + CallHook(container, ResourceHook.BeforeImplicitUpdateRelationship, ArrayFactory.Create(resourcesByRelationship, pipeline)); } /// @@ -512,7 +512,7 @@ private void FireAfterUpdateRelationship(IResourceHookContainer container, IReso // For the nested hook we need to replace these attributes with their inverse. // See the FireNestedBeforeUpdateHooks method for a more detailed example. var resourcesByRelationship = CreateRelationshipHelper(node.ResourceType, ReplaceKeysWithInverseRelationships(currentResourcesGrouped)); - CallHook(container, ResourceHook.AfterUpdateRelationship, new object[] { resourcesByRelationship, pipeline }); + CallHook(container, ResourceHook.AfterUpdateRelationship, ArrayFactory.Create(resourcesByRelationship, pipeline)); } /// diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs index 1700ec401a..136666500f 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs @@ -37,7 +37,7 @@ public void BeforeReadSingle(TId id, ResourcePipeline pipeline) public void AfterReadSingle(TResource resource, ResourcePipeline pipeline) where TResource : class, IIdentifiable { - _resourceHookExecutor.AfterRead(ToList(resource), pipeline); + _resourceHookExecutor.AfterRead(resource.AsList(), pipeline); } public void BeforeReadMany() @@ -55,37 +55,37 @@ public void AfterReadMany(IReadOnlyCollection resources) public void BeforeCreate(TResource resource) where TResource : class, IIdentifiable { - _resourceHookExecutor.BeforeCreate(ToList(resource), ResourcePipeline.Post); + _resourceHookExecutor.BeforeCreate(resource.AsList(), ResourcePipeline.Post); } public void AfterCreate(TResource resource) where TResource : class, IIdentifiable { - _resourceHookExecutor.AfterCreate(ToList(resource), ResourcePipeline.Post); + _resourceHookExecutor.AfterCreate(resource.AsList(), ResourcePipeline.Post); } public void BeforeUpdateResource(TResource resource) where TResource : class, IIdentifiable { - _resourceHookExecutor.BeforeUpdate(ToList(resource), ResourcePipeline.Patch); + _resourceHookExecutor.BeforeUpdate(resource.AsList(), ResourcePipeline.Patch); } public void AfterUpdateResource(TResource resource) where TResource : class, IIdentifiable { - _resourceHookExecutor.AfterUpdate(ToList(resource), ResourcePipeline.Patch); + _resourceHookExecutor.AfterUpdate(resource.AsList(), ResourcePipeline.Patch); } public void BeforeUpdateRelationship(TResource resource) where TResource : class, IIdentifiable { - _resourceHookExecutor.BeforeUpdate(ToList(resource), ResourcePipeline.PatchRelationship); + _resourceHookExecutor.BeforeUpdate(resource.AsList(), ResourcePipeline.PatchRelationship); } public void AfterUpdateRelationship(TResource resource) where TResource : class, IIdentifiable { - _resourceHookExecutor.AfterUpdate(ToList(resource), ResourcePipeline.PatchRelationship); + _resourceHookExecutor.AfterUpdate(resource.AsList(), ResourcePipeline.PatchRelationship); } public void BeforeDelete(TId id) @@ -94,7 +94,7 @@ public void BeforeDelete(TId id) var temporaryResource = _resourceFactory.CreateInstance(); temporaryResource.Id = id; - _resourceHookExecutor.BeforeDelete(ToList(temporaryResource), ResourcePipeline.Delete); + _resourceHookExecutor.BeforeDelete(temporaryResource.AsList(), ResourcePipeline.Delete); } public void AfterDelete(TId id) @@ -103,13 +103,13 @@ public void AfterDelete(TId id) var temporaryResource = _resourceFactory.CreateInstance(); temporaryResource.Id = id; - _resourceHookExecutor.AfterDelete(ToList(temporaryResource), ResourcePipeline.Delete, true); + _resourceHookExecutor.AfterDelete(temporaryResource.AsList(), ResourcePipeline.Delete, true); } public void OnReturnSingle(TResource resource, ResourcePipeline pipeline) where TResource : class, IIdentifiable { - _resourceHookExecutor.OnReturn(ToList(resource), pipeline); + _resourceHookExecutor.OnReturn(resource.AsList(), pipeline); } public IReadOnlyCollection OnReturnMany(IReadOnlyCollection resources) @@ -128,16 +128,11 @@ public object OnReturnRelationship(object resourceOrResources) if (resourceOrResources is IIdentifiable) { - var resources = ToList((dynamic)resourceOrResources); + var resources = ObjectExtensions.AsList((dynamic)resourceOrResources); return Enumerable.SingleOrDefault(_resourceHookExecutor.OnReturn(resources, ResourcePipeline.GetRelationship)); } return resourceOrResources; } - - private static List ToList(TResource resource) - { - return new List {resource}; - } } } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs index fc3ab804ab..7f4c5e7395 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs @@ -67,7 +67,7 @@ public RootNode CreateRootNode(IEnumerable root /// Root node. public NodeLayer CreateNextLayer(IResourceNode rootNode) { - return CreateNextLayer(new[] { rootNode }); + return CreateNextLayer(rootNode.AsEnumerable()); } /// @@ -159,7 +159,7 @@ private Dictionary(list)); } return (leftResourcesGrouped, rightResourcesGrouped); diff --git a/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs b/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs index 70afbe24ad..f8841e3b57 100644 --- a/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs +++ b/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs @@ -73,21 +73,15 @@ protected virtual ErrorDocument CreateErrorDocument(Exception exception) var errors = exception is JsonApiException jsonApiException ? jsonApiException.Errors : exception is OperationCanceledException - ? new[] - { - new Error((HttpStatusCode) 499) + ? new Error((HttpStatusCode) 499) { Title = "Request execution was canceled." - } - } - : new[] - { - new Error(HttpStatusCode.InternalServerError) + }.AsArray() + : new Error(HttpStatusCode.InternalServerError) { Title = "An unhandled error occurred while processing this request.", Detail = exception.Message - } - }; + }.AsArray(); foreach (var error in errors) { diff --git a/src/JsonApiDotNetCore/ObjectExtensions.cs b/src/JsonApiDotNetCore/ObjectExtensions.cs new file mode 100644 index 0000000000..7dfa76e02c --- /dev/null +++ b/src/JsonApiDotNetCore/ObjectExtensions.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +namespace JsonApiDotNetCore +{ + internal static class ObjectExtensions + { + public static IEnumerable AsEnumerable(this T element) + { + yield return element; + } + + public static T[] AsArray(this T element) + { + return new[] {element}; + } + + public static List AsList(this T element) + { + return new List {element}; + } + } +} diff --git a/src/JsonApiDotNetCore/Queries/Expressions/ResourceFieldChainExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/ResourceFieldChainExpression.cs index 3d3527c72c..911116bff9 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/ResourceFieldChainExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/ResourceFieldChainExpression.cs @@ -16,7 +16,7 @@ public ResourceFieldChainExpression(ResourceFieldAttribute field) { ArgumentGuard.NotNull(field, nameof(field)); - Fields = new[] {field}; + Fields = field.AsArray(); } public ResourceFieldChainExpression(IReadOnlyCollection fields) diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/IncludeParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/IncludeParser.cs index 4fd6e0aa2a..bafe5d1ef9 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/IncludeParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/IncludeParser.cs @@ -39,10 +39,7 @@ protected IncludeExpression ParseInclude(int? maximumDepth) ResourceFieldChainExpression firstChain = ParseFieldChain(FieldChainRequirements.IsRelationship, "Relationship name expected."); - var chains = new List - { - firstChain - }; + var chains = firstChain.AsList(); while (TokenStack.Any()) { diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SortParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SortParser.cs index c866b25398..45b2546e43 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SortParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SortParser.cs @@ -38,10 +38,7 @@ protected SortExpression ParseSort() { SortElementExpression firstElement = ParseSortElement(); - var elements = new List - { - firstElement - }; + var elements = firstElement.AsList(); while (TokenStack.Any()) { diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldSetParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldSetParser.cs index f428a1cd2b..f0958f8b09 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldSetParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldSetParser.cs @@ -59,7 +59,7 @@ protected override IReadOnlyCollection OnResolveFieldCha _validateSingleFieldCallback?.Invoke(field, _resourceContext, path); - return new[] {field}; + return field.AsArray(); } } } diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs index 84551a8b47..5a478eb653 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs @@ -190,7 +190,7 @@ private IReadOnlyCollection ProcessIncludeSet(IReadOnl private static IReadOnlyCollection ApplyIncludeElementUpdates(IEnumerable includeElements, IDictionary> updatesInChildren) { - var newIncludeElements = new List(includeElements); + var newIncludeElements = includeElements.ToList(); foreach (var (existingElement, updatedChildren) in updatesInChildren) { @@ -211,7 +211,7 @@ public QueryLayer ComposeForGetById(TId id, ResourceContext resourceContext var queryLayer = ComposeFromConstraints(resourceContext); queryLayer.Sort = null; queryLayer.Pagination = null; - queryLayer.Filter = CreateFilterById(id, idAttribute, queryLayer.Filter); + queryLayer.Filter = CreateFilterByIds(id.AsArray(), idAttribute, queryLayer.Filter); if (fieldSelection == TopFieldSelection.OnlyIdAttribute) { @@ -271,7 +271,7 @@ public QueryLayer WrapLayerForSecondaryEndpoint(QueryLayer secondaryLayer, return new QueryLayer(primaryResourceContext) { Include = RewriteIncludeForSecondaryEndpoint(innerInclude, secondaryRelationship), - Filter = CreateFilterById(primaryId, primaryIdAttribute, primaryFilter), + Filter = CreateFilterByIds(primaryId.AsArray(), primaryIdAttribute, primaryFilter), Projection = primaryProjection }; } @@ -282,13 +282,7 @@ private IncludeExpression RewriteIncludeForSecondaryEndpoint(IncludeExpression r ? new IncludeElementExpression(secondaryRelationship, relativeInclude.Elements) : new IncludeElementExpression(secondaryRelationship); - return new IncludeExpression(new[] {parentElement}); - } - - private FilterExpression CreateFilterById(TId id, AttrAttribute idAttribute, FilterExpression existingFilter) - { - var ids = new[] { id }; - return CreateFilterByIds(ids, idAttribute, existingFilter); + return new IncludeExpression(parentElement.AsArray()); } private FilterExpression CreateFilterByIds(ICollection ids, AttrAttribute idAttribute, FilterExpression existingFilter) @@ -314,7 +308,7 @@ private FilterExpression CreateFilterByIds(ICollection ids, AttrAttrib ? existingFilter : existingFilter == null ? filter - : new LogicalExpression(LogicalOperator.And, new[] {filter, existingFilter}); + : new LogicalExpression(LogicalOperator.And, ArrayFactory.Create(filter, existingFilter)); // @formatter:keep_existing_linebreaks restore } @@ -333,7 +327,7 @@ public QueryLayer ComposeForUpdate(TId id, ResourceContext primaryResource) primaryLayer.Include = includeElements.Any() ? new IncludeExpression(includeElements) : IncludeExpression.Empty; primaryLayer.Sort = null; primaryLayer.Pagination = null; - primaryLayer.Filter = CreateFilterById(id, primaryIdAttribute, primaryLayer.Filter); + primaryLayer.Filter = CreateFilterByIds(id.AsArray(), primaryIdAttribute, primaryLayer.Filter); primaryLayer.Projection = null; return primaryLayer; @@ -395,12 +389,12 @@ public QueryLayer ComposeForHasMany(HasManyAttribute hasManyRelationship, T var rightIdAttribute = GetIdAttribute(rightResourceContext); var rightTypedIds = rightResourceIds.Select(resource => resource.GetTypedId()).ToArray(); - var leftFilter = CreateFilterById(leftId, leftIdAttribute, null); + var leftFilter = CreateFilterByIds(leftId.AsArray(), leftIdAttribute, null); var rightFilter = CreateFilterByIds(rightTypedIds, rightIdAttribute, null); return new QueryLayer(leftResourceContext) { - Include = new IncludeExpression(new[] {new IncludeElementExpression(hasManyRelationship)}), + Include = new IncludeExpression(new IncludeElementExpression(hasManyRelationship).AsArray()), Filter = leftFilter, Projection = new Dictionary { @@ -451,7 +445,7 @@ protected virtual SortExpression GetSort(IReadOnlyCollection ex if (sort == null) { var idAttribute = GetIdAttribute(resourceContext); - sort = new SortExpression(new[] {new SortElementExpression(new ResourceFieldChainExpression(idAttribute), true)}); + sort = new SortExpression(new SortElementExpression(new ResourceFieldChainExpression(idAttribute), true).AsArray()); } return sort; diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs index 013a434501..65cd279bb8 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs @@ -76,10 +76,7 @@ private Expression IncludeExtensionMethodCall(Expression source, string navigati { Expression navigationExpression = Expression.Constant(navigationPropertyPath); - return Expression.Call(typeof(EntityFrameworkQueryableExtensions), "Include", new[] - { - LambdaScope.Parameter.Type - }, source, navigationExpression); + return Expression.Call(typeof(EntityFrameworkQueryableExtensions), "Include", LambdaScope.Parameter.Type.AsArray(), source, navigationExpression); } } } diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs index addc02a88d..65ab9bc017 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs @@ -70,11 +70,8 @@ private static string GetOperationName(bool hasPrecedingSort, bool isAscending) private Expression ExtensionMethodCall(Expression source, string operationName, Type keyType, LambdaExpression keySelector) { - return Expression.Call(_extensionType, operationName, new[] - { - LambdaScope.Parameter.Type, - keyType - }, source, keySelector); + var typeArguments = ArrayFactory.Create(LambdaScope.Parameter.Type, keyType); + return Expression.Call(_extensionType, operationName, typeArguments, source, keySelector); } protected override MemberExpression CreatePropertyExpressionForFieldChain(IReadOnlyCollection chain, Expression source) diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs index 582816db41..641fccc41a 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs @@ -187,10 +187,7 @@ private Expression CreateCollectionInitializer(LambdaScope lambdaScope, Property Type enumerableOfElementType = typeof(IEnumerable<>).MakeGenericType(elementType); Type typedCollection = TypeHelper.ToConcreteCollectionType(collectionProperty.PropertyType); - ConstructorInfo typedCollectionConstructor = typedCollection.GetConstructor(new[] - { - enumerableOfElementType - }); + ConstructorInfo typedCollectionConstructor = typedCollection.GetConstructor(enumerableOfElementType.AsArray()); if (typedCollectionConstructor == null) { @@ -213,19 +210,13 @@ private static Expression TestForNull(Expression expressionToTest, Expression if private static Expression CopyCollectionExtensionMethodCall(Expression source, string operationName, Type elementType) { - return Expression.Call(typeof(Enumerable), operationName, new[] - { - elementType - }, source); + return Expression.Call(typeof(Enumerable), operationName, elementType.AsArray(), source); } private Expression SelectExtensionMethodCall(Expression source, Type elementType, Expression selectorBody) { - return Expression.Call(_extensionType, "Select", new[] - { - elementType, - elementType - }, source, selectorBody); + var typeArguments = ArrayFactory.Create(elementType, elementType); + return Expression.Call(_extensionType, "Select", typeArguments, source, selectorBody); } private sealed class PropertySelector diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SkipTakeClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SkipTakeClauseBuilder.cs index 993d637548..ef812ad61f 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SkipTakeClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SkipTakeClauseBuilder.cs @@ -53,10 +53,7 @@ private Expression ExtensionMethodCall(Expression source, string operationName, { Expression constant = CreateTupleAccessExpressionForConstant(value, typeof(int)); - return Expression.Call(_extensionType, operationName, new[] - { - LambdaScope.Parameter.Type - }, source, constant); + return Expression.Call(_extensionType, operationName, LambdaScope.Parameter.Type.AsArray(), source, constant); } } } diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs index 5c1fb942a8..073c3bc0e9 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs @@ -41,10 +41,7 @@ public Expression ApplyWhere(FilterExpression filter) private Expression WhereExtensionMethodCall(LambdaExpression predicate) { - return Expression.Call(_extensionType, "Where", new[] - { - LambdaScope.Parameter.Type - }, _source, predicate); + return Expression.Call(_extensionType, "Where", LambdaScope.Parameter.Type.AsArray(), _source, predicate); } public override Expression VisitCollectionNotEmpty(CollectionNotEmptyExpression expression, Type argument) @@ -63,10 +60,7 @@ public override Expression VisitCollectionNotEmpty(CollectionNotEmptyExpression private static MethodCallExpression AnyExtensionMethodCall(Type elementType, Expression source) { - return Expression.Call(typeof(Enumerable), "Any", new[] - { - elementType - }, source); + return Expression.Call(typeof(Enumerable), "Any", elementType.AsArray(), source); } public override Expression VisitMatchText(MatchTextExpression expression, Type argument) @@ -111,10 +105,7 @@ public override Expression VisitEqualsAnyOf(EqualsAnyOfExpression expression, Ty private static Expression ContainsExtensionMethodCall(Expression collection, Expression value) { - return Expression.Call(typeof(Enumerable), "Contains", new[] - { - value.Type - }, collection, value); + return Expression.Call(typeof(Enumerable), "Contains", value.Type.AsArray(), collection, value); } public override Expression VisitLogical(LogicalExpression expression, Type argument) diff --git a/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs b/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs index 70b95972af..e351c44510 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs @@ -91,7 +91,7 @@ public IReadOnlyCollection GetIdAttributeSetForRelationshipQuery( ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); var idAttribute = resourceContext.Attributes.Single(attr => attr.Property.Name == nameof(Identifiable.Id)); - var inputExpression = new SparseFieldSetExpression(new []{idAttribute}); + var inputExpression = new SparseFieldSetExpression(idAttribute.AsArray()); // Intentionally not cached, as we are fetching ID only (ignoring any sparse fieldset that came from query string). var outputExpression = _resourceDefinitionAccessor.OnApplySparseFieldSet(resourceContext.ResourceType, inputExpression); diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/IncludeQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/IncludeQueryStringParameterReader.cs index c30f8fc7e0..5acf639640 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/IncludeQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/IncludeQueryStringParameterReader.cs @@ -83,7 +83,7 @@ public virtual IReadOnlyCollection GetConstraints() ? new ExpressionInScope(null, _includeExpression) : new ExpressionInScope(null, IncludeExpression.Empty); - return new[] {expressionInScope}; + return expressionInScope.AsArray(); } } } diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs index 98bfaf4179..7f790b71af 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs @@ -86,10 +86,7 @@ private SparseFieldSetExpression GetSparseFieldSet(string parameterValue, Resour public virtual IReadOnlyCollection GetConstraints() { return _sparseFieldTable.Any() - ? new[] - { - new ExpressionInScope(null, new SparseFieldTableExpression(_sparseFieldTable)) - } + ? new ExpressionInScope(null, new SparseFieldTableExpression(_sparseFieldTable)).AsArray() : Array.Empty(); } } diff --git a/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs index 4e5448d944..c6705c4a23 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs @@ -227,7 +227,7 @@ private List ParsePageSizeExpressio var parser = new PaginationParser(_provider); var paginationExpression = parser.Parse(pageSizeParameterValue, requestResource); - return new List(paginationExpression.Elements); + return paginationExpression.Elements.ToList(); } /// diff --git a/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs b/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs index 035b5f9e8d..362e339e54 100644 --- a/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs +++ b/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs @@ -185,7 +185,7 @@ private IEnumerable GetResourceTypesFromRequestBody(object model) return resourceCollection.Select(r => r.GetType()).Distinct(); } - return model == null ? Array.Empty() : new[] { model.GetType() }; + return model == null ? Enumerable.Empty() : model.GetType().AsEnumerable(); } private void ValidateRequestIncludesId(object model, string body) diff --git a/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs b/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs index d63f2e0a60..1604c286c8 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs @@ -15,7 +15,7 @@ public ErrorDocument() } public ErrorDocument(Error error) - : this(new[] {error}) + : this(error.AsEnumerable()) { } diff --git a/src/JsonApiDotNetCore/TypeHelper.cs b/src/JsonApiDotNetCore/TypeHelper.cs index b9c37b141b..d322b2f72b 100644 --- a/src/JsonApiDotNetCore/TypeHelper.cs +++ b/src/JsonApiDotNetCore/TypeHelper.cs @@ -182,7 +182,7 @@ public static Dictionary> ConvertAttributeDicti /// Open generic type public static object CreateInstanceOfOpenType(Type openType, Type parameter, params object[] constructorArguments) { - return CreateInstanceOfOpenType(openType, new[] {parameter}, constructorArguments); + return CreateInstanceOfOpenType(openType, parameter.AsArray(), constructorArguments); } /// @@ -287,7 +287,7 @@ public static ICollection ExtractResources(object value) if (value is IIdentifiable resource) { - return new[] {resource}; + return resource.AsArray(); } return Array.Empty(); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs index cd15f69a76..8e11640cfe 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs @@ -5,7 +5,6 @@ using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Serialization.Objects; using JsonApiDotNetCoreExampleTests.Startups; -using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; using Xunit; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs index 8bbddb4681..3a0f791045 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs @@ -3,6 +3,7 @@ using System.Net; using System.Threading.Tasks; using FluentAssertions; +using JsonApiDotNetCore; using JsonApiDotNetCore.Serialization.Objects; using JsonApiDotNetCoreExampleTests.Startups; using Microsoft.EntityFrameworkCore; @@ -802,7 +803,7 @@ public async Task Cannot_add_for_unknown_IDs_in_data() { // Arrange var existingCompany = _fakers.RecordCompany.Generate(); - var trackIds = new[] {Guid.NewGuid(), Guid.NewGuid()}; + var trackIds = ArrayFactory.Create(Guid.NewGuid(), Guid.NewGuid()); await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs index c12f2cdb74..50de26773d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs @@ -3,6 +3,7 @@ using System.Net; using System.Threading.Tasks; using FluentAssertions; +using JsonApiDotNetCore; using JsonApiDotNetCore.Serialization.Objects; using JsonApiDotNetCoreExampleTests.Startups; using Microsoft.EntityFrameworkCore; @@ -769,7 +770,7 @@ public async Task Cannot_remove_for_unknown_IDs_in_data() { // Arrange var existingCompany = _fakers.RecordCompany.Generate(); - var trackIds = new[] {Guid.NewGuid(), Guid.NewGuid()}; + var trackIds = ArrayFactory.Create(Guid.NewGuid(), Guid.NewGuid()); await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs index 9002bea652..108a070664 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs @@ -3,6 +3,7 @@ using System.Net; using System.Threading.Tasks; using FluentAssertions; +using JsonApiDotNetCore; using JsonApiDotNetCore.Serialization.Objects; using JsonApiDotNetCoreExampleTests.Startups; using Microsoft.EntityFrameworkCore; @@ -875,7 +876,7 @@ public async Task Cannot_replace_for_unknown_IDs_in_data() { // Arrange var existingCompany = _fakers.RecordCompany.Generate(); - var trackIds = new[] {Guid.NewGuid(), Guid.NewGuid()}; + var trackIds = ArrayFactory.Create(Guid.NewGuid(), Guid.NewGuid()); await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs index c68a421394..1b4c51d93b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs @@ -3,6 +3,7 @@ using System.Net; using System.Threading.Tasks; using FluentAssertions; +using JsonApiDotNetCore; using JsonApiDotNetCore.Serialization.Objects; using JsonApiDotNetCoreExampleTests.Startups; using Microsoft.EntityFrameworkCore; @@ -588,7 +589,7 @@ public async Task Cannot_replace_for_unknown_IDs_in_relationship_data() { // Arrange var existingCompany = _fakers.RecordCompany.Generate(); - var trackIds = new[] {Guid.NewGuid(), Guid.NewGuid()}; + var trackIds = ArrayFactory.Create(Guid.NewGuid(), Guid.NewGuid()); await _testContext.RunOnDatabaseAsync(async dbContext => { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs index 4251351818..57b1d35d85 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources; @@ -47,7 +48,7 @@ public override QueryExpression VisitComparison(ComparisonExpression expression, throw new NotSupportedException("Only equality comparisons are possible on Car IDs."); } - return RewriteFilterOnCarStringIds(leftChain, new[] {rightConstant.Value}); + return RewriteFilterOnCarStringIds(leftChain, rightConstant.Value.AsEnumerable()); } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs index c6aafdba6e..91efaed905 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingTests.cs @@ -3,7 +3,6 @@ using System.Threading.Tasks; using FluentAssertions; using JsonApiDotNetCore.Serialization.Objects; -using Microsoft.EntityFrameworkCore; using TestBuildingBlocks; using Xunit; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs index eb63565446..f19078a987 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs @@ -6,7 +6,6 @@ using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Serialization.Objects; using JsonApiDotNetCoreExampleTests.Startups; -using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; using Xunit; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs index c81ec7b9c2..860691893f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs @@ -3,6 +3,7 @@ using System.Net; using System.Threading.Tasks; using FluentAssertions; +using JsonApiDotNetCore; using JsonApiDotNetCore.Serialization.Objects; using JsonApiDotNetCoreExampleTests.Startups; using Microsoft.EntityFrameworkCore; @@ -887,10 +888,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => dbContext.WorkItems.Add(existingWorkItem); await dbContext.SaveChangesAsync(); - existingWorkItem.Children = new List - { - existingWorkItem - }; + existingWorkItem.Children = existingWorkItem.AsList(); await dbContext.SaveChangesAsync(); }); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs index 8ccc21b3e2..f810bde4ed 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorTests.cs @@ -4,7 +4,6 @@ using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Serialization.Objects; using JsonApiDotNetCoreExampleTests.Startups; -using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; using Xunit; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs index 1061613f6c..e956d6c259 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs @@ -2,6 +2,7 @@ using System.ComponentModel; using System.Linq; using System.Net; +using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Queries.Expressions; @@ -52,7 +53,7 @@ public override FilterExpression OnApplyFilter(FilterExpression existingFilter) return existingFilter == null ? (FilterExpression) isNotDeleted - : new LogicalExpression(LogicalOperator.And, new[] {isNotDeleted, existingFilter}); + : new LogicalExpression(LogicalOperator.And, ArrayFactory.Create(isNotDeleted, existingFilter)); } public override SortExpression OnApplySort(SortExpression existingSort) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs index b519f6c977..f41738308a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs @@ -12,7 +12,6 @@ using JsonApiDotNetCoreExample.Data; using JsonApiDotNetCoreExample.Definitions; using JsonApiDotNetCoreExample.Models; -using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using TestBuildingBlocks; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionResourceDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionResourceDefinition.cs index b3e32ba74c..151da3cd5c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionResourceDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionResourceDefinition.cs @@ -1,4 +1,5 @@ using System.Linq; +using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources; @@ -26,8 +27,7 @@ public override FilterExpression OnApplyFilter(FilterExpression existingFilter) return existingFilter == null ? (FilterExpression) isNotSoftDeleted - : new LogicalExpression(LogicalOperator.And, new[] {isNotSoftDeleted, existingFilter}); + : new LogicalExpression(LogicalOperator.And, ArrayFactory.Create(isNotSoftDeleted, existingFilter)); } - } } diff --git a/test/JsonApiDotNetCoreExampleTests/UnitTests/Links/LinkInclusionTests.cs b/test/JsonApiDotNetCoreExampleTests/UnitTests/Links/LinkInclusionTests.cs index 1134e7782b..14beb27a4f 100644 --- a/test/JsonApiDotNetCoreExampleTests/UnitTests/Links/LinkInclusionTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/UnitTests/Links/LinkInclusionTests.cs @@ -1,4 +1,5 @@ using FluentAssertions; +using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.Queries; @@ -60,10 +61,7 @@ public void Applies_cascading_settings_for_top_level_links(LinkTypes linksInReso TopLevelLinks = linksInResourceContext }; - var resourceGraph = new ResourceGraph(new[] - { - exampleResourceContext - }); + var resourceGraph = new ResourceGraph(exampleResourceContext.AsArray()); var request = new JsonApiRequest { @@ -162,10 +160,7 @@ public void Applies_cascading_settings_for_resource_links(LinkTypes linksInResou ResourceLinks = linksInResourceContext }; - var resourceGraph = new ResourceGraph(new[] - { - exampleResourceContext - }); + var resourceGraph = new ResourceGraph(exampleResourceContext.AsArray()); var request = new JsonApiRequest(); @@ -330,10 +325,7 @@ public void Applies_cascading_settings_for_relationship_links(LinkTypes linksInR RelationshipLinks = linksInResourceContext }; - var resourceGraph = new ResourceGraph(new[] - { - exampleResourceContext - }); + var resourceGraph = new ResourceGraph(exampleResourceContext.AsArray()); var request = new JsonApiRequest(); diff --git a/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs index 33eef8a83c..37f94ff1e1 100644 --- a/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteWithDbValuesTests.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using JsonApiDotNetCore; using JsonApiDotNetCore.Hooks.Internal.Execution; using JsonApiDotNetCoreExample.Data; using JsonApiDotNetCoreExample.Models; @@ -42,7 +43,7 @@ public void BeforeDelete() var (_, hookExecutor, personResourceMock, todoResourceMock, passportResourceMock) = CreateTestObjects(personDiscovery, todoDiscovery, passportDiscovery, repoDbContextOptions: _options); // Act - hookExecutor.BeforeDelete(new List { _person }, ResourcePipeline.Delete); + hookExecutor.BeforeDelete(_person.AsList(), ResourcePipeline.Delete); // Assert personResourceMock.Verify(rd => rd.BeforeDelete(It.IsAny>(), It.IsAny()), Times.Once()); @@ -61,7 +62,7 @@ public void BeforeDelete_No_Parent_Hooks() var (_, hookExecutor, personResourceMock, todoResourceMock, passportResourceMock) = CreateTestObjects(personDiscovery, todoDiscovery, passportDiscovery, repoDbContextOptions: _options); // Act - hookExecutor.BeforeDelete(new List { _person }, ResourcePipeline.Delete); + hookExecutor.BeforeDelete(_person.AsList(), ResourcePipeline.Delete); // Assert todoResourceMock.Verify(rd => rd.BeforeImplicitUpdateRelationship(It.Is>(rh => CheckImplicitTodoItems(rh)), ResourcePipeline.Delete), Times.Once()); @@ -79,7 +80,7 @@ public void BeforeDelete_No_Children_Hooks() var (_, hookExecutor, personResourceMock, todoResourceMock, passportResourceMock) = CreateTestObjects(personDiscovery, todoDiscovery, passportDiscovery, repoDbContextOptions: _options); // Act - hookExecutor.BeforeDelete(new List { _person }, ResourcePipeline.Delete); + hookExecutor.BeforeDelete(_person.AsList(), ResourcePipeline.Delete); // Assert personResourceMock.Verify(rd => rd.BeforeDelete(It.IsAny>(), It.IsAny()), Times.Once()); diff --git a/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs b/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs index 5a08ab777a..f41cd99dc7 100644 --- a/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using JsonApiDotNetCore; using JsonApiDotNetCore.Hooks.Internal.Execution; using JsonApiDotNetCoreExample.Models; using Moq; @@ -37,7 +38,7 @@ public sealed class ManyToManyOnReturnTests : HooksTestsSetup var allJoins = joinsSubSet.Concat(completeJoin).ToList(); - var articles = new List
    { articleTagsSubset, articleWithAllTags }; + var articles = ArrayFactory.Create(articleTagsSubset, articleWithAllTags).ToList(); return (articles, allJoins, allTags); } diff --git a/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs b/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs index 1c95e78f03..b6562b15c9 100644 --- a/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs @@ -1,6 +1,5 @@ -using System.Collections.Generic; +using System.Linq; using JsonApiDotNetCore.Hooks.Internal.Execution; -using JsonApiDotNetCore.Queries; using JsonApiDotNetCoreExample.Models; using Moq; using Xunit; @@ -37,7 +36,7 @@ public void BeforeReadWithInclusion() // eg a call on api/todoItems?include=owner,assignee,stakeHolders var relationshipsChains = GetIncludedRelationshipsChains("owner", "assignee", "stakeHolders"); - constraintsMock.Setup(x => x.GetEnumerator()).Returns(new List(ConvertInclusionChains(relationshipsChains)).GetEnumerator()); + constraintsMock.Setup(x => x.GetEnumerator()).Returns(ConvertInclusionChains(relationshipsChains).GetEnumerator()); // Act hookExecutor.BeforeRead(ResourcePipeline.Get); @@ -59,7 +58,7 @@ public void BeforeReadWithNestedInclusion() // eg a call on api/todoItems?include=owner.passport,assignee,stakeHolders var relationshipsChains = GetIncludedRelationshipsChains("owner.passport", "assignee", "stakeHolders"); - constraintsMock.Setup(x => x.GetEnumerator()).Returns(new List(ConvertInclusionChains(relationshipsChains)).GetEnumerator()); + constraintsMock.Setup(x => x.GetEnumerator()).Returns(ConvertInclusionChains(relationshipsChains).GetEnumerator()); // Act hookExecutor.BeforeRead(ResourcePipeline.Get); @@ -83,7 +82,7 @@ public void BeforeReadWithNestedInclusion_No_Parent_Hook_Implemented() // eg a call on api/todoItems?include=owner.passport,assignee,stakeHolders var relationshipsChains = GetIncludedRelationshipsChains("owner.passport", "assignee", "stakeHolders"); - constraintsMock.Setup(x => x.GetEnumerator()).Returns(new List(ConvertInclusionChains(relationshipsChains)).GetEnumerator()); + constraintsMock.Setup(x => x.GetEnumerator()).Returns(ConvertInclusionChains(relationshipsChains).GetEnumerator()); // Act hookExecutor.BeforeRead(ResourcePipeline.Get); @@ -105,7 +104,7 @@ public void BeforeReadWithNestedInclusion_No_Child_Hook_Implemented() // eg a call on api/todoItems?include=owner.passport,assignee,stakeHolders var relationshipsChains = GetIncludedRelationshipsChains("owner.passport", "assignee", "stakeHolders"); - constraintsMock.Setup(x => x.GetEnumerator()).Returns(new List(ConvertInclusionChains(relationshipsChains)).GetEnumerator()); + constraintsMock.Setup(x => x.GetEnumerator()).Returns(ConvertInclusionChains(relationshipsChains).GetEnumerator()); // Act hookExecutor.BeforeRead(ResourcePipeline.Get); @@ -127,7 +126,7 @@ public void BeforeReadWithNestedInclusion_No_Grandchild_Hook_Implemented() // eg a call on api/todoItems?include=owner.passport,assignee,stakeHolders var relationshipsChains = GetIncludedRelationshipsChains("owner.passport", "assignee", "stakeHolders"); - constraintsMock.Setup(x => x.GetEnumerator()).Returns(new List(ConvertInclusionChains(relationshipsChains)).GetEnumerator()); + constraintsMock.Setup(x => x.GetEnumerator()).Returns(ConvertInclusionChains(relationshipsChains).GetEnumerator()); // Act hookExecutor.BeforeRead(ResourcePipeline.Get); @@ -150,7 +149,7 @@ public void BeforeReadWithNestedInclusion_Without_Any_Hook_Implemented() // eg a call on api/todoItems?include=owner.passport,assignee,stakeHolders var relationshipsChains = GetIncludedRelationshipsChains("owner.passport", "assignee", "stakeHolders"); - constraintsMock.Setup(x => x.GetEnumerator()).Returns(new List(ConvertInclusionChains(relationshipsChains)).GetEnumerator()); + constraintsMock.Setup(x => x.GetEnumerator()).Returns(ConvertInclusionChains(relationshipsChains).GetEnumerator()); // Act hookExecutor.BeforeRead(ResourcePipeline.Get); diff --git a/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs b/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs index 986011e7b2..0b2b3ab1c9 100644 --- a/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JsonApiDotNetCore; using JsonApiDotNetCore.Hooks.Internal.Execution; using JsonApiDotNetCoreExample.Models; using Moq; @@ -23,7 +24,7 @@ public void Resource_Has_Multiple_Relations_To_Same_Type() todo.Assignee = person2; var person3 = new Person { StakeHolderTodoItem = todo }; todo.StakeHolders = new HashSet { person3 }; - var todoList = new List { todo }; + var todoList = todo.AsList(); // Act hookExecutor.OnReturn(todoList, ResourcePipeline.Post); @@ -42,8 +43,8 @@ public void Resource_Has_Cyclic_Relations() var (_, hookExecutor, todoResourceMock) = CreateTestObjects(todoDiscovery); var todo = new TodoItem(); todo.ParentTodo = todo; - todo.ChildTodoItems = new List { todo }; - var todoList = new List { todo }; + todo.ChildTodoItems = todo.AsList(); + var todoList = todo.AsList(); // Act hookExecutor.OnReturn(todoList, ResourcePipeline.Post); @@ -61,13 +62,13 @@ public void Resource_Has_Nested_Cyclic_Relations() var (_, hookExecutor, todoResourceMock) = CreateTestObjects(todoDiscovery); var rootTodo = new TodoItem { Id = 1 }; var child = new TodoItem { ParentTodo = rootTodo, Id = 2 }; - rootTodo.ChildTodoItems = new List { child }; + rootTodo.ChildTodoItems = child.AsList(); var grandChild = new TodoItem { ParentTodo = child, Id = 3 }; - child.ChildTodoItems = new List { grandChild }; + child.ChildTodoItems = grandChild.AsList(); var greatGrandChild = new TodoItem { ParentTodo = grandChild, Id = 4 }; - grandChild.ChildTodoItems = new List { greatGrandChild }; - greatGrandChild.ChildTodoItems = new List { rootTodo }; - var todoList = new List { rootTodo }; + grandChild.ChildTodoItems = greatGrandChild.AsList(); + greatGrandChild.ChildTodoItems = rootTodo.AsList(); + var todoList = rootTodo.AsList(); // Act hookExecutor.OnReturn(todoList, ResourcePipeline.Post); diff --git a/test/UnitTests/ResourceHooks/HooksDummyData.cs b/test/UnitTests/ResourceHooks/HooksDummyData.cs index 158832c14c..980bf4d659 100644 --- a/test/UnitTests/ResourceHooks/HooksDummyData.cs +++ b/test/UnitTests/ResourceHooks/HooksDummyData.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using Bogus; +using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Hooks.Internal.Execution; using JsonApiDotNetCoreExample.Models; @@ -65,7 +66,7 @@ protected List CreateTodoWithToOnePerson() { var todoItem = TodoFaker.Generate(); var person = PersonFaker.Generate(); - var todoList = new List { todoItem }; + var todoList = todoItem.AsList(); person.OneToOneTodoItem = todoItem; todoItem.OneToOnePerson = person; return todoList; @@ -107,7 +108,7 @@ protected HashSet CreateTodoWithOwner() var allJoins = joinsSubSet.Concat(completeJoin).ToList(); - var articles = new List
    { articleTagsSubset, articleWithAllTags }; + var articles = ArrayFactory.Create(articleTagsSubset, articleWithAllTags).ToList(); return (articles, allJoins, allTags); } @@ -135,7 +136,7 @@ protected HashSet CreateTodoWithOwner() } var allJoins = joinsSubSet.Concat(completeJoin).ToList(); - var articles = new List
    { articleTagsSubset, articleWithAllTags }; + var articles = ArrayFactory.Create(articleTagsSubset, articleWithAllTags).ToList(); return (articles, allJoins, allTags); } } diff --git a/test/UnitTests/ResourceHooks/HooksTestsSetup.cs b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs index d189544d3a..80c0ab39be 100644 --- a/test/UnitTests/ResourceHooks/HooksTestsSetup.cs +++ b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs @@ -29,7 +29,7 @@ public class HooksTestsSetup : HooksDummyData var ufMock = new Mock(); var constraintsMock = new Mock>(); - constraintsMock.Setup(x => x.GetEnumerator()).Returns(new List(new IQueryConstraintProvider[0]).GetEnumerator()); + constraintsMock.Setup(x => x.GetEnumerator()).Returns(Enumerable.Empty().GetEnumerator()); var optionsMock = new JsonApiOptions { LoadDatabaseValues = false }; return (ufMock, constraintsMock, pfMock, optionsMock); @@ -137,7 +137,7 @@ protected IHooksDiscovery SetDiscoverableHooks(ResourceHoo .Returns(enableDbValuesHooks); } mock.Setup(discovery => discovery.DatabaseValuesEnabledHooks) - .Returns(new[] { ResourceHook.BeforeImplicitUpdateRelationship }.Concat(enableDbValuesHooks).ToArray()); + .Returns(ResourceHook.BeforeImplicitUpdateRelationship.AsEnumerable().Concat(enableDbValuesHooks).ToArray()); return mock.Object; } @@ -246,7 +246,7 @@ private IResourceReadRepository CreateTestRepository(AppDbC var targetedFields = new TargetedFields(); return new EntityFrameworkCoreRepository(targetedFields, resolver, resourceGraph, resourceFactory, - new List(), NullLoggerFactory.Instance); + Enumerable.Empty(), NullLoggerFactory.Instance); } private IDbContextResolver CreateTestDbResolver(AppDbContext dbContext) @@ -258,7 +258,7 @@ private IDbContextResolver CreateTestDbResolver(AppDbContext dbContext) private void ResolveInverseRelationships(AppDbContext context) { - var dbContextResolvers = new[] {new DbContextResolver(context)}; + var dbContextResolvers = new DbContextResolver(context).AsEnumerable(); var inverseRelationships = new InverseNavigationResolver(ResourceGraph, dbContextResolvers); inverseRelationships.Resolve(); } @@ -314,7 +314,7 @@ protected IEnumerable ConvertInclusionChains(List x.GetConstraints()).Returns(expressionsInScope); IQueryConstraintProvider includeConstraintProvider = mock.Object; - return new List {includeConstraintProvider}; + return includeConstraintProvider.AsEnumerable(); } } diff --git a/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs b/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs index 72272dd019..d512ae9bca 100644 --- a/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs +++ b/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JsonApiDotNetCore; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; using JsonApiDotNetCore.Serialization.Building; @@ -66,7 +67,7 @@ public void ResourceToDocument_SingleResource_CanBuild() public void ResourceToDocument_ResourceList_CanBuild() { // Arrange - var resources = new List { new DummyResource(), new DummyResource() }; + var resources = ArrayFactory.Create(new DummyResource(), new DummyResource()); // Act var document = _builder.Build(resources); diff --git a/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs b/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs index bea75b9bf1..7933daaa6a 100644 --- a/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs +++ b/test/UnitTests/Serialization/Common/BaseDocumentParserTests.cs @@ -203,7 +203,7 @@ public void DeserializeAttributes_ComplexListType_CanDeserialize() Id = "1", Attributes = new Dictionary { - ["complexFields"] = new [] + ["complexFields"] = new[] { new Dictionary { diff --git a/test/UnitTests/Serialization/DeserializerTestsSetup.cs b/test/UnitTests/Serialization/DeserializerTestsSetup.cs index 4785b346af..920b79c977 100644 --- a/test/UnitTests/Serialization/DeserializerTestsSetup.cs +++ b/test/UnitTests/Serialization/DeserializerTestsSetup.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; @@ -52,22 +53,18 @@ protected Document CreateDocumentWithRelationships(string primaryType) protected RelationshipEntry CreateRelationshipData(string relatedType = null, bool isToManyData = false, string id = "10") { - var data = new RelationshipEntry(); + var entry = new RelationshipEntry(); var rio = relatedType == null ? null : new ResourceIdentifierObject { Id = id, Type = relatedType }; if (isToManyData) { - data.Data = new List(); - if (relatedType != null) - { - ((List)data.Data).Add(rio); - } + entry.Data = relatedType != null ? rio.AsList() : new List(); } else { - data.Data = rio; + entry.Data = rio; } - return data; + return entry; } protected Document CreateTestResourceDocument() diff --git a/test/UnitTests/Serialization/SerializerTestsSetup.cs b/test/UnitTests/Serialization/SerializerTestsSetup.cs index a7bd82a8ad..7fd845c16f 100644 --- a/test/UnitTests/Serialization/SerializerTestsSetup.cs +++ b/test/UnitTests/Serialization/SerializerTestsSetup.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Queries.Expressions; @@ -39,7 +40,7 @@ public SerializerTestsSetup() }; } - protected ResponseSerializer GetResponseSerializer(List> inclusionChains = null, Dictionary metaDict = null, TopLevelLinks topLinks = null, ResourceLinks resourceLinks = null, RelationshipLinks relationshipLinks = null) where T : class, IIdentifiable + protected ResponseSerializer GetResponseSerializer(IEnumerable> inclusionChains = null, Dictionary metaDict = null, TopLevelLinks topLinks = null, ResourceLinks resourceLinks = null, RelationshipLinks relationshipLinks = null) where T : class, IIdentifiable { var meta = GetMetaBuilder(metaDict); var link = GetLinkBuilder(topLinks, resourceLinks, relationshipLinks); @@ -50,7 +51,7 @@ protected ResponseSerializer GetResponseSerializer(List(meta, link, includedBuilder, fieldsToSerialize, resourceObjectBuilder, new JsonApiOptions()); } - protected ResponseResourceObjectBuilder GetResponseResourceObjectBuilder(List> inclusionChains = null, ResourceLinks resourceLinks = null, RelationshipLinks relationshipLinks = null) + protected ResponseResourceObjectBuilder GetResponseResourceObjectBuilder(IEnumerable> inclusionChains = null, ResourceLinks resourceLinks = null, RelationshipLinks relationshipLinks = null) { var link = GetLinkBuilder(null, resourceLinks, relationshipLinks); var includeConstraints = GetIncludeConstraints(inclusionChains); @@ -100,13 +101,13 @@ protected IFieldsToSerialize GetSerializableFields() return mock.Object; } - protected IEnumerable GetIncludeConstraints(List> inclusionChains = null) + protected IEnumerable GetIncludeConstraints(IEnumerable> inclusionChains = null) { var expressionsInScope = new List(); if (inclusionChains != null) { - var chains = inclusionChains.Select(relationships => new ResourceFieldChainExpression(relationships)).ToList(); + var chains = inclusionChains.Select(relationships => new ResourceFieldChainExpression(relationships.ToArray())).ToList(); var includeExpression = IncludeChainConverter.FromRelationshipChains(chains); expressionsInScope.Add(new ExpressionInScope(null, includeExpression)); } @@ -115,7 +116,7 @@ protected IEnumerable GetIncludeConstraints(List x.GetConstraints()).Returns(expressionsInScope); IQueryConstraintProvider includeConstraintProvider = mock.Object; - return new List {includeConstraintProvider}; + return includeConstraintProvider.AsEnumerable(); } /// diff --git a/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs b/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs index 7dcc2acd64..7586ed17a1 100644 --- a/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs +++ b/test/UnitTests/Serialization/Server/ResponseResourceObjectBuilderTests.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using JsonApiDotNetCore; using JsonApiDotNetCore.Resources.Annotations; using UnitTests.TestModels; using Xunit; @@ -52,7 +53,7 @@ public void Build_RelationshipIncludedAndLinksDisabled_RelationshipEntryWithData { // Arrange var resource = new OneToManyPrincipal { Id = 10, Dependents = new HashSet { new OneToManyDependent { Id = 20 } } }; - var builder = GetResponseResourceObjectBuilder(inclusionChains: new List> { _relationshipsForBuild } ); + var builder = GetResponseResourceObjectBuilder(inclusionChains: _relationshipsForBuild.AsEnumerable()); // Act var resourceObject = builder.Build(resource, relationships: _relationshipsForBuild); @@ -69,7 +70,7 @@ public void Build_RelationshipIncludedAndLinksEnabled_RelationshipEntryWithDataA { // Arrange var resource = new OneToManyPrincipal { Id = 10, Dependents = new HashSet { new OneToManyDependent { Id = 20 } } }; - var builder = GetResponseResourceObjectBuilder(inclusionChains: new List> { _relationshipsForBuild }, relationshipLinks: DummyRelationshipLinks); + var builder = GetResponseResourceObjectBuilder(inclusionChains: _relationshipsForBuild.AsEnumerable(), relationshipLinks: DummyRelationshipLinks); // Act var resourceObject = builder.Build(resource, relationships: _relationshipsForBuild); diff --git a/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs b/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs index c1d86e8b62..fad17e27cd 100644 --- a/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs +++ b/test/UnitTests/Serialization/Server/ResponseSerializerTests.cs @@ -2,7 +2,7 @@ using System.Linq; using System.Net; using System.Text.RegularExpressions; -using JsonApiDotNetCore.Resources.Annotations; +using JsonApiDotNetCore; using JsonApiDotNetCore.Serialization.Objects; using Newtonsoft.Json; using UnitTests.TestModels; @@ -52,7 +52,7 @@ public void SerializeMany_ResourceWithDefaultTargetFields_CanSerialize() var serializer = GetResponseSerializer(); // Act - string serialized = serializer.SerializeMany(new List { resource }); + string serialized = serializer.SerializeMany(resource.AsArray()); // Assert const string expectedFormatted = @"{ @@ -85,7 +85,7 @@ public void SerializeSingle_ResourceWithIncludedRelationships_CanSerialize() PopulatedToOne = new OneToOneDependent { Id = 10 }, PopulatedToManies = new HashSet { new OneToManyDependent { Id = 20 } } }; - var chain = ResourceGraph.GetRelationships().Select(r => new List { r }).ToList(); + var chain = ResourceGraph.GetRelationships().Select(r => r.AsEnumerable()).ToList(); var serializer = GetResponseSerializer(inclusionChains: chain); // Act @@ -150,10 +150,10 @@ public void SerializeSingle_ResourceWithDeeplyIncludedRelationships_CanSerialize var chains = ResourceGraph.GetRelationships() .Select(r => { - var chain = new List {r}; + var chain = r.AsList(); if (r.PublicName != "populatedToManies") { - return new List {r}; + return chain; } chain.AddRange(ResourceGraph.GetRelationships()); @@ -246,6 +246,7 @@ public void SerializeList_EmptyList_CanSerialize() { // Arrange var serializer = GetResponseSerializer(); + // Act string serialized = serializer.SerializeMany(new List()); From 5a8ff066b6acfbebc10ef0bd72f877d52e819dbe Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Tue, 23 Feb 2021 13:56:31 +0100 Subject: [PATCH 30/60] Corrected link rendering for hosting inside an IIS application vdir (#955) Corrected link rendering for hosting inside an IIS application virtual directory --- .../Middleware/JsonApiMiddleware.cs | 5 + .../HostingInIIS/ArtGalleriesController.cs | 16 +++ .../HostingInIIS/ArtGallery.cs | 15 +++ .../HostingInIIS/HostingDbContext.cs | 15 +++ .../HostingInIIS/HostingFakers.cs | 22 ++++ .../HostingInIIS/HostingStartup.cs | 32 +++++ .../HostingInIIS/HostingTests.cs | 116 ++++++++++++++++++ .../IntegrationTests/HostingInIIS/Painting.cs | 14 +++ .../HostingInIIS/PaintingsController.cs | 19 +++ .../KebabCasingConventionStartup.cs | 1 - 10 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/ArtGalleriesController.cs create mode 100644 test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/ArtGallery.cs create mode 100644 test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingDbContext.cs create mode 100644 test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingFakers.cs create mode 100644 test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingStartup.cs create mode 100644 test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingTests.cs create mode 100644 test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/Painting.cs create mode 100644 test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/PaintingsController.cs diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs index 82b8712219..24bdb2c779 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs @@ -222,6 +222,11 @@ private static string GetBasePath(string resourceName, IJsonApiOptions options, builder.Append(httpRequest.Host); } + if (httpRequest.PathBase.HasValue) + { + builder.Append(httpRequest.PathBase); + } + string customRoute = GetCustomRoute(resourceName, options.Namespace, httpRequest.HttpContext); if (!string.IsNullOrEmpty(customRoute)) { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/ArtGalleriesController.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/ArtGalleriesController.cs new file mode 100644 index 0000000000..d7383df1eb --- /dev/null +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/ArtGalleriesController.cs @@ -0,0 +1,16 @@ +using JsonApiDotNetCore.Configuration; +using JsonApiDotNetCore.Controllers; +using JsonApiDotNetCore.Services; +using Microsoft.Extensions.Logging; + +namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS +{ + public sealed class ArtGalleriesController : JsonApiController + { + public ArtGalleriesController(IJsonApiOptions options, ILoggerFactory loggerFactory, + IResourceService resourceService) + : base(options, loggerFactory, resourceService) + { + } + } +} diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/ArtGallery.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/ArtGallery.cs new file mode 100644 index 0000000000..470b7c4e63 --- /dev/null +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/ArtGallery.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + +namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS +{ + public sealed class ArtGallery : Identifiable + { + [Attr] + public string Theme { get; set; } + + [HasMany] + public ISet Paintings { get; set; } + } +} diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingDbContext.cs new file mode 100644 index 0000000000..03795fe1cf --- /dev/null +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingDbContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; + +namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS +{ + public sealed class HostingDbContext : DbContext + { + public DbSet ArtGalleries { get; set; } + public DbSet Paintings { get; set; } + + public HostingDbContext(DbContextOptions options) + : base(options) + { + } + } +} diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingFakers.cs new file mode 100644 index 0000000000..428c27ad69 --- /dev/null +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingFakers.cs @@ -0,0 +1,22 @@ +using System; +using Bogus; +using TestBuildingBlocks; + +namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS +{ + internal sealed class HostingFakers : FakerContainer + { + private readonly Lazy> _lazyArtGalleryFaker = new Lazy>(() => + new Faker() + .UseSeed(GetFakerSeed()) + .RuleFor(artGallery => artGallery.Theme, f => f.Lorem.Word())); + + private readonly Lazy> _lazyPaintingFaker = new Lazy>(() => + new Faker() + .UseSeed(GetFakerSeed()) + .RuleFor(painting => painting.Title, f => f.Lorem.Sentence())); + + public Faker ArtGallery => _lazyArtGalleryFaker.Value; + public Faker Painting => _lazyPaintingFaker.Value; + } +} diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingStartup.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingStartup.cs new file mode 100644 index 0000000000..8d3da5f0e3 --- /dev/null +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingStartup.cs @@ -0,0 +1,32 @@ +using JsonApiDotNetCore.Configuration; +using JsonApiDotNetCoreExampleTests.Startups; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; + +namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS +{ + public sealed class HostingStartup : TestableStartup + where TDbContext : DbContext + { + public HostingStartup(IConfiguration configuration) : base(configuration) + { + } + + protected override void SetJsonApiOptions(JsonApiOptions options) + { + base.SetJsonApiOptions(options); + + options.Namespace = "public-api"; + options.IncludeTotalResourceCount = true; + } + + public override void Configure(IApplicationBuilder app, IWebHostEnvironment environment) + { + app.UsePathBase("/iis-application-virtual-directory"); + + base.Configure(app, environment); + } + } +} diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingTests.cs new file mode 100644 index 0000000000..e3e35b7f72 --- /dev/null +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingTests.cs @@ -0,0 +1,116 @@ +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using FluentAssertions; +using JsonApiDotNetCore.Serialization.Objects; +using TestBuildingBlocks; +using Xunit; + +namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS +{ + public sealed class HostingTests + : IClassFixture, HostingDbContext>> + { + private const string HostPrefix = "http://localhost"; + + private readonly ExampleIntegrationTestContext, HostingDbContext> _testContext; + private readonly HostingFakers _fakers = new HostingFakers(); + + public HostingTests(ExampleIntegrationTestContext, HostingDbContext> testContext) + { + _testContext = testContext; + } + + [Fact] + public async Task Get_primary_resources_with_include_returns_links() + { + // Arrange + var gallery = _fakers.ArtGallery.Generate(); + gallery.Paintings = _fakers.Painting.Generate(1).ToHashSet(); + + await _testContext.RunOnDatabaseAsync(async dbContext => + { + await dbContext.ClearTableAsync(); + dbContext.ArtGalleries.Add(gallery); + await dbContext.SaveChangesAsync(); + }); + + const string route = "/iis-application-virtual-directory/public-api/artGalleries?include=paintings"; + + // Act + var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); + + // Assert + httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); + + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.Related.Should().BeNull(); + responseDocument.Links.First.Should().Be(HostPrefix + route); + responseDocument.Links.Last.Should().Be(HostPrefix + route); + responseDocument.Links.Prev.Should().BeNull(); + responseDocument.Links.Next.Should().BeNull(); + + string galleryLink = HostPrefix + $"/iis-application-virtual-directory/public-api/artGalleries/{gallery.StringId}"; + + responseDocument.ManyData.Should().HaveCount(1); + responseDocument.ManyData[0].Links.Self.Should().Be(galleryLink); + responseDocument.ManyData[0].Relationships["paintings"].Links.Self.Should().Be(galleryLink + "/relationships/paintings"); + responseDocument.ManyData[0].Relationships["paintings"].Links.Related.Should().Be(galleryLink + "/paintings"); + + // TODO: The next link is wrong: it should use the custom route. + // https://github.com/json-api-dotnet/JsonApiDotNetCore/issues/956 + string paintingLink = HostPrefix + $"/iis-application-virtual-directory/public-api/paintings/{gallery.Paintings.ElementAt(0).StringId}"; + + responseDocument.Included.Should().HaveCount(1); + responseDocument.Included[0].Links.Self.Should().Be(paintingLink); + responseDocument.Included[0].Relationships["exposedAt"].Links.Self.Should().Be(paintingLink + "/relationships/exposedAt"); + responseDocument.Included[0].Relationships["exposedAt"].Links.Related.Should().Be(paintingLink + "/exposedAt"); + } + + [Fact] + public async Task Get_primary_resources_with_include_on_custom_route_returns_links() + { + // Arrange + var painting = _fakers.Painting.Generate(); + painting.ExposedAt = _fakers.ArtGallery.Generate(); + + await _testContext.RunOnDatabaseAsync(async dbContext => + { + await dbContext.ClearTableAsync(); + dbContext.Paintings.Add(painting); + await dbContext.SaveChangesAsync(); + }); + + const string route = "/iis-application-virtual-directory/custom/path/to/paintings?include=exposedAt"; + + // Act + var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route); + + // Assert + httpResponse.Should().HaveStatusCode(HttpStatusCode.OK); + + responseDocument.Links.Self.Should().Be(HostPrefix + route); + responseDocument.Links.Related.Should().BeNull(); + responseDocument.Links.First.Should().Be(HostPrefix + route); + responseDocument.Links.Last.Should().Be(HostPrefix + route); + responseDocument.Links.Prev.Should().BeNull(); + responseDocument.Links.Next.Should().BeNull(); + + string paintingLink = HostPrefix + $"/iis-application-virtual-directory/custom/path/to/paintings/{painting.StringId}"; + + responseDocument.ManyData.Should().HaveCount(1); + responseDocument.ManyData[0].Links.Self.Should().Be(paintingLink); + responseDocument.ManyData[0].Relationships["exposedAt"].Links.Self.Should().Be(paintingLink + "/relationships/exposedAt"); + responseDocument.ManyData[0].Relationships["exposedAt"].Links.Related.Should().Be(paintingLink + "/exposedAt"); + + // TODO: The next link is wrong: it should not use the custom route. + // https://github.com/json-api-dotnet/JsonApiDotNetCore/issues/956 + string galleryLink = HostPrefix + $"/iis-application-virtual-directory/custom/path/to/artGalleries/{painting.ExposedAt.StringId}"; + + responseDocument.Included.Should().HaveCount(1); + responseDocument.Included[0].Links.Self.Should().Be(galleryLink); + responseDocument.Included[0].Relationships["paintings"].Links.Self.Should().Be(galleryLink + "/relationships/paintings"); + responseDocument.Included[0].Relationships["paintings"].Links.Related.Should().Be(galleryLink + "/paintings"); + } + } +} diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/Painting.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/Painting.cs new file mode 100644 index 0000000000..75979bf30c --- /dev/null +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/Painting.cs @@ -0,0 +1,14 @@ +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Resources.Annotations; + +namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS +{ + public sealed class Painting : Identifiable + { + [Attr] + public string Title { get; set; } + + [HasOne] + public ArtGallery ExposedAt { get; set; } + } +} diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/PaintingsController.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/PaintingsController.cs new file mode 100644 index 0000000000..ced2427169 --- /dev/null +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/PaintingsController.cs @@ -0,0 +1,19 @@ +using JsonApiDotNetCore.Configuration; +using JsonApiDotNetCore.Controllers; +using JsonApiDotNetCore.Controllers.Annotations; +using JsonApiDotNetCore.Services; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS +{ + [DisableRoutingConvention, Route("custom/path/to/paintings")] + public sealed class PaintingsController : JsonApiController + { + public PaintingsController(IJsonApiOptions options, ILoggerFactory loggerFactory, + IResourceService resourceService) + : base(options, loggerFactory, resourceService) + { + } + } +} diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs index d871dac25e..b7980fcb10 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs @@ -17,7 +17,6 @@ protected override void SetJsonApiOptions(JsonApiOptions options) { base.SetJsonApiOptions(options); - options.IncludeExceptionStackTraceInErrors = true; options.Namespace = "public-api"; options.UseRelativeLinks = true; options.IncludeTotalResourceCount = true; From de03aba0db06bf7e32a2e766fa0beca86ea02b9b Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Tue, 23 Feb 2021 13:57:46 +0100 Subject: [PATCH 31/60] Update version from 4.0.3 to 4.0.4 --- src/JsonApiDotNetCore/JsonApiDotNetCore.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj b/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj index f19914dc3c..33a5e9647e 100644 --- a/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj +++ b/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj @@ -1,6 +1,6 @@ - 4.0.3 + 4.0.4 $(NetCoreAppVersion) true From 2ca3086e132e3de29a081378eb4ae0537953e9e6 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 24 Feb 2021 13:10:41 +0100 Subject: [PATCH 32/60] Marked types/members sealed/internal where non-breaking --- benchmarks/Program.cs | 2 +- benchmarks/SubResource.cs | 4 ++-- src/Examples/GettingStarted/Program.cs | 4 ++-- .../Definitions/ArticleHooksDefinition.cs | 2 +- .../Definitions/PassportHooksDefinition.cs | 2 +- .../Definitions/PersonHooksDefinition.cs | 2 +- .../Definitions/TagHooksDefinition.cs | 2 +- .../Definitions/TodoItemHooksDefinition.cs | 2 +- .../Models/IdentifiableArticleTag.cs | 2 +- .../JsonApiDotNetCoreExample/Models/Passport.cs | 2 +- src/Examples/JsonApiDotNetCoreExample/Models/Tag.cs | 2 +- .../JsonApiDotNetCoreExample/Models/TodoItem.cs | 2 +- src/Examples/JsonApiDotNetCoreExample/Models/User.cs | 2 +- src/Examples/JsonApiDotNetCoreExample/Program.cs | 4 ++-- .../JsonApiDotNetCoreExample/Startups/Startup.cs | 4 ++-- src/Examples/MultiDbContextExample/Program.cs | 4 ++-- .../Repositories/DbContextARepository.cs | 2 +- .../Repositories/DbContextBRepository.cs | 2 +- src/Examples/MultiDbContextExample/Startup.cs | 2 +- src/Examples/NoEntityFrameworkExample/Program.cs | 4 ++-- src/Examples/NoEntityFrameworkExample/Startup.cs | 2 +- src/Examples/ReportsExample/Program.cs | 4 ++-- src/JsonApiDotNetCore/ArgumentGuard.cs | 2 +- .../Configuration/JsonApiModelMetadataProvider.cs | 2 +- .../Configuration/ResourceDescriptor.cs | 2 +- test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs | 8 ++++---- .../ExampleIntegrationTestContext.cs | 2 +- .../ResourceDefinitions/LyricPermissionProvider.cs | 4 ++-- .../CompositeKeys/CarExpressionRewriter.cs | 2 +- .../BaseToothbrushesController.cs | 10 +++++----- .../ConsumerArticleIsNoLongerAvailableException.cs | 4 +--- .../ExceptionHandling/ConsumerArticleService.cs | 2 +- .../SparseFieldSets/ResourceCaptureStore.cs | 6 +++--- .../SkipCacheQueryStringParameterReader.cs | 2 ++ .../SoftDeletion/SoftDeletionResourceDefinition.cs | 2 +- .../ServiceCollectionExtensions.cs | 2 +- .../TestBuildingBlocks/IntegrationTestConfiguration.cs | 2 +- test/UnitTests/Builders/ResourceGraphBuilderTests.cs | 4 ++-- .../Extensions/ServiceCollectionExtensionsTests.cs | 2 +- .../Graph/ResourceDescriptorAssemblyCacheTests.cs | 2 +- test/UnitTests/Internal/ResourceGraphBuilderTests.cs | 4 ++-- test/UnitTests/Models/ResourceWithStringConstructor.cs | 4 ++-- .../Models/ResourceWithThrowingConstructor.cs | 4 ++-- test/UnitTests/Models/ResourceWithoutConstructor.cs | 4 ++-- test/UnitTests/ResourceHooks/DiscoveryTests.cs | 6 +++--- test/UnitTests/ResourceHooks/NotTargeted.cs | 4 ++-- test/UnitTests/TestModels/Article.cs | 4 ++-- test/UnitTests/TestModels/Blog.cs | 4 ++-- test/UnitTests/TestModels/ComplexType.cs | 4 ++-- test/UnitTests/TestModels/FirstDerivedModel.cs | 4 ++-- test/UnitTests/TestModels/Food.cs | 4 ++-- .../TestModels/MultipleRelationshipsDependentPart.cs | 4 ++-- .../UnitTests/TestModels/OneToManyRequiredDependent.cs | 4 ++-- test/UnitTests/TestModels/Person.cs | 4 ++-- test/UnitTests/TestModels/SecondDerivedModel.cs | 4 ++-- test/UnitTests/TestModels/Song.cs | 4 ++-- .../TestModels/TestResourceWithAbstractRelationship.cs | 4 ++-- test/UnitTests/TestModels/TestResourceWithList.cs | 4 ++-- 58 files changed, 96 insertions(+), 96 deletions(-) diff --git a/benchmarks/Program.cs b/benchmarks/Program.cs index 396f8786cb..963b0322e8 100644 --- a/benchmarks/Program.cs +++ b/benchmarks/Program.cs @@ -5,7 +5,7 @@ namespace Benchmarks { - internal class Program + internal static class Program { private static void Main(string[] args) { diff --git a/benchmarks/SubResource.cs b/benchmarks/SubResource.cs index 71c59b6785..f37e4384c0 100644 --- a/benchmarks/SubResource.cs +++ b/benchmarks/SubResource.cs @@ -3,9 +3,9 @@ namespace Benchmarks { - public class SubResource : Identifiable + public sealed class SubResource : Identifiable { [Attr] public string Value { get; set; } } -} \ No newline at end of file +} diff --git a/src/Examples/GettingStarted/Program.cs b/src/Examples/GettingStarted/Program.cs index f58d01afb3..fad81e1bba 100644 --- a/src/Examples/GettingStarted/Program.cs +++ b/src/Examples/GettingStarted/Program.cs @@ -3,14 +3,14 @@ namespace GettingStarted { - public static class Program + internal static class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } - public static IHostBuilder CreateHostBuilder(string[] args) => + private static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/ArticleHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/ArticleHooksDefinition.cs index 9c91823669..7b84ce0378 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/ArticleHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/ArticleHooksDefinition.cs @@ -10,7 +10,7 @@ namespace JsonApiDotNetCoreExample.Definitions { - public class ArticleHooksDefinition : ResourceHooksDefinition
    + public sealed class ArticleHooksDefinition : ResourceHooksDefinition
    { public ArticleHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/PassportHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/PassportHooksDefinition.cs index 5ccfcf2447..2e9cf34a15 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/PassportHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/PassportHooksDefinition.cs @@ -9,7 +9,7 @@ namespace JsonApiDotNetCoreExample.Definitions { - public class PassportHooksDefinition : LockableHooksDefinition + public sealed class PassportHooksDefinition : LockableHooksDefinition { public PassportHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/PersonHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/PersonHooksDefinition.cs index 42c1b405e4..33a5defbce 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/PersonHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/PersonHooksDefinition.cs @@ -6,7 +6,7 @@ namespace JsonApiDotNetCoreExample.Definitions { - public class PersonHooksDefinition : LockableHooksDefinition + public sealed class PersonHooksDefinition : LockableHooksDefinition { public PersonHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/TagHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/TagHooksDefinition.cs index 7112924140..f9339719f0 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/TagHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/TagHooksDefinition.cs @@ -7,7 +7,7 @@ namespace JsonApiDotNetCoreExample.Definitions { - public class TagHooksDefinition : ResourceHooksDefinition + public sealed class TagHooksDefinition : ResourceHooksDefinition { public TagHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs index 3d8ef7f1c0..31a7e8aae9 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs @@ -9,7 +9,7 @@ namespace JsonApiDotNetCoreExample.Definitions { - public class TodoItemHooksDefinition : LockableHooksDefinition + public sealed class TodoItemHooksDefinition : LockableHooksDefinition { public TodoItemHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/IdentifiableArticleTag.cs b/src/Examples/JsonApiDotNetCoreExample/Models/IdentifiableArticleTag.cs index 1d64298d7d..91131b8187 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/IdentifiableArticleTag.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/IdentifiableArticleTag.cs @@ -3,7 +3,7 @@ namespace JsonApiDotNetCoreExample.Models { - public class IdentifiableArticleTag : Identifiable + public sealed class IdentifiableArticleTag : Identifiable { public int ArticleId { get; set; } [HasOne] diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/Passport.cs b/src/Examples/JsonApiDotNetCoreExample/Models/Passport.cs index 0945d47938..600a77d285 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/Passport.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/Passport.cs @@ -3,7 +3,7 @@ namespace JsonApiDotNetCoreExample.Models { - public class Passport : Identifiable, IIsLockable + public sealed class Passport : Identifiable, IIsLockable { [Attr] public bool IsLocked { get; set; } diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/Tag.cs b/src/Examples/JsonApiDotNetCoreExample/Models/Tag.cs index 995adea17e..ae98d787d5 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/Tag.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/Tag.cs @@ -3,7 +3,7 @@ namespace JsonApiDotNetCoreExample.Models { - public class Tag : Identifiable + public sealed class Tag : Identifiable { [Attr] public string Name { get; set; } diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs b/src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs index 48e76cec8a..b7982e182d 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs @@ -4,7 +4,7 @@ namespace JsonApiDotNetCoreExample.Models { - public class TodoItem : Identifiable, IIsLockable + public sealed class TodoItem : Identifiable, IIsLockable { public bool IsLocked { get; set; } diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/User.cs b/src/Examples/JsonApiDotNetCoreExample/Models/User.cs index f61cf6e7ef..7361fe0e72 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/User.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/User.cs @@ -3,7 +3,7 @@ namespace JsonApiDotNetCoreExample.Models { - public class User : Identifiable + public sealed class User : Identifiable { [Attr] public string UserName { get; set; } diff --git a/src/Examples/JsonApiDotNetCoreExample/Program.cs b/src/Examples/JsonApiDotNetCoreExample/Program.cs index 4a6647a3f1..e2866c25ec 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Program.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Program.cs @@ -4,14 +4,14 @@ namespace JsonApiDotNetCoreExample { - public static class Program + internal static class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } - public static IHostBuilder CreateHostBuilder(string[] args) => + private static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { diff --git a/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs b/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs index 9586e0ac17..8d8fbb58fa 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs @@ -12,7 +12,7 @@ namespace JsonApiDotNetCoreExample.Startups { - public class Startup : EmptyStartup + public sealed class Startup : EmptyStartup { private static readonly Version PostgresCiBuildVersion = new Version(9, 6); private readonly string _connectionString; @@ -37,7 +37,7 @@ public override void ConfigureServices(IServiceCollection services) services.AddJsonApi(ConfigureJsonApiOptions, discovery => discovery.AddCurrentAssembly()); } - protected void ConfigureJsonApiOptions(JsonApiOptions options) + private void ConfigureJsonApiOptions(JsonApiOptions options) { options.IncludeExceptionStackTraceInErrors = true; options.Namespace = "api/v1"; diff --git a/src/Examples/MultiDbContextExample/Program.cs b/src/Examples/MultiDbContextExample/Program.cs index 1541869cee..5d138239c0 100644 --- a/src/Examples/MultiDbContextExample/Program.cs +++ b/src/Examples/MultiDbContextExample/Program.cs @@ -3,14 +3,14 @@ namespace MultiDbContextExample { - public static class Program + internal static class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } - public static IHostBuilder CreateHostBuilder(string[] args) + private static IHostBuilder CreateHostBuilder(string[] args) { return Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup()); diff --git a/src/Examples/MultiDbContextExample/Repositories/DbContextARepository.cs b/src/Examples/MultiDbContextExample/Repositories/DbContextARepository.cs index 574695700b..aeaf7fe7cb 100644 --- a/src/Examples/MultiDbContextExample/Repositories/DbContextARepository.cs +++ b/src/Examples/MultiDbContextExample/Repositories/DbContextARepository.cs @@ -8,7 +8,7 @@ namespace MultiDbContextExample.Repositories { - public class DbContextARepository : EntityFrameworkCoreRepository + public sealed class DbContextARepository : EntityFrameworkCoreRepository where TResource : class, IIdentifiable { public DbContextARepository(ITargetedFields targetedFields, DbContextResolver contextResolver, diff --git a/src/Examples/MultiDbContextExample/Repositories/DbContextBRepository.cs b/src/Examples/MultiDbContextExample/Repositories/DbContextBRepository.cs index 098a580579..5fb3c41651 100644 --- a/src/Examples/MultiDbContextExample/Repositories/DbContextBRepository.cs +++ b/src/Examples/MultiDbContextExample/Repositories/DbContextBRepository.cs @@ -8,7 +8,7 @@ namespace MultiDbContextExample.Repositories { - public class DbContextBRepository : EntityFrameworkCoreRepository + public sealed class DbContextBRepository : EntityFrameworkCoreRepository where TResource : class, IIdentifiable { public DbContextBRepository(ITargetedFields targetedFields, DbContextResolver contextResolver, diff --git a/src/Examples/MultiDbContextExample/Startup.cs b/src/Examples/MultiDbContextExample/Startup.cs index 09e120cd01..5b4c537591 100644 --- a/src/Examples/MultiDbContextExample/Startup.cs +++ b/src/Examples/MultiDbContextExample/Startup.cs @@ -10,7 +10,7 @@ namespace MultiDbContextExample { - public class Startup + public sealed class Startup { // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) diff --git a/src/Examples/NoEntityFrameworkExample/Program.cs b/src/Examples/NoEntityFrameworkExample/Program.cs index f455ca9728..c5b2eaa194 100755 --- a/src/Examples/NoEntityFrameworkExample/Program.cs +++ b/src/Examples/NoEntityFrameworkExample/Program.cs @@ -3,14 +3,14 @@ namespace NoEntityFrameworkExample { - public static class Program + internal static class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } - public static IHostBuilder CreateHostBuilder(string[] args) => + private static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { diff --git a/src/Examples/NoEntityFrameworkExample/Startup.cs b/src/Examples/NoEntityFrameworkExample/Startup.cs index 4754f6003d..f61d858f79 100644 --- a/src/Examples/NoEntityFrameworkExample/Startup.cs +++ b/src/Examples/NoEntityFrameworkExample/Startup.cs @@ -11,7 +11,7 @@ namespace NoEntityFrameworkExample { - public class Startup + public sealed class Startup { private readonly string _connectionString; diff --git a/src/Examples/ReportsExample/Program.cs b/src/Examples/ReportsExample/Program.cs index 049930dc48..ee8edaa620 100644 --- a/src/Examples/ReportsExample/Program.cs +++ b/src/Examples/ReportsExample/Program.cs @@ -3,14 +3,14 @@ namespace ReportsExample { - public static class Program + internal static class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } - public static IHostBuilder CreateHostBuilder(string[] args) => + private static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { diff --git a/src/JsonApiDotNetCore/ArgumentGuard.cs b/src/JsonApiDotNetCore/ArgumentGuard.cs index 68c76ca96e..28640848a2 100644 --- a/src/JsonApiDotNetCore/ArgumentGuard.cs +++ b/src/JsonApiDotNetCore/ArgumentGuard.cs @@ -5,7 +5,7 @@ namespace JsonApiDotNetCore { - public static class ArgumentGuard + internal static class ArgumentGuard { [AssertionMethod] [ContractAnnotation("value: null => halt")] diff --git a/src/JsonApiDotNetCore/Configuration/JsonApiModelMetadataProvider.cs b/src/JsonApiDotNetCore/Configuration/JsonApiModelMetadataProvider.cs index b363227b65..e40935696d 100644 --- a/src/JsonApiDotNetCore/Configuration/JsonApiModelMetadataProvider.cs +++ b/src/JsonApiDotNetCore/Configuration/JsonApiModelMetadataProvider.cs @@ -8,7 +8,7 @@ namespace JsonApiDotNetCore.Configuration /// /// Custom implementation of to support JSON:API partial patching. /// - internal class JsonApiModelMetadataProvider : DefaultModelMetadataProvider + internal sealed class JsonApiModelMetadataProvider : DefaultModelMetadataProvider { private readonly JsonApiValidationFilter _jsonApiValidationFilter; diff --git a/src/JsonApiDotNetCore/Configuration/ResourceDescriptor.cs b/src/JsonApiDotNetCore/Configuration/ResourceDescriptor.cs index 420b9015d6..70a14513ae 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceDescriptor.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceDescriptor.cs @@ -2,7 +2,7 @@ namespace JsonApiDotNetCore.Configuration { - internal class ResourceDescriptor + internal sealed class ResourceDescriptor { public Type ResourceType { get; } public Type IdType { get; } diff --git a/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs b/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs index d3401230d0..d9edcf8de3 100644 --- a/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs +++ b/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs @@ -156,7 +156,7 @@ public void Can_add_resource_hooks_definition_from_current_assembly_to_container public sealed class TestResource : Identifiable { } - public class TestResourceService : JsonApiResourceService + public sealed class TestResourceService : JsonApiResourceService { public TestResourceService( IResourceRepositoryAccessor repositoryAccessor, @@ -173,7 +173,7 @@ public TestResourceService( } } - public class TestResourceRepository : EntityFrameworkCoreRepository + public sealed class TestResourceRepository : EntityFrameworkCoreRepository { public TestResourceRepository( ITargetedFields targetedFields, @@ -186,12 +186,12 @@ public TestResourceRepository( { } } - public class TestResourceHooksDefinition : ResourceHooksDefinition + public sealed class TestResourceHooksDefinition : ResourceHooksDefinition { public TestResourceHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } } - public class TestResourceDefinition : JsonApiResourceDefinition + public sealed class TestResourceDefinition : JsonApiResourceDefinition { public TestResourceDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } } diff --git a/test/JsonApiDotNetCoreExampleTests/ExampleIntegrationTestContext.cs b/test/JsonApiDotNetCoreExampleTests/ExampleIntegrationTestContext.cs index 319f06f3a9..311d18b4d1 100644 --- a/test/JsonApiDotNetCoreExampleTests/ExampleIntegrationTestContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/ExampleIntegrationTestContext.cs @@ -9,7 +9,7 @@ namespace JsonApiDotNetCoreExampleTests ///
    /// The server Startup class, which can be defined in the test project. /// The EF Core database context, which can be defined in the test project. - public class ExampleIntegrationTestContext : BaseIntegrationTestContext + public sealed class ExampleIntegrationTestContext : BaseIntegrationTestContext where TStartup : class where TDbContext : DbContext { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ResourceDefinitions/LyricPermissionProvider.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ResourceDefinitions/LyricPermissionProvider.cs index 501c820391..07140f6fa1 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ResourceDefinitions/LyricPermissionProvider.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ResourceDefinitions/LyricPermissionProvider.cs @@ -2,7 +2,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.Resour { public sealed class LyricPermissionProvider { - public bool CanViewText { get; set; } - public int HitCount { get; set; } + internal bool CanViewText { get; set; } + internal int HitCount { get; set; } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs index 57b1d35d85..2da565d34e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs @@ -17,7 +17,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CompositeKeys /// /// This enables queries to use , which is not mapped in the database. /// - public sealed class CarExpressionRewriter : QueryExpressionRewriter + internal sealed class CarExpressionRewriter : QueryExpressionRewriter { private readonly AttrAttribute _regionIdAttribute; private readonly AttrAttribute _licensePlateAttribute; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/BaseToothbrushesController.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/BaseToothbrushesController.cs index 460ea8cded..e8d6f252f4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/BaseToothbrushesController.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/BaseToothbrushesController.cs @@ -12,11 +12,11 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ControllerActionResults { public abstract class BaseToothbrushesController : BaseJsonApiController { - public const int EmptyActionResultId = 11111111; - public const int ActionResultWithErrorObjectId = 22222222; - public const int ActionResultWithStringParameter = 33333333; - public const int ObjectResultWithErrorObjectId = 44444444; - public const int ObjectResultWithErrorCollectionId = 55555555; + internal const int EmptyActionResultId = 11111111; + internal const int ActionResultWithErrorObjectId = 22222222; + internal const int ActionResultWithStringParameter = 33333333; + internal const int ObjectResultWithErrorObjectId = 44444444; + internal const int ObjectResultWithErrorCollectionId = 55555555; protected BaseToothbrushesController(IJsonApiOptions options, ILoggerFactory loggerFactory, IResourceService resourceService) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleIsNoLongerAvailableException.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleIsNoLongerAvailableException.cs index f4420dea90..bae3760b76 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleIsNoLongerAvailableException.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleIsNoLongerAvailableException.cs @@ -4,9 +4,8 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ExceptionHandling { - public sealed class ConsumerArticleIsNoLongerAvailableException : JsonApiException + internal sealed class ConsumerArticleIsNoLongerAvailableException : JsonApiException { - public string ArticleCode { get; } public string SupportEmailAddress { get; } public ConsumerArticleIsNoLongerAvailableException(string articleCode, string supportEmailAddress) @@ -16,7 +15,6 @@ public ConsumerArticleIsNoLongerAvailableException(string articleCode, string su Detail = $"Article with code '{articleCode}' is no longer available." }) { - ArticleCode = articleCode; SupportEmailAddress = supportEmailAddress; } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs index b59e95b5c5..d80e32ce44 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs @@ -14,7 +14,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ExceptionHandling { public sealed class ConsumerArticleService : JsonApiResourceService { - public const string UnavailableArticlePrefix = "X"; + internal const string UnavailableArticlePrefix = "X"; private const string SupportEmailAddress = "company@email.com"; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/ResourceCaptureStore.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/ResourceCaptureStore.cs index 2082031663..08e342ff21 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/ResourceCaptureStore.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/ResourceCaptureStore.cs @@ -5,14 +5,14 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings.SparseFiel { public sealed class ResourceCaptureStore { - public List Resources { get; } = new List(); + internal List Resources { get; } = new List(); - public void Add(IEnumerable resources) + internal void Add(IEnumerable resources) { Resources.AddRange(resources); } - public void Clear() + internal void Clear() { Resources.Clear(); } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/SkipCacheQueryStringParameterReader.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/SkipCacheQueryStringParameterReader.cs index 53faca19cc..f129f5121e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/SkipCacheQueryStringParameterReader.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/SkipCacheQueryStringParameterReader.cs @@ -1,4 +1,5 @@ using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Controllers.Annotations; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.QueryStrings; @@ -10,6 +11,7 @@ public sealed class SkipCacheQueryStringParameterReader : IQueryStringParameterR { private const string SkipCacheParameterName = "skipCache"; + [UsedImplicitly] public bool SkipCache { get; private set; } public bool IsEnabled(DisableQueryStringAttribute disableQueryStringAttribute) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionResourceDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionResourceDefinition.cs index 151da3cd5c..a460536990 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionResourceDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionResourceDefinition.cs @@ -6,7 +6,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.SoftDeletion { - public class SoftDeletionResourceDefinition : JsonApiResourceDefinition + public sealed class SoftDeletionResourceDefinition : JsonApiResourceDefinition where TResource : class, IIdentifiable, ISoftDeletable { private readonly IResourceGraph _resourceGraph; diff --git a/test/JsonApiDotNetCoreExampleTests/ServiceCollectionExtensions.cs b/test/JsonApiDotNetCoreExampleTests/ServiceCollectionExtensions.cs index e3edf1f02d..b0ec80ebe3 100644 --- a/test/JsonApiDotNetCoreExampleTests/ServiceCollectionExtensions.cs +++ b/test/JsonApiDotNetCoreExampleTests/ServiceCollectionExtensions.cs @@ -4,7 +4,7 @@ namespace JsonApiDotNetCoreExampleTests { - public static class ServiceCollectionExtensions + internal static class ServiceCollectionExtensions { public static void AddControllersFromExampleProject(this IServiceCollection services) { diff --git a/test/TestBuildingBlocks/IntegrationTestConfiguration.cs b/test/TestBuildingBlocks/IntegrationTestConfiguration.cs index 32014a9630..0ae06299c4 100644 --- a/test/TestBuildingBlocks/IntegrationTestConfiguration.cs +++ b/test/TestBuildingBlocks/IntegrationTestConfiguration.cs @@ -2,7 +2,7 @@ namespace TestBuildingBlocks { - public static class IntegrationTestConfiguration + internal static class IntegrationTestConfiguration { // Because our tests often deserialize incoming responses into weakly-typed string-to-object dictionaries (as part of ResourceObject), // Newtonsoft.JSON is unable to infer the target type in such cases. So we steer a bit using explicit configuration. diff --git a/test/UnitTests/Builders/ResourceGraphBuilderTests.cs b/test/UnitTests/Builders/ResourceGraphBuilderTests.cs index 6bd6ea1bfe..677c9f3d72 100644 --- a/test/UnitTests/Builders/ResourceGraphBuilderTests.cs +++ b/test/UnitTests/Builders/ResourceGraphBuilderTests.cs @@ -17,7 +17,7 @@ private sealed class NonDbResource : Identifiable { } private sealed class DbResource : Identifiable { } - private class TestContext : DbContext + private sealed class TestContext : DbContext { public DbSet DbResources { get; set; } @@ -106,6 +106,6 @@ public sealed class TestResource : Identifiable public ISet RelatedResources { get; set; } } - public class RelatedResource : Identifiable { } + public sealed class RelatedResource : Identifiable { } } } diff --git a/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs b/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs index 2701e20019..912665284d 100644 --- a/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs +++ b/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs @@ -187,7 +187,7 @@ public void AddJsonApi_With_Context_Uses_Resource_Type_Name_If_NoOtherSpecified( } public sealed class IntResource : Identifiable { } - public class GuidResource : Identifiable { } + public sealed class GuidResource : Identifiable { } private sealed class IntResourceService : IResourceService { diff --git a/test/UnitTests/Graph/ResourceDescriptorAssemblyCacheTests.cs b/test/UnitTests/Graph/ResourceDescriptorAssemblyCacheTests.cs index fc1f6d6543..5ceac23ecd 100644 --- a/test/UnitTests/Graph/ResourceDescriptorAssemblyCacheTests.cs +++ b/test/UnitTests/Graph/ResourceDescriptorAssemblyCacheTests.cs @@ -5,7 +5,7 @@ namespace UnitTests.Graph { - public class ResourceDescriptorAssemblyCacheTests + public sealed class ResourceDescriptorAssemblyCacheTests { [Fact] public void GetResourceDescriptorsPerAssembly_Locates_Identifiable_Resource() diff --git a/test/UnitTests/Internal/ResourceGraphBuilderTests.cs b/test/UnitTests/Internal/ResourceGraphBuilderTests.cs index ba1fc670b1..01c0f3a1c9 100644 --- a/test/UnitTests/Internal/ResourceGraphBuilderTests.cs +++ b/test/UnitTests/Internal/ResourceGraphBuilderTests.cs @@ -75,9 +75,9 @@ public void GetResourceContext_Yields_Right_Type_For_Identifiable() Assert.Equal(typeof(Bar), result.ResourceType); } - private class Foo { } + private sealed class Foo { } - private class TestContext : DbContext + private sealed class TestContext : DbContext { public DbSet Foos { get; set; } } diff --git a/test/UnitTests/Models/ResourceWithStringConstructor.cs b/test/UnitTests/Models/ResourceWithStringConstructor.cs index ce17fc1db3..8714e3f05f 100644 --- a/test/UnitTests/Models/ResourceWithStringConstructor.cs +++ b/test/UnitTests/Models/ResourceWithStringConstructor.cs @@ -3,7 +3,7 @@ namespace UnitTests.Models { - public class ResourceWithStringConstructor : Identifiable + public sealed class ResourceWithStringConstructor : Identifiable { public string Text { get; } @@ -14,4 +14,4 @@ public ResourceWithStringConstructor(string text) Text = text; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/Models/ResourceWithThrowingConstructor.cs b/test/UnitTests/Models/ResourceWithThrowingConstructor.cs index 634b9ca5cd..fd319c0a0d 100644 --- a/test/UnitTests/Models/ResourceWithThrowingConstructor.cs +++ b/test/UnitTests/Models/ResourceWithThrowingConstructor.cs @@ -3,11 +3,11 @@ namespace UnitTests.Models { - public class ResourceWithThrowingConstructor : Identifiable + public sealed class ResourceWithThrowingConstructor : Identifiable { public ResourceWithThrowingConstructor() { throw new ArgumentException("Failed to initialize."); } } -} \ No newline at end of file +} diff --git a/test/UnitTests/Models/ResourceWithoutConstructor.cs b/test/UnitTests/Models/ResourceWithoutConstructor.cs index 266f99ef1c..fa642e920c 100644 --- a/test/UnitTests/Models/ResourceWithoutConstructor.cs +++ b/test/UnitTests/Models/ResourceWithoutConstructor.cs @@ -2,7 +2,7 @@ namespace UnitTests.Models { - public class ResourceWithoutConstructor : Identifiable + public sealed class ResourceWithoutConstructor : Identifiable { } -} \ No newline at end of file +} diff --git a/test/UnitTests/ResourceHooks/DiscoveryTests.cs b/test/UnitTests/ResourceHooks/DiscoveryTests.cs index 4a6bc0df93..91879f6b6f 100644 --- a/test/UnitTests/ResourceHooks/DiscoveryTests.cs +++ b/test/UnitTests/ResourceHooks/DiscoveryTests.cs @@ -13,7 +13,7 @@ namespace UnitTests.ResourceHooks { public sealed class DiscoveryTests { - public class Dummy : Identifiable { } + public sealed class Dummy : Identifiable { } public sealed class DummyResourceDefinition : ResourceHooksDefinition { public DummyResourceDefinition() : base(new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance).Add().Build()) { } @@ -40,7 +40,7 @@ public void HookDiscovery_StandardResourceDefinition_CanDiscover() Assert.Contains(ResourceHook.AfterDelete, hookConfig.ImplementedHooks); } - public class AnotherDummy : Identifiable { } + public sealed class AnotherDummy : Identifiable { } public abstract class ResourceDefinitionBase : ResourceHooksDefinition where T : class, IIdentifiable { protected ResourceDefinitionBase(IResourceGraph resourceGraph) : base(resourceGraph) { } @@ -64,7 +64,7 @@ public void HookDiscovery_InheritanceSubclass_CanDiscover() Assert.Contains(ResourceHook.AfterDelete, hookConfig.ImplementedHooks); } - public class YetAnotherDummy : Identifiable { } + public sealed class YetAnotherDummy : Identifiable { } public sealed class YetAnotherDummyResourceDefinition : ResourceHooksDefinition { public YetAnotherDummyResourceDefinition() : base(new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance).Add().Build()) { } diff --git a/test/UnitTests/ResourceHooks/NotTargeted.cs b/test/UnitTests/ResourceHooks/NotTargeted.cs index d6a722b06f..b33bc03f15 100644 --- a/test/UnitTests/ResourceHooks/NotTargeted.cs +++ b/test/UnitTests/ResourceHooks/NotTargeted.cs @@ -2,5 +2,5 @@ namespace UnitTests.ResourceHooks { - public class NotTargeted : Identifiable { } -} \ No newline at end of file + public sealed class NotTargeted : Identifiable { } +} diff --git a/test/UnitTests/TestModels/Article.cs b/test/UnitTests/TestModels/Article.cs index 1bfde88836..5690be73ed 100644 --- a/test/UnitTests/TestModels/Article.cs +++ b/test/UnitTests/TestModels/Article.cs @@ -3,7 +3,7 @@ namespace UnitTests.TestModels { - public class Article : Identifiable + public sealed class Article : Identifiable { [Attr] public string Title { get; set; } [HasOne] public Person Reviewer { get; set; } @@ -11,4 +11,4 @@ public class Article : Identifiable [HasOne(CanInclude = false)] public Person CannotInclude { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/Blog.cs b/test/UnitTests/TestModels/Blog.cs index 3d32028cd2..8ff9b974a7 100644 --- a/test/UnitTests/TestModels/Blog.cs +++ b/test/UnitTests/TestModels/Blog.cs @@ -3,10 +3,10 @@ namespace UnitTests.TestModels { - public class Blog : Identifiable + public sealed class Blog : Identifiable { [Attr] public string Title { get; set; } [HasOne] public Person Reviewer { get; set; } [HasOne] public Person Author { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/ComplexType.cs b/test/UnitTests/TestModels/ComplexType.cs index ee7e62aebf..bf77fbe451 100644 --- a/test/UnitTests/TestModels/ComplexType.cs +++ b/test/UnitTests/TestModels/ComplexType.cs @@ -1,7 +1,7 @@ namespace UnitTests.TestModels { - public class ComplexType + public sealed class ComplexType { public string CompoundName { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/FirstDerivedModel.cs b/test/UnitTests/TestModels/FirstDerivedModel.cs index bb77b63137..efeca5cf35 100644 --- a/test/UnitTests/TestModels/FirstDerivedModel.cs +++ b/test/UnitTests/TestModels/FirstDerivedModel.cs @@ -2,8 +2,8 @@ namespace UnitTests.TestModels { - public class FirstDerivedModel : BaseModel + public sealed class FirstDerivedModel : BaseModel { [Attr] public bool FirstProperty { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/Food.cs b/test/UnitTests/TestModels/Food.cs index 3397f2138d..49f01c658b 100644 --- a/test/UnitTests/TestModels/Food.cs +++ b/test/UnitTests/TestModels/Food.cs @@ -3,8 +3,8 @@ namespace UnitTests.TestModels { - public class Food : Identifiable + public sealed class Food : Identifiable { [Attr] public string Dish { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/MultipleRelationshipsDependentPart.cs b/test/UnitTests/TestModels/MultipleRelationshipsDependentPart.cs index 0f172799b6..75ed16107d 100644 --- a/test/UnitTests/TestModels/MultipleRelationshipsDependentPart.cs +++ b/test/UnitTests/TestModels/MultipleRelationshipsDependentPart.cs @@ -2,7 +2,7 @@ namespace UnitTests.TestModels { - public class MultipleRelationshipsDependentPart : IdentifiableWithAttribute + public sealed class MultipleRelationshipsDependentPart : IdentifiableWithAttribute { [HasOne] public OneToOnePrincipal PopulatedToOne { get; set; } public int PopulatedToOneId { get; set; } @@ -13,4 +13,4 @@ public class MultipleRelationshipsDependentPart : IdentifiableWithAttribute [HasOne] public OneToManyPrincipal EmptyToMany { get; set; } public int? EmptyToManyId { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/OneToManyRequiredDependent.cs b/test/UnitTests/TestModels/OneToManyRequiredDependent.cs index 8953aeef58..4008d76eba 100644 --- a/test/UnitTests/TestModels/OneToManyRequiredDependent.cs +++ b/test/UnitTests/TestModels/OneToManyRequiredDependent.cs @@ -2,9 +2,9 @@ namespace UnitTests.TestModels { - public class OneToManyRequiredDependent : IdentifiableWithAttribute + public sealed class OneToManyRequiredDependent : IdentifiableWithAttribute { [HasOne] public OneToManyPrincipal Principal { get; set; } public int PrincipalId { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/Person.cs b/test/UnitTests/TestModels/Person.cs index 9588c43cee..48b4396336 100644 --- a/test/UnitTests/TestModels/Person.cs +++ b/test/UnitTests/TestModels/Person.cs @@ -4,11 +4,11 @@ namespace UnitTests.TestModels { - public class Person : Identifiable + public sealed class Person : Identifiable { [Attr] public string Name { get; set; } [HasMany] public ISet Blogs { get; set; } [HasOne] public Food FavoriteFood { get; set; } [HasOne] public Song FavoriteSong { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/SecondDerivedModel.cs b/test/UnitTests/TestModels/SecondDerivedModel.cs index cec4cb78a5..82d8d74fb9 100644 --- a/test/UnitTests/TestModels/SecondDerivedModel.cs +++ b/test/UnitTests/TestModels/SecondDerivedModel.cs @@ -2,8 +2,8 @@ namespace UnitTests.TestModels { - public class SecondDerivedModel : BaseModel + public sealed class SecondDerivedModel : BaseModel { [Attr] public bool SecondProperty { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/Song.cs b/test/UnitTests/TestModels/Song.cs index 301f31aa70..e1e5aa8928 100644 --- a/test/UnitTests/TestModels/Song.cs +++ b/test/UnitTests/TestModels/Song.cs @@ -3,8 +3,8 @@ namespace UnitTests.TestModels { - public class Song : Identifiable + public sealed class Song : Identifiable { [Attr] public string Title { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/TestResourceWithAbstractRelationship.cs b/test/UnitTests/TestModels/TestResourceWithAbstractRelationship.cs index e2415af01d..5a3561605c 100644 --- a/test/UnitTests/TestModels/TestResourceWithAbstractRelationship.cs +++ b/test/UnitTests/TestModels/TestResourceWithAbstractRelationship.cs @@ -4,9 +4,9 @@ namespace UnitTests.TestModels { - public class TestResourceWithAbstractRelationship : Identifiable + public sealed class TestResourceWithAbstractRelationship : Identifiable { [HasOne] public BaseModel ToOne { get; set; } [HasMany] public List ToMany { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/TestResourceWithList.cs b/test/UnitTests/TestModels/TestResourceWithList.cs index 80d7a1ecf7..55dcee7610 100644 --- a/test/UnitTests/TestModels/TestResourceWithList.cs +++ b/test/UnitTests/TestModels/TestResourceWithList.cs @@ -4,8 +4,8 @@ namespace UnitTests.TestModels { - public class TestResourceWithList : Identifiable + public sealed class TestResourceWithList : Identifiable { [Attr] public List ComplexFields { get; set; } } -} \ No newline at end of file +} From 7ca1aa20092f3f7f8ef565371b77198ed96b2f8d Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 24 Feb 2021 15:34:26 +0100 Subject: [PATCH 33/60] Removed redundancies in code --- src/Examples/ReportsExample/Services/ReportService.cs | 1 - src/JsonApiDotNetCore/Serialization/JsonApiReader.cs | 2 +- .../Updating/Relationships/AddToToManyRelationshipTests.cs | 2 +- .../Updating/Relationships/RemoveFromToManyRelationshipTests.cs | 2 +- .../Updating/Relationships/ReplaceToManyRelationshipTests.cs | 2 +- .../Updating/Relationships/UpdateToOneRelationshipTests.cs | 2 +- .../ReadWrite/Updating/Resources/UpdateResourceTests.cs | 2 +- test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs | 1 - 8 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Examples/ReportsExample/Services/ReportService.cs b/src/Examples/ReportsExample/Services/ReportService.cs index 139efe688c..706e0e0d44 100644 --- a/src/Examples/ReportsExample/Services/ReportService.cs +++ b/src/Examples/ReportsExample/Services/ReportService.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using System.Threading; using System.Threading.Tasks; using JsonApiDotNetCore.Services; diff --git a/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs b/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs index 362e339e54..e816e6f035 100644 --- a/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs +++ b/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs @@ -2,9 +2,9 @@ using System.Collections; using System.Collections.Generic; using System.IO; -using System.Net.Http; using System.Linq; using System.Net; +using System.Net.Http; using System.Threading.Tasks; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs index b9196de726..730ead680e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs @@ -599,7 +599,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.Conflict); error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - error.Detail.Should().Be($"Expected resource of type 'workTags' in POST request body at endpoint " + + error.Detail.Should().Be("Expected resource of type 'workTags' in POST request body at endpoint " + $"'/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs index 7e9a5a37a0..35bc7a1d06 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs @@ -591,7 +591,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.Conflict); error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - error.Detail.Should().Be($"Expected resource of type 'workTags' in DELETE request body at endpoint " + + error.Detail.Should().Be("Expected resource of type 'workTags' in DELETE request body at endpoint " + $"'/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs index 5283429787..bbbf94c7aa 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs @@ -638,7 +638,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.Conflict); error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - error.Detail.Should().Be($"Expected resource of type 'workTags' in PATCH request body at endpoint " + + error.Detail.Should().Be("Expected resource of type 'workTags' in PATCH request body at endpoint " + $"'/workItems/{existingWorkItem.StringId}/relationships/tags', instead of 'userAccounts'."); } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs index fd232b653d..4a09dc6305 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs @@ -567,7 +567,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.Conflict); error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - error.Detail.Should().Be($"Expected resource of type 'userAccounts' in PATCH request body at endpoint " + + error.Detail.Should().Be("Expected resource of type 'userAccounts' in PATCH request body at endpoint " + $"'/workItems/{existingWorkItem.StringId}/relationships/assignee', instead of 'rgbColors'."); } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs index ca346683fb..57f106ac8b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs @@ -753,7 +753,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.Conflict); error.Title.Should().Be("Resource type mismatch between request body and endpoint URL."); - error.Detail.Should().Be($"Expected resource of type 'workItems' in PATCH request body at endpoint " + + error.Detail.Should().Be("Expected resource of type 'workItems' in PATCH request body at endpoint " + $"'/workItems/{existingWorkItem.StringId}', instead of 'rgbColors'."); } diff --git a/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs b/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs index b6562b15c9..fb02d79826 100644 --- a/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs @@ -1,4 +1,3 @@ -using System.Linq; using JsonApiDotNetCore.Hooks.Internal.Execution; using JsonApiDotNetCoreExample.Models; using Moq; From f394102bdb4bca94039ab46fc113fff17fcda82b Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Thu, 25 Feb 2021 11:21:04 +0100 Subject: [PATCH 34/60] remove unused tuple elements --- .../Executor/Delete/AfterDeleteTests.cs | 4 ++-- .../Executor/Delete/BeforeDeleteTests.cs | 4 ++-- .../Executor/ManyToManyOnReturnTests.cs | 14 ++++++------- .../Executor/Read/BeforeReadTests.cs | 2 +- .../Executor/Read/ManyToManyAfterReadTests.cs | 8 ++++---- .../Executor/SameResourceTypeTests.cs | 4 ++-- .../UnitTests/ResourceHooks/HooksDummyData.cs | 6 ++---- .../ResourceHooks/HooksTestsSetup.cs | 20 +++++++++---------- .../IncludedResourceObjectBuilderTests.cs | 6 +++--- 9 files changed, 31 insertions(+), 37 deletions(-) diff --git a/test/UnitTests/ResourceHooks/Executor/Delete/AfterDeleteTests.cs b/test/UnitTests/ResourceHooks/Executor/Delete/AfterDeleteTests.cs index e8f9f30f73..16478d2b04 100644 --- a/test/UnitTests/ResourceHooks/Executor/Delete/AfterDeleteTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Delete/AfterDeleteTests.cs @@ -15,7 +15,7 @@ public void AfterDelete() { // Arrange var discovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); - var (_, hookExecutor, resourceDefinitionMock) = CreateTestObjects(discovery); + var (hookExecutor, resourceDefinitionMock) = CreateTestObjects(discovery); var todoList = CreateTodoWithOwner(); // Act @@ -31,7 +31,7 @@ public void AfterDelete_Without_Any_Hook_Implemented() { // Arrange var discovery = SetDiscoverableHooks(NoHooks, DisableDbValues); - var (_, hookExecutor, resourceDefinitionMock) = CreateTestObjects(discovery); + var (hookExecutor, resourceDefinitionMock) = CreateTestObjects(discovery); var todoList = CreateTodoWithOwner(); // Act diff --git a/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteTests.cs b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteTests.cs index 0dfd223ad7..8435f6f9bc 100644 --- a/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Delete/BeforeDeleteTests.cs @@ -14,7 +14,7 @@ public void BeforeDelete() { // Arrange var discovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); - var (_, hookExecutor, resourceDefinitionMock) = CreateTestObjects(discovery); + var (hookExecutor, resourceDefinitionMock) = CreateTestObjects(discovery); var todoList = CreateTodoWithOwner(); // Act @@ -30,7 +30,7 @@ public void BeforeDelete_Without_Any_Hook_Implemented() { // Arrange var discovery = SetDiscoverableHooks(NoHooks, DisableDbValues); - var (_, hookExecutor, resourceDefinitionMock) = CreateTestObjects(discovery); + var (hookExecutor, resourceDefinitionMock) = CreateTestObjects(discovery); var todoList = CreateTodoWithOwner(); // Act diff --git a/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs b/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs index f41cd99dc7..4b2e51d566 100644 --- a/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/ManyToManyOnReturnTests.cs @@ -12,7 +12,7 @@ public sealed class ManyToManyOnReturnTests : HooksTestsSetup { private readonly ResourceHook[] _targetHooks = { ResourceHook.OnReturn }; - private (List
    , List, List) CreateDummyData() + private (List
    , List) CreateDummyData() { var tagsSubset = TagFaker.Generate(3); var joinsSubSet = ArticleTagFaker.Generate(3); @@ -36,10 +36,8 @@ public sealed class ManyToManyOnReturnTests : HooksTestsSetup completeJoin[i].Tag = allTags[i]; } - var allJoins = joinsSubSet.Concat(completeJoin).ToList(); - var articles = ArrayFactory.Create(articleTagsSubset, articleWithAllTags).ToList(); - return (articles, allJoins, allTags); + return (articles, allTags); } [Fact] @@ -49,7 +47,7 @@ public void OnReturn() var articleDiscovery = SetDiscoverableHooks
    (_targetHooks, DisableDbValues); var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); - var (articles, _, tags) = CreateDummyData(); + var (articles, tags) = CreateDummyData(); // Act hookExecutor.OnReturn(articles, ResourcePipeline.Get); @@ -67,7 +65,7 @@ public void OnReturn_Without_Parent_Hook_Implemented() var articleDiscovery = SetDiscoverableHooks
    (NoHooks, DisableDbValues); var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); - var (articles, _, tags) = CreateDummyData(); + var (articles, tags) = CreateDummyData(); // Act hookExecutor.OnReturn(articles, ResourcePipeline.Get); @@ -84,7 +82,7 @@ public void OnReturn_Without_Children_Hooks_Implemented() var articleDiscovery = SetDiscoverableHooks
    (_targetHooks, DisableDbValues); var tagDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); - var (articles, _, _) = CreateDummyData(); + var (articles, _) = CreateDummyData(); // Act hookExecutor.OnReturn(articles, ResourcePipeline.Get); @@ -102,7 +100,7 @@ public void OnReturn_Without_Any_Hook_Implemented() var tagDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); - var (articles, _, _) = CreateDummyData(); + var (articles, _) = CreateDummyData(); // Act hookExecutor.OnReturn(articles, ResourcePipeline.Get); diff --git a/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs b/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs index fb02d79826..c5be40aa74 100644 --- a/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Read/BeforeReadTests.cs @@ -14,7 +14,7 @@ public void BeforeRead() { // Arrange var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); - var (_, hookExecutor, todoResourceMock) = CreateTestObjects(todoDiscovery); + var (hookExecutor, todoResourceMock) = CreateTestObjects(todoDiscovery); // Act hookExecutor.BeforeRead(ResourcePipeline.Get); diff --git a/test/UnitTests/ResourceHooks/Executor/Read/ManyToManyAfterReadTests.cs b/test/UnitTests/ResourceHooks/Executor/Read/ManyToManyAfterReadTests.cs index fd1f8f4644..e13f25c209 100644 --- a/test/UnitTests/ResourceHooks/Executor/Read/ManyToManyAfterReadTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/Read/ManyToManyAfterReadTests.cs @@ -18,7 +18,7 @@ public void AfterRead() var articleDiscovery = SetDiscoverableHooks
    (_targetHooks, DisableDbValues); var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); - var (articles, _, tags) = CreateManyToManyData(); + var (articles, tags) = CreateManyToManyData(); // Act hookExecutor.AfterRead(articles, ResourcePipeline.Get); @@ -36,7 +36,7 @@ public void AfterRead_Without_Parent_Hook_Implemented() var articleDiscovery = SetDiscoverableHooks
    (NoHooks, DisableDbValues); var tagDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); - var (articles, _, tags) = CreateManyToManyData(); + var (articles, tags) = CreateManyToManyData(); // Act hookExecutor.AfterRead(articles, ResourcePipeline.Get); @@ -53,7 +53,7 @@ public void AfterRead_Without_Children_Hooks_Implemented() var articleDiscovery = SetDiscoverableHooks
    (_targetHooks, DisableDbValues); var tagDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); - var (articles, _, _) = CreateManyToManyData(); + var (articles, _) = CreateManyToManyData(); // Act hookExecutor.AfterRead(articles, ResourcePipeline.Get); @@ -70,7 +70,7 @@ public void AfterRead_Without_Any_Hook_Implemented() var articleDiscovery = SetDiscoverableHooks
    (NoHooks, DisableDbValues); var tagDiscovery = SetDiscoverableHooks(NoHooks, DisableDbValues); var (_, _, hookExecutor, articleResourceMock, tagResourceMock) = CreateTestObjects(articleDiscovery, tagDiscovery); - var (articles, _, _) = CreateManyToManyData(); + var (articles, _) = CreateManyToManyData(); // Act hookExecutor.AfterRead(articles, ResourcePipeline.Get); diff --git a/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs b/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs index 0b2b3ab1c9..be5186ea1b 100644 --- a/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs +++ b/test/UnitTests/ResourceHooks/Executor/SameResourceTypeTests.cs @@ -40,7 +40,7 @@ public void Resource_Has_Cyclic_Relations() { // Arrange var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); - var (_, hookExecutor, todoResourceMock) = CreateTestObjects(todoDiscovery); + var (hookExecutor, todoResourceMock) = CreateTestObjects(todoDiscovery); var todo = new TodoItem(); todo.ParentTodo = todo; todo.ChildTodoItems = todo.AsList(); @@ -59,7 +59,7 @@ public void Resource_Has_Nested_Cyclic_Relations() { // Arrange var todoDiscovery = SetDiscoverableHooks(_targetHooks, DisableDbValues); - var (_, hookExecutor, todoResourceMock) = CreateTestObjects(todoDiscovery); + var (hookExecutor, todoResourceMock) = CreateTestObjects(todoDiscovery); var rootTodo = new TodoItem { Id = 1 }; var child = new TodoItem { ParentTodo = rootTodo, Id = 2 }; rootTodo.ChildTodoItems = child.AsList(); diff --git a/test/UnitTests/ResourceHooks/HooksDummyData.cs b/test/UnitTests/ResourceHooks/HooksDummyData.cs index 980bf4d659..af1691fd3d 100644 --- a/test/UnitTests/ResourceHooks/HooksDummyData.cs +++ b/test/UnitTests/ResourceHooks/HooksDummyData.cs @@ -82,7 +82,7 @@ protected HashSet CreateTodoWithOwner() return todoList; } - protected (List
    , List, List) CreateManyToManyData() + protected (List
    , List) CreateManyToManyData() { var tagsSubset = TagFaker.Generate(3); var joinsSubSet = ArticleTagFaker.Generate(3); @@ -106,10 +106,8 @@ protected HashSet CreateTodoWithOwner() completeJoin[i].Tag = allTags[i]; } - var allJoins = joinsSubSet.Concat(completeJoin).ToList(); - var articles = ArrayFactory.Create(articleTagsSubset, articleWithAllTags).ToList(); - return (articles, allJoins, allTags); + return (articles, allTags); } protected (List
    , List, List) CreateIdentifiableManyToManyData() diff --git a/test/UnitTests/ResourceHooks/HooksTestsSetup.cs b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs index 80c0ab39be..afa8cb71dd 100644 --- a/test/UnitTests/ResourceHooks/HooksTestsSetup.cs +++ b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs @@ -35,11 +35,11 @@ public class HooksTestsSetup : HooksDummyData return (ufMock, constraintsMock, pfMock, optionsMock); } - internal (Mock>, ResourceHookExecutor, Mock>) CreateTestObjects(IHooksDiscovery primaryDiscovery = null) + internal (ResourceHookExecutor, Mock>) CreateTestObjects(IHooksDiscovery primaryDiscovery = null) where TPrimary : class, IIdentifiable { // creates the resource definition mock and corresponding ImplementedHooks discovery instance - var primaryResource = CreateResourceDefinition(primaryDiscovery); + var primaryResource = CreateResourceDefinition(); // mocking the genericServiceFactory and JsonApiContext and wiring them up. var (ufMock, constraintsMock, gpfMock, options) = CreateMocks(); @@ -50,7 +50,7 @@ public class HooksTestsSetup : HooksDummyData var traversalHelper = new TraversalHelper(ResourceGraph, ufMock.Object); var hookExecutor = new ResourceHookExecutor(execHelper, traversalHelper, ufMock.Object, constraintsMock.Object, ResourceGraph); - return (constraintsMock, hookExecutor, primaryResource); + return (hookExecutor, primaryResource); } protected (Mock>, Mock, IResourceHookExecutor, Mock>, Mock>) @@ -63,8 +63,8 @@ public class HooksTestsSetup : HooksDummyData where TSecondary : class, IIdentifiable { // creates the resource definition mock and corresponding for a given set of discoverable hooks - var primaryResource = CreateResourceDefinition(primaryDiscovery); - var secondaryResource = CreateResourceDefinition(secondaryDiscovery); + var primaryResource = CreateResourceDefinition(); + var secondaryResource = CreateResourceDefinition(); // mocking the genericServiceFactory and JsonApiContext and wiring them up. var (ufMock, constraintsMock, gpfMock, options) = CreateMocks(); @@ -98,9 +98,9 @@ public class HooksTestsSetup : HooksDummyData where TSecondSecondary : class, IIdentifiable { // creates the resource definition mock and corresponding for a given set of discoverable hooks - var primaryResource = CreateResourceDefinition(primaryDiscovery); - var firstSecondaryResource = CreateResourceDefinition(firstSecondaryDiscovery); - var secondSecondaryResource = CreateResourceDefinition(secondSecondaryDiscovery); + var primaryResource = CreateResourceDefinition(); + var firstSecondaryResource = CreateResourceDefinition(); + var secondSecondaryResource = CreateResourceDefinition(); // mocking the genericServiceFactory and JsonApiContext and wiring them up. var (ufMock, constraintsMock, gpfMock, options) = CreateMocks(); @@ -263,9 +263,7 @@ private void ResolveInverseRelationships(AppDbContext context) inverseRelationships.Resolve(); } - private Mock> CreateResourceDefinition - (IHooksDiscovery discovery - ) + private Mock> CreateResourceDefinition() where TModel : class, IIdentifiable { var resourceDefinition = new Mock>(); diff --git a/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs b/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs index 228d51fa42..3e8eb9747b 100644 --- a/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs +++ b/test/UnitTests/Serialization/Server/IncludedResourceObjectBuilderTests.cs @@ -63,7 +63,7 @@ public void BuildIncluded_OverlappingDeeplyNestedCircularChains_CanBuild() var (article, author, _, reviewer, reviewerFood) = GetAuthorChainInstances(); var sharedBlog = author.Blogs.First(); var sharedBlogAuthor = reviewer; - var (_, _, _, authorSong) = GetReviewerChainInstances(article, sharedBlog, sharedBlogAuthor); + var authorSong = GetReviewerChainInstances(article, sharedBlog, sharedBlogAuthor); var reviewerChain = GetIncludedRelationshipsChain("reviewer.blogs.author.favoriteSong"); var builder = GetBuilder(); @@ -88,7 +88,7 @@ public void BuildIncluded_OverlappingDeeplyNestedCircularChains_CanBuild() Assert.Equal(reviewerFood.StringId, sharedBlogAuthor.FavoriteFood.StringId); } - private (Person, Song, Person, Song) GetReviewerChainInstances(Article article, Blog sharedBlog, Person sharedBlogAuthor) + private Song GetReviewerChainInstances(Article article, Blog sharedBlog, Person sharedBlogAuthor) { var reviewer = PersonFaker.Generate(); article.Reviewer = reviewer; @@ -108,7 +108,7 @@ public void BuildIncluded_OverlappingDeeplyNestedCircularChains_CanBuild() var reviewerSong = SongFaker.Generate(); reviewer.FavoriteSong = reviewerSong; - return (reviewer, reviewerSong, author, authorSong); + return authorSong; } private (Article, Person, Food, Person, Food) GetAuthorChainInstances() From 66c8e9cc92c48cab40d882c74abd3ec37e15a6e3 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Thu, 25 Feb 2021 12:07:35 +0100 Subject: [PATCH 35/60] Fixed spelling in comments --- .../AtomicOperations/IOperationProcessorAccessor.cs | 4 ++-- .../Queries/Expressions/QueryableHandlerExpression.cs | 2 +- .../Repositories/IRepositorySupportsTransaction.cs | 2 +- .../Repositories/IResourceRepositoryAccessor.cs | 2 +- .../Resources/IResourceDefinitionAccessor.cs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/JsonApiDotNetCore/AtomicOperations/IOperationProcessorAccessor.cs b/src/JsonApiDotNetCore/AtomicOperations/IOperationProcessorAccessor.cs index ca4aa424cf..3045e33f7d 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/IOperationProcessorAccessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/IOperationProcessorAccessor.cs @@ -1,4 +1,4 @@ -using System.Threading; +using System.Threading; using System.Threading.Tasks; using JsonApiDotNetCore.AtomicOperations.Processors; using JsonApiDotNetCore.Resources; @@ -6,7 +6,7 @@ namespace JsonApiDotNetCore.AtomicOperations { /// - /// Retrieves a instance from the D/I container and invokes a method on it. + /// Retrieves an instance from the D/I container and invokes a method on it. /// public interface IOperationProcessorAccessor { diff --git a/src/JsonApiDotNetCore/Queries/Expressions/QueryableHandlerExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/QueryableHandlerExpression.cs index ef411a132a..3dcf1f2083 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/QueryableHandlerExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/QueryableHandlerExpression.cs @@ -6,7 +6,7 @@ namespace JsonApiDotNetCore.Queries.Expressions { /// - /// Holds a expression, used for custom query string handlers from s. + /// Holds an expression, used for custom query string handlers from s. /// public class QueryableHandlerExpression : QueryExpression { diff --git a/src/JsonApiDotNetCore/Repositories/IRepositorySupportsTransaction.cs b/src/JsonApiDotNetCore/Repositories/IRepositorySupportsTransaction.cs index d134e39bd9..42026e9712 100644 --- a/src/JsonApiDotNetCore/Repositories/IRepositorySupportsTransaction.cs +++ b/src/JsonApiDotNetCore/Repositories/IRepositorySupportsTransaction.cs @@ -3,7 +3,7 @@ namespace JsonApiDotNetCore.Repositories { /// - /// Used to indicate that a supports execution inside a transaction. + /// Used to indicate that an supports execution inside a transaction. /// public interface IRepositorySupportsTransaction { diff --git a/src/JsonApiDotNetCore/Repositories/IResourceRepositoryAccessor.cs b/src/JsonApiDotNetCore/Repositories/IResourceRepositoryAccessor.cs index 824bfe0423..93f9640038 100644 --- a/src/JsonApiDotNetCore/Repositories/IResourceRepositoryAccessor.cs +++ b/src/JsonApiDotNetCore/Repositories/IResourceRepositoryAccessor.cs @@ -9,7 +9,7 @@ namespace JsonApiDotNetCore.Repositories { /// - /// Retrieves a instance from the D/I container and invokes a method on it. + /// Retrieves an instance from the D/I container and invokes a method on it. /// public interface IResourceRepositoryAccessor { diff --git a/src/JsonApiDotNetCore/Resources/IResourceDefinitionAccessor.cs b/src/JsonApiDotNetCore/Resources/IResourceDefinitionAccessor.cs index 2f7a5837ee..b3b744ba1f 100644 --- a/src/JsonApiDotNetCore/Resources/IResourceDefinitionAccessor.cs +++ b/src/JsonApiDotNetCore/Resources/IResourceDefinitionAccessor.cs @@ -6,7 +6,7 @@ namespace JsonApiDotNetCore.Resources { /// - /// Retrieves a instance from the D/I container and invokes a callback on it. + /// Retrieves an instance from the D/I container and invokes a callback on it. /// public interface IResourceDefinitionAccessor { From 1792982b0b3f9bfeb4a333d7b66cdb04f84a8efa Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Thu, 25 Feb 2021 12:04:40 +0100 Subject: [PATCH 36/60] Added formatter directive to ErrorDocumentTests to prevent array chop --- test/UnitTests/Internal/ErrorDocumentTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/UnitTests/Internal/ErrorDocumentTests.cs b/test/UnitTests/Internal/ErrorDocumentTests.cs index ada75aa29b..e202d847e3 100644 --- a/test/UnitTests/Internal/ErrorDocumentTests.cs +++ b/test/UnitTests/Internal/ErrorDocumentTests.cs @@ -8,11 +8,13 @@ namespace UnitTests.Internal { public sealed class ErrorDocumentTests { + // @formatter:wrap_array_initializer_style wrap_if_long [Theory] [InlineData(new[] { HttpStatusCode.UnprocessableEntity }, HttpStatusCode.UnprocessableEntity)] [InlineData(new[] { HttpStatusCode.UnprocessableEntity, HttpStatusCode.UnprocessableEntity }, HttpStatusCode.UnprocessableEntity)] [InlineData(new[] { HttpStatusCode.UnprocessableEntity, HttpStatusCode.Unauthorized }, HttpStatusCode.BadRequest)] [InlineData(new[] { HttpStatusCode.UnprocessableEntity, HttpStatusCode.BadGateway }, HttpStatusCode.InternalServerError)] + // @formatter:wrap_array_initializer_style restore public void ErrorDocument_GetErrorStatusCode_IsCorrect(HttpStatusCode[] errorCodes, HttpStatusCode expected) { // Arrange From accf050a05ad18f3f20a89da215fd73b939d9f8c Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 24 Feb 2021 15:42:28 +0100 Subject: [PATCH 37/60] Added [UsedImplicitly] on DbContext classes to suppress suggestions like 'member can be private, set accessor is never used'etc. --- src/Examples/GettingStarted/Data/SampleDbContext.cs | 2 ++ src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs | 2 ++ src/Examples/MultiDbContextExample/Data/DbContextA.cs | 2 ++ src/Examples/MultiDbContextExample/Data/DbContextB.cs | 2 ++ src/Examples/NoEntityFrameworkExample/Data/AppDbContext.cs | 2 ++ .../IntegrationTests/AtomicOperations/OperationsDbContext.cs | 2 ++ .../AtomicOperations/Transactions/ExtraDbContext.cs | 2 ++ .../IntegrationTests/CompositeKeys/CompositeDbContext.cs | 2 ++ .../IntegrationTests/ContentNegotiation/PolicyDbContext.cs | 2 ++ .../ControllerActionResults/ActionResultDbContext.cs | 2 ++ .../IntegrationTests/CustomRoutes/CustomRouteDbContext.cs | 2 ++ .../IntegrationTests/EagerLoading/EagerLoadingDbContext.cs | 2 ++ .../IntegrationTests/ExceptionHandling/ErrorDbContext.cs | 2 ++ .../IntegrationTests/HostingInIIS/HostingDbContext.cs | 2 ++ .../IntegrationTests/IdObfuscation/ObfuscationDbContext.cs | 2 ++ .../IntegrationTests/Links/LinksDbContext.cs | 2 ++ .../IntegrationTests/Logging/AuditDbContext.cs | 2 ++ .../IntegrationTests/Meta/SupportDbContext.cs | 2 ++ .../ModelStateValidation/ModelStateDbContext.cs | 2 ++ .../IntegrationTests/NamingConventions/SwimmingDbContext.cs | 2 ++ .../IntegrationTests/QueryStrings/Filtering/FilterDbContext.cs | 2 ++ .../IntegrationTests/QueryStrings/QueryStringDbContext.cs | 2 ++ .../IntegrationTests/ReadWrite/ReadWriteDbContext.cs | 2 ++ .../RequiredRelationships/DefaultBehaviorDbContext.cs | 2 ++ .../ResourceConstructorInjection/InjectionDbContext.cs | 2 ++ .../IntegrationTests/ResourceDefinitions/CallableDbContext.cs | 2 ++ .../ResourceInheritance/InheritanceDbContext.cs | 2 ++ .../RestrictedControllers/RestrictionDbContext.cs | 2 ++ .../IntegrationTests/Serialization/SerializationDbContext.cs | 2 ++ .../IntegrationTests/SoftDeletion/SoftDeletionDbContext.cs | 2 ++ .../IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs | 2 ++ test/UnitTests/Builders/ResourceGraphBuilderTests.cs | 2 ++ test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs | 2 ++ test/UnitTests/Internal/ResourceGraphBuilderTests.cs | 2 ++ 34 files changed, 68 insertions(+) diff --git a/src/Examples/GettingStarted/Data/SampleDbContext.cs b/src/Examples/GettingStarted/Data/SampleDbContext.cs index 95781423b6..b54011ff14 100644 --- a/src/Examples/GettingStarted/Data/SampleDbContext.cs +++ b/src/Examples/GettingStarted/Data/SampleDbContext.cs @@ -1,8 +1,10 @@ using GettingStarted.Models; +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace GettingStarted.Data { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public class SampleDbContext : DbContext { public DbSet Books { get; set; } diff --git a/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs b/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs index 052338711a..a438f44831 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCoreExample.Models; using Microsoft.EntityFrameworkCore; @@ -5,6 +6,7 @@ namespace JsonApiDotNetCoreExample.Data { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class AppDbContext : DbContext { public DbSet TodoItems { get; set; } diff --git a/src/Examples/MultiDbContextExample/Data/DbContextA.cs b/src/Examples/MultiDbContextExample/Data/DbContextA.cs index 72fb233d5b..cb6000e051 100644 --- a/src/Examples/MultiDbContextExample/Data/DbContextA.cs +++ b/src/Examples/MultiDbContextExample/Data/DbContextA.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using MultiDbContextExample.Models; namespace MultiDbContextExample.Data { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class DbContextA : DbContext { public DbSet ResourceAs { get; set; } diff --git a/src/Examples/MultiDbContextExample/Data/DbContextB.cs b/src/Examples/MultiDbContextExample/Data/DbContextB.cs index 4b6c5e7690..b3e4e6e47f 100644 --- a/src/Examples/MultiDbContextExample/Data/DbContextB.cs +++ b/src/Examples/MultiDbContextExample/Data/DbContextB.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using MultiDbContextExample.Models; namespace MultiDbContextExample.Data { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class DbContextB : DbContext { public DbSet ResourceBs { get; set; } diff --git a/src/Examples/NoEntityFrameworkExample/Data/AppDbContext.cs b/src/Examples/NoEntityFrameworkExample/Data/AppDbContext.cs index abf11869dd..336951eec3 100644 --- a/src/Examples/NoEntityFrameworkExample/Data/AppDbContext.cs +++ b/src/Examples/NoEntityFrameworkExample/Data/AppDbContext.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using NoEntityFrameworkExample.Models; namespace NoEntityFrameworkExample.Data { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class AppDbContext : DbContext { public DbSet WorkItems { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs index bde4cec990..839c6cd7b8 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; // @formatter:wrap_chained_method_calls chop_always namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class OperationsDbContext : DbContext { public DbSet Playlists { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/ExtraDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/ExtraDbContext.cs index f9776989a0..fee681e5e3 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/ExtraDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/ExtraDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.Transactions { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ExtraDbContext : DbContext { public ExtraDbContext(DbContextOptions options) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs index 545f2c380f..602dd90e15 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; // @formatter:wrap_chained_method_calls chop_always namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CompositeKeys { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class CompositeDbContext : DbContext { public DbSet Cars { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/PolicyDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/PolicyDbContext.cs index 4402f859c8..f5481e1865 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/PolicyDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/PolicyDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ContentNegotiation { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class PolicyDbContext : DbContext { public DbSet Policies { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/ActionResultDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/ActionResultDbContext.cs index 4db7d81157..9407c8f255 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/ActionResultDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/ActionResultDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ControllerActionResults { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ActionResultDbContext : DbContext { public DbSet Toothbrushes { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteDbContext.cs index 4b76077d27..d368ca14b4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/CustomRouteDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CustomRoutes { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class CustomRouteDbContext : DbContext { public DbSet Towns { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs index 4058533637..efce1b3014 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; // @formatter:wrap_chained_method_calls chop_always namespace JsonApiDotNetCoreExampleTests.IntegrationTests.EagerLoading { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class EagerLoadingDbContext : DbContext { public DbSet States { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ErrorDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ErrorDbContext.cs index 9e4d0feab8..ff9abd6509 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ErrorDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ErrorDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ExceptionHandling { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ErrorDbContext : DbContext { public DbSet ConsumerArticles { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingDbContext.cs index 03795fe1cf..82d77b2b16 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class HostingDbContext : DbContext { public DbSet ArtGalleries { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/ObfuscationDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/ObfuscationDbContext.cs index 489ba4970c..939bae05bf 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/ObfuscationDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/ObfuscationDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.IdObfuscation { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ObfuscationDbContext : DbContext { public DbSet BankAccounts { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/LinksDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/LinksDbContext.cs index 810eb4be48..1e0a63bfad 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/LinksDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/LinksDbContext.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; // @formatter:wrap_chained_method_calls chop_always namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Links { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class LinksDbContext : DbContext { public DbSet PhotoAlbums { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/AuditDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/AuditDbContext.cs index f640452877..416b381728 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/AuditDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/AuditDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Logging { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class AuditDbContext : DbContext { public DbSet AuditEntries { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportDbContext.cs index 6d8850c63a..0e0376264c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Meta { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class SupportDbContext : DbContext { public DbSet ProductFamilies { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateDbContext.cs index b3de2e1cbd..6de2695ae9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/ModelStateDbContext.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; // @formatter:wrap_chained_method_calls chop_always namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ModelStateValidation { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ModelStateDbContext : DbContext { public DbSet Directories { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/SwimmingDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/SwimmingDbContext.cs index 9d8de4aa26..2722b91cc9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/SwimmingDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/SwimmingDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.NamingConventions { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class SwimmingDbContext : DbContext { public DbSet SwimmingPools { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDbContext.cs index ec0e971b39..d8f0fb49bb 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings.Filtering { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class FilterDbContext : DbContext { public DbSet FilterableResources { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs index 962babc0b7..a26e1d47b8 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; // @formatter:wrap_chained_method_calls chop_always namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class QueryStringDbContext : DbContext { public DbSet Blogs { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs index 7cb3517453..b8da68ee04 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; // @formatter:wrap_chained_method_calls chop_always namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ReadWrite { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ReadWriteDbContext : DbContext { public DbSet WorkItems { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs index 96331a0aeb..d8a617037b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; // @formatter:wrap_chained_method_calls chop_always namespace JsonApiDotNetCoreExampleTests.IntegrationTests.RequiredRelationships { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class DefaultBehaviorDbContext : DbContext { public DbSet Customers { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionDbContext.cs index d274e3ca89..df174c7c6f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionDbContext.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using JsonApiDotNetCore; using Microsoft.AspNetCore.Authentication; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceConstructorInjection { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class InjectionDbContext : DbContext { public ISystemClock SystemClock { get; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableDbContext.cs index 395d356313..cea928d6b4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceDefinitions { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class CallableDbContext : DbContext { public DbSet CallableResources { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceDbContext.cs index 770d739ccf..69f49b73b9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/InheritanceDbContext.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance.Models; using Microsoft.EntityFrameworkCore; @@ -5,6 +6,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class InheritanceDbContext : DbContext { public InheritanceDbContext(DbContextOptions options) : base(options) { } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/RestrictionDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/RestrictionDbContext.cs index 190df5f4d1..c26e120450 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/RestrictionDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/RestrictionDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.RestrictedControllers { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class RestrictionDbContext : DbContext { public DbSet Tables { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationDbContext.cs index 730ea37d42..87e39675a7 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/SerializationDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Serialization { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class SerializationDbContext : DbContext { public DbSet Meetings { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionDbContext.cs index df5c8cdcf5..01bdfe6ba6 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionDbContext.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.SoftDeletion { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class SoftDeletionDbContext : DbContext { public DbSet Companies { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs index b9a1de31ca..9fa95d2860 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; // @formatter:wrap_chained_method_calls chop_always namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ZeroKeys { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ZeroKeyDbContext : DbContext { public DbSet Games { get; set; } diff --git a/test/UnitTests/Builders/ResourceGraphBuilderTests.cs b/test/UnitTests/Builders/ResourceGraphBuilderTests.cs index 677c9f3d72..2e1684b388 100644 --- a/test/UnitTests/Builders/ResourceGraphBuilderTests.cs +++ b/test/UnitTests/Builders/ResourceGraphBuilderTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; @@ -17,6 +18,7 @@ private sealed class NonDbResource : Identifiable { } private sealed class DbResource : Identifiable { } + [UsedImplicitly(ImplicitUseTargetFlags.Members)] private sealed class TestContext : DbContext { public DbSet DbResources { get; set; } diff --git a/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs b/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs index 912665284d..60025d9b4d 100644 --- a/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs +++ b/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Middleware; @@ -245,6 +246,7 @@ private sealed class GuidResourceRepository : IResourceRepository secondaryResourceIds, CancellationToken cancellationToken) => throw new NotImplementedException(); } + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public class TestContext : DbContext { public TestContext(DbContextOptions options) : base(options) diff --git a/test/UnitTests/Internal/ResourceGraphBuilderTests.cs b/test/UnitTests/Internal/ResourceGraphBuilderTests.cs index 01c0f3a1c9..7a5c77298f 100644 --- a/test/UnitTests/Internal/ResourceGraphBuilderTests.cs +++ b/test/UnitTests/Internal/ResourceGraphBuilderTests.cs @@ -1,5 +1,6 @@ using System.Linq; using Castle.DynamicProxy; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; using Microsoft.EntityFrameworkCore; @@ -77,6 +78,7 @@ public void GetResourceContext_Yields_Right_Type_For_Identifiable() private sealed class Foo { } + [UsedImplicitly(ImplicitUseTargetFlags.Members)] private sealed class TestContext : DbContext { public DbSet Foos { get; set; } From b5383af6e7bac538db823a63bdd8508e3abbce49 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 24 Feb 2021 15:52:05 +0100 Subject: [PATCH 38/60] Added [UsedImplicitly] on resource services, repositories, definitions and startups --- .../Definitions/ArticleHooksDefinition.cs | 2 ++ .../Definitions/PassportHooksDefinition.cs | 2 ++ .../Definitions/PersonHooksDefinition.cs | 2 ++ .../Definitions/TagHooksDefinition.cs | 7 ++----- .../Definitions/TodoItemHooksDefinition.cs | 2 ++ .../Repositories/DbContextARepository.cs | 2 ++ .../Repositories/DbContextBRepository.cs | 2 ++ .../NoEntityFrameworkExample/Services/WorkItemService.cs | 2 ++ src/Examples/ReportsExample/Services/ReportService.cs | 2 ++ test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs | 7 ++++++- .../AtomicOperations/Meta/MusicTrackMetaDefinition.cs | 2 ++ .../AtomicOperations/Meta/TextLanguageMetaDefinition.cs | 2 ++ .../QueryStrings/MusicTrackReleaseDefinition.cs | 2 ++ .../ResourceDefinitions/LyricTextDefinition.cs | 2 ++ .../AtomicOperations/Transactions/LyricRepository.cs | 2 ++ .../AtomicOperations/Transactions/MusicTrackRepository.cs | 2 ++ .../AtomicOperations/Transactions/PerformerRepository.cs | 2 ++ .../IntegrationTests/CompositeKeys/CarRepository.cs | 2 ++ .../IntegrationTests/EagerLoading/BuildingRepository.cs | 2 ++ .../ExceptionHandling/ConsumerArticleService.cs | 2 ++ .../IntegrationTests/HostingInIIS/HostingStartup.cs | 2 ++ .../IntegrationTests/Meta/SupportTicketDefinition.cs | 2 ++ .../NamingConventions/KebabCasingConventionStartup.cs | 2 ++ .../SparseFieldSets/ResultCapturingRepository.cs | 2 ++ .../ResourceDefinitions/CallableResourceDefinition.cs | 2 ++ .../IntegrationTests/ResourceHooks/ResourceHooksStartup.cs | 2 ++ .../SoftDeletion/SoftDeletionResourceDefinition.cs | 2 ++ .../Startups/AbsoluteLinksInApiNamespaceStartup.cs | 2 ++ .../Startups/AbsoluteLinksNoNamespaceStartup.cs | 2 ++ .../Startups/ModelStateValidationStartup.cs | 2 ++ .../Startups/RelativeLinksInApiNamespaceStartup.cs | 2 ++ .../Startups/RelativeLinksNoNamespaceStartup.cs | 2 ++ .../Extensions/ServiceCollectionExtensionsTests.cs | 4 ++++ test/UnitTests/ResourceHooks/DiscoveryTests.cs | 7 +++++++ 34 files changed, 79 insertions(+), 6 deletions(-) diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/ArticleHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/ArticleHooksDefinition.cs index 7b84ce0378..6d4bc02cdb 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/ArticleHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/ArticleHooksDefinition.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Hooks.Internal.Execution; @@ -10,6 +11,7 @@ namespace JsonApiDotNetCoreExample.Definitions { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class ArticleHooksDefinition : ResourceHooksDefinition
    { public ArticleHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/PassportHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/PassportHooksDefinition.cs index 2e9cf34a15..8d73f9eaec 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/PassportHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/PassportHooksDefinition.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Hooks.Internal.Execution; @@ -9,6 +10,7 @@ namespace JsonApiDotNetCoreExample.Definitions { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class PassportHooksDefinition : LockableHooksDefinition { public PassportHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/PersonHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/PersonHooksDefinition.cs index 33a5defbce..28e1d51955 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/PersonHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/PersonHooksDefinition.cs @@ -1,11 +1,13 @@ using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Hooks.Internal.Execution; using JsonApiDotNetCoreExample.Models; namespace JsonApiDotNetCoreExample.Definitions { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class PersonHooksDefinition : LockableHooksDefinition { public PersonHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/TagHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/TagHooksDefinition.cs index f9339719f0..2ae1a543c6 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/TagHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/TagHooksDefinition.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Hooks.Internal.Execution; using JsonApiDotNetCore.Resources; @@ -7,15 +8,11 @@ namespace JsonApiDotNetCoreExample.Definitions { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class TagHooksDefinition : ResourceHooksDefinition { public TagHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } - public override IEnumerable BeforeCreate(IResourceHashSet resources, ResourcePipeline pipeline) - { - return base.BeforeCreate(resources, pipeline); - } - public override IEnumerable OnReturn(HashSet resources, ResourcePipeline pipeline) { return resources.Where(t => t.Name != "This should not be included"); diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs index 31a7e8aae9..892b12c7a8 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Hooks.Internal.Execution; @@ -9,6 +10,7 @@ namespace JsonApiDotNetCoreExample.Definitions { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class TodoItemHooksDefinition : LockableHooksDefinition { public TodoItemHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } diff --git a/src/Examples/MultiDbContextExample/Repositories/DbContextARepository.cs b/src/Examples/MultiDbContextExample/Repositories/DbContextARepository.cs index aeaf7fe7cb..44174777f8 100644 --- a/src/Examples/MultiDbContextExample/Repositories/DbContextARepository.cs +++ b/src/Examples/MultiDbContextExample/Repositories/DbContextARepository.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Repositories; @@ -8,6 +9,7 @@ namespace MultiDbContextExample.Repositories { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class DbContextARepository : EntityFrameworkCoreRepository where TResource : class, IIdentifiable { diff --git a/src/Examples/MultiDbContextExample/Repositories/DbContextBRepository.cs b/src/Examples/MultiDbContextExample/Repositories/DbContextBRepository.cs index 5fb3c41651..eb2cc5fc2b 100644 --- a/src/Examples/MultiDbContextExample/Repositories/DbContextBRepository.cs +++ b/src/Examples/MultiDbContextExample/Repositories/DbContextBRepository.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Repositories; @@ -8,6 +9,7 @@ namespace MultiDbContextExample.Repositories { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class DbContextBRepository : EntityFrameworkCoreRepository where TResource : class, IIdentifiable { diff --git a/src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs b/src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs index c2927ecb99..c0fdc425cf 100644 --- a/src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs +++ b/src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using Dapper; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Services; using Microsoft.Extensions.Configuration; @@ -13,6 +14,7 @@ namespace NoEntityFrameworkExample.Services { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class WorkItemService : IResourceService { private readonly string _connectionString; diff --git a/src/Examples/ReportsExample/Services/ReportService.cs b/src/Examples/ReportsExample/Services/ReportService.cs index 706e0e0d44..2fcb4367f0 100644 --- a/src/Examples/ReportsExample/Services/ReportService.cs +++ b/src/Examples/ReportsExample/Services/ReportService.cs @@ -1,12 +1,14 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Services; using Microsoft.Extensions.Logging; using ReportsExample.Models; namespace ReportsExample.Services { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public class ReportService : IGetAllService { private readonly ILogger _logger; diff --git a/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs b/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs index d9edcf8de3..efea19d9fc 100644 --- a/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs +++ b/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using FluentAssertions; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Hooks; using JsonApiDotNetCore.Middleware; @@ -156,6 +157,7 @@ public void Can_add_resource_hooks_definition_from_current_assembly_to_container public sealed class TestResource : Identifiable { } + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class TestResourceService : JsonApiResourceService { public TestResourceService( @@ -173,6 +175,7 @@ public TestResourceService( } } + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class TestResourceRepository : EntityFrameworkCoreRepository { public TestResourceRepository( @@ -185,12 +188,14 @@ public TestResourceRepository( : base(targetedFields, contextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory) { } } - + + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class TestResourceHooksDefinition : ResourceHooksDefinition { public TestResourceHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } } + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class TestResourceDefinition : JsonApiResourceDefinition { public TestResourceDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/MusicTrackMetaDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/MusicTrackMetaDefinition.cs index 2ff54786a0..27e13c0b7e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/MusicTrackMetaDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/MusicTrackMetaDefinition.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.Meta { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class MusicTrackMetaDefinition : JsonApiResourceDefinition { public MusicTrackMetaDefinition(IResourceGraph resourceGraph) : base(resourceGraph) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/TextLanguageMetaDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/TextLanguageMetaDefinition.cs index 93f4b6888e..ace9c8828f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/TextLanguageMetaDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Meta/TextLanguageMetaDefinition.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.Meta { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class TextLanguageMetaDefinition : JsonApiResourceDefinition { internal const string NoticeText = "See https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes for ISO 639-1 language codes."; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs index 90b3602301..ced06e127f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; @@ -8,6 +9,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.QueryStrings { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class MusicTrackReleaseDefinition : JsonApiResourceDefinition { private readonly ISystemClock _systemClock; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ResourceDefinitions/LyricTextDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ResourceDefinitions/LyricTextDefinition.cs index be315c3f0a..bf89c79b70 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ResourceDefinitions/LyricTextDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/ResourceDefinitions/LyricTextDefinition.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.ResourceDefinitions { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class LyricTextDefinition : JsonApiResourceDefinition { private readonly LyricPermissionProvider _lyricPermissionProvider; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/LyricRepository.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/LyricRepository.cs index 581ff9f64a..4417ee9d3b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/LyricRepository.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/LyricRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Repositories; @@ -8,6 +9,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.Transactions { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class LyricRepository : EntityFrameworkCoreRepository { private readonly ExtraDbContext _extraDbContext; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/MusicTrackRepository.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/MusicTrackRepository.cs index 740195172a..554f6b6d3e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/MusicTrackRepository.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/MusicTrackRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Repositories; @@ -8,6 +9,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.Transactions { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class MusicTrackRepository : EntityFrameworkCoreRepository { public override Guid? TransactionId => null; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/PerformerRepository.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/PerformerRepository.cs index 354e4a01a1..f22a3d8846 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/PerformerRepository.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Transactions/PerformerRepository.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Repositories; @@ -9,6 +10,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations.Transactions { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class PerformerRepository : IResourceRepository { public Task> GetAsync(QueryLayer layer, CancellationToken cancellationToken) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarRepository.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarRepository.cs index d266ae4ae1..a167ae4fff 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarRepository.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarRepository.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Queries.Expressions; @@ -9,6 +10,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CompositeKeys { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class CarRepository : EntityFrameworkCoreRepository { private readonly IResourceGraph _resourceGraph; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/BuildingRepository.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/BuildingRepository.cs index e8fd8644d5..78501d46b2 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/BuildingRepository.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/BuildingRepository.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Repositories; @@ -9,6 +10,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.EagerLoading { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class BuildingRepository : EntityFrameworkCoreRepository { public BuildingRepository(ITargetedFields targetedFields, IDbContextResolver contextResolver, diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs index d80e32ce44..7013299c6a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs @@ -1,6 +1,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Hooks; using JsonApiDotNetCore.Middleware; @@ -12,6 +13,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ExceptionHandling { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class ConsumerArticleService : JsonApiResourceService { internal const string UnavailableArticlePrefix = "X"; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingStartup.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingStartup.cs index 8d3da5f0e3..70c5ccca42 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingStartup.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCoreExampleTests.Startups; using Microsoft.AspNetCore.Builder; @@ -7,6 +8,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class HostingStartup : TestableStartup where TDbContext : DbContext { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportTicketDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportTicketDefinition.cs index 1261d09d9f..1f3d1be0a2 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportTicketDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportTicketDefinition.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Meta { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class SupportTicketDefinition : JsonApiResourceDefinition { public SupportTicketDefinition(IResourceGraph resourceGraph) : base(resourceGraph) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs index b7980fcb10..bc02d82085 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCoreExampleTests.Startups; using Microsoft.EntityFrameworkCore; @@ -6,6 +7,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.NamingConventions { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class KebabCasingConventionStartup : TestableStartup where TDbContext : DbContext { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/ResultCapturingRepository.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/ResultCapturingRepository.cs index 1b0f8b7efc..8efb97d80b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/ResultCapturingRepository.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/SparseFieldSets/ResultCapturingRepository.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Repositories; @@ -12,6 +13,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings.SparseFiel /// /// Enables sparse fieldset tests to verify which fields were (not) retrieved from the database. /// + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class ResultCapturingRepository : EntityFrameworkCoreRepository where TResource : class, IIdentifiable { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs index e956d6c259..67d7fd5d61 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResourceDefinition.cs @@ -2,6 +2,7 @@ using System.ComponentModel; using System.Linq; using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; @@ -12,6 +13,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceDefinitions { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class CallableResourceDefinition : JsonApiResourceDefinition { private readonly IUserRolesService _userRolesService; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHooksStartup.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHooksStartup.cs index 64685ba34e..3df537b2e4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHooksStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHooksStartup.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCoreExampleTests.Startups; using Microsoft.EntityFrameworkCore; @@ -6,6 +7,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceHooks { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class ResourceHooksStartup : TestableStartup where TDbContext : DbContext { diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionResourceDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionResourceDefinition.cs index a460536990..095bdaf02f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionResourceDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/SoftDeletionResourceDefinition.cs @@ -1,4 +1,5 @@ using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; @@ -6,6 +7,7 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.SoftDeletion { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class SoftDeletionResourceDefinition : JsonApiResourceDefinition where TResource : class, IIdentifiable, ISoftDeletable { diff --git a/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksInApiNamespaceStartup.cs b/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksInApiNamespaceStartup.cs index a9950b3da7..093b1e6908 100644 --- a/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksInApiNamespaceStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksInApiNamespaceStartup.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; namespace JsonApiDotNetCoreExampleTests.Startups { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class AbsoluteLinksInApiNamespaceStartup : TestableStartup where TDbContext : DbContext { diff --git a/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksNoNamespaceStartup.cs b/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksNoNamespaceStartup.cs index 636a84ca14..3dc0abb455 100644 --- a/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksNoNamespaceStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksNoNamespaceStartup.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; namespace JsonApiDotNetCoreExampleTests.Startups { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class AbsoluteLinksNoNamespaceStartup : TestableStartup where TDbContext : DbContext { diff --git a/test/JsonApiDotNetCoreExampleTests/Startups/ModelStateValidationStartup.cs b/test/JsonApiDotNetCoreExampleTests/Startups/ModelStateValidationStartup.cs index 8816d19f21..1a67f21c8f 100644 --- a/test/JsonApiDotNetCoreExampleTests/Startups/ModelStateValidationStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/Startups/ModelStateValidationStartup.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; namespace JsonApiDotNetCoreExampleTests.Startups { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class ModelStateValidationStartup : TestableStartup where TDbContext : DbContext { diff --git a/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksInApiNamespaceStartup.cs b/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksInApiNamespaceStartup.cs index f8e3b18814..52b74b15cd 100644 --- a/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksInApiNamespaceStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksInApiNamespaceStartup.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; namespace JsonApiDotNetCoreExampleTests.Startups { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class RelativeLinksInApiNamespaceStartup : TestableStartup where TDbContext : DbContext { diff --git a/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksNoNamespaceStartup.cs b/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksNoNamespaceStartup.cs index 365f3454ca..dd95d8ab30 100644 --- a/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksNoNamespaceStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksNoNamespaceStartup.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; namespace JsonApiDotNetCoreExampleTests.Startups { + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class RelativeLinksNoNamespaceStartup : TestableStartup where TDbContext : DbContext { diff --git a/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs b/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs index 60025d9b4d..b795c05ec3 100644 --- a/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs +++ b/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs @@ -190,6 +190,7 @@ public void AddJsonApi_With_Context_Uses_Resource_Type_Name_If_NoOtherSpecified( public sealed class IntResource : Identifiable { } public sealed class GuidResource : Identifiable { } + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] private sealed class IntResourceService : IResourceService { public Task> GetAsync(CancellationToken cancellationToken) => throw new NotImplementedException(); @@ -204,6 +205,7 @@ private sealed class IntResourceService : IResourceService public Task RemoveFromToManyRelationshipAsync(int primaryId, string relationshipName, ISet secondaryResourceIds, CancellationToken cancellationToken) => throw new NotImplementedException(); } + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] private sealed class GuidResourceService : IResourceService { public Task> GetAsync(CancellationToken cancellationToken) => throw new NotImplementedException(); @@ -218,6 +220,7 @@ private sealed class GuidResourceService : IResourceService public Task RemoveFromToManyRelationshipAsync(Guid primaryId, string relationshipName, ISet secondaryResourceIds, CancellationToken cancellationToken) => throw new NotImplementedException(); } + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] private sealed class IntResourceRepository : IResourceRepository { public Task> GetAsync(QueryLayer layer, CancellationToken cancellationToken) => throw new NotImplementedException(); @@ -232,6 +235,7 @@ private sealed class IntResourceRepository : IResourceRepository public Task RemoveFromToManyRelationshipAsync(IntResource primaryResource, ISet secondaryResourceIds, CancellationToken cancellationToken) => throw new NotImplementedException(); } + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] private sealed class GuidResourceRepository : IResourceRepository { public Task> GetAsync(QueryLayer layer, CancellationToken cancellationToken) => throw new NotImplementedException(); diff --git a/test/UnitTests/ResourceHooks/DiscoveryTests.cs b/test/UnitTests/ResourceHooks/DiscoveryTests.cs index 91879f6b6f..be9c137f9b 100644 --- a/test/UnitTests/ResourceHooks/DiscoveryTests.cs +++ b/test/UnitTests/ResourceHooks/DiscoveryTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Hooks.Internal.Discovery; @@ -14,6 +15,8 @@ namespace UnitTests.ResourceHooks public sealed class DiscoveryTests { public sealed class Dummy : Identifiable { } + + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class DummyResourceDefinition : ResourceHooksDefinition { public DummyResourceDefinition() : base(new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance).Add().Build()) { } @@ -48,6 +51,7 @@ protected ResourceDefinitionBase(IResourceGraph resourceGraph) : base(resourceGr public override void AfterDelete(HashSet resources, ResourcePipeline pipeline, bool succeeded) { } } + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class AnotherDummyResourceDefinition : ResourceDefinitionBase { public AnotherDummyResourceDefinition() : base(new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance).Add().Build()) { } @@ -65,6 +69,8 @@ public void HookDiscovery_InheritanceSubclass_CanDiscover() } public sealed class YetAnotherDummy : Identifiable { } + + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class YetAnotherDummyResourceDefinition : ResourceHooksDefinition { public YetAnotherDummyResourceDefinition() : base(new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance).Add().Build()) { } @@ -96,6 +102,7 @@ public void HookDiscovery_InheritanceWithGenericSubclass_CanDiscover() Assert.Contains(ResourceHook.AfterDelete, hookConfig.ImplementedHooks); } + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] public sealed class GenericDummyResourceDefinition : ResourceHooksDefinition where TResource : class, IIdentifiable { public GenericDummyResourceDefinition() : base(new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance).Add().Build()) { } From 61bf587246763112be0fae83df30ed3dfcc750de Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 24 Feb 2021 16:09:23 +0100 Subject: [PATCH 39/60] Added [UsedImplicitly] on models --- benchmarks/BenchmarkResource.cs | 2 ++ benchmarks/SubResource.cs | 2 ++ src/Examples/GettingStarted/Models/Book.cs | 2 ++ src/Examples/GettingStarted/Models/Person.cs | 2 ++ src/Examples/JsonApiDotNetCoreExample/Models/Article.cs | 2 ++ src/Examples/JsonApiDotNetCoreExample/Models/ArticleTag.cs | 3 +++ src/Examples/JsonApiDotNetCoreExample/Models/Author.cs | 2 ++ .../Models/IdentifiableArticleTag.cs | 2 ++ src/Examples/JsonApiDotNetCoreExample/Models/Passport.cs | 2 ++ src/Examples/JsonApiDotNetCoreExample/Models/Person.cs | 2 ++ src/Examples/JsonApiDotNetCoreExample/Models/Tag.cs | 2 ++ src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs | 2 ++ src/Examples/JsonApiDotNetCoreExample/Models/User.cs | 2 ++ src/Examples/MultiDbContextExample/Models/ResourceA.cs | 2 ++ src/Examples/MultiDbContextExample/Models/ResourceB.cs | 2 ++ src/Examples/NoEntityFrameworkExample/Models/WorkItem.cs | 2 ++ src/Examples/ReportsExample/Models/Report.cs | 2 ++ test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs | 1 + .../IntegrationTests/AtomicOperations/Lyric.cs | 2 ++ .../IntegrationTests/AtomicOperations/MusicTrack.cs | 2 ++ .../IntegrationTests/AtomicOperations/Performer.cs | 2 ++ .../IntegrationTests/AtomicOperations/Playlist.cs | 2 ++ .../IntegrationTests/AtomicOperations/PlaylistMusicTrack.cs | 2 ++ .../IntegrationTests/AtomicOperations/RecordCompany.cs | 2 ++ .../IntegrationTests/AtomicOperations/TextLanguage.cs | 2 ++ .../IntegrationTests/CompositeKeys/Car.cs | 2 ++ .../IntegrationTests/CompositeKeys/Dealership.cs | 2 ++ .../IntegrationTests/CompositeKeys/Engine.cs | 2 ++ .../IntegrationTests/ContentNegotiation/Policy.cs | 2 ++ .../IntegrationTests/ControllerActionResults/Toothbrush.cs | 2 ++ .../IntegrationTests/CustomRoutes/Civilian.cs | 2 ++ .../IntegrationTests/CustomRoutes/Town.cs | 2 ++ .../IntegrationTests/EagerLoading/Building.cs | 2 ++ .../IntegrationTests/EagerLoading/City.cs | 2 ++ .../IntegrationTests/EagerLoading/Door.cs | 3 +++ .../IntegrationTests/EagerLoading/State.cs | 2 ++ .../IntegrationTests/EagerLoading/Street.cs | 2 ++ .../IntegrationTests/EagerLoading/Window.cs | 5 ++++- .../IntegrationTests/ExceptionHandling/ConsumerArticle.cs | 2 ++ .../IntegrationTests/ExceptionHandling/ThrowingArticle.cs | 2 ++ .../IntegrationTests/HostingInIIS/ArtGallery.cs | 2 ++ .../IntegrationTests/HostingInIIS/Painting.cs | 2 ++ .../IntegrationTests/IdObfuscation/BankAccount.cs | 2 ++ .../IntegrationTests/IdObfuscation/DebitCard.cs | 2 ++ .../IntegrationTests/Links/Photo.cs | 2 ++ .../IntegrationTests/Links/PhotoAlbum.cs | 2 ++ .../IntegrationTests/Links/PhotoLocation.cs | 2 ++ .../IntegrationTests/Logging/AuditEntry.cs | 2 ++ .../IntegrationTests/Meta/ProductFamily.cs | 2 ++ .../IntegrationTests/Meta/SupportTicket.cs | 2 ++ .../IntegrationTests/ModelStateValidation/SystemDirectory.cs | 2 ++ .../IntegrationTests/ModelStateValidation/SystemFile.cs | 2 ++ .../IntegrationTests/NamingConventions/DivingBoard.cs | 2 ++ .../IntegrationTests/NamingConventions/SwimmingPool.cs | 2 ++ .../IntegrationTests/NamingConventions/WaterSlide.cs | 2 ++ .../IntegrationTests/QueryStrings/AccountPreferences.cs | 2 ++ .../IntegrationTests/QueryStrings/Appointment.cs | 2 ++ .../IntegrationTests/QueryStrings/Blog.cs | 2 ++ .../IntegrationTests/QueryStrings/BlogPost.cs | 2 ++ .../IntegrationTests/QueryStrings/BlogPostLabel.cs | 3 +++ .../IntegrationTests/QueryStrings/Calendar.cs | 4 +++- .../IntegrationTests/QueryStrings/Comment.cs | 2 ++ .../QueryStrings/Filtering/FilterableResource.cs | 2 ++ .../IntegrationTests/QueryStrings/Label.cs | 2 ++ .../IntegrationTests/QueryStrings/WebAccount.cs | 2 ++ .../IntegrationTests/ReadWrite/RgbColor.cs | 2 ++ .../IntegrationTests/ReadWrite/UserAccount.cs | 2 ++ .../IntegrationTests/ReadWrite/WorkItem.cs | 2 ++ .../IntegrationTests/ReadWrite/WorkItemGroup.cs | 2 ++ .../IntegrationTests/ReadWrite/WorkItemTag.cs | 3 +++ .../IntegrationTests/ReadWrite/WorkItemToWorkItem.cs | 3 +++ .../IntegrationTests/ReadWrite/WorkTag.cs | 2 ++ .../IntegrationTests/RequiredRelationships/Customer.cs | 2 ++ .../IntegrationTests/RequiredRelationships/Order.cs | 2 ++ .../IntegrationTests/RequiredRelationships/Shipment.cs | 2 ++ .../ResourceConstructorInjection/GiftCertificate.cs | 2 ++ .../ResourceConstructorInjection/PostOffice.cs | 2 ++ .../IntegrationTests/ResourceDefinitions/CallableResource.cs | 2 ++ .../IntegrationTests/ResourceInheritance/Models/Book.cs | 2 ++ .../ResourceInheritance/Models/CompanyHealthInsurance.cs | 2 ++ .../ResourceInheritance/Models/ContentItem.cs | 2 ++ .../ResourceInheritance/Models/FamilyHealthInsurance.cs | 2 ++ .../ResourceInheritance/Models/HealthInsurance.cs | 2 ++ .../IntegrationTests/ResourceInheritance/Models/Human.cs | 2 ++ .../ResourceInheritance/Models/HumanFavoriteContentItem.cs | 3 +++ .../IntegrationTests/ResourceInheritance/Models/Man.cs | 2 ++ .../IntegrationTests/ResourceInheritance/Models/Video.cs | 2 ++ .../IntegrationTests/ResourceInheritance/Models/Woman.cs | 2 ++ .../IntegrationTests/RestrictedControllers/Bed.cs | 2 ++ .../IntegrationTests/RestrictedControllers/Chair.cs | 2 ++ .../IntegrationTests/RestrictedControllers/Sofa.cs | 2 ++ .../IntegrationTests/RestrictedControllers/Table.cs | 2 ++ .../IntegrationTests/Serialization/Meeting.cs | 2 ++ .../IntegrationTests/Serialization/MeetingAttendee.cs | 4 +++- .../IntegrationTests/SoftDeletion/Company.cs | 2 ++ .../IntegrationTests/SoftDeletion/Department.cs | 2 ++ .../IntegrationTests/ZeroKeys/Game.cs | 2 ++ .../IntegrationTests/ZeroKeys/Map.cs | 2 ++ .../IntegrationTests/ZeroKeys/Player.cs | 2 ++ test/UnitTests/Builders/ResourceGraphBuilderTests.cs | 1 + test/UnitTests/Controllers/BaseJsonApiControllerTests.cs | 2 ++ test/UnitTests/Models/ResourceWithStringConstructor.cs | 2 ++ test/UnitTests/Models/ResourceWithThrowingConstructor.cs | 2 ++ test/UnitTests/ResourceHooks/Dummy.cs | 4 +++- test/UnitTests/TestModels/Article.cs | 2 ++ test/UnitTests/TestModels/Blog.cs | 2 ++ test/UnitTests/TestModels/FirstDerivedModel.cs | 2 ++ test/UnitTests/TestModels/Food.cs | 2 ++ test/UnitTests/TestModels/IdentifiableWithAttribute.cs | 4 +++- .../TestModels/MultipleRelationshipsDependentPart.cs | 2 ++ .../TestModels/MultipleRelationshipsPrincipalPart.cs | 4 +++- test/UnitTests/TestModels/OneToManyDependent.cs | 4 +++- test/UnitTests/TestModels/OneToManyPrincipal.cs | 4 +++- test/UnitTests/TestModels/OneToManyRequiredDependent.cs | 2 ++ test/UnitTests/TestModels/OneToOneDependent.cs | 4 +++- test/UnitTests/TestModels/OneToOnePrincipal.cs | 4 +++- test/UnitTests/TestModels/OneToOneRequiredDependent.cs | 4 +++- test/UnitTests/TestModels/Person.cs | 2 ++ test/UnitTests/TestModels/SecondDerivedModel.cs | 2 ++ test/UnitTests/TestModels/Song.cs | 2 ++ test/UnitTests/TestModels/TestResource.cs | 2 ++ .../TestModels/TestResourceWithAbstractRelationship.cs | 2 ++ test/UnitTests/TestModels/TestResourceWithList.cs | 2 ++ 123 files changed, 262 insertions(+), 11 deletions(-) diff --git a/benchmarks/BenchmarkResource.cs b/benchmarks/BenchmarkResource.cs index a79ede4675..50c132c8a7 100644 --- a/benchmarks/BenchmarkResource.cs +++ b/benchmarks/BenchmarkResource.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace Benchmarks { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class BenchmarkResource : Identifiable { [Attr(PublicName = BenchmarkResourcePublicNames.NameAttr)] diff --git a/benchmarks/SubResource.cs b/benchmarks/SubResource.cs index f37e4384c0..73536a87ae 100644 --- a/benchmarks/SubResource.cs +++ b/benchmarks/SubResource.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace Benchmarks { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class SubResource : Identifiable { [Attr] diff --git a/src/Examples/GettingStarted/Models/Book.cs b/src/Examples/GettingStarted/Models/Book.cs index 9e4ae01b50..9f15d3e3c9 100644 --- a/src/Examples/GettingStarted/Models/Book.cs +++ b/src/Examples/GettingStarted/Models/Book.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace GettingStarted.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Book : Identifiable { [Attr] diff --git a/src/Examples/GettingStarted/Models/Person.cs b/src/Examples/GettingStarted/Models/Person.cs index 35551bb311..495a4fe27b 100644 --- a/src/Examples/GettingStarted/Models/Person.cs +++ b/src/Examples/GettingStarted/Models/Person.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace GettingStarted.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Person : Identifiable { [Attr] diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/Article.cs b/src/Examples/JsonApiDotNetCoreExample/Models/Article.cs index 65addba5a3..84de22fcdf 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/Article.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/Article.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Article : Identifiable { [Attr] diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/ArticleTag.cs b/src/Examples/JsonApiDotNetCoreExample/Models/ArticleTag.cs index b0e4d59435..7edc32ef75 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/ArticleTag.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/ArticleTag.cs @@ -1,5 +1,8 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCoreExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ArticleTag { public int ArticleId { get; set; } diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/Author.cs b/src/Examples/JsonApiDotNetCoreExample/Models/Author.cs index cd023ba729..0b5b1d1acd 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/Author.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/Author.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Author : Identifiable { [Attr] diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/IdentifiableArticleTag.cs b/src/Examples/JsonApiDotNetCoreExample/Models/IdentifiableArticleTag.cs index 91131b8187..ba44bf56ad 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/IdentifiableArticleTag.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/IdentifiableArticleTag.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class IdentifiableArticleTag : Identifiable { public int ArticleId { get; set; } diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/Passport.cs b/src/Examples/JsonApiDotNetCoreExample/Models/Passport.cs index 600a77d285..23d4012dd9 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/Passport.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/Passport.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Passport : Identifiable, IIsLockable { [Attr] diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/Person.cs b/src/Examples/JsonApiDotNetCoreExample/Models/Person.cs index 17f6a26473..45015c437f 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/Person.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/Person.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Person : Identifiable, IIsLockable { public bool IsLocked { get; set; } diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/Tag.cs b/src/Examples/JsonApiDotNetCoreExample/Models/Tag.cs index ae98d787d5..b1b446d7f2 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/Tag.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/Tag.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Tag : Identifiable { [Attr] diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs b/src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs index b7982e182d..b9f0277b61 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class TodoItem : Identifiable, IIsLockable { public bool IsLocked { get; set; } diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/User.cs b/src/Examples/JsonApiDotNetCoreExample/Models/User.cs index 7361fe0e72..fd7852ec3b 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/User.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/User.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class User : Identifiable { [Attr] diff --git a/src/Examples/MultiDbContextExample/Models/ResourceA.cs b/src/Examples/MultiDbContextExample/Models/ResourceA.cs index 104611cffc..85cbf2b89a 100644 --- a/src/Examples/MultiDbContextExample/Models/ResourceA.cs +++ b/src/Examples/MultiDbContextExample/Models/ResourceA.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace MultiDbContextExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ResourceA : Identifiable { [Attr] diff --git a/src/Examples/MultiDbContextExample/Models/ResourceB.cs b/src/Examples/MultiDbContextExample/Models/ResourceB.cs index 1fb41b6f96..dd1739ee49 100644 --- a/src/Examples/MultiDbContextExample/Models/ResourceB.cs +++ b/src/Examples/MultiDbContextExample/Models/ResourceB.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace MultiDbContextExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ResourceB : Identifiable { [Attr] diff --git a/src/Examples/NoEntityFrameworkExample/Models/WorkItem.cs b/src/Examples/NoEntityFrameworkExample/Models/WorkItem.cs index a3a929bd5a..20d381a2ba 100644 --- a/src/Examples/NoEntityFrameworkExample/Models/WorkItem.cs +++ b/src/Examples/NoEntityFrameworkExample/Models/WorkItem.cs @@ -1,9 +1,11 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace NoEntityFrameworkExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class WorkItem : Identifiable { [Attr] diff --git a/src/Examples/ReportsExample/Models/Report.cs b/src/Examples/ReportsExample/Models/Report.cs index 8125f1f0ab..6635687a1d 100644 --- a/src/Examples/ReportsExample/Models/Report.cs +++ b/src/Examples/ReportsExample/Models/Report.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace ReportsExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Report : Identifiable { [Attr] diff --git a/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs b/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs index efea19d9fc..4f568d9555 100644 --- a/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs +++ b/test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs @@ -155,6 +155,7 @@ public void Can_add_resource_hooks_definition_from_current_assembly_to_container resourceHooksDefinition.Should().BeOfType(); } + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class TestResource : Identifiable { } [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Lyric.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Lyric.cs index a02949e2e9..31e9e5106a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Lyric.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Lyric.cs @@ -1,9 +1,11 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Lyric : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/MusicTrack.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/MusicTrack.cs index 8639702c78..991d999f1d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/MusicTrack.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/MusicTrack.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class MusicTrack : Identifiable { [RegularExpression(@"(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$")] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Performer.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Performer.cs index 9b6d85c610..37a0f0c16b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Performer.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Performer.cs @@ -1,9 +1,11 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Performer : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Playlist.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Playlist.cs index 11fd778cc2..5b0713c45b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Playlist.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/Playlist.cs @@ -1,11 +1,13 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Playlist : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/PlaylistMusicTrack.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/PlaylistMusicTrack.cs index 9c5389867a..47540cafdf 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/PlaylistMusicTrack.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/PlaylistMusicTrack.cs @@ -1,7 +1,9 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class PlaylistMusicTrack { public long PlaylistId { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/RecordCompany.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/RecordCompany.cs index 5dc89a7a87..d735fe4d7b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/RecordCompany.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/RecordCompany.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class RecordCompany : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/TextLanguage.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/TextLanguage.cs index 57452eb2d2..7942ebc5ed 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/TextLanguage.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/TextLanguage.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.AtomicOperations { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class TextLanguage : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/Car.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/Car.cs index 70591f317f..eccd7acda0 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/Car.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/Car.cs @@ -1,10 +1,12 @@ using System; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CompositeKeys { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Car : Identifiable { [NotMapped] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/Dealership.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/Dealership.cs index b8c845dc7c..8ac8d4e50d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/Dealership.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/Dealership.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CompositeKeys { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Dealership : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/Engine.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/Engine.cs index 33ecaf4b6c..b58c3b53ec 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/Engine.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/Engine.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CompositeKeys { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Engine : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/Policy.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/Policy.cs index 3a09cce5e6..155bcea4a4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/Policy.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ContentNegotiation/Policy.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ContentNegotiation { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Policy : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/Toothbrush.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/Toothbrush.cs index be88ad4f4e..3a9f69ec1f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/Toothbrush.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ControllerActionResults/Toothbrush.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ControllerActionResults { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Toothbrush : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/Civilian.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/Civilian.cs index c5f75a2c38..65b3acedc7 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/Civilian.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/Civilian.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CustomRoutes { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Civilian : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/Town.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/Town.cs index 0f2dc93926..ba0ba27fe2 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/Town.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/CustomRoutes/Town.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CustomRoutes { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Town : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Building.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Building.cs index ff68b9a0c5..79af5eac30 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Building.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Building.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.EagerLoading { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Building : Identifiable { private string _tempPrimaryDoorColor; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/City.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/City.cs index 2fbff2cf67..ec8c85b56a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/City.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/City.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.EagerLoading { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class City : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Door.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Door.cs index 919d0a1907..068c06414c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Door.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Door.cs @@ -1,5 +1,8 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.EagerLoading { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Door { public int Id { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/State.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/State.cs index 28fb189d05..99e46ff0a3 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/State.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/State.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.EagerLoading { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class State : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Street.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Street.cs index 7e275d03a2..6ea7264c67 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Street.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Street.cs @@ -1,11 +1,13 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.EagerLoading { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Street : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Window.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Window.cs index 85a10775e2..88dd4a6896 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Window.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/EagerLoading/Window.cs @@ -1,5 +1,8 @@ -namespace JsonApiDotNetCoreExampleTests.IntegrationTests.EagerLoading +using JetBrains.Annotations; + +namespace JsonApiDotNetCoreExampleTests.IntegrationTests.EagerLoading { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Window { public int Id { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticle.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticle.cs index 320355edfa..a7c2b686e8 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticle.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ConsumerArticle.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ExceptionHandling { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ConsumerArticle : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ThrowingArticle.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ThrowingArticle.cs index af4f7890ac..fe2d61c6d6 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ThrowingArticle.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ExceptionHandling/ThrowingArticle.cs @@ -1,10 +1,12 @@ using System; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ExceptionHandling { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ThrowingArticle : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/ArtGallery.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/ArtGallery.cs index 470b7c4e63..b3fd2d7317 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/ArtGallery.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/ArtGallery.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ArtGallery : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/Painting.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/Painting.cs index 75979bf30c..2b4c3d5d4f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/Painting.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/Painting.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Painting : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/BankAccount.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/BankAccount.cs index d2f33c7dc7..da98000a04 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/BankAccount.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/BankAccount.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.IdObfuscation { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class BankAccount : ObfuscatedIdentifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/DebitCard.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/DebitCard.cs index 9bd4bcc789..2c0a12fd30 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/DebitCard.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/IdObfuscation/DebitCard.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.IdObfuscation { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class DebitCard : ObfuscatedIdentifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/Photo.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/Photo.cs index 592d5ccb12..e13d93fd92 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/Photo.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/Photo.cs @@ -1,9 +1,11 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Links { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Photo : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/PhotoAlbum.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/PhotoAlbum.cs index d5a6b448e3..19ff317933 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/PhotoAlbum.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/PhotoAlbum.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Links { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class PhotoAlbum : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/PhotoLocation.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/PhotoLocation.cs index 362c6edb36..feb6582694 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/PhotoLocation.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Links/PhotoLocation.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Links { [ResourceLinks(TopLevelLinks = LinkTypes.None, ResourceLinks = LinkTypes.None, RelationshipLinks = LinkTypes.Related)] + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class PhotoLocation : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/AuditEntry.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/AuditEntry.cs index e9fcfcfe5e..d7001f400f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/AuditEntry.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/AuditEntry.cs @@ -1,9 +1,11 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Logging { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class AuditEntry : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/ProductFamily.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/ProductFamily.cs index 75a8e34441..ea40d2c09f 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/ProductFamily.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/ProductFamily.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Meta { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ProductFamily : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportTicket.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportTicket.cs index b006ba51e2..b93fcb6b8c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportTicket.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Meta/SupportTicket.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Meta { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class SupportTicket : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/SystemDirectory.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/SystemDirectory.cs index 9c851fe832..f78848863a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/SystemDirectory.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/SystemDirectory.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ModelStateValidation { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class SystemDirectory : Identifiable { [Required] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/SystemFile.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/SystemFile.cs index a7890730f2..8598695d35 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/SystemFile.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ModelStateValidation/SystemFile.cs @@ -1,9 +1,11 @@ using System.ComponentModel.DataAnnotations; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ModelStateValidation { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class SystemFile : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/DivingBoard.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/DivingBoard.cs index c46c4f410f..fc23994b25 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/DivingBoard.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/DivingBoard.cs @@ -1,9 +1,11 @@ using System.ComponentModel.DataAnnotations; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.NamingConventions { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class DivingBoard : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/SwimmingPool.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/SwimmingPool.cs index 6c1274816e..324b984522 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/SwimmingPool.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/SwimmingPool.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.NamingConventions { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class SwimmingPool : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/WaterSlide.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/WaterSlide.cs index b7dea1d5ba..b9007dfe98 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/WaterSlide.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/WaterSlide.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.NamingConventions { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class WaterSlide : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/AccountPreferences.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/AccountPreferences.cs index ecc7308906..f623cf82d9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/AccountPreferences.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/AccountPreferences.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class AccountPreferences : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Appointment.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Appointment.cs index 62838a6df8..d7a6f84e9a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Appointment.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Appointment.cs @@ -1,9 +1,11 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Appointment : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Blog.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Blog.cs index d1ae74e810..2edbb10c99 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Blog.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Blog.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Blog : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/BlogPost.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/BlogPost.cs index 10205816ab..dea9789436 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/BlogPost.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/BlogPost.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class BlogPost : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/BlogPostLabel.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/BlogPostLabel.cs index fd14bbf831..d394a0b1bd 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/BlogPostLabel.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/BlogPostLabel.cs @@ -1,5 +1,8 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class BlogPostLabel { public int BlogPostId { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Calendar.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Calendar.cs index 5447aba40b..494184ee68 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Calendar.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Calendar.cs @@ -1,9 +1,11 @@ -using System.Collections.Generic; +using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Calendar : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Comment.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Comment.cs index 848915f7ed..199f8c1287 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Comment.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Comment.cs @@ -1,9 +1,11 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Comment : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterableResource.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterableResource.cs index 4be6b98e02..60cd72d510 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterableResource.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Filtering/FilterableResource.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings.Filtering { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class FilterableResource : Identifiable { [Attr] public string SomeString { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Label.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Label.cs index 1a45f848e8..adfb7a1226 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Label.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/Label.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Label : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/WebAccount.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/WebAccount.cs index 576953088a..3a51366dc0 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/WebAccount.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/WebAccount.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class WebAccount : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/RgbColor.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/RgbColor.cs index 2e5f60d881..5e1094bd17 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/RgbColor.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/RgbColor.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ReadWrite { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class RgbColor : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/UserAccount.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/UserAccount.cs index 1ed7034038..a13f98a5be 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/UserAccount.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/UserAccount.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ReadWrite { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class UserAccount : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItem.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItem.cs index b908090c48..c667e45f5a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItem.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItem.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ReadWrite { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class WorkItem : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemGroup.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemGroup.cs index 07bc16ba31..740c96ad22 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemGroup.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemGroup.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ReadWrite { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class WorkItemGroup : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemTag.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemTag.cs index d9c13d9e4c..bf17fd2a3e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemTag.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemTag.cs @@ -1,5 +1,8 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ReadWrite { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class WorkItemTag { public WorkItem Item { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemToWorkItem.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemToWorkItem.cs index 5d2eb588e8..92fa943645 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemToWorkItem.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemToWorkItem.cs @@ -1,5 +1,8 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ReadWrite { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class WorkItemToWorkItem { public WorkItem FromItem { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkTag.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkTag.cs index 04ef9d3d95..290a0285c5 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkTag.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkTag.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ReadWrite { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class WorkTag : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/Customer.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/Customer.cs index 1d2cf0c1c3..0dad711a61 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/Customer.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/Customer.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.RequiredRelationships { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Customer : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/Order.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/Order.cs index 3e57bae01e..7ddae205fa 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/Order.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/Order.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.RequiredRelationships { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Order : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/Shipment.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/Shipment.cs index b79335b841..00257b5f0c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/Shipment.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RequiredRelationships/Shipment.cs @@ -1,9 +1,11 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.RequiredRelationships { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Shipment : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/GiftCertificate.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/GiftCertificate.cs index 44436e03ee..ea508c877a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/GiftCertificate.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/GiftCertificate.cs @@ -1,11 +1,13 @@ using System; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; using Microsoft.AspNetCore.Authentication; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceConstructorInjection { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class GiftCertificate : Identifiable { private readonly ISystemClock _systemClock; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/PostOffice.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/PostOffice.cs index e183760098..1980a1113c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/PostOffice.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/PostOffice.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; using Microsoft.AspNetCore.Authentication; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceConstructorInjection { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class PostOffice : Identifiable { private readonly ISystemClock _systemClock; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResource.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResource.cs index e63ae24daa..73820a9364 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResource.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/CallableResource.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceDefinitions { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class CallableResource : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Book.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Book.cs index 1c87e2f825..406456baa5 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Book.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Book.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Book : ContentItem { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/CompanyHealthInsurance.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/CompanyHealthInsurance.cs index cb1a8bcce8..4813c2b185 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/CompanyHealthInsurance.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/CompanyHealthInsurance.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class CompanyHealthInsurance : HealthInsurance { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/ContentItem.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/ContentItem.cs index 9f1509f98e..7eca0cab9a 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/ContentItem.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/ContentItem.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public abstract class ContentItem : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/FamilyHealthInsurance.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/FamilyHealthInsurance.cs index 564e8f5701..ff38ba3094 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/FamilyHealthInsurance.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/FamilyHealthInsurance.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class FamilyHealthInsurance : HealthInsurance { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/HealthInsurance.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/HealthInsurance.cs index 4dc82d5cbf..eeaef53aa9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/HealthInsurance.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/HealthInsurance.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public abstract class HealthInsurance : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Human.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Human.cs index e4177e1c91..88086338c9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Human.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Human.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public abstract class Human : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/HumanFavoriteContentItem.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/HumanFavoriteContentItem.cs index 1494b8912e..b5ac783c76 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/HumanFavoriteContentItem.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/HumanFavoriteContentItem.cs @@ -1,5 +1,8 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class HumanFavoriteContentItem { public int ContentItemId { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Man.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Man.cs index 462dd0fc78..7c0acfaa35 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Man.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Man.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Man : Human { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Video.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Video.cs index 62cae2af08..dc34ebaf6c 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Video.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Video.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Video : ContentItem { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Woman.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Woman.cs index 666fd53305..29007907a8 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Woman.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceInheritance/Models/Woman.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceInheritance.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Woman : Human { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Bed.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Bed.cs index 8c84293143..a576e6c903 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Bed.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Bed.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.RestrictedControllers { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Bed : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Chair.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Chair.cs index 1948563f01..4f58b57233 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Chair.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Chair.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.RestrictedControllers { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Chair : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Sofa.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Sofa.cs index c812e24b01..a126d7d0cc 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Sofa.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Sofa.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.RestrictedControllers { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Sofa : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Table.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Table.cs index 6d07ba65d6..a9d2325ae2 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Table.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/RestrictedControllers/Table.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.RestrictedControllers { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Table : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/Meeting.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/Meeting.cs index 6a3092004f..147eaa24c9 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/Meeting.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/Meeting.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Serialization { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Meeting : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/MeetingAttendee.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/MeetingAttendee.cs index dd79ed029b..86628469c5 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/MeetingAttendee.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Serialization/MeetingAttendee.cs @@ -1,9 +1,11 @@ -using System; +using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.Serialization { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class MeetingAttendee : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/Company.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/Company.cs index 77128d4dbc..1e4dad6f61 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/Company.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/Company.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.SoftDeletion { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Company : Identifiable, ISoftDeletable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/Department.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/Department.cs index 06154b5a84..db2ec47c68 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/Department.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/SoftDeletion/Department.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.SoftDeletion { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Department : Identifiable, ISoftDeletable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/Game.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/Game.cs index 46269627ef..721da9d377 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/Game.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/Game.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ZeroKeys { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Game : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/Map.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/Map.cs index 994f2d0d2f..21ffe008a6 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/Map.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/Map.cs @@ -1,9 +1,11 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ZeroKeys { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Map : Identifiable { [Attr] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/Player.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/Player.cs index 656bfd61a9..3d5a6236cf 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/Player.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ZeroKeys/Player.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ZeroKeys { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Player : Identifiable { [Attr] diff --git a/test/UnitTests/Builders/ResourceGraphBuilderTests.cs b/test/UnitTests/Builders/ResourceGraphBuilderTests.cs index 2e1684b388..bda43cdd6a 100644 --- a/test/UnitTests/Builders/ResourceGraphBuilderTests.cs +++ b/test/UnitTests/Builders/ResourceGraphBuilderTests.cs @@ -96,6 +96,7 @@ public void Relationships_Without_Names_Specified_Will_Use_Configured_Formatter( Assert.Equal("relatedResources", resource.Relationships.Single(r => !(r is HasOneAttribute)).PublicName); } + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class TestResource : Identifiable { [Attr] diff --git a/test/UnitTests/Controllers/BaseJsonApiControllerTests.cs b/test/UnitTests/Controllers/BaseJsonApiControllerTests.cs index 3a4dd66e27..5764bffef3 100644 --- a/test/UnitTests/Controllers/BaseJsonApiControllerTests.cs +++ b/test/UnitTests/Controllers/BaseJsonApiControllerTests.cs @@ -2,6 +2,7 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers; using JsonApiDotNetCore.Errors; @@ -19,6 +20,7 @@ namespace UnitTests.Controllers { public sealed class BaseJsonApiControllerTests { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Resource : Identifiable { [Attr] public string TestAttribute { get; set; } diff --git a/test/UnitTests/Models/ResourceWithStringConstructor.cs b/test/UnitTests/Models/ResourceWithStringConstructor.cs index 8714e3f05f..51371b18ff 100644 --- a/test/UnitTests/Models/ResourceWithStringConstructor.cs +++ b/test/UnitTests/Models/ResourceWithStringConstructor.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore; using JsonApiDotNetCore.Resources; namespace UnitTests.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ResourceWithStringConstructor : Identifiable { public string Text { get; } diff --git a/test/UnitTests/Models/ResourceWithThrowingConstructor.cs b/test/UnitTests/Models/ResourceWithThrowingConstructor.cs index fd319c0a0d..753d1fb80e 100644 --- a/test/UnitTests/Models/ResourceWithThrowingConstructor.cs +++ b/test/UnitTests/Models/ResourceWithThrowingConstructor.cs @@ -1,8 +1,10 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; namespace UnitTests.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ResourceWithThrowingConstructor : Identifiable { public ResourceWithThrowingConstructor() diff --git a/test/UnitTests/ResourceHooks/Dummy.cs b/test/UnitTests/ResourceHooks/Dummy.cs index 9d84c065ab..821fdb2bbc 100644 --- a/test/UnitTests/ResourceHooks/Dummy.cs +++ b/test/UnitTests/ResourceHooks/Dummy.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.ResourceHooks { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Dummy : Identifiable { public string SomeUpdatedProperty { get; set; } @@ -16,4 +18,4 @@ public sealed class Dummy : Identifiable [HasMany] public ISet ToManies { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/Article.cs b/test/UnitTests/TestModels/Article.cs index 5690be73ed..0731286f59 100644 --- a/test/UnitTests/TestModels/Article.cs +++ b/test/UnitTests/TestModels/Article.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Article : Identifiable { [Attr] public string Title { get; set; } diff --git a/test/UnitTests/TestModels/Blog.cs b/test/UnitTests/TestModels/Blog.cs index 8ff9b974a7..fcc61891b8 100644 --- a/test/UnitTests/TestModels/Blog.cs +++ b/test/UnitTests/TestModels/Blog.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Blog : Identifiable { [Attr] public string Title { get; set; } diff --git a/test/UnitTests/TestModels/FirstDerivedModel.cs b/test/UnitTests/TestModels/FirstDerivedModel.cs index efeca5cf35..b381cf0857 100644 --- a/test/UnitTests/TestModels/FirstDerivedModel.cs +++ b/test/UnitTests/TestModels/FirstDerivedModel.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class FirstDerivedModel : BaseModel { [Attr] public bool FirstProperty { get; set; } diff --git a/test/UnitTests/TestModels/Food.cs b/test/UnitTests/TestModels/Food.cs index 49f01c658b..81e08dd055 100644 --- a/test/UnitTests/TestModels/Food.cs +++ b/test/UnitTests/TestModels/Food.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Food : Identifiable { [Attr] public string Dish { get; set; } diff --git a/test/UnitTests/TestModels/IdentifiableWithAttribute.cs b/test/UnitTests/TestModels/IdentifiableWithAttribute.cs index 50ff8ec777..a46fa1e9b3 100644 --- a/test/UnitTests/TestModels/IdentifiableWithAttribute.cs +++ b/test/UnitTests/TestModels/IdentifiableWithAttribute.cs @@ -1,10 +1,12 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public class IdentifiableWithAttribute : Identifiable { [Attr] public string AttributeMember { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/MultipleRelationshipsDependentPart.cs b/test/UnitTests/TestModels/MultipleRelationshipsDependentPart.cs index 75ed16107d..0d2ef40933 100644 --- a/test/UnitTests/TestModels/MultipleRelationshipsDependentPart.cs +++ b/test/UnitTests/TestModels/MultipleRelationshipsDependentPart.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class MultipleRelationshipsDependentPart : IdentifiableWithAttribute { [HasOne] public OneToOnePrincipal PopulatedToOne { get; set; } diff --git a/test/UnitTests/TestModels/MultipleRelationshipsPrincipalPart.cs b/test/UnitTests/TestModels/MultipleRelationshipsPrincipalPart.cs index 6e2a640411..0374ba1971 100644 --- a/test/UnitTests/TestModels/MultipleRelationshipsPrincipalPart.cs +++ b/test/UnitTests/TestModels/MultipleRelationshipsPrincipalPart.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class MultipleRelationshipsPrincipalPart : IdentifiableWithAttribute { [HasOne] public OneToOneDependent PopulatedToOne { get; set; } @@ -11,4 +13,4 @@ public sealed class MultipleRelationshipsPrincipalPart : IdentifiableWithAttribu [HasMany] public ISet EmptyToManies { get; set; } [HasOne] public MultipleRelationshipsPrincipalPart Multi { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/OneToManyDependent.cs b/test/UnitTests/TestModels/OneToManyDependent.cs index c6f87fea67..32ac04e77e 100644 --- a/test/UnitTests/TestModels/OneToManyDependent.cs +++ b/test/UnitTests/TestModels/OneToManyDependent.cs @@ -1,10 +1,12 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class OneToManyDependent : IdentifiableWithAttribute { [HasOne] public OneToManyPrincipal Principal { get; set; } public int? PrincipalId { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/OneToManyPrincipal.cs b/test/UnitTests/TestModels/OneToManyPrincipal.cs index eea9d19ec9..39e0bd931b 100644 --- a/test/UnitTests/TestModels/OneToManyPrincipal.cs +++ b/test/UnitTests/TestModels/OneToManyPrincipal.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class OneToManyPrincipal : IdentifiableWithAttribute { [HasMany] public ISet Dependents { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/OneToManyRequiredDependent.cs b/test/UnitTests/TestModels/OneToManyRequiredDependent.cs index 4008d76eba..89491b8065 100644 --- a/test/UnitTests/TestModels/OneToManyRequiredDependent.cs +++ b/test/UnitTests/TestModels/OneToManyRequiredDependent.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class OneToManyRequiredDependent : IdentifiableWithAttribute { [HasOne] public OneToManyPrincipal Principal { get; set; } diff --git a/test/UnitTests/TestModels/OneToOneDependent.cs b/test/UnitTests/TestModels/OneToOneDependent.cs index e88ed3a852..7a8b0d34f7 100644 --- a/test/UnitTests/TestModels/OneToOneDependent.cs +++ b/test/UnitTests/TestModels/OneToOneDependent.cs @@ -1,10 +1,12 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class OneToOneDependent : IdentifiableWithAttribute { [HasOne] public OneToOnePrincipal Principal { get; set; } public int? PrincipalId { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/OneToOnePrincipal.cs b/test/UnitTests/TestModels/OneToOnePrincipal.cs index a3a183b4c7..b5678a0e69 100644 --- a/test/UnitTests/TestModels/OneToOnePrincipal.cs +++ b/test/UnitTests/TestModels/OneToOnePrincipal.cs @@ -1,9 +1,11 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class OneToOnePrincipal : IdentifiableWithAttribute { [HasOne] public OneToOneDependent Dependent { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/OneToOneRequiredDependent.cs b/test/UnitTests/TestModels/OneToOneRequiredDependent.cs index 463b3e80a1..2c4672ef82 100644 --- a/test/UnitTests/TestModels/OneToOneRequiredDependent.cs +++ b/test/UnitTests/TestModels/OneToOneRequiredDependent.cs @@ -1,10 +1,12 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class OneToOneRequiredDependent : IdentifiableWithAttribute { [HasOne] public OneToOnePrincipal Principal { get; set; } public int PrincipalId { get; set; } } -} \ No newline at end of file +} diff --git a/test/UnitTests/TestModels/Person.cs b/test/UnitTests/TestModels/Person.cs index 48b4396336..58f616ccdd 100644 --- a/test/UnitTests/TestModels/Person.cs +++ b/test/UnitTests/TestModels/Person.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Person : Identifiable { [Attr] public string Name { get; set; } diff --git a/test/UnitTests/TestModels/SecondDerivedModel.cs b/test/UnitTests/TestModels/SecondDerivedModel.cs index 82d8d74fb9..3f04f9d7ee 100644 --- a/test/UnitTests/TestModels/SecondDerivedModel.cs +++ b/test/UnitTests/TestModels/SecondDerivedModel.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class SecondDerivedModel : BaseModel { [Attr] public bool SecondProperty { get; set; } diff --git a/test/UnitTests/TestModels/Song.cs b/test/UnitTests/TestModels/Song.cs index e1e5aa8928..ea7cd5f78d 100644 --- a/test/UnitTests/TestModels/Song.cs +++ b/test/UnitTests/TestModels/Song.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class Song : Identifiable { [Attr] public string Title { get; set; } diff --git a/test/UnitTests/TestModels/TestResource.cs b/test/UnitTests/TestModels/TestResource.cs index bc7922997f..f5d8f9b90d 100644 --- a/test/UnitTests/TestModels/TestResource.cs +++ b/test/UnitTests/TestModels/TestResource.cs @@ -1,9 +1,11 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class TestResource : Identifiable { [Attr] public string StringField { get; set; } diff --git a/test/UnitTests/TestModels/TestResourceWithAbstractRelationship.cs b/test/UnitTests/TestModels/TestResourceWithAbstractRelationship.cs index 5a3561605c..f7db45eb51 100644 --- a/test/UnitTests/TestModels/TestResourceWithAbstractRelationship.cs +++ b/test/UnitTests/TestModels/TestResourceWithAbstractRelationship.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class TestResourceWithAbstractRelationship : Identifiable { [HasOne] public BaseModel ToOne { get; set; } diff --git a/test/UnitTests/TestModels/TestResourceWithList.cs b/test/UnitTests/TestModels/TestResourceWithList.cs index 55dcee7610..e9995208d5 100644 --- a/test/UnitTests/TestModels/TestResourceWithList.cs +++ b/test/UnitTests/TestModels/TestResourceWithList.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class TestResourceWithList : Identifiable { [Attr] public List ComplexFields { get; set; } From 3fdcf8588037bb77cbd95713fe2a549a1c699c34 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 24 Feb 2021 16:29:24 +0100 Subject: [PATCH 40/60] Use discard in empty property setters --- .../IntegrationTests/AtomicOperations/TextLanguage.cs | 2 +- .../IntegrationTests/ReadWrite/WorkItem.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/TextLanguage.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/TextLanguage.cs index 7942ebc5ed..be25c89b7d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/TextLanguage.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/TextLanguage.cs @@ -18,7 +18,7 @@ public sealed class TextLanguage : Identifiable public Guid ConcurrencyToken { get => Guid.NewGuid(); - set { } + set => _ = value; } [HasMany] diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItem.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItem.cs index c667e45f5a..1136e1c98b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItem.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItem.cs @@ -24,7 +24,7 @@ public sealed class WorkItem : Identifiable public Guid ConcurrencyToken { get => Guid.NewGuid(); - set { } + set => _ = value; } [HasOne] From af9738d31f8b1f6bc170ef8fb79bd00208791b0b Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 24 Feb 2021 16:50:19 +0100 Subject: [PATCH 41/60] Added missing setter --- src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs b/src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs index fe409cef5d..7cf6866550 100644 --- a/src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs +++ b/src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs @@ -72,7 +72,7 @@ public sealed class JsonApiOptions : IJsonApiOptions public int? MaximumOperationsPerRequest { get; set; } = 10; /// - public IsolationLevel? TransactionIsolationLevel { get; } + public IsolationLevel? TransactionIsolationLevel { get; set; } /// public JsonSerializerSettings SerializerSettings { get; } = new JsonSerializerSettings From 3b66bf75a28369e63395809d9fb28096d2592a1a Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 24 Feb 2021 17:34:17 +0100 Subject: [PATCH 42/60] Addressed possible NullReferenceException warnings --- .../Configuration/IJsonApiOptions.cs | 9 ++++++- .../Configuration/JsonApiOptions.cs | 4 +++- .../Configuration/ResourceGraphBuilder.cs | 4 ++-- .../Configuration/ResourceNameFormatter.cs | 4 ++-- .../Controllers/BaseJsonApiController.cs | 6 ++--- .../BaseJsonApiOperationsController.cs | 3 +-- .../Internal/Discovery/HooksDiscovery.cs | 2 +- .../Internal/Execution/HookExecutorHelper.cs | 2 +- .../Hooks/Internal/ResourceHookExecutor.cs | 4 ++-- .../Internal/Traversal/RelationshipProxy.cs | 2 +- .../Internal/Traversal/TraversalHelper.cs | 2 +- .../Middleware/JsonApiRoutingConvention.cs | 4 +--- .../QueryableBuilding/WhereClauseBuilder.cs | 2 +- .../Serialization/Building/MetaBuilder.cs | 3 +-- .../Client/Internal/ResponseDeserializer.cs | 24 +++++++++++-------- .../KebabCasingConventionStartup.cs | 6 +++-- .../Resources/UpdateToOneRelationshipTests.cs | 2 +- .../RelationshipDictionaryTests.cs | 2 +- 18 files changed, 47 insertions(+), 38 deletions(-) diff --git a/src/JsonApiDotNetCore/Configuration/IJsonApiOptions.cs b/src/JsonApiDotNetCore/Configuration/IJsonApiOptions.cs index b12fd6c497..ab46a78af2 100644 --- a/src/JsonApiDotNetCore/Configuration/IJsonApiOptions.cs +++ b/src/JsonApiDotNetCore/Configuration/IJsonApiOptions.cs @@ -187,6 +187,13 @@ public interface IJsonApiOptions /// JsonSerializerSettings SerializerSettings { get; } - internal DefaultContractResolver SerializerContractResolver => (DefaultContractResolver) SerializerSettings.ContractResolver; + internal NamingStrategy SerializerNamingStrategy + { + get + { + var contractResolver = SerializerSettings.ContractResolver as DefaultContractResolver; + return contractResolver?.NamingStrategy ?? JsonApiOptions.DefaultNamingStrategy; + } + } } } diff --git a/src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs b/src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs index 7cf6866550..85b07ba8f6 100644 --- a/src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs +++ b/src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs @@ -8,6 +8,8 @@ namespace JsonApiDotNetCore.Configuration /// public sealed class JsonApiOptions : IJsonApiOptions { + internal static readonly NamingStrategy DefaultNamingStrategy = new CamelCaseNamingStrategy(); + /// public string Namespace { get; set; } @@ -79,7 +81,7 @@ public sealed class JsonApiOptions : IJsonApiOptions { ContractResolver = new DefaultContractResolver { - NamingStrategy = new CamelCaseNamingStrategy() + NamingStrategy = DefaultNamingStrategy } }; diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs index fbf4d75f57..22ffd4a713 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs @@ -305,13 +305,13 @@ private Type TypeOrElementType(Type type) private string FormatResourceName(Type resourceType) { - var formatter = new ResourceNameFormatter(_options); + var formatter = new ResourceNameFormatter(_options.SerializerNamingStrategy); return formatter.FormatResourceName(resourceType); } private string FormatPropertyName(PropertyInfo resourceProperty) { - return _options.SerializerContractResolver.NamingStrategy.GetPropertyName(resourceProperty.Name, false); + return _options.SerializerNamingStrategy.GetPropertyName(resourceProperty.Name, false); } } } diff --git a/src/JsonApiDotNetCore/Configuration/ResourceNameFormatter.cs b/src/JsonApiDotNetCore/Configuration/ResourceNameFormatter.cs index 85bf857a9a..70963bb1a3 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceNameFormatter.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceNameFormatter.cs @@ -10,9 +10,9 @@ internal sealed class ResourceNameFormatter { private readonly NamingStrategy _namingStrategy; - public ResourceNameFormatter(IJsonApiOptions options) + public ResourceNameFormatter(NamingStrategy namingStrategy) { - _namingStrategy = options.SerializerContractResolver.NamingStrategy; + _namingStrategy = namingStrategy; } /// diff --git a/src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs b/src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs index ebed4f6beb..1d5640db00 100644 --- a/src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs +++ b/src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs @@ -189,8 +189,7 @@ public virtual async Task PostAsync([FromBody] TResource resource if (_options.ValidateModelState && !ModelState.IsValid) { - var namingStrategy = _options.SerializerContractResolver.NamingStrategy; - throw new InvalidModelStateException(ModelState, typeof(TResource), _options.IncludeExceptionStackTraceInErrors, namingStrategy); + throw new InvalidModelStateException(ModelState, typeof(TResource), _options.IncludeExceptionStackTraceInErrors, _options.SerializerNamingStrategy); } var newResource = await _create.CreateAsync(resource, cancellationToken); @@ -250,8 +249,7 @@ public virtual async Task PatchAsync(TId id, [FromBody] TResource if (_options.ValidateModelState && !ModelState.IsValid) { - var namingStrategy = _options.SerializerContractResolver.NamingStrategy; - throw new InvalidModelStateException(ModelState, typeof(TResource), _options.IncludeExceptionStackTraceInErrors, namingStrategy); + throw new InvalidModelStateException(ModelState, typeof(TResource), _options.IncludeExceptionStackTraceInErrors, _options.SerializerNamingStrategy); } var updated = await _update.UpdateAsync(id, resource, cancellationToken); diff --git a/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs b/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs index 3470c2155e..66c7a185c6 100644 --- a/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs +++ b/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs @@ -171,8 +171,7 @@ protected virtual void ValidateModelState(IEnumerable operat if (violations.Any()) { - var namingStrategy = _options.SerializerContractResolver.NamingStrategy; - throw new InvalidModelStateException(violations, _options.IncludeExceptionStackTraceInErrors, namingStrategy); + throw new InvalidModelStateException(violations, _options.IncludeExceptionStackTraceInErrors, _options.SerializerNamingStrategy); } } } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs index c09045cbc3..b682df3596 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs @@ -61,7 +61,7 @@ private void DiscoverImplementedHooks(Type containerType) foreach (var hook in _allHooks) { var method = containerType.GetMethod(hook.ToString("G")); - if (method.DeclaringType == _boundResourceDefinitionType) + if (method == null || method.DeclaringType == _boundResourceDefinitionType) { continue; } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs index 0e4cc4924a..f3e8269a3a 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs @@ -87,7 +87,7 @@ public IEnumerable LoadDbValues(LeftType resourceTypeForRepository, IEnumerable { var idType = TypeHelper.GetIdType(resourceTypeForRepository); var parameterizedGetWhere = GetType() - .GetMethod(nameof(GetWhereAndInclude), BindingFlags.NonPublic | BindingFlags.Instance) + .GetMethod(nameof(GetWhereAndInclude), BindingFlags.NonPublic | BindingFlags.Instance)! .MakeGenericMethod(resourceTypeForRepository, idType); var cast = ((IEnumerable)resources).Cast(); var ids = TypeHelper.CopyToList(cast.Select(i => i.GetTypedId()), idType); diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs index cbfa1837ee..586b73f3e9 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs @@ -419,7 +419,7 @@ private IEnumerable CallHook(IResourceHookContainer container, ResourceHook hook // note that some of the hooks return "void". When these hooks, the // are called reflectively with Invoke like here, the return value // is just null, so we don't have to worry about casting issues here. - return (IEnumerable)ThrowJsonApiExceptionOnError(() => method.Invoke(container, arguments)); + return (IEnumerable)ThrowJsonApiExceptionOnError(() => method?.Invoke(container, arguments)); } /// @@ -431,7 +431,7 @@ private object ThrowJsonApiExceptionOnError(Func action) { return action(); } - catch (TargetInvocationException tie) + catch (TargetInvocationException tie) when (tie.InnerException != null) { throw tie.InnerException; } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs index 6b6a6aa391..6addbf1701 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs @@ -105,7 +105,7 @@ public void SetValue(IIdentifiable resource, object value) var filteredList = new List(); var rightResources = TypeHelper.CopyToList((IEnumerable)value, RightType); - foreach (var throughResource in throughResources) + foreach (var throughResource in throughResources ?? Array.Empty()) { if (rightResources.Contains(hasManyThrough.RightProperty.GetValue(throughResource))) { diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs index 7f4c5e7395..c8dd98d0a9 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs @@ -170,7 +170,7 @@ private Dictionary(list)); + processResourcesMethod!.MakeGenericMethod(type).Invoke(this, ArrayFactory.Create(list)); } return (leftResourcesGrouped, rightResourcesGrouped); diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs b/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs index dfb0057ea1..c8538c4fe4 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs @@ -124,9 +124,7 @@ private string TemplateFromResource(ControllerModel model) /// private string TemplateFromController(ControllerModel model) { - string controllerName = - _options.SerializerContractResolver.NamingStrategy.GetPropertyName(model.ControllerName, false); - + string controllerName = _options.SerializerNamingStrategy.GetPropertyName(model.ControllerName, false); var template = $"{_options.Namespace}/{controllerName}"; if (_registeredTemplates.Add(template)) diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs index 073c3bc0e9..f0e985e9ff 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs @@ -96,7 +96,7 @@ public override Expression VisitEqualsAnyOf(EqualsAnyOfExpression expression, Ty foreach (LiteralConstantExpression constant in expression.Constants) { object value = ConvertTextToTargetType(constant.Value, property.Type); - valueList.Add(value); + valueList!.Add(value); } ConstantExpression collection = Expression.Constant(valueList); diff --git a/src/JsonApiDotNetCore/Serialization/Building/MetaBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/MetaBuilder.cs index 8fd323adc4..2b3cef07cc 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/MetaBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/MetaBuilder.cs @@ -40,8 +40,7 @@ public IDictionary Build() { if (_paginationContext.TotalResourceCount != null) { - var namingStrategy = _options.SerializerContractResolver.NamingStrategy; - string key = namingStrategy.GetPropertyName("TotalResources", false); + string key = _options.SerializerNamingStrategy.GetPropertyName("TotalResources", false); _meta.Add(key, _paginationContext.TotalResourceCount); } diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs index 201e2681c4..fda86b3437 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs @@ -72,17 +72,21 @@ protected override void AfterProcessField(IIdentifiable resource, ResourceFieldA return; } - if (field is HasOneAttribute hasOneAttr) + if (data != null) { - // add attributes and relationships of a parsed HasOne relationship - var rio = data.SingleData; - hasOneAttr.SetValue(resource, rio == null ? null : ParseIncludedRelationship(rio)); - } - else if (field is HasManyAttribute hasManyAttr) - { // add attributes and relationships of a parsed HasMany relationship - var items = data.ManyData.Select(ParseIncludedRelationship); - var values = TypeHelper.CopyToTypedCollection(items, hasManyAttr.Property.PropertyType); - hasManyAttr.SetValue(resource, values); + if (field is HasOneAttribute hasOneAttr) + { + // add attributes and relationships of a parsed HasOne relationship + var rio = data.SingleData; + hasOneAttr.SetValue(resource, rio == null ? null : ParseIncludedRelationship(rio)); + } + else if (field is HasManyAttribute hasManyAttr) + { + // add attributes and relationships of a parsed HasMany relationship + var items = data.ManyData.Select(ParseIncludedRelationship); + var values = TypeHelper.CopyToTypedCollection(items, hasManyAttr.Property.PropertyType); + hasManyAttr.SetValue(resource, values); + } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs index bc02d82085..bec80d91e5 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs @@ -24,8 +24,10 @@ protected override void SetJsonApiOptions(JsonApiOptions options) options.IncludeTotalResourceCount = true; options.ValidateModelState = true; - var resolver = (DefaultContractResolver) options.SerializerSettings.ContractResolver; - resolver!.NamingStrategy = new KebabCaseNamingStrategy(); + options.SerializerSettings.ContractResolver = new DefaultContractResolver + { + NamingStrategy = new KebabCaseNamingStrategy() + }; } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs index 8d461c2c0f..8176376fee 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs @@ -196,7 +196,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => var colorInDatabase2 = colorsInDatabase.SingleOrDefault(color => color.Id == existingGroups[1].Color.Id); colorInDatabase2.Should().NotBeNull(); - colorInDatabase2.Group.Should().BeNull(); + colorInDatabase2!.Group.Should().BeNull(); }); } diff --git a/test/UnitTests/ResourceHooks/RelationshipDictionaryTests.cs b/test/UnitTests/ResourceHooks/RelationshipDictionaryTests.cs index 595cf03b2d..4612b864a3 100644 --- a/test/UnitTests/ResourceHooks/RelationshipDictionaryTests.cs +++ b/test/UnitTests/ResourceHooks/RelationshipDictionaryTests.cs @@ -177,7 +177,7 @@ public void ResourceDiff_GetAffected_Attributes() var dbResources = new HashSet(_allResources.Select(e => new Dummy { Id = e.Id })); var updatedAttributes = new Dictionary> { - { typeof(Dummy).GetProperty("SomeUpdatedProperty"), _allResources } + { typeof(Dummy).GetProperty(nameof(Dummy.SomeUpdatedProperty))!, _allResources } }; DiffableResourceHashSet diffs = new DiffableResourceHashSet(_allResources, dbResources, _relationships, updatedAttributes); From 874ee0f34e91c43c69d0e0e194a3be752929c08d Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 24 Feb 2021 17:49:24 +0100 Subject: [PATCH 43/60] Marked assertion methods as such, to suppress warning 'parameter is only used for precondition checks' Note that one suppression is needed, due to a bug in Resharper --- .../Configuration/ResourceGraphBuilder.cs | 1 + .../Hooks/Internal/ResourceHookExecutor.cs | 2 ++ .../Internal/PaginationQueryStringParameterReader.cs | 2 ++ src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs | 3 +++ src/JsonApiDotNetCore/Serialization/JsonApiReader.cs | 3 +++ .../Serialization/RequestDeserializer.cs | 3 +++ src/JsonApiDotNetCore/Services/JsonApiResourceService.cs | 3 +++ .../ResourceHooks/RelationshipDictionaryTests.cs | 8 +++++--- 8 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs index 22ffd4a713..b21d468afd 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs @@ -267,6 +267,7 @@ private Type GetRelationshipType(RelationshipAttribute relationship, PropertyInf return relationship is HasOneAttribute ? property.PropertyType : property.PropertyType.GetGenericArguments()[0]; } + // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local private IReadOnlyCollection GetEagerLoads(Type resourceType, int recursionDepth = 0) { if (recursionDepth >= 500) diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs index 586b73f3e9..003965fdf7 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Hooks.Internal.Execution; using JsonApiDotNetCore.Hooks.Internal.Traversal; @@ -401,6 +402,7 @@ private void FireForAffectedImplicits(Type resourceTypeToInclude, Dictionary /// The collection returned from the hook /// The pipeline from which the hook was fired + [AssertionMethod] private void ValidateHookResponse(IEnumerable returnedList, ResourcePipeline pipeline = 0) { if (pipeline == ResourcePipeline.GetSingle && returnedList.Count() > 1) diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/PaginationQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/PaginationQueryStringParameterReader.cs index c30bc66f6b..1b62d0b86c 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/PaginationQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/PaginationQueryStringParameterReader.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers.Annotations; using JsonApiDotNetCore.Errors; @@ -102,6 +103,7 @@ protected virtual void ValidatePageSize(PaginationQueryStringValueExpression con } } + [AssertionMethod] protected virtual void ValidatePageNumber(PaginationQueryStringValueExpression constraint) { if (_options.MaximumPageNumber != null && diff --git a/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs b/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs index 26d4d096e3..d24bb4fb9b 100644 --- a/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs +++ b/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; @@ -260,6 +261,7 @@ private IIdentifiable CreateRightResource(RelationshipAttribute relationship, return null; } + [AssertionMethod] private void AssertHasType(ResourceIdentifierObject resourceIdentifierObject, RelationshipAttribute relationship) { if (resourceIdentifierObject.Type == null) @@ -300,6 +302,7 @@ private void AssertHasIdOrLid(ResourceIdentifierObject resourceIdentifierObject, } } + [AssertionMethod] private void AssertHasNoLid(ResourceIdentifierObject resourceIdentifierObject) { if (resourceIdentifierObject.Lid != null) diff --git a/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs b/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs index e816e6f035..7e2eed758c 100644 --- a/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs +++ b/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs @@ -6,6 +6,7 @@ using System.Net; using System.Net.Http; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Middleware; @@ -138,6 +139,7 @@ private void ValidateRequestBody(object model, string body, HttpRequest httpRequ } } + [AssertionMethod] private static void AssertHasRequestBody(object model, string body) { if (model == null && string.IsNullOrWhiteSpace(body)) @@ -244,6 +246,7 @@ private static bool TryGetId(object model, out string id) return false; } + [AssertionMethod] private void ValidateForRelationshipType(string requestMethod, object model, string body) { if (_request.Relationship is HasOneAttribute) diff --git a/src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs b/src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs index ff90e89bfd..b53be1e7e6 100644 --- a/src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs +++ b/src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Net.Http; using Humanizer; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.Resources; @@ -122,6 +123,7 @@ private OperationContainer DeserializeOperation(AtomicOperationObject operation) return ParseForRelationshipOperation(operation, kind, requireToManyRelationship); } + [AssertionMethod] private void AssertHasNoHref(AtomicOperationObject operation) { if (operation.Href != null) @@ -243,6 +245,7 @@ private ResourceObject GetRequiredSingleDataForResourceOperation(AtomicOperation return operation.SingleData; } + [AssertionMethod] private void AssertElementHasType(ResourceIdentifierObject resourceIdentifierObject, string elementPath) { if (resourceIdentifierObject.Type == null) diff --git a/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs b/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs index f498579d56..bf2fbca932 100644 --- a/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs +++ b/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs @@ -5,6 +5,7 @@ using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Hooks; @@ -446,6 +447,7 @@ private async Task GetPrimaryResourceForUpdateAsync(TId id, Cancellat return resource; } + [AssertionMethod] private void AssertPrimaryResourceExists(TResource resource) { if (resource == null) @@ -454,6 +456,7 @@ private void AssertPrimaryResourceExists(TResource resource) } } + [AssertionMethod] private void AssertHasRelationship(RelationshipAttribute relationship, string name) { if (relationship == null) diff --git a/test/UnitTests/ResourceHooks/RelationshipDictionaryTests.cs b/test/UnitTests/ResourceHooks/RelationshipDictionaryTests.cs index 4612b864a3..732899dff7 100644 --- a/test/UnitTests/ResourceHooks/RelationshipDictionaryTests.cs +++ b/test/UnitTests/ResourceHooks/RelationshipDictionaryTests.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using JetBrains.Annotations; using JsonApiDotNetCore.Hooks.Internal.Execution; using JsonApiDotNetCore.Resources.Annotations; using Xunit; @@ -190,10 +191,11 @@ public void ResourceDiff_GetAffected_Attributes() Assert.Empty(affectedThroughSomeNotUpdatedProperty); } + [AssertionMethod] private void AssertRelationshipDictionaryGetters(Dictionary> relationshipsDictionary, - Dictionary> toOnes, - Dictionary> toManies, - Dictionary> notTargeted) + Dictionary> toOnes, + Dictionary> toManies, + Dictionary> notTargeted) { Assert.Contains(_firstToOneAttr, toOnes.Keys); Assert.Contains(_secondToOneAttr, toOnes.Keys); From d0b3114f2a2c0d52dcb8d9c58a259b34ffedbe4e Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 24 Feb 2021 18:14:50 +0100 Subject: [PATCH 44/60] Addressed possible multiple enumeration warnings --- .../Hooks/Internal/Execution/HookExecutorHelper.cs | 6 ++++-- .../Hooks/Internal/ResourceHookExecutor.cs | 2 ++ .../Hooks/Internal/Traversal/TraversalHelper.cs | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs index f3e8269a3a..d2108411ba 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs @@ -202,6 +202,8 @@ public Dictionary LoadImplicitlyAffected( Dictionary leftResourcesByRelation, IEnumerable existingRightResources = null) { + var existingRightResourceList = existingRightResources?.Cast().ToList(); + var implicitlyAffected = new Dictionary(); foreach (var kvp in leftResourcesByRelation) { @@ -233,9 +235,9 @@ public Dictionary LoadImplicitlyAffected( } var dbRightResourceListCast = dbRightResourceList.Cast().ToList(); - if (existingRightResources != null) + if (existingRightResourceList != null) { - dbRightResourceListCast = dbRightResourceListCast.Except(existingRightResources.Cast(), _comparer).ToList(); + dbRightResourceListCast = dbRightResourceListCast.Except(existingRightResourceList, _comparer).ToList(); } if (dbRightResourceListCast.Any()) diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs index 003965fdf7..c15bd16a11 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs @@ -14,6 +14,8 @@ using LeftType = System.Type; using RightType = System.Type; +// ReSharper disable PossibleMultipleEnumeration + namespace JsonApiDotNetCore.Hooks.Internal { /// diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs index c8dd98d0a9..295e9d8c22 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs @@ -309,7 +309,8 @@ private IResourceNode CreateNodeInstance(RightType nodeType, RelationshipProxy[] /// private IRelationshipsFromPreviousLayer CreateRelationshipsFromInstance(RightType nodeType, IEnumerable relationshipsFromPrev) { - var cast = TypeHelper.CopyToList(relationshipsFromPrev, relationshipsFromPrev.First().GetType()); + var relationshipsFromPrevList = relationshipsFromPrev.ToList(); + var cast = TypeHelper.CopyToList(relationshipsFromPrevList, relationshipsFromPrevList.First().GetType()); return (IRelationshipsFromPreviousLayer)TypeHelper.CreateInstanceOfOpenType(typeof(RelationshipsFromPreviousLayer<>), nodeType, cast); } From ea9b2e54125ba641feeb09015a7a6173b3613e22 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Thu, 25 Feb 2021 11:07:12 +0100 Subject: [PATCH 45/60] Suppressed warnings on non-readonly member access in GetHashCode, because these are assigned once at application startup by the resource graph builder and then are considered immutable. --- .../Resources/Annotations/HasManyThroughAttribute.cs | 2 ++ .../Resources/Annotations/RelationshipAttribute.cs | 2 ++ .../Resources/Annotations/ResourceFieldAttribute.cs | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/JsonApiDotNetCore/Resources/Annotations/HasManyThroughAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/HasManyThroughAttribute.cs index eab79390f9..a245fee0fd 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/HasManyThroughAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/HasManyThroughAttribute.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Reflection; +// ReSharper disable NonReadonlyMemberInGetHashCode + namespace JsonApiDotNetCore.Resources.Annotations { /// diff --git a/src/JsonApiDotNetCore/Resources/Annotations/RelationshipAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/RelationshipAttribute.cs index 2cdab2a99f..9003c25706 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/RelationshipAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/RelationshipAttribute.cs @@ -2,6 +2,8 @@ using System.Reflection; using JsonApiDotNetCore.Configuration; +// ReSharper disable NonReadonlyMemberInGetHashCode + namespace JsonApiDotNetCore.Resources.Annotations { /// diff --git a/src/JsonApiDotNetCore/Resources/Annotations/ResourceFieldAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/ResourceFieldAttribute.cs index 04c4f67ba8..725be216b7 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/ResourceFieldAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/ResourceFieldAttribute.cs @@ -1,6 +1,8 @@ using System; using System.Reflection; +// ReSharper disable NonReadonlyMemberInGetHashCode + namespace JsonApiDotNetCore.Resources.Annotations { /// From 379dbcfcbbcfe7ecd1eaddd79a9d6aa1863aa292 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Thu, 25 Feb 2021 11:27:13 +0100 Subject: [PATCH 46/60] extra: UsedImplicitly on models --- src/Examples/ReportsExample/Models/ReportStatistics.cs | 3 +++ .../IntegrationTests/QueryStrings/LabelColor.cs | 3 +++ .../IntegrationTests/ReadWrite/WorkItemPriority.cs | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/Examples/ReportsExample/Models/ReportStatistics.cs b/src/Examples/ReportsExample/Models/ReportStatistics.cs index 85b1ffdf1f..53c2c2d2ee 100644 --- a/src/Examples/ReportsExample/Models/ReportStatistics.cs +++ b/src/Examples/ReportsExample/Models/ReportStatistics.cs @@ -1,5 +1,8 @@ +using JetBrains.Annotations; + namespace ReportsExample.Models { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ReportStatistics { public string ProgressIndication { get; set; } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/LabelColor.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/LabelColor.cs index 0f9f971eca..62a35c09d2 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/LabelColor.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/QueryStrings/LabelColor.cs @@ -1,5 +1,8 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.QueryStrings { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public enum LabelColor { Red, diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemPriority.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemPriority.cs index baa810f7c0..4ee4e283e5 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemPriority.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ReadWrite/WorkItemPriority.cs @@ -1,5 +1,8 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ReadWrite { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public enum WorkItemPriority { Low, From 2a3274d333c236a17dced4e67283321908803e59 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Thu, 25 Feb 2021 13:13:02 +0100 Subject: [PATCH 47/60] Added [PublicAPI] on exposed types to suppress warnings like 'type/member can be made internal', 'type has no inheritors and can be marked sealed', 'member is never written to' etc. --- .../AtomicOperations/EntityFrameworkCoreTransaction.cs | 2 ++ .../AtomicOperations/IOperationsTransaction.cs | 2 ++ src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs | 2 ++ .../AtomicOperations/OperationProcessorAccessor.cs | 2 ++ .../AtomicOperations/OperationsProcessor.cs | 2 ++ .../Processors/AddToRelationshipProcessor.cs | 2 ++ .../AtomicOperations/Processors/CreateProcessor.cs | 2 ++ .../AtomicOperations/Processors/DeleteProcessor.cs | 2 ++ .../Processors/IAddToRelationshipProcessor.cs | 2 ++ .../AtomicOperations/Processors/ICreateProcessor.cs | 2 ++ .../AtomicOperations/Processors/IDeleteProcessor.cs | 2 ++ .../Processors/IRemoveFromRelationshipProcessor.cs | 2 ++ .../Processors/ISetRelationshipProcessor.cs | 2 ++ .../AtomicOperations/Processors/IUpdateProcessor.cs | 2 ++ .../Processors/RemoveFromRelationshipProcessor.cs | 2 ++ .../Processors/SetRelationshipProcessor.cs | 2 ++ .../AtomicOperations/Processors/UpdateProcessor.cs | 2 ++ .../Configuration/IGenericServiceFactory.cs | 2 ++ .../Configuration/IInverseNavigationResolver.cs | 2 ++ src/JsonApiDotNetCore/Configuration/IResourceGraph.cs | 2 ++ .../Configuration/InverseNavigationResolver.cs | 2 ++ src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs | 2 ++ src/JsonApiDotNetCore/Configuration/PageNumber.cs | 2 ++ src/JsonApiDotNetCore/Configuration/PageSize.cs | 2 ++ src/JsonApiDotNetCore/Configuration/ResourceContext.cs | 2 ++ src/JsonApiDotNetCore/Configuration/ResourceGraph.cs | 2 ++ .../Configuration/ResourceGraphBuilder.cs | 2 ++ .../Configuration/ServiceCollectionExtensions.cs | 2 ++ .../Configuration/ServiceDiscoveryFacade.cs | 2 ++ .../Controllers/Annotations/DisableQueryStringAttribute.cs | 2 ++ .../Annotations/DisableRoutingConventionAttribute.cs | 2 ++ .../Controllers/Annotations/HttpReadOnlyAttribute.cs | 3 +++ .../Controllers/Annotations/NoHttpDeleteAttribute.cs | 3 +++ .../Controllers/Annotations/NoHttpPatchAttribute.cs | 3 +++ .../Controllers/Annotations/NoHttpPostAttribute.cs | 3 +++ .../Controllers/BaseJsonApiOperationsController.cs | 2 ++ src/JsonApiDotNetCore/Controllers/ModelStateViolation.cs | 2 ++ .../Errors/CannotClearRequiredRelationshipException.cs | 2 ++ .../Errors/InvalidConfigurationException.cs | 2 ++ src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs | 2 ++ src/JsonApiDotNetCore/Errors/InvalidQueryException.cs | 2 ++ .../Errors/InvalidQueryStringParameterException.cs | 2 ++ .../Errors/InvalidRequestBodyException.cs | 2 ++ src/JsonApiDotNetCore/Errors/JsonApiException.cs | 2 ++ .../Errors/MissingResourceInRelationship.cs | 3 +++ .../Errors/MissingTransactionSupportException.cs | 2 ++ .../Errors/NonSharedTransactionException.cs | 2 ++ .../Errors/RelationshipNotFoundException.cs | 2 ++ .../Errors/RequestMethodNotAllowedException.cs | 2 ++ .../Errors/ResourceAlreadyExistsException.cs | 2 ++ .../ResourceIdInCreateResourceNotAllowedException.cs | 2 ++ .../Errors/ResourceIdMismatchException.cs | 2 ++ src/JsonApiDotNetCore/Errors/ResourceNotFoundException.cs | 2 ++ .../Errors/ResourceTypeMismatchException.cs | 2 ++ .../Errors/ResourcesInRelationshipsNotFoundException.cs | 2 ++ .../Errors/ToManyRelationshipRequiredException.cs | 2 ++ .../Errors/UnsuccessfulActionResultException.cs | 2 ++ .../Hooks/Internal/Discovery/HooksDiscovery.cs | 2 ++ .../Internal/Discovery/LoadDatabaseValuesAttribute.cs | 2 ++ .../Hooks/Internal/Execution/DiffableResourceHashSet.cs | 2 ++ .../Hooks/Internal/Execution/RelationshipsDictionary.cs | 2 ++ .../Hooks/Internal/Execution/ResourceDiffPair.cs | 4 +++- .../Hooks/Internal/Execution/ResourceHashSet.cs | 2 ++ .../Hooks/Internal/Execution/ResourcePipeline.cs | 2 ++ .../Hooks/Internal/Traversal/RelationshipProxy.cs | 2 +- .../Middleware/AsyncJsonApiExceptionFilter.cs | 2 ++ src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs | 2 ++ src/JsonApiDotNetCore/Middleware/HttpContextExtensions.cs | 2 ++ .../Middleware/IAsyncConvertEmptyActionResultFilter.cs | 2 ++ .../Middleware/IAsyncJsonApiExceptionFilter.cs | 2 ++ .../Middleware/IAsyncQueryStringActionFilter.cs | 2 ++ src/JsonApiDotNetCore/Middleware/IJsonApiInputFormatter.cs | 2 ++ .../Middleware/IJsonApiOutputFormatter.cs | 2 ++ .../Middleware/IJsonApiRoutingConvention.cs | 2 ++ src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs | 2 ++ src/JsonApiDotNetCore/Middleware/JsonApiRequest.cs | 2 ++ .../Middleware/JsonApiRoutingConvention.cs | 2 ++ src/JsonApiDotNetCore/Queries/ExpressionInScope.cs | 2 ++ .../Queries/Expressions/CollectionNotEmptyExpression.cs | 2 ++ .../Queries/Expressions/ComparisonExpression.cs | 2 ++ .../Queries/Expressions/CountExpression.cs | 2 ++ .../Queries/Expressions/EqualsAnyOfExpression.cs | 2 ++ .../Queries/Expressions/IncludeElementExpression.cs | 2 ++ .../Queries/Expressions/IncludeExpression.cs | 2 ++ .../Queries/Expressions/LiteralConstantExpression.cs | 3 +++ .../Queries/Expressions/LogicalExpression.cs | 2 ++ .../Queries/Expressions/MatchTextExpression.cs | 2 ++ src/JsonApiDotNetCore/Queries/Expressions/NotExpression.cs | 2 ++ .../Queries/Expressions/NullConstantExpression.cs | 2 ++ .../PaginationElementQueryStringValueExpression.cs | 2 ++ .../Queries/Expressions/PaginationExpression.cs | 2 ++ .../Expressions/PaginationQueryStringValueExpression.cs | 2 ++ .../Queries/Expressions/QueryExpressionRewriter.cs | 2 ++ .../Queries/Expressions/QueryExpressionVisitor.cs | 3 +++ .../Expressions/QueryStringParameterScopeExpression.cs | 2 ++ .../Queries/Expressions/QueryableHandlerExpression.cs | 2 ++ .../Queries/Expressions/ResourceFieldChainExpression.cs | 2 ++ .../Queries/Expressions/SortElementExpression.cs | 2 ++ .../Queries/Expressions/SortExpression.cs | 2 ++ .../Queries/Expressions/SparseFieldSetExpression.cs | 2 ++ .../Expressions/SparseFieldSetExpressionExtensions.cs | 2 ++ .../Queries/Expressions/SparseFieldTableExpression.cs | 2 ++ .../Queries/Internal/Parsing/FilterParser.cs | 2 ++ .../Queries/Internal/Parsing/IncludeParser.cs | 2 ++ src/JsonApiDotNetCore/Queries/Internal/Parsing/Keywords.cs | 3 +++ .../Queries/Internal/Parsing/PaginationParser.cs | 2 ++ .../Queries/Internal/Parsing/QueryExpressionParser.cs | 2 ++ .../Queries/Internal/Parsing/QueryParseException.cs | 2 ++ .../Internal/Parsing/QueryStringParameterScopeParser.cs | 2 ++ .../Queries/Internal/Parsing/QueryTokenizer.cs | 2 ++ .../Queries/Internal/Parsing/ResourceFieldChainResolver.cs | 6 +++--- .../Queries/Internal/Parsing/SortParser.cs | 2 ++ .../Queries/Internal/Parsing/SparseFieldSetParser.cs | 2 ++ .../Queries/Internal/Parsing/SparseFieldTypeParser.cs | 2 ++ src/JsonApiDotNetCore/Queries/Internal/Parsing/Token.cs | 3 +++ .../Queries/Internal/QueryLayerComposer.cs | 2 ++ .../Internal/QueryableBuilding/IncludeClauseBuilder.cs | 2 ++ .../QueryableBuilding/LambdaParameterNameFactory.cs | 2 ++ .../Internal/QueryableBuilding/LambdaParameterNameScope.cs | 2 ++ .../Queries/Internal/QueryableBuilding/LambdaScope.cs | 2 ++ .../Internal/QueryableBuilding/LambdaScopeFactory.cs | 2 ++ .../Internal/QueryableBuilding/OrderClauseBuilder.cs | 2 ++ .../Queries/Internal/QueryableBuilding/QueryableBuilder.cs | 2 ++ .../Internal/QueryableBuilding/SelectClauseBuilder.cs | 2 ++ .../Internal/QueryableBuilding/SkipTakeClauseBuilder.cs | 2 ++ .../Internal/QueryableBuilding/WhereClauseBuilder.cs | 2 ++ .../Queries/Internal/SparseFieldSetCache.cs | 2 ++ src/JsonApiDotNetCore/Queries/QueryLayer.cs | 2 ++ .../QueryStrings/IFilterQueryStringParameterReader.cs | 2 ++ .../QueryStrings/IIncludeQueryStringParameterReader.cs | 2 ++ .../QueryStrings/IPaginationQueryStringParameterReader.cs | 2 ++ .../IResourceDefinitionQueryableParameterReader.cs | 2 ++ .../QueryStrings/ISortQueryStringParameterReader.cs | 2 ++ .../ISparseFieldSetQueryStringParameterReader.cs | 2 ++ .../Internal/DefaultsQueryStringParameterReader.cs | 2 ++ .../Internal/FilterQueryStringParameterReader.cs | 2 ++ .../Internal/IncludeQueryStringParameterReader.cs | 2 ++ .../QueryStrings/Internal/LegacyFilterNotationConverter.cs | 2 ++ .../Internal/NullsQueryStringParameterReader.cs | 2 ++ .../Internal/PaginationQueryStringParameterReader.cs | 1 + .../QueryStrings/Internal/QueryStringReader.cs | 2 ++ .../Internal/ResourceDefinitionQueryableParameterReader.cs | 2 ++ .../Internal/SortQueryStringParameterReader.cs | 2 ++ .../Internal/SparseFieldSetQueryStringParameterReader.cs | 2 ++ .../Repositories/DataStoreUpdateException.cs | 2 ++ src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs | 2 ++ src/JsonApiDotNetCore/Repositories/DbContextResolver.cs | 2 ++ .../Repositories/EntityFrameworkCoreRepository.cs | 5 ++++- .../Repositories/IRepositorySupportsTransaction.cs | 2 ++ .../Repositories/IResourceReadRepository.cs | 2 ++ src/JsonApiDotNetCore/Repositories/IResourceRepository.cs | 2 ++ .../Repositories/IResourceWriteRepository.cs | 2 ++ .../Repositories/MemoryLeakDetectionBugRewriter.cs | 2 ++ .../Repositories/PlaceholderResourceCollector.cs | 2 ++ .../Repositories/ResourceRepositoryAccessor.cs | 2 ++ .../Resources/Annotations/AttrAttribute.cs | 2 ++ .../Resources/Annotations/EagerLoadAttribute.cs | 2 ++ .../Resources/Annotations/HasManyThroughAttribute.cs | 2 ++ .../Resources/Annotations/RelationshipAttribute.cs | 2 ++ .../Resources/Annotations/ResourceAttribute.cs | 2 ++ .../Resources/Annotations/ResourceFieldAttribute.cs | 2 ++ .../Resources/Annotations/ResourceLinksAttribute.cs | 2 ++ src/JsonApiDotNetCore/Resources/IResourceDefinition.cs | 3 +++ src/JsonApiDotNetCore/Resources/IdentifiableComparer.cs | 2 ++ .../Resources/JsonApiResourceDefinition.cs | 3 +++ src/JsonApiDotNetCore/Resources/OperationContainer.cs | 2 ++ src/JsonApiDotNetCore/Resources/ResourceChangeTracker.cs | 2 ++ .../Resources/ResourceDefinitionAccessor.cs | 2 ++ src/JsonApiDotNetCore/Resources/ResourceHooksDefinition.cs | 2 ++ .../Serialization/AtomicOperationsResponseSerializer.cs | 2 ++ src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs | 1 + .../Serialization/Building/IMetaBuilder.cs | 2 ++ .../Building/IncludedResourceObjectBuilder.cs | 2 ++ .../Serialization/Building/LinkBuilder.cs | 2 ++ .../Serialization/Building/MetaBuilder.cs | 2 ++ .../Serialization/Building/ResourceObjectBuilder.cs | 2 ++ .../Building/ResourceObjectBuilderSettings.cs | 2 ++ .../Building/ResponseResourceObjectBuilder.cs | 2 ++ .../Client/Internal/DeserializedResponseBase.cs | 2 ++ .../Serialization/Client/Internal/IRequestSerializer.cs | 2 ++ .../Serialization/Client/Internal/IResponseDeserializer.cs | 2 ++ .../Serialization/Client/Internal/ManyResponse.cs | 2 ++ .../Serialization/Client/Internal/RequestSerializer.cs | 2 ++ .../Serialization/Client/Internal/ResponseDeserializer.cs | 2 ++ .../Serialization/Client/Internal/SingleResponse.cs | 2 ++ src/JsonApiDotNetCore/Serialization/FieldsToSerialize.cs | 2 ++ src/JsonApiDotNetCore/Serialization/IJsonApiReader.cs | 2 ++ .../Serialization/IJsonApiSerializerFactory.cs | 7 +++++-- src/JsonApiDotNetCore/Serialization/IJsonApiWriter.cs | 4 +++- src/JsonApiDotNetCore/Serialization/JsonApiReader.cs | 1 + .../Serialization/JsonApiSerializationException.cs | 2 ++ src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs | 2 ++ src/JsonApiDotNetCore/Serialization/Objects/Error.cs | 2 ++ .../Serialization/Objects/ErrorDocument.cs | 2 ++ src/JsonApiDotNetCore/Serialization/Objects/ErrorMeta.cs | 2 ++ .../Serialization/Objects/ExposableData.cs | 2 ++ src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs | 1 + src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs | 2 ++ .../Serialization/ResponseSerializerFactory.cs | 2 ++ .../Services/AsyncCollectionExtensions.cs | 2 ++ .../Services/IAddToRelationshipService.cs | 2 ++ src/JsonApiDotNetCore/Services/JsonApiResourceService.cs | 2 ++ test/TestBuildingBlocks/FakeLoggerFactory.cs | 2 ++ test/TestBuildingBlocks/HttpResponseMessageExtensions.cs | 2 ++ test/TestBuildingBlocks/ObjectAssertionsExtensions.cs | 2 ++ 205 files changed, 424 insertions(+), 9 deletions(-) diff --git a/src/JsonApiDotNetCore/AtomicOperations/EntityFrameworkCoreTransaction.cs b/src/JsonApiDotNetCore/AtomicOperations/EntityFrameworkCoreTransaction.cs index 7e2bf88bb5..edb1cdd45d 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/EntityFrameworkCoreTransaction.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/EntityFrameworkCoreTransaction.cs @@ -1,6 +1,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Repositories; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage; @@ -10,6 +11,7 @@ namespace JsonApiDotNetCore.AtomicOperations /// /// Represents an Entity Framework Core transaction in an atomic:operations request. /// + [PublicAPI] public sealed class EntityFrameworkCoreTransaction : IOperationsTransaction { private readonly IDbContextTransaction _transaction; diff --git a/src/JsonApiDotNetCore/AtomicOperations/IOperationsTransaction.cs b/src/JsonApiDotNetCore/AtomicOperations/IOperationsTransaction.cs index 5e36b5ff03..16f7e6c4e5 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/IOperationsTransaction.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/IOperationsTransaction.cs @@ -1,12 +1,14 @@ using System; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; namespace JsonApiDotNetCore.AtomicOperations { /// /// Represents the overarching transaction in an atomic:operations request. /// + [PublicAPI] public interface IOperationsTransaction : IAsyncDisposable { /// diff --git a/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs b/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs index 27f8cbe5e4..55061a8ed8 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Middleware; @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.AtomicOperations /// /// Validates declaration, assignment and reference of local IDs within a list of operations. /// + [PublicAPI] public sealed class LocalIdValidator { private readonly ILocalIdTracker _localIdTracker; diff --git a/src/JsonApiDotNetCore/AtomicOperations/OperationProcessorAccessor.cs b/src/JsonApiDotNetCore/AtomicOperations/OperationProcessorAccessor.cs index 614dde20f6..54978414b7 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/OperationProcessorAccessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/OperationProcessorAccessor.cs @@ -1,6 +1,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.AtomicOperations.Processors; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; @@ -10,6 +11,7 @@ namespace JsonApiDotNetCore.AtomicOperations { /// + [PublicAPI] public class OperationProcessorAccessor : IOperationProcessorAccessor { private readonly IResourceContextProvider _resourceContextProvider; diff --git a/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs index fb97ccbd50..f660a1aafa 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs @@ -3,6 +3,7 @@ using System.Net; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Middleware; @@ -12,6 +13,7 @@ namespace JsonApiDotNetCore.AtomicOperations { /// + [PublicAPI] public class OperationsProcessor : IOperationsProcessor { private readonly IOperationProcessorAccessor _operationProcessorAccessor; diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/AddToRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/AddToRelationshipProcessor.cs index a7c42a514c..c988d8da00 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/AddToRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/AddToRelationshipProcessor.cs @@ -1,11 +1,13 @@ using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Services; namespace JsonApiDotNetCore.AtomicOperations.Processors { /// + [PublicAPI] public class AddToRelationshipProcessor : IAddToRelationshipProcessor where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/CreateProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/CreateProcessor.cs index 8e0b66d6c8..9c8547a676 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/CreateProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/CreateProcessor.cs @@ -1,5 +1,6 @@ using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Services; @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors { /// + [PublicAPI] public class CreateProcessor : ICreateProcessor where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/DeleteProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/DeleteProcessor.cs index f5780ba1b8..dd91f23384 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/DeleteProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/DeleteProcessor.cs @@ -1,11 +1,13 @@ using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Services; namespace JsonApiDotNetCore.AtomicOperations.Processors { /// + [PublicAPI] public class DeleteProcessor : IDeleteProcessor where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/IAddToRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/IAddToRelationshipProcessor.cs index 965c704e0a..b5f9d081ec 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/IAddToRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/IAddToRelationshipProcessor.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCore.AtomicOperations.Processors @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors /// /// The resource type. /// The resource identifier type. + [PublicAPI] public interface IAddToRelationshipProcessor : IOperationProcessor where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/ICreateProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/ICreateProcessor.cs index 846d6fc39a..392b6873b0 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/ICreateProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/ICreateProcessor.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCore.AtomicOperations.Processors @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors /// /// The resource type. /// The resource identifier type. + [PublicAPI] public interface ICreateProcessor : IOperationProcessor where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/IDeleteProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/IDeleteProcessor.cs index bb3efc30b0..e24f372301 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/IDeleteProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/IDeleteProcessor.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCore.AtomicOperations.Processors @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors /// /// The resource type. /// The resource identifier type. + [PublicAPI] public interface IDeleteProcessor : IOperationProcessor where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/IRemoveFromRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/IRemoveFromRelationshipProcessor.cs index ae5d80c55a..85e4ec7850 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/IRemoveFromRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/IRemoveFromRelationshipProcessor.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCore.AtomicOperations.Processors @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors /// /// /// + [PublicAPI] public interface IRemoveFromRelationshipProcessor : IOperationProcessor where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/ISetRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/ISetRelationshipProcessor.cs index f99c91d672..7847c2f985 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/ISetRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/ISetRelationshipProcessor.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCore.AtomicOperations.Processors @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors /// /// The resource type. /// The resource identifier type. + [PublicAPI] public interface ISetRelationshipProcessor : IOperationProcessor where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/IUpdateProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/IUpdateProcessor.cs index f4f403c073..34bdeb32fd 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/IUpdateProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/IUpdateProcessor.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCore.AtomicOperations.Processors @@ -8,6 +9,7 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors /// /// The resource type. /// The resource identifier type. + [PublicAPI] public interface IUpdateProcessor : IOperationProcessor where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/RemoveFromRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/RemoveFromRelationshipProcessor.cs index 789b5d8592..5a3c339417 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/RemoveFromRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/RemoveFromRelationshipProcessor.cs @@ -1,11 +1,13 @@ using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Services; namespace JsonApiDotNetCore.AtomicOperations.Processors { /// + [PublicAPI] public class RemoveFromRelationshipProcessor : IRemoveFromRelationshipProcessor where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/SetRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/SetRelationshipProcessor.cs index 0c0b0a6a63..1f9e825537 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/SetRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/SetRelationshipProcessor.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; using JsonApiDotNetCore.Services; @@ -8,6 +9,7 @@ namespace JsonApiDotNetCore.AtomicOperations.Processors { /// + [PublicAPI] public class SetRelationshipProcessor : ISetRelationshipProcessor where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/UpdateProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/UpdateProcessor.cs index c714e96c7c..f1828caaaf 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/UpdateProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/UpdateProcessor.cs @@ -1,11 +1,13 @@ using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Services; namespace JsonApiDotNetCore.AtomicOperations.Processors { /// + [PublicAPI] public class UpdateProcessor : IUpdateProcessor where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/Configuration/IGenericServiceFactory.cs b/src/JsonApiDotNetCore/Configuration/IGenericServiceFactory.cs index 52acdc14f2..63177fdfd2 100644 --- a/src/JsonApiDotNetCore/Configuration/IGenericServiceFactory.cs +++ b/src/JsonApiDotNetCore/Configuration/IGenericServiceFactory.cs @@ -1,4 +1,5 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Configuration { @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Configuration /// Represents the Service Locator design pattern. Used to obtain object instances for types are not known until runtime. /// This is only used by resource hooks and subject to be removed in a future version. /// + [PublicAPI] public interface IGenericServiceFactory { /// diff --git a/src/JsonApiDotNetCore/Configuration/IInverseNavigationResolver.cs b/src/JsonApiDotNetCore/Configuration/IInverseNavigationResolver.cs index b726ccf71f..5a91192eed 100644 --- a/src/JsonApiDotNetCore/Configuration/IInverseNavigationResolver.cs +++ b/src/JsonApiDotNetCore/Configuration/IInverseNavigationResolver.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Configuration @@ -11,6 +12,7 @@ namespace JsonApiDotNetCore.Configuration /// that depend on the inverse navigation property (BeforeImplicitUpdateRelationship), /// you will need to override this service, or set explicitly. /// + [PublicAPI] public interface IInverseNavigationResolver { /// diff --git a/src/JsonApiDotNetCore/Configuration/IResourceGraph.cs b/src/JsonApiDotNetCore/Configuration/IResourceGraph.cs index 8a11d587f1..a02045257c 100644 --- a/src/JsonApiDotNetCore/Configuration/IResourceGraph.cs +++ b/src/JsonApiDotNetCore/Configuration/IResourceGraph.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq.Expressions; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Configuration /// /// Enables retrieving the exposed resource fields (attributes and relationships) of resources registered in the resource graph. /// + [PublicAPI] public interface IResourceGraph : IResourceContextProvider { /// diff --git a/src/JsonApiDotNetCore/Configuration/InverseNavigationResolver.cs b/src/JsonApiDotNetCore/Configuration/InverseNavigationResolver.cs index 4333623529..63d9c600ea 100644 --- a/src/JsonApiDotNetCore/Configuration/InverseNavigationResolver.cs +++ b/src/JsonApiDotNetCore/Configuration/InverseNavigationResolver.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Repositories; using JsonApiDotNetCore.Resources.Annotations; using Microsoft.EntityFrameworkCore; @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Configuration { /// + [PublicAPI] public class InverseNavigationResolver : IInverseNavigationResolver { private readonly IResourceContextProvider _resourceContextProvider; diff --git a/src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs b/src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs index 85b07ba8f6..85811578fd 100644 --- a/src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs +++ b/src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs @@ -1,4 +1,5 @@ using System.Data; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Configuration { /// + [PublicAPI] public sealed class JsonApiOptions : IJsonApiOptions { internal static readonly NamingStrategy DefaultNamingStrategy = new CamelCaseNamingStrategy(); diff --git a/src/JsonApiDotNetCore/Configuration/PageNumber.cs b/src/JsonApiDotNetCore/Configuration/PageNumber.cs index bc94b3ca75..81561aefcb 100644 --- a/src/JsonApiDotNetCore/Configuration/PageNumber.cs +++ b/src/JsonApiDotNetCore/Configuration/PageNumber.cs @@ -1,7 +1,9 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Configuration { + [PublicAPI] public sealed class PageNumber : IEquatable { public static readonly PageNumber ValueOne = new PageNumber(1); diff --git a/src/JsonApiDotNetCore/Configuration/PageSize.cs b/src/JsonApiDotNetCore/Configuration/PageSize.cs index c1e3de877c..4533461502 100644 --- a/src/JsonApiDotNetCore/Configuration/PageSize.cs +++ b/src/JsonApiDotNetCore/Configuration/PageSize.cs @@ -1,7 +1,9 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Configuration { + [PublicAPI] public sealed class PageSize : IEquatable { public int Value { get; } diff --git a/src/JsonApiDotNetCore/Configuration/ResourceContext.cs b/src/JsonApiDotNetCore/Configuration/ResourceContext.cs index edde0bcc41..355c11e3ac 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceContext.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceContext.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Configuration @@ -8,6 +9,7 @@ namespace JsonApiDotNetCore.Configuration /// /// Provides metadata for a resource, such as its attributes and relationships. /// + [PublicAPI] public class ResourceContext { /// diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs index f1d457d2ec..5d9a0bd902 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs @@ -2,12 +2,14 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Configuration { /// + [PublicAPI] public class ResourceGraph : IResourceGraph { private readonly IReadOnlyCollection _resources; diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs index b21d468afd..0a2d2e667e 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using JetBrains.Annotations; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; @@ -12,6 +13,7 @@ namespace JsonApiDotNetCore.Configuration /// /// Builds and configures the . /// + [PublicAPI] public class ResourceGraphBuilder { private readonly IJsonApiOptions _options; diff --git a/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs b/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs index 7166c06873..ac2e28b22a 100644 --- a/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs +++ b/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using JetBrains.Annotations; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Repositories; using JsonApiDotNetCore.Serialization.Building; @@ -12,6 +13,7 @@ namespace JsonApiDotNetCore.Configuration { + [PublicAPI] public static class ServiceCollectionExtensions { /// diff --git a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs index 39c11d4dca..40107fc477 100644 --- a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs +++ b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using JetBrains.Annotations; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Repositories; using JsonApiDotNetCore.Resources; @@ -15,6 +16,7 @@ namespace JsonApiDotNetCore.Configuration /// /// Scans for types like resources, services, repositories and resource definitions in an assembly and registers them to the IoC container. /// + [PublicAPI] public class ServiceDiscoveryFacade { internal static readonly HashSet ServiceInterfaces = new HashSet { diff --git a/src/JsonApiDotNetCore/Controllers/Annotations/DisableQueryStringAttribute.cs b/src/JsonApiDotNetCore/Controllers/Annotations/DisableQueryStringAttribute.cs index f165c9758d..c325d96d47 100644 --- a/src/JsonApiDotNetCore/Controllers/Annotations/DisableQueryStringAttribute.cs +++ b/src/JsonApiDotNetCore/Controllers/Annotations/DisableQueryStringAttribute.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.QueryStrings; namespace JsonApiDotNetCore.Controllers.Annotations @@ -16,6 +17,7 @@ namespace JsonApiDotNetCore.Controllers.Annotations /// [DisableQueryString("skipCache")] /// public class CustomersController : JsonApiController { } /// ]]> + [PublicAPI] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface)] public sealed class DisableQueryStringAttribute : Attribute { diff --git a/src/JsonApiDotNetCore/Controllers/Annotations/DisableRoutingConventionAttribute.cs b/src/JsonApiDotNetCore/Controllers/Annotations/DisableRoutingConventionAttribute.cs index ecd55377ab..4450aca1ce 100644 --- a/src/JsonApiDotNetCore/Controllers/Annotations/DisableRoutingConventionAttribute.cs +++ b/src/JsonApiDotNetCore/Controllers/Annotations/DisableRoutingConventionAttribute.cs @@ -1,4 +1,5 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Controllers.Annotations { @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Controllers.Annotations /// [DisableRoutingConvention, Route("some/custom/route/to/customers")] /// public class CustomersController : JsonApiController { } /// ]]> + [PublicAPI] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface)] public sealed class DisableRoutingConventionAttribute : Attribute { } diff --git a/src/JsonApiDotNetCore/Controllers/Annotations/HttpReadOnlyAttribute.cs b/src/JsonApiDotNetCore/Controllers/Annotations/HttpReadOnlyAttribute.cs index 46b0f93f79..269086a586 100644 --- a/src/JsonApiDotNetCore/Controllers/Annotations/HttpReadOnlyAttribute.cs +++ b/src/JsonApiDotNetCore/Controllers/Annotations/HttpReadOnlyAttribute.cs @@ -1,3 +1,5 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCore.Controllers.Annotations { /// @@ -9,6 +11,7 @@ namespace JsonApiDotNetCore.Controllers.Annotations /// { /// } /// ]]> + [PublicAPI] public sealed class HttpReadOnlyAttribute : HttpRestrictAttribute { protected override string[] Methods { get; } = { "POST", "PATCH", "DELETE" }; diff --git a/src/JsonApiDotNetCore/Controllers/Annotations/NoHttpDeleteAttribute.cs b/src/JsonApiDotNetCore/Controllers/Annotations/NoHttpDeleteAttribute.cs index 02a5fbdba1..e898dc0118 100644 --- a/src/JsonApiDotNetCore/Controllers/Annotations/NoHttpDeleteAttribute.cs +++ b/src/JsonApiDotNetCore/Controllers/Annotations/NoHttpDeleteAttribute.cs @@ -1,3 +1,5 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCore.Controllers.Annotations { /// @@ -9,6 +11,7 @@ namespace JsonApiDotNetCore.Controllers.Annotations /// { /// } /// ]]> + [PublicAPI] public sealed class NoHttpDeleteAttribute : HttpRestrictAttribute { protected override string[] Methods { get; } = { "DELETE" }; diff --git a/src/JsonApiDotNetCore/Controllers/Annotations/NoHttpPatchAttribute.cs b/src/JsonApiDotNetCore/Controllers/Annotations/NoHttpPatchAttribute.cs index 7039356db2..01dc0e31ba 100644 --- a/src/JsonApiDotNetCore/Controllers/Annotations/NoHttpPatchAttribute.cs +++ b/src/JsonApiDotNetCore/Controllers/Annotations/NoHttpPatchAttribute.cs @@ -1,3 +1,5 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCore.Controllers.Annotations { /// @@ -9,6 +11,7 @@ namespace JsonApiDotNetCore.Controllers.Annotations /// { /// } /// ]]> + [PublicAPI] public sealed class NoHttpPatchAttribute : HttpRestrictAttribute { protected override string[] Methods { get; } = { "PATCH" }; diff --git a/src/JsonApiDotNetCore/Controllers/Annotations/NoHttpPostAttribute.cs b/src/JsonApiDotNetCore/Controllers/Annotations/NoHttpPostAttribute.cs index a40f1a3574..34a0c8a83c 100644 --- a/src/JsonApiDotNetCore/Controllers/Annotations/NoHttpPostAttribute.cs +++ b/src/JsonApiDotNetCore/Controllers/Annotations/NoHttpPostAttribute.cs @@ -1,3 +1,5 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCore.Controllers.Annotations { /// @@ -9,6 +11,7 @@ namespace JsonApiDotNetCore.Controllers.Annotations /// { /// } /// ]]> + [PublicAPI] public sealed class NoHttpPostAttribute : HttpRestrictAttribute { protected override string[] Methods { get; } = { "POST" }; diff --git a/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs b/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs index 66c7a185c6..27c1319371 100644 --- a/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs +++ b/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.AtomicOperations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; @@ -16,6 +17,7 @@ namespace JsonApiDotNetCore.Controllers /// Implements the foundational ASP.NET Core controller layer in the JsonApiDotNetCore architecture for handling atomic:operations requests. /// See https://jsonapi.org/ext/atomic/ for details. Delegates work to . /// + [PublicAPI] public abstract class BaseJsonApiOperationsController : CoreJsonApiController { private readonly IJsonApiOptions _options; diff --git a/src/JsonApiDotNetCore/Controllers/ModelStateViolation.cs b/src/JsonApiDotNetCore/Controllers/ModelStateViolation.cs index f786b2045c..8bda54c806 100644 --- a/src/JsonApiDotNetCore/Controllers/ModelStateViolation.cs +++ b/src/JsonApiDotNetCore/Controllers/ModelStateViolation.cs @@ -1,4 +1,5 @@ using System; +using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc.ModelBinding; namespace JsonApiDotNetCore.Controllers @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Controllers /// /// Represents the violation of a model state validation rule. /// + [PublicAPI] public sealed class ModelStateViolation { public string Prefix { get; } diff --git a/src/JsonApiDotNetCore/Errors/CannotClearRequiredRelationshipException.cs b/src/JsonApiDotNetCore/Errors/CannotClearRequiredRelationshipException.cs index 36105a3252..e0a647a8b2 100644 --- a/src/JsonApiDotNetCore/Errors/CannotClearRequiredRelationshipException.cs +++ b/src/JsonApiDotNetCore/Errors/CannotClearRequiredRelationshipException.cs @@ -1,4 +1,5 @@ using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Errors @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when a required relationship is cleared. /// + [PublicAPI] public sealed class CannotClearRequiredRelationshipException : JsonApiException { public CannotClearRequiredRelationshipException(string relationshipName, string resourceId, diff --git a/src/JsonApiDotNetCore/Errors/InvalidConfigurationException.cs b/src/JsonApiDotNetCore/Errors/InvalidConfigurationException.cs index c838e2ca9d..884ed046a7 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidConfigurationException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidConfigurationException.cs @@ -1,10 +1,12 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Errors { /// /// The error that is thrown when configured usage of this library is invalid. /// + [PublicAPI] public sealed class InvalidConfigurationException : Exception { public InvalidConfigurationException(string message, Exception innerException = null) diff --git a/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs b/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs index 8670345755..80d2becf94 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Net; using System.Reflection; +using JetBrains.Annotations; using JsonApiDotNetCore.Controllers; using JsonApiDotNetCore.Resources.Annotations; using JsonApiDotNetCore.Serialization.Objects; @@ -14,6 +15,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when model state validation fails. /// + [PublicAPI] public class InvalidModelStateException : JsonApiException { public InvalidModelStateException(ModelStateDictionary modelState, Type resourceType, diff --git a/src/JsonApiDotNetCore/Errors/InvalidQueryException.cs b/src/JsonApiDotNetCore/Errors/InvalidQueryException.cs index 3b68dfc931..b776d2c683 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidQueryException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidQueryException.cs @@ -1,5 +1,6 @@ using System; using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Serialization.Objects; @@ -8,6 +9,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when translating a to Entity Framework Core fails. /// + [PublicAPI] public sealed class InvalidQueryException : JsonApiException { public InvalidQueryException(string reason, Exception exception) diff --git a/src/JsonApiDotNetCore/Errors/InvalidQueryStringParameterException.cs b/src/JsonApiDotNetCore/Errors/InvalidQueryStringParameterException.cs index 12e66112d0..f0e2b146d6 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidQueryStringParameterException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidQueryStringParameterException.cs @@ -1,5 +1,6 @@ using System; using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Errors @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when processing the request fails due to an error in the request query string. /// + [PublicAPI] public sealed class InvalidQueryStringParameterException : JsonApiException { public string QueryParameterName { get; } diff --git a/src/JsonApiDotNetCore/Errors/InvalidRequestBodyException.cs b/src/JsonApiDotNetCore/Errors/InvalidRequestBodyException.cs index e9f2bf0a75..b50101f6dc 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidRequestBodyException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidRequestBodyException.cs @@ -1,6 +1,7 @@ using System; using System.Net; using System.Text; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Errors @@ -8,6 +9,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when deserializing the request body fails. /// + [PublicAPI] public sealed class InvalidRequestBodyException : JsonApiException { public InvalidRequestBodyException(string reason, string details, string requestBody, Exception innerException = null) diff --git a/src/JsonApiDotNetCore/Errors/JsonApiException.cs b/src/JsonApiDotNetCore/Errors/JsonApiException.cs index 3a73e8ac9a..278aa1f4ab 100644 --- a/src/JsonApiDotNetCore/Errors/JsonApiException.cs +++ b/src/JsonApiDotNetCore/Errors/JsonApiException.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; using Newtonsoft.Json; @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Errors /// /// The base class for an that represents one or more JSON:API error objects in an unsuccessful response. /// + [PublicAPI] public class JsonApiException : Exception { private static readonly JsonSerializerSettings ErrorSerializerSettings = new JsonSerializerSettings diff --git a/src/JsonApiDotNetCore/Errors/MissingResourceInRelationship.cs b/src/JsonApiDotNetCore/Errors/MissingResourceInRelationship.cs index 9777bbb46e..95ef199932 100644 --- a/src/JsonApiDotNetCore/Errors/MissingResourceInRelationship.cs +++ b/src/JsonApiDotNetCore/Errors/MissingResourceInRelationship.cs @@ -1,5 +1,8 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCore.Errors { + [PublicAPI] public sealed class MissingResourceInRelationship { public string RelationshipName { get; } diff --git a/src/JsonApiDotNetCore/Errors/MissingTransactionSupportException.cs b/src/JsonApiDotNetCore/Errors/MissingTransactionSupportException.cs index 85339f7252..980f6457fb 100644 --- a/src/JsonApiDotNetCore/Errors/MissingTransactionSupportException.cs +++ b/src/JsonApiDotNetCore/Errors/MissingTransactionSupportException.cs @@ -1,4 +1,5 @@ using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Errors @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Errors /// The error that is thrown when accessing a repository that does not support transactions /// during an atomic:operations request. /// + [PublicAPI] public sealed class MissingTransactionSupportException : JsonApiException { public MissingTransactionSupportException(string resourceType) diff --git a/src/JsonApiDotNetCore/Errors/NonSharedTransactionException.cs b/src/JsonApiDotNetCore/Errors/NonSharedTransactionException.cs index 9753d765ca..dbf699c301 100644 --- a/src/JsonApiDotNetCore/Errors/NonSharedTransactionException.cs +++ b/src/JsonApiDotNetCore/Errors/NonSharedTransactionException.cs @@ -1,4 +1,5 @@ using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Errors @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Errors /// The error that is thrown when a repository does not participate in the overarching transaction /// during an atomic:operations request. /// + [PublicAPI] public sealed class NonSharedTransactionException : JsonApiException { public NonSharedTransactionException() diff --git a/src/JsonApiDotNetCore/Errors/RelationshipNotFoundException.cs b/src/JsonApiDotNetCore/Errors/RelationshipNotFoundException.cs index 313222f4a2..091ff99586 100644 --- a/src/JsonApiDotNetCore/Errors/RelationshipNotFoundException.cs +++ b/src/JsonApiDotNetCore/Errors/RelationshipNotFoundException.cs @@ -1,4 +1,5 @@ using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Errors @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when a relationship does not exist. /// + [PublicAPI] public sealed class RelationshipNotFoundException : JsonApiException { public RelationshipNotFoundException(string relationshipName, string resourceType) : base(new Error(HttpStatusCode.NotFound) diff --git a/src/JsonApiDotNetCore/Errors/RequestMethodNotAllowedException.cs b/src/JsonApiDotNetCore/Errors/RequestMethodNotAllowedException.cs index 7444d6cc46..0a2db9e061 100644 --- a/src/JsonApiDotNetCore/Errors/RequestMethodNotAllowedException.cs +++ b/src/JsonApiDotNetCore/Errors/RequestMethodNotAllowedException.cs @@ -1,5 +1,6 @@ using System.Net; using System.Net.Http; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Errors @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when a request is received that contains an unsupported HTTP verb. /// + [PublicAPI] public sealed class RequestMethodNotAllowedException : JsonApiException { public HttpMethod Method { get; } diff --git a/src/JsonApiDotNetCore/Errors/ResourceAlreadyExistsException.cs b/src/JsonApiDotNetCore/Errors/ResourceAlreadyExistsException.cs index dcc0a0a66b..34bc21dff5 100644 --- a/src/JsonApiDotNetCore/Errors/ResourceAlreadyExistsException.cs +++ b/src/JsonApiDotNetCore/Errors/ResourceAlreadyExistsException.cs @@ -1,4 +1,5 @@ using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Errors @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when creating a resource with an ID that already exists. /// + [PublicAPI] public sealed class ResourceAlreadyExistsException : JsonApiException { public ResourceAlreadyExistsException(string resourceId, string resourceType) diff --git a/src/JsonApiDotNetCore/Errors/ResourceIdInCreateResourceNotAllowedException.cs b/src/JsonApiDotNetCore/Errors/ResourceIdInCreateResourceNotAllowedException.cs index fff90a6fb9..efe5d80c72 100644 --- a/src/JsonApiDotNetCore/Errors/ResourceIdInCreateResourceNotAllowedException.cs +++ b/src/JsonApiDotNetCore/Errors/ResourceIdInCreateResourceNotAllowedException.cs @@ -1,4 +1,5 @@ using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Errors @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when a resource creation request or operation is received that contains a client-generated ID. /// + [PublicAPI] public sealed class ResourceIdInCreateResourceNotAllowedException : JsonApiException { public ResourceIdInCreateResourceNotAllowedException(int? atomicOperationIndex = null) diff --git a/src/JsonApiDotNetCore/Errors/ResourceIdMismatchException.cs b/src/JsonApiDotNetCore/Errors/ResourceIdMismatchException.cs index 427dfa583c..b75366f102 100644 --- a/src/JsonApiDotNetCore/Errors/ResourceIdMismatchException.cs +++ b/src/JsonApiDotNetCore/Errors/ResourceIdMismatchException.cs @@ -1,4 +1,5 @@ using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Errors @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when the resource ID in the request body does not match the ID in the current endpoint URL. /// + [PublicAPI] public sealed class ResourceIdMismatchException : JsonApiException { public ResourceIdMismatchException(string bodyId, string endpointId, string requestPath) diff --git a/src/JsonApiDotNetCore/Errors/ResourceNotFoundException.cs b/src/JsonApiDotNetCore/Errors/ResourceNotFoundException.cs index a9d127ee59..4e63220269 100644 --- a/src/JsonApiDotNetCore/Errors/ResourceNotFoundException.cs +++ b/src/JsonApiDotNetCore/Errors/ResourceNotFoundException.cs @@ -1,4 +1,5 @@ using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Errors @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when a resource does not exist. /// + [PublicAPI] public sealed class ResourceNotFoundException : JsonApiException { public ResourceNotFoundException(string resourceId, string resourceType) diff --git a/src/JsonApiDotNetCore/Errors/ResourceTypeMismatchException.cs b/src/JsonApiDotNetCore/Errors/ResourceTypeMismatchException.cs index 851895fbd9..78f490c593 100644 --- a/src/JsonApiDotNetCore/Errors/ResourceTypeMismatchException.cs +++ b/src/JsonApiDotNetCore/Errors/ResourceTypeMismatchException.cs @@ -1,5 +1,6 @@ using System.Net; using System.Net.Http; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Serialization.Objects; @@ -8,6 +9,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when the resource type in the request body does not match the type expected at the current endpoint URL. /// + [PublicAPI] public sealed class ResourceTypeMismatchException : JsonApiException { public ResourceTypeMismatchException(HttpMethod method, string requestPath, ResourceContext expected, ResourceContext actual) diff --git a/src/JsonApiDotNetCore/Errors/ResourcesInRelationshipsNotFoundException.cs b/src/JsonApiDotNetCore/Errors/ResourcesInRelationshipsNotFoundException.cs index cc91a119e3..450ae4cdd5 100644 --- a/src/JsonApiDotNetCore/Errors/ResourcesInRelationshipsNotFoundException.cs +++ b/src/JsonApiDotNetCore/Errors/ResourcesInRelationshipsNotFoundException.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Errors @@ -8,6 +9,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when referencing one or more non-existing resources in one or more relationships. /// + [PublicAPI] public sealed class ResourcesInRelationshipsNotFoundException : JsonApiException { public ResourcesInRelationshipsNotFoundException(IEnumerable missingResources) diff --git a/src/JsonApiDotNetCore/Errors/ToManyRelationshipRequiredException.cs b/src/JsonApiDotNetCore/Errors/ToManyRelationshipRequiredException.cs index 5682ef9679..840965aed4 100644 --- a/src/JsonApiDotNetCore/Errors/ToManyRelationshipRequiredException.cs +++ b/src/JsonApiDotNetCore/Errors/ToManyRelationshipRequiredException.cs @@ -1,4 +1,5 @@ using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Errors @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when an attempt is made to update a to-one relationship from a to-many relationship endpoint. /// + [PublicAPI] public sealed class ToManyRelationshipRequiredException : JsonApiException { public ToManyRelationshipRequiredException(string relationshipName) diff --git a/src/JsonApiDotNetCore/Errors/UnsuccessfulActionResultException.cs b/src/JsonApiDotNetCore/Errors/UnsuccessfulActionResultException.cs index dbb8ccf24b..58c0219bf6 100644 --- a/src/JsonApiDotNetCore/Errors/UnsuccessfulActionResultException.cs +++ b/src/JsonApiDotNetCore/Errors/UnsuccessfulActionResultException.cs @@ -1,4 +1,5 @@ using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; using Microsoft.AspNetCore.Mvc; @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Errors /// /// The error that is thrown when an with non-success status is returned from a controller method. /// + [PublicAPI] public sealed class UnsuccessfulActionResultException : JsonApiException { public UnsuccessfulActionResultException(HttpStatusCode status) diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs index b682df3596..720363cc82 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/HooksDiscovery.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Hooks.Internal.Execution; using JsonApiDotNetCore.Resources; @@ -11,6 +12,7 @@ namespace JsonApiDotNetCore.Hooks.Internal.Discovery /// /// The default implementation for IHooksDiscovery /// + [PublicAPI] public class HooksDiscovery : IHooksDiscovery where TResource : class, IIdentifiable { private readonly Type _boundResourceDefinitionType = typeof(ResourceHooksDefinition); diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/LoadDatabaseValuesAttribute.cs b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/LoadDatabaseValuesAttribute.cs index c44d33469e..5fe3e71c39 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/LoadDatabaseValuesAttribute.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/LoadDatabaseValuesAttribute.cs @@ -1,7 +1,9 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Hooks.Internal.Discovery { + [PublicAPI] [AttributeUsage(AttributeTargets.Method)] public sealed class LoadDatabaseValuesAttribute : Attribute { diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs index ebd754b8e3..f4c764240b 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs @@ -4,12 +4,14 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; +using JetBrains.Annotations; using JsonApiDotNetCore.Hooks.Internal.Discovery; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Hooks.Internal.Execution { + [PublicAPI] public sealed class DiffableResourceHashSet : ResourceHashSet, IDiffableResourceHashSet where TResource : class, IIdentifiable { private readonly HashSet _databaseValues; diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/RelationshipsDictionary.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/RelationshipsDictionary.cs index f593839a7a..0aa1b9406d 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/RelationshipsDictionary.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/RelationshipsDictionary.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; @@ -14,6 +15,7 @@ namespace JsonApiDotNetCore.Hooks.Internal.Execution /// It is practically a ReadOnlyDictionary{RelationshipAttribute, HashSet{TRightResource}} dictionary /// with the two helper methods defined on IAffectedRelationships{TRightResource}. /// + [PublicAPI] public class RelationshipsDictionary : Dictionary>, IRelationshipsDictionary where TResource : class, IIdentifiable diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceDiffPair.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceDiffPair.cs index a627c5d38b..fe52b4f9b3 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceDiffPair.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceDiffPair.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCore.Hooks.Internal.Execution @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Hooks.Internal.Execution /// A wrapper that contains a resource that is affected by the request, /// matched to its current database value /// + [PublicAPI] public sealed class ResourceDiffPair where TResource : class, IIdentifiable { public ResourceDiffPair(TResource resource, TResource databaseValue) @@ -23,4 +25,4 @@ public ResourceDiffPair(TResource resource, TResource databaseValue) /// public TResource DatabaseValue { get; } } -} \ No newline at end of file +} diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceHashSet.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceHashSet.cs index 66297ddf18..067dec9dcc 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceHashSet.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceHashSet.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq.Expressions; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; @@ -15,6 +16,7 @@ namespace JsonApiDotNetCore.Hooks.Internal.Execution /// Also contains information about updated relationships through /// implementation of IRelationshipsDictionary> /// + [PublicAPI] public class ResourceHashSet : HashSet, IResourceHashSet where TResource : class, IIdentifiable { /// diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourcePipeline.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourcePipeline.cs index 9d8c906106..3c256f1ad4 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourcePipeline.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourcePipeline.cs @@ -1,4 +1,5 @@ using System.Threading; +using JetBrains.Annotations; using JsonApiDotNetCore.Services; namespace JsonApiDotNetCore.Hooks.Internal.Execution @@ -8,6 +9,7 @@ namespace JsonApiDotNetCore.Hooks.Internal.Execution /// is called from , it will be called /// with parameter pipeline = ResourceAction.GetSingle. /// + [PublicAPI] public enum ResourcePipeline { None, diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs index 6addbf1701..86677d1907 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RelationshipProxy.cs @@ -33,7 +33,7 @@ internal sealed class RelationshipProxy public bool IsContextRelation { get; } - public RelationshipAttribute Attribute { get; set; } + public RelationshipAttribute Attribute { get; } public RelationshipProxy(RelationshipAttribute attr, Type relatedType, bool isContextRelation) { diff --git a/src/JsonApiDotNetCore/Middleware/AsyncJsonApiExceptionFilter.cs b/src/JsonApiDotNetCore/Middleware/AsyncJsonApiExceptionFilter.cs index 8d447bb152..9fa5df8366 100644 --- a/src/JsonApiDotNetCore/Middleware/AsyncJsonApiExceptionFilter.cs +++ b/src/JsonApiDotNetCore/Middleware/AsyncJsonApiExceptionFilter.cs @@ -1,10 +1,12 @@ using System.Threading.Tasks; +using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; namespace JsonApiDotNetCore.Middleware { /// + [PublicAPI] public class AsyncJsonApiExceptionFilter : IAsyncJsonApiExceptionFilter { private readonly IExceptionHandler _exceptionHandler; diff --git a/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs b/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs index f8841e3b57..568cf6fed7 100644 --- a/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs +++ b/src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.Net; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Serialization.Objects; @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Middleware { /// + [PublicAPI] public class ExceptionHandler : IExceptionHandler { private readonly IJsonApiOptions _options; diff --git a/src/JsonApiDotNetCore/Middleware/HttpContextExtensions.cs b/src/JsonApiDotNetCore/Middleware/HttpContextExtensions.cs index c8411756ba..b77cf79a2a 100644 --- a/src/JsonApiDotNetCore/Middleware/HttpContextExtensions.cs +++ b/src/JsonApiDotNetCore/Middleware/HttpContextExtensions.cs @@ -1,7 +1,9 @@ +using JetBrains.Annotations; using Microsoft.AspNetCore.Http; namespace JsonApiDotNetCore.Middleware { + [PublicAPI] public static class HttpContextExtensions { private const string IsJsonApiRequestKey = "JsonApiDotNetCore_IsJsonApiRequest"; diff --git a/src/JsonApiDotNetCore/Middleware/IAsyncConvertEmptyActionResultFilter.cs b/src/JsonApiDotNetCore/Middleware/IAsyncConvertEmptyActionResultFilter.cs index 6b860d625b..9101c97c21 100644 --- a/src/JsonApiDotNetCore/Middleware/IAsyncConvertEmptyActionResultFilter.cs +++ b/src/JsonApiDotNetCore/Middleware/IAsyncConvertEmptyActionResultFilter.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc.Filters; namespace JsonApiDotNetCore.Middleware @@ -12,5 +13,6 @@ namespace JsonApiDotNetCore.Middleware /// This ensures our formatter is invoked, where we'll build a JSON:API compliant response. /// For details, see: https://github.com/dotnet/aspnetcore/issues/16969 /// + [PublicAPI] public interface IAsyncConvertEmptyActionResultFilter : IAsyncAlwaysRunResultFilter { } } diff --git a/src/JsonApiDotNetCore/Middleware/IAsyncJsonApiExceptionFilter.cs b/src/JsonApiDotNetCore/Middleware/IAsyncJsonApiExceptionFilter.cs index f47a13bd58..67b1985816 100644 --- a/src/JsonApiDotNetCore/Middleware/IAsyncJsonApiExceptionFilter.cs +++ b/src/JsonApiDotNetCore/Middleware/IAsyncJsonApiExceptionFilter.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc.Filters; namespace JsonApiDotNetCore.Middleware @@ -5,5 +6,6 @@ namespace JsonApiDotNetCore.Middleware /// /// Application-wide exception filter that invokes for JSON:API requests. /// + [PublicAPI] public interface IAsyncJsonApiExceptionFilter : IAsyncExceptionFilter { } } diff --git a/src/JsonApiDotNetCore/Middleware/IAsyncQueryStringActionFilter.cs b/src/JsonApiDotNetCore/Middleware/IAsyncQueryStringActionFilter.cs index 2f1f844166..c2a4effcce 100644 --- a/src/JsonApiDotNetCore/Middleware/IAsyncQueryStringActionFilter.cs +++ b/src/JsonApiDotNetCore/Middleware/IAsyncQueryStringActionFilter.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc.Filters; namespace JsonApiDotNetCore.Middleware @@ -5,5 +6,6 @@ namespace JsonApiDotNetCore.Middleware /// /// Application-wide entry point for processing JSON:API request query strings. /// + [PublicAPI] public interface IAsyncQueryStringActionFilter : IAsyncActionFilter { } } diff --git a/src/JsonApiDotNetCore/Middleware/IJsonApiInputFormatter.cs b/src/JsonApiDotNetCore/Middleware/IJsonApiInputFormatter.cs index 7a08e89277..1aeb803be6 100644 --- a/src/JsonApiDotNetCore/Middleware/IJsonApiInputFormatter.cs +++ b/src/JsonApiDotNetCore/Middleware/IJsonApiInputFormatter.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc.Formatters; namespace JsonApiDotNetCore.Middleware @@ -5,5 +6,6 @@ namespace JsonApiDotNetCore.Middleware /// /// Application-wide entry point for reading JSON:API request bodies. /// + [PublicAPI] public interface IJsonApiInputFormatter : IInputFormatter { } } diff --git a/src/JsonApiDotNetCore/Middleware/IJsonApiOutputFormatter.cs b/src/JsonApiDotNetCore/Middleware/IJsonApiOutputFormatter.cs index b02192ae0a..1afd8683f9 100644 --- a/src/JsonApiDotNetCore/Middleware/IJsonApiOutputFormatter.cs +++ b/src/JsonApiDotNetCore/Middleware/IJsonApiOutputFormatter.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc.Formatters; namespace JsonApiDotNetCore.Middleware @@ -5,5 +6,6 @@ namespace JsonApiDotNetCore.Middleware /// /// Application-wide entry point for writing JSON:API response bodies. /// + [PublicAPI] public interface IJsonApiOutputFormatter : IOutputFormatter { } } diff --git a/src/JsonApiDotNetCore/Middleware/IJsonApiRoutingConvention.cs b/src/JsonApiDotNetCore/Middleware/IJsonApiRoutingConvention.cs index 3d4df4d29c..e1c941414c 100644 --- a/src/JsonApiDotNetCore/Middleware/IJsonApiRoutingConvention.cs +++ b/src/JsonApiDotNetCore/Middleware/IJsonApiRoutingConvention.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc.ApplicationModels; namespace JsonApiDotNetCore.Middleware @@ -6,5 +7,6 @@ namespace JsonApiDotNetCore.Middleware /// Service for specifying which routing convention to use. This can be overridden to customize /// the relation between controllers and mapped routes. /// + [PublicAPI] public interface IJsonApiRoutingConvention : IApplicationModelConvention, IControllerResourceMapping { } } diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs index 24bdb2c779..3a5b2cf848 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs @@ -6,6 +6,7 @@ using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources.Annotations; using JsonApiDotNetCore.Serialization; @@ -21,6 +22,7 @@ namespace JsonApiDotNetCore.Middleware /// /// Intercepts HTTP requests to populate injected instance for JSON:API requests. /// + [PublicAPI] public sealed class JsonApiMiddleware { private static readonly MediaTypeHeaderValue MediaType = MediaTypeHeaderValue.Parse(HeaderConstants.MediaType); diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiRequest.cs b/src/JsonApiDotNetCore/Middleware/JsonApiRequest.cs index 113199ff91..ce2704aadf 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiRequest.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiRequest.cs @@ -1,10 +1,12 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Middleware { /// + [PublicAPI] public sealed class JsonApiRequest : IJsonApiRequest { /// diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs b/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs index c8538c4fe4..73468d4ef3 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiRoutingConvention.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers; using JsonApiDotNetCore.Controllers.Annotations; @@ -28,6 +29,7 @@ namespace JsonApiDotNetCore.Middleware /// /// public class SomeVeryCustomController : CoreJsonApiController { } // => /someVeryCustoms/relationship/relatedResource /// ]]> + [PublicAPI] public class JsonApiRoutingConvention : IJsonApiRoutingConvention { private readonly IJsonApiOptions _options; diff --git a/src/JsonApiDotNetCore/Queries/ExpressionInScope.cs b/src/JsonApiDotNetCore/Queries/ExpressionInScope.cs index 443f36f728..56f56468c1 100644 --- a/src/JsonApiDotNetCore/Queries/ExpressionInScope.cs +++ b/src/JsonApiDotNetCore/Queries/ExpressionInScope.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Queries /// /// Represents an expression coming from query string. The scope determines at which depth in the to apply its expression. /// + [PublicAPI] public class ExpressionInScope { public ResourceFieldChainExpression Scope { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/CollectionNotEmptyExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/CollectionNotEmptyExpression.cs index 7a9afb0e30..47bdde4bda 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/CollectionNotEmptyExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/CollectionNotEmptyExpression.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Queries.Internal.Parsing; namespace JsonApiDotNetCore.Queries.Expressions @@ -5,6 +6,7 @@ namespace JsonApiDotNetCore.Queries.Expressions /// /// Represents the "has" filter function, resulting from text such as: has(articles) /// + [PublicAPI] public class CollectionNotEmptyExpression : FilterExpression { public ResourceFieldChainExpression TargetCollection { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/ComparisonExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/ComparisonExpression.cs index c22d3d01fd..16063c9c1f 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/ComparisonExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/ComparisonExpression.cs @@ -1,11 +1,13 @@ using System; using Humanizer; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Queries.Expressions { /// /// Represents a comparison filter function, resulting from text such as: equals(name,'Joe') /// + [PublicAPI] public class ComparisonExpression : FilterExpression { public ComparisonOperator Operator { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/CountExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/CountExpression.cs index 23a53a7be2..26459b943f 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/CountExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/CountExpression.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Queries.Internal.Parsing; namespace JsonApiDotNetCore.Queries.Expressions @@ -5,6 +6,7 @@ namespace JsonApiDotNetCore.Queries.Expressions /// /// Represents the "count" function, resulting from text such as: count(articles) /// + [PublicAPI] public class CountExpression : FunctionExpression { public ResourceFieldChainExpression TargetCollection { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/EqualsAnyOfExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/EqualsAnyOfExpression.cs index 44b867d590..69076e2d39 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/EqualsAnyOfExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/EqualsAnyOfExpression.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using JetBrains.Annotations; using JsonApiDotNetCore.Queries.Internal.Parsing; namespace JsonApiDotNetCore.Queries.Expressions @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Queries.Expressions /// /// Represents the "any" filter function, resulting from text such as: any(name,'Jack','Joe') /// + [PublicAPI] public class EqualsAnyOfExpression : FilterExpression { public ResourceFieldChainExpression TargetAttribute { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/IncludeElementExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/IncludeElementExpression.cs index 198d412bc6..2b9be3d95d 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/IncludeElementExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/IncludeElementExpression.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Queries.Expressions @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Queries.Expressions /// /// Represents an element in . /// + [PublicAPI] public class IncludeElementExpression : QueryExpression { public RelationshipAttribute Relationship { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/IncludeExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/IncludeExpression.cs index 66a5110957..a96065db56 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/IncludeExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/IncludeExpression.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Queries.Expressions { /// /// Represents an inclusion tree, resulting from text such as: owner,articles.revisions /// + [PublicAPI] public class IncludeExpression : QueryExpression { public IReadOnlyCollection Elements { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/LiteralConstantExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/LiteralConstantExpression.cs index 8da035d752..e59299ba3d 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/LiteralConstantExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/LiteralConstantExpression.cs @@ -1,8 +1,11 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCore.Queries.Expressions { /// /// Represents a non-null constant value, resulting from text such as: equals(firstName,'Jack') /// + [PublicAPI] public class LiteralConstantExpression : IdentifierExpression { public string Value { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/LogicalExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/LogicalExpression.cs index 29f0396f31..ef093e204f 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/LogicalExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/LogicalExpression.cs @@ -3,12 +3,14 @@ using System.Linq; using System.Text; using Humanizer; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Queries.Expressions { /// /// Represents a logical filter function, resulting from text such as: and(equals(title,'Work'),has(articles)) /// + [PublicAPI] public class LogicalExpression : FilterExpression { public LogicalOperator Operator { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/MatchTextExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/MatchTextExpression.cs index 5ae5979a77..6c026d0258 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/MatchTextExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/MatchTextExpression.cs @@ -1,12 +1,14 @@ using System; using System.Text; using Humanizer; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Queries.Expressions { /// /// Represents a text-matching filter function, resulting from text such as: startsWith(name,'A') /// + [PublicAPI] public class MatchTextExpression : FilterExpression { public ResourceFieldChainExpression TargetAttribute { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/NotExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/NotExpression.cs index d679fcc8a4..23a9637045 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/NotExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/NotExpression.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Queries.Internal.Parsing; namespace JsonApiDotNetCore.Queries.Expressions @@ -5,6 +6,7 @@ namespace JsonApiDotNetCore.Queries.Expressions /// /// Represents the "not" filter function, resulting from text such as: not(equals(title,'Work')) /// + [PublicAPI] public class NotExpression : FilterExpression { public QueryExpression Child { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/NullConstantExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/NullConstantExpression.cs index 7344518ef1..1041be47dd 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/NullConstantExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/NullConstantExpression.cs @@ -1,4 +1,5 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Queries.Internal.Parsing; namespace JsonApiDotNetCore.Queries.Expressions @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Queries.Expressions /// /// Represents the constant null, resulting from text such as: equals(lastName,null) /// + [PublicAPI] public class NullConstantExpression : IdentifierExpression { public override TResult Accept(QueryExpressionVisitor visitor, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/PaginationElementQueryStringValueExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/PaginationElementQueryStringValueExpression.cs index 9c1bc03c0b..29dbf72d99 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/PaginationElementQueryStringValueExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/PaginationElementQueryStringValueExpression.cs @@ -1,10 +1,12 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Queries.Expressions { /// /// Represents an element in . /// + [PublicAPI] public class PaginationElementQueryStringValueExpression : QueryExpression { public ResourceFieldChainExpression Scope { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/PaginationExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/PaginationExpression.cs index a74538758d..593e2ca1b8 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/PaginationExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/PaginationExpression.cs @@ -1,4 +1,5 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; namespace JsonApiDotNetCore.Queries.Expressions @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Queries.Expressions /// /// Represents a pagination, produced from . /// + [PublicAPI] public class PaginationExpression : QueryExpression { public PageNumber PageNumber { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/PaginationQueryStringValueExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/PaginationQueryStringValueExpression.cs index a3dc88b3b2..5e054d000e 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/PaginationQueryStringValueExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/PaginationQueryStringValueExpression.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Queries.Expressions { /// /// Represents pagination in a query string, resulting from text such as: 1,articles:2 /// + [PublicAPI] public class PaginationQueryStringValueExpression : QueryExpression { public IReadOnlyCollection Elements { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/QueryExpressionRewriter.cs b/src/JsonApiDotNetCore/Queries/Expressions/QueryExpressionRewriter.cs index 8a09340a11..6ff2e777aa 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/QueryExpressionRewriter.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/QueryExpressionRewriter.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; namespace JsonApiDotNetCore.Queries.Expressions @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Queries.Expressions /// /// Building block for rewriting trees. It walks through nested expressions and updates parent on changes. /// + [PublicAPI] public class QueryExpressionRewriter : QueryExpressionVisitor { public override QueryExpression Visit(QueryExpression expression, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/QueryExpressionVisitor.cs b/src/JsonApiDotNetCore/Queries/Expressions/QueryExpressionVisitor.cs index 309da19819..6b7da6210d 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/QueryExpressionVisitor.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/QueryExpressionVisitor.cs @@ -1,8 +1,11 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCore.Queries.Expressions { /// /// Implements the visitor design pattern that enables traversing a tree. /// + [PublicAPI] public abstract class QueryExpressionVisitor { public virtual TResult Visit(QueryExpression expression, TArgument argument) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/QueryStringParameterScopeExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/QueryStringParameterScopeExpression.cs index 4ae22a7380..ca514c6638 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/QueryStringParameterScopeExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/QueryStringParameterScopeExpression.cs @@ -1,10 +1,12 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Queries.Expressions { /// /// Represents the scope of a query string parameter, resulting from text such as: ?filter[articles]=... /// + [PublicAPI] public class QueryStringParameterScopeExpression : QueryExpression { public LiteralConstantExpression ParameterName { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/QueryableHandlerExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/QueryableHandlerExpression.cs index 3dcf1f2083..dd47117388 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/QueryableHandlerExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/QueryableHandlerExpression.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using Microsoft.Extensions.Primitives; @@ -8,6 +9,7 @@ namespace JsonApiDotNetCore.Queries.Expressions /// /// Holds an expression, used for custom query string handlers from s. /// + [PublicAPI] public class QueryableHandlerExpression : QueryExpression { private readonly object _queryableHandler; diff --git a/src/JsonApiDotNetCore/Queries/Expressions/ResourceFieldChainExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/ResourceFieldChainExpression.cs index 911116bff9..40c30113d9 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/ResourceFieldChainExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/ResourceFieldChainExpression.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Queries.Expressions @@ -8,6 +9,7 @@ namespace JsonApiDotNetCore.Queries.Expressions /// /// Represents a chain of fields (relationships and attributes), resulting from text such as: articles.revisions.author /// + [PublicAPI] public class ResourceFieldChainExpression : IdentifierExpression { public IReadOnlyCollection Fields { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/SortElementExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/SortElementExpression.cs index 12c4ff9d0a..4711bd0cdc 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/SortElementExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/SortElementExpression.cs @@ -1,11 +1,13 @@ using System; using System.Text; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Queries.Expressions { /// /// Represents an element in . /// + [PublicAPI] public class SortElementExpression : QueryExpression { public ResourceFieldChainExpression TargetAttribute { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/SortExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/SortExpression.cs index 625c152a5e..43e25df7e3 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/SortExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/SortExpression.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Queries.Expressions { /// /// Represents a sorting, resulting from text such as: lastName,-lastModifiedAt /// + [PublicAPI] public class SortExpression : QueryExpression { public IReadOnlyCollection Elements { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpression.cs index 224c9f162e..db55b1ee29 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpression.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Queries.Expressions @@ -8,6 +9,7 @@ namespace JsonApiDotNetCore.Queries.Expressions /// /// Represents a sparse fieldset, resulting from text such as: firstName,lastName,articles /// + [PublicAPI] public class SparseFieldSetExpression : QueryExpression { public IReadOnlyCollection Fields { get; } diff --git a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpressionExtensions.cs b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpressionExtensions.cs index e967b01d72..4afc587499 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpressionExtensions.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpressionExtensions.cs @@ -1,12 +1,14 @@ using System; using System.Linq; using System.Linq.Expressions; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Queries.Expressions { + [PublicAPI] public static class SparseFieldSetExpressionExtensions { public static SparseFieldSetExpression Including(this SparseFieldSetExpression sparseFieldSet, diff --git a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldTableExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldTableExpression.cs index c9feca96b5..fcbdd2fd82 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldTableExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldTableExpression.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; namespace JsonApiDotNetCore.Queries.Expressions @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Queries.Expressions /// /// Represents a lookup table of sparse fieldsets per resource type. /// + [PublicAPI] public class SparseFieldTableExpression : QueryExpression { public IReadOnlyDictionary Table { get; } diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/FilterParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/FilterParser.cs index b35a983949..aeb5358249 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/FilterParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/FilterParser.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using Humanizer; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources; @@ -10,6 +11,7 @@ namespace JsonApiDotNetCore.Queries.Internal.Parsing { + [PublicAPI] public class FilterParser : QueryExpressionParser { private readonly IResourceFactory _resourceFactory; diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/IncludeParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/IncludeParser.cs index bafe5d1ef9..d1b7d73321 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/IncludeParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/IncludeParser.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Queries.Internal.Parsing { + [PublicAPI] public class IncludeParser : QueryExpressionParser { private readonly Action _validateSingleRelationshipCallback; diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/Keywords.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/Keywords.cs index c1933152e1..dabe52e605 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/Keywords.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/Keywords.cs @@ -1,5 +1,8 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCore.Queries.Internal.Parsing { + [PublicAPI] public static class Keywords { public const string Null = "null"; diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/PaginationParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/PaginationParser.cs index 8e04950a63..c4744876a7 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/PaginationParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/PaginationParser.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Queries.Internal.Parsing { + [PublicAPI] public class PaginationParser : QueryExpressionParser { private readonly Action _validateSingleFieldCallback; diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryExpressionParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryExpressionParser.cs index 277d18f62d..15b189c7f7 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryExpressionParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryExpressionParser.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources.Annotations; @@ -13,6 +14,7 @@ namespace JsonApiDotNetCore.Queries.Internal.Parsing /// Uses a tokenizer to populate a stack of tokens, which is then manipulated from the various parsing routines for subexpressions. /// Implementations should throw on invalid input. /// + [PublicAPI] public abstract class QueryExpressionParser { private protected ResourceFieldChainResolver ChainResolver { get; } diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryParseException.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryParseException.cs index 33a556e6c2..da2d85f25a 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryParseException.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryParseException.cs @@ -1,7 +1,9 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Queries.Internal.Parsing { + [PublicAPI] public sealed class QueryParseException : Exception { public QueryParseException(string message) : base(message) diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryStringParameterScopeParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryStringParameterScopeParser.cs index b6187e3f4b..33965facd4 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryStringParameterScopeParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryStringParameterScopeParser.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Queries.Internal.Parsing { + [PublicAPI] public class QueryStringParameterScopeParser : QueryExpressionParser { private readonly FieldChainRequirements _chainRequirements; diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryTokenizer.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryTokenizer.cs index d27df8ac38..0084fa7bc2 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryTokenizer.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryTokenizer.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Queries.Internal.Parsing { + [PublicAPI] public sealed class QueryTokenizer { public static readonly IReadOnlyDictionary SingleCharacterToTokenKinds = diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/ResourceFieldChainResolver.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/ResourceFieldChainResolver.cs index 15672107b0..ce0b703328 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/ResourceFieldChainResolver.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/ResourceFieldChainResolver.cs @@ -192,7 +192,7 @@ public IReadOnlyCollection ResolveToOneChainEndingInAttr return chain; } - public RelationshipAttribute GetRelationship(string publicName, ResourceContext resourceContext, string path) + private RelationshipAttribute GetRelationship(string publicName, ResourceContext resourceContext, string path) { var relationship = resourceContext.Relationships.FirstOrDefault(r => r.PublicName == publicName); @@ -206,7 +206,7 @@ public RelationshipAttribute GetRelationship(string publicName, ResourceContext return relationship; } - public RelationshipAttribute GetToManyRelationship(string publicName, ResourceContext resourceContext, string path) + private RelationshipAttribute GetToManyRelationship(string publicName, ResourceContext resourceContext, string path) { var relationship = GetRelationship(publicName, resourceContext, path); @@ -220,7 +220,7 @@ public RelationshipAttribute GetToManyRelationship(string publicName, ResourceCo return relationship; } - public RelationshipAttribute GetToOneRelationship(string publicName, ResourceContext resourceContext, string path) + private RelationshipAttribute GetToOneRelationship(string publicName, ResourceContext resourceContext, string path) { var relationship = GetRelationship(publicName, resourceContext, path); diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SortParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SortParser.cs index 45b2546e43..2b00f686ef 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SortParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SortParser.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Queries.Internal.Parsing { + [PublicAPI] public class SortParser : QueryExpressionParser { private readonly Action _validateSingleFieldCallback; diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldSetParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldSetParser.cs index f0958f8b09..aea883f43e 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldSetParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldSetParser.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Queries.Internal.Parsing { + [PublicAPI] public class SparseFieldSetParser : QueryExpressionParser { private readonly Action _validateSingleFieldCallback; diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldTypeParser.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldTypeParser.cs index 9f6e2d4dac..18fd966167 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldTypeParser.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/SparseFieldTypeParser.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Queries.Internal.Parsing { + [PublicAPI] public class SparseFieldTypeParser : QueryExpressionParser { private readonly IResourceContextProvider _resourceContextProvider; diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/Token.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/Token.cs index 93995233d2..c8c8623a67 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/Token.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/Token.cs @@ -1,5 +1,8 @@ +using JetBrains.Annotations; + namespace JsonApiDotNetCore.Queries.Internal.Parsing { + [PublicAPI] public sealed class Token { public TokenKind Kind { get; } diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs index 5a478eb653..e20c67eb45 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources; @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Queries.Internal { /// + [PublicAPI] public class QueryLayerComposer : IQueryLayerComposer { private readonly IEnumerable _constraintProviders; diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs index 65cd279bb8..3e4284e9fd 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources.Annotations; @@ -11,6 +12,7 @@ namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding /// /// Transforms into calls. /// + [PublicAPI] public class IncludeClauseBuilder : QueryClauseBuilder { private readonly Expression _source; diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameFactory.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameFactory.cs index 4c06e24abf..40d8b241b3 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameFactory.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameFactory.cs @@ -1,11 +1,13 @@ using System.Collections.Generic; using Humanizer; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding { /// /// Produces unique names for lambda parameters. /// + [PublicAPI] public sealed class LambdaParameterNameFactory { private readonly HashSet _namesInScope = new HashSet(); diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameScope.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameScope.cs index f757d864dd..178ed800b6 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameScope.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaParameterNameScope.cs @@ -1,7 +1,9 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding { + [PublicAPI] public sealed class LambdaParameterNameScope : IDisposable { private readonly LambdaParameterNameFactory _owner; diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScope.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScope.cs index 3f4a65d56a..208c1a9fb3 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScope.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScope.cs @@ -1,5 +1,6 @@ using System; using System.Linq.Expressions; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding /// /// Contains details on a lambda expression, such as the name of the selector "x" in "x => x.Name". /// + [PublicAPI] public sealed class LambdaScope : IDisposable { private readonly LambdaParameterNameScope _parameterNameScope; diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScopeFactory.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScopeFactory.cs index dd168506df..d9dc5b6a19 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScopeFactory.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/LambdaScopeFactory.cs @@ -1,9 +1,11 @@ using System; using System.Linq.Expressions; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding { + [PublicAPI] public sealed class LambdaScopeFactory { private readonly LambdaParameterNameFactory _nameFactory; diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs index 65ab9bc017..2ddfb60e47 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/OrderClauseBuilder.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using JetBrains.Annotations; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources.Annotations; @@ -10,6 +11,7 @@ namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding /// /// Transforms into calls. /// + [PublicAPI] public class OrderClauseBuilder : QueryClauseBuilder { private readonly Expression _source; diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryableBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryableBuilder.cs index cc78913692..2faa590dc1 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryableBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryableBuilder.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources; @@ -13,6 +14,7 @@ namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding /// /// Drives conversion from into system trees. /// + [PublicAPI] public class QueryableBuilder { private readonly Expression _source; diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs index 641fccc41a..09f1d3c3ed 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Repositories; @@ -16,6 +17,7 @@ namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding /// /// Transforms into calls. /// + [PublicAPI] public class SelectClauseBuilder : QueryClauseBuilder { private static readonly ConstantExpression NullConstant = Expression.Constant(null); diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SkipTakeClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SkipTakeClauseBuilder.cs index ef812ad61f..70daaab698 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SkipTakeClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SkipTakeClauseBuilder.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Linq.Expressions; +using JetBrains.Annotations; using JsonApiDotNetCore.Queries.Expressions; namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding @@ -8,6 +9,7 @@ namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding /// /// Transforms into and calls. /// + [PublicAPI] public class SkipTakeClauseBuilder : QueryClauseBuilder { private readonly Expression _source; diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs index f0e985e9ff..25da976355 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using JetBrains.Annotations; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources.Annotations; @@ -12,6 +13,7 @@ namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding /// /// Transforms into calls. /// + [PublicAPI] public class WhereClauseBuilder : QueryClauseBuilder { private static readonly ConstantExpression NullConstant = Expression.Constant(null); diff --git a/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs b/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs index e351c44510..cedc3e6228 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources; @@ -11,6 +12,7 @@ namespace JsonApiDotNetCore.Queries.Internal /// /// Takes sparse fieldsets from s and invokes on them. /// + [PublicAPI] public sealed class SparseFieldSetCache { private readonly IResourceDefinitionAccessor _resourceDefinitionAccessor; diff --git a/src/JsonApiDotNetCore/Queries/QueryLayer.cs b/src/JsonApiDotNetCore/Queries/QueryLayer.cs index bed006b12c..c50146a329 100644 --- a/src/JsonApiDotNetCore/Queries/QueryLayer.cs +++ b/src/JsonApiDotNetCore/Queries/QueryLayer.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources.Annotations; @@ -11,6 +12,7 @@ namespace JsonApiDotNetCore.Queries /// /// A nested data structure that contains constraints per resource type. /// + [PublicAPI] public sealed class QueryLayer { public ResourceContext ResourceContext { get; } diff --git a/src/JsonApiDotNetCore/QueryStrings/IFilterQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/IFilterQueryStringParameterReader.cs index a9666d946c..49caf84786 100644 --- a/src/JsonApiDotNetCore/QueryStrings/IFilterQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/IFilterQueryStringParameterReader.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Queries; namespace JsonApiDotNetCore.QueryStrings @@ -5,6 +6,7 @@ namespace JsonApiDotNetCore.QueryStrings /// /// Reads the 'filter' query string parameter and produces a set of query constraints from it. /// + [PublicAPI] public interface IFilterQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider { } diff --git a/src/JsonApiDotNetCore/QueryStrings/IIncludeQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/IIncludeQueryStringParameterReader.cs index b03feed61c..e348f3635c 100644 --- a/src/JsonApiDotNetCore/QueryStrings/IIncludeQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/IIncludeQueryStringParameterReader.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Queries; namespace JsonApiDotNetCore.QueryStrings @@ -5,6 +6,7 @@ namespace JsonApiDotNetCore.QueryStrings /// /// Reads the 'include' query string parameter and produces a set of query constraints from it. /// + [PublicAPI] public interface IIncludeQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider { } diff --git a/src/JsonApiDotNetCore/QueryStrings/IPaginationQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/IPaginationQueryStringParameterReader.cs index 7d60dbec17..c41f417435 100644 --- a/src/JsonApiDotNetCore/QueryStrings/IPaginationQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/IPaginationQueryStringParameterReader.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Queries; namespace JsonApiDotNetCore.QueryStrings @@ -5,6 +6,7 @@ namespace JsonApiDotNetCore.QueryStrings /// /// Reads the 'page' query string parameter and produces a set of query constraints from it. /// + [PublicAPI] public interface IPaginationQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider { } diff --git a/src/JsonApiDotNetCore/QueryStrings/IResourceDefinitionQueryableParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/IResourceDefinitionQueryableParameterReader.cs index 5443dd58e8..58e1f18d40 100644 --- a/src/JsonApiDotNetCore/QueryStrings/IResourceDefinitionQueryableParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/IResourceDefinitionQueryableParameterReader.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Resources; @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.QueryStrings /// Reads custom query string parameters for which handlers on are registered /// and produces a set of query constraints from it. /// + [PublicAPI] public interface IResourceDefinitionQueryableParameterReader : IQueryStringParameterReader, IQueryConstraintProvider { } diff --git a/src/JsonApiDotNetCore/QueryStrings/ISortQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/ISortQueryStringParameterReader.cs index 6b66b43839..1fe5f4cb51 100644 --- a/src/JsonApiDotNetCore/QueryStrings/ISortQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/ISortQueryStringParameterReader.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Queries; namespace JsonApiDotNetCore.QueryStrings @@ -5,6 +6,7 @@ namespace JsonApiDotNetCore.QueryStrings /// /// Reads the 'sort' query string parameter and produces a set of query constraints from it. /// + [PublicAPI] public interface ISortQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider { } diff --git a/src/JsonApiDotNetCore/QueryStrings/ISparseFieldSetQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/ISparseFieldSetQueryStringParameterReader.cs index 7d48297e0a..7a307f1f40 100644 --- a/src/JsonApiDotNetCore/QueryStrings/ISparseFieldSetQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/ISparseFieldSetQueryStringParameterReader.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Queries; namespace JsonApiDotNetCore.QueryStrings @@ -5,6 +6,7 @@ namespace JsonApiDotNetCore.QueryStrings /// /// Reads the 'fields' query string parameter and produces a set of query constraints from it. /// + [PublicAPI] public interface ISparseFieldSetQueryStringParameterReader : IQueryStringParameterReader, IQueryConstraintProvider { } diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/DefaultsQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/DefaultsQueryStringParameterReader.cs index c58585f315..bf88cfb9e5 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/DefaultsQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/DefaultsQueryStringParameterReader.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers.Annotations; using JsonApiDotNetCore.Errors; @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.QueryStrings.Internal { /// + [PublicAPI] public class DefaultsQueryStringParameterReader : IDefaultsQueryStringParameterReader { private readonly IJsonApiOptions _options; diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs index c9830348b2..e8b1991f83 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers.Annotations; using JsonApiDotNetCore.Errors; @@ -14,6 +15,7 @@ namespace JsonApiDotNetCore.QueryStrings.Internal { + [PublicAPI] public class FilterQueryStringParameterReader : QueryStringParameterReader, IFilterQueryStringParameterReader { private static readonly LegacyFilterNotationConverter LegacyConverter = new LegacyFilterNotationConverter(); diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/IncludeQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/IncludeQueryStringParameterReader.cs index 5acf639640..f9dc9d30d7 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/IncludeQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/IncludeQueryStringParameterReader.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers.Annotations; using JsonApiDotNetCore.Errors; @@ -11,6 +12,7 @@ namespace JsonApiDotNetCore.QueryStrings.Internal { + [PublicAPI] public class IncludeQueryStringParameterReader : QueryStringParameterReader, IIncludeQueryStringParameterReader { private readonly IJsonApiOptions _options; diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs index aa9aba3211..ae8e7a2230 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/LegacyFilterNotationConverter.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Queries.Internal.Parsing; namespace JsonApiDotNetCore.QueryStrings.Internal { + [PublicAPI] public sealed class LegacyFilterNotationConverter { private const string ParameterNamePrefix = "filter["; diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/NullsQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/NullsQueryStringParameterReader.cs index ea3236b8e5..98658bd356 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/NullsQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/NullsQueryStringParameterReader.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers.Annotations; using JsonApiDotNetCore.Errors; @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.QueryStrings.Internal { /// + [PublicAPI] public class NullsQueryStringParameterReader : INullsQueryStringParameterReader { private readonly IJsonApiOptions _options; diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/PaginationQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/PaginationQueryStringParameterReader.cs index 1b62d0b86c..0eb3a71b49 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/PaginationQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/PaginationQueryStringParameterReader.cs @@ -13,6 +13,7 @@ namespace JsonApiDotNetCore.QueryStrings.Internal { + [PublicAPI] public class PaginationQueryStringParameterReader : QueryStringParameterReader, IPaginationQueryStringParameterReader { private const string PageSizeParameterName = "page[size]"; diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringReader.cs index 22ccfb3f41..6297463a4f 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringReader.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers.Annotations; using JsonApiDotNetCore.Errors; @@ -8,6 +9,7 @@ namespace JsonApiDotNetCore.QueryStrings.Internal { /// + [PublicAPI] public class QueryStringReader : IQueryStringReader { private readonly IJsonApiOptions _options; diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/ResourceDefinitionQueryableParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/ResourceDefinitionQueryableParameterReader.cs index 9f29d4456a..868551fa26 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/ResourceDefinitionQueryableParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/ResourceDefinitionQueryableParameterReader.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Controllers.Annotations; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Middleware; @@ -10,6 +11,7 @@ namespace JsonApiDotNetCore.QueryStrings.Internal { /// + [PublicAPI] public class ResourceDefinitionQueryableParameterReader : IResourceDefinitionQueryableParameterReader { private readonly IJsonApiRequest _request; diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/SortQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/SortQueryStringParameterReader.cs index af6a56ccad..e9ca858acf 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/SortQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/SortQueryStringParameterReader.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers.Annotations; using JsonApiDotNetCore.Errors; @@ -12,6 +13,7 @@ namespace JsonApiDotNetCore.QueryStrings.Internal { + [PublicAPI] public class SortQueryStringParameterReader : QueryStringParameterReader, ISortQueryStringParameterReader { private readonly QueryStringParameterScopeParser _scopeParser; diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs index 7f790b71af..b1cc88afdc 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/SparseFieldSetQueryStringParameterReader.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers.Annotations; using JsonApiDotNetCore.Errors; @@ -13,6 +14,7 @@ namespace JsonApiDotNetCore.QueryStrings.Internal { + [PublicAPI] public class SparseFieldSetQueryStringParameterReader : QueryStringParameterReader, ISparseFieldSetQueryStringParameterReader { private readonly SparseFieldTypeParser _sparseFieldTypeParser; diff --git a/src/JsonApiDotNetCore/Repositories/DataStoreUpdateException.cs b/src/JsonApiDotNetCore/Repositories/DataStoreUpdateException.cs index 9ce5d31c1c..80a1b85a77 100644 --- a/src/JsonApiDotNetCore/Repositories/DataStoreUpdateException.cs +++ b/src/JsonApiDotNetCore/Repositories/DataStoreUpdateException.cs @@ -1,10 +1,12 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Repositories { /// /// The error that is thrown when the underlying data store is unable to persist changes. /// + [PublicAPI] public sealed class DataStoreUpdateException : Exception { public DataStoreUpdateException(Exception exception) diff --git a/src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs b/src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs index ffe1a399e1..5adfbc2c8f 100644 --- a/src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs +++ b/src/JsonApiDotNetCore/Repositories/DbContextExtensions.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; namespace JsonApiDotNetCore.Repositories { + [PublicAPI] public static class DbContextExtensions { /// diff --git a/src/JsonApiDotNetCore/Repositories/DbContextResolver.cs b/src/JsonApiDotNetCore/Repositories/DbContextResolver.cs index 1cdee231d2..9b8f1327ce 100644 --- a/src/JsonApiDotNetCore/Repositories/DbContextResolver.cs +++ b/src/JsonApiDotNetCore/Repositories/DbContextResolver.cs @@ -1,8 +1,10 @@ +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; namespace JsonApiDotNetCore.Repositories { /// + [PublicAPI] public sealed class DbContextResolver : IDbContextResolver where TDbContext : DbContext { diff --git a/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs b/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs index 420e8c21a6..95f525ed7c 100644 --- a/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs +++ b/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Middleware; @@ -22,6 +23,7 @@ namespace JsonApiDotNetCore.Repositories /// /// Implements the foundational Repository layer in the JsonApiDotNetCore architecture that uses Entity Framework Core. /// + [PublicAPI] public class EntityFrameworkCoreRepository : IResourceRepository, IRepositorySupportsTransaction where TResource : class, IIdentifiable { @@ -159,7 +161,7 @@ public virtual async Task CreateAsync(TResource resourceFromRequest, TResource r } var dbSet = _dbContext.Set(); - dbSet.Add(resourceForDatabase); + await dbSet.AddAsync(resourceForDatabase, cancellationToken); await SaveChangesAsync(cancellationToken); } @@ -432,6 +434,7 @@ protected virtual async Task SaveChangesAsync(CancellationToken cancellationToke /// /// Implements the foundational Repository layer in the JsonApiDotNetCore architecture that uses Entity Framework Core. /// + [PublicAPI] public class EntityFrameworkCoreRepository : EntityFrameworkCoreRepository, IResourceRepository where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/Repositories/IRepositorySupportsTransaction.cs b/src/JsonApiDotNetCore/Repositories/IRepositorySupportsTransaction.cs index 42026e9712..fb1f026d31 100644 --- a/src/JsonApiDotNetCore/Repositories/IRepositorySupportsTransaction.cs +++ b/src/JsonApiDotNetCore/Repositories/IRepositorySupportsTransaction.cs @@ -1,10 +1,12 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Repositories { /// /// Used to indicate that an supports execution inside a transaction. /// + [PublicAPI] public interface IRepositorySupportsTransaction { /// diff --git a/src/JsonApiDotNetCore/Repositories/IResourceReadRepository.cs b/src/JsonApiDotNetCore/Repositories/IResourceReadRepository.cs index 907792c8b7..ec373094db 100644 --- a/src/JsonApiDotNetCore/Repositories/IResourceReadRepository.cs +++ b/src/JsonApiDotNetCore/Repositories/IResourceReadRepository.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Resources; @@ -18,6 +19,7 @@ public interface IResourceReadRepository /// /// The resource type. /// The resource identifier type. + [PublicAPI] public interface IResourceReadRepository where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/Repositories/IResourceRepository.cs b/src/JsonApiDotNetCore/Repositories/IResourceRepository.cs index 9400612d82..266672cf77 100644 --- a/src/JsonApiDotNetCore/Repositories/IResourceRepository.cs +++ b/src/JsonApiDotNetCore/Repositories/IResourceRepository.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCore.Repositories @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Repositories /// Represents the foundational Resource Repository layer in the JsonApiDotNetCore architecture that provides data access to an underlying store. /// /// The resource type. + [PublicAPI] public interface IResourceRepository : IResourceRepository, IResourceReadRepository, IResourceWriteRepository where TResource : class, IIdentifiable diff --git a/src/JsonApiDotNetCore/Repositories/IResourceWriteRepository.cs b/src/JsonApiDotNetCore/Repositories/IResourceWriteRepository.cs index 27244c5f17..35f7ab1459 100644 --- a/src/JsonApiDotNetCore/Repositories/IResourceWriteRepository.cs +++ b/src/JsonApiDotNetCore/Repositories/IResourceWriteRepository.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Resources; @@ -17,6 +18,7 @@ public interface IResourceWriteRepository /// /// The resource type. /// The resource identifier type. + [PublicAPI] public interface IResourceWriteRepository where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/Repositories/MemoryLeakDetectionBugRewriter.cs b/src/JsonApiDotNetCore/Repositories/MemoryLeakDetectionBugRewriter.cs index e27894ac7a..0b7509fc28 100644 --- a/src/JsonApiDotNetCore/Repositories/MemoryLeakDetectionBugRewriter.cs +++ b/src/JsonApiDotNetCore/Repositories/MemoryLeakDetectionBugRewriter.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Resources; @@ -14,6 +15,7 @@ namespace JsonApiDotNetCore.Repositories /// Note that by using this workaround, nested filtering, paging and sorting all remain broken in EF Core 3.1 when using injected parameters in resources. /// But at least it enables simple top-level queries to succeed without an exception. /// + [PublicAPI] public sealed class MemoryLeakDetectionBugRewriter { public QueryLayer Rewrite(QueryLayer queryLayer) diff --git a/src/JsonApiDotNetCore/Repositories/PlaceholderResourceCollector.cs b/src/JsonApiDotNetCore/Repositories/PlaceholderResourceCollector.cs index c29e974efc..3dfa3c9d99 100644 --- a/src/JsonApiDotNetCore/Repositories/PlaceholderResourceCollector.cs +++ b/src/JsonApiDotNetCore/Repositories/PlaceholderResourceCollector.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; using Microsoft.EntityFrameworkCore; @@ -10,6 +11,7 @@ namespace JsonApiDotNetCore.Repositories /// Entity Framework Core change tracker so they can be used in relationship updates without fetching the resource. /// On disposal, the created placeholders are detached, leaving the change tracker in a clean state for reuse. /// + [PublicAPI] public sealed class PlaceholderResourceCollector : IDisposable { private readonly IResourceFactory _resourceFactory; diff --git a/src/JsonApiDotNetCore/Repositories/ResourceRepositoryAccessor.cs b/src/JsonApiDotNetCore/Repositories/ResourceRepositoryAccessor.cs index aafc518106..8dfe3971e3 100644 --- a/src/JsonApiDotNetCore/Repositories/ResourceRepositoryAccessor.cs +++ b/src/JsonApiDotNetCore/Repositories/ResourceRepositoryAccessor.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Middleware; @@ -13,6 +14,7 @@ namespace JsonApiDotNetCore.Repositories { /// + [PublicAPI] public class ResourceRepositoryAccessor : IResourceRepositoryAccessor { private readonly IServiceProvider _serviceProvider; diff --git a/src/JsonApiDotNetCore/Resources/Annotations/AttrAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/AttrAttribute.cs index f2e11ac449..bd19f5e850 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/AttrAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/AttrAttribute.cs @@ -1,10 +1,12 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Resources.Annotations { /// /// Used to expose a property on a resource class as a JSON:API attribute (https://jsonapi.org/format/#document-resource-object-attributes). /// + [PublicAPI] [AttributeUsage(AttributeTargets.Property)] public sealed class AttrAttribute : ResourceFieldAttribute { diff --git a/src/JsonApiDotNetCore/Resources/Annotations/EagerLoadAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/EagerLoadAttribute.cs index bb31d018ef..17685ccd47 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/EagerLoadAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/EagerLoadAttribute.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Resources.Annotations { @@ -33,6 +34,7 @@ namespace JsonApiDotNetCore.Resources.Annotations /// } /// ]]> /// + [PublicAPI] [AttributeUsage(AttributeTargets.Property)] public sealed class EagerLoadAttribute : Attribute { diff --git a/src/JsonApiDotNetCore/Resources/Annotations/HasManyThroughAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/HasManyThroughAttribute.cs index a245fee0fd..49124a6822 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/HasManyThroughAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/HasManyThroughAttribute.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using JetBrains.Annotations; // ReSharper disable NonReadonlyMemberInGetHashCode @@ -42,6 +43,7 @@ namespace JsonApiDotNetCore.Resources.Annotations /// } /// ]]> /// + [PublicAPI] [AttributeUsage(AttributeTargets.Property)] public sealed class HasManyThroughAttribute : HasManyAttribute { diff --git a/src/JsonApiDotNetCore/Resources/Annotations/RelationshipAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/RelationshipAttribute.cs index 9003c25706..cd7188b3a5 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/RelationshipAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/RelationshipAttribute.cs @@ -1,5 +1,6 @@ using System; using System.Reflection; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; // ReSharper disable NonReadonlyMemberInGetHashCode @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Resources.Annotations /// /// Used to expose a property on a resource class as a JSON:API relationship (https://jsonapi.org/format/#document-resource-object-relationships). /// + [PublicAPI] public abstract class RelationshipAttribute : ResourceFieldAttribute { /// diff --git a/src/JsonApiDotNetCore/Resources/Annotations/ResourceAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/ResourceAttribute.cs index f44666f492..df3227acf1 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/ResourceAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/ResourceAttribute.cs @@ -1,10 +1,12 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Resources.Annotations { /// /// When put on a resource class, overrides the convention-based resource name. /// + [PublicAPI] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface)] public sealed class ResourceAttribute : Attribute { diff --git a/src/JsonApiDotNetCore/Resources/Annotations/ResourceFieldAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/ResourceFieldAttribute.cs index 725be216b7..c538c6a12c 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/ResourceFieldAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/ResourceFieldAttribute.cs @@ -1,5 +1,6 @@ using System; using System.Reflection; +using JetBrains.Annotations; // ReSharper disable NonReadonlyMemberInGetHashCode @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Resources.Annotations /// Used to expose a property on a resource class as a JSON:API field (attribute or relationship). /// See https://jsonapi.org/format/#document-resource-object-fields. /// + [PublicAPI] public abstract class ResourceFieldAttribute : Attribute { private string _publicName; diff --git a/src/JsonApiDotNetCore/Resources/Annotations/ResourceLinksAttribute.cs b/src/JsonApiDotNetCore/Resources/Annotations/ResourceLinksAttribute.cs index 4a4e73027e..ede3a402be 100644 --- a/src/JsonApiDotNetCore/Resources/Annotations/ResourceLinksAttribute.cs +++ b/src/JsonApiDotNetCore/Resources/Annotations/ResourceLinksAttribute.cs @@ -1,4 +1,5 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; namespace JsonApiDotNetCore.Resources.Annotations @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Resources.Annotations /// /// When put on a resource class, overrides global configuration for which links to render. /// + [PublicAPI] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface)] public sealed class ResourceLinksAttribute : Attribute { diff --git a/src/JsonApiDotNetCore/Resources/IResourceDefinition.cs b/src/JsonApiDotNetCore/Resources/IResourceDefinition.cs index 5273e7638e..0ca5e77950 100644 --- a/src/JsonApiDotNetCore/Resources/IResourceDefinition.cs +++ b/src/JsonApiDotNetCore/Resources/IResourceDefinition.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Queries.Expressions; namespace JsonApiDotNetCore.Resources @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Resources /// The goal here is to reduce the need for overriding the service and repository layers. /// /// The resource type. + [PublicAPI] public interface IResourceDefinition : IResourceDefinition where TResource : class, IIdentifiable { @@ -20,6 +22,7 @@ public interface IResourceDefinition : IResourceDefinition /// The resource type. /// The resource identifier type. + [PublicAPI] public interface IResourceDefinition where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/Resources/IdentifiableComparer.cs b/src/JsonApiDotNetCore/Resources/IdentifiableComparer.cs index 99885c951f..21782057db 100644 --- a/src/JsonApiDotNetCore/Resources/IdentifiableComparer.cs +++ b/src/JsonApiDotNetCore/Resources/IdentifiableComparer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Resources { @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Resources /// Compares `IIdentifiable` instances with each other based on their type and , /// falling back to when both StringIds are null. /// + [PublicAPI] public sealed class IdentifiableComparer : IEqualityComparer { public static readonly IdentifiableComparer Instance = new IdentifiableComparer(); diff --git a/src/JsonApiDotNetCore/Resources/JsonApiResourceDefinition.cs b/src/JsonApiDotNetCore/Resources/JsonApiResourceDefinition.cs index bc5778a8b5..1d3e945c00 100644 --- a/src/JsonApiDotNetCore/Resources/JsonApiResourceDefinition.cs +++ b/src/JsonApiDotNetCore/Resources/JsonApiResourceDefinition.cs @@ -3,6 +3,7 @@ using System.ComponentModel; using System.Linq; using System.Linq.Expressions; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; @@ -13,6 +14,7 @@ namespace JsonApiDotNetCore.Resources /// The goal here is to reduce the need for overriding the service and repository layers. /// /// The resource type. + [PublicAPI] public class JsonApiResourceDefinition : JsonApiResourceDefinition, IResourceDefinition where TResource : class, IIdentifiable { @@ -23,6 +25,7 @@ public JsonApiResourceDefinition(IResourceGraph resourceGraph) } /// + [PublicAPI] public class JsonApiResourceDefinition : IResourceDefinition where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/Resources/OperationContainer.cs b/src/JsonApiDotNetCore/Resources/OperationContainer.cs index a9df285e8f..083ecc8dd4 100644 --- a/src/JsonApiDotNetCore/Resources/OperationContainer.cs +++ b/src/JsonApiDotNetCore/Resources/OperationContainer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Middleware; namespace JsonApiDotNetCore.Resources @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Resources /// /// Represents a write operation on a JSON:API resource. /// + [PublicAPI] public sealed class OperationContainer { public OperationKind Kind { get; } diff --git a/src/JsonApiDotNetCore/Resources/ResourceChangeTracker.cs b/src/JsonApiDotNetCore/Resources/ResourceChangeTracker.cs index 24be52dea2..f4e88c8c27 100644 --- a/src/JsonApiDotNetCore/Resources/ResourceChangeTracker.cs +++ b/src/JsonApiDotNetCore/Resources/ResourceChangeTracker.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources.Annotations; using Newtonsoft.Json; @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Resources { /// + [PublicAPI] public sealed class ResourceChangeTracker : IResourceChangeTracker where TResource : class, IIdentifiable { private readonly IJsonApiOptions _options; diff --git a/src/JsonApiDotNetCore/Resources/ResourceDefinitionAccessor.cs b/src/JsonApiDotNetCore/Resources/ResourceDefinitionAccessor.cs index bf71e8bfbe..fe5dc40088 100644 --- a/src/JsonApiDotNetCore/Resources/ResourceDefinitionAccessor.cs +++ b/src/JsonApiDotNetCore/Resources/ResourceDefinitionAccessor.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries.Expressions; using Microsoft.Extensions.DependencyInjection; @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Resources { /// + [PublicAPI] public class ResourceDefinitionAccessor : IResourceDefinitionAccessor { private readonly IResourceContextProvider _resourceContextProvider; diff --git a/src/JsonApiDotNetCore/Resources/ResourceHooksDefinition.cs b/src/JsonApiDotNetCore/Resources/ResourceHooksDefinition.cs index 1ab143f43d..6b20919de2 100644 --- a/src/JsonApiDotNetCore/Resources/ResourceHooksDefinition.cs +++ b/src/JsonApiDotNetCore/Resources/ResourceHooksDefinition.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Hooks.Internal; using JsonApiDotNetCore.Hooks.Internal.Execution; @@ -11,6 +12,7 @@ namespace JsonApiDotNetCore.Resources /// The goal of this class is to reduce the frequency with which developers have to override the service and repository layers. /// /// The resource type. + [PublicAPI] public class ResourceHooksDefinition : IResourceHookContainer where TResource : class, IIdentifiable { protected IResourceGraph ResourceGraph { get; } diff --git a/src/JsonApiDotNetCore/Serialization/AtomicOperationsResponseSerializer.cs b/src/JsonApiDotNetCore/Serialization/AtomicOperationsResponseSerializer.cs index 526db5ffb2..b9692bfac2 100644 --- a/src/JsonApiDotNetCore/Serialization/AtomicOperationsResponseSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/AtomicOperationsResponseSerializer.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.Resources; @@ -12,6 +13,7 @@ namespace JsonApiDotNetCore.Serialization /// /// Server serializer implementation of for atomic:operations responses. /// + [PublicAPI] public sealed class AtomicOperationsResponseSerializer : BaseSerializer, IJsonApiSerializer { private readonly IMetaBuilder _metaBuilder; diff --git a/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs b/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs index d24bb4fb9b..070f501d01 100644 --- a/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs +++ b/src/JsonApiDotNetCore/Serialization/BaseDeserializer.cs @@ -17,6 +17,7 @@ namespace JsonApiDotNetCore.Serialization /// Abstract base class for deserialization. Deserializes JSON content into s /// and constructs instances of the resource(s) in the document body. /// + [PublicAPI] public abstract class BaseDeserializer { protected IResourceContextProvider ResourceContextProvider { get; } diff --git a/src/JsonApiDotNetCore/Serialization/Building/IMetaBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/IMetaBuilder.cs index c56607db75..0a83126407 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/IMetaBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/IMetaBuilder.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Serialization.Building { /// /// Builds the top-level meta object. /// + [PublicAPI] public interface IMetaBuilder { /// diff --git a/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs index 8749121f6b..a590fa0063 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs @@ -1,6 +1,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Queries.Internal; @@ -10,6 +11,7 @@ namespace JsonApiDotNetCore.Serialization.Building { + [PublicAPI] public class IncludedResourceObjectBuilder : ResourceObjectBuilder, IIncludedResourceObjectBuilder { private readonly HashSet _included; diff --git a/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs index c6705c4a23..db15f31300 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/LinkBuilder.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.Queries; @@ -15,6 +16,7 @@ namespace JsonApiDotNetCore.Serialization.Building { + [PublicAPI] public class LinkBuilder : ILinkBuilder { private const string PageSizeParameterName = "page[size]"; diff --git a/src/JsonApiDotNetCore/Serialization/Building/MetaBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/MetaBuilder.cs index 2b3cef07cc..d641910969 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/MetaBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/MetaBuilder.cs @@ -1,11 +1,13 @@ using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries; namespace JsonApiDotNetCore.Serialization.Building { /// + [PublicAPI] public class MetaBuilder : IMetaBuilder { private readonly IPaginationContext _paginationContext; diff --git a/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs index c0a0e8eb67..f76e8391e4 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Serialization.Building { /// + [PublicAPI] public class ResourceObjectBuilder : IResourceObjectBuilder { protected IResourceContextProvider ResourceContextProvider { get; } diff --git a/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilderSettings.cs b/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilderSettings.cs index c6ecf2234b..b14ea44ea3 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilderSettings.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilderSettings.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; using Newtonsoft.Json; @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Serialization.Building /// Options used to configure how fields of a model get serialized into /// a JSON:API . /// + [PublicAPI] public sealed class ResourceObjectBuilderSettings { public NullValueHandling SerializerNullValueHandling { get; } diff --git a/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs index 9e6c9e9f39..eb3e445c94 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/ResponseResourceObjectBuilder.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Queries.Expressions; @@ -11,6 +12,7 @@ namespace JsonApiDotNetCore.Serialization.Building { + [PublicAPI] public class ResponseResourceObjectBuilder : ResourceObjectBuilder { private readonly IIncludedResourceObjectBuilder _includedBuilder; diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/DeserializedResponseBase.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/DeserializedResponseBase.cs index c2831e327e..14587a1cb2 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/DeserializedResponseBase.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/DeserializedResponseBase.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Serialization.Objects; namespace JsonApiDotNetCore.Serialization.Client.Internal @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Serialization.Client.Internal /// TODO: Currently and /// information is ignored by the serializer. This is out of scope for now because /// it is not considered mission critical for v4. + [PublicAPI] public abstract class DeserializedResponseBase { public TopLevelLinks Links { get; set; } diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/IRequestSerializer.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/IRequestSerializer.cs index 94c0556a49..86e2b8bcbf 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/IRequestSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/IRequestSerializer.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Serialization.Client.Internal /// Interface for client serializer that can be used to register with the DI container, for usage in /// custom services or repositories. /// + [PublicAPI] public interface IRequestSerializer { /// diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/IResponseDeserializer.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/IResponseDeserializer.cs index c4ede45737..6d29d2779d 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/IResponseDeserializer.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/IResponseDeserializer.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCore.Serialization.Client.Internal @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Serialization.Client.Internal /// except for in the tests. Exposed publicly to make testing easier or to implement /// server-to-server communication. /// + [PublicAPI] public interface IResponseDeserializer { /// diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/ManyResponse.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/ManyResponse.cs index 954b65e167..c48a3f54b9 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/ManyResponse.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/ManyResponse.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCore.Serialization.Client.Internal @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Serialization.Client.Internal /// Represents a deserialized document with "many data". /// /// Type of the resource(s) in the primary data. + [PublicAPI] public sealed class ManyResponse : DeserializedResponseBase where TResource : class, IIdentifiable { public IReadOnlyCollection Data { get; set; } diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs index e980253fc2..61d3c5a2fe 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/RequestSerializer.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; @@ -13,6 +14,7 @@ namespace JsonApiDotNetCore.Serialization.Client.Internal /// /// Client serializer implementation of . /// + [PublicAPI] public class RequestSerializer : BaseSerializer, IRequestSerializer { private Type _currentTargetedResource; diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs index fda86b3437..a9e4232076 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/ResponseDeserializer.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; @@ -11,6 +12,7 @@ namespace JsonApiDotNetCore.Serialization.Client.Internal /// /// Client deserializer implementation of the . /// + [PublicAPI] public class ResponseDeserializer : BaseDeserializer, IResponseDeserializer { public ResponseDeserializer(IResourceContextProvider resourceContextProvider, IResourceFactory resourceFactory) : base(resourceContextProvider, resourceFactory) { } diff --git a/src/JsonApiDotNetCore/Serialization/Client/Internal/SingleResponse.cs b/src/JsonApiDotNetCore/Serialization/Client/Internal/SingleResponse.cs index 562317f2bf..d40421567b 100644 --- a/src/JsonApiDotNetCore/Serialization/Client/Internal/SingleResponse.cs +++ b/src/JsonApiDotNetCore/Serialization/Client/Internal/SingleResponse.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCore.Serialization.Client.Internal @@ -6,6 +7,7 @@ namespace JsonApiDotNetCore.Serialization.Client.Internal /// Represents a deserialized document with "single data". /// /// Type of the resource in the primary data. + [PublicAPI] public sealed class SingleResponse : DeserializedResponseBase where TResource : class, IIdentifiable { public TResource Data { get; set; } diff --git a/src/JsonApiDotNetCore/Serialization/FieldsToSerialize.cs b/src/JsonApiDotNetCore/Serialization/FieldsToSerialize.cs index cbbb062769..aea6a2d1e7 100644 --- a/src/JsonApiDotNetCore/Serialization/FieldsToSerialize.cs +++ b/src/JsonApiDotNetCore/Serialization/FieldsToSerialize.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.Queries; @@ -11,6 +12,7 @@ namespace JsonApiDotNetCore.Serialization { /// + [PublicAPI] public class FieldsToSerialize : IFieldsToSerialize { private readonly IResourceContextProvider _resourceContextProvider; diff --git a/src/JsonApiDotNetCore/Serialization/IJsonApiReader.cs b/src/JsonApiDotNetCore/Serialization/IJsonApiReader.cs index 37fc344c0e..9313d5b8c6 100644 --- a/src/JsonApiDotNetCore/Serialization/IJsonApiReader.cs +++ b/src/JsonApiDotNetCore/Serialization/IJsonApiReader.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc.Formatters; namespace JsonApiDotNetCore.Serialization @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Serialization /// The deserializer of the body, used in ASP.NET Core internally /// to process `FromBody`. /// + [PublicAPI] public interface IJsonApiReader { Task ReadAsync(InputFormatterContext context); diff --git a/src/JsonApiDotNetCore/Serialization/IJsonApiSerializerFactory.cs b/src/JsonApiDotNetCore/Serialization/IJsonApiSerializerFactory.cs index 75d7f928af..38796a596e 100644 --- a/src/JsonApiDotNetCore/Serialization/IJsonApiSerializerFactory.cs +++ b/src/JsonApiDotNetCore/Serialization/IJsonApiSerializerFactory.cs @@ -1,5 +1,8 @@ -namespace JsonApiDotNetCore.Serialization +using JetBrains.Annotations; + +namespace JsonApiDotNetCore.Serialization { + [PublicAPI] public interface IJsonApiSerializerFactory { /// @@ -7,4 +10,4 @@ public interface IJsonApiSerializerFactory /// IJsonApiSerializer GetSerializer(); } -} \ No newline at end of file +} diff --git a/src/JsonApiDotNetCore/Serialization/IJsonApiWriter.cs b/src/JsonApiDotNetCore/Serialization/IJsonApiWriter.cs index 0f8287801a..ac29395115 100644 --- a/src/JsonApiDotNetCore/Serialization/IJsonApiWriter.cs +++ b/src/JsonApiDotNetCore/Serialization/IJsonApiWriter.cs @@ -1,10 +1,12 @@ using System.Threading.Tasks; +using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc.Formatters; namespace JsonApiDotNetCore.Serialization { + [PublicAPI] public interface IJsonApiWriter { Task WriteAsync(OutputFormatterWriteContext context); } -} \ No newline at end of file +} diff --git a/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs b/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs index 7e2eed758c..91d4fc80b9 100644 --- a/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs +++ b/src/JsonApiDotNetCore/Serialization/JsonApiReader.cs @@ -21,6 +21,7 @@ namespace JsonApiDotNetCore.Serialization { /// + [PublicAPI] public class JsonApiReader : IJsonApiReader { private readonly IJsonApiDeserializer _deserializer; diff --git a/src/JsonApiDotNetCore/Serialization/JsonApiSerializationException.cs b/src/JsonApiDotNetCore/Serialization/JsonApiSerializationException.cs index 92848c3eca..a575ce59d8 100644 --- a/src/JsonApiDotNetCore/Serialization/JsonApiSerializationException.cs +++ b/src/JsonApiDotNetCore/Serialization/JsonApiSerializationException.cs @@ -1,10 +1,12 @@ using System; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Serialization { /// /// The error that is thrown when (de)serialization of a JSON:API body fails. /// + [PublicAPI] public class JsonApiSerializationException : Exception { public string GenericMessage { get; } diff --git a/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs b/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs index ea97a0e936..8608101ed4 100644 --- a/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs +++ b/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs @@ -4,6 +4,7 @@ using System.Net.Http; using System.Text; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Errors; using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.Serialization.Objects; @@ -18,6 +19,7 @@ namespace JsonApiDotNetCore.Serialization /// Formats the response data used (see https://docs.microsoft.com/en-us/aspnet/core/web-api/advanced/formatting?view=aspnetcore-3.0). /// It was intended to have as little dependencies as possible in formatting layer for greater extensibility. /// + [PublicAPI] public class JsonApiWriter : IJsonApiWriter { private readonly IJsonApiSerializer _serializer; diff --git a/src/JsonApiDotNetCore/Serialization/Objects/Error.cs b/src/JsonApiDotNetCore/Serialization/Objects/Error.cs index ffc7c38ef4..545c71da54 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/Error.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/Error.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Net; +using JetBrains.Annotations; using Newtonsoft.Json; namespace JsonApiDotNetCore.Serialization.Objects @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Serialization.Objects /// Provides additional information about a problem encountered while performing an operation. /// Error objects MUST be returned as an array keyed by errors in the top level of a JSON:API document. /// + [PublicAPI] public sealed class Error { public Error(HttpStatusCode statusCode) diff --git a/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs b/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs index 1604c286c8..67d0e82a27 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs @@ -2,9 +2,11 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Serialization.Objects { + [PublicAPI] public sealed class ErrorDocument { public IReadOnlyList Errors { get; } diff --git a/src/JsonApiDotNetCore/Serialization/Objects/ErrorMeta.cs b/src/JsonApiDotNetCore/Serialization/Objects/ErrorMeta.cs index 43b327c359..9c4477dd02 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/ErrorMeta.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/ErrorMeta.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using Newtonsoft.Json; namespace JsonApiDotNetCore.Serialization.Objects @@ -7,6 +8,7 @@ namespace JsonApiDotNetCore.Serialization.Objects /// /// A meta object containing non-standard meta-information about the error. /// + [PublicAPI] public sealed class ErrorMeta { [JsonExtensionData] diff --git a/src/JsonApiDotNetCore/Serialization/Objects/ExposableData.cs b/src/JsonApiDotNetCore/Serialization/Objects/ExposableData.cs index 06ba76ba39..40292cfb36 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/ExposableData.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/ExposableData.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace JsonApiDotNetCore.Serialization.Objects { + [PublicAPI] public abstract class ExposableData where TResource : class { /// diff --git a/src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs b/src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs index b53be1e7e6..746e12654b 100644 --- a/src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs +++ b/src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs @@ -17,6 +17,7 @@ namespace JsonApiDotNetCore.Serialization /// /// Server deserializer implementation of the . /// + [PublicAPI] public class RequestDeserializer : BaseDeserializer, IJsonApiDeserializer { private readonly ITargetedFields _targetedFields; diff --git a/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs b/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs index 45711086fd..70f5fca56b 100644 --- a/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs +++ b/src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.Resources; @@ -21,6 +22,7 @@ namespace JsonApiDotNetCore.Serialization /// /// Type of the resource associated with the scope of the request /// for which this serializer is used. + [PublicAPI] public class ResponseSerializer : BaseSerializer, IJsonApiSerializer where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/Serialization/ResponseSerializerFactory.cs b/src/JsonApiDotNetCore/Serialization/ResponseSerializerFactory.cs index 0a1722b7be..4b6b1c12b5 100644 --- a/src/JsonApiDotNetCore/Serialization/ResponseSerializerFactory.cs +++ b/src/JsonApiDotNetCore/Serialization/ResponseSerializerFactory.cs @@ -1,4 +1,5 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Middleware; using Microsoft.Extensions.DependencyInjection; @@ -9,6 +10,7 @@ namespace JsonApiDotNetCore.Serialization /// A factory class to abstract away the initialization of the serializer from the /// ASP.NET Core formatter pipeline. /// + [PublicAPI] public class ResponseSerializerFactory : IJsonApiSerializerFactory { private readonly IServiceProvider _provider; diff --git a/src/JsonApiDotNetCore/Services/AsyncCollectionExtensions.cs b/src/JsonApiDotNetCore/Services/AsyncCollectionExtensions.cs index 923c473ecf..be11ea908e 100644 --- a/src/JsonApiDotNetCore/Services/AsyncCollectionExtensions.cs +++ b/src/JsonApiDotNetCore/Services/AsyncCollectionExtensions.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Services { + [PublicAPI] public static class AsyncCollectionExtensions { public static async Task AddRangeAsync(this ICollection source, IAsyncEnumerable elementsToAdd, CancellationToken cancellationToken = default) diff --git a/src/JsonApiDotNetCore/Services/IAddToRelationshipService.cs b/src/JsonApiDotNetCore/Services/IAddToRelationshipService.cs index 49baddbcf3..8561348486 100644 --- a/src/JsonApiDotNetCore/Services/IAddToRelationshipService.cs +++ b/src/JsonApiDotNetCore/Services/IAddToRelationshipService.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCore.Services @@ -11,6 +12,7 @@ public interface IAddToRelationshipService : IAddToRelationshipServic { } /// + [PublicAPI] public interface IAddToRelationshipService where TResource : class, IIdentifiable { diff --git a/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs b/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs index bf2fbca932..4ea52f6743 100644 --- a/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs +++ b/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs @@ -20,6 +20,7 @@ namespace JsonApiDotNetCore.Services { /// + [PublicAPI] public class JsonApiResourceService : IResourceService where TResource : class, IIdentifiable @@ -470,6 +471,7 @@ private void AssertHasRelationship(RelationshipAttribute relationship, string na /// Represents the foundational Resource Service layer in the JsonApiDotNetCore architecture that uses a Resource Repository for data access. /// /// The resource type. + [PublicAPI] public class JsonApiResourceService : JsonApiResourceService, IResourceService where TResource : class, IIdentifiable diff --git a/test/TestBuildingBlocks/FakeLoggerFactory.cs b/test/TestBuildingBlocks/FakeLoggerFactory.cs index f474e6a2e3..f62dea7e71 100644 --- a/test/TestBuildingBlocks/FakeLoggerFactory.cs +++ b/test/TestBuildingBlocks/FakeLoggerFactory.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using JetBrains.Annotations; using Microsoft.Extensions.Logging; namespace TestBuildingBlocks { + [PublicAPI] public sealed class FakeLoggerFactory : ILoggerFactory, ILoggerProvider { public FakeLogger Logger { get; } diff --git a/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs b/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs index c8be07454a..9026441f0e 100644 --- a/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs +++ b/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs @@ -3,11 +3,13 @@ using System.Threading.Tasks; using FluentAssertions; using FluentAssertions.Primitives; +using JetBrains.Annotations; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace TestBuildingBlocks { + [PublicAPI] public static class HttpResponseMessageExtensions { public static HttpResponseMessageAssertions Should(this HttpResponseMessage instance) diff --git a/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs b/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs index f0fe3825ed..a7f826de75 100644 --- a/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs +++ b/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs @@ -2,11 +2,13 @@ using FluentAssertions; using FluentAssertions.Numeric; using FluentAssertions.Primitives; +using JetBrains.Annotations; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace TestBuildingBlocks { + [PublicAPI] public static class ObjectAssertionsExtensions { private const decimal NumericPrecision = 0.00000000001M; From 7f1b5337b86a3928d8b6b34b8140ba91e34612ec Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Thu, 25 Feb 2021 14:20:57 +0100 Subject: [PATCH 48/60] Cleanup Startups --- src/Examples/GettingStarted/Startup.cs | 2 ++ .../JsonApiDotNetCoreExample/Startups/EmptyStartup.cs | 5 ----- src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs | 1 - src/Examples/MultiDbContextExample/Startup.cs | 2 ++ src/Examples/NoEntityFrameworkExample/Startup.cs | 2 ++ .../IntegrationTests/HostingInIIS/HostingStartup.cs | 5 ----- .../NamingConventions/KebabCasingConventionStartup.cs | 5 ----- .../IntegrationTests/ResourceHooks/ResourceHooksStartup.cs | 6 ------ .../Startups/AbsoluteLinksInApiNamespaceStartup.cs | 6 ------ .../Startups/AbsoluteLinksNoNamespaceStartup.cs | 6 ------ .../Startups/ModelStateValidationStartup.cs | 6 ------ .../Startups/RelativeLinksInApiNamespaceStartup.cs | 6 ------ .../Startups/RelativeLinksNoNamespaceStartup.cs | 6 ------ .../Startups/TestableStartup.cs | 5 ----- 14 files changed, 6 insertions(+), 57 deletions(-) diff --git a/src/Examples/GettingStarted/Startup.cs b/src/Examples/GettingStarted/Startup.cs index b97618f823..8d7eacdeea 100644 --- a/src/Examples/GettingStarted/Startup.cs +++ b/src/Examples/GettingStarted/Startup.cs @@ -1,5 +1,6 @@ using GettingStarted.Data; using GettingStarted.Models; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using Microsoft.AspNetCore.Builder; using Microsoft.EntityFrameworkCore; @@ -27,6 +28,7 @@ public void ConfigureServices(IServiceCollection services) } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + [UsedImplicitly] public void Configure(IApplicationBuilder app, SampleDbContext context) { context.Database.EnsureDeleted(); diff --git a/src/Examples/JsonApiDotNetCoreExample/Startups/EmptyStartup.cs b/src/Examples/JsonApiDotNetCoreExample/Startups/EmptyStartup.cs index de254cb942..0ee7454da6 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Startups/EmptyStartup.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Startups/EmptyStartup.cs @@ -1,6 +1,5 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace JsonApiDotNetCoreExample.Startups @@ -11,10 +10,6 @@ namespace JsonApiDotNetCoreExample.Startups /// public abstract class EmptyStartup { - protected EmptyStartup(IConfiguration configuration) - { - } - public virtual void ConfigureServices(IServiceCollection services) { } diff --git a/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs b/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs index 8d8fbb58fa..fa7580865d 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs @@ -18,7 +18,6 @@ public sealed class Startup : EmptyStartup private readonly string _connectionString; public Startup(IConfiguration configuration) - : base(configuration) { string postgresPassword = Environment.GetEnvironmentVariable("PGPASSWORD") ?? "postgres"; _connectionString = configuration["Data:DefaultConnection"].Replace("###", postgresPassword); diff --git a/src/Examples/MultiDbContextExample/Startup.cs b/src/Examples/MultiDbContextExample/Startup.cs index 5b4c537591..b1b7b6c57e 100644 --- a/src/Examples/MultiDbContextExample/Startup.cs +++ b/src/Examples/MultiDbContextExample/Startup.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -28,6 +29,7 @@ public void ConfigureServices(IServiceCollection services) } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + [UsedImplicitly] public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DbContextA dbContextA, DbContextB dbContextB) { diff --git a/src/Examples/NoEntityFrameworkExample/Startup.cs b/src/Examples/NoEntityFrameworkExample/Startup.cs index f61d858f79..6699be3376 100644 --- a/src/Examples/NoEntityFrameworkExample/Startup.cs +++ b/src/Examples/NoEntityFrameworkExample/Startup.cs @@ -1,4 +1,5 @@ using System; +using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Services; using Microsoft.AspNetCore.Builder; @@ -39,6 +40,7 @@ public void ConfigureServices(IServiceCollection services) } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + [UsedImplicitly] public void Configure(IApplicationBuilder app, AppDbContext context) { context.Database.EnsureCreated(); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingStartup.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingStartup.cs index 70c5ccca42..2b369b3c6e 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/HostingInIIS/HostingStartup.cs @@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS { @@ -12,10 +11,6 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.HostingInIIS public sealed class HostingStartup : TestableStartup where TDbContext : DbContext { - public HostingStartup(IConfiguration configuration) : base(configuration) - { - } - protected override void SetJsonApiOptions(JsonApiOptions options) { base.SetJsonApiOptions(options); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs index bec80d91e5..b6e762d46b 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/NamingConventions/KebabCasingConventionStartup.cs @@ -2,7 +2,6 @@ using JsonApiDotNetCore.Configuration; using JsonApiDotNetCoreExampleTests.Startups; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; using Newtonsoft.Json.Serialization; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.NamingConventions @@ -11,10 +10,6 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.NamingConventions public sealed class KebabCasingConventionStartup : TestableStartup where TDbContext : DbContext { - public KebabCasingConventionStartup(IConfiguration configuration) : base(configuration) - { - } - protected override void SetJsonApiOptions(JsonApiOptions options) { base.SetJsonApiOptions(options); diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHooksStartup.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHooksStartup.cs index 3df537b2e4..57974b5ede 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHooksStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHooksStartup.cs @@ -2,7 +2,6 @@ using JsonApiDotNetCore.Configuration; using JsonApiDotNetCoreExampleTests.Startups; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceHooks @@ -11,11 +10,6 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.ResourceHooks public sealed class ResourceHooksStartup : TestableStartup where TDbContext : DbContext { - public ResourceHooksStartup(IConfiguration configuration) - : base(configuration) - { - } - public override void ConfigureServices(IServiceCollection services) { base.ConfigureServices(services); diff --git a/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksInApiNamespaceStartup.cs b/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksInApiNamespaceStartup.cs index 093b1e6908..261947f6e4 100644 --- a/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksInApiNamespaceStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksInApiNamespaceStartup.cs @@ -1,7 +1,6 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; namespace JsonApiDotNetCoreExampleTests.Startups { @@ -9,11 +8,6 @@ namespace JsonApiDotNetCoreExampleTests.Startups public sealed class AbsoluteLinksInApiNamespaceStartup : TestableStartup where TDbContext : DbContext { - public AbsoluteLinksInApiNamespaceStartup(IConfiguration configuration) - : base(configuration) - { - } - protected override void SetJsonApiOptions(JsonApiOptions options) { base.SetJsonApiOptions(options); diff --git a/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksNoNamespaceStartup.cs b/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksNoNamespaceStartup.cs index 3dc0abb455..b3cd8df056 100644 --- a/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksNoNamespaceStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/Startups/AbsoluteLinksNoNamespaceStartup.cs @@ -1,7 +1,6 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; namespace JsonApiDotNetCoreExampleTests.Startups { @@ -9,11 +8,6 @@ namespace JsonApiDotNetCoreExampleTests.Startups public sealed class AbsoluteLinksNoNamespaceStartup : TestableStartup where TDbContext : DbContext { - public AbsoluteLinksNoNamespaceStartup(IConfiguration configuration) - : base(configuration) - { - } - protected override void SetJsonApiOptions(JsonApiOptions options) { base.SetJsonApiOptions(options); diff --git a/test/JsonApiDotNetCoreExampleTests/Startups/ModelStateValidationStartup.cs b/test/JsonApiDotNetCoreExampleTests/Startups/ModelStateValidationStartup.cs index 1a67f21c8f..4a814722a8 100644 --- a/test/JsonApiDotNetCoreExampleTests/Startups/ModelStateValidationStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/Startups/ModelStateValidationStartup.cs @@ -1,7 +1,6 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; namespace JsonApiDotNetCoreExampleTests.Startups { @@ -9,11 +8,6 @@ namespace JsonApiDotNetCoreExampleTests.Startups public sealed class ModelStateValidationStartup : TestableStartup where TDbContext : DbContext { - public ModelStateValidationStartup(IConfiguration configuration) - : base(configuration) - { - } - protected override void SetJsonApiOptions(JsonApiOptions options) { base.SetJsonApiOptions(options); diff --git a/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksInApiNamespaceStartup.cs b/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksInApiNamespaceStartup.cs index 52b74b15cd..092a3c1ef1 100644 --- a/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksInApiNamespaceStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksInApiNamespaceStartup.cs @@ -1,7 +1,6 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; namespace JsonApiDotNetCoreExampleTests.Startups { @@ -9,11 +8,6 @@ namespace JsonApiDotNetCoreExampleTests.Startups public sealed class RelativeLinksInApiNamespaceStartup : TestableStartup where TDbContext : DbContext { - public RelativeLinksInApiNamespaceStartup(IConfiguration configuration) - : base(configuration) - { - } - protected override void SetJsonApiOptions(JsonApiOptions options) { base.SetJsonApiOptions(options); diff --git a/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksNoNamespaceStartup.cs b/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksNoNamespaceStartup.cs index dd95d8ab30..8623301d7a 100644 --- a/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksNoNamespaceStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/Startups/RelativeLinksNoNamespaceStartup.cs @@ -1,7 +1,6 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Configuration; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; namespace JsonApiDotNetCoreExampleTests.Startups { @@ -9,11 +8,6 @@ namespace JsonApiDotNetCoreExampleTests.Startups public sealed class RelativeLinksNoNamespaceStartup : TestableStartup where TDbContext : DbContext { - public RelativeLinksNoNamespaceStartup(IConfiguration configuration) - : base(configuration) - { - } - protected override void SetJsonApiOptions(JsonApiOptions options) { base.SetJsonApiOptions(options); diff --git a/test/JsonApiDotNetCoreExampleTests/Startups/TestableStartup.cs b/test/JsonApiDotNetCoreExampleTests/Startups/TestableStartup.cs index 36cf40c68b..a486046b4e 100644 --- a/test/JsonApiDotNetCoreExampleTests/Startups/TestableStartup.cs +++ b/test/JsonApiDotNetCoreExampleTests/Startups/TestableStartup.cs @@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Newtonsoft.Json.Converters; @@ -13,10 +12,6 @@ namespace JsonApiDotNetCoreExampleTests.Startups public class TestableStartup : EmptyStartup where TDbContext : DbContext { - public TestableStartup(IConfiguration configuration) : base(configuration) - { - } - public override void ConfigureServices(IServiceCollection services) { services.AddJsonApi(SetJsonApiOptions); From 4ae214c2459f566406d148417fed531179ddb233 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Thu, 25 Feb 2021 14:33:45 +0100 Subject: [PATCH 49/60] BenchmarkDotNet runners cannot be sealed --- .../LinkBuilderGetNamespaceFromPathBenchmarks.cs | 11 +++++------ benchmarks/Query/QueryParserBenchmarks.cs | 1 + .../Serialization/JsonApiDeserializerBenchmarks.cs | 1 + .../Serialization/JsonApiSerializerBenchmarks.cs | 1 + 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/benchmarks/LinkBuilder/LinkBuilderGetNamespaceFromPathBenchmarks.cs b/benchmarks/LinkBuilder/LinkBuilderGetNamespaceFromPathBenchmarks.cs index 60b5f31ce1..3486ce30d9 100644 --- a/benchmarks/LinkBuilder/LinkBuilderGetNamespaceFromPathBenchmarks.cs +++ b/benchmarks/LinkBuilder/LinkBuilderGetNamespaceFromPathBenchmarks.cs @@ -4,6 +4,7 @@ namespace Benchmarks.LinkBuilder { + // ReSharper disable once ClassCanBeSealed.Global [MarkdownExporter, SimpleJob(launchCount: 3, warmupCount: 10, targetCount: 20), MemoryDiagnoser] public class LinkBuilderGetNamespaceFromPathBenchmarks { @@ -17,7 +18,7 @@ public class LinkBuilderGetNamespaceFromPathBenchmarks [Benchmark] public void UsingReadOnlySpan() => GetNamespaceFromPathUsingReadOnlySpan(RequestPath, ResourceName); - public static string GetNamespaceFromPathUsingStringSplit(string path, string resourceName) + private static void GetNamespaceFromPathUsingStringSplit(string path, string resourceName) { StringBuilder namespaceBuilder = new StringBuilder(path.Length); string[] segments = path.Split('/'); @@ -33,10 +34,10 @@ public static string GetNamespaceFromPathUsingStringSplit(string path, string re namespaceBuilder.Append(segments[index]); } - return namespaceBuilder.ToString(); + _ = namespaceBuilder.ToString(); } - public static string GetNamespaceFromPathUsingReadOnlySpan(string path, string resourceName) + private static void GetNamespaceFromPathUsingReadOnlySpan(string path, string resourceName) { ReadOnlySpan resourceNameSpan = resourceName.AsSpan(); ReadOnlySpan pathSpan = path.AsSpan(); @@ -57,14 +58,12 @@ public static string GetNamespaceFromPathUsingReadOnlySpan(string path, string r bool hasDelimiterAfterSegment = pathSpan.Length >= lastCharacterIndex + 1 && pathSpan[lastCharacterIndex].Equals(PathDelimiter); if (isAtEnd || hasDelimiterAfterSegment) { - return pathSpan.Slice(0, index).ToString(); + _ = pathSpan.Slice(0, index).ToString(); } } } } } - - return string.Empty; } } } diff --git a/benchmarks/Query/QueryParserBenchmarks.cs b/benchmarks/Query/QueryParserBenchmarks.cs index 8ba74abc74..f34f37f919 100644 --- a/benchmarks/Query/QueryParserBenchmarks.cs +++ b/benchmarks/Query/QueryParserBenchmarks.cs @@ -13,6 +13,7 @@ namespace Benchmarks.Query { + // ReSharper disable once ClassCanBeSealed.Global [MarkdownExporter, SimpleJob(launchCount: 3, warmupCount: 10, targetCount: 20), MemoryDiagnoser] public class QueryParserBenchmarks { diff --git a/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs b/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs index 81a6622880..3d43a1fe87 100644 --- a/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs +++ b/benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs @@ -12,6 +12,7 @@ namespace Benchmarks.Serialization { + // ReSharper disable once ClassCanBeSealed.Global [MarkdownExporter] public class JsonApiDeserializerBenchmarks { diff --git a/benchmarks/Serialization/JsonApiSerializerBenchmarks.cs b/benchmarks/Serialization/JsonApiSerializerBenchmarks.cs index 6407a2ccdf..c3f613ab56 100644 --- a/benchmarks/Serialization/JsonApiSerializerBenchmarks.cs +++ b/benchmarks/Serialization/JsonApiSerializerBenchmarks.cs @@ -11,6 +11,7 @@ namespace Benchmarks.Serialization { + // ReSharper disable once ClassCanBeSealed.Global [MarkdownExporter] public class JsonApiSerializerBenchmarks { From e85531183a7843604ea66ff072bb705e8de2ab41 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Thu, 25 Feb 2021 14:36:32 +0100 Subject: [PATCH 50/60] Suppress cases of unused TResource type parameter, because we register an open generic for them to enable different implementations per resource type. --- .../AtomicOperations/Processors/IAddToRelationshipProcessor.cs | 2 ++ .../AtomicOperations/Processors/ICreateProcessor.cs | 2 ++ .../AtomicOperations/Processors/IDeleteProcessor.cs | 2 ++ .../Processors/IRemoveFromRelationshipProcessor.cs | 2 ++ .../AtomicOperations/Processors/ISetRelationshipProcessor.cs | 2 ++ .../AtomicOperations/Processors/IUpdateProcessor.cs | 2 ++ .../Hooks/Internal/Discovery/IHooksDiscovery.cs | 2 ++ src/JsonApiDotNetCore/Services/IAddToRelationshipService.cs | 2 ++ src/JsonApiDotNetCore/Services/IDeleteService.cs | 2 ++ src/JsonApiDotNetCore/Services/IGetRelationshipService.cs | 2 ++ src/JsonApiDotNetCore/Services/IGetSecondaryService.cs | 2 ++ .../Services/IRemoveFromRelationshipService.cs | 2 ++ src/JsonApiDotNetCore/Services/ISetRelationshipService.cs | 2 ++ 13 files changed, 26 insertions(+) diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/IAddToRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/IAddToRelationshipProcessor.cs index b5f9d081ec..113771ab4d 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/IAddToRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/IAddToRelationshipProcessor.cs @@ -1,6 +1,8 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Resources; +// ReSharper disable UnusedTypeParameter + namespace JsonApiDotNetCore.AtomicOperations.Processors { /// diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/ICreateProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/ICreateProcessor.cs index 392b6873b0..79ffaf4090 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/ICreateProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/ICreateProcessor.cs @@ -1,6 +1,8 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Resources; +// ReSharper disable UnusedTypeParameter + namespace JsonApiDotNetCore.AtomicOperations.Processors { /// diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/IDeleteProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/IDeleteProcessor.cs index e24f372301..3c5fbff948 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/IDeleteProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/IDeleteProcessor.cs @@ -1,6 +1,8 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Resources; +// ReSharper disable UnusedTypeParameter + namespace JsonApiDotNetCore.AtomicOperations.Processors { /// diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/IRemoveFromRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/IRemoveFromRelationshipProcessor.cs index 85e4ec7850..02ce98d21d 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/IRemoveFromRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/IRemoveFromRelationshipProcessor.cs @@ -1,6 +1,8 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Resources; +// ReSharper disable UnusedTypeParameter + namespace JsonApiDotNetCore.AtomicOperations.Processors { /// diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/ISetRelationshipProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/ISetRelationshipProcessor.cs index 7847c2f985..4943cdf97f 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/ISetRelationshipProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/ISetRelationshipProcessor.cs @@ -1,6 +1,8 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Resources; +// ReSharper disable UnusedTypeParameter + namespace JsonApiDotNetCore.AtomicOperations.Processors { /// diff --git a/src/JsonApiDotNetCore/AtomicOperations/Processors/IUpdateProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/Processors/IUpdateProcessor.cs index 34bdeb32fd..7c8967e8e7 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/Processors/IUpdateProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/Processors/IUpdateProcessor.cs @@ -1,6 +1,8 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Resources; +// ReSharper disable UnusedTypeParameter + namespace JsonApiDotNetCore.AtomicOperations.Processors { /// diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/IHooksDiscovery.cs b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/IHooksDiscovery.cs index 9473ddbb24..7fede4e57b 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Discovery/IHooksDiscovery.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Discovery/IHooksDiscovery.cs @@ -1,6 +1,8 @@ using JsonApiDotNetCore.Hooks.Internal.Execution; using JsonApiDotNetCore.Resources; +// ReSharper disable UnusedTypeParameter + namespace JsonApiDotNetCore.Hooks.Internal.Discovery { /// diff --git a/src/JsonApiDotNetCore/Services/IAddToRelationshipService.cs b/src/JsonApiDotNetCore/Services/IAddToRelationshipService.cs index 8561348486..ca1e968767 100644 --- a/src/JsonApiDotNetCore/Services/IAddToRelationshipService.cs +++ b/src/JsonApiDotNetCore/Services/IAddToRelationshipService.cs @@ -4,6 +4,8 @@ using JetBrains.Annotations; using JsonApiDotNetCore.Resources; +// ReSharper disable UnusedTypeParameter + namespace JsonApiDotNetCore.Services { /// diff --git a/src/JsonApiDotNetCore/Services/IDeleteService.cs b/src/JsonApiDotNetCore/Services/IDeleteService.cs index 548ddad6f3..5dcaebdf19 100644 --- a/src/JsonApiDotNetCore/Services/IDeleteService.cs +++ b/src/JsonApiDotNetCore/Services/IDeleteService.cs @@ -2,6 +2,8 @@ using System.Threading.Tasks; using JsonApiDotNetCore.Resources; +// ReSharper disable UnusedTypeParameter + namespace JsonApiDotNetCore.Services { /// diff --git a/src/JsonApiDotNetCore/Services/IGetRelationshipService.cs b/src/JsonApiDotNetCore/Services/IGetRelationshipService.cs index d986728aea..575f8ca6bf 100644 --- a/src/JsonApiDotNetCore/Services/IGetRelationshipService.cs +++ b/src/JsonApiDotNetCore/Services/IGetRelationshipService.cs @@ -2,6 +2,8 @@ using System.Threading.Tasks; using JsonApiDotNetCore.Resources; +// ReSharper disable UnusedTypeParameter + namespace JsonApiDotNetCore.Services { /// diff --git a/src/JsonApiDotNetCore/Services/IGetSecondaryService.cs b/src/JsonApiDotNetCore/Services/IGetSecondaryService.cs index bb376c7307..b035aa6327 100644 --- a/src/JsonApiDotNetCore/Services/IGetSecondaryService.cs +++ b/src/JsonApiDotNetCore/Services/IGetSecondaryService.cs @@ -2,6 +2,8 @@ using System.Threading.Tasks; using JsonApiDotNetCore.Resources; +// ReSharper disable UnusedTypeParameter + namespace JsonApiDotNetCore.Services { /// diff --git a/src/JsonApiDotNetCore/Services/IRemoveFromRelationshipService.cs b/src/JsonApiDotNetCore/Services/IRemoveFromRelationshipService.cs index baf4bf2313..56b3d5137b 100644 --- a/src/JsonApiDotNetCore/Services/IRemoveFromRelationshipService.cs +++ b/src/JsonApiDotNetCore/Services/IRemoveFromRelationshipService.cs @@ -3,6 +3,8 @@ using System.Threading.Tasks; using JsonApiDotNetCore.Resources; +// ReSharper disable UnusedTypeParameter + namespace JsonApiDotNetCore.Services { /// diff --git a/src/JsonApiDotNetCore/Services/ISetRelationshipService.cs b/src/JsonApiDotNetCore/Services/ISetRelationshipService.cs index aa2075a2f1..46ec2153f1 100644 --- a/src/JsonApiDotNetCore/Services/ISetRelationshipService.cs +++ b/src/JsonApiDotNetCore/Services/ISetRelationshipService.cs @@ -2,6 +2,8 @@ using System.Threading.Tasks; using JsonApiDotNetCore.Resources; +// ReSharper disable UnusedTypeParameter + namespace JsonApiDotNetCore.Services { /// From d23df0e16ae604f29627194565542ba3008df43f Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Thu, 25 Feb 2021 14:39:34 +0100 Subject: [PATCH 51/60] Additional cleanup and annotations based on warnings and suggestions --- .../JsonApiDotNetCoreExample/Models/IIsLockable.cs | 6 +++--- .../HttpResponseMessageExtensions.cs | 1 + .../Controllers/BaseJsonApiControllerTests.cs | 2 +- .../Extensions/ServiceCollectionExtensionsTests.cs | 8 +++++--- test/UnitTests/Graph/BaseType.cs | 6 ++++-- test/UnitTests/Graph/DerivedType.cs | 4 ++-- test/UnitTests/Graph/IGenericInterface.cs | 6 ++++-- test/UnitTests/Graph/Implementation.cs | 4 ++-- test/UnitTests/Graph/Model.cs | 4 ++-- test/UnitTests/Internal/ResourceGraphBuilderTests.cs | 5 +++-- test/UnitTests/Internal/TypeHelperTests.cs | 11 ++--------- .../UnitTests/Models/ResourceWithStringConstructor.cs | 2 +- .../Models/ResourceWithThrowingConstructor.cs | 2 +- test/UnitTests/Models/ResourceWithoutConstructor.cs | 2 +- test/UnitTests/ResourceHooks/HooksDummyData.cs | 10 +++++----- test/UnitTests/ResourceHooks/HooksTestsSetup.cs | 2 +- test/UnitTests/ResourceHooks/NotTargeted.cs | 2 +- .../Serialization/Client/RequestSerializerTests.cs | 3 +-- .../Serialization/Common/BaseDocumentBuilderTests.cs | 7 ++----- .../UnitTests/Serialization/DeserializerTestsSetup.cs | 2 +- .../Serialization/SerializationTestsSetupBase.cs | 4 ++-- test/UnitTests/Serialization/SerializerTestsSetup.cs | 9 +++++---- test/UnitTests/TestModels/ComplexType.cs | 3 +++ 23 files changed, 53 insertions(+), 52 deletions(-) diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/IIsLockable.cs b/src/Examples/JsonApiDotNetCoreExample/Models/IIsLockable.cs index fe7d07ad34..d59f5b8f4d 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/IIsLockable.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/IIsLockable.cs @@ -1,7 +1,7 @@ -namespace JsonApiDotNetCoreExample.Models +namespace JsonApiDotNetCoreExample.Models { public interface IIsLockable { - bool IsLocked { get; set; } + bool IsLocked { get; } } -} \ No newline at end of file +} diff --git a/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs b/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs index 9026441f0e..d020dab884 100644 --- a/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs +++ b/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs @@ -27,6 +27,7 @@ public HttpResponseMessageAssertions(HttpResponseMessage instance) Subject = instance; } + // ReSharper disable once UnusedMethodReturnValue.Global public AndConstraint HaveStatusCode(HttpStatusCode statusCode) { if (Subject.StatusCode != statusCode) diff --git a/test/UnitTests/Controllers/BaseJsonApiControllerTests.cs b/test/UnitTests/Controllers/BaseJsonApiControllerTests.cs index 5764bffef3..076a13e442 100644 --- a/test/UnitTests/Controllers/BaseJsonApiControllerTests.cs +++ b/test/UnitTests/Controllers/BaseJsonApiControllerTests.cs @@ -26,7 +26,7 @@ public sealed class Resource : Identifiable [Attr] public string TestAttribute { get; set; } } - public sealed class ResourceController : BaseJsonApiController + private sealed class ResourceController : BaseJsonApiController { public ResourceController( IJsonApiOptions options, diff --git a/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs b/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs index b795c05ec3..57009509cf 100644 --- a/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs +++ b/test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs @@ -187,8 +187,10 @@ public void AddJsonApi_With_Context_Uses_Resource_Type_Name_If_NoOtherSpecified( Assert.Equal("intResources", resource.PublicName); } - public sealed class IntResource : Identifiable { } - public sealed class GuidResource : Identifiable { } + private sealed class IntResource : Identifiable { } + + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] + private sealed class GuidResource : Identifiable { } [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] private sealed class IntResourceService : IResourceService @@ -251,7 +253,7 @@ private sealed class GuidResourceRepository : IResourceRepository options) : base(options) { diff --git a/test/UnitTests/Graph/BaseType.cs b/test/UnitTests/Graph/BaseType.cs index 45e9b91463..c2ee6f5fe8 100644 --- a/test/UnitTests/Graph/BaseType.cs +++ b/test/UnitTests/Graph/BaseType.cs @@ -1,4 +1,6 @@ +// ReSharper disable UnusedTypeParameter + namespace UnitTests.Graph { - public class BaseType { } -} \ No newline at end of file + internal class BaseType { } +} diff --git a/test/UnitTests/Graph/DerivedType.cs b/test/UnitTests/Graph/DerivedType.cs index 64c0b5fbf6..c9c12ecd97 100644 --- a/test/UnitTests/Graph/DerivedType.cs +++ b/test/UnitTests/Graph/DerivedType.cs @@ -1,4 +1,4 @@ namespace UnitTests.Graph { - public sealed class DerivedType : BaseType { } -} \ No newline at end of file + internal sealed class DerivedType : BaseType { } +} diff --git a/test/UnitTests/Graph/IGenericInterface.cs b/test/UnitTests/Graph/IGenericInterface.cs index 4ab2f68f64..648a8e8ea4 100644 --- a/test/UnitTests/Graph/IGenericInterface.cs +++ b/test/UnitTests/Graph/IGenericInterface.cs @@ -1,4 +1,6 @@ +// ReSharper disable UnusedTypeParameter + namespace UnitTests.Graph { - public interface IGenericInterface { } -} \ No newline at end of file + internal interface IGenericInterface { } +} diff --git a/test/UnitTests/Graph/Implementation.cs b/test/UnitTests/Graph/Implementation.cs index da379b84b9..08a61c229e 100644 --- a/test/UnitTests/Graph/Implementation.cs +++ b/test/UnitTests/Graph/Implementation.cs @@ -1,4 +1,4 @@ namespace UnitTests.Graph { - public sealed class Implementation : IGenericInterface { } -} \ No newline at end of file + internal sealed class Implementation : IGenericInterface { } +} diff --git a/test/UnitTests/Graph/Model.cs b/test/UnitTests/Graph/Model.cs index 231f060fa4..cd2830f7f8 100644 --- a/test/UnitTests/Graph/Model.cs +++ b/test/UnitTests/Graph/Model.cs @@ -2,5 +2,5 @@ namespace UnitTests.Graph { - public sealed class Model : Identifiable { } -} \ No newline at end of file + internal sealed class Model : Identifiable { } +} diff --git a/test/UnitTests/Internal/ResourceGraphBuilderTests.cs b/test/UnitTests/Internal/ResourceGraphBuilderTests.cs index 7a5c77298f..68f5a86efe 100644 --- a/test/UnitTests/Internal/ResourceGraphBuilderTests.cs +++ b/test/UnitTests/Internal/ResourceGraphBuilderTests.cs @@ -76,6 +76,7 @@ public void GetResourceContext_Yields_Right_Type_For_Identifiable() Assert.Equal(typeof(Bar), result.ResourceType); } + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] private sealed class Foo { } [UsedImplicitly(ImplicitUseTargetFlags.Members)] @@ -84,8 +85,8 @@ private sealed class TestContext : DbContext public DbSet Foos { get; set; } } + // ReSharper disable once ClassCanBeSealed.Global + // ReSharper disable once MemberCanBePrivate.Global public class Bar : Identifiable { } - } - } diff --git a/test/UnitTests/Internal/TypeHelperTests.cs b/test/UnitTests/Internal/TypeHelperTests.cs index 044b270fff..2a9c6b1f5b 100644 --- a/test/UnitTests/Internal/TypeHelperTests.cs +++ b/test/UnitTests/Internal/TypeHelperTests.cs @@ -50,10 +50,7 @@ public void Can_Convert_Enums() public void ConvertType_Returns_Value_If_Type_Is_Same() { // Arrange - var val = new ComplexType - { - Property = 1 - }; + var val = new ComplexType(); var type = val.GetType(); @@ -68,10 +65,7 @@ public void ConvertType_Returns_Value_If_Type_Is_Same() public void ConvertType_Returns_Value_If_Type_Is_Assignable() { // Arrange - var val = new ComplexType - { - Property = 1 - }; + var val = new ComplexType(); var baseType = typeof(BaseType); var iType = typeof(IType); @@ -179,7 +173,6 @@ private enum TestEnum private sealed class ComplexType : BaseType { - public int Property { get; set; } } private class BaseType : IType diff --git a/test/UnitTests/Models/ResourceWithStringConstructor.cs b/test/UnitTests/Models/ResourceWithStringConstructor.cs index 51371b18ff..8b166f50e4 100644 --- a/test/UnitTests/Models/ResourceWithStringConstructor.cs +++ b/test/UnitTests/Models/ResourceWithStringConstructor.cs @@ -5,7 +5,7 @@ namespace UnitTests.Models { [UsedImplicitly(ImplicitUseTargetFlags.Members)] - public sealed class ResourceWithStringConstructor : Identifiable + internal sealed class ResourceWithStringConstructor : Identifiable { public string Text { get; } diff --git a/test/UnitTests/Models/ResourceWithThrowingConstructor.cs b/test/UnitTests/Models/ResourceWithThrowingConstructor.cs index 753d1fb80e..b1fe9f6d48 100644 --- a/test/UnitTests/Models/ResourceWithThrowingConstructor.cs +++ b/test/UnitTests/Models/ResourceWithThrowingConstructor.cs @@ -5,7 +5,7 @@ namespace UnitTests.Models { [UsedImplicitly(ImplicitUseTargetFlags.Members)] - public sealed class ResourceWithThrowingConstructor : Identifiable + internal sealed class ResourceWithThrowingConstructor : Identifiable { public ResourceWithThrowingConstructor() { diff --git a/test/UnitTests/Models/ResourceWithoutConstructor.cs b/test/UnitTests/Models/ResourceWithoutConstructor.cs index fa642e920c..521e01405e 100644 --- a/test/UnitTests/Models/ResourceWithoutConstructor.cs +++ b/test/UnitTests/Models/ResourceWithoutConstructor.cs @@ -2,7 +2,7 @@ namespace UnitTests.Models { - public sealed class ResourceWithoutConstructor : Identifiable + internal sealed class ResourceWithoutConstructor : Identifiable { } } diff --git a/test/UnitTests/ResourceHooks/HooksDummyData.cs b/test/UnitTests/ResourceHooks/HooksDummyData.cs index af1691fd3d..1a5d88a365 100644 --- a/test/UnitTests/ResourceHooks/HooksDummyData.cs +++ b/test/UnitTests/ResourceHooks/HooksDummyData.cs @@ -21,10 +21,10 @@ public class HooksDummyData protected readonly Faker
    ArticleFaker; protected readonly Faker TagFaker; protected readonly Faker ArticleTagFaker; - protected readonly Faker IdentifiableArticleTagFaker; + private readonly Faker _identifiableArticleTagFaker; protected readonly Faker PassportFaker; - public HooksDummyData() + protected HooksDummyData() { ResourceGraph = new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance) .Add() @@ -52,7 +52,7 @@ public HooksDummyData() ArticleTagFaker = new Faker(); - IdentifiableArticleTagFaker = new Faker() + _identifiableArticleTagFaker = new Faker() .RuleFor(x => x.Id, f => f.UniqueIndex + 1); PassportFaker = new Faker() @@ -113,7 +113,7 @@ protected HashSet CreateTodoWithOwner() protected (List
    , List, List) CreateIdentifiableManyToManyData() { var tagsSubset = TagFaker.Generate(3); - var joinsSubSet = IdentifiableArticleTagFaker.Generate(3); + var joinsSubSet = _identifiableArticleTagFaker.Generate(3); var articleTagsSubset = ArticleFaker.Generate(); articleTagsSubset.IdentifiableArticleTags = joinsSubSet.ToHashSet(); for (int i = 0; i < 3; i++) @@ -122,7 +122,7 @@ protected HashSet CreateTodoWithOwner() joinsSubSet[i].Tag = tagsSubset[i]; } var allTags = TagFaker.Generate(3).Concat(tagsSubset).ToList(); - var completeJoin = IdentifiableArticleTagFaker.Generate(6); + var completeJoin = _identifiableArticleTagFaker.Generate(6); var articleWithAllTags = ArticleFaker.Generate(); articleWithAllTags.IdentifiableArticleTags = joinsSubSet.ToHashSet(); diff --git a/test/UnitTests/ResourceHooks/HooksTestsSetup.cs b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs index afa8cb71dd..9a37f3efa5 100644 --- a/test/UnitTests/ResourceHooks/HooksTestsSetup.cs +++ b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs @@ -283,7 +283,7 @@ protected List> GetIncludedRelationshipsChains(param return parsedChains; } - protected List GetIncludedRelationshipsChain(string chain) + private List GetIncludedRelationshipsChain(string chain) { var parsedChain = new List(); var resourceContext = ResourceGraph.GetResourceContext(); diff --git a/test/UnitTests/ResourceHooks/NotTargeted.cs b/test/UnitTests/ResourceHooks/NotTargeted.cs index b33bc03f15..cff5f41d19 100644 --- a/test/UnitTests/ResourceHooks/NotTargeted.cs +++ b/test/UnitTests/ResourceHooks/NotTargeted.cs @@ -2,5 +2,5 @@ namespace UnitTests.ResourceHooks { - public sealed class NotTargeted : Identifiable { } + internal sealed class NotTargeted : Identifiable { } } diff --git a/test/UnitTests/Serialization/Client/RequestSerializerTests.cs b/test/UnitTests/Serialization/Client/RequestSerializerTests.cs index f2bb1fb654..5ea4d7fa78 100644 --- a/test/UnitTests/Serialization/Client/RequestSerializerTests.cs +++ b/test/UnitTests/Serialization/Client/RequestSerializerTests.cs @@ -223,11 +223,10 @@ public void SerializeSingle_Null_CanBuild() public void SerializeMany_EmptyList_CanBuild() { // Arrange - var resources = new List(); _serializer.AttributesToSerialize = ResourceGraph.GetAttributes(tr => tr.StringField); // Act - string serialized = _serializer.Serialize(resources); + string serialized = _serializer.Serialize(new List()); // Assert const string expectedFormatted = @"{ diff --git a/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs b/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs index d512ae9bca..5219ffa792 100644 --- a/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs +++ b/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs @@ -37,11 +37,8 @@ public void ResourceToDocument_NullResource_CanBuild() [Fact] public void ResourceToDocument_EmptyList_CanBuild() { - // Arrange - var resources = new List(); - // Act - var document = _builder.Build(resources); + var document = _builder.Build(new List()); // Assert Assert.NotNull(document.Data); @@ -77,7 +74,7 @@ public void ResourceToDocument_ResourceList_CanBuild() Assert.Equal(2, data.Count); } - public sealed class DummyResource : Identifiable + private sealed class DummyResource : Identifiable { } } diff --git a/test/UnitTests/Serialization/DeserializerTestsSetup.cs b/test/UnitTests/Serialization/DeserializerTestsSetup.cs index 920b79c977..f22f9406a5 100644 --- a/test/UnitTests/Serialization/DeserializerTestsSetup.cs +++ b/test/UnitTests/Serialization/DeserializerTestsSetup.cs @@ -14,7 +14,7 @@ public class DeserializerTestsSetup : SerializationTestsSetupBase { protected Mock MockHttpContextAccessor { get; } - public DeserializerTestsSetup() + protected DeserializerTestsSetup() { MockHttpContextAccessor = new Mock(); MockHttpContextAccessor.Setup(mock => mock.HttpContext).Returns(new DefaultHttpContext()); diff --git a/test/UnitTests/Serialization/SerializationTestsSetupBase.cs b/test/UnitTests/Serialization/SerializationTestsSetupBase.cs index 841237ce34..5b20e8764c 100644 --- a/test/UnitTests/Serialization/SerializationTestsSetupBase.cs +++ b/test/UnitTests/Serialization/SerializationTestsSetupBase.cs @@ -15,7 +15,7 @@ public class SerializationTestsSetupBase protected Faker BlogFaker { get; } protected Faker PersonFaker { get; } - public SerializationTestsSetupBase() + protected SerializationTestsSetupBase() { ResourceGraph = BuildGraph(); @@ -46,7 +46,7 @@ public SerializationTestsSetupBase() // @formatter:keep_existing_linebreaks restore } - protected IResourceGraph BuildGraph() + private IResourceGraph BuildGraph() { var resourceGraphBuilder = new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance); resourceGraphBuilder.Add("testResource"); diff --git a/test/UnitTests/Serialization/SerializerTestsSetup.cs b/test/UnitTests/Serialization/SerializerTestsSetup.cs index 7fd845c16f..0f1bc4daea 100644 --- a/test/UnitTests/Serialization/SerializerTestsSetup.cs +++ b/test/UnitTests/Serialization/SerializerTestsSetup.cs @@ -19,7 +19,8 @@ public class SerializerTestsSetup : SerializationTestsSetupBase protected readonly TopLevelLinks DummyTopLevelLinks; protected readonly ResourceLinks DummyResourceLinks; protected readonly RelationshipLinks DummyRelationshipLinks; - public SerializerTestsSetup() + + protected SerializerTestsSetup() { DummyTopLevelLinks = new TopLevelLinks { @@ -71,13 +72,13 @@ protected IResourceObjectBuilderSettingsProvider GetSerializerSettingsProvider() return mock.Object; } - protected IResourceDefinitionAccessor GetResourceDefinitionAccessor() + private IResourceDefinitionAccessor GetResourceDefinitionAccessor() { var mock = new Mock(); return mock.Object; } - protected IMetaBuilder GetMetaBuilder(Dictionary meta = null) + private IMetaBuilder GetMetaBuilder(Dictionary meta = null) { var mock = new Mock(); mock.Setup(m => m.Build()).Returns(meta); @@ -101,7 +102,7 @@ protected IFieldsToSerialize GetSerializableFields() return mock.Object; } - protected IEnumerable GetIncludeConstraints(IEnumerable> inclusionChains = null) + private IEnumerable GetIncludeConstraints(IEnumerable> inclusionChains = null) { var expressionsInScope = new List(); diff --git a/test/UnitTests/TestModels/ComplexType.cs b/test/UnitTests/TestModels/ComplexType.cs index bf77fbe451..a8748203e6 100644 --- a/test/UnitTests/TestModels/ComplexType.cs +++ b/test/UnitTests/TestModels/ComplexType.cs @@ -1,5 +1,8 @@ +using JetBrains.Annotations; + namespace UnitTests.TestModels { + [UsedImplicitly(ImplicitUseTargetFlags.Members)] public sealed class ComplexType { public string CompoundName { get; set; } From e638822c7911d8f5b6d201a6ecae32ce419f5676 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Sat, 27 Feb 2021 10:31:49 +0100 Subject: [PATCH 52/60] AV1755: Async method name should end with [Task]Async --- src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs | 4 ++-- src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs | 2 +- src/JsonApiDotNetCore/Services/JsonApiResourceService.cs | 4 ++-- test/UnitTests/Middleware/JsonApiMiddlewareTests.cs | 2 +- test/UnitTests/Middleware/JsonApiRequestTests.cs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs b/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs index f660a1aafa..4cbd1f938b 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/OperationsProcessor.cs @@ -64,7 +64,7 @@ public virtual async Task> ProcessAsync(IList> ProcessAsync(IList ProcessOperation(OperationContainer operation, + protected virtual async Task ProcessOperationAsync(OperationContainer operation, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs index 3a5b2cf848..46aded0e1f 100644 --- a/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs +++ b/src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs @@ -35,7 +35,7 @@ public JsonApiMiddleware(RequestDelegate next) _next = next; } - public async Task Invoke(HttpContext httpContext, + public async Task InvokeAsync(HttpContext httpContext, IControllerResourceMapping controllerResourceMapping, IJsonApiOptions options, IJsonApiRequest request, diff --git a/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs b/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs index 4ea52f6743..6b08585445 100644 --- a/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs +++ b/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs @@ -278,7 +278,7 @@ public async Task AddToToManyRelationshipAsync(TId primaryId, string relationshi { // In the case of a many-to-many relationship, creating a duplicate entry in the join table results in a // unique constraint violation. We avoid that by excluding already-existing entries from the set in advance. - await RemoveExistingIdsFromSecondarySet(primaryId, secondaryResourceIds, hasManyThrough, cancellationToken); + await RemoveExistingIdsFromSecondarySetAsync(primaryId, secondaryResourceIds, hasManyThrough, cancellationToken); } try @@ -296,7 +296,7 @@ public async Task AddToToManyRelationshipAsync(TId primaryId, string relationshi } } - private async Task RemoveExistingIdsFromSecondarySet(TId primaryId, ISet secondaryResourceIds, + private async Task RemoveExistingIdsFromSecondarySetAsync(TId primaryId, ISet secondaryResourceIds, HasManyThroughAttribute hasManyThrough, CancellationToken cancellationToken) { var queryLayer = _queryLayerComposer.ComposeForHasMany(hasManyThrough, primaryId, secondaryResourceIds); diff --git a/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs b/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs index 72228aea78..6890913574 100644 --- a/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs +++ b/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs @@ -84,7 +84,7 @@ private Task RunMiddlewareTask(InvokeConfiguration holder) var options = holder.Options.Object; var request = holder.Request; var resourceGraph = holder.ResourceGraph.Object; - return holder.MiddleWare.Invoke(context, controllerResourceMapping, options, request, resourceGraph); + return holder.MiddleWare.InvokeAsync(context, controllerResourceMapping, options, request, resourceGraph); } private InvokeConfiguration GetConfiguration(string path, string resourceName = "users", string action = "", string id =null, Type relType = null) { diff --git a/test/UnitTests/Middleware/JsonApiRequestTests.cs b/test/UnitTests/Middleware/JsonApiRequestTests.cs index 62139617ec..70b7b70268 100644 --- a/test/UnitTests/Middleware/JsonApiRequestTests.cs +++ b/test/UnitTests/Middleware/JsonApiRequestTests.cs @@ -57,7 +57,7 @@ public async Task Sets_request_properties_correctly(string requestMethod, string var middleware = new JsonApiMiddleware(_ => Task.CompletedTask); // Act - await middleware.Invoke(httpContext, controllerResourceMappingMock.Object, options, request, resourceGraph); + await middleware.InvokeAsync(httpContext, controllerResourceMappingMock.Object, options, request, resourceGraph); // Assert request.IsCollection.Should().Be(expectIsCollection); From af6955c259f5a54f52ed9ee5e922454190c50b2d Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Sat, 27 Feb 2021 10:54:14 +0100 Subject: [PATCH 53/60] AV1739: Use underscores for unused lambda parameters --- .../Hooks/Internal/Traversal/RootNode.cs | 4 ++-- .../Queries/Internal/QueryLayerComposer.cs | 6 +++--- src/JsonApiDotNetCore/TypeHelper.cs | 2 +- .../IntegrationTests/Logging/LoggingTests.cs | 2 +- .../ResourceConstructorInjection/InjectionFakers.cs | 4 ++-- test/UnitTests/Middleware/JsonApiMiddlewareTests.cs | 2 +- test/UnitTests/ResourceHooks/HooksTestsSetup.cs | 10 +++++----- .../Serialization/Client/RequestSerializerTests.cs | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RootNode.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RootNode.cs index 99a3057841..166b98f0a2 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RootNode.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/RootNode.cs @@ -24,7 +24,7 @@ public Dictionary> LeftsToN { return _allRelationshipsToNextLayer .GroupBy(proxy => proxy.RightType) - .ToDictionary(gdc => gdc.Key, gdc => gdc.ToDictionary(p => p.Attribute, p => UniqueResources)); + .ToDictionary(gdc => gdc.Key, gdc => gdc.ToDictionary(p => p.Attribute, _ => UniqueResources)); } /// @@ -32,7 +32,7 @@ public Dictionary> LeftsToN /// public Dictionary LeftsToNextLayer() { - return RelationshipsToNextLayer.ToDictionary(p => p.Attribute, p => UniqueResources); + return RelationshipsToNextLayer.ToDictionary(p => p.Attribute, _ => UniqueResources); } /// diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs index e20c67eb45..783d5aeed0 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs @@ -250,7 +250,7 @@ private IDictionary GetProjectionForRelation { var secondaryAttributeSet = _sparseFieldSetCache.GetIdAttributeSetForRelationshipQuery(secondaryResourceContext); - return secondaryAttributeSet.ToDictionary(key => (ResourceFieldAttribute)key, value => (QueryLayer)null); + return secondaryAttributeSet.ToDictionary(key => (ResourceFieldAttribute)key, _ => (QueryLayer)null); } /// @@ -264,7 +264,7 @@ public QueryLayer WrapLayerForSecondaryEndpoint(QueryLayer secondaryLayer, secondaryLayer.Include = null; var primaryAttributeSet = _sparseFieldSetCache.GetIdAttributeSetForRelationshipQuery(primaryResourceContext); - var primaryProjection = primaryAttributeSet.ToDictionary(key => (ResourceFieldAttribute)key, value => (QueryLayer)null); + var primaryProjection = primaryAttributeSet.ToDictionary(key => (ResourceFieldAttribute)key, _ => (QueryLayer)null); primaryProjection[secondaryRelationship] = secondaryLayer; var primaryFilter = GetFilter(Array.Empty(), primaryResourceContext); @@ -481,7 +481,7 @@ protected virtual IDictionary GetProjectionF var idAttribute = GetIdAttribute(resourceContext); attributeSet.Add(idAttribute); - return attributeSet.ToDictionary(key => (ResourceFieldAttribute)key, value => (QueryLayer)null); + return attributeSet.ToDictionary(key => (ResourceFieldAttribute)key, _ => (QueryLayer)null); } private static AttrAttribute GetIdAttribute(ResourceContext resourceContext) diff --git a/src/JsonApiDotNetCore/TypeHelper.cs b/src/JsonApiDotNetCore/TypeHelper.cs index d322b2f72b..c3b004979a 100644 --- a/src/JsonApiDotNetCore/TypeHelper.cs +++ b/src/JsonApiDotNetCore/TypeHelper.cs @@ -170,7 +170,7 @@ public static Dictionary> ConvertRelat /// public static Dictionary> ConvertAttributeDictionary(IEnumerable attributes, HashSet resources) { - return attributes.ToDictionary(attr => attr.Property, attr => resources); + return attributes.ToDictionary(attr => attr.Property, _ => resources); } /// diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/LoggingTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/LoggingTests.cs index 92dc28d1a0..44ba7be6c4 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/LoggingTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/Logging/LoggingTests.cs @@ -29,7 +29,7 @@ public LoggingTests(ExampleIntegrationTestContext true); + options.AddFilter((_, __) => true); }); testContext.ConfigureServicesBeforeStartup(services => diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionFakers.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionFakers.cs index 54df54c48f..75c5dc6f92 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionFakers.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceConstructorInjection/InjectionFakers.cs @@ -28,13 +28,13 @@ public InjectionFakers(IServiceProvider serviceProvider) _lazyPostOfficeFaker = new Lazy>(() => new Faker() .UseSeed(GetFakerSeed()) - .CustomInstantiator(f => new PostOffice(ResolveDbContext())) + .CustomInstantiator(_ => new PostOffice(ResolveDbContext())) .RuleFor(postOffice => postOffice.Address, f => f.Address.FullAddress())); _lazyGiftCertificateFaker = new Lazy>(() => new Faker() .UseSeed(GetFakerSeed()) - .CustomInstantiator(f => new GiftCertificate(ResolveDbContext())) + .CustomInstantiator(_ => new GiftCertificate(ResolveDbContext())) .RuleFor(giftCertificate => giftCertificate.IssueDate, f => f.Date.PastOffset())); } diff --git a/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs b/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs index 6890913574..cfdfd8d85c 100644 --- a/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs +++ b/test/UnitTests/Middleware/JsonApiMiddlewareTests.cs @@ -92,7 +92,7 @@ private InvokeConfiguration GetConfiguration(string path, string resourceName = { throw new ArgumentException("Path should start with a '/'"); } - var middleware = new JsonApiMiddleware(httpContext => + var middleware = new JsonApiMiddleware(_ => { return Task.Run(() => Console.WriteLine("finished")); }); diff --git a/test/UnitTests/ResourceHooks/HooksTestsSetup.cs b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs index 9a37f3efa5..d02671435c 100644 --- a/test/UnitTests/ResourceHooks/HooksTestsSetup.cs +++ b/test/UnitTests/ResourceHooks/HooksTestsSetup.cs @@ -168,29 +168,29 @@ private void MockHooks(Mock> resourceDefi { resourceDefinition .Setup(rd => rd.BeforeCreate(It.IsAny>(), It.IsAny())) - .Returns, ResourcePipeline>((resources, context) => resources) + .Returns, ResourcePipeline>((resources, _) => resources) .Verifiable(); resourceDefinition .Setup(rd => rd.BeforeRead(It.IsAny(), It.IsAny(), It.IsAny())) .Verifiable(); resourceDefinition .Setup(rd => rd.BeforeUpdate(It.IsAny>(), It.IsAny())) - .Returns, ResourcePipeline>((resources, context) => resources) + .Returns, ResourcePipeline>((resources, _) => resources) .Verifiable(); resourceDefinition .Setup(rd => rd.BeforeDelete(It.IsAny>(), It.IsAny())) - .Returns, ResourcePipeline>((resources, context) => resources) + .Returns, ResourcePipeline>((resources, _) => resources) .Verifiable(); resourceDefinition .Setup(rd => rd.BeforeUpdateRelationship(It.IsAny>(), It.IsAny>(), It.IsAny())) - .Returns, IRelationshipsDictionary, ResourcePipeline>((ids, context, helper) => ids) + .Returns, IRelationshipsDictionary, ResourcePipeline>((ids, _, __) => ids) .Verifiable(); resourceDefinition .Setup(rd => rd.BeforeImplicitUpdateRelationship(It.IsAny>(), It.IsAny())) .Verifiable(); resourceDefinition .Setup(rd => rd.OnReturn(It.IsAny>(), It.IsAny())) - .Returns, ResourcePipeline>((resources, context) => resources) + .Returns, ResourcePipeline>((resources, _) => resources) .Verifiable(); resourceDefinition .Setup(rd => rd.AfterCreate(It.IsAny>(), It.IsAny())) diff --git a/test/UnitTests/Serialization/Client/RequestSerializerTests.cs b/test/UnitTests/Serialization/Client/RequestSerializerTests.cs index 5ea4d7fa78..449338a508 100644 --- a/test/UnitTests/Serialization/Client/RequestSerializerTests.cs +++ b/test/UnitTests/Serialization/Client/RequestSerializerTests.cs @@ -100,7 +100,7 @@ public void SerializeSingle_ResourceWithoutTargetedAttributes_CanBuild() { // Arrange var resource = new TestResource { Id = 1, StringField = "value", NullableIntField = 123 }; - _serializer.AttributesToSerialize = ResourceGraph.GetAttributes(tr => new { }); + _serializer.AttributesToSerialize = ResourceGraph.GetAttributes(_ => new { }); // Act string serialized = _serializer.Serialize(resource); From 324fe4ac1ceff34192d46b0be38d72aa8f6aef5f Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Sat, 27 Feb 2021 11:28:25 +0100 Subject: [PATCH 54/60] AV1568: Parameter value is overwritten in method body --- .../Configuration/ResourceGraph.cs | 8 ++- .../Configuration/ResourceGraphBuilder.cs | 27 +++++---- .../Hooks/Internal/ResourceHookExecutor.cs | 14 +++-- .../SparseFieldSetExpressionExtensions.cs | 12 ++-- .../Parsing/ResourceFieldChainResolver.cs | 55 ++++++++++--------- .../Queries/Internal/QueryLayerComposer.cs | 9 ++- .../QueryableBuilding/IncludeClauseBuilder.cs | 8 ++- .../FilterQueryStringParameterReader.cs | 9 ++- .../Internal/QueryStringReader.cs | 4 +- .../EntityFrameworkCoreRepository.cs | 5 +- .../Building/ResourceObjectBuilder.cs | 8 ++- .../Serialization/JsonApiWriter.cs | 8 +-- .../MusicTrackReleaseDefinition.cs | 6 +- 13 files changed, 101 insertions(+), 72 deletions(-) diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs index 5d9a0bd902..a52af699c1 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraph.cs @@ -177,15 +177,17 @@ private bool IsLazyLoadingProxyForResourceType(Type resourceType) => private static Expression RemoveConvert(Expression expression) { + var innerExpression = expression; + while (true) { - if (expression is UnaryExpression { NodeType: ExpressionType.Convert } unaryExpression) + if (innerExpression is UnaryExpression { NodeType: ExpressionType.Convert } unaryExpression) { - expression = unaryExpression.Operand; + innerExpression = unaryExpression.Operand; } else { - return expression; + return innerExpression; } } } diff --git a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs index 0a2d2e667e..7b07847682 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceGraphBuilder.cs @@ -85,19 +85,22 @@ public ResourceGraphBuilder Add(Type resourceType, Type idType = null, string pu { ArgumentGuard.NotNull(resourceType, nameof(resourceType)); - if (_resources.All(e => e.ResourceType != resourceType)) + if (_resources.Any(e => e.ResourceType == resourceType)) { - if (TypeHelper.IsOrImplementsInterface(resourceType, typeof(IIdentifiable))) - { - publicName ??= FormatResourceName(resourceType); - idType ??= TypeLocator.TryGetIdType(resourceType); - var resourceContext = CreateResourceContext(publicName, resourceType, idType); - _resources.Add(resourceContext); - } - else - { - _logger.LogWarning($"Entity '{resourceType}' does not implement '{nameof(IIdentifiable)}'."); - } + return this; + } + + if (TypeHelper.IsOrImplementsInterface(resourceType, typeof(IIdentifiable))) + { + var effectivePublicName = publicName ?? FormatResourceName(resourceType); + var effectiveIdType = idType ?? TypeLocator.TryGetIdType(resourceType); + + var resourceContext = CreateResourceContext(effectivePublicName, resourceType, effectiveIdType); + _resources.Add(resourceContext); + } + else + { + _logger.LogWarning($"Entity '{resourceType}' does not implement '{nameof(IIdentifiable)}'."); } return this; diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs index c15bd16a11..73186da2c2 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs @@ -215,14 +215,16 @@ private bool GetHook(ResourceHook target, IEnumerable reso /// private void Traverse(NodeLayer currentLayer, ResourceHook target, Action action) { + var nextLayer = currentLayer; + while (true) { - if (!currentLayer.AnyResources()) + if (!nextLayer.AnyResources()) { return; } - foreach (IResourceNode node in currentLayer) + foreach (IResourceNode node in nextLayer) { var resourceType = node.ResourceType; var hookContainer = _executorHelper.GetResourceHookContainer(resourceType, target); @@ -235,7 +237,7 @@ private void Traverse(NodeLayer currentLayer, ResourceHook target, Action action) /// The relationship helper. private IRelationshipsDictionary CreateRelationshipHelper(RightType resourceType, Dictionary prevLayerRelationships, IEnumerable dbValues = null) { + var prevLayerRelationshipsWithDbValues = prevLayerRelationships; + if (dbValues != null) { - prevLayerRelationships = ReplaceWithDbValues(prevLayerRelationships, dbValues.Cast()); + prevLayerRelationshipsWithDbValues = ReplaceWithDbValues(prevLayerRelationshipsWithDbValues, dbValues.Cast()); } - return (IRelationshipsDictionary)TypeHelper.CreateInstanceOfOpenType(typeof(RelationshipsDictionary<>), resourceType, true, prevLayerRelationships); + return (IRelationshipsDictionary)TypeHelper.CreateInstanceOfOpenType(typeof(RelationshipsDictionary<>), resourceType, true, prevLayerRelationshipsWithDbValues); } /// diff --git a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpressionExtensions.cs b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpressionExtensions.cs index 4afc587499..7375326189 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpressionExtensions.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/SparseFieldSetExpressionExtensions.cs @@ -18,12 +18,14 @@ public static SparseFieldSetExpression Including(this SparseFieldSetE ArgumentGuard.NotNull(fieldSelector, nameof(fieldSelector)); ArgumentGuard.NotNull(resourceGraph, nameof(resourceGraph)); + var newSparseFieldSet = sparseFieldSet; + foreach (var field in resourceGraph.GetFields(fieldSelector)) { - sparseFieldSet = IncludeField(sparseFieldSet, field); + newSparseFieldSet = IncludeField(newSparseFieldSet, field); } - return sparseFieldSet; + return newSparseFieldSet; } private static SparseFieldSetExpression IncludeField(SparseFieldSetExpression sparseFieldSet, ResourceFieldAttribute fieldToInclude) @@ -45,12 +47,14 @@ public static SparseFieldSetExpression Excluding(this SparseFieldSetE ArgumentGuard.NotNull(fieldSelector, nameof(fieldSelector)); ArgumentGuard.NotNull(resourceGraph, nameof(resourceGraph)); + var newSparseFieldSet = sparseFieldSet; + foreach (var field in resourceGraph.GetFields(fieldSelector)) { - sparseFieldSet = ExcludeField(sparseFieldSet, field); + newSparseFieldSet = ExcludeField(newSparseFieldSet, field); } - return sparseFieldSet; + return newSparseFieldSet; } private static SparseFieldSetExpression ExcludeField(SparseFieldSetExpression sparseFieldSet, ResourceFieldAttribute fieldToExclude) diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/ResourceFieldChainResolver.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/ResourceFieldChainResolver.cs index ce0b703328..b0a4af334f 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/ResourceFieldChainResolver.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/ResourceFieldChainResolver.cs @@ -29,21 +29,22 @@ public IReadOnlyCollection ResolveToManyChain(ResourceCo var chain = new List(); var publicNameParts = path.Split("."); + var nextResourceContext = resourceContext; foreach (string publicName in publicNameParts[..^1]) { - var relationship = GetRelationship(publicName, resourceContext, path); + var relationship = GetRelationship(publicName, nextResourceContext, path); - validateCallback?.Invoke(relationship, resourceContext, path); + validateCallback?.Invoke(relationship, nextResourceContext, path); chain.Add(relationship); - resourceContext = _resourceContextProvider.GetResourceContext(relationship.RightType); + nextResourceContext = _resourceContextProvider.GetResourceContext(relationship.RightType); } string lastName = publicNameParts[^1]; - var lastToManyRelationship = GetToManyRelationship(lastName, resourceContext, path); + var lastToManyRelationship = GetToManyRelationship(lastName, nextResourceContext, path); - validateCallback?.Invoke(lastToManyRelationship, resourceContext, path); + validateCallback?.Invoke(lastToManyRelationship, nextResourceContext, path); chain.Add(lastToManyRelationship); return chain; @@ -65,15 +66,16 @@ public IReadOnlyCollection ResolveRelationshipChain(Reso Action validateCallback = null) { var chain = new List(); + var nextResourceContext = resourceContext; foreach (string publicName in path.Split(".")) { - var relationship = GetRelationship(publicName, resourceContext, path); + var relationship = GetRelationship(publicName, nextResourceContext, path); - validateCallback?.Invoke(relationship, resourceContext, path); + validateCallback?.Invoke(relationship, nextResourceContext, path); chain.Add(relationship); - resourceContext = _resourceContextProvider.GetResourceContext(relationship.RightType); + nextResourceContext = _resourceContextProvider.GetResourceContext(relationship.RightType); } return chain; @@ -94,21 +96,22 @@ public IReadOnlyCollection ResolveToOneChainEndingInAttr List chain = new List(); var publicNameParts = path.Split("."); + var nextResourceContext = resourceContext; foreach (string publicName in publicNameParts[..^1]) { - var toOneRelationship = GetToOneRelationship(publicName, resourceContext, path); + var toOneRelationship = GetToOneRelationship(publicName, nextResourceContext, path); - validateCallback?.Invoke(toOneRelationship, resourceContext, path); + validateCallback?.Invoke(toOneRelationship, nextResourceContext, path); chain.Add(toOneRelationship); - resourceContext = _resourceContextProvider.GetResourceContext(toOneRelationship.RightType); + nextResourceContext = _resourceContextProvider.GetResourceContext(toOneRelationship.RightType); } string lastName = publicNameParts[^1]; - var lastAttribute = GetAttribute(lastName, resourceContext, path); + var lastAttribute = GetAttribute(lastName, nextResourceContext, path); - validateCallback?.Invoke(lastAttribute, resourceContext, path); + validateCallback?.Invoke(lastAttribute, nextResourceContext, path); chain.Add(lastAttribute); return chain; @@ -129,22 +132,23 @@ public IReadOnlyCollection ResolveToOneChainEndingInToMa List chain = new List(); var publicNameParts = path.Split("."); + var nextResourceContext = resourceContext; foreach (string publicName in publicNameParts[..^1]) { - var toOneRelationship = GetToOneRelationship(publicName, resourceContext, path); + var toOneRelationship = GetToOneRelationship(publicName, nextResourceContext, path); - validateCallback?.Invoke(toOneRelationship, resourceContext, path); + validateCallback?.Invoke(toOneRelationship, nextResourceContext, path); chain.Add(toOneRelationship); - resourceContext = _resourceContextProvider.GetResourceContext(toOneRelationship.RightType); + nextResourceContext = _resourceContextProvider.GetResourceContext(toOneRelationship.RightType); } string lastName = publicNameParts[^1]; - var toManyRelationship = GetToManyRelationship(lastName, resourceContext, path); + var toManyRelationship = GetToManyRelationship(lastName, nextResourceContext, path); - validateCallback?.Invoke(toManyRelationship, resourceContext, path); + validateCallback?.Invoke(toManyRelationship, nextResourceContext, path); chain.Add(toManyRelationship); return chain; @@ -165,28 +169,29 @@ public IReadOnlyCollection ResolveToOneChainEndingInAttr List chain = new List(); var publicNameParts = path.Split("."); + var nextResourceContext = resourceContext; foreach (string publicName in publicNameParts[..^1]) { - var toOneRelationship = GetToOneRelationship(publicName, resourceContext, path); + var toOneRelationship = GetToOneRelationship(publicName, nextResourceContext, path); - validateCallback?.Invoke(toOneRelationship, resourceContext, path); + validateCallback?.Invoke(toOneRelationship, nextResourceContext, path); chain.Add(toOneRelationship); - resourceContext = _resourceContextProvider.GetResourceContext(toOneRelationship.RightType); + nextResourceContext = _resourceContextProvider.GetResourceContext(toOneRelationship.RightType); } string lastName = publicNameParts[^1]; - var lastField = GetField(lastName, resourceContext, path); + var lastField = GetField(lastName, nextResourceContext, path); if (lastField is HasManyAttribute) { throw new QueryParseException(path == lastName - ? $"Field '{lastName}' must be an attribute or a to-one relationship on resource '{resourceContext.PublicName}'." - : $"Field '{lastName}' in '{path}' must be an attribute or a to-one relationship on resource '{resourceContext.PublicName}'."); + ? $"Field '{lastName}' must be an attribute or a to-one relationship on resource '{nextResourceContext.PublicName}'." + : $"Field '{lastName}' in '{path}' must be an attribute or a to-one relationship on resource '{nextResourceContext.PublicName}'."); } - validateCallback?.Invoke(lastField, resourceContext, path); + validateCallback?.Invoke(lastField, nextResourceContext, path); chain.Add(lastField); return chain; diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs index 783d5aeed0..eac149391a 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs @@ -132,11 +132,11 @@ private IncludeExpression ComposeChildren(QueryLayer topLayer, ICollection ProcessIncludeSet(IReadOnlyCollection includeElements, QueryLayer parentLayer, ICollection parentRelationshipChain, ICollection constraints) { - includeElements = GetIncludeElements(includeElements, parentLayer.ResourceContext) ?? Array.Empty(); + var includeElementsEvaluated = GetIncludeElements(includeElements, parentLayer.ResourceContext) ?? Array.Empty(); var updatesInChildren = new Dictionary>(); - foreach (var includeElement in includeElements) + foreach (var includeElement in includeElementsEvaluated) { parentLayer.Projection ??= new Dictionary(); @@ -186,7 +186,7 @@ private IReadOnlyCollection ProcessIncludeSet(IReadOnl } } - return !updatesInChildren.Any() ? includeElements : ApplyIncludeElementUpdates(includeElements, updatesInChildren); + return !updatesInChildren.Any() ? includeElementsEvaluated : ApplyIncludeElementUpdates(includeElementsEvaluated, updatesInChildren); } private static IReadOnlyCollection ApplyIncludeElementUpdates(IEnumerable includeElements, @@ -417,8 +417,7 @@ protected virtual IReadOnlyCollection GetIncludeElemen { ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); - includeElements = _resourceDefinitionAccessor.OnApplyIncludes(resourceContext.ResourceType, includeElements); - return includeElements; + return _resourceDefinitionAccessor.OnApplyIncludes(resourceContext.ResourceType, includeElements); } protected virtual FilterExpression GetFilter(IReadOnlyCollection expressionsInScope, ResourceContext resourceContext) diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs index 3e4284e9fd..f0c47aaf5b 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs @@ -63,15 +63,17 @@ public override Expression VisitInclude(IncludeExpression expression, object arg private Expression ApplyEagerLoads(Expression source, IEnumerable eagerLoads, string pathPrefix) { + var result = source; + foreach (var eagerLoad in eagerLoads) { string path = pathPrefix != null ? pathPrefix + "." + eagerLoad.Property.Name : eagerLoad.Property.Name; - source = IncludeExtensionMethodCall(source, path); + result = IncludeExtensionMethodCall(result, path); - source = ApplyEagerLoads(source, eagerLoad.Children, path); + result = ApplyEagerLoads(result, eagerLoad.Children, path); } - return source; + return result; } private Expression IncludeExtensionMethodCall(Expression source, string navigationPropertyPath) diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs index e8b1991f83..822836c6c7 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs @@ -99,13 +99,16 @@ private void ReadSingleValue(string parameterName, string parameterValue) { try { + string name = parameterName; + string value = parameterValue; + if (_options.EnableLegacyFilterNotation) { - (parameterName, parameterValue) = LegacyConverter.Convert(parameterName, parameterValue); + (name, value) = LegacyConverter.Convert(name, value); } - ResourceFieldChainExpression scope = GetScope(parameterName); - FilterExpression filter = GetFilter(parameterValue, scope); + ResourceFieldChainExpression scope = GetScope(name); + FilterExpression filter = GetFilter(value, scope); StoreFilterInScope(filter, scope); } diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringReader.cs index 6297463a4f..b7528624d2 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringReader.cs @@ -34,7 +34,7 @@ public QueryStringReader(IJsonApiOptions options, IRequestQueryStringAccessor qu /// public virtual void ReadAll(DisableQueryStringAttribute disableQueryStringAttribute) { - disableQueryStringAttribute ??= DisableQueryStringAttribute.Empty; + var disableQueryStringAttributeNotNull = disableQueryStringAttribute ?? DisableQueryStringAttribute.Empty; foreach (var (parameterName, parameterValue) in _queryStringAccessor.Query) { @@ -51,7 +51,7 @@ public virtual void ReadAll(DisableQueryStringAttribute disableQueryStringAttrib _logger.LogDebug( $"Query string parameter '{parameterName}' with value '{parameterValue}' was accepted by {reader.GetType().Name}."); - if (!reader.IsEnabled(disableQueryStringAttribute)) + if (!reader.IsEnabled(disableQueryStringAttributeNotNull)) { throw new InvalidQueryStringParameterException(parameterName, "Usage of one or more query string parameters is not allowed at the requested endpoint.", diff --git a/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs b/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs index 95f525ed7c..a87155cda1 100644 --- a/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs +++ b/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs @@ -92,10 +92,11 @@ protected virtual IQueryable ApplyQueryLayer(QueryLayer layer) ArgumentGuard.NotNull(layer, nameof(layer)); + QueryLayer rewrittenLayer = layer; if (EntityFrameworkCoreSupport.Version.Major < 5) { var writer = new MemoryLeakDetectionBugRewriter(); - layer = writer.Rewrite(layer); + rewrittenLayer = writer.Rewrite(layer); } IQueryable source = GetAll(); @@ -121,7 +122,7 @@ protected virtual IQueryable ApplyQueryLayer(QueryLayer layer) var nameFactory = new LambdaParameterNameFactory(); var builder = new QueryableBuilder(source.Expression, source.ElementType, typeof(Queryable), nameFactory, _resourceFactory, _resourceGraph, _dbContext.Model); - var expression = builder.ApplyQuery(layer); + var expression = builder.ApplyQuery(rewrittenLayer); return source.Provider.CreateQuery(expression); } diff --git a/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs index f76e8391e4..5f5f40368f 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs @@ -36,9 +36,13 @@ public virtual ResourceObject Build(IIdentifiable resource, IReadOnlyCollection< var resourceObject = new ResourceObject { Type = resourceContext.PublicName, Id = resource.StringId }; // populating the top-level "attribute" member of a resource object. never include "id" as an attribute - if (attributes != null && (attributes = attributes.Where(attr => attr.Property.Name != nameof(Identifiable.Id)).ToArray()).Any()) + if (attributes != null) { - ProcessAttributes(resource, attributes, resourceObject); + var attributesWithoutId = attributes.Where(attr => attr.Property.Name != nameof(Identifiable.Id)).ToArray(); + if (attributesWithoutId.Any()) + { + ProcessAttributes(resource, attributesWithoutId, resourceObject); + } } // populating the top-level "relationship" member of a resource object. diff --git a/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs b/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs index 8608101ed4..c925825a80 100644 --- a/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs +++ b/src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs @@ -87,21 +87,21 @@ private string SerializeResponse(object contextObject, HttpStatusCode statusCode } } - contextObject = WrapErrors(contextObject); + var contextObjectWrapped = WrapErrors(contextObject); - return _serializer.Serialize(contextObject); + return _serializer.Serialize(contextObjectWrapped); } private static object WrapErrors(object contextObject) { if (contextObject is IEnumerable errors) { - contextObject = new ErrorDocument(errors); + return new ErrorDocument(errors); } if (contextObject is Error error) { - contextObject = new ErrorDocument(error); + return new ErrorDocument(error); } return contextObject; diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs index ced06e127f..d3869ba33d 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/AtomicOperations/QueryStrings/MusicTrackReleaseDefinition.cs @@ -32,14 +32,16 @@ public override QueryStringParameterHandlers OnRegisterQueryableHand private IQueryable FilterOnRecentlyReleased(IQueryable source, StringValues parameterValue) { + var tracks = source; + if (bool.Parse(parameterValue)) { - source = source.Where(musicTrack => + tracks = tracks.Where(musicTrack => musicTrack.ReleasedAt < _systemClock.UtcNow && musicTrack.ReleasedAt > _systemClock.UtcNow.AddMonths(-3)); } - return source; + return tracks; } } } From c5dd9182e43efb6080160bed3553eec277aa4a37 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Sat, 27 Feb 2021 11:31:27 +0100 Subject: [PATCH 55/60] AV1535: Block scope in case clauses --- .../AtomicOperations/OperationProcessorAccessor.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/JsonApiDotNetCore/AtomicOperations/OperationProcessorAccessor.cs b/src/JsonApiDotNetCore/AtomicOperations/OperationProcessorAccessor.cs index 54978414b7..551e564358 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/OperationProcessorAccessor.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/OperationProcessorAccessor.cs @@ -50,19 +50,33 @@ private static Type GetProcessorInterface(OperationKind kind) switch (kind) { case OperationKind.CreateResource: + { return typeof(ICreateProcessor<,>); + } case OperationKind.UpdateResource: + { return typeof(IUpdateProcessor<,>); + } case OperationKind.DeleteResource: + { return typeof(IDeleteProcessor<,>); + } case OperationKind.SetRelationship: + { return typeof(ISetRelationshipProcessor<,>); + } case OperationKind.AddToRelationship: + { return typeof(IAddToRelationshipProcessor<,>); + } case OperationKind.RemoveFromRelationship: + { return typeof(IRemoveFromRelationshipProcessor<,>); + } default: + { throw new NotSupportedException($"Unknown operation kind '{kind}'."); + } } } } From f7b0e2b1b1f800111b2372823e3d47db9b3a01e1 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Sat, 27 Feb 2021 11:33:52 +0100 Subject: [PATCH 56/60] AV1522: Multiple assignments in single statement --- .../Serialization/Building/IncludedResourceObjectBuilder.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs index a590fa0063..f6f0184d2e 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs @@ -144,7 +144,8 @@ private void ProcessRelationship(IIdentifiable parent, List Date: Tue, 2 Mar 2021 12:21:34 +0100 Subject: [PATCH 57/60] AV1532: Avoid nested loops --- .../AtomicOperations/LocalIdValidator.cs | 42 +++++----- .../InverseNavigationResolver.cs | 21 +++-- .../Configuration/ServiceDiscoveryFacade.cs | 31 ++++---- .../Configuration/TypeLocator.cs | 21 ++--- .../BaseJsonApiOperationsController.cs | 30 +++++-- .../Errors/InvalidModelStateException.cs | 50 ++++++++---- .../Internal/Execution/HookExecutorHelper.cs | 72 +++++++++-------- .../Hooks/Internal/ResourceHookExecutor.cs | 22 +++--- .../Hooks/Internal/Traversal/ChildNode.cs | 34 ++++---- .../Internal/Traversal/TraversalHelper.cs | 78 +++++++++++-------- .../Expressions/IncludeChainConverter.cs | 25 +++--- .../QueryableBuilding/IncludeClauseBuilder.cs | 24 +++--- .../Queries/Internal/SparseFieldSetCache.cs | 26 ++++--- .../FilterQueryStringParameterReader.cs | 21 +++-- .../Resources/OperationContainer.cs | 17 ++-- .../Building/IncludedResourceObjectBuilder.cs | 46 ++++++----- 16 files changed, 331 insertions(+), 229 deletions(-) diff --git a/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs b/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs index 55061a8ed8..95ce18da6d 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/LocalIdValidator.cs @@ -37,28 +37,10 @@ public void Validate(IEnumerable operations) { foreach (var operation in operations) { - if (operation.Kind == OperationKind.CreateResource) - { - DeclareLocalId(operation.Resource); - } - else - { - AssertLocalIdIsAssigned(operation.Resource); - } - - foreach (var secondaryResource in operation.GetSecondaryResources()) - { - AssertLocalIdIsAssigned(secondaryResource); - } - - if (operation.Kind == OperationKind.CreateResource) - { - AssignLocalId(operation); - } + ValidateOperation(operation); operationIndex++; } - } catch (JsonApiException exception) { @@ -71,6 +53,28 @@ public void Validate(IEnumerable operations) } } + private void ValidateOperation(OperationContainer operation) + { + if (operation.Kind == OperationKind.CreateResource) + { + DeclareLocalId(operation.Resource); + } + else + { + AssertLocalIdIsAssigned(operation.Resource); + } + + foreach (var secondaryResource in operation.GetSecondaryResources()) + { + AssertLocalIdIsAssigned(secondaryResource); + } + + if (operation.Kind == OperationKind.CreateResource) + { + AssignLocalId(operation); + } + } + private void DeclareLocalId(IIdentifiable resource) { if (resource.LocalId != null) diff --git a/src/JsonApiDotNetCore/Configuration/InverseNavigationResolver.cs b/src/JsonApiDotNetCore/Configuration/InverseNavigationResolver.cs index 63d9c600ea..4c895a9251 100644 --- a/src/JsonApiDotNetCore/Configuration/InverseNavigationResolver.cs +++ b/src/JsonApiDotNetCore/Configuration/InverseNavigationResolver.cs @@ -41,14 +41,19 @@ private void Resolve(DbContext dbContext) IEntityType entityType = dbContext.Model.FindEntityType(resourceContext.ResourceType); if (entityType != null) { - foreach (var relationship in resourceContext.Relationships) - { - if (!(relationship is HasManyThroughAttribute)) - { - INavigation inverseNavigation = entityType.FindNavigation(relationship.Property.Name)?.FindInverse(); - relationship.InverseNavigationProperty = inverseNavigation?.PropertyInfo; - } - } + ResolveRelationships(resourceContext.Relationships, entityType); + } + } + } + + private void ResolveRelationships(IReadOnlyCollection relationships, IEntityType entityType) + { + foreach (var relationship in relationships) + { + if (!(relationship is HasManyThroughAttribute)) + { + INavigation inverseNavigation = entityType.FindNavigation(relationship.Property.Name)?.FindInverse(); + relationship.InverseNavigationProperty = inverseNavigation?.PropertyInfo; } } } diff --git a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs index 40107fc477..bdcd027a84 100644 --- a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs +++ b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs @@ -101,12 +101,9 @@ public ServiceDiscoveryFacade AddAssembly(Assembly assembly) internal void DiscoverResources() { - foreach (var (_, resourceDescriptors) in _assemblyCache.GetResourceDescriptorsPerAssembly()) + foreach (var resourceDescriptor in _assemblyCache.GetResourceDescriptorsPerAssembly().SelectMany(tuple => tuple.resourceDescriptors)) { - foreach (var resourceDescriptor in resourceDescriptors) - { - AddResource(resourceDescriptor); - } + AddResource(resourceDescriptor); } } @@ -115,21 +112,25 @@ internal void DiscoverInjectables() foreach (var (assembly, resourceDescriptors) in _assemblyCache.GetResourceDescriptorsPerAssembly()) { AddDbContextResolvers(assembly); + AddInjectables(resourceDescriptors, assembly); + } + } - foreach (var resourceDescriptor in resourceDescriptors) + private void AddInjectables(IReadOnlyCollection resourceDescriptors, Assembly assembly) + { + foreach (var resourceDescriptor in resourceDescriptors) + { + AddServices(assembly, resourceDescriptor); + AddRepositories(assembly, resourceDescriptor); + AddResourceDefinitions(assembly, resourceDescriptor); + + if (_options.EnableResourceHooks) { - AddServices(assembly, resourceDescriptor); - AddRepositories(assembly, resourceDescriptor); - AddResourceDefinitions(assembly, resourceDescriptor); - - if (_options.EnableResourceHooks) - { - AddResourceHookDefinitions(assembly, resourceDescriptor); - } + AddResourceHookDefinitions(assembly, resourceDescriptor); } } } - + private void AddDbContextResolvers(Assembly assembly) { var dbContextTypes = TypeLocator.GetDerivedTypes(assembly, typeof(DbContext)); diff --git a/src/JsonApiDotNetCore/Configuration/TypeLocator.cs b/src/JsonApiDotNetCore/Configuration/TypeLocator.cs index 057c3ef918..a3684b77ca 100644 --- a/src/JsonApiDotNetCore/Configuration/TypeLocator.cs +++ b/src/JsonApiDotNetCore/Configuration/TypeLocator.cs @@ -70,18 +70,21 @@ public static (Type implementation, Type registrationInterface)? GetGenericInter $"instead of {interfaceGenericTypeArguments.Length}.", nameof(interfaceGenericTypeArguments)); } - foreach (var nextType in assembly.GetTypes()) + return assembly.GetTypes().Select(type => FindGenericInterfaceImplementationForType(type, openGenericInterface, interfaceGenericTypeArguments)) + .FirstOrDefault(result => result != null); + } + + private static (Type implementation, Type registrationInterface)? FindGenericInterfaceImplementationForType(Type nextType, Type openGenericInterface, Type[] interfaceGenericTypeArguments) + { + foreach (var nextGenericInterface in nextType.GetInterfaces().Where(type => type.IsGenericType)) { - foreach (var nextGenericInterface in nextType.GetInterfaces().Where(x => x.IsGenericType)) + var nextOpenGenericInterface = nextGenericInterface.GetGenericTypeDefinition(); + if (nextOpenGenericInterface == openGenericInterface) { - var nextOpenGenericInterface = nextGenericInterface.GetGenericTypeDefinition(); - if (nextOpenGenericInterface == openGenericInterface) + var nextGenericArguments = nextGenericInterface.GetGenericArguments(); + if (nextGenericArguments.Length == interfaceGenericTypeArguments.Length && nextGenericArguments.SequenceEqual(interfaceGenericTypeArguments)) { - var nextGenericArguments = nextGenericInterface.GetGenericArguments(); - if (nextGenericArguments.Length == interfaceGenericTypeArguments.Length && nextGenericArguments.SequenceEqual(interfaceGenericTypeArguments)) - { - return (nextType, nextOpenGenericInterface.MakeGenericType(interfaceGenericTypeArguments)); - } + return (nextType, nextOpenGenericInterface.MakeGenericType(interfaceGenericTypeArguments)); } } } diff --git a/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs b/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs index 27c1319371..719b281db6 100644 --- a/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs +++ b/src/JsonApiDotNetCore/Controllers/BaseJsonApiOperationsController.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -9,6 +10,7 @@ using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.Resources; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.Extensions.Logging; namespace JsonApiDotNetCore.Controllers @@ -157,14 +159,7 @@ protected virtual void ValidateModelState(IEnumerable operat if (!validationContext.ModelState.IsValid) { - foreach (var (key, entry) in validationContext.ModelState) - { - foreach (var error in entry.Errors) - { - var violation = new ModelStateViolation($"/atomic:operations[{index}]/data/attributes/", key, operation.Resource.GetType(), error); - violations.Add(violation); - } - } + AddValidationErrors(validationContext.ModelState, operation.Resource.GetType(), index, violations); } } @@ -176,5 +171,24 @@ protected virtual void ValidateModelState(IEnumerable operat throw new InvalidModelStateException(violations, _options.IncludeExceptionStackTraceInErrors, _options.SerializerNamingStrategy); } } + + private static void AddValidationErrors(ModelStateDictionary modelState, Type resourceType, int operationIndex, List violations) + { + foreach (var (propertyName, entry) in modelState) + { + AddValidationErrors(entry, propertyName, resourceType, operationIndex, violations); + } + } + + private static void AddValidationErrors(ModelStateEntry entry, string propertyName, Type resourceType, int operationIndex, List violations) + { + foreach (var error in entry.Errors) + { + var prefix = $"/atomic:operations[{operationIndex}]/data/attributes/"; + var violation = new ModelStateViolation(prefix, propertyName, resourceType, error); + + violations.Add(violation); + } + } } } diff --git a/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs b/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs index 80d2becf94..a3db7f492b 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Net; using System.Reflection; using JetBrains.Annotations; @@ -26,12 +27,26 @@ public InvalidModelStateException(ModelStateDictionary modelState, Type resource private static IEnumerable FromModelStateDictionary(ModelStateDictionary modelState, Type resourceType) { + ArgumentGuard.NotNull(modelState, nameof(modelState)); + ArgumentGuard.NotNull(resourceType, nameof(resourceType)); + + var violations = new List(); + foreach (var (propertyName, entry) in modelState) { - foreach (ModelError error in entry.Errors) - { - yield return new ModelStateViolation("/data/attributes/", propertyName, resourceType, error); - } + AddValidationErrors(entry, propertyName, resourceType, violations); + } + + return violations; + } + + private static void AddValidationErrors(ModelStateEntry entry, string propertyName, Type resourceType, + List violations) + { + foreach (ModelError error in entry.Errors) + { + var violation = new ModelStateViolation("/data/attributes/", propertyName, resourceType, error); + violations.Add(violation); } } @@ -47,22 +62,25 @@ private static IEnumerable FromModelStateViolations(IEnumerable FromModelStateViolation(violation, includeExceptionStackTraceInErrors, namingStrategy)); + } + + private static IEnumerable FromModelStateViolation(ModelStateViolation violation, bool includeExceptionStackTraceInErrors, + NamingStrategy namingStrategy) + { + if (violation.Error.Exception is JsonApiException jsonApiException) { - if (violation.Error.Exception is JsonApiException jsonApiException) + foreach (var error in jsonApiException.Errors) { - foreach (var error in jsonApiException.Errors) - { - yield return error; - } + yield return error; } - else - { - string attributeName = GetDisplayNameForProperty(violation.PropertyName, violation.ResourceType, namingStrategy); - var attributePath = violation.Prefix + attributeName; + } + else + { + string attributeName = GetDisplayNameForProperty(violation.PropertyName, violation.ResourceType, namingStrategy); + var attributePath = violation.Prefix + attributeName; - yield return FromModelError(violation.Error, attributePath, includeExceptionStackTraceInErrors); - } + yield return FromModelError(violation.Error, attributePath, includeExceptionStackTraceInErrors); } } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs index d2108411ba..222c8754e9 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/HookExecutorHelper.cs @@ -215,48 +215,56 @@ public Dictionary LoadImplicitlyAffected( // note that we don't have to check if BeforeImplicitUpdate hook is implemented. If not, it wont ever get here. var includedLefts = LoadDbValues(relationship.LeftType, lefts, ResourceHook.BeforeImplicitUpdateRelationship, relationship); - foreach (IIdentifiable ip in includedLefts) + AddToImplicitlyAffected(includedLefts, relationship, existingRightResourceList, implicitlyAffected); + } + + return implicitlyAffected.ToDictionary(kvp => kvp.Key, kvp => TypeHelper.CreateHashSetFor(kvp.Key.RightType, kvp.Value)); + } + + private void AddToImplicitlyAffected(IEnumerable includedLefts, RelationshipAttribute relationship, List existingRightResourceList, + Dictionary implicitlyAffected) + { + foreach (IIdentifiable ip in includedLefts) + { + IList dbRightResourceList = TypeHelper.CreateListFor(relationship.RightType); + var relationshipValue = relationship.GetValue(ip); + if (!(relationshipValue is IEnumerable)) { - IList dbRightResourceList = TypeHelper.CreateListFor(relationship.RightType); - var relationshipValue = relationship.GetValue(ip); - if (!(relationshipValue is IEnumerable)) - { - if (relationshipValue != null) - { - dbRightResourceList.Add(relationshipValue); - } - } - else + if (relationshipValue != null) { - foreach (var item in (IEnumerable) relationshipValue) - { - dbRightResourceList.Add(item); - } + dbRightResourceList.Add(relationshipValue); } + } + else + { + AddToList(dbRightResourceList, (IEnumerable)relationshipValue); + } - var dbRightResourceListCast = dbRightResourceList.Cast().ToList(); - if (existingRightResourceList != null) - { - dbRightResourceListCast = dbRightResourceListCast.Except(existingRightResourceList, _comparer).ToList(); - } + var dbRightResourceListCast = dbRightResourceList.Cast().ToList(); + if (existingRightResourceList != null) + { + dbRightResourceListCast = dbRightResourceListCast.Except(existingRightResourceList, _comparer).ToList(); + } - if (dbRightResourceListCast.Any()) + if (dbRightResourceListCast.Any()) + { + if (!implicitlyAffected.TryGetValue(relationship, out IEnumerable affected)) { - if (!implicitlyAffected.TryGetValue(relationship, out IEnumerable affected)) - { - affected = TypeHelper.CreateListFor(relationship.RightType); - implicitlyAffected[relationship] = affected; - } - - foreach (var item in dbRightResourceListCast) - { - ((IList)affected).Add(item); - } + affected = TypeHelper.CreateListFor(relationship.RightType); + implicitlyAffected[relationship] = affected; } + + AddToList((IList)affected, dbRightResourceListCast); } } + } - return implicitlyAffected.ToDictionary(kvp => kvp.Key, kvp => TypeHelper.CreateHashSetFor(kvp.Key.RightType, kvp.Value)); + private static void AddToList(IList list, IEnumerable itemsToAdd) + { + foreach (var item in itemsToAdd) + { + list.Add(item); + } } private bool IsHasManyThrough(KeyValuePair kvp, diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs index 73186da2c2..d2bfcb39a8 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs @@ -224,20 +224,22 @@ private void Traverse(NodeLayer currentLayer, ResourceHook target, Action action, ResourceHook target) + { + foreach (IResourceNode node in nextLayer) + { + var hookContainer = _executorHelper.GetResourceHookContainer(node.ResourceType, target); + + if (hookContainer != null) + { action(hookContainer, node); } - - nextLayer = _traversalHelper.CreateNextLayer(nextLayer.ToList()); } } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/ChildNode.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/ChildNode.cs index 045d068150..8e0ee92706 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/ChildNode.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/ChildNode.cs @@ -61,22 +61,28 @@ public void Reassign(IEnumerable updated = null) var proxy = group.Proxy; var leftResources = group.LeftResources; - foreach (IIdentifiable left in leftResources) - { - var currentValue = proxy.GetValue(left); + Reassign(leftResources, proxy, unique); + } + } - if (currentValue is IEnumerable relationshipCollection) - { - var intersection = relationshipCollection.Intersect(unique, _comparer); - IEnumerable typedCollection = TypeHelper.CopyToTypedCollection(intersection, relationshipCollection.GetType()); - proxy.SetValue(left, typedCollection); - } - else if (currentValue is IIdentifiable relationshipSingle) + private void Reassign(IEnumerable leftResources, RelationshipProxy proxy, HashSet unique) + { + foreach (IIdentifiable left in leftResources) + { + var currentValue = proxy.GetValue(left); + + if (currentValue is IEnumerable relationshipCollection) + { + var intersection = relationshipCollection.Intersect(unique, _comparer); + IEnumerable typedCollection = + TypeHelper.CopyToTypedCollection(intersection, relationshipCollection.GetType()); + proxy.SetValue(left, typedCollection); + } + else if (currentValue is IIdentifiable relationshipSingle) + { + if (!unique.Intersect(new HashSet {relationshipSingle}, _comparer).Any()) { - if (!unique.Intersect(new HashSet { relationshipSingle }, _comparer).Any()) - { - proxy.SetValue(left, null); - } + proxy.SetValue(left, null); } } } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs index 295e9d8c22..b27c0762ea 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Traversal/TraversalHelper.cs @@ -131,38 +131,8 @@ private Dictionary(), proxy.RightType); - if (proxy.IsContextRelation || uniqueRightResources.Any()) - { - AddToRelationshipGroup(rightResourcesGrouped, proxy, uniqueRightResources); - AddToRelationshipGroup(leftResourcesGrouped, proxy, leftResource.AsEnumerable()); - } - } - } + + ExtractLeftResources(leftResources, relationships, rightResourcesGrouped, leftResourcesGrouped); } var processResourcesMethod = GetType().GetMethod(nameof(ProcessResources), BindingFlags.NonPublic | BindingFlags.Instance); @@ -176,6 +146,50 @@ private Dictionary> rightResourcesGrouped, + Dictionary> leftResourcesGrouped) + { + foreach (IIdentifiable leftResource in leftResources) + { + ExtractLeftResource(leftResource, relationships, rightResourcesGrouped, leftResourcesGrouped); + } + } + + private void ExtractLeftResource(IIdentifiable leftResource, RelationshipProxy[] relationships, + Dictionary> rightResourcesGrouped, + Dictionary> leftResourcesGrouped) + { + foreach (var proxy in relationships) + { + var relationshipValue = proxy.GetValue(leftResource); + // skip this relationship if it's not populated + if (!proxy.IsContextRelation && relationshipValue == null) + { + continue; + } + + if (!(relationshipValue is IEnumerable rightResources)) + { + // in the case of a to-one relationship, the assigned value + // will not be a list. We therefore first wrap it in a list. + var list = TypeHelper.CreateListFor(proxy.RightType); + if (relationshipValue != null) + { + list.Add(relationshipValue); + } + + rightResources = list; + } + + var uniqueRightResources = UniqueInTree(rightResources.Cast(), proxy.RightType); + if (proxy.IsContextRelation || uniqueRightResources.Any()) + { + AddToRelationshipGroup(rightResourcesGrouped, proxy, uniqueRightResources); + AddToRelationshipGroup(leftResourcesGrouped, proxy, leftResource.AsEnumerable()); + } + } + } + /// /// Get all populated relationships known in the current tree traversal from a /// left type to any right type diff --git a/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs b/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs index 27de23ddfd..6814166c4f 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/IncludeChainConverter.cs @@ -76,20 +76,25 @@ private static IReadOnlyCollection ConvertChainsToElem foreach (ResourceFieldChainExpression chain in chains) { - MutableIncludeNode currentNode = rootNode; + ConvertChainToElement(chain, rootNode); + } - foreach (var relationship in chain.Fields.OfType()) - { - if (!currentNode.Children.ContainsKey(relationship)) - { - currentNode.Children[relationship] = new MutableIncludeNode(relationship); - } + return rootNode.Children.Values.Select(child => child.ToExpression()).ToArray(); + } - currentNode = currentNode.Children[relationship]; + private static void ConvertChainToElement(ResourceFieldChainExpression chain, MutableIncludeNode rootNode) + { + MutableIncludeNode currentNode = rootNode; + + foreach (var relationship in chain.Fields.OfType()) + { + if (!currentNode.Children.ContainsKey(relationship)) + { + currentNode.Children[relationship] = new MutableIncludeNode(relationship); } - } - return rootNode.Children.Values.Select(child => child.ToExpression()).ToArray(); + currentNode = currentNode.Children[relationship]; + } } private sealed class IncludeToChainsConverter : QueryExpressionVisitor diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs index f0c47aaf5b..2571b4931f 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/IncludeClauseBuilder.cs @@ -45,20 +45,26 @@ public override Expression VisitInclude(IncludeExpression expression, object arg foreach (ResourceFieldChainExpression chain in IncludeChainConverter.GetRelationshipChains(expression)) { - string path = null; + source = ProcessRelationshipChain(chain, source); + } + + return source; + } - foreach (var relationship in chain.Fields.Cast()) - { - path = path == null ? relationship.RelationshipPath : path + "." + relationship.RelationshipPath; + private Expression ProcessRelationshipChain(ResourceFieldChainExpression chain, Expression source) + { + string path = null; + var result = source; - var resourceContext = _resourceContextProvider.GetResourceContext(relationship.RightType); - source = ApplyEagerLoads(source, resourceContext.EagerLoads, path); - } + foreach (var relationship in chain.Fields.Cast()) + { + path = path == null ? relationship.RelationshipPath : path + "." + relationship.RelationshipPath; - source = IncludeExtensionMethodCall(source, path); + var resourceContext = _resourceContextProvider.GetResourceContext(relationship.RightType); + result = ApplyEagerLoads(result, resourceContext.EagerLoads, path); } - return source; + return IncludeExtensionMethodCall(result, path); } private Expression ApplyEagerLoads(Expression source, IEnumerable eagerLoads, string pathPrefix) diff --git a/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs b/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs index cedc3e6228..9f355696d3 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/SparseFieldSetCache.cs @@ -40,6 +40,7 @@ private static IDictionary> Bui .Select(constraint => constraint.Expression) .OfType() .Select(expression => expression.Table) + .SelectMany(table => table) .ToArray(); // @formatter:keep_existing_linebreaks restore @@ -47,25 +48,28 @@ private static IDictionary> Bui var mergedTable = new Dictionary>(); - foreach (var sparseFieldTable in sparseFieldTables) + foreach (var (resourceContext, sparseFieldSet) in sparseFieldTables) { - foreach (var (resourceContext, sparseFieldSet) in sparseFieldTable) + if (!mergedTable.ContainsKey(resourceContext)) { - if (!mergedTable.ContainsKey(resourceContext)) - { - mergedTable[resourceContext] = new HashSet(); - } - - foreach (var field in sparseFieldSet.Fields) - { - mergedTable[resourceContext].Add(field); - } + mergedTable[resourceContext] = new HashSet(); } + + AddSparseFieldsToSet(sparseFieldSet.Fields, mergedTable[resourceContext]); } return mergedTable; } + private static void AddSparseFieldsToSet(IReadOnlyCollection sparseFieldsToAdd, + HashSet sparseFieldSet) + { + foreach (var field in sparseFieldsToAdd) + { + sparseFieldSet.Add(field); + } + } + public IReadOnlyCollection GetSparseFieldSetForQuery(ResourceContext resourceContext) { ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); diff --git a/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs index 822836c6c7..3565f9beb1 100644 --- a/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs @@ -71,28 +71,25 @@ public virtual void Read(string parameterName, StringValues parameterValue) { _lastParameterName = parameterName; - foreach (string value in ExtractParameterValues(parameterValue)) + foreach (string value in parameterValue.SelectMany(ExtractParameterValue)) { ReadSingleValue(parameterName, value); } } - private IEnumerable ExtractParameterValues(StringValues parameterValues) + private IEnumerable ExtractParameterValue(string parameterValue) { - foreach (string parameterValue in parameterValues) + if (_options.EnableLegacyFilterNotation) { - if (_options.EnableLegacyFilterNotation) - { - foreach (string condition in LegacyConverter.ExtractConditions(parameterValue)) - { - yield return condition; - } - } - else + foreach (string condition in LegacyConverter.ExtractConditions(parameterValue)) { - yield return parameterValue; + yield return condition; } } + else + { + yield return parameterValue; + } } private void ReadSingleValue(string parameterName, string parameterValue) diff --git a/src/JsonApiDotNetCore/Resources/OperationContainer.cs b/src/JsonApiDotNetCore/Resources/OperationContainer.cs index 083ecc8dd4..85000dff0e 100644 --- a/src/JsonApiDotNetCore/Resources/OperationContainer.cs +++ b/src/JsonApiDotNetCore/Resources/OperationContainer.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using JetBrains.Annotations; using JsonApiDotNetCore.Middleware; +using JsonApiDotNetCore.Resources.Annotations; namespace JsonApiDotNetCore.Resources { @@ -47,14 +48,20 @@ public ISet GetSecondaryResources() foreach (var relationship in TargetedFields.Relationships) { - var rightValue = relationship.GetValue(Resource); - foreach (var rightResource in TypeHelper.ExtractResources(rightValue)) - { - secondaryResources.Add(rightResource); - } + AddSecondaryResources(relationship, secondaryResources); } return secondaryResources; } + + private void AddSecondaryResources(RelationshipAttribute relationship, HashSet secondaryResources) + { + var rightValue = relationship.GetValue(Resource); + + foreach (var rightResource in TypeHelper.ExtractResources(rightValue)) + { + secondaryResources.Add(rightResource); + } + } } } diff --git a/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs index f6f0184d2e..b784f7cf8b 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs @@ -50,26 +50,9 @@ public IList Build() { if (resourceObject.Relationships != null) { - foreach (var relationshipName in resourceObject.Relationships.Keys.ToArray()) - { - var resourceContext = ResourceContextProvider.GetResourceContext(resourceObject.Type); - var relationship = resourceContext.Relationships.Single(rel => rel.PublicName == relationshipName); - - if (!IsRelationshipInSparseFieldSet(relationship)) - { - resourceObject.Relationships.Remove(relationshipName); - } - } - - // removes relationship entries (s) if they're completely empty. - var pruned = resourceObject.Relationships.Where(p => p.Value.IsPopulated || p.Value.Links != null).ToDictionary(p => p.Key, p => p.Value); - if (!pruned.Any()) - { - pruned = null; - } - - resourceObject.Relationships = pruned; + UpdateRelationships(resourceObject); } + resourceObject.Links = _linkBuilder.GetResourceLinks(resourceObject.Type, resourceObject.Id); } return _included.ToArray(); @@ -77,6 +60,31 @@ public IList Build() return null; } + private void UpdateRelationships(ResourceObject resourceObject) + { + foreach (var relationshipName in resourceObject.Relationships.Keys.ToArray()) + { + var resourceContext = ResourceContextProvider.GetResourceContext(resourceObject.Type); + var relationship = resourceContext.Relationships.Single(rel => rel.PublicName == relationshipName); + + if (!IsRelationshipInSparseFieldSet(relationship)) + { + resourceObject.Relationships.Remove(relationshipName); + } + } + + resourceObject.Relationships = PruneRelationshipEntries(resourceObject); + } + + private static Dictionary PruneRelationshipEntries(ResourceObject resourceObject) + { + var pruned = resourceObject.Relationships + .Where(pair => pair.Value.IsPopulated || pair.Value.Links != null) + .ToDictionary(pair => pair.Key, pair => pair.Value); + + return !pruned.Any() ? null : pruned; + } + private bool IsRelationshipInSparseFieldSet(RelationshipAttribute relationship) { var resourceContext = ResourceContextProvider.GetResourceContext(relationship.LeftType); From a0bf005c5b820096aeef419ea8b8c20eb134307b Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Tue, 2 Mar 2021 13:24:30 +0100 Subject: [PATCH 58/60] AV1010: Member hides inherited member --- .../Hooks/Internal/Execution/DiffableResourceHashSet.cs | 2 +- .../Hooks/Internal/Execution/ResourceHashSet.cs | 2 +- .../Serialization/Common/BaseDocumentBuilderTests.cs | 8 ++++---- test/UnitTests/Serialization/SerializerTestsSetup.cs | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs index f4c764240b..574966af47 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/DiffableResourceHashSet.cs @@ -57,7 +57,7 @@ public IEnumerable> GetDiffs() } /// - public new HashSet GetAffected(Expression> navigationAction) + public override HashSet GetAffected(Expression> navigationAction) { ArgumentGuard.NotNull(navigationAction, nameof(navigationAction)); diff --git a/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceHashSet.cs b/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceHashSet.cs index 067dec9dcc..192bcdad21 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceHashSet.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/Execution/ResourceHashSet.cs @@ -51,7 +51,7 @@ public Dictionary> GetByRelationship - public HashSet GetAffected(Expression> navigationAction) + public virtual HashSet GetAffected(Expression> navigationAction) { return _relationships.GetAffected(navigationAction); } diff --git a/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs b/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs index 5219ffa792..9e21fc2f62 100644 --- a/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs +++ b/test/UnitTests/Serialization/Common/BaseDocumentBuilderTests.cs @@ -26,7 +26,7 @@ public BaseDocumentBuilderTests() public void ResourceToDocument_NullResource_CanBuild() { // Act - var document = _builder.Build((TestResource) null); + var document = _builder.PublicBuild((TestResource) null); // Assert Assert.Null(document.Data); @@ -38,7 +38,7 @@ public void ResourceToDocument_NullResource_CanBuild() public void ResourceToDocument_EmptyList_CanBuild() { // Act - var document = _builder.Build(new List()); + var document = _builder.PublicBuild(new List()); // Assert Assert.NotNull(document.Data); @@ -53,7 +53,7 @@ public void ResourceToDocument_SingleResource_CanBuild() IIdentifiable dummy = new DummyResource(); // Act - var document = _builder.Build(dummy); + var document = _builder.PublicBuild(dummy); // Assert Assert.NotNull(document.Data); @@ -67,7 +67,7 @@ public void ResourceToDocument_ResourceList_CanBuild() var resources = ArrayFactory.Create(new DummyResource(), new DummyResource()); // Act - var document = _builder.Build(resources); + var document = _builder.PublicBuild(resources); var data = (List)document.Data; // Assert diff --git a/test/UnitTests/Serialization/SerializerTestsSetup.cs b/test/UnitTests/Serialization/SerializerTestsSetup.cs index 0f1bc4daea..d856f48d81 100644 --- a/test/UnitTests/Serialization/SerializerTestsSetup.cs +++ b/test/UnitTests/Serialization/SerializerTestsSetup.cs @@ -128,14 +128,14 @@ protected sealed class TestSerializer : BaseSerializer { public TestSerializer(IResourceObjectBuilder resourceObjectBuilder) : base(resourceObjectBuilder) { } - public new Document Build(IIdentifiable resource, IReadOnlyCollection attributes = null, IReadOnlyCollection relationships = null) + public Document PublicBuild(IIdentifiable resource, IReadOnlyCollection attributes = null, IReadOnlyCollection relationships = null) { - return base.Build(resource, attributes, relationships); + return Build(resource, attributes, relationships); } - public new Document Build(IReadOnlyCollection resources, IReadOnlyCollection attributes = null, IReadOnlyCollection relationships = null) + public Document PublicBuild(IReadOnlyCollection resources, IReadOnlyCollection attributes = null, IReadOnlyCollection relationships = null) { - return base.Build(resources, attributes, relationships); + return Build(resources, attributes, relationships); } } } From 14468b50bb4201a600649bae6d99616bab7c6679 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Tue, 2 Mar 2021 15:24:15 +0100 Subject: [PATCH 59/60] AV1130: Use collection interface as return type --- .../Building/IncludedResourceObjectBuilder.cs | 8 ++++---- .../Serialization/Building/ResourceObjectBuilder.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs index b784f7cf8b..99ee0c2e7d 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/IncludedResourceObjectBuilder.cs @@ -76,7 +76,7 @@ private void UpdateRelationships(ResourceObject resourceObject) resourceObject.Relationships = PruneRelationshipEntries(resourceObject); } - private static Dictionary PruneRelationshipEntries(ResourceObject resourceObject) + private static IDictionary PruneRelationshipEntries(ResourceObject resourceObject) { var pruned = resourceObject.Relationships .Where(pair => pair.Value.IsPopulated || pair.Value.Links != null) @@ -119,7 +119,7 @@ public void IncludeRelationshipChain(IReadOnlyCollection ProcessChain(related, chainRemainder); } - private void ProcessChain(object related, List inclusionChain) + private void ProcessChain(object related, IList inclusionChain) { if (related is IEnumerable children) { @@ -134,7 +134,7 @@ private void ProcessChain(object related, List inclusionC } } - private void ProcessRelationship(IIdentifiable parent, List inclusionChain) + private void ProcessRelationship(IIdentifiable parent, IList inclusionChain) { // get the resource object for parent. var resourceObject = GetOrBuildResourceObject(parent); @@ -166,7 +166,7 @@ private void ProcessRelationship(IIdentifiable parent, List ShiftChain(IReadOnlyCollection chain) + private IList ShiftChain(IReadOnlyCollection chain) { var chainRemainder = chain.ToList(); chainRemainder.RemoveAt(0); diff --git a/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs b/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs index 5f5f40368f..b67e04e410 100644 --- a/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Building/ResourceObjectBuilder.cs @@ -100,7 +100,7 @@ private ResourceIdentifierObject GetRelatedResourceLinkageForHasOne(HasOneAttrib /// /// Builds the s for a HasMany relationship. /// - private List GetRelatedResourceLinkageForHasMany(HasManyAttribute relationship, IIdentifiable resource) + private IList GetRelatedResourceLinkageForHasMany(HasManyAttribute relationship, IIdentifiable resource) { var value = relationship.GetValue(resource); var relatedResources = TypeHelper.ExtractResources(value); From 6a3e91096cf65cb324a2ad62ba6b871805bbb7f7 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 3 Mar 2021 11:00:02 +0100 Subject: [PATCH 60/60] Fixed: Without the [CustomAssertion] attribute, Fluent Assertions would find the line that calls Subject.StatusCode.Should().Be() and treat the Subject variable as the subject-under-test (SUT). But by applying this attribute, it will ignore this invocation and instead find the SUT by looking for a call to Should().HaveStatusCode() and use the response variable instead. --- test/TestBuildingBlocks/HttpResponseMessageExtensions.cs | 1 + test/TestBuildingBlocks/ObjectAssertionsExtensions.cs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs b/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs index d020dab884..69b733d868 100644 --- a/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs +++ b/test/TestBuildingBlocks/HttpResponseMessageExtensions.cs @@ -28,6 +28,7 @@ public HttpResponseMessageAssertions(HttpResponseMessage instance) } // ReSharper disable once UnusedMethodReturnValue.Global + [CustomAssertion] public AndConstraint HaveStatusCode(HttpStatusCode statusCode) { if (Subject.StatusCode != statusCode) diff --git a/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs b/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs index a7f826de75..c217b97f87 100644 --- a/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs +++ b/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs @@ -23,6 +23,7 @@ public static class ObjectAssertionsExtensions /// whose value is returned as in JSON:API response body /// because of . /// + [CustomAssertion] public static void BeCloseTo(this ObjectAssertions source, DateTimeOffset? expected, string because = "", params object[] becauseArgs) { @@ -45,6 +46,7 @@ public static void BeCloseTo(this ObjectAssertions source, DateTimeOffset? expec /// /// Same as , but with default precision. /// + [CustomAssertion] public static AndConstraint> BeApproximately(this NumericAssertions parent, decimal expectedValue, string because = "", params object[] becauseArgs) { @@ -54,6 +56,7 @@ public static AndConstraint> BeApproximately(this Num /// /// Same as , but with default precision. /// + [CustomAssertion] public static AndConstraint> BeApproximately( this NullableNumericAssertions parent, decimal? expectedValue, string because = "", params object[] becauseArgs) @@ -64,6 +67,7 @@ public static AndConstraint> BeApproximately( /// /// Used to assert on a JSON-formatted string, ignoring differences in insignificant whitespace and line endings. /// + [CustomAssertion] public static void BeJson(this StringAssertions source, string expected, string because = "", params object[] becauseArgs) {