From a6180ab896f2afb368b00abbc4328a68f060232b Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 7 Feb 2023 17:59:37 +0100 Subject: [PATCH 01/15] Increment version to 5.1.3 (used for pre-release builds from ci) --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index a9d5421..e2ea325 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,7 @@ 6.0.* 5.1.2 2.15.0 - 5.1.2 + 5.1.3 $(MSBuildThisFileDirectory)CodingGuidelines.ruleset 9999 enable From 4fbff188e3239d77d42653f1a6a145ea2f72f883 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 7 Feb 2023 18:25:59 +0100 Subject: [PATCH 02/15] Package updates --- .config/dotnet-tools.json | 6 +++--- Directory.Build.props | 6 +++--- test/TestBuildingBlocks/FakerContainer.cs | 2 +- test/TestBuildingBlocks/TestBuildingBlocks.csproj | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index d914fc3..da7dc3d 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,13 +3,13 @@ "isRoot": true, "tools": { "jetbrains.resharper.globaltools": { - "version": "2022.2.3", + "version": "2022.2.4", "commands": [ "jb" ] }, "regitlint": { - "version": "6.1.1", + "version": "6.3.10", "commands": [ "regitlint" ] @@ -21,7 +21,7 @@ ] }, "dotnet-reportgenerator-globaltool": { - "version": "5.1.3", + "version": "5.1.15", "commands": [ "reportgenerator" ] diff --git a/Directory.Build.props b/Directory.Build.props index e2ea325..580412e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -31,8 +31,8 @@ - 3.2.0 - 4.16.1 - 17.4.0 + 3.2.* + 4.18.* + 17.4.* diff --git a/test/TestBuildingBlocks/FakerContainer.cs b/test/TestBuildingBlocks/FakerContainer.cs index 99cce6e..72f9a05 100644 --- a/test/TestBuildingBlocks/FakerContainer.cs +++ b/test/TestBuildingBlocks/FakerContainer.cs @@ -12,7 +12,7 @@ static FakerContainer() { // Setting the system DateTime to kind Utc, so that faker calls like PastOffset() don't depend on the system time zone. // See https://docs.microsoft.com/en-us/dotnet/api/system.datetimeoffset.op_implicit?view=net-6.0#remarks - Date.SystemClock = () => 1.January(2020).AsUtc(); + Date.SystemClock = () => 1.January(2020).At(1, 1, 1).AsUtc(); } protected static int GetFakerSeed() diff --git a/test/TestBuildingBlocks/TestBuildingBlocks.csproj b/test/TestBuildingBlocks/TestBuildingBlocks.csproj index db9e8da..a9701e2 100644 --- a/test/TestBuildingBlocks/TestBuildingBlocks.csproj +++ b/test/TestBuildingBlocks/TestBuildingBlocks.csproj @@ -10,7 +10,7 @@ - + From c959baa128c58767aa06598d675d7068c0c1f59c Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Wed, 29 Mar 2023 02:09:50 +0200 Subject: [PATCH 03/15] Refresh NuGet API key --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2593740..91678d5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -32,14 +32,14 @@ for: - provider: NuGet skip_symbols: false api_key: - secure: S9fkLwmhi7w+DGouXYqYq/1PGocnYo8UBUKwv+BGpWHnzE6yHZEYth3j/XJ9Ydsa + secure: oy2i3qo34xygjtxsjq5q5mcxpispceluvorutzd7kkxejm on: branch: master appveyor_repo_tag: true - provider: NuGet skip_symbols: false api_key: - secure: S9fkLwmhi7w+DGouXYqYq/1PGocnYo8UBUKwv+BGpWHnzE6yHZEYth3j/XJ9Ydsa + secure: oy2i3qo34xygjtxsjq5q5mcxpispceluvorutzd7kkxejm on: branch: /release\/.+/ appveyor_repo_tag: true From 3ba88b29a39ad7540a7d1f38aa1fd46f71597b7c Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Wed, 29 Mar 2023 21:02:14 +0200 Subject: [PATCH 04/15] Refresh leaked NuGet API key --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 91678d5..18aa690 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -32,14 +32,14 @@ for: - provider: NuGet skip_symbols: false api_key: - secure: oy2i3qo34xygjtxsjq5q5mcxpispceluvorutzd7kkxejm + secure: hlP/zkfkHzmutSXPYAiINmPdv+QEj3TpAjKewHEkCtQnHnA2tSo+Xey0g6FVM6S5 on: branch: master appveyor_repo_tag: true - provider: NuGet skip_symbols: false api_key: - secure: oy2i3qo34xygjtxsjq5q5mcxpispceluvorutzd7kkxejm + secure: hlP/zkfkHzmutSXPYAiINmPdv+QEj3TpAjKewHEkCtQnHnA2tSo+Xey0g6FVM6S5 on: branch: /release\/.+/ appveyor_repo_tag: true From 76e27d2ab775b8ddad61ec24ad48efdd9a45fcaf Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Thu, 18 May 2023 16:47:21 +0200 Subject: [PATCH 05/15] Package updates --- .config/dotnet-tools.json | 6 +++--- Directory.Build.props | 6 +++--- test/TestBuildingBlocks/TestBuildingBlocks.csproj | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index da7dc3d..9278758 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,13 +3,13 @@ "isRoot": true, "tools": { "jetbrains.resharper.globaltools": { - "version": "2022.2.4", + "version": "2023.1.2", "commands": [ "jb" ] }, "regitlint": { - "version": "6.3.10", + "version": "6.3.11", "commands": [ "regitlint" ] @@ -21,7 +21,7 @@ ] }, "dotnet-reportgenerator-globaltool": { - "version": "5.1.15", + "version": "5.1.20", "commands": [ "reportgenerator" ] diff --git a/Directory.Build.props b/Directory.Build.props index 580412e..21b3f73 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,7 +2,7 @@ net6.0 6.0.* - 5.1.2 + 5.2.0 2.15.0 5.1.3 $(MSBuildThisFileDirectory)CodingGuidelines.ruleset @@ -15,7 +15,7 @@ - + @@ -33,6 +33,6 @@ 3.2.* 4.18.* - 17.4.* + 17.6.* diff --git a/test/TestBuildingBlocks/TestBuildingBlocks.csproj b/test/TestBuildingBlocks/TestBuildingBlocks.csproj index a9701e2..9dccdb2 100644 --- a/test/TestBuildingBlocks/TestBuildingBlocks.csproj +++ b/test/TestBuildingBlocks/TestBuildingBlocks.csproj @@ -10,7 +10,7 @@ - + From 6616ee5860f4841628555d5b1518e6e9b7689954 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Thu, 18 May 2023 17:52:19 +0200 Subject: [PATCH 06/15] Update to JADNC v5.2.0 --- .editorconfig | 9 ++++++--- Build.ps1 | 9 +++------ Directory.Build.props | 1 - JetBrainsInspectCodeTransform.xslt | 4 ++++ JsonApiDotNetCore.MongoDb.sln.DotSettings | 16 +++++++++++----- WarningSeverities.DotSettings | 14 ++++++++++++++ .../Properties/launchSettings.json | 4 ++-- src/Examples/GettingStarted/appsettings.json | 2 ++ .../Definitions/TodoItemDefinition.cs | 2 +- .../Models/TodoItem.cs | 3 +++ .../Models/TodoItemPriority.cs | 6 +++--- .../JsonApiDotNetCoreMongoDbExample/Program.cs | 7 +++++-- .../Properties/AssemblyInfo.cs | 4 ---- .../Properties/launchSettings.json | 8 ++++---- .../appsettings.json | 2 ++ .../MongoQueryExpressionValidator.cs | 2 +- .../IntegrationTests/Meta/TopLevelCountTests.cs | 13 ++----------- .../Filtering/FilterDataTypeTests.cs | 7 ++++--- .../Pagination/PaginationWithTotalCountTests.cs | 2 +- .../SparseFieldSets/SparseFieldSetTests.cs | 2 +- .../Reading/ResourceDefinitionReadTests.cs | 13 ++----------- .../ObjectAssertionsExtensions.cs | 11 +++++++++++ test/TestBuildingBlocks/appsettings.json | 5 ++++- 23 files changed, 86 insertions(+), 60 deletions(-) delete mode 100644 src/Examples/JsonApiDotNetCoreMongoDbExample/Properties/AssemblyInfo.cs diff --git a/.editorconfig b/.editorconfig index ca191cf..86cbbc3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -66,15 +66,18 @@ csharp_indent_case_contents_when_block = false csharp_preserve_single_line_statements = false # 'var' usage preferences -csharp_style_var_for_built_in_types = false:suggestion -csharp_style_var_when_type_is_apparent = true:suggestion -csharp_style_var_elsewhere = false:suggestion +csharp_style_var_for_built_in_types = false:none +csharp_style_var_when_type_is_apparent = true:none +csharp_style_var_elsewhere = false:none # Parentheses preferences dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:suggestion dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggestion dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:suggestion +# Expression value is never used +dotnet_diagnostic.IDE0058.severity = none + #### Naming Style #### dotnet_diagnostic.IDE1006.severity = warning diff --git a/Build.ps1 b/Build.ps1 index ce11718..623cfa7 100644 --- a/Build.ps1 +++ b/Build.ps1 @@ -23,7 +23,7 @@ function RunInspectCode { $issueType = $xml.report.IssueTypes.SelectSingleNode("IssueType[@Id='$($_.TypeId)']") $severity = $_.Severity ?? $issueType.Severity - Write-Output "[$severity] $($_.File):$($_.Line) $($_.Message)" + Write-Output "[$severity] $($_.File):$($_.Line) $($_.TypeId): $($_.Message)" }) }) } @@ -104,11 +104,8 @@ CheckLastExitCode dotnet build -c Release CheckLastExitCode -# https://youtrack.jetbrains.com/issue/RSRP-488628/Breaking-InspectCode-fails-with-Roslyn-Worker-process-exited-unexpectedly-after-update -if ($IsWindows) { - RunInspectCode - RunCleanupCode -} +RunInspectCode +RunCleanupCode dotnet test -c Release --no-build --collect:"XPlat Code Coverage" CheckLastExitCode diff --git a/Directory.Build.props b/Directory.Build.props index 21b3f73..be5871c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -32,7 +32,6 @@ 3.2.* - 4.18.* 17.6.* diff --git a/JetBrainsInspectCodeTransform.xslt b/JetBrainsInspectCodeTransform.xslt index 098821f..28fa772 100644 --- a/JetBrainsInspectCodeTransform.xslt +++ b/JetBrainsInspectCodeTransform.xslt @@ -25,6 +25,7 @@ File Line Number + Type Message @@ -35,6 +36,9 @@ + + + diff --git a/JsonApiDotNetCore.MongoDb.sln.DotSettings b/JsonApiDotNetCore.MongoDb.sln.DotSettings index 8e80299..8e89021 100644 --- a/JsonApiDotNetCore.MongoDb.sln.DotSettings +++ b/JsonApiDotNetCore.MongoDb.sln.DotSettings @@ -28,6 +28,7 @@ JsonApiDotNetCore.MongoDb.ArgumentGuard.NotNull($EXPR$); SUGGESTION SUGGESTION WARNING + WARNING SUGGESTION SUGGESTION SUGGESTION @@ -54,16 +55,16 @@ JsonApiDotNetCore.MongoDb.ArgumentGuard.NotNull($EXPR$); WARNING WARNING WARNING + SUGGESTION HINT WARNING DO_NOT_SHOW HINT SUGGESTION - WARNING - WARNING + SUGGESTION + SUGGESTION WARNING WARNING - SUGGESTION WARNING SUGGESTION SUGGESTION @@ -76,6 +77,7 @@ JsonApiDotNetCore.MongoDb.ArgumentGuard.NotNull($EXPR$); SUGGESTION SUGGESTION SUGGESTION + WARNING WARNING WARNING WARNING @@ -88,8 +90,10 @@ JsonApiDotNetCore.MongoDb.ArgumentGuard.NotNull($EXPR$); WARNING WARNING WARNING + SUGGESTION + SUGGESTION WARNING - <?xml version="1.0" encoding="utf-16"?><Profile name="JADNC Full Cleanup"><XMLReformatCode>True</XMLReformatCode><CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeArgumentsStyle="True" ArrangeCodeBodyStyle="True" ArrangeVarStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" /><CssAlphabetizeProperties>True</CssAlphabetizeProperties><JsInsertSemicolon>True</JsInsertSemicolon><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><CorrectVariableKindsDescriptor>True</CorrectVariableKindsDescriptor><VariablesToInnerScopesDescriptor>True</VariablesToInnerScopesDescriptor><StringToTemplatesDescriptor>True</StringToTemplatesDescriptor><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><RemoveRedundantQualifiersTs>True</RemoveRedundantQualifiersTs><OptimizeImportsTs>True</OptimizeImportsTs><OptimizeReferenceCommentsTs>True</OptimizeReferenceCommentsTs><PublicModifierStyleTs>True</PublicModifierStyleTs><ExplicitAnyTs>True</ExplicitAnyTs><TypeAnnotationStyleTs>True</TypeAnnotationStyleTs><RelativePathStyleTs>True</RelativePathStyleTs><AsInsteadOfCastTs>True</AsInsteadOfCastTs><HtmlReformatCode>True</HtmlReformatCode><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CssReformatCode>True</CssReformatCode><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><CSReorderTypeMembers>True</CSReorderTypeMembers><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags></Profile> + <?xml version="1.0" encoding="utf-16"?><Profile name="JADNC Full Cleanup"><XMLReformatCode>True</XMLReformatCode><CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeArgumentsStyle="True" ArrangeCodeBodyStyle="True" ArrangeVarStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" ArrangeNullCheckingPattern="True" /><CssAlphabetizeProperties>True</CssAlphabetizeProperties><JsInsertSemicolon>True</JsInsertSemicolon><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><CorrectVariableKindsDescriptor>True</CorrectVariableKindsDescriptor><VariablesToInnerScopesDescriptor>True</VariablesToInnerScopesDescriptor><StringToTemplatesDescriptor>True</StringToTemplatesDescriptor><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><RemoveRedundantQualifiersTs>True</RemoveRedundantQualifiersTs><OptimizeImportsTs>True</OptimizeImportsTs><OptimizeReferenceCommentsTs>True</OptimizeReferenceCommentsTs><PublicModifierStyleTs>True</PublicModifierStyleTs><ExplicitAnyTs>True</ExplicitAnyTs><TypeAnnotationStyleTs>True</TypeAnnotationStyleTs><RelativePathStyleTs>True</RelativePathStyleTs><AsInsteadOfCastTs>True</AsInsteadOfCastTs><HtmlReformatCode>True</HtmlReformatCode><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CssReformatCode>True</CssReformatCode><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><CSReorderTypeMembers>True</CSReorderTypeMembers><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags><CSReformatInactiveBranches>True</CSReformatInactiveBranches></Profile> JADNC Full Cleanup Required Required @@ -116,6 +120,7 @@ JsonApiDotNetCore.MongoDb.ArgumentGuard.NotNull($EXPR$); False False False + False False False False @@ -134,6 +139,7 @@ JsonApiDotNetCore.MongoDb.ArgumentGuard.NotNull($EXPR$); False False CHOP_ALWAYS + False True True True @@ -641,7 +647,7 @@ $left$ = $right$; True CSHARP False - JsonApiDotNetCore.ArgumentGuard.NotNull($argument$); + JsonApiDotNetCore.MongoDb.ArgumentGuard.NotNull($argument$); if ($argument$ is null) throw new ArgumentNullException(nameof($argument$)); WARNING True diff --git a/WarningSeverities.DotSettings b/WarningSeverities.DotSettings index 0d4eeba..96f358d 100644 --- a/WarningSeverities.DotSettings +++ b/WarningSeverities.DotSettings @@ -13,6 +13,7 @@ WARNING WARNING WARNING + WARNING WARNING WARNING WARNING @@ -70,6 +71,7 @@ WARNING WARNING WARNING + WARNING WARNING WARNING WARNING @@ -82,6 +84,7 @@ WARNING WARNING WARNING + WARNING WARNING WARNING WARNING @@ -97,8 +100,13 @@ WARNING WARNING WARNING + WARNING WARNING WARNING + WARNING + WARNING + WARNING + WARNING WARNING WARNING WARNING @@ -109,12 +117,14 @@ WARNING WARNING WARNING + WARNING WARNING WARNING WARNING WARNING WARNING WARNING + WARNING WARNING WARNING WARNING @@ -135,6 +145,7 @@ WARNING WARNING WARNING + WARNING WARNING WARNING WARNING @@ -152,6 +163,8 @@ WARNING WARNING WARNING + WARNING + WARNING WARNING WARNING WARNING @@ -240,6 +253,7 @@ WARNING WARNING WARNING + WARNING WARNING WARNING WARNING diff --git a/src/Examples/GettingStarted/Properties/launchSettings.json b/src/Examples/GettingStarted/Properties/launchSettings.json index ad97b55..b82968b 100644 --- a/src/Examples/GettingStarted/Properties/launchSettings.json +++ b/src/Examples/GettingStarted/Properties/launchSettings.json @@ -10,7 +10,7 @@ "profiles": { "IIS Express": { "commandName": "IISExpress", - "launchBrowser": false, + "launchBrowser": true, "launchUrl": "api/books", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" @@ -18,7 +18,7 @@ }, "Kestrel": { "commandName": "Project", - "launchBrowser": false, + "launchBrowser": true, "launchUrl": "api/books", "applicationUrl": "http://localhost:24141", "environmentVariables": { diff --git a/src/Examples/GettingStarted/appsettings.json b/src/Examples/GettingStarted/appsettings.json index 31455b7..4db298e 100644 --- a/src/Examples/GettingStarted/appsettings.json +++ b/src/Examples/GettingStarted/appsettings.json @@ -6,7 +6,9 @@ "Logging": { "LogLevel": { "Default": "Warning", + // Include server startup and incoming requests. "Microsoft.Hosting.Lifetime": "Information", + "Microsoft.AspNetCore.Hosting.Diagnostics": "Information", "Microsoft.EntityFrameworkCore": "Critical" } }, diff --git a/src/Examples/JsonApiDotNetCoreMongoDbExample/Definitions/TodoItemDefinition.cs b/src/Examples/JsonApiDotNetCoreMongoDbExample/Definitions/TodoItemDefinition.cs index 8079def..61027b4 100644 --- a/src/Examples/JsonApiDotNetCoreMongoDbExample/Definitions/TodoItemDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreMongoDbExample/Definitions/TodoItemDefinition.cs @@ -29,7 +29,7 @@ private SortExpression GetDefaultSortOrder() { return CreateSortExpressionFromLambda(new PropertySortOrder { - (todoItem => todoItem.Priority, ListSortDirection.Descending), + (todoItem => todoItem.Priority, ListSortDirection.Ascending), (todoItem => todoItem.LastModifiedAt, ListSortDirection.Descending) }); } diff --git a/src/Examples/JsonApiDotNetCoreMongoDbExample/Models/TodoItem.cs b/src/Examples/JsonApiDotNetCoreMongoDbExample/Models/TodoItem.cs index 7dc654c..9b0e8d6 100644 --- a/src/Examples/JsonApiDotNetCoreMongoDbExample/Models/TodoItem.cs +++ b/src/Examples/JsonApiDotNetCoreMongoDbExample/Models/TodoItem.cs @@ -16,6 +16,9 @@ public sealed class TodoItem : HexStringMongoIdentifiable [Required] public TodoItemPriority? Priority { get; set; } + [Attr] + public long? DurationInHours { get; set; } + [Attr(Capabilities = AttrCapabilities.AllowFilter | AttrCapabilities.AllowSort | AttrCapabilities.AllowView)] public DateTimeOffset CreatedAt { get; set; } diff --git a/src/Examples/JsonApiDotNetCoreMongoDbExample/Models/TodoItemPriority.cs b/src/Examples/JsonApiDotNetCoreMongoDbExample/Models/TodoItemPriority.cs index a782897..3bb17ed 100644 --- a/src/Examples/JsonApiDotNetCoreMongoDbExample/Models/TodoItemPriority.cs +++ b/src/Examples/JsonApiDotNetCoreMongoDbExample/Models/TodoItemPriority.cs @@ -5,7 +5,7 @@ namespace JsonApiDotNetCoreMongoDbExample.Models; [UsedImplicitly(ImplicitUseTargetFlags.Members)] public enum TodoItemPriority { - Low, - Medium, - High + High = 1, + Medium = 2, + Low = 3 } diff --git a/src/Examples/JsonApiDotNetCoreMongoDbExample/Program.cs b/src/Examples/JsonApiDotNetCoreMongoDbExample/Program.cs index 5f4b0dc..9820cb1 100644 --- a/src/Examples/JsonApiDotNetCoreMongoDbExample/Program.cs +++ b/src/Examples/JsonApiDotNetCoreMongoDbExample/Program.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.MongoDb.Configuration; @@ -6,6 +7,8 @@ using Microsoft.AspNetCore.Authentication; using MongoDB.Driver; +[assembly: ExcludeFromCodeCoverage] + WebApplicationBuilder builder = WebApplication.CreateBuilder(args); // Add services to the container. @@ -37,13 +40,13 @@ static void ConfigureJsonApiOptions(JsonApiOptions options) { - options.Namespace = "api/v1"; + options.Namespace = "api"; options.UseRelativeLinks = true; options.IncludeTotalResourceCount = true; - options.SerializerOptions.WriteIndented = true; options.SerializerOptions.Converters.Add(new JsonStringEnumConverter()); #if DEBUG options.IncludeExceptionStackTraceInErrors = true; options.IncludeRequestBodyInErrors = true; + options.SerializerOptions.WriteIndented = true; #endif } diff --git a/src/Examples/JsonApiDotNetCoreMongoDbExample/Properties/AssemblyInfo.cs b/src/Examples/JsonApiDotNetCoreMongoDbExample/Properties/AssemblyInfo.cs deleted file mode 100644 index 82d1291..0000000 --- a/src/Examples/JsonApiDotNetCoreMongoDbExample/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -// https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/MSBuildIntegration.md#excluding-from-coverage -[assembly: ExcludeFromCodeCoverage] diff --git a/src/Examples/JsonApiDotNetCoreMongoDbExample/Properties/launchSettings.json b/src/Examples/JsonApiDotNetCoreMongoDbExample/Properties/launchSettings.json index f155249..c14bdd1 100644 --- a/src/Examples/JsonApiDotNetCoreMongoDbExample/Properties/launchSettings.json +++ b/src/Examples/JsonApiDotNetCoreMongoDbExample/Properties/launchSettings.json @@ -11,16 +11,16 @@ "profiles": { "IIS Express": { "commandName": "IISExpress", - "launchBrowser": false, - "launchUrl": "api/v1/todoItems", + "launchBrowser": true, + "launchUrl": "api/todoItems", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "Kestrel": { "commandName": "Project", - "launchBrowser": false, - "launchUrl": "api/v1/todoItems", + "launchBrowser": true, + "launchUrl": "api/todoItems", "applicationUrl": "https://localhost:44340;http://localhost:24140", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" diff --git a/src/Examples/JsonApiDotNetCoreMongoDbExample/appsettings.json b/src/Examples/JsonApiDotNetCoreMongoDbExample/appsettings.json index dde4b49..b8ed43e 100644 --- a/src/Examples/JsonApiDotNetCoreMongoDbExample/appsettings.json +++ b/src/Examples/JsonApiDotNetCoreMongoDbExample/appsettings.json @@ -6,7 +6,9 @@ "Logging": { "LogLevel": { "Default": "Warning", + // Include server startup and incoming requests. "Microsoft.Hosting.Lifetime": "Information", + "Microsoft.AspNetCore.Hosting.Diagnostics": "Information", "Microsoft.EntityFrameworkCore": "Critical" } }, diff --git a/src/JsonApiDotNetCore.MongoDb/Repositories/MongoQueryExpressionValidator.cs b/src/JsonApiDotNetCore.MongoDb/Repositories/MongoQueryExpressionValidator.cs index 58081c6..5e17cff 100644 --- a/src/JsonApiDotNetCore.MongoDb/Repositories/MongoQueryExpressionValidator.cs +++ b/src/JsonApiDotNetCore.MongoDb/Repositories/MongoQueryExpressionValidator.cs @@ -62,7 +62,7 @@ private void ValidateExpression(QueryExpression? expression) public override QueryExpression? VisitComparison(ComparisonExpression expression, object? argument) { - if (expression.Left is ResourceFieldChainExpression && expression.Right is ResourceFieldChainExpression) + if (expression is { Left: ResourceFieldChainExpression, Right: ResourceFieldChainExpression }) { throw new AttributeComparisonInFilterNotSupportedException(); } diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/Meta/TopLevelCountTests.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/Meta/TopLevelCountTests.cs index 6b1c1c7..c486d0d 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/Meta/TopLevelCountTests.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/Meta/TopLevelCountTests.cs @@ -1,5 +1,4 @@ using System.Net; -using System.Text.Json; using FluentAssertions; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Resources; @@ -54,11 +53,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Meta.ShouldNotBeNull(); - responseDocument.Meta.ShouldContainKey("total").With(value => - { - JsonElement element = value.Should().BeOfType().Subject; - element.GetInt32().Should().Be(1); - }); + responseDocument.Meta.Should().ContainTotal(1); } [Fact] @@ -80,11 +75,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Meta.ShouldNotBeNull(); - responseDocument.Meta.ShouldContainKey("total").With(value => - { - JsonElement element = value.Should().BeOfType().Subject; - element.GetInt32().Should().Be(0); - }); + responseDocument.Meta.Should().ContainTotal(0); } [Fact] diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs index 3e97ce3..c8e6a05 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs @@ -237,7 +237,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } [Fact] - public async Task Cannot_filter_equality_on_incompatible_value() + public async Task Cannot_filter_equality_on_incompatible_values() { // Arrange var resource = new FilterableResource @@ -264,9 +264,10 @@ await _testContext.RunOnDatabaseAsync(async dbContext => ErrorObject error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.BadRequest); - error.Title.Should().Be("Query creation failed due to incompatible types."); + error.Title.Should().Be("The specified filter is invalid."); error.Detail.Should().Be("Failed to convert 'ABC' of type 'String' to type 'Int32'."); - error.Source.Should().BeNull(); + error.Source.ShouldNotBeNull(); + error.Source.Parameter.Should().Be("filter"); } [Theory] diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs index cb54c88..d638555 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Pagination/PaginationWithTotalCountTests.cs @@ -94,7 +94,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } [Fact] - public async Task Returns_all_resources_when_paging_is_disabled() + public async Task Returns_all_resources_when_pagination_is_disabled() { // Arrange var options = (JsonApiOptions)_testContext.Factory.Services.GetRequiredService(); diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs index b5b2344..dca4609 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/SparseFieldSets/SparseFieldSetTests.cs @@ -300,7 +300,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } [Fact] - public async Task Retrieves_all_properties_when_fieldset_contains_readonly_attribute() + public async Task Fetches_all_scalar_properties_when_fieldset_contains_readonly_attribute() { // Arrange var store = _testContext.Factory.Services.GetRequiredService(); diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/ResourceDefinitions/Reading/ResourceDefinitionReadTests.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/ResourceDefinitions/Reading/ResourceDefinitionReadTests.cs index 521da09..d9b54c4 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/ResourceDefinitions/Reading/ResourceDefinitionReadTests.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/ResourceDefinitions/Reading/ResourceDefinitionReadTests.cs @@ -1,5 +1,4 @@ using System.Net; -using System.Text.Json; using FluentAssertions; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Serialization.Objects; @@ -70,11 +69,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Data.ManyValue[0].Id.Should().Be(planets[1].StringId); responseDocument.Data.ManyValue[1].Id.Should().Be(planets[3].StringId); - responseDocument.Meta.ShouldContainKey("total").With(value => - { - JsonElement element = value.Should().BeOfType().Subject; - element.GetInt32().Should().Be(2); - }); + responseDocument.Meta.Should().ContainTotal(2); hitCounter.HitExtensibilityPoints.Should().BeEquivalentTo(new[] { @@ -129,11 +124,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Data.ManyValue.ShouldHaveCount(1); responseDocument.Data.ManyValue[0].Id.Should().Be(planets[3].StringId); - responseDocument.Meta.ShouldContainKey("total").With(value => - { - JsonElement element = value.Should().BeOfType().Subject; - element.GetInt32().Should().Be(1); - }); + responseDocument.Meta.Should().ContainTotal(1); hitCounter.HitExtensibilityPoints.Should().BeEquivalentTo(new[] { diff --git a/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs b/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs index c78a005..1e833be 100644 --- a/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs +++ b/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs @@ -1,4 +1,6 @@ +using System.Text.Json; using FluentAssertions; +using FluentAssertions.Collections; using FluentAssertions.Numeric; using JetBrains.Annotations; @@ -19,4 +21,13 @@ public static AndConstraint> BeApproximately( { return parent.BeApproximately(expectedValue, NumericPrecision, because, becauseArgs); } + + /// + /// Asserts that a "meta" dictionary contains a single element named "total" with the specified value. + /// + [CustomAssertion] + public static void ContainTotal(this GenericDictionaryAssertions, string, object?> source, int expectedTotal) + { + source.ContainKey("total").WhoseValue.Should().BeOfType().Subject.GetInt32().Should().Be(expectedTotal); + } } diff --git a/test/TestBuildingBlocks/appsettings.json b/test/TestBuildingBlocks/appsettings.json index edbd7e4..5c69fe7 100644 --- a/test/TestBuildingBlocks/appsettings.json +++ b/test/TestBuildingBlocks/appsettings.json @@ -2,8 +2,11 @@ "Logging": { "LogLevel": { "Default": "Warning", + // Disable logging to keep the output from C/I build clean. Errors are expected to occur while testing failure handling. + "Microsoft.AspNetCore.Hosting.Diagnostics": "None", "Microsoft.Hosting.Lifetime": "Warning", - "Microsoft.EntityFrameworkCore": "Critical" + "Microsoft.EntityFrameworkCore": "Critical", + "JsonApiDotNetCore": "Critical" } } } From 621883c2117a5f29c288574b5c1e4e2a19312d36 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Thu, 18 May 2023 18:55:56 +0200 Subject: [PATCH 07/15] Add test throttling (reduces the duration of running all tests from 2:37 to 0:30 on my system) --- .../AtomicOperationsFixture.cs | 12 +++++-- .../JsonApiDotNetCoreMongoDbTests.csproj | 6 ---- .../xunit.runner.json | 4 --- test/TestBuildingBlocks/IntegrationTest.cs | 25 +++++++++++-- .../IntegrationTestContext.cs | 35 +++++++++++-------- 5 files changed, 53 insertions(+), 29 deletions(-) delete mode 100644 test/JsonApiDotNetCoreMongoDbTests/xunit.runner.json diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/AtomicOperations/AtomicOperationsFixture.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/AtomicOperations/AtomicOperationsFixture.cs index e10e17d..c9029bb 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/AtomicOperations/AtomicOperationsFixture.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/AtomicOperations/AtomicOperationsFixture.cs @@ -1,11 +1,12 @@ using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using TestBuildingBlocks; +using Xunit; namespace JsonApiDotNetCoreMongoDbTests.IntegrationTests.AtomicOperations; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class AtomicOperationsFixture : IDisposable +public sealed class AtomicOperationsFixture : IAsyncLifetime { internal IntegrationTestContext TestContext { get; } @@ -21,8 +22,13 @@ public AtomicOperationsFixture() TestContext.ConfigureServicesAfterStartup(services => services.AddSingleton()); } - public void Dispose() + public Task InitializeAsync() { - TestContext.Dispose(); + return Task.CompletedTask; + } + + public async Task DisposeAsync() + { + await TestContext.DisposeAsync(); } } diff --git a/test/JsonApiDotNetCoreMongoDbTests/JsonApiDotNetCoreMongoDbTests.csproj b/test/JsonApiDotNetCoreMongoDbTests/JsonApiDotNetCoreMongoDbTests.csproj index c202a91..dbfe9fa 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/JsonApiDotNetCoreMongoDbTests.csproj +++ b/test/JsonApiDotNetCoreMongoDbTests/JsonApiDotNetCoreMongoDbTests.csproj @@ -3,12 +3,6 @@ $(TargetFrameworkName) - - - PreserveNewest - - - diff --git a/test/JsonApiDotNetCoreMongoDbTests/xunit.runner.json b/test/JsonApiDotNetCoreMongoDbTests/xunit.runner.json deleted file mode 100644 index 9db029b..0000000 --- a/test/JsonApiDotNetCoreMongoDbTests/xunit.runner.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "parallelizeAssembly": false, - "parallelizeTestCollections": false -} diff --git a/test/TestBuildingBlocks/IntegrationTest.cs b/test/TestBuildingBlocks/IntegrationTest.cs index c66e6c5..a42877a 100644 --- a/test/TestBuildingBlocks/IntegrationTest.cs +++ b/test/TestBuildingBlocks/IntegrationTest.cs @@ -2,16 +2,26 @@ using System.Text; using System.Text.Json; using JsonApiDotNetCore.Middleware; +using Xunit; namespace TestBuildingBlocks; /// -/// A base class for tests that conveniently enables to execute HTTP requests against JSON:API endpoints. +/// A base class for tests that conveniently enables to execute HTTP requests against JSON:API endpoints. It throttles tests that are running in parallel +/// to avoid exceeding the maximum active database connections. /// -public abstract class IntegrationTest +public abstract class IntegrationTest : IAsyncLifetime { + private static readonly SemaphoreSlim ThrottleSemaphore; + protected abstract JsonSerializerOptions SerializerOptions { get; } + static IntegrationTest() + { + int maxConcurrentTestRuns = Environment.GetEnvironmentVariable("APPVEYOR") != null ? 32 : 64; + ThrottleSemaphore = new SemaphoreSlim(maxConcurrentTestRuns); + } + public async Task<(HttpResponseMessage httpResponse, TResponseDocument responseDocument)> ExecuteGetAsync(string requestUrl, Action? setRequestHeaders = null) { @@ -99,4 +109,15 @@ public abstract class IntegrationTest throw new FormatException($"Failed to deserialize response body to JSON:\n{responseText}", exception); } } + + public async Task InitializeAsync() + { + await ThrottleSemaphore.WaitAsync(); + } + + public virtual Task DisposeAsync() + { + _ = ThrottleSemaphore.Release(); + return Task.CompletedTask; + } } diff --git a/test/TestBuildingBlocks/IntegrationTestContext.cs b/test/TestBuildingBlocks/IntegrationTestContext.cs index 2e3cc72..826447d 100644 --- a/test/TestBuildingBlocks/IntegrationTestContext.cs +++ b/test/TestBuildingBlocks/IntegrationTestContext.cs @@ -28,7 +28,7 @@ namespace TestBuildingBlocks; /// . /// [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public class IntegrationTestContext : IntegrationTest, IDisposable +public class IntegrationTestContext : IntegrationTest where TStartup : class where TMongoDbContextShim : MongoDbContextShim { @@ -125,19 +125,6 @@ private void ConfigureJsonApiOptions(JsonApiOptions options) options.SerializerOptions.WriteIndented = true; } - public void Dispose() - { - if (_lazyFactory.IsValueCreated) - { - _lazyFactory.Value.Dispose(); - } - - if (_runner.IsValueCreated) - { - _runner.Value.Dispose(); - } - } - public void ConfigureServicesAfterStartup(Action servicesConfiguration) { _afterServicesConfiguration = servicesConfiguration; @@ -151,6 +138,26 @@ public async Task RunOnDatabaseAsync(Func asyncAction await asyncAction(mongoDbContextShim); } + public override async Task DisposeAsync() + { + try + { + if (_lazyFactory.IsValueCreated) + { + await _lazyFactory.Value.DisposeAsync(); + } + + if (_runner.IsValueCreated) + { + _runner.Value.Dispose(); + } + } + finally + { + await base.DisposeAsync(); + } + } + private sealed class IntegrationTestWebApplicationFactory : WebApplicationFactory { private Action? _beforeServicesConfiguration; From ab732781d7a4e29dec0f1168ddfc9cfb73cce260 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 25 Jul 2023 21:30:15 +0200 Subject: [PATCH 08/15] Package updates --- Directory.Build.props | 4 ++-- test/TestBuildingBlocks/TestBuildingBlocks.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index be5871c..d8ee665 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -14,7 +14,7 @@ - + @@ -31,7 +31,7 @@ - 3.2.* + 6.0.* 17.6.* diff --git a/test/TestBuildingBlocks/TestBuildingBlocks.csproj b/test/TestBuildingBlocks/TestBuildingBlocks.csproj index 9dccdb2..629c236 100644 --- a/test/TestBuildingBlocks/TestBuildingBlocks.csproj +++ b/test/TestBuildingBlocks/TestBuildingBlocks.csproj @@ -14,7 +14,7 @@ - - + + From e764e086c24da3107abc3bcc7ff7631793855df8 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 25 Jul 2023 21:28:34 +0200 Subject: [PATCH 09/15] Update to build against JsonApiDotNetCore v5.3.0 --- Directory.Build.props | 2 +- .../Configuration/ServiceCollectionExtensions.cs | 2 +- .../HideRelationshipsSparseFieldSetCache.cs | 1 - .../Repositories/MongoRepository.cs | 14 +++++++------- .../Transactions/LyricRepository.cs | 6 ++++-- .../Transactions/MusicTrackRepository.cs | 6 ++++-- .../QueryStrings/Filtering/FilterDataTypeTests.cs | 2 +- .../SparseFieldSets/ResultCapturingRepository.cs | 5 +++-- 8 files changed, 21 insertions(+), 17 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index d8ee665..e53af2e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,7 +2,7 @@ net6.0 6.0.* - 5.2.0 + 5.3.0 2.15.0 5.1.3 $(MSBuildThisFileDirectory)CodingGuidelines.ruleset diff --git a/src/JsonApiDotNetCore.MongoDb/Configuration/ServiceCollectionExtensions.cs b/src/JsonApiDotNetCore.MongoDb/Configuration/ServiceCollectionExtensions.cs index f914f91..836cf87 100644 --- a/src/JsonApiDotNetCore.MongoDb/Configuration/ServiceCollectionExtensions.cs +++ b/src/JsonApiDotNetCore.MongoDb/Configuration/ServiceCollectionExtensions.cs @@ -3,7 +3,7 @@ using JsonApiDotNetCore.MongoDb.AtomicOperations; using JsonApiDotNetCore.MongoDb.Queries.Internal; using JsonApiDotNetCore.MongoDb.Repositories; -using JsonApiDotNetCore.Queries.Internal; +using JsonApiDotNetCore.Queries; using Microsoft.Extensions.DependencyInjection; namespace JsonApiDotNetCore.MongoDb.Configuration; diff --git a/src/JsonApiDotNetCore.MongoDb/Queries/Internal/HideRelationshipsSparseFieldSetCache.cs b/src/JsonApiDotNetCore.MongoDb/Queries/Internal/HideRelationshipsSparseFieldSetCache.cs index fcd9d8a..505bf89 100644 --- a/src/JsonApiDotNetCore.MongoDb/Queries/Internal/HideRelationshipsSparseFieldSetCache.cs +++ b/src/JsonApiDotNetCore.MongoDb/Queries/Internal/HideRelationshipsSparseFieldSetCache.cs @@ -2,7 +2,6 @@ using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.MongoDb.Resources; using JsonApiDotNetCore.Queries; -using JsonApiDotNetCore.Queries.Internal; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; diff --git a/src/JsonApiDotNetCore.MongoDb/Repositories/MongoRepository.cs b/src/JsonApiDotNetCore.MongoDb/Repositories/MongoRepository.cs index 6bd64e3..ea673c0 100644 --- a/src/JsonApiDotNetCore.MongoDb/Repositories/MongoRepository.cs +++ b/src/JsonApiDotNetCore.MongoDb/Repositories/MongoRepository.cs @@ -7,7 +7,7 @@ using JsonApiDotNetCore.MongoDb.Resources; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Queries.Expressions; -using JsonApiDotNetCore.Queries.Internal.QueryableBuilding; +using JsonApiDotNetCore.Queries.QueryableBuilding; using JsonApiDotNetCore.Repositories; using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Resources.Annotations; @@ -29,6 +29,7 @@ public class MongoRepository : IResourceRepository _constraintProviders; private readonly IResourceDefinitionAccessor _resourceDefinitionAccessor; + private readonly IQueryableBuilder _queryableBuilder; protected virtual IMongoCollection Collection => _mongoDataAccess.MongoDatabase.GetCollection(typeof(TResource).Name); @@ -36,7 +37,7 @@ public class MongoRepository : IResourceRepository _mongoDataAccess.TransactionId; public MongoRepository(IMongoDataAccess mongoDataAccess, ITargetedFields targetedFields, IResourceGraph resourceGraph, IResourceFactory resourceFactory, - IEnumerable constraintProviders, IResourceDefinitionAccessor resourceDefinitionAccessor) + IEnumerable constraintProviders, IResourceDefinitionAccessor resourceDefinitionAccessor, IQueryableBuilder queryableBuilder) { ArgumentGuard.NotNull(mongoDataAccess); ArgumentGuard.NotNull(targetedFields); @@ -44,6 +45,7 @@ public MongoRepository(IMongoDataAccess mongoDataAccess, ITargetedFields targete ArgumentGuard.NotNull(resourceFactory); ArgumentGuard.NotNull(constraintProviders); ArgumentGuard.NotNull(resourceDefinitionAccessor); + ArgumentGuard.NotNull(queryableBuilder); _mongoDataAccess = mongoDataAccess; _targetedFields = targetedFields; @@ -51,6 +53,7 @@ public MongoRepository(IMongoDataAccess mongoDataAccess, ITargetedFields targete _resourceFactory = resourceFactory; _constraintProviders = constraintProviders; _resourceDefinitionAccessor = resourceDefinitionAccessor; + _queryableBuilder = queryableBuilder; if (!typeof(TResource).IsAssignableTo(typeof(IMongoIdentifiable))) { @@ -112,12 +115,9 @@ protected virtual IMongoQueryable ApplyQueryLayer(QueryLayer queryLay source = queryableHandler.Apply(source); } - var nameFactory = new LambdaParameterNameFactory(); + var context = QueryableBuilderContext.CreateRoot(source, typeof(Queryable), new MongoModel(_resourceGraph), null); + Expression expression = _queryableBuilder.ApplyQuery(queryLayer, context); - var builder = new QueryableBuilder(source.Expression, source.ElementType, typeof(Queryable), nameFactory, _resourceFactory, - new MongoModel(_resourceGraph)); - - Expression expression = builder.ApplyQuery(queryLayer); return (IMongoQueryable)source.Provider.CreateQuery(expression); } diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/AtomicOperations/Transactions/LyricRepository.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/AtomicOperations/Transactions/LyricRepository.cs index c1275be..93e31b2 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/AtomicOperations/Transactions/LyricRepository.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/AtomicOperations/Transactions/LyricRepository.cs @@ -4,6 +4,7 @@ using JsonApiDotNetCore.MongoDb.AtomicOperations; using JsonApiDotNetCore.MongoDb.Repositories; using JsonApiDotNetCore.Queries; +using JsonApiDotNetCore.Queries.QueryableBuilding; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCoreMongoDbTests.IntegrationTests.AtomicOperations.Transactions; @@ -19,8 +20,9 @@ public sealed class LyricRepository : MongoRepository, IAsyncDis public override string TransactionId => _transaction.TransactionId; public LyricRepository(IMongoDataAccess mongoDataAccess, ITargetedFields targetedFields, IResourceGraph resourceGraph, IResourceFactory resourceFactory, - IEnumerable constraintProviders, IResourceDefinitionAccessor resourceDefinitionAccessor) - : base(mongoDataAccess, targetedFields, resourceGraph, resourceFactory, constraintProviders, resourceDefinitionAccessor) + IEnumerable constraintProviders, IResourceDefinitionAccessor resourceDefinitionAccessor, + IQueryableBuilder queryableBuilder) + : base(mongoDataAccess, targetedFields, resourceGraph, resourceFactory, constraintProviders, resourceDefinitionAccessor, queryableBuilder) { IMongoDataAccess otherDataAccess = new MongoDataAccess(mongoDataAccess.MongoDatabase); diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/AtomicOperations/Transactions/MusicTrackRepository.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/AtomicOperations/Transactions/MusicTrackRepository.cs index 09164f2..5d40f37 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/AtomicOperations/Transactions/MusicTrackRepository.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/AtomicOperations/Transactions/MusicTrackRepository.cs @@ -2,6 +2,7 @@ using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.MongoDb.Repositories; using JsonApiDotNetCore.Queries; +using JsonApiDotNetCore.Queries.QueryableBuilding; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCoreMongoDbTests.IntegrationTests.AtomicOperations.Transactions; @@ -14,8 +15,9 @@ public sealed class MusicTrackRepository : MongoRepository public override string? TransactionId => null; public MusicTrackRepository(IMongoDataAccess mongoDataAccess, ITargetedFields targetedFields, IResourceGraph resourceGraph, - IResourceFactory resourceFactory, IEnumerable constraintProviders, IResourceDefinitionAccessor resourceDefinitionAccessor) - : base(mongoDataAccess, targetedFields, resourceGraph, resourceFactory, constraintProviders, resourceDefinitionAccessor) + IResourceFactory resourceFactory, IEnumerable constraintProviders, IResourceDefinitionAccessor resourceDefinitionAccessor, + IQueryableBuilder queryableBuilder) + : base(mongoDataAccess, targetedFields, resourceGraph, resourceFactory, constraintProviders, resourceDefinitionAccessor, queryableBuilder) { } } diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs index c8e6a05..5dc1442 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Filtering/FilterDataTypeTests.cs @@ -265,7 +265,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => ErrorObject error = responseDocument.Errors[0]; error.StatusCode.Should().Be(HttpStatusCode.BadRequest); error.Title.Should().Be("The specified filter is invalid."); - error.Detail.Should().Be("Failed to convert 'ABC' of type 'String' to type 'Int32'."); + error.Detail.Should().StartWith("Failed to convert 'ABC' of type 'String' to type 'Int32'."); error.Source.ShouldNotBeNull(); error.Source.Parameter.Should().Be("filter"); } diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/SparseFieldSets/ResultCapturingRepository.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/SparseFieldSets/ResultCapturingRepository.cs index 400ee49..b88cd2e 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/SparseFieldSets/ResultCapturingRepository.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/SparseFieldSets/ResultCapturingRepository.cs @@ -2,6 +2,7 @@ using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.MongoDb.Repositories; using JsonApiDotNetCore.Queries; +using JsonApiDotNetCore.Queries.QueryableBuilding; using JsonApiDotNetCore.Resources; namespace JsonApiDotNetCoreMongoDbTests.IntegrationTests.QueryStrings.SparseFieldSets; @@ -17,8 +18,8 @@ public sealed class ResultCapturingRepository : MongoRepository< public ResultCapturingRepository(IMongoDataAccess mongoDataAccess, ITargetedFields targetedFields, IResourceGraph resourceGraph, IResourceFactory resourceFactory, IEnumerable constraintProviders, IResourceDefinitionAccessor resourceDefinitionAccessor, - ResourceCaptureStore captureStore) - : base(mongoDataAccess, targetedFields, resourceGraph, resourceFactory, constraintProviders, resourceDefinitionAccessor) + IQueryableBuilder queryableBuilder, ResourceCaptureStore captureStore) + : base(mongoDataAccess, targetedFields, resourceGraph, resourceFactory, constraintProviders, resourceDefinitionAccessor, queryableBuilder) { _captureStore = captureStore; } From eb7247d986134293cf75cae757815c5dcc305ed6 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 25 Jul 2023 22:01:17 +0200 Subject: [PATCH 10/15] Add missing controller annotations in tests --- .../IntegrationTests/QueryStrings/AccountPreferences.cs | 1 + .../IntegrationTests/QueryStrings/Label.cs | 1 + .../IntegrationTests/QueryStrings/LoginAttempt.cs | 1 + .../IntegrationTests/ReadWrite/WorkTag.cs | 1 + 4 files changed, 4 insertions(+) diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/AccountPreferences.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/AccountPreferences.cs index 0cd5aa2..73ea764 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/AccountPreferences.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/AccountPreferences.cs @@ -5,6 +5,7 @@ namespace JsonApiDotNetCoreMongoDbTests.IntegrationTests.QueryStrings; [UsedImplicitly(ImplicitUseTargetFlags.Members)] +[Resource(ControllerNamespace = "JsonApiDotNetCoreMongoDbTests.IntegrationTests.QueryStrings")] public sealed class AccountPreferences : HexStringMongoIdentifiable { [Attr] diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Label.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Label.cs index 5c267fb..1cc8ce3 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Label.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/Label.cs @@ -6,6 +6,7 @@ namespace JsonApiDotNetCoreMongoDbTests.IntegrationTests.QueryStrings; [UsedImplicitly(ImplicitUseTargetFlags.Members)] +[Resource(ControllerNamespace = "JsonApiDotNetCoreMongoDbTests.IntegrationTests.QueryStrings")] public sealed class Label : HexStringMongoIdentifiable { [Attr] diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/LoginAttempt.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/LoginAttempt.cs index 5e06cea..412b964 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/LoginAttempt.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/QueryStrings/LoginAttempt.cs @@ -5,6 +5,7 @@ namespace JsonApiDotNetCoreMongoDbTests.IntegrationTests.QueryStrings; [UsedImplicitly(ImplicitUseTargetFlags.Members)] +[Resource(ControllerNamespace = "JsonApiDotNetCoreMongoDbTests.IntegrationTests.QueryStrings")] public sealed class LoginAttempt : HexStringMongoIdentifiable { [Attr] diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/ReadWrite/WorkTag.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/ReadWrite/WorkTag.cs index 48de6cf..bbd12e5 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/ReadWrite/WorkTag.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/ReadWrite/WorkTag.cs @@ -6,6 +6,7 @@ namespace JsonApiDotNetCoreMongoDbTests.IntegrationTests.ReadWrite; [UsedImplicitly(ImplicitUseTargetFlags.Members)] +[Resource(ControllerNamespace = "JsonApiDotNetCoreMongoDbTests.IntegrationTests.ReadWrite")] public sealed class WorkTag : HexStringMongoIdentifiable { [Attr] From 7e29252dd52421f211288a9dac1e5af6e61f8e09 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 25 Jul 2023 22:06:11 +0200 Subject: [PATCH 11/15] Add readme to NuGet package --- PackageReadme.md | 1 + .../JsonApiDotNetCore.MongoDb.csproj | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 PackageReadme.md diff --git a/PackageReadme.md b/PackageReadme.md new file mode 100644 index 0000000..6c9ce84 --- /dev/null +++ b/PackageReadme.md @@ -0,0 +1 @@ +Persistence layer implementation for use of [MongoDB](https://www.mongodb.com/) in APIs using [JsonApiDotNetCore](https://www.jsonapi.net/). diff --git a/src/JsonApiDotNetCore.MongoDb/JsonApiDotNetCore.MongoDb.csproj b/src/JsonApiDotNetCore.MongoDb/JsonApiDotNetCore.MongoDb.csproj index 2cc225f..ab3c7f6 100644 --- a/src/JsonApiDotNetCore.MongoDb/JsonApiDotNetCore.MongoDb.csproj +++ b/src/JsonApiDotNetCore.MongoDb/JsonApiDotNetCore.MongoDb.csproj @@ -15,16 +15,15 @@ false See https://github.com/json-api-dotnet/JsonApiDotNetCore.MongoDb/releases. logo.png + PackageReadme.md true true embedded - - True - - + + From 5449118cb675fa6cc4d6bda6c160746882ca1598 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 25 Jul 2023 22:11:07 +0200 Subject: [PATCH 12/15] Deterministic CI-builds --- .../JsonApiDotNetCore.MongoDb.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/JsonApiDotNetCore.MongoDb/JsonApiDotNetCore.MongoDb.csproj b/src/JsonApiDotNetCore.MongoDb/JsonApiDotNetCore.MongoDb.csproj index ab3c7f6..7b9f43a 100644 --- a/src/JsonApiDotNetCore.MongoDb/JsonApiDotNetCore.MongoDb.csproj +++ b/src/JsonApiDotNetCore.MongoDb/JsonApiDotNetCore.MongoDb.csproj @@ -21,6 +21,10 @@ embedded + + true + + From f32d1b07bfc05236009d8ee6a580d376ffdd0266 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 25 Jul 2023 22:12:33 +0200 Subject: [PATCH 13/15] Adapt for corrected nullability annotation in .NET 8 --- .../ResourceDefinitions/Reading/MoonDefinition.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/ResourceDefinitions/Reading/MoonDefinition.cs b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/ResourceDefinitions/Reading/MoonDefinition.cs index b2b8fa6..26dcdb5 100644 --- a/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/ResourceDefinitions/Reading/MoonDefinition.cs +++ b/test/JsonApiDotNetCoreMongoDbTests/IntegrationTests/ResourceDefinitions/Reading/MoonDefinition.cs @@ -29,7 +29,7 @@ public override QueryStringParameterHandlers OnRegisterQueryableHandlersFo private static IQueryable FilterByRadius(IQueryable source, StringValues parameterValue) { - bool isFilterOnLargerThan = bool.Parse(parameterValue); + bool isFilterOnLargerThan = bool.Parse(parameterValue.ToString()); return isFilterOnLargerThan ? source.Where(moon => moon.SolarRadius > 1m) : source.Where(moon => moon.SolarRadius <= 1m); } } From da00cd5cde84eeb5c35d305f5e1b74bac97285bf Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 25 Jul 2023 22:24:36 +0200 Subject: [PATCH 14/15] Update MongoDB.Driver package due to a known moderate severity vulnerability in v2.15.0, which was fixed in v2.19.0 --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index e53af2e..160cbe7 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -3,7 +3,7 @@ net6.0 6.0.* 5.3.0 - 2.15.0 + 2.20.0 5.1.3 $(MSBuildThisFileDirectory)CodingGuidelines.ruleset 9999 From e7ac033417b8ae67adf931a013185d48f2f45df8 Mon Sep 17 00:00:00 2001 From: Bart Koelman <10324372+bkoelman@users.noreply.github.com> Date: Tue, 25 Jul 2023 23:08:39 +0200 Subject: [PATCH 15/15] Update version to 5.3.0 --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 160cbe7..218247a 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,7 @@ 6.0.* 5.3.0 2.20.0 - 5.1.3 + 5.3.0 $(MSBuildThisFileDirectory)CodingGuidelines.ruleset 9999 enable