From 24fb4a91627ea843563ff34209dbf06d8a9dca27 Mon Sep 17 00:00:00 2001 From: Adrian Iftode Date: Fri, 29 Nov 2024 08:59:30 +0000 Subject: [PATCH 1/4] Next to 1.8.0 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index b2d3e4e..464885c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 1.7.0-ci-{build} +version: 1.8.0-ci-{build} image: Visual Studio 2022 branches: only: From 3a2e3acb56ae2cddc89947dff857dcc989f9ca98 Mon Sep 17 00:00:00 2001 From: Adrian Iftode Date: Mon, 20 Jan 2025 12:39:20 +0000 Subject: [PATCH 2/4] Add NET9.0 Sample --- FluentAssertions.Web.sln | 28 +++++++---------- .../Properties/launchSettings.json | 30 ------------------- .../Properties/launchSettings.json | 30 ------------------- .../Sample.Api.Net70/Sample.Api.Net70.csproj | 9 ------ .../Properties/launchSettings.json | 12 ++++++++ .../Sample.Api.Net90.csproj} | 2 +- test/Directory.Build.props | 2 +- test/Sample.Api.Tests/Sample.Api.Tests.csproj | 17 ++++------- 8 files changed, 30 insertions(+), 100 deletions(-) delete mode 100644 samples/Sample.Api.Net60/Properties/launchSettings.json delete mode 100644 samples/Sample.Api.Net70/Properties/launchSettings.json delete mode 100644 samples/Sample.Api.Net70/Sample.Api.Net70.csproj create mode 100644 samples/Sample.Api.Net90/Properties/launchSettings.json rename samples/{Sample.Api.Net60/Sample.Api.Net60.csproj => Sample.Api.Net90/Sample.Api.Net90.csproj} (79%) diff --git a/FluentAssertions.Web.sln b/FluentAssertions.Web.sln index 2d2fc1d..d9605ed 100644 --- a/FluentAssertions.Web.sln +++ b/FluentAssertions.Web.sln @@ -28,14 +28,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .gitignore = .gitignore appveyor.yml = appveyor.yml Directory.Packages.props = Directory.Packages.props - readme.md = readme.md nuget.config = nuget.config + readme.md = readme.md EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Api.Tests", "test\Sample.Api.Tests\Sample.Api.Tests.csproj", "{5E7E24A9-A31F-4EBB-A3BA-167B0DD9C37E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Api.Net60", "samples\Sample.Api.Net60\Sample.Api.Net60.csproj", "{FACC5AED-9978-441D-A359-DCD83F924BF8}" -EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Sample.Api.Shared", "Samples\Sample.Api.Shared\Sample.Api.Shared.shproj", "{815C141D-4504-42B1-A6F7-672C2476A474}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentAssertions.Web.Serializers.NewtonsoftJson", "src\FluentAssertions.Web.Serializers.NewtonsoftJson\FluentAssertions.Web.Serializers.NewtonsoftJson.csproj", "{1BDE8312-1789-40EA-86B2-83784E560740}" @@ -44,10 +42,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentAssertions.Web.Serial EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentAssertions.Web.FluentAssertionsWebConfig.Tests", "test\FluentAssertions.Web.FluentAssertionsWebConfig.Tests\FluentAssertions.Web.FluentAssertionsWebConfig.Tests.csproj", "{538479CE-5922-4FF9-A09D-80C9E91FFFF1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Api.Net70", "samples\Sample.Api.Net70\Sample.Api.Net70.csproj", "{DCC4B007-DCE3-443E-BC9D-635EE367882B}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.Api.Net80", "samples\Sample.Api.Net80\Sample.Api.Net80.csproj", "{9B53847C-0D39-46AB-9E39-A2DCA0676D88}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.Api.Net90", "samples\Sample.Api.Net90\Sample.Api.Net90.csproj", "{73E11379-908A-4BA0-9365-AE800A88C39B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -66,10 +64,6 @@ Global {5E7E24A9-A31F-4EBB-A3BA-167B0DD9C37E}.Debug|Any CPU.Build.0 = Debug|Any CPU {5E7E24A9-A31F-4EBB-A3BA-167B0DD9C37E}.Release|Any CPU.ActiveCfg = Release|Any CPU {5E7E24A9-A31F-4EBB-A3BA-167B0DD9C37E}.Release|Any CPU.Build.0 = Release|Any CPU - {FACC5AED-9978-441D-A359-DCD83F924BF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FACC5AED-9978-441D-A359-DCD83F924BF8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FACC5AED-9978-441D-A359-DCD83F924BF8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FACC5AED-9978-441D-A359-DCD83F924BF8}.Release|Any CPU.Build.0 = Release|Any CPU {1BDE8312-1789-40EA-86B2-83784E560740}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1BDE8312-1789-40EA-86B2-83784E560740}.Debug|Any CPU.Build.0 = Debug|Any CPU {1BDE8312-1789-40EA-86B2-83784E560740}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -82,14 +76,14 @@ Global {538479CE-5922-4FF9-A09D-80C9E91FFFF1}.Debug|Any CPU.Build.0 = Debug|Any CPU {538479CE-5922-4FF9-A09D-80C9E91FFFF1}.Release|Any CPU.ActiveCfg = Release|Any CPU {538479CE-5922-4FF9-A09D-80C9E91FFFF1}.Release|Any CPU.Build.0 = Release|Any CPU - {DCC4B007-DCE3-443E-BC9D-635EE367882B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DCC4B007-DCE3-443E-BC9D-635EE367882B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DCC4B007-DCE3-443E-BC9D-635EE367882B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DCC4B007-DCE3-443E-BC9D-635EE367882B}.Release|Any CPU.Build.0 = Release|Any CPU {9B53847C-0D39-46AB-9E39-A2DCA0676D88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9B53847C-0D39-46AB-9E39-A2DCA0676D88}.Debug|Any CPU.Build.0 = Debug|Any CPU {9B53847C-0D39-46AB-9E39-A2DCA0676D88}.Release|Any CPU.ActiveCfg = Release|Any CPU {9B53847C-0D39-46AB-9E39-A2DCA0676D88}.Release|Any CPU.Build.0 = Release|Any CPU + {73E11379-908A-4BA0-9365-AE800A88C39B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {73E11379-908A-4BA0-9365-AE800A88C39B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {73E11379-908A-4BA0-9365-AE800A88C39B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {73E11379-908A-4BA0-9365-AE800A88C39B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -98,21 +92,19 @@ Global {313919D0-7CE6-4118-A6A2-8963362A338F} = {BFF7517A-C9EA-458D-829E-28A10F8D61BF} {3C892A67-86B1-491F-8BF6-6E782FE4F689} = {14FDD52D-B83A-445B-BD2F-04B3E7B8033C} {5E7E24A9-A31F-4EBB-A3BA-167B0DD9C37E} = {BFF7517A-C9EA-458D-829E-28A10F8D61BF} - {FACC5AED-9978-441D-A359-DCD83F924BF8} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9} {815C141D-4504-42B1-A6F7-672C2476A474} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9} {1BDE8312-1789-40EA-86B2-83784E560740} = {14FDD52D-B83A-445B-BD2F-04B3E7B8033C} {F2C0B6F2-4ACE-4688-8F96-9EB1D5718B60} = {BFF7517A-C9EA-458D-829E-28A10F8D61BF} {538479CE-5922-4FF9-A09D-80C9E91FFFF1} = {BFF7517A-C9EA-458D-829E-28A10F8D61BF} - {DCC4B007-DCE3-443E-BC9D-635EE367882B} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9} {9B53847C-0D39-46AB-9E39-A2DCA0676D88} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9} + {73E11379-908A-4BA0-9365-AE800A88C39B} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {81F41C75-2F8A-4E70-BA17-38146C4BB6E6} EndGlobalSection GlobalSection(SharedMSBuildProjectFiles) = preSolution - Samples\Sample.Api.Shared\Sample.Api.Shared.projitems*{4c9619bf-7ed4-42a3-b25c-15e288264c6f}*SharedItemsImports = 5 + Samples\Sample.Api.Shared\Sample.Api.Shared.projitems*{73e11379-908a-4ba0-9365-ae800a88c39b}*SharedItemsImports = 5 Samples\Sample.Api.Shared\Sample.Api.Shared.projitems*{815c141d-4504-42b1-a6f7-672c2476a474}*SharedItemsImports = 13 - Samples\Sample.Api.Shared\Sample.Api.Shared.projitems*{dcc4b007-dce3-443e-bc9d-635ee367882b}*SharedItemsImports = 5 - Samples\Sample.Api.Shared\Sample.Api.Shared.projitems*{facc5aed-9978-441d-a359-dcd83f924bf8}*SharedItemsImports = 5 + Samples\Sample.Api.Shared\Sample.Api.Shared.projitems*{9b53847c-0d39-46ab-9e39-a2dca0676d88}*SharedItemsImports = 5 EndGlobalSection EndGlobal diff --git a/samples/Sample.Api.Net60/Properties/launchSettings.json b/samples/Sample.Api.Net60/Properties/launchSettings.json deleted file mode 100644 index 77e49fd..0000000 --- a/samples/Sample.Api.Net60/Properties/launchSettings.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:58229", - "sslPort": 44366 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "api/values", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "FluentAssertions.Web.Api": { - "commandName": "Project", - "launchBrowser": true, - "launchUrl": "api/values", - "applicationUrl": "https://localhost:5001;http://localhost:5000", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/samples/Sample.Api.Net70/Properties/launchSettings.json b/samples/Sample.Api.Net70/Properties/launchSettings.json deleted file mode 100644 index 77e49fd..0000000 --- a/samples/Sample.Api.Net70/Properties/launchSettings.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:58229", - "sslPort": 44366 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "api/values", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "FluentAssertions.Web.Api": { - "commandName": "Project", - "launchBrowser": true, - "launchUrl": "api/values", - "applicationUrl": "https://localhost:5001;http://localhost:5000", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/samples/Sample.Api.Net70/Sample.Api.Net70.csproj b/samples/Sample.Api.Net70/Sample.Api.Net70.csproj deleted file mode 100644 index fd07e20..0000000 --- a/samples/Sample.Api.Net70/Sample.Api.Net70.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - net7.0 - - - - - diff --git a/samples/Sample.Api.Net90/Properties/launchSettings.json b/samples/Sample.Api.Net90/Properties/launchSettings.json new file mode 100644 index 0000000..1f17278 --- /dev/null +++ b/samples/Sample.Api.Net90/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "Sample.Api.Net90": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:54002;http://localhost:54003" + } + } +} \ No newline at end of file diff --git a/samples/Sample.Api.Net60/Sample.Api.Net60.csproj b/samples/Sample.Api.Net90/Sample.Api.Net90.csproj similarity index 79% rename from samples/Sample.Api.Net60/Sample.Api.Net60.csproj rename to samples/Sample.Api.Net90/Sample.Api.Net90.csproj index 98d784a..e7d4a13 100644 --- a/samples/Sample.Api.Net60/Sample.Api.Net60.csproj +++ b/samples/Sample.Api.Net90/Sample.Api.Net90.csproj @@ -1,7 +1,7 @@  - net6.0 + net9.0 diff --git a/test/Directory.Build.props b/test/Directory.Build.props index b124cf0..fd545e4 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -1,7 +1,7 @@ - netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net6.0;net7.0;net8.0 + netcoreapp2.1;netcoreapp3.1;net8.0;net9.0 latest enable CS8600;CS8602;CS8603 diff --git a/test/Sample.Api.Tests/Sample.Api.Tests.csproj b/test/Sample.Api.Tests/Sample.Api.Tests.csproj index 11cd7c3..a4671c9 100644 --- a/test/Sample.Api.Tests/Sample.Api.Tests.csproj +++ b/test/Sample.Api.Tests/Sample.Api.Tests.csproj @@ -1,24 +1,19 @@  - net6.0;net7.0;net8.0 + net8.0;net9.0 - - - - - - - - - - + + + + + From 2472e087e735fa45e32d8c9bda3d3750a0010625 Mon Sep 17 00:00:00 2001 From: Adrian Iftode Date: Mon, 20 Jan 2025 14:02:23 +0000 Subject: [PATCH 3/4] Add support for Fluent Assertsion v8 --- Directory.Packages.props | 2 +- appveyor.yml | 3 +- ...ions.Web.Serializers.NewtonsoftJson.csproj | 1 + .../BadRequestAssertions.cs | 19 +- .../BadRequestAssertionsExtensions.cs | 111 -- .../FluentAssertions.Web.csproj | 7 +- .../HaveHeaderAssertions.cs | 23 +- .../HaveHeaderAssertionsExtensions.cs | 52 - .../HttpResponseContentAssertions.cs | 23 +- ...HttpResponseContentAssertionsExtensions.cs | 99 -- .../HttpResponseMessageAssertions.cs | 3 +- ...sponseMessageFluentAssertionsExtensions.cs | 17 + .../HttpStatusCodeAssertions.cs | 226 ++-- .../HttpStatusCodeAssertionsExtensions.cs | 1048 ----------------- .../SatisfyHttpResponseMessageAssertions.cs | 8 +- ...HttpResponseMessageAssertionsExtensions.cs | 59 - .../SatisfyModelAssertions.cs | 24 +- .../SatisfyModelAssertionsExtensions.cs | 117 -- .../DeserializationExceptionTests.cs | 12 - .../HeadersAssertionsSpecs.cs | 4 +- .../HttpResponseContentAssertionsSpecs.cs | 2 +- .../Internal/ApiAccessibilityTests.cs | 54 - 22 files changed, 192 insertions(+), 1722 deletions(-) delete mode 100644 src/FluentAssertions.Web/BadRequestAssertionsExtensions.cs delete mode 100644 src/FluentAssertions.Web/HaveHeaderAssertionsExtensions.cs delete mode 100644 src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs create mode 100644 src/FluentAssertions.Web/HttpResponseMessageFluentAssertionsExtensions.cs delete mode 100644 src/FluentAssertions.Web/HttpStatusCodeAssertionsExtensions.cs delete mode 100644 src/FluentAssertions.Web/SatisfyHttpResponseMessageAssertionsExtensions.cs delete mode 100644 src/FluentAssertions.Web/SatisfyModelAssertionsExtensions.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 5d4d29e..769b5d4 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,7 +6,7 @@ - + diff --git a/appveyor.yml b/appveyor.yml index 464885c..42ca01e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,6 +3,7 @@ image: Visual Studio 2022 branches: only: - master + - master-v8 - /\d+\.\d+\.\d+/ pull_requests: do_not_increment_build_number: false @@ -70,7 +71,7 @@ artifacts: deploy: - provider: NuGet api_key: - secure: aHT1IlqkfTAZm236Pkjt84NdjfEIrPJqJt4IwO5QNvH0LpIWqx/L3oFRewdCwCQs + secure: vSWvi7ciU2pZZmpcXGvvR0APUpesgZBAScxNcBUttDHuWhgEAFS5fEeEiFFl5wl6 skip_symbols: true artifact: /.*\.nupkg/ on: diff --git a/src/FluentAssertions.Web.Serializers.NewtonsoftJson/FluentAssertions.Web.Serializers.NewtonsoftJson.csproj b/src/FluentAssertions.Web.Serializers.NewtonsoftJson/FluentAssertions.Web.Serializers.NewtonsoftJson.csproj index a1b4ff3..ab7756e 100644 --- a/src/FluentAssertions.Web.Serializers.NewtonsoftJson/FluentAssertions.Web.Serializers.NewtonsoftJson.csproj +++ b/src/FluentAssertions.Web.Serializers.NewtonsoftJson/FluentAssertions.Web.Serializers.NewtonsoftJson.csproj @@ -1,6 +1,7 @@ + FluentAssertions.Web.v8.Serializers.NewtonsoftJson NewtonsoftJson based serializer for FluentAssertions.Web diff --git a/src/FluentAssertions.Web/BadRequestAssertions.cs b/src/FluentAssertions.Web/BadRequestAssertions.cs index 9a1aa9e..36fe329 100644 --- a/src/FluentAssertions.Web/BadRequestAssertions.cs +++ b/src/FluentAssertions.Web/BadRequestAssertions.cs @@ -12,7 +12,8 @@ public class BadRequestAssertions : HttpResponseMessageAssertions /// class. /// /// The subject value to be asserted. - public BadRequestAssertions(HttpResponseMessage value) : base(value) + /// The assertion chain to build and manage assertions. + public BadRequestAssertions(HttpResponseMessage value, AssertionChain assertionChain) : base(value, assertionChain) { } @@ -56,7 +57,7 @@ public AndConstraint HaveError(string expectedErrorField, var allFields = json.GetChildrenNames(""); var fields = hasErrorsProperty ? fieldsOfErrorsProperty : allFields; - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(fields.Any(field => string.Equals(field, expectedErrorField, StringComparison.OrdinalIgnoreCase))) .FailWith("Expected {context:response} " + @@ -72,7 +73,7 @@ public AndConstraint HaveError(string expectedErrorField, return !scope.Discard().Any(); }); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(matchFound) .FailWith("Expected {context:response} to contain " + @@ -122,7 +123,7 @@ public AndConstraint OnlyHaveError(string expectedErrorFie var allFields = json.GetChildrenNames(""); var fields = hasErrorsProperty ? fieldsOfErrorsProperty : allFields; - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(fields.Any(field => string.Equals(field, expectedErrorField, StringComparison.OrdinalIgnoreCase))) .FailWith("Expected {context:response} " + @@ -133,7 +134,7 @@ public AndConstraint OnlyHaveError(string expectedErrorFie var parent = hasErrorsProperty ? ErrorsPropertyName : json.GetParentKey(expectedErrorField); var children = json.GetChildrenNames(parent); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(children.Count() == 1) .FailWith("Expected {context:response} " + @@ -149,7 +150,7 @@ public AndConstraint OnlyHaveError(string expectedErrorFie return !scope.Discard().Any(); }); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(expectedWildcardErrorMessageMatchFound) .FailWith("Expected {context:response} to contain " + @@ -160,7 +161,7 @@ public AndConstraint OnlyHaveError(string expectedErrorFie expectedErrorField, Subject); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(values.Count() == 1) .FailWith("Expected {context:response} " + @@ -202,7 +203,7 @@ public AndConstraint NotHaveError(string expectedErrorFiel var allFields = json.GetChildrenNames(""); var fields = hasErrorsProperty ? fieldsOfErrorsProperty : allFields; - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(!fields.Any(c => string.Equals(c, expectedErrorField, StringComparison.OrdinalIgnoreCase))) .FailWith("Expected {context:response} " + @@ -247,7 +248,7 @@ public AndConstraint HaveErrorMessage(string expectedWildc return !scope.Discard().Any(); }); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(matchFound) .FailWith("Expected {context:response} to contain " + diff --git a/src/FluentAssertions.Web/BadRequestAssertionsExtensions.cs b/src/FluentAssertions.Web/BadRequestAssertionsExtensions.cs deleted file mode 100644 index ce11c79..0000000 --- a/src/FluentAssertions.Web/BadRequestAssertionsExtensions.cs +++ /dev/null @@ -1,111 +0,0 @@ -// ReSharper disable once CheckNamespace -namespace FluentAssertions; - -/// -/// Contains extension methods for custom assertions in unit tests related to . -/// -[DebuggerNonUserCode] -public static class BadRequestAssertionsExtensions -{ - /// - /// Asserts that a Bad Request HTTP response content contains an error message identifiable by an expected field name and a wildcard error text. - /// - /// - /// This assertion considers the HTTP response content a JSON generated by the ASP.NET Core 3.0 framework or less - /// - /// - /// The expected field name. - /// - /// - /// The wildcard pattern with which the error field associated error message is matched, where * and ? have special meanings. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint HaveError( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - string expectedErrorField, string expectedWildcardErrorMessage, - string because = "", params object[] becauseArgs) - => new BadRequestAssertions(parent.Subject).HaveError(expectedErrorField, expectedWildcardErrorMessage, because, becauseArgs); - - /// - /// Asserts that a Bad Request HTTP response content contains only a single error message identifiable by an expected field name and a wildcard error text. - /// - /// - /// This assertion considers the HTTP response content a JSON generated by the ASP.NET Core 3.0 framework or less - /// - /// - /// The expected field name. - /// - /// - /// The wildcard pattern with which the error field associated error message is matched, where * and ? have special meanings. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint OnlyHaveError( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - string expectedErrorField, string expectedWildcardErrorMessage, - string because = "", params object[] becauseArgs) - => new BadRequestAssertions(parent.Subject).OnlyHaveError(expectedErrorField, expectedWildcardErrorMessage, because, becauseArgs); - - /// - /// Asserts that a Bad Request HTTP response content does not contain an error message identifiable by an expected field name. - /// - /// - /// This assertion considers the HTTP response content a JSON generated by the ASP.NET Core 3.0 framework or less - /// - /// - /// The expected field name. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint NotHaveError( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - string expectedErrorField, string because = "", params object[] becauseArgs) - => new BadRequestAssertions(parent.Subject).NotHaveError(expectedErrorField, because, becauseArgs); - - /// - /// Asserts that a Bad Request HTTP response content contains an error message identifiable by an wildcard error text. - /// - /// - /// The wildcard pattern with which the error field associated error message is matched, where * and ? have special meanings. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint HaveErrorMessage( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - string expectedWildcardErrorMessage, - string because = "", params object[] becauseArgs) - => new BadRequestAssertions(parent.Subject).HaveErrorMessage(expectedWildcardErrorMessage, because, becauseArgs); -} \ No newline at end of file diff --git a/src/FluentAssertions.Web/FluentAssertions.Web.csproj b/src/FluentAssertions.Web/FluentAssertions.Web.csproj index a3bc593..b1ec0cb 100644 --- a/src/FluentAssertions.Web/FluentAssertions.Web.csproj +++ b/src/FluentAssertions.Web/FluentAssertions.Web.csproj @@ -1,9 +1,10 @@  - - This is a FluentAssertions extension over the HttpResponseMessage object. It provides assertions specific to HTTP responses and outputs rich erros messages when the tests fail, so less time with debugging is spent. - + FluentAssertions.Web.v8 + + This is a FluentAssertions extension over the HttpResponseMessage object. It provides assertions specific to HTTP responses and outputs rich erros messages when the tests fail, so less time with debugging is spent. + diff --git a/src/FluentAssertions.Web/HaveHeaderAssertions.cs b/src/FluentAssertions.Web/HaveHeaderAssertions.cs index 5a2215a..39717c5 100644 --- a/src/FluentAssertions.Web/HaveHeaderAssertions.cs +++ b/src/FluentAssertions.Web/HaveHeaderAssertions.cs @@ -13,7 +13,8 @@ public class HeadersAssertions : HttpResponseMessageAssertions /// /// The subject value to be asserted. /// The HTTP header name to be asserted. - public HeadersAssertions(HttpResponseMessage value, string header) : base(value) => _header = header; + /// The assertion chain to build and manage assertions. + public HeadersAssertions(HttpResponseMessage value, string header, AssertionChain assertionChain) : base(value, assertionChain) => _header = header; /// /// Asserts that an existing HTTP header in a HTTP response contains at least a value that matches a wildcard pattern. @@ -37,7 +38,7 @@ public AndConstraint Match(string expectedWildcardValue, stri { Guard.ThrowIfArgumentIsNull(expectedWildcardValue, nameof(expectedWildcardValue), "Cannot verify a HTTP header to be a value against a value. Use And.BeEmpty to test if the HTTP header has no values."); - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -51,7 +52,7 @@ public AndConstraint Match(string expectedWildcardValue, stri return !scope.Discard().Any(); }); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(matchFound) .FailWith("Expected {context:response} to contain " + @@ -78,7 +79,7 @@ public AndConstraint BeEmpty(string because = "", params obje { var headerValues = Subject.GetHeaderValues(_header); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(!headerValues.Any()) .FailWith("Expected {context:response} to contain " + @@ -105,7 +106,7 @@ public AndConstraint NotBeEmpty(string because = "", params o { var headerValues = Subject.GetHeaderValues(_header); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(headerValues.Any()) .FailWith("Expected {context:response} to contain " + @@ -151,7 +152,7 @@ public AndConstraint BeValues(IEnumerable expectedVal failures = scope.Discard(); } - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(failures.Length == 0) .FailWith("Expected {context:response} to contain " + @@ -182,7 +183,7 @@ public AndConstraint BeValue(string expectedValue, { Guard.ThrowIfArgumentIsNullOrEmpty(expectedValue, nameof(expectedValue), "Cannot verify a HTTP header to be a value against a or empty value. Use And.BeEmpty to test if the HTTP header has no value."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(Subject.GetHeaderValues(_header).Count() == 1) .FailWith($$""" @@ -200,7 +201,7 @@ public AndConstraint BeValue(string expectedValue, failures = scope.Discard(); } - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(failures.Length == 0) .FailWith($$""" @@ -237,7 +238,7 @@ public AndConstraint HaveHeader(string expectedHeader, { Guard.ThrowIfArgumentIsNull(expectedHeader, nameof(expectedHeader), "Cannot verify having a header against a header."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(IsHeaderPresent(expectedHeader)) .FailWith("Expected {context:response} to contain " + @@ -245,7 +246,7 @@ public AndConstraint HaveHeader(string expectedHeader, expectedHeader, Subject); - return new AndConstraint(new HeadersAssertions(Subject, expectedHeader)); + return new AndConstraint(new HeadersAssertions(Subject, expectedHeader, CurrentAssertionChain)); } /// @@ -267,7 +268,7 @@ public AndConstraint NotHaveHeader(string expecte { Guard.ThrowIfArgumentIsNull(expectedHeader, nameof(expectedHeader), "Cannot verify not having a header against a header."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(!IsHeaderPresent(expectedHeader)) .FailWith("Expected {context:response} to not to contain " + diff --git a/src/FluentAssertions.Web/HaveHeaderAssertionsExtensions.cs b/src/FluentAssertions.Web/HaveHeaderAssertionsExtensions.cs deleted file mode 100644 index e565ff9..0000000 --- a/src/FluentAssertions.Web/HaveHeaderAssertionsExtensions.cs +++ /dev/null @@ -1,52 +0,0 @@ -namespace FluentAssertions; - -/// -/// Contains extension methods for custom assertions in unit tests related to . -/// -[DebuggerNonUserCode] -public static class HeadersAssertionsExtensions -{ - /// - /// Asserts that an HTTP response has a named header. - /// - /// - /// The expected header with which the HTTP headers list is matched. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint HaveHeader( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - string expectedHeader, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).HaveHeader(expectedHeader, because, becauseArgs); - - /// - /// Asserts that an HTTP response does not have a named header. - /// - /// - /// The expected header with which the HTTP headers list is matched. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint NotHaveHeader( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - string expectedHeader, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).NotHaveHeader(expectedHeader, because, becauseArgs); -} \ No newline at end of file diff --git a/src/FluentAssertions.Web/HttpResponseContentAssertions.cs b/src/FluentAssertions.Web/HttpResponseContentAssertions.cs index 856cb75..8199eaa 100644 --- a/src/FluentAssertions.Web/HttpResponseContentAssertions.cs +++ b/src/FluentAssertions.Web/HttpResponseContentAssertions.cs @@ -18,14 +18,14 @@ public partial class HttpResponseMessageAssertions [CustomAssertion] public AndConstraint BeEmpty(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); var content = GetContent(); - Execute.Assertion + CurrentAssertionChain .ForCondition(string.IsNullOrEmpty(content)) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:response} to have no content. {0}", Subject); @@ -57,10 +57,9 @@ public AndConstraint BeAs(TModel expected /// The expected model. /// /// - /// A reference to the configuration object that can be used + /// A reference to the configuration object that can be used /// to influence the way the object graphs are compared. You can also provide an alternative instance of the - /// class. The global defaults are determined by the - /// class. + /// class. The global defaults are determined by the /// /// /// A formatted phrase as is supported by explaining why the assertion @@ -70,11 +69,11 @@ public AndConstraint BeAs(TModel expected /// Zero or more objects to format using the placeholders in . /// [CustomAssertion] - public AndConstraint BeAs(TModel expectedModel, Func, EquivalencyAssertionOptions> options, string because = "", params object[] becauseArgs) + public AndConstraint BeAs(TModel expectedModel, Func, EquivalencyOptions> options, string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(options, nameof(options)); - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -88,7 +87,7 @@ public AndConstraint BeAs(TModel expected var (success, errorMessage) = TryGetSubjectModel(out var subjectModel, expectedModelType); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(success) .FailWith("Expected {context:response} to have a content equivalent to a model of type {0}, but the JSON representation could not be parsed, as the operation failed with the following message: {2}{reason}. {1}", @@ -103,7 +102,7 @@ public AndConstraint BeAs(TModel expected failures = scope.Discard(); } - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(failures.Length == 0) .FailWith("Expected {context:response} to have a content equivalent to a model, but it has differences:{0}{reason}. {1}", @@ -135,7 +134,7 @@ public AndConstraint MatchInContent(string expect { Guard.ThrowIfArgumentIsNull(expectedWildcardText, nameof(expectedWildcardText), "Cannot verify a HTTP response content match a wildcard pattern."); - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -144,7 +143,7 @@ public AndConstraint MatchInContent(string expect if (string.IsNullOrEmpty(content)) { - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith("Expected {context:response} to match the wildcard pattern {0} in its content, but content was {reason}. {1}", expectedWildcardText, @@ -160,7 +159,7 @@ public AndConstraint MatchInContent(string expect failures = scope.Discard(); } - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(failures.Length == 0) .FailWith("Expected {context:response} to match a wildcard pattern in its content, but does not since:{0}{reason}. {1}", diff --git a/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs b/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs deleted file mode 100644 index c4babeb..0000000 --- a/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs +++ /dev/null @@ -1,99 +0,0 @@ -namespace FluentAssertions; - -/// -/// Contains extension methods for custom assertions in unit tests related to Http Response Content Assertions -/// -[DebuggerNonUserCode] -public static class HttpResponseContentAssertionsExtensions -{ - /// - /// Asserts that HTTP response content is empty - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint BeEmpty( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).BeEmpty(because, becauseArgs); - - /// - /// Asserts that HTTP response content can be an equivalent representation of the expected model. - /// - /// - /// The expected model. - /// - /// - /// A reference to the configuration object that can be used - /// to influence the way the object graphs are compared. You can also provide an alternative instance of the - /// class. The global defaults are determined by the - /// class. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint BeAs( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - TModel expectedModel, Func, EquivalencyAssertionOptions> options, string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).BeAs(expectedModel, options, because, becauseArgs); - - /// - /// Asserts that HTTP response content can be an equivalent representation of the expected model. - /// - /// - /// The expected model. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint BeAs( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - TModel expectedModel, string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).BeAs(expectedModel, because, becauseArgs); - - /// - /// Asserts that HTTP response has content that matches a wildcard pattern. - /// - /// - /// The wildcard pattern with which the subject is matched, where * and ? have special meanings. - /// - /// * - Matches any number of characters. You can use the asterisk (*) anywhere in a character string. Example: wh* finds what, white, and why, but not awhile or watch. - /// ? - Matches a single alphabet in a specific position. Example: b?ll finds ball, bell, and bill. - /// - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint MatchInContent( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string expectedWildcardText, string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).MatchInContent(expectedWildcardText, because, becauseArgs); -} diff --git a/src/FluentAssertions.Web/HttpResponseMessageAssertions.cs b/src/FluentAssertions.Web/HttpResponseMessageAssertions.cs index eedc382..f96c9c1 100644 --- a/src/FluentAssertions.Web/HttpResponseMessageAssertions.cs +++ b/src/FluentAssertions.Web/HttpResponseMessageAssertions.cs @@ -19,7 +19,8 @@ static HttpResponseMessageAssertions() /// class. /// /// The subject value to be asserted. - public HttpResponseMessageAssertions(HttpResponseMessage value) : base(value) { } + /// The assertion chain to build and manage assertions. + public HttpResponseMessageAssertions(HttpResponseMessage value, AssertionChain assertionChain) : base(value, assertionChain) { } /// /// Returns the type of the subject the assertion applies on. diff --git a/src/FluentAssertions.Web/HttpResponseMessageFluentAssertionsExtensions.cs b/src/FluentAssertions.Web/HttpResponseMessageFluentAssertionsExtensions.cs new file mode 100644 index 0000000..7a6d609 --- /dev/null +++ b/src/FluentAssertions.Web/HttpResponseMessageFluentAssertionsExtensions.cs @@ -0,0 +1,17 @@ +// ReSharper disable once CheckNamespace +namespace FluentAssertions +{ + /// + /// Contains extension methods for custom assertions in unit tests. + /// + [DebuggerNonUserCode] + public static class HttpResponseMessageFluentAssertionsExtensions + { + /// + /// Returns an object that can be used to assert the + /// current . + /// + public static HttpResponseMessageAssertions Should(this HttpResponseMessage? actual) + => new HttpResponseMessageAssertions(actual, AssertionChain.GetOrCreate()); + } +} \ No newline at end of file diff --git a/src/FluentAssertions.Web/HttpStatusCodeAssertions.cs b/src/FluentAssertions.Web/HttpStatusCodeAssertions.cs index 0f801ab..f73eb75 100644 --- a/src/FluentAssertions.Web/HttpStatusCodeAssertions.cs +++ b/src/FluentAssertions.Web/HttpStatusCodeAssertions.cs @@ -18,12 +18,12 @@ public partial class HttpResponseMessageAssertions // ReSharper disable once InconsistentNaming public AndConstraint Be1XXInformational(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(Subject!.StatusCode < HttpStatusCode.OK) .FailWith("Expected {context:response} to have a HTTP status code representing an informational error, but it was {0}{reason}.{1}", @@ -49,12 +49,12 @@ public AndConstraint Be1XXInformational(string be // ReSharper disable once InconsistentNaming public AndConstraint Be2XXSuccessful(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(Subject!.IsSuccessStatusCode) .FailWith("Expected {context:response} to have a successful HTTP status code, but it was {0}{reason}.{1}", @@ -80,12 +80,12 @@ public AndConstraint Be2XXSuccessful(string becau // ReSharper disable once InconsistentNaming public AndConstraint Be3XXRedirection(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(Subject!.StatusCode >= HttpStatusCode.Moved && Subject!.StatusCode < HttpStatusCode.BadRequest) .FailWith("Expected {context:response} to have a HTTP status code representing a redirection, but it was {0}{reason}.{1}", @@ -111,12 +111,12 @@ public AndConstraint Be3XXRedirection(string beca // ReSharper disable once InconsistentNaming public AndConstraint Be4XXClientError(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(Subject!.StatusCode >= HttpStatusCode.BadRequest && Subject!.StatusCode < HttpStatusCode.InternalServerError) .FailWith("Expected {context:response} to have a HTTP status code representing a client error, but it was {0}{reason}.{1}", @@ -142,12 +142,12 @@ public AndConstraint Be4XXClientError(string beca // ReSharper disable once InconsistentNaming public AndConstraint Be5XXServerError(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(Subject!.StatusCode >= HttpStatusCode.InternalServerError) .FailWith("Expected {context:response} to have a HTTP status code representing a server error, but it was {0}{reason}.{1}", @@ -174,12 +174,12 @@ public AndConstraint Be5XXServerError(string beca [CustomAssertion] public AndConstraint HaveHttpStatusCode(HttpStatusCode expected, string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(expected == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -205,12 +205,12 @@ public AndConstraint HaveHttpStatusCode(HttpStatu [CustomAssertion] public AndConstraint NotHaveHttpStatusCode(HttpStatusCode unexpected, string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(unexpected != Subject!.StatusCode) .FailWith("Did not expect {context:response} to have status {0}{reason}.{1}", @@ -233,12 +233,12 @@ public AndConstraint NotHaveHttpStatusCode(HttpSt [CustomAssertion] public AndConstraint Be100Continue(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Continue == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -259,12 +259,12 @@ public AndConstraint Be100Continue(string because [CustomAssertion] public AndConstraint Be101SwitchingProtocols(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.SwitchingProtocols == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -285,12 +285,12 @@ public AndConstraint Be101SwitchingProtocols(stri [CustomAssertion] public AndConstraint Be200Ok(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.OK == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -311,12 +311,12 @@ public AndConstraint Be200Ok(string because = "", [CustomAssertion] public AndConstraint Be201Created(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Created == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -337,12 +337,12 @@ public AndConstraint Be201Created(string because [CustomAssertion] public AndConstraint Be202Accepted(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Accepted == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -363,12 +363,12 @@ public AndConstraint Be202Accepted(string because [CustomAssertion] public AndConstraint Be203NonAuthoritativeInformation(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.NonAuthoritativeInformation == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -389,12 +389,12 @@ public AndConstraint Be203NonAuthoritativeInforma [CustomAssertion] public AndConstraint Be204NoContent(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.NoContent == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -415,12 +415,12 @@ public AndConstraint Be204NoContent(string becaus [CustomAssertion] public AndConstraint Be205ResetContent(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.ResetContent == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -441,12 +441,12 @@ public AndConstraint Be205ResetContent(string bec [CustomAssertion] public AndConstraint Be206PartialContent(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.PartialContent == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -467,12 +467,12 @@ public AndConstraint Be206PartialContent(string b [CustomAssertion] public AndConstraint Be300MultipleChoices(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.MultipleChoices == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -493,12 +493,12 @@ public AndConstraint Be300MultipleChoices(string [CustomAssertion] public AndConstraint Be300Ambiguous(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Ambiguous == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -519,12 +519,12 @@ public AndConstraint Be300Ambiguous(string becaus [CustomAssertion] public AndConstraint Be301MovedPermanently(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.MovedPermanently == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -545,12 +545,12 @@ public AndConstraint Be301MovedPermanently(string [CustomAssertion] public AndConstraint Be301Moved(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Moved == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -571,12 +571,12 @@ public AndConstraint Be301Moved(string because = [CustomAssertion] public AndConstraint Be302Found(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Found == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -597,12 +597,12 @@ public AndConstraint Be302Found(string because = [CustomAssertion] public AndConstraint Be302Redirect(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Redirect == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -623,12 +623,12 @@ public AndConstraint Be302Redirect(string because [CustomAssertion] public AndConstraint Be303SeeOther(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.SeeOther == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -649,12 +649,12 @@ public AndConstraint Be303SeeOther(string because [CustomAssertion] public AndConstraint Be303RedirectMethod(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.RedirectMethod == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -675,12 +675,12 @@ public AndConstraint Be303RedirectMethod(string b [CustomAssertion] public AndConstraint Be304NotModified(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.NotModified == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -701,12 +701,12 @@ public AndConstraint Be304NotModified(string beca [CustomAssertion] public AndConstraint Be305UseProxy(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.UseProxy == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -727,12 +727,12 @@ public AndConstraint Be305UseProxy(string because [CustomAssertion] public AndConstraint Be306Unused(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Unused == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -753,12 +753,12 @@ public AndConstraint Be306Unused(string because = [CustomAssertion] public AndConstraint Be307TemporaryRedirect(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.TemporaryRedirect == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -779,12 +779,12 @@ public AndConstraint Be307TemporaryRedirect(strin [CustomAssertion] public AndConstraint Be307RedirectKeepVerb(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.RedirectKeepVerb == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -805,17 +805,17 @@ public AndConstraint Be307RedirectKeepVerb(string [CustomAssertion] public AndConstraint Be400BadRequest(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.BadRequest == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" , HttpStatusCode.BadRequest, Subject!.StatusCode, Subject); - return new AndConstraint(new BadRequestAssertions(Subject)); + return new AndConstraint(new BadRequestAssertions(Subject, CurrentAssertionChain)); } /// @@ -831,12 +831,12 @@ public AndConstraint Be400BadRequest(string because = "", [CustomAssertion] public AndConstraint Be401Unauthorized(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Unauthorized == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -857,12 +857,12 @@ public AndConstraint Be401Unauthorized(string bec [CustomAssertion] public AndConstraint Be402PaymentRequired(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.PaymentRequired == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -883,12 +883,12 @@ public AndConstraint Be402PaymentRequired(string [CustomAssertion] public AndConstraint Be403Forbidden(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Forbidden == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -909,12 +909,12 @@ public AndConstraint Be403Forbidden(string becaus [CustomAssertion] public AndConstraint Be404NotFound(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.NotFound == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -935,12 +935,12 @@ public AndConstraint Be404NotFound(string because [CustomAssertion] public AndConstraint Be405MethodNotAllowed(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.MethodNotAllowed == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -961,12 +961,12 @@ public AndConstraint Be405MethodNotAllowed(string [CustomAssertion] public AndConstraint Be406NotAcceptable(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.NotAcceptable == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -987,12 +987,12 @@ public AndConstraint Be406NotAcceptable(string be [CustomAssertion] public AndConstraint Be407ProxyAuthenticationRequired(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.ProxyAuthenticationRequired == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1013,12 +1013,12 @@ public AndConstraint Be407ProxyAuthenticationRequ [CustomAssertion] public AndConstraint Be408RequestTimeout(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.RequestTimeout == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1039,12 +1039,12 @@ public AndConstraint Be408RequestTimeout(string b [CustomAssertion] public AndConstraint Be409Conflict(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Conflict == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1065,12 +1065,12 @@ public AndConstraint Be409Conflict(string because [CustomAssertion] public AndConstraint Be410Gone(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Gone == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1091,12 +1091,12 @@ public AndConstraint Be410Gone(string because = " [CustomAssertion] public AndConstraint Be411LengthRequired(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.LengthRequired == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1117,12 +1117,12 @@ public AndConstraint Be411LengthRequired(string b [CustomAssertion] public AndConstraint Be412PreconditionFailed(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.PreconditionFailed == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1143,12 +1143,12 @@ public AndConstraint Be412PreconditionFailed(stri [CustomAssertion] public AndConstraint Be413RequestEntityTooLarge(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.RequestEntityTooLarge == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1169,12 +1169,12 @@ public AndConstraint Be413RequestEntityTooLarge(s [CustomAssertion] public AndConstraint Be414RequestUriTooLong(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.RequestUriTooLong == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1195,12 +1195,12 @@ public AndConstraint Be414RequestUriTooLong(strin [CustomAssertion] public AndConstraint Be415UnsupportedMediaType(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.UnsupportedMediaType == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1221,12 +1221,12 @@ public AndConstraint Be415UnsupportedMediaType(st [CustomAssertion] public AndConstraint Be416RequestedRangeNotSatisfiable(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.RequestedRangeNotSatisfiable == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1247,12 +1247,12 @@ public AndConstraint Be416RequestedRangeNotSatisf [CustomAssertion] public AndConstraint Be417ExpectationFailed(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.ExpectationFailed == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1273,12 +1273,12 @@ public AndConstraint Be417ExpectationFailed(strin [CustomAssertion] public AndConstraint Be422UnprocessableEntity(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(422 == (int)Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1299,12 +1299,12 @@ public AndConstraint Be422UnprocessableEntity(str [CustomAssertion] public AndConstraint Be429TooManyRequests(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(429 == (int)Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1325,12 +1325,12 @@ public AndConstraint Be429TooManyRequests(string [CustomAssertion] public AndConstraint Be426UpgradeRequired(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.UpgradeRequired == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1351,12 +1351,12 @@ public AndConstraint Be426UpgradeRequired(string [CustomAssertion] public AndConstraint Be500InternalServerError(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.InternalServerError == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1377,12 +1377,12 @@ public AndConstraint Be500InternalServerError(str [CustomAssertion] public AndConstraint Be501NotImplemented(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.NotImplemented == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1403,12 +1403,12 @@ public AndConstraint Be501NotImplemented(string b [CustomAssertion] public AndConstraint Be502BadGateway(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.BadGateway == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1429,12 +1429,12 @@ public AndConstraint Be502BadGateway(string becau [CustomAssertion] public AndConstraint Be503ServiceUnavailable(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.ServiceUnavailable == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1455,12 +1455,12 @@ public AndConstraint Be503ServiceUnavailable(stri [CustomAssertion] public AndConstraint Be504GatewayTimeout(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.GatewayTimeout == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1481,12 +1481,12 @@ public AndConstraint Be504GatewayTimeout(string b [CustomAssertion] public AndConstraint Be505HttpVersionNotSupported(string because = "", params object[] becauseArgs) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.HttpVersionNotSupported == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" diff --git a/src/FluentAssertions.Web/HttpStatusCodeAssertionsExtensions.cs b/src/FluentAssertions.Web/HttpStatusCodeAssertionsExtensions.cs deleted file mode 100644 index e317e7b..0000000 --- a/src/FluentAssertions.Web/HttpStatusCodeAssertionsExtensions.cs +++ /dev/null @@ -1,1048 +0,0 @@ -// ReSharper disable once CheckNamespace -namespace FluentAssertions; - -/// -/// Contains extension methods for custom assertions in unit tests related to . -/// -public static class HttpStatusCodeAssertionsExtensions -{ - #region Be1XXInformational - /// - /// Asserts that a HTTP response has a HTTP status code representing an informational response. - /// - /// The HTTP response was an informational one if was in the range 100-199. - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - // ReSharper disable once InconsistentNaming - public static AndConstraint Be1XXInformational( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be1XXInformational(because, becauseArgs); - #endregion - - #region Be2XXSuccessful - /// - /// Asserts that a HTTP response has a successful HTTP status code. - /// - /// The HTTP response was successful if was in the range 200-299. - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - // ReSharper disable once InconsistentNaming - public static AndConstraint Be2XXSuccessful( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be2XXSuccessful(because, becauseArgs); - #endregion - - #region Be3XXRedirection - /// - /// Asserts that a HTTP response has a HTTP status code representing a redirection response. - /// - /// The HTTP response was an informational one if was in the range 300-399. - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - // ReSharper disable once InconsistentNaming - public static AndConstraint Be3XXRedirection( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be3XXRedirection(because, becauseArgs); - #endregion - - #region Be4XXClientError - /// - /// Asserts that a HTTP response has a HTTP status code representing a client error. - /// - /// The HTTP response was a client error if was in the range 400-499. - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - // ReSharper disable once InconsistentNaming - public static AndConstraint Be4XXClientError( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be4XXClientError(because, becauseArgs); - #endregion - - #region Be5XXServerError - /// - /// Asserts that a HTTP response has a HTTP status code representing a server error. - /// - /// The HTTP response was a server error if was above 500. - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - // ReSharper disable once InconsistentNaming - public static AndConstraint Be5XXServerError( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be5XXServerError(because, becauseArgs); - #endregion - - #region HaveHtppStatus - /// - /// Asserts that a HTTP response has a HTTP status with the specified code. - /// - /// - /// The code of the expected HTTP Status. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint HaveHttpStatusCode( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - HttpStatusCode expected, string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).HaveHttpStatusCode(expected, because, becauseArgs); - #endregion - - #region NotHaveHtppStatus - /// - /// Asserts that a HTTP response does not have a HTTP status with the specified code. - /// - /// - /// The code of the unexpected HTTP Status. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint NotHaveHttpStatusCode( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - HttpStatusCode unexpected, string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).NotHaveHttpStatusCode(unexpected, because, becauseArgs); - #endregion - - #region BeXXXHttpStatus - /// - /// Asserts that a HTTP response has the HTTP status 100 Continue - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be100Continue( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be100Continue(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 101 Switching Protocols - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be101SwitchingProtocols( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be101SwitchingProtocols(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 200 Ok - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be200Ok( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be200Ok(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 201 Created - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be201Created( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be201Created(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 202 Accepted - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be202Accepted( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be202Accepted(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 203 Non Authoritative Information - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be203NonAuthoritativeInformation( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be203NonAuthoritativeInformation(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 204 No Content - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be204NoContent( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be204NoContent(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 205 Reset Content - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be205ResetContent( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be205ResetContent(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 206 Partial Content - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be206PartialContent( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be206PartialContent(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 300 Multiple Choices - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be300MultipleChoices( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be300MultipleChoices(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 300 Ambiguous - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be300Ambiguous( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be300Ambiguous(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 301 Moved Permanently - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be301MovedPermanently( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be301MovedPermanently(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 301 Moved - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be301Moved( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be301Moved(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 302 Found - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be302Found( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be302Found(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 302 Redirect - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be302Redirect( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be302Redirect(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 303 See Other - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be303SeeOther( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be303SeeOther(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 303 Redirect Method - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be303RedirectMethod( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be303RedirectMethod(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 304 Not Modified - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be304NotModified( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be304NotModified(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 305 Use Proxy - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be305UseProxy( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be305UseProxy(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 306 Unused - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be306Unused( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be306Unused(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 307 Temporary Redirect - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be307TemporaryRedirect( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be307TemporaryRedirect(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 307 Redirect Keep Verb - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be307RedirectKeepVerb( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be307RedirectKeepVerb(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 400 BadRequest - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be400BadRequest( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new BadRequestAssertions(parent.Subject).Be400BadRequest(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 401 Unauthorized - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be401Unauthorized( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be401Unauthorized(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 402 Payment Required - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be402PaymentRequired( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be402PaymentRequired(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 403 Forbidden - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be403Forbidden( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be403Forbidden(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 404 Not Found - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be404NotFound( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be404NotFound(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 405 Method Not Allowed - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be405MethodNotAllowed( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be405MethodNotAllowed(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 406 Not Acceptable - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be406NotAcceptable( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be406NotAcceptable(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 407 Proxy Authentication Required - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be407ProxyAuthenticationRequired( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be407ProxyAuthenticationRequired(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 408 Request Timeout - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be408RequestTimeout( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be408RequestTimeout(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 409 Conflict - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be409Conflict( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be409Conflict(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 410 Gone - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be410Gone( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be410Gone(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 411 Length Required - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be411LengthRequired( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be411LengthRequired(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 412 Precondition Failed - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be412PreconditionFailed( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be412PreconditionFailed(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 413 Request Entity Too Large - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be413RequestEntityTooLarge( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be413RequestEntityTooLarge(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 414 Request Uri Too Long - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be414RequestUriTooLong( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be414RequestUriTooLong(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 415 Unsupported Media Type - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be415UnsupportedMediaType( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be415UnsupportedMediaType(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 416 Requested Range Not Satisfiable - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be416RequestedRangeNotSatisfiable( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be416RequestedRangeNotSatisfiable(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 417 Expectation Failed - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be417ExpectationFailed( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be417ExpectationFailed(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 422 UnprocessableEntity - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be422UnprocessableEntity( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be422UnprocessableEntity(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 429 TooManyRequests - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be429TooManyRequests( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be429TooManyRequests(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 426 UpgradeRequired - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be426UpgradeRequired( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be426UpgradeRequired(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 500 Internal Server Error - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be500InternalServerError( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be500InternalServerError(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 501 Not Implemented - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be501NotImplemented( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be501NotImplemented(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 502 Bad Gateway - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be502BadGateway( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be502BadGateway(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 503 Service Unavailable - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be503ServiceUnavailable( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be503ServiceUnavailable(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 504 Gateway Timeout - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be504GatewayTimeout( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be504GatewayTimeout(because, becauseArgs); - - /// - /// Asserts that a HTTP response has the HTTP status 505 Http Version Not Supported - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Be505HttpVersionNotSupported( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Be505HttpVersionNotSupported(because, becauseArgs); - #endregion -} diff --git a/src/FluentAssertions.Web/SatisfyHttpResponseMessageAssertions.cs b/src/FluentAssertions.Web/SatisfyHttpResponseMessageAssertions.cs index 6c25f17..2450276 100644 --- a/src/FluentAssertions.Web/SatisfyHttpResponseMessageAssertions.cs +++ b/src/FluentAssertions.Web/SatisfyHttpResponseMessageAssertions.cs @@ -24,7 +24,7 @@ public AndConstraint Satisfy(Action."); @@ -33,7 +33,7 @@ public AndConstraint Satisfy(Action Satisfy(Func."); @@ -78,7 +78,7 @@ public AndConstraint Satisfy(Func -/// Contains extension methods for custom assertions in unit tests related to Http Response Message. -/// -[DebuggerNonUserCode] -public static class SatisfyHttpResponseMessageAssertionsExtensions -{ - /// - /// Asserts that an HTTP response satisfies an assertion. - /// - /// - /// An assertion about the HTTP response. - /// - /// - /// The assertion can be a single assertion or a collection of assertions if the assertion action is expressed as a statement lambda. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Satisfy( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - Action assertion, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Satisfy(assertion, because, becauseArgs); - - /// - /// Asserts that an HTTP response satisfies an asynchronous assertion. - /// - /// - /// An assertion about the HTTP response. - /// - /// - /// The assertion can be a single assertion or a collection of assertions if the assertion action is expressed as a statement lambda. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Satisfy( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573, - Func assertion, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Satisfy(assertion, because, becauseArgs); -} diff --git a/src/FluentAssertions.Web/SatisfyModelAssertions.cs b/src/FluentAssertions.Web/SatisfyModelAssertions.cs index d3efcb5..22d4c4c 100644 --- a/src/FluentAssertions.Web/SatisfyModelAssertions.cs +++ b/src/FluentAssertions.Web/SatisfyModelAssertions.cs @@ -26,7 +26,7 @@ public AndConstraint Satisfy( Guard.ThrowIfArgumentIsNull(assertion, nameof(assertion), "Cannot verify the subject satisfies a `null` assertion."); - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -35,7 +35,7 @@ public AndConstraint Satisfy( Type? modelType = typeof(TModel); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(success) .FailWith("Expected {context:response} to have a content equivalent to a model of type {0}, but the JSON representation could not be parsed, as the operation failed with the following message: {2}{reason}. {1}", @@ -45,7 +45,7 @@ public AndConstraint Satisfy( if (failuresFromAssertions.Any()) { - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith( "Expected {context:response} to satisfy one or more model assertions, but it wasn't{reason}: {0}{1}", @@ -83,7 +83,7 @@ public AndConstraint Satisfy(TModel given { Guard.ThrowIfArgumentIsNull(assertion, nameof(assertion), "Cannot verify the subject satisfies a `null` assertion."); - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -92,7 +92,7 @@ public AndConstraint Satisfy(TModel given Type? modelType = typeof(TModel); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(success) .FailWith("Expected {context:response} to have a content equivalent to a model of type {0}, but the JSON representation could not be parsed, as the operation failed with the following message: {2}{reason}. {1}", @@ -102,7 +102,7 @@ public AndConstraint Satisfy(TModel given if (failuresFromAssertions.Any()) { - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith( "Expected {context:response} to satisfy one or more model assertions, but it wasn't{reason}: {0}{1}", @@ -136,7 +136,7 @@ public AndConstraint Satisfy( Guard.ThrowIfArgumentIsNull(assertion, nameof(assertion), "Cannot verify the subject satisfies a `null` assertion."); - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -153,7 +153,7 @@ public AndConstraint Satisfy( Type? modelType = typeof(TModel); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(success) .FailWith("Expected {context:response} to have a content equivalent to a model of type {0}, but the JSON representation could not be parsed, as the operation failed with the following message: {2}{reason}. {1}", @@ -163,7 +163,7 @@ public AndConstraint Satisfy( if (failuresFromAssertions.Any()) { - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith( "Expected {context:response} to satisfy one or more model assertions, but it wasn't{reason}: {0}{1}", @@ -201,7 +201,7 @@ public AndConstraint Satisfy(TModel given { Guard.ThrowIfArgumentIsNull(assertion, nameof(assertion), "Cannot verify the subject satisfies a `null` assertion."); - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -218,7 +218,7 @@ public AndConstraint Satisfy(TModel given Type? modelType = typeof(TModel); - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .ForCondition(success) .FailWith("Expected {context:response} to have a content equivalent to a model of type {0}, but the JSON representation could not be parsed, as the operation failed with the following message: {2}{reason}. {1}", @@ -228,7 +228,7 @@ public AndConstraint Satisfy(TModel given if (failuresFromAssertions.Any()) { - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith( "Expected {context:response} to satisfy one or more model assertions, but it wasn't{reason}: {0}{1}", diff --git a/src/FluentAssertions.Web/SatisfyModelAssertionsExtensions.cs b/src/FluentAssertions.Web/SatisfyModelAssertionsExtensions.cs deleted file mode 100644 index 5fd132c..0000000 --- a/src/FluentAssertions.Web/SatisfyModelAssertionsExtensions.cs +++ /dev/null @@ -1,117 +0,0 @@ -// ReSharper disable once CheckNamespace -namespace FluentAssertions; - -/// -/// Contains extension methods for custom assertions in unit tests related to Http Response Message. -/// -[DebuggerNonUserCode] -public static class SatisfyModelAssertionsExtensions -{ - /// - /// Asserts that an HTTP response content can be a model that satisfies an assertion. - /// - /// - /// An assertion regarding the given model. - /// - /// - /// The assertion can be a single assertion or a collection of assertions if the assertion action is expressed as a statement lambda. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Satisfy( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - Action assertion, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Satisfy(assertion, because, becauseArgs); - - /// - /// Asserts that an HTTP response content can be a model that satisfies an assertion starting from an inferred model structure. - /// - /// - /// A proposed model structure that will help to compose the assertions. This is used to defined the type of the asserted model and it doesn't have to contain other values than the default one. - /// - /// - /// The assertion can be a single assertion or a collection of assertions if the assertion action is expressed as a statement lambda. - /// - /// - /// An assertion or a collection of assertions regarding the given model. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Satisfy( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - TModel givenModelStructure, - Action assertion, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Satisfy(givenModelStructure, assertion, because, becauseArgs); - - /// - /// Asserts that an HTTP response content can be a model that satisfies an asynchronous assertion. - /// - /// - /// An assertion regarding the given model. - /// - /// - /// The assertion can be a single assertion or a collection of assertions if the assertion action is expressed as a statement lambda. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Satisfy( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - Func assertion, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Satisfy(assertion, because, becauseArgs); - - /// - /// Asserts that an HTTP response content can be a model that satisfies an asynchronous assertion starting from an inferred model structure. - /// - /// - /// A proposed model structure that will help to compose the assertions. This is used to defined the type of the asserted model and it doesn't have to contain other values than the default one. - /// - /// - /// The assertion can be a single assertion or a collection of assertions if the assertion action is expressed as a statement lambda. - /// - /// - /// An assertion or a collection of assertions regarding the given model. - /// - /// - /// A formatted phrase as is supported by explaining why the assertion - /// is needed. If the phrase does not start with the word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in . - /// - [CustomAssertion] - public static AndConstraint Satisfy( -#pragma warning disable 1573 - this Primitives.HttpResponseMessageAssertions parent, -#pragma warning restore 1573 - TModel givenModelStructure, - Func assertion, - string because = "", params object[] becauseArgs) - => new HttpResponseMessageAssertions(parent.Subject).Satisfy(givenModelStructure, assertion, because, becauseArgs); -} diff --git a/test/FluentAssertions.Web.Tests/DeserializationExceptionTests.cs b/test/FluentAssertions.Web.Tests/DeserializationExceptionTests.cs index bc81292..e1aa93d 100644 --- a/test/FluentAssertions.Web.Tests/DeserializationExceptionTests.cs +++ b/test/FluentAssertions.Web.Tests/DeserializationExceptionTests.cs @@ -31,16 +31,4 @@ public void Ctor_WhenInnerException_DoesNotThrow() // Assert act.Should().NotThrow(); } - -#if !NET8_0_OR_GREATER - [Fact] - public void Exception_ShouldBeBinarySerializable() - { - // Arrange - var sut = new DeserializationException("Exception message", new Exception()); - - // Assert - sut.Should().BeBinarySerializable(); - } -#endif } diff --git a/test/FluentAssertions.Web.Tests/HeadersAssertionsSpecs.cs b/test/FluentAssertions.Web.Tests/HeadersAssertionsSpecs.cs index 5327f7c..ebc084a 100644 --- a/test/FluentAssertions.Web.Tests/HeadersAssertionsSpecs.cs +++ b/test/FluentAssertions.Web.Tests/HeadersAssertionsSpecs.cs @@ -404,7 +404,7 @@ public void When_asserting_response_with_header_with_multiple_values_indicated_b // Assert act.Should().Throw() - .WithMessage("*the *custom-header* HTTP header*value to be equivalent to*value1*but*value1,value2*differs*reason*"); + .WithMessage("*the*custom-header*HTTP header*equivalent*but they differ at*value1,value2*value1*reason*"); } [Fact] @@ -425,7 +425,7 @@ public void When_asserting_response_with_header_without_some_value_to_be_differe // Assert act.Should().Throw() - .WithMessage("*the *custom-header* HTTP header*value to be equivalent to*other-than-value1*but*value1*differs*reason*"); + .WithMessage("*the *custom-header* HTTP header*value* to be equivalent to the same string, but they differ at*reason*"); } [Fact] diff --git a/test/FluentAssertions.Web.Tests/HttpResponseContentAssertionsSpecs.cs b/test/FluentAssertions.Web.Tests/HttpResponseContentAssertionsSpecs.cs index b9aa8f6..79f5bd0 100644 --- a/test/FluentAssertions.Web.Tests/HttpResponseContentAssertionsSpecs.cs +++ b/test/FluentAssertions.Web.Tests/HttpResponseContentAssertionsSpecs.cs @@ -339,7 +339,7 @@ public void When_asserting_response_to_be_as_model_with_null_equivalency_asserti // Act Action act = () => - subject.Should().BeAs(new { }, options: (Func, EquivalencyAssertionOptions>)(null!)); + subject.Should().BeAs(new { }, options: (Func, EquivalencyOptions>)(null!)); // Assert act.Should().Throw() diff --git a/test/FluentAssertions.Web.Tests/Internal/ApiAccessibilityTests.cs b/test/FluentAssertions.Web.Tests/Internal/ApiAccessibilityTests.cs index 176706f..38d881f 100644 --- a/test/FluentAssertions.Web.Tests/Internal/ApiAccessibilityTests.cs +++ b/test/FluentAssertions.Web.Tests/Internal/ApiAccessibilityTests.cs @@ -49,46 +49,6 @@ public void ThereShouldAlways_Be_Assertions_Extensions_Ending_With_The_Assertion assertionsExtensionsTypes.Should().NotBeEmpty(); } - [Fact] - public void Each_HttpResponseMessage_Assertion_ShouldHaveAnExtensionOverPrimitivesHttpResponseMessageAssertions() - { - // Arrange - var baseAssertionsType = typeof(ReferenceTypeAssertions); - var httpResponseMessageAssertions = typeof(HttpResponseMessageAssertions).Assembly - .GetTypes() - .Where(c => c.BaseType == baseAssertionsType) - .ToList(); - httpResponseMessageAssertions.Should().NotBeEmpty(); - - var allExtensions = typeof(HttpResponseMessageAssertions).Assembly - .GetTypes() - .Where(c => c.Name.EndsWith("AssertionsExtensions")) - .SelectMany(c => c.GetMethods(BindingFlags.Static | BindingFlags.Public)) - .ToList(); - - // Assert - foreach (var assertionType in httpResponseMessageAssertions) - { - foreach (var assertionMethod in assertionType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) - { - allExtensions.Should().Contain(extensionMethod => - extensionMethod.Name == assertionMethod.Name - && extensionMethod.ReturnType.GetType() == assertionMethod.ReturnType.GetType() - && SameParameters(extensionMethod, assertionMethod), - "\n we wanted to check \n" + - "the assertion method {0} \n" + - "from assertion type {1} \n" + - "and return type {2} \n" + - "and arguments {3} \n" + - "has a corresponding extension method", - assertionMethod.Name, - assertionType.FullName, - assertionMethod.ReturnType.FullName, - string.Join(", ", assertionMethod.GetParameters().Select(c => $"{c.Name} of type {c.ParameterType.FullName}"))); - } - } - } - [Fact] public void Each_HttpResponseMessage_Assertion_Should_Have_The_CustomAssertion_Attribute() { @@ -106,20 +66,6 @@ public void Each_HttpResponseMessage_Assertion_Should_Have_The_CustomAssertion_A .Should().AllSatisfy(method => method.Should().BeDecoratedWith()); } - [Fact] - public void Each_HttpResponseMessage_Assertion_Extension_Should_Have_The_CustomAssertion_Attribute() - { - // Arrange - var allExtensions = typeof(HttpResponseMessageAssertions).Assembly - .GetTypes() - .Where(c => c.Name.EndsWith("AssertionsExtensions")) - .SelectMany(c => c.GetMethods(BindingFlags.Static | BindingFlags.Public)) - .ToList(); - - // Assert - allExtensions.Should().AllSatisfy(method => method.Should().BeDecoratedWith()); - } - [Fact] public void Each_HttpResponseMessage_Assertion_Extension_Should_Be_In_The_Fluent_Assertions_Namespace_Only() { From d3a6e419a227614752dd98fd65b86cd3122e963b Mon Sep 17 00:00:00 2001 From: Adrian Iftode Date: Mon, 20 Jan 2025 22:31:14 +0000 Subject: [PATCH 4/4] Use one source, resolve versions by preprocessor directives --- Directory.Packages.props | 2 +- FluentAssertions.Web.sln | 28 + appveyor.yml | 2 +- readme.md | 30 +- src/Directory.Build.props | 4 - ...ions.Web.Serializers.NewtonsoftJson.csproj | 5 +- .../DeserializationException.cs | 1 + .../FluentAssertions.Web.Types.csproj | 5 + .../FluentAssertionsWebConfig.cs | 0 .../GlobalUsings.cs | 5 + .../ISerializer.cs | 4 + .../Serializers/SystemTextJsonSerializer.cs | 0 .../Properties/AssemblyInfo.cs | 5 + .../SystemTextJsonSerializerConfig.cs | 0 .../FluentAssertions.Web.v8.csproj | 31 + .../Properties/AssemblyInfo.cs | 3 + .../BadRequestAssertions.cs | 37 +- .../BadRequestAssertionsExtensions.cs | 113 ++ .../FluentAssertions.Web.csproj | 13 +- .../HaveHeaderAssertions.cs | 46 +- .../HaveHeaderAssertionsExtensions.cs | 56 + .../HttpResponseContentAssertions.cs | 42 +- ...HttpResponseContentAssertionsExtensions.cs | 102 ++ .../HttpResponseMessageAssertions.cs | 7 +- ...sponseMessageFluentAssertionsExtensions.cs | 6 +- .../HttpStatusCodeAssertions.cs | 454 ++++++- .../HttpStatusCodeAssertionsExtensions.cs | 1050 +++++++++++++++++ .../Properties/AssemblyInfo.cs | 1 - .../SatisfyHttpResponseMessageAssertions.cs | 20 +- ...HttpResponseMessageAssertionsExtensions.cs | 61 + .../SatisfyModelAssertions.cs | 56 +- .../SatisfyModelAssertionsExtensions.cs | 119 ++ test/Directory.Build.props | 1 - ...Web.FluentAssertionsWebConfig.Tests.csproj | 6 +- ...eb.Serializers.NewtonsoftJson.Tests.csproj | 5 + .../FluentAssertions.Web.Tests.csproj | 4 + .../HeadersAssertionsSpecs.cs | 4 +- .../HttpResponseContentAssertionsSpecs.cs | 6 +- .../Internal/ApiAccessibilityTests.cs | 57 + .../FallbackProcessorTests.cs | 1 - .../FluentAssertions.Web.v8.Tests.csproj | 22 + .../CommentsControllerTests.cs | 1 + .../Sample.Api.v8.Tests.csproj | 33 + 43 files changed, 2409 insertions(+), 39 deletions(-) rename src/{FluentAssertions.Web => FluentAssertions.Web.Types}/DeserializationException.cs (99%) create mode 100644 src/FluentAssertions.Web.Types/FluentAssertions.Web.Types.csproj rename src/{FluentAssertions.Web => FluentAssertions.Web.Types}/FluentAssertionsWebConfig.cs (100%) create mode 100644 src/FluentAssertions.Web.Types/GlobalUsings.cs rename src/{FluentAssertions.Web => FluentAssertions.Web.Types}/ISerializer.cs (90%) rename src/{FluentAssertions.Web => FluentAssertions.Web.Types}/Internal/Serializers/SystemTextJsonSerializer.cs (100%) create mode 100644 src/FluentAssertions.Web.Types/Properties/AssemblyInfo.cs rename src/{FluentAssertions.Web => FluentAssertions.Web.Types}/SystemTextJsonSerializerConfig.cs (100%) create mode 100644 src/FluentAssertions.Web.v8/FluentAssertions.Web.v8.csproj create mode 100644 src/FluentAssertions.Web.v8/Properties/AssemblyInfo.cs create mode 100644 src/FluentAssertions.Web/BadRequestAssertionsExtensions.cs create mode 100644 src/FluentAssertions.Web/HaveHeaderAssertionsExtensions.cs create mode 100644 src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs create mode 100644 src/FluentAssertions.Web/HttpStatusCodeAssertionsExtensions.cs create mode 100644 src/FluentAssertions.Web/SatisfyHttpResponseMessageAssertionsExtensions.cs create mode 100644 src/FluentAssertions.Web/SatisfyModelAssertionsExtensions.cs create mode 100644 test/FluentAssertions.Web.v8.Tests/FluentAssertions.Web.v8.Tests.csproj create mode 100644 test/Sample.Api.v8.Tests/Sample.Api.v8.Tests.csproj diff --git a/Directory.Packages.props b/Directory.Packages.props index 769b5d4..3842892 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,7 +6,7 @@ - + diff --git a/FluentAssertions.Web.sln b/FluentAssertions.Web.sln index d9605ed..b13b697 100644 --- a/FluentAssertions.Web.sln +++ b/FluentAssertions.Web.sln @@ -46,6 +46,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.Api.Net80", "samples EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.Api.Net90", "samples\Sample.Api.Net90\Sample.Api.Net90.csproj", "{73E11379-908A-4BA0-9365-AE800A88C39B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentAssertions.Web.v8", "src\FluentAssertions.Web.v8\FluentAssertions.Web.v8.csproj", "{3872DF64-5DA9-4983-90D8-2802A0A26CFE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.Api.v8.Tests", "test\Sample.Api.v8.Tests\Sample.Api.v8.Tests.csproj", "{EBB6D06F-B87F-4BDA-8F1B-A6E88C96C2E1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentAssertions.Web.v8.Tests", "test\FluentAssertions.Web.v8.Tests\FluentAssertions.Web.v8.Tests.csproj", "{056E517C-F644-4B8A-9494-09276E6E3C6B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentAssertions.Web.Types", "src\FluentAssertions.Web.Types\FluentAssertions.Web.Types.csproj", "{455E5F41-B678-4286-BB4D-FC232D08CAC0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -84,6 +92,22 @@ Global {73E11379-908A-4BA0-9365-AE800A88C39B}.Debug|Any CPU.Build.0 = Debug|Any CPU {73E11379-908A-4BA0-9365-AE800A88C39B}.Release|Any CPU.ActiveCfg = Release|Any CPU {73E11379-908A-4BA0-9365-AE800A88C39B}.Release|Any CPU.Build.0 = Release|Any CPU + {3872DF64-5DA9-4983-90D8-2802A0A26CFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3872DF64-5DA9-4983-90D8-2802A0A26CFE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3872DF64-5DA9-4983-90D8-2802A0A26CFE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3872DF64-5DA9-4983-90D8-2802A0A26CFE}.Release|Any CPU.Build.0 = Release|Any CPU + {EBB6D06F-B87F-4BDA-8F1B-A6E88C96C2E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EBB6D06F-B87F-4BDA-8F1B-A6E88C96C2E1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EBB6D06F-B87F-4BDA-8F1B-A6E88C96C2E1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EBB6D06F-B87F-4BDA-8F1B-A6E88C96C2E1}.Release|Any CPU.Build.0 = Release|Any CPU + {056E517C-F644-4B8A-9494-09276E6E3C6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {056E517C-F644-4B8A-9494-09276E6E3C6B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {056E517C-F644-4B8A-9494-09276E6E3C6B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {056E517C-F644-4B8A-9494-09276E6E3C6B}.Release|Any CPU.Build.0 = Release|Any CPU + {455E5F41-B678-4286-BB4D-FC232D08CAC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {455E5F41-B678-4286-BB4D-FC232D08CAC0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {455E5F41-B678-4286-BB4D-FC232D08CAC0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {455E5F41-B678-4286-BB4D-FC232D08CAC0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -98,6 +122,10 @@ Global {538479CE-5922-4FF9-A09D-80C9E91FFFF1} = {BFF7517A-C9EA-458D-829E-28A10F8D61BF} {9B53847C-0D39-46AB-9E39-A2DCA0676D88} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9} {73E11379-908A-4BA0-9365-AE800A88C39B} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9} + {3872DF64-5DA9-4983-90D8-2802A0A26CFE} = {14FDD52D-B83A-445B-BD2F-04B3E7B8033C} + {EBB6D06F-B87F-4BDA-8F1B-A6E88C96C2E1} = {BFF7517A-C9EA-458D-829E-28A10F8D61BF} + {056E517C-F644-4B8A-9494-09276E6E3C6B} = {BFF7517A-C9EA-458D-829E-28A10F8D61BF} + {455E5F41-B678-4286-BB4D-FC232D08CAC0} = {14FDD52D-B83A-445B-BD2F-04B3E7B8033C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {81F41C75-2F8A-4E70-BA17-38146C4BB6E6} diff --git a/appveyor.yml b/appveyor.yml index 42ca01e..a376ca8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -71,7 +71,7 @@ artifacts: deploy: - provider: NuGet api_key: - secure: vSWvi7ciU2pZZmpcXGvvR0APUpesgZBAScxNcBUttDHuWhgEAFS5fEeEiFFl5wl6 + secure: Ihowbb270n9ZDddCMfVAwAUNrEJ+Okjsld802+/Qw+cGxx3/ih8ToDxU8OxQ4sq9 skip_symbols: true artifact: /.*\.nupkg/ on: diff --git a/readme.md b/readme.md index d4b79f2..0a587d8 100644 --- a/readme.md +++ b/readme.md @@ -3,10 +3,6 @@ This is a [*FluentAssertions*](https://fluentassertions.com/) extension over the It provides assertions specific to HTTP responses and outputs rich erros messages when the tests fail, so less time with debugging is spent. -[![Build status](https://ci.appveyor.com/api/projects/status/93qtbyftww0snl4x/branch/master?svg=true)](https://ci.appveyor.com/project/adrianiftode/fluentassertions-web/branch/master) -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=adrianiftode_FluentAssertions.Web&metric=alert_status)](https://sonarcloud.io/project/overview?id=adrianiftode_FluentAssertions.Web) -[![NuGet](https://img.shields.io/nuget/v/FluentAssertions.Web.svg)](https://www.nuget.org/packages/FluentAssertions.Web) - ```csharp [Fact] public async Task Post_ReturnsOk() @@ -49,6 +45,26 @@ Once the response is ready you'll want to assert it. With first level properties ![FailedTest1](https://github.com/adrianiftode/FluentAssertions.Web/blob/master/docs/images/FailedTest1.png?raw=true) +### Status + +[![Build status](https://ci.appveyor.com/api/projects/status/93qtbyftww0snl4x/branch/master?svg=true)](https://ci.appveyor.com/project/adrianiftode/fluentassertions-web/branch/master) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=adrianiftode_FluentAssertions.Web&metric=alert_status)](https://sonarcloud.io/project/overview?id=adrianiftode_FluentAssertions.Web) +[![NuGet](https://img.shields.io/nuget/v/FluentAssertions.Web.svg)](https://www.nuget.org/packages/FluentAssertions.Web) +[![NuGet FA v8](https://img.shields.io/nuget/v/FluentAssertions.Web.svg)](https://www.nuget.org/packages/FluentAssertions.Web.v8) + +### Getting started + +If you are using FluentAssertions < 8.0.0 +``` +dotnet add package FluentAssertions.Web +``` + +If you are using FluentAssertions >= 8.0.0 + +``` +dotnet add package FluentAssertions.Web.v8 +``` + ### FluentAssertions.Web Examples - Asserting that the response content of a HTTP POST request is equivalent to a certain object @@ -333,3 +349,9 @@ This library can still be used with FluentAssertions and it did not become obsol When FluentAssertions.Web was created, [FluentAssertions.Http](https://github.com/balanikas/FluentAssertions.Http) also existed at the time, solving the same problem when considering the asserting language. Besides the extra assertions added by FluentAssertions.Web, an important effort is put by this library on what happens when a test fails. + +**FluentAssertions 8.0.0 and beyond** + +Starting 8.0.0, FA is not an FOSS anymore. **FluentAssertions.Web** will maintain both FOSS (< 8.0.0) and the Commercial versions of FA (>= 8.0.0), so they will be deployed as separate Nuget packages: + - **FluentAssertions.Web** will continue to dependend on the FOSS versions + - **FluentAssertions.Web.v8** will dependend on the Commercial versions diff --git a/src/Directory.Build.props b/src/Directory.Build.props index e008a9a..3cd149c 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -20,8 +20,4 @@ True - - - - \ No newline at end of file diff --git a/src/FluentAssertions.Web.Serializers.NewtonsoftJson/FluentAssertions.Web.Serializers.NewtonsoftJson.csproj b/src/FluentAssertions.Web.Serializers.NewtonsoftJson/FluentAssertions.Web.Serializers.NewtonsoftJson.csproj index ab7756e..11f4299 100644 --- a/src/FluentAssertions.Web.Serializers.NewtonsoftJson/FluentAssertions.Web.Serializers.NewtonsoftJson.csproj +++ b/src/FluentAssertions.Web.Serializers.NewtonsoftJson/FluentAssertions.Web.Serializers.NewtonsoftJson.csproj @@ -1,7 +1,6 @@ - FluentAssertions.Web.v8.Serializers.NewtonsoftJson NewtonsoftJson based serializer for FluentAssertions.Web @@ -12,7 +11,7 @@ - + - + diff --git a/src/FluentAssertions.Web/DeserializationException.cs b/src/FluentAssertions.Web.Types/DeserializationException.cs similarity index 99% rename from src/FluentAssertions.Web/DeserializationException.cs rename to src/FluentAssertions.Web.Types/DeserializationException.cs index b7b45c3..98e04b5 100644 --- a/src/FluentAssertions.Web/DeserializationException.cs +++ b/src/FluentAssertions.Web.Types/DeserializationException.cs @@ -1,4 +1,5 @@ // ReSharper disable once CheckNamespace +using System; using System.Runtime.Serialization; namespace FluentAssertions; diff --git a/src/FluentAssertions.Web.Types/FluentAssertions.Web.Types.csproj b/src/FluentAssertions.Web.Types/FluentAssertions.Web.Types.csproj new file mode 100644 index 0000000..c32e4aa --- /dev/null +++ b/src/FluentAssertions.Web.Types/FluentAssertions.Web.Types.csproj @@ -0,0 +1,5 @@ + + + + + diff --git a/src/FluentAssertions.Web/FluentAssertionsWebConfig.cs b/src/FluentAssertions.Web.Types/FluentAssertionsWebConfig.cs similarity index 100% rename from src/FluentAssertions.Web/FluentAssertionsWebConfig.cs rename to src/FluentAssertions.Web.Types/FluentAssertionsWebConfig.cs diff --git a/src/FluentAssertions.Web.Types/GlobalUsings.cs b/src/FluentAssertions.Web.Types/GlobalUsings.cs new file mode 100644 index 0000000..5203d66 --- /dev/null +++ b/src/FluentAssertions.Web.Types/GlobalUsings.cs @@ -0,0 +1,5 @@ +global using FluentAssertions.Web.Internal.Serializers; +global using System; +global using System.IO; +global using System.Text.Json; +global using System.Threading.Tasks; diff --git a/src/FluentAssertions.Web/ISerializer.cs b/src/FluentAssertions.Web.Types/ISerializer.cs similarity index 90% rename from src/FluentAssertions.Web/ISerializer.cs rename to src/FluentAssertions.Web.Types/ISerializer.cs index 23cb6eb..55d966e 100644 --- a/src/FluentAssertions.Web/ISerializer.cs +++ b/src/FluentAssertions.Web.Types/ISerializer.cs @@ -1,4 +1,8 @@ // ReSharper disable once CheckNamespace +using System; +using System.IO; +using System.Threading.Tasks; + namespace FluentAssertions; /// diff --git a/src/FluentAssertions.Web/Internal/Serializers/SystemTextJsonSerializer.cs b/src/FluentAssertions.Web.Types/Internal/Serializers/SystemTextJsonSerializer.cs similarity index 100% rename from src/FluentAssertions.Web/Internal/Serializers/SystemTextJsonSerializer.cs rename to src/FluentAssertions.Web.Types/Internal/Serializers/SystemTextJsonSerializer.cs diff --git a/src/FluentAssertions.Web.Types/Properties/AssemblyInfo.cs b/src/FluentAssertions.Web.Types/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..dcb9b49 --- /dev/null +++ b/src/FluentAssertions.Web.Types/Properties/AssemblyInfo.cs @@ -0,0 +1,5 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("FluentAssertions.Web.Tests")] +[assembly: InternalsVisibleTo("FluentAssertions.Web.v8.Tests")] +[assembly: InternalsVisibleTo("FluentAssertions.Web.FluentAssertionsWebConfig.Tests")] \ No newline at end of file diff --git a/src/FluentAssertions.Web/SystemTextJsonSerializerConfig.cs b/src/FluentAssertions.Web.Types/SystemTextJsonSerializerConfig.cs similarity index 100% rename from src/FluentAssertions.Web/SystemTextJsonSerializerConfig.cs rename to src/FluentAssertions.Web.Types/SystemTextJsonSerializerConfig.cs diff --git a/src/FluentAssertions.Web.v8/FluentAssertions.Web.v8.csproj b/src/FluentAssertions.Web.v8/FluentAssertions.Web.v8.csproj new file mode 100644 index 0000000..a866bb7 --- /dev/null +++ b/src/FluentAssertions.Web.v8/FluentAssertions.Web.v8.csproj @@ -0,0 +1,31 @@ + + + + + This is a FluentAssertions extension over the HttpResponseMessage object. It provides assertions specific to HTTP responses and outputs rich erros messages when the tests fail, so less time with debugging is spent. + This version depends on the commercial version of the FluentAssertions library (>= 8.0.0). + + + + + $(DefineConstants);FAV8 + + + + + + + + + + + + + + + %(RecursiveDir)%(Filename)%(Extension) + $(ContentTargetFolders)\src\%RecursiveDir% + + + + diff --git a/src/FluentAssertions.Web.v8/Properties/AssemblyInfo.cs b/src/FluentAssertions.Web.v8/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..bdb2a4d --- /dev/null +++ b/src/FluentAssertions.Web.v8/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("FluentAssertions.Web.v8.Tests")] diff --git a/src/FluentAssertions.Web/BadRequestAssertions.cs b/src/FluentAssertions.Web/BadRequestAssertions.cs index 36fe329..be3b364 100644 --- a/src/FluentAssertions.Web/BadRequestAssertions.cs +++ b/src/FluentAssertions.Web/BadRequestAssertions.cs @@ -12,8 +12,12 @@ public class BadRequestAssertions : HttpResponseMessageAssertions /// class. /// /// The subject value to be asserted. +#if FAV8 /// The assertion chain to build and manage assertions. public BadRequestAssertions(HttpResponseMessage value, AssertionChain assertionChain) : base(value, assertionChain) +#else + public BadRequestAssertions(HttpResponseMessage value) : base(value) +#endif { } @@ -56,8 +60,11 @@ public AndConstraint HaveError(string expectedErrorField, var fieldsOfErrorsProperty = json.GetChildrenNames(ErrorsPropertyName); var allFields = json.GetChildrenNames(""); var fields = hasErrorsProperty ? fieldsOfErrorsProperty : allFields; - +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(fields.Any(field => string.Equals(field, expectedErrorField, StringComparison.OrdinalIgnoreCase))) .FailWith("Expected {context:response} " + @@ -73,7 +80,11 @@ public AndConstraint HaveError(string expectedErrorField, return !scope.Discard().Any(); }); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(matchFound) .FailWith("Expected {context:response} to contain " + @@ -123,7 +134,11 @@ public AndConstraint OnlyHaveError(string expectedErrorFie var allFields = json.GetChildrenNames(""); var fields = hasErrorsProperty ? fieldsOfErrorsProperty : allFields; +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(fields.Any(field => string.Equals(field, expectedErrorField, StringComparison.OrdinalIgnoreCase))) .FailWith("Expected {context:response} " + @@ -134,7 +149,11 @@ public AndConstraint OnlyHaveError(string expectedErrorFie var parent = hasErrorsProperty ? ErrorsPropertyName : json.GetParentKey(expectedErrorField); var children = json.GetChildrenNames(parent); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(children.Count() == 1) .FailWith("Expected {context:response} " + @@ -150,7 +169,11 @@ public AndConstraint OnlyHaveError(string expectedErrorFie return !scope.Discard().Any(); }); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(expectedWildcardErrorMessageMatchFound) .FailWith("Expected {context:response} to contain " + @@ -161,7 +184,11 @@ public AndConstraint OnlyHaveError(string expectedErrorFie expectedErrorField, Subject); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(values.Count() == 1) .FailWith("Expected {context:response} " + @@ -203,7 +230,11 @@ public AndConstraint NotHaveError(string expectedErrorFiel var allFields = json.GetChildrenNames(""); var fields = hasErrorsProperty ? fieldsOfErrorsProperty : allFields; +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(!fields.Any(c => string.Equals(c, expectedErrorField, StringComparison.OrdinalIgnoreCase))) .FailWith("Expected {context:response} " + @@ -248,7 +279,11 @@ public AndConstraint HaveErrorMessage(string expectedWildc return !scope.Discard().Any(); }); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(matchFound) .FailWith("Expected {context:response} to contain " + diff --git a/src/FluentAssertions.Web/BadRequestAssertionsExtensions.cs b/src/FluentAssertions.Web/BadRequestAssertionsExtensions.cs new file mode 100644 index 0000000..796b168 --- /dev/null +++ b/src/FluentAssertions.Web/BadRequestAssertionsExtensions.cs @@ -0,0 +1,113 @@ +#if !FAV8 +// ReSharper disable once CheckNamespace +namespace FluentAssertions; + +/// +/// Contains extension methods for custom assertions in unit tests related to . +/// +[DebuggerNonUserCode] +public static class BadRequestAssertionsExtensions +{ + /// + /// Asserts that a Bad Request HTTP response content contains an error message identifiable by an expected field name and a wildcard error text. + /// + /// + /// This assertion considers the HTTP response content a JSON generated by the ASP.NET Core 3.0 framework or less + /// + /// + /// The expected field name. + /// + /// + /// The wildcard pattern with which the error field associated error message is matched, where * and ? have special meanings. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint HaveError( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + string expectedErrorField, string expectedWildcardErrorMessage, + string because = "", params object[] becauseArgs) + => new BadRequestAssertions(parent.Subject).HaveError(expectedErrorField, expectedWildcardErrorMessage, because, becauseArgs); + + /// + /// Asserts that a Bad Request HTTP response content contains only a single error message identifiable by an expected field name and a wildcard error text. + /// + /// + /// This assertion considers the HTTP response content a JSON generated by the ASP.NET Core 3.0 framework or less + /// + /// + /// The expected field name. + /// + /// + /// The wildcard pattern with which the error field associated error message is matched, where * and ? have special meanings. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint OnlyHaveError( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + string expectedErrorField, string expectedWildcardErrorMessage, + string because = "", params object[] becauseArgs) + => new BadRequestAssertions(parent.Subject).OnlyHaveError(expectedErrorField, expectedWildcardErrorMessage, because, becauseArgs); + + /// + /// Asserts that a Bad Request HTTP response content does not contain an error message identifiable by an expected field name. + /// + /// + /// This assertion considers the HTTP response content a JSON generated by the ASP.NET Core 3.0 framework or less + /// + /// + /// The expected field name. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint NotHaveError( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + string expectedErrorField, string because = "", params object[] becauseArgs) + => new BadRequestAssertions(parent.Subject).NotHaveError(expectedErrorField, because, becauseArgs); + + /// + /// Asserts that a Bad Request HTTP response content contains an error message identifiable by an wildcard error text. + /// + /// + /// The wildcard pattern with which the error field associated error message is matched, where * and ? have special meanings. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint HaveErrorMessage( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + string expectedWildcardErrorMessage, + string because = "", params object[] becauseArgs) + => new BadRequestAssertions(parent.Subject).HaveErrorMessage(expectedWildcardErrorMessage, because, becauseArgs); +} +#endif \ No newline at end of file diff --git a/src/FluentAssertions.Web/FluentAssertions.Web.csproj b/src/FluentAssertions.Web/FluentAssertions.Web.csproj index b1ec0cb..57766fa 100644 --- a/src/FluentAssertions.Web/FluentAssertions.Web.csproj +++ b/src/FluentAssertions.Web/FluentAssertions.Web.csproj @@ -1,15 +1,18 @@  - FluentAssertions.Web.v8 - - This is a FluentAssertions extension over the HttpResponseMessage object. It provides assertions specific to HTTP responses and outputs rich erros messages when the tests fail, so less time with debugging is spent. - + + This is a FluentAssertions extension over the HttpResponseMessage object. It provides assertions specific to HTTP responses and outputs rich erros messages when the tests fail, so less time with debugging is spent. + - + + + + + diff --git a/src/FluentAssertions.Web/HaveHeaderAssertions.cs b/src/FluentAssertions.Web/HaveHeaderAssertions.cs index 39717c5..bd8148f 100644 --- a/src/FluentAssertions.Web/HaveHeaderAssertions.cs +++ b/src/FluentAssertions.Web/HaveHeaderAssertions.cs @@ -13,9 +13,12 @@ public class HeadersAssertions : HttpResponseMessageAssertions /// /// The subject value to be asserted. /// The HTTP header name to be asserted. +#if FAV8 /// The assertion chain to build and manage assertions. public HeadersAssertions(HttpResponseMessage value, string header, AssertionChain assertionChain) : base(value, assertionChain) => _header = header; - +#else + public HeadersAssertions(HttpResponseMessage value, string header) : base(value) => _header = header; +#endif /// /// Asserts that an existing HTTP header in a HTTP response contains at least a value that matches a wildcard pattern. /// @@ -38,7 +41,11 @@ public AndConstraint Match(string expectedWildcardValue, stri { Guard.ThrowIfArgumentIsNull(expectedWildcardValue, nameof(expectedWildcardValue), "Cannot verify a HTTP header to be a value against a value. Use And.BeEmpty to test if the HTTP header has no values."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -52,7 +59,11 @@ public AndConstraint Match(string expectedWildcardValue, stri return !scope.Discard().Any(); }); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(matchFound) .FailWith("Expected {context:response} to contain " + @@ -79,7 +90,11 @@ public AndConstraint BeEmpty(string because = "", params obje { var headerValues = Subject.GetHeaderValues(_header); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(!headerValues.Any()) .FailWith("Expected {context:response} to contain " + @@ -106,7 +121,11 @@ public AndConstraint NotBeEmpty(string because = "", params o { var headerValues = Subject.GetHeaderValues(_header); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(headerValues.Any()) .FailWith("Expected {context:response} to contain " + @@ -152,7 +171,11 @@ public AndConstraint BeValues(IEnumerable expectedVal failures = scope.Discard(); } +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(failures.Length == 0) .FailWith("Expected {context:response} to contain " + @@ -183,7 +206,11 @@ public AndConstraint BeValue(string expectedValue, { Guard.ThrowIfArgumentIsNullOrEmpty(expectedValue, nameof(expectedValue), "Cannot verify a HTTP header to be a value against a or empty value. Use And.BeEmpty to test if the HTTP header has no value."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(Subject.GetHeaderValues(_header).Count() == 1) .FailWith($$""" @@ -201,7 +228,11 @@ public AndConstraint BeValue(string expectedValue, failures = scope.Discard(); } +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(failures.Length == 0) .FailWith($$""" @@ -238,15 +269,22 @@ public AndConstraint HaveHeader(string expectedHeader, { Guard.ThrowIfArgumentIsNull(expectedHeader, nameof(expectedHeader), "Cannot verify having a header against a header."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(IsHeaderPresent(expectedHeader)) .FailWith("Expected {context:response} to contain " + "the HTTP header {0}, but no such header was found in the actual response{reason}.{1}", expectedHeader, Subject); - +#if FAV8 return new AndConstraint(new HeadersAssertions(Subject, expectedHeader, CurrentAssertionChain)); +#else + return new AndConstraint(new HeadersAssertions(Subject, expectedHeader)); +#endif } /// @@ -268,7 +306,11 @@ public AndConstraint NotHaveHeader(string expecte { Guard.ThrowIfArgumentIsNull(expectedHeader, nameof(expectedHeader), "Cannot verify not having a header against a header."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(!IsHeaderPresent(expectedHeader)) .FailWith("Expected {context:response} to not to contain " + diff --git a/src/FluentAssertions.Web/HaveHeaderAssertionsExtensions.cs b/src/FluentAssertions.Web/HaveHeaderAssertionsExtensions.cs new file mode 100644 index 0000000..53b9442 --- /dev/null +++ b/src/FluentAssertions.Web/HaveHeaderAssertionsExtensions.cs @@ -0,0 +1,56 @@ +#if !FAV8 + +namespace FluentAssertions; + + +/// +/// Contains extension methods for custom assertions in unit tests related to . +/// +[DebuggerNonUserCode] +public static class HeadersAssertionsExtensions +{ + /// + /// Asserts that an HTTP response has a named header. + /// + /// + /// The expected header with which the HTTP headers list is matched. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint HaveHeader( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + string expectedHeader, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).HaveHeader(expectedHeader, because, becauseArgs); + + /// + /// Asserts that an HTTP response does not have a named header. + /// + /// + /// The expected header with which the HTTP headers list is matched. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint NotHaveHeader( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + string expectedHeader, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).NotHaveHeader(expectedHeader, because, becauseArgs); +} +#endif \ No newline at end of file diff --git a/src/FluentAssertions.Web/HttpResponseContentAssertions.cs b/src/FluentAssertions.Web/HttpResponseContentAssertions.cs index 8199eaa..1988475 100644 --- a/src/FluentAssertions.Web/HttpResponseContentAssertions.cs +++ b/src/FluentAssertions.Web/HttpResponseContentAssertions.cs @@ -18,14 +18,22 @@ public partial class HttpResponseMessageAssertions [CustomAssertion] public AndConstraint BeEmpty(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); var content = GetContent(); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(string.IsNullOrEmpty(content)) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:response} to have no content. {0}", Subject); @@ -59,7 +67,11 @@ public AndConstraint BeAs(TModel expected /// /// A reference to the configuration object that can be used /// to influence the way the object graphs are compared. You can also provide an alternative instance of the +#if FAV8 /// class. The global defaults are determined by the +#else + /// class. The global defaults are determined by the +#endif /// /// /// A formatted phrase as is supported by explaining why the assertion @@ -69,11 +81,19 @@ public AndConstraint BeAs(TModel expected /// Zero or more objects to format using the placeholders in . /// [CustomAssertion] +#if FAV8 public AndConstraint BeAs(TModel expectedModel, Func, EquivalencyOptions> options, string because = "", params object[] becauseArgs) +#else + public AndConstraint BeAs(TModel expectedModel, Func, EquivalencyAssertionOptions> options, string because = "", params object[] becauseArgs) +#endif { Guard.ThrowIfArgumentIsNull(options, nameof(options)); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -87,7 +107,11 @@ public AndConstraint BeAs(TModel expected var (success, errorMessage) = TryGetSubjectModel(out var subjectModel, expectedModelType); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(success) .FailWith("Expected {context:response} to have a content equivalent to a model of type {0}, but the JSON representation could not be parsed, as the operation failed with the following message: {2}{reason}. {1}", @@ -102,7 +126,11 @@ public AndConstraint BeAs(TModel expected failures = scope.Discard(); } +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(failures.Length == 0) .FailWith("Expected {context:response} to have a content equivalent to a model, but it has differences:{0}{reason}. {1}", @@ -134,7 +162,11 @@ public AndConstraint MatchInContent(string expect { Guard.ThrowIfArgumentIsNull(expectedWildcardText, nameof(expectedWildcardText), "Cannot verify a HTTP response content match a wildcard pattern."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -143,7 +175,11 @@ public AndConstraint MatchInContent(string expect if (string.IsNullOrEmpty(content)) { - CurrentAssertionChain +#if FAV8 + CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .FailWith("Expected {context:response} to match the wildcard pattern {0} in its content, but content was {reason}. {1}", expectedWildcardText, @@ -159,7 +195,11 @@ public AndConstraint MatchInContent(string expect failures = scope.Discard(); } +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(failures.Length == 0) .FailWith("Expected {context:response} to match a wildcard pattern in its content, but does not since:{0}{reason}. {1}", diff --git a/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs b/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs new file mode 100644 index 0000000..71714af --- /dev/null +++ b/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs @@ -0,0 +1,102 @@ +#if !FAV8 +// ReSharper disable once CheckNamespace +namespace FluentAssertions; + +/// +/// Contains extension methods for custom assertions in unit tests related to Http Response Content Assertions +/// +[DebuggerNonUserCode] +public static class HttpResponseContentAssertionsExtensions +{ + /// + /// Asserts that HTTP response content is empty + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint BeEmpty( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).BeEmpty(because, becauseArgs); + + /// + /// Asserts that HTTP response content can be an equivalent representation of the expected model. + /// + /// + /// The expected model. + /// + /// + /// A reference to the configuration object that can be used + /// to influence the way the object graphs are compared. You can also provide an alternative instance of the + /// class. The global defaults are determined by the + /// class. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint BeAs( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + TModel expectedModel, Func, EquivalencyAssertionOptions> options, string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).BeAs(expectedModel, options, because, becauseArgs); + + /// + /// Asserts that HTTP response content can be an equivalent representation of the expected model. + /// + /// + /// The expected model. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint BeAs( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + TModel expectedModel, string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).BeAs(expectedModel, because, becauseArgs); + + /// + /// Asserts that HTTP response has content that matches a wildcard pattern. + /// + /// + /// The wildcard pattern with which the subject is matched, where * and ? have special meanings. + /// + /// * - Matches any number of characters. You can use the asterisk (*) anywhere in a character string. Example: wh* finds what, white, and why, but not awhile or watch. + /// ? - Matches a single alphabet in a specific position. Example: b?ll finds ball, bell, and bill. + /// + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint MatchInContent( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string expectedWildcardText, string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).MatchInContent(expectedWildcardText, because, becauseArgs); +} +#endif \ No newline at end of file diff --git a/src/FluentAssertions.Web/HttpResponseMessageAssertions.cs b/src/FluentAssertions.Web/HttpResponseMessageAssertions.cs index f96c9c1..850d3a6 100644 --- a/src/FluentAssertions.Web/HttpResponseMessageAssertions.cs +++ b/src/FluentAssertions.Web/HttpResponseMessageAssertions.cs @@ -19,8 +19,13 @@ static HttpResponseMessageAssertions() /// class. /// /// The subject value to be asserted. +#if FAV8 /// The assertion chain to build and manage assertions. - public HttpResponseMessageAssertions(HttpResponseMessage value, AssertionChain assertionChain) : base(value, assertionChain) { } + public HttpResponseMessageAssertions(HttpResponseMessage value, AssertionChain assertionChain) : base(value, assertionChain) +#else + public HttpResponseMessageAssertions(HttpResponseMessage value) : base(value) +#endif + { } /// /// Returns the type of the subject the assertion applies on. diff --git a/src/FluentAssertions.Web/HttpResponseMessageFluentAssertionsExtensions.cs b/src/FluentAssertions.Web/HttpResponseMessageFluentAssertionsExtensions.cs index 7a6d609..6c2b29c 100644 --- a/src/FluentAssertions.Web/HttpResponseMessageFluentAssertionsExtensions.cs +++ b/src/FluentAssertions.Web/HttpResponseMessageFluentAssertionsExtensions.cs @@ -1,4 +1,5 @@ -// ReSharper disable once CheckNamespace +#if FAV8 +// ReSharper disable once CheckNamespace namespace FluentAssertions { /// @@ -14,4 +15,5 @@ public static class HttpResponseMessageFluentAssertionsExtensions public static HttpResponseMessageAssertions Should(this HttpResponseMessage? actual) => new HttpResponseMessageAssertions(actual, AssertionChain.GetOrCreate()); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/src/FluentAssertions.Web/HttpStatusCodeAssertions.cs b/src/FluentAssertions.Web/HttpStatusCodeAssertions.cs index f73eb75..ccbb073 100644 --- a/src/FluentAssertions.Web/HttpStatusCodeAssertions.cs +++ b/src/FluentAssertions.Web/HttpStatusCodeAssertions.cs @@ -18,12 +18,20 @@ public partial class HttpResponseMessageAssertions // ReSharper disable once InconsistentNaming public AndConstraint Be1XXInformational(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(Subject!.StatusCode < HttpStatusCode.OK) .FailWith("Expected {context:response} to have a HTTP status code representing an informational error, but it was {0}{reason}.{1}", @@ -49,12 +57,20 @@ public AndConstraint Be1XXInformational(string be // ReSharper disable once InconsistentNaming public AndConstraint Be2XXSuccessful(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(Subject!.IsSuccessStatusCode) .FailWith("Expected {context:response} to have a successful HTTP status code, but it was {0}{reason}.{1}", @@ -80,12 +96,20 @@ public AndConstraint Be2XXSuccessful(string becau // ReSharper disable once InconsistentNaming public AndConstraint Be3XXRedirection(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(Subject!.StatusCode >= HttpStatusCode.Moved && Subject!.StatusCode < HttpStatusCode.BadRequest) .FailWith("Expected {context:response} to have a HTTP status code representing a redirection, but it was {0}{reason}.{1}", @@ -111,12 +135,20 @@ public AndConstraint Be3XXRedirection(string beca // ReSharper disable once InconsistentNaming public AndConstraint Be4XXClientError(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(Subject!.StatusCode >= HttpStatusCode.BadRequest && Subject!.StatusCode < HttpStatusCode.InternalServerError) .FailWith("Expected {context:response} to have a HTTP status code representing a client error, but it was {0}{reason}.{1}", @@ -142,12 +174,20 @@ public AndConstraint Be4XXClientError(string beca // ReSharper disable once InconsistentNaming public AndConstraint Be5XXServerError(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(Subject!.StatusCode >= HttpStatusCode.InternalServerError) .FailWith("Expected {context:response} to have a HTTP status code representing a server error, but it was {0}{reason}.{1}", @@ -174,12 +214,20 @@ public AndConstraint Be5XXServerError(string beca [CustomAssertion] public AndConstraint HaveHttpStatusCode(HttpStatusCode expected, string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(expected == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -205,12 +253,20 @@ public AndConstraint HaveHttpStatusCode(HttpStatu [CustomAssertion] public AndConstraint NotHaveHttpStatusCode(HttpStatusCode unexpected, string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(unexpected != Subject!.StatusCode) .FailWith("Did not expect {context:response} to have status {0}{reason}.{1}", @@ -233,12 +289,20 @@ public AndConstraint NotHaveHttpStatusCode(HttpSt [CustomAssertion] public AndConstraint Be100Continue(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Continue == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -259,12 +323,20 @@ public AndConstraint Be100Continue(string because [CustomAssertion] public AndConstraint Be101SwitchingProtocols(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.SwitchingProtocols == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -285,12 +357,20 @@ public AndConstraint Be101SwitchingProtocols(stri [CustomAssertion] public AndConstraint Be200Ok(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.OK == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -311,12 +391,20 @@ public AndConstraint Be200Ok(string because = "", [CustomAssertion] public AndConstraint Be201Created(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Created == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -337,12 +425,20 @@ public AndConstraint Be201Created(string because [CustomAssertion] public AndConstraint Be202Accepted(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Accepted == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -363,12 +459,20 @@ public AndConstraint Be202Accepted(string because [CustomAssertion] public AndConstraint Be203NonAuthoritativeInformation(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.NonAuthoritativeInformation == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -389,12 +493,20 @@ public AndConstraint Be203NonAuthoritativeInforma [CustomAssertion] public AndConstraint Be204NoContent(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.NoContent == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -415,12 +527,20 @@ public AndConstraint Be204NoContent(string becaus [CustomAssertion] public AndConstraint Be205ResetContent(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.ResetContent == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -441,12 +561,20 @@ public AndConstraint Be205ResetContent(string bec [CustomAssertion] public AndConstraint Be206PartialContent(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.PartialContent == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -467,12 +595,20 @@ public AndConstraint Be206PartialContent(string b [CustomAssertion] public AndConstraint Be300MultipleChoices(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.MultipleChoices == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -493,12 +629,20 @@ public AndConstraint Be300MultipleChoices(string [CustomAssertion] public AndConstraint Be300Ambiguous(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Ambiguous == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -519,12 +663,20 @@ public AndConstraint Be300Ambiguous(string becaus [CustomAssertion] public AndConstraint Be301MovedPermanently(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.MovedPermanently == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -545,12 +697,20 @@ public AndConstraint Be301MovedPermanently(string [CustomAssertion] public AndConstraint Be301Moved(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Moved == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -571,12 +731,20 @@ public AndConstraint Be301Moved(string because = [CustomAssertion] public AndConstraint Be302Found(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Found == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -597,12 +765,20 @@ public AndConstraint Be302Found(string because = [CustomAssertion] public AndConstraint Be302Redirect(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Redirect == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -623,12 +799,20 @@ public AndConstraint Be302Redirect(string because [CustomAssertion] public AndConstraint Be303SeeOther(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.SeeOther == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -649,12 +833,20 @@ public AndConstraint Be303SeeOther(string because [CustomAssertion] public AndConstraint Be303RedirectMethod(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.RedirectMethod == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -675,12 +867,20 @@ public AndConstraint Be303RedirectMethod(string b [CustomAssertion] public AndConstraint Be304NotModified(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.NotModified == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -701,12 +901,20 @@ public AndConstraint Be304NotModified(string beca [CustomAssertion] public AndConstraint Be305UseProxy(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.UseProxy == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -727,12 +935,20 @@ public AndConstraint Be305UseProxy(string because [CustomAssertion] public AndConstraint Be306Unused(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Unused == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -753,12 +969,20 @@ public AndConstraint Be306Unused(string because = [CustomAssertion] public AndConstraint Be307TemporaryRedirect(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.TemporaryRedirect == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -779,12 +1003,20 @@ public AndConstraint Be307TemporaryRedirect(strin [CustomAssertion] public AndConstraint Be307RedirectKeepVerb(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.RedirectKeepVerb == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -805,17 +1037,29 @@ public AndConstraint Be307RedirectKeepVerb(string [CustomAssertion] public AndConstraint Be400BadRequest(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.BadRequest == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" , HttpStatusCode.BadRequest, Subject!.StatusCode, Subject); +#if FAV8 return new AndConstraint(new BadRequestAssertions(Subject, CurrentAssertionChain)); +#else + return new AndConstraint(new BadRequestAssertions(Subject)); +#endif } /// @@ -831,12 +1075,20 @@ public AndConstraint Be400BadRequest(string because = "", [CustomAssertion] public AndConstraint Be401Unauthorized(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Unauthorized == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -857,12 +1109,20 @@ public AndConstraint Be401Unauthorized(string bec [CustomAssertion] public AndConstraint Be402PaymentRequired(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.PaymentRequired == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -883,12 +1143,20 @@ public AndConstraint Be402PaymentRequired(string [CustomAssertion] public AndConstraint Be403Forbidden(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Forbidden == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -909,12 +1177,20 @@ public AndConstraint Be403Forbidden(string becaus [CustomAssertion] public AndConstraint Be404NotFound(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.NotFound == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -935,12 +1211,20 @@ public AndConstraint Be404NotFound(string because [CustomAssertion] public AndConstraint Be405MethodNotAllowed(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.MethodNotAllowed == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -961,12 +1245,20 @@ public AndConstraint Be405MethodNotAllowed(string [CustomAssertion] public AndConstraint Be406NotAcceptable(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.NotAcceptable == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -987,12 +1279,20 @@ public AndConstraint Be406NotAcceptable(string be [CustomAssertion] public AndConstraint Be407ProxyAuthenticationRequired(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.ProxyAuthenticationRequired == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1013,12 +1313,20 @@ public AndConstraint Be407ProxyAuthenticationRequ [CustomAssertion] public AndConstraint Be408RequestTimeout(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.RequestTimeout == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1039,12 +1347,20 @@ public AndConstraint Be408RequestTimeout(string b [CustomAssertion] public AndConstraint Be409Conflict(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Conflict == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1065,12 +1381,20 @@ public AndConstraint Be409Conflict(string because [CustomAssertion] public AndConstraint Be410Gone(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.Gone == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1091,12 +1415,20 @@ public AndConstraint Be410Gone(string because = " [CustomAssertion] public AndConstraint Be411LengthRequired(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.LengthRequired == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1117,12 +1449,20 @@ public AndConstraint Be411LengthRequired(string b [CustomAssertion] public AndConstraint Be412PreconditionFailed(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.PreconditionFailed == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1143,12 +1483,20 @@ public AndConstraint Be412PreconditionFailed(stri [CustomAssertion] public AndConstraint Be413RequestEntityTooLarge(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.RequestEntityTooLarge == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1169,12 +1517,20 @@ public AndConstraint Be413RequestEntityTooLarge(s [CustomAssertion] public AndConstraint Be414RequestUriTooLong(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.RequestUriTooLong == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1195,12 +1551,20 @@ public AndConstraint Be414RequestUriTooLong(strin [CustomAssertion] public AndConstraint Be415UnsupportedMediaType(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.UnsupportedMediaType == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1221,12 +1585,20 @@ public AndConstraint Be415UnsupportedMediaType(st [CustomAssertion] public AndConstraint Be416RequestedRangeNotSatisfiable(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.RequestedRangeNotSatisfiable == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1247,12 +1619,20 @@ public AndConstraint Be416RequestedRangeNotSatisf [CustomAssertion] public AndConstraint Be417ExpectationFailed(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.ExpectationFailed == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1273,12 +1653,20 @@ public AndConstraint Be417ExpectationFailed(strin [CustomAssertion] public AndConstraint Be422UnprocessableEntity(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(422 == (int)Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1299,12 +1687,20 @@ public AndConstraint Be422UnprocessableEntity(str [CustomAssertion] public AndConstraint Be429TooManyRequests(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(429 == (int)Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1325,12 +1721,20 @@ public AndConstraint Be429TooManyRequests(string [CustomAssertion] public AndConstraint Be426UpgradeRequired(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.UpgradeRequired == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1351,12 +1755,20 @@ public AndConstraint Be426UpgradeRequired(string [CustomAssertion] public AndConstraint Be500InternalServerError(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.InternalServerError == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1377,12 +1789,20 @@ public AndConstraint Be500InternalServerError(str [CustomAssertion] public AndConstraint Be501NotImplemented(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.NotImplemented == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1403,12 +1823,20 @@ public AndConstraint Be501NotImplemented(string b [CustomAssertion] public AndConstraint Be502BadGateway(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.BadGateway == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1429,12 +1857,20 @@ public AndConstraint Be502BadGateway(string becau [CustomAssertion] public AndConstraint Be503ServiceUnavailable(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.ServiceUnavailable == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1455,12 +1891,20 @@ public AndConstraint Be503ServiceUnavailable(stri [CustomAssertion] public AndConstraint Be504GatewayTimeout(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.GatewayTimeout == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" @@ -1481,17 +1925,25 @@ public AndConstraint Be504GatewayTimeout(string b [CustomAssertion] public AndConstraint Be505HttpVersionNotSupported(string because = "", params object[] becauseArgs) { +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(HttpStatusCode.HttpVersionNotSupported == Subject!.StatusCode) .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}" , HttpStatusCode.HttpVersionNotSupported, Subject!.StatusCode, Subject); return new AndConstraint(this); } - #endregion +#endregion } \ No newline at end of file diff --git a/src/FluentAssertions.Web/HttpStatusCodeAssertionsExtensions.cs b/src/FluentAssertions.Web/HttpStatusCodeAssertionsExtensions.cs new file mode 100644 index 0000000..68fe24a --- /dev/null +++ b/src/FluentAssertions.Web/HttpStatusCodeAssertionsExtensions.cs @@ -0,0 +1,1050 @@ +#if !FAV8 +// ReSharper disable once CheckNamespace +namespace FluentAssertions; + +/// +/// Contains extension methods for custom assertions in unit tests related to . +/// +public static class HttpStatusCodeAssertionsExtensions +{ + #region Be1XXInformational + /// + /// Asserts that a HTTP response has a HTTP status code representing an informational response. + /// + /// The HTTP response was an informational one if was in the range 100-199. + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + // ReSharper disable once InconsistentNaming + public static AndConstraint Be1XXInformational( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be1XXInformational(because, becauseArgs); + #endregion + + #region Be2XXSuccessful + /// + /// Asserts that a HTTP response has a successful HTTP status code. + /// + /// The HTTP response was successful if was in the range 200-299. + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + // ReSharper disable once InconsistentNaming + public static AndConstraint Be2XXSuccessful( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be2XXSuccessful(because, becauseArgs); + #endregion + + #region Be3XXRedirection + /// + /// Asserts that a HTTP response has a HTTP status code representing a redirection response. + /// + /// The HTTP response was an informational one if was in the range 300-399. + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + // ReSharper disable once InconsistentNaming + public static AndConstraint Be3XXRedirection( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be3XXRedirection(because, becauseArgs); + #endregion + + #region Be4XXClientError + /// + /// Asserts that a HTTP response has a HTTP status code representing a client error. + /// + /// The HTTP response was a client error if was in the range 400-499. + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + // ReSharper disable once InconsistentNaming + public static AndConstraint Be4XXClientError( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be4XXClientError(because, becauseArgs); + #endregion + + #region Be5XXServerError + /// + /// Asserts that a HTTP response has a HTTP status code representing a server error. + /// + /// The HTTP response was a server error if was above 500. + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + // ReSharper disable once InconsistentNaming + public static AndConstraint Be5XXServerError( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be5XXServerError(because, becauseArgs); + #endregion + + #region HaveHtppStatus + /// + /// Asserts that a HTTP response has a HTTP status with the specified code. + /// + /// + /// The code of the expected HTTP Status. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint HaveHttpStatusCode( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + HttpStatusCode expected, string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).HaveHttpStatusCode(expected, because, becauseArgs); + #endregion + + #region NotHaveHtppStatus + /// + /// Asserts that a HTTP response does not have a HTTP status with the specified code. + /// + /// + /// The code of the unexpected HTTP Status. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint NotHaveHttpStatusCode( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + HttpStatusCode unexpected, string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).NotHaveHttpStatusCode(unexpected, because, becauseArgs); + #endregion + + #region BeXXXHttpStatus + /// + /// Asserts that a HTTP response has the HTTP status 100 Continue + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be100Continue( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be100Continue(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 101 Switching Protocols + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be101SwitchingProtocols( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be101SwitchingProtocols(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 200 Ok + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be200Ok( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be200Ok(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 201 Created + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be201Created( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be201Created(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 202 Accepted + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be202Accepted( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be202Accepted(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 203 Non Authoritative Information + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be203NonAuthoritativeInformation( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be203NonAuthoritativeInformation(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 204 No Content + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be204NoContent( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be204NoContent(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 205 Reset Content + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be205ResetContent( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be205ResetContent(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 206 Partial Content + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be206PartialContent( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be206PartialContent(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 300 Multiple Choices + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be300MultipleChoices( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be300MultipleChoices(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 300 Ambiguous + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be300Ambiguous( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be300Ambiguous(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 301 Moved Permanently + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be301MovedPermanently( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be301MovedPermanently(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 301 Moved + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be301Moved( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be301Moved(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 302 Found + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be302Found( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be302Found(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 302 Redirect + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be302Redirect( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be302Redirect(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 303 See Other + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be303SeeOther( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be303SeeOther(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 303 Redirect Method + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be303RedirectMethod( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be303RedirectMethod(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 304 Not Modified + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be304NotModified( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be304NotModified(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 305 Use Proxy + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be305UseProxy( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be305UseProxy(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 306 Unused + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be306Unused( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be306Unused(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 307 Temporary Redirect + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be307TemporaryRedirect( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be307TemporaryRedirect(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 307 Redirect Keep Verb + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be307RedirectKeepVerb( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be307RedirectKeepVerb(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 400 BadRequest + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be400BadRequest( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new BadRequestAssertions(parent.Subject).Be400BadRequest(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 401 Unauthorized + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be401Unauthorized( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be401Unauthorized(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 402 Payment Required + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be402PaymentRequired( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be402PaymentRequired(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 403 Forbidden + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be403Forbidden( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be403Forbidden(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 404 Not Found + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be404NotFound( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be404NotFound(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 405 Method Not Allowed + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be405MethodNotAllowed( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be405MethodNotAllowed(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 406 Not Acceptable + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be406NotAcceptable( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be406NotAcceptable(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 407 Proxy Authentication Required + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be407ProxyAuthenticationRequired( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be407ProxyAuthenticationRequired(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 408 Request Timeout + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be408RequestTimeout( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be408RequestTimeout(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 409 Conflict + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be409Conflict( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be409Conflict(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 410 Gone + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be410Gone( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be410Gone(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 411 Length Required + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be411LengthRequired( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be411LengthRequired(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 412 Precondition Failed + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be412PreconditionFailed( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be412PreconditionFailed(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 413 Request Entity Too Large + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be413RequestEntityTooLarge( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be413RequestEntityTooLarge(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 414 Request Uri Too Long + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be414RequestUriTooLong( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be414RequestUriTooLong(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 415 Unsupported Media Type + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be415UnsupportedMediaType( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be415UnsupportedMediaType(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 416 Requested Range Not Satisfiable + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be416RequestedRangeNotSatisfiable( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be416RequestedRangeNotSatisfiable(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 417 Expectation Failed + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be417ExpectationFailed( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be417ExpectationFailed(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 422 UnprocessableEntity + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be422UnprocessableEntity( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be422UnprocessableEntity(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 429 TooManyRequests + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be429TooManyRequests( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be429TooManyRequests(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 426 UpgradeRequired + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be426UpgradeRequired( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be426UpgradeRequired(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 500 Internal Server Error + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be500InternalServerError( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be500InternalServerError(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 501 Not Implemented + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be501NotImplemented( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be501NotImplemented(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 502 Bad Gateway + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be502BadGateway( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be502BadGateway(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 503 Service Unavailable + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be503ServiceUnavailable( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be503ServiceUnavailable(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 504 Gateway Timeout + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be504GatewayTimeout( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be504GatewayTimeout(because, becauseArgs); + + /// + /// Asserts that a HTTP response has the HTTP status 505 Http Version Not Supported + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Be505HttpVersionNotSupported( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Be505HttpVersionNotSupported(because, becauseArgs); + #endregion +} +#endif \ No newline at end of file diff --git a/src/FluentAssertions.Web/Properties/AssemblyInfo.cs b/src/FluentAssertions.Web/Properties/AssemblyInfo.cs index 0db377c..354a245 100644 --- a/src/FluentAssertions.Web/Properties/AssemblyInfo.cs +++ b/src/FluentAssertions.Web/Properties/AssemblyInfo.cs @@ -1,4 +1,3 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("FluentAssertions.Web.Tests")] -[assembly: InternalsVisibleTo("FluentAssertions.Web.FluentAssertionsWebConfig.Tests")] \ No newline at end of file diff --git a/src/FluentAssertions.Web/SatisfyHttpResponseMessageAssertions.cs b/src/FluentAssertions.Web/SatisfyHttpResponseMessageAssertions.cs index 2450276..0db346e 100644 --- a/src/FluentAssertions.Web/SatisfyHttpResponseMessageAssertions.cs +++ b/src/FluentAssertions.Web/SatisfyHttpResponseMessageAssertions.cs @@ -24,7 +24,11 @@ public AndConstraint Satisfy(Action."); @@ -33,7 +37,11 @@ public AndConstraint Satisfy(Action Satisfy(Func."); @@ -78,7 +90,11 @@ public AndConstraint Satisfy(Func +/// Contains extension methods for custom assertions in unit tests related to Http Response Message. +/// +[DebuggerNonUserCode] +public static class SatisfyHttpResponseMessageAssertionsExtensions +{ + /// + /// Asserts that an HTTP response satisfies an assertion. + /// + /// + /// An assertion about the HTTP response. + /// + /// + /// The assertion can be a single assertion or a collection of assertions if the assertion action is expressed as a statement lambda. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Satisfy( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + Action assertion, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Satisfy(assertion, because, becauseArgs); + + /// + /// Asserts that an HTTP response satisfies an asynchronous assertion. + /// + /// + /// An assertion about the HTTP response. + /// + /// + /// The assertion can be a single assertion or a collection of assertions if the assertion action is expressed as a statement lambda. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Satisfy( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573, + Func assertion, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Satisfy(assertion, because, becauseArgs); +} +#endif \ No newline at end of file diff --git a/src/FluentAssertions.Web/SatisfyModelAssertions.cs b/src/FluentAssertions.Web/SatisfyModelAssertions.cs index 22d4c4c..7d32d62 100644 --- a/src/FluentAssertions.Web/SatisfyModelAssertions.cs +++ b/src/FluentAssertions.Web/SatisfyModelAssertions.cs @@ -26,7 +26,11 @@ public AndConstraint Satisfy( Guard.ThrowIfArgumentIsNull(assertion, nameof(assertion), "Cannot verify the subject satisfies a `null` assertion."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -35,7 +39,11 @@ public AndConstraint Satisfy( Type? modelType = typeof(TModel); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(success) .FailWith("Expected {context:response} to have a content equivalent to a model of type {0}, but the JSON representation could not be parsed, as the operation failed with the following message: {2}{reason}. {1}", @@ -45,7 +53,11 @@ public AndConstraint Satisfy( if (failuresFromAssertions.Any()) { - CurrentAssertionChain + #if FAV8 + CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .FailWith( "Expected {context:response} to satisfy one or more model assertions, but it wasn't{reason}: {0}{1}", @@ -83,7 +95,11 @@ public AndConstraint Satisfy(TModel given { Guard.ThrowIfArgumentIsNull(assertion, nameof(assertion), "Cannot verify the subject satisfies a `null` assertion."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -92,7 +108,11 @@ public AndConstraint Satisfy(TModel given Type? modelType = typeof(TModel); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(success) .FailWith("Expected {context:response} to have a content equivalent to a model of type {0}, but the JSON representation could not be parsed, as the operation failed with the following message: {2}{reason}. {1}", @@ -102,7 +122,11 @@ public AndConstraint Satisfy(TModel given if (failuresFromAssertions.Any()) { - CurrentAssertionChain + #if FAV8 + CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .FailWith( "Expected {context:response} to satisfy one or more model assertions, but it wasn't{reason}: {0}{1}", @@ -136,7 +160,11 @@ public AndConstraint Satisfy( Guard.ThrowIfArgumentIsNull(assertion, nameof(assertion), "Cannot verify the subject satisfies a `null` assertion."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -153,7 +181,11 @@ public AndConstraint Satisfy( Type? modelType = typeof(TModel); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(success) .FailWith("Expected {context:response} to have a content equivalent to a model of type {0}, but the JSON representation could not be parsed, as the operation failed with the following message: {2}{reason}. {1}", @@ -163,7 +195,11 @@ public AndConstraint Satisfy( if (failuresFromAssertions.Any()) { - CurrentAssertionChain + #if FAV8 + CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .FailWith( "Expected {context:response} to satisfy one or more model assertions, but it wasn't{reason}: {0}{1}", @@ -201,7 +237,11 @@ public AndConstraint Satisfy(TModel given { Guard.ThrowIfArgumentIsNull(assertion, nameof(assertion), "Cannot verify the subject satisfies a `null` assertion."); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected a {context:response} to assert{reason}, but found ."); @@ -218,7 +258,11 @@ public AndConstraint Satisfy(TModel given Type? modelType = typeof(TModel); +#if FAV8 CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .ForCondition(success) .FailWith("Expected {context:response} to have a content equivalent to a model of type {0}, but the JSON representation could not be parsed, as the operation failed with the following message: {2}{reason}. {1}", @@ -228,7 +272,11 @@ public AndConstraint Satisfy(TModel given if (failuresFromAssertions.Any()) { - CurrentAssertionChain + #if FAV8 + CurrentAssertionChain +#else + Execute.Assertion +#endif .BecauseOf(because, becauseArgs) .FailWith( "Expected {context:response} to satisfy one or more model assertions, but it wasn't{reason}: {0}{1}", diff --git a/src/FluentAssertions.Web/SatisfyModelAssertionsExtensions.cs b/src/FluentAssertions.Web/SatisfyModelAssertionsExtensions.cs new file mode 100644 index 0000000..a0f6c22 --- /dev/null +++ b/src/FluentAssertions.Web/SatisfyModelAssertionsExtensions.cs @@ -0,0 +1,119 @@ +#if !FAV8 +// ReSharper disable once CheckNamespace +namespace FluentAssertions; + +/// +/// Contains extension methods for custom assertions in unit tests related to Http Response Message. +/// +[DebuggerNonUserCode] +public static class SatisfyModelAssertionsExtensions +{ + /// + /// Asserts that an HTTP response content can be a model that satisfies an assertion. + /// + /// + /// An assertion regarding the given model. + /// + /// + /// The assertion can be a single assertion or a collection of assertions if the assertion action is expressed as a statement lambda. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Satisfy( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + Action assertion, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Satisfy(assertion, because, becauseArgs); + + /// + /// Asserts that an HTTP response content can be a model that satisfies an assertion starting from an inferred model structure. + /// + /// + /// A proposed model structure that will help to compose the assertions. This is used to defined the type of the asserted model and it doesn't have to contain other values than the default one. + /// + /// + /// The assertion can be a single assertion or a collection of assertions if the assertion action is expressed as a statement lambda. + /// + /// + /// An assertion or a collection of assertions regarding the given model. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Satisfy( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + TModel givenModelStructure, + Action assertion, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Satisfy(givenModelStructure, assertion, because, becauseArgs); + + /// + /// Asserts that an HTTP response content can be a model that satisfies an asynchronous assertion. + /// + /// + /// An assertion regarding the given model. + /// + /// + /// The assertion can be a single assertion or a collection of assertions if the assertion action is expressed as a statement lambda. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Satisfy( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + Func assertion, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Satisfy(assertion, because, becauseArgs); + + /// + /// Asserts that an HTTP response content can be a model that satisfies an asynchronous assertion starting from an inferred model structure. + /// + /// + /// A proposed model structure that will help to compose the assertions. This is used to defined the type of the asserted model and it doesn't have to contain other values than the default one. + /// + /// + /// The assertion can be a single assertion or a collection of assertions if the assertion action is expressed as a statement lambda. + /// + /// + /// An assertion or a collection of assertions regarding the given model. + /// + /// + /// A formatted phrase as is supported by explaining why the assertion + /// is needed. If the phrase does not start with the word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in . + /// + [CustomAssertion] + public static AndConstraint Satisfy( +#pragma warning disable 1573 + this Primitives.HttpResponseMessageAssertions parent, +#pragma warning restore 1573 + TModel givenModelStructure, + Func assertion, + string because = "", params object[] becauseArgs) + => new HttpResponseMessageAssertions(parent.Subject).Satisfy(givenModelStructure, assertion, because, becauseArgs); +} +#endif \ No newline at end of file diff --git a/test/Directory.Build.props b/test/Directory.Build.props index fd545e4..dfc8e90 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -12,7 +12,6 @@ - diff --git a/test/FluentAssertions.Web.FluentAssertionsWebConfig.Tests/FluentAssertions.Web.FluentAssertionsWebConfig.Tests.csproj b/test/FluentAssertions.Web.FluentAssertionsWebConfig.Tests/FluentAssertions.Web.FluentAssertionsWebConfig.Tests.csproj index 45fb4f3..3874c34 100644 --- a/test/FluentAssertions.Web.FluentAssertionsWebConfig.Tests/FluentAssertions.Web.FluentAssertionsWebConfig.Tests.csproj +++ b/test/FluentAssertions.Web.FluentAssertionsWebConfig.Tests/FluentAssertions.Web.FluentAssertionsWebConfig.Tests.csproj @@ -1,6 +1,11 @@ + + + + + @@ -10,5 +15,4 @@ - diff --git a/test/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests.csproj b/test/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests.csproj index d1334ae..cdb40ad 100644 --- a/test/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests.csproj +++ b/test/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests.csproj @@ -1,6 +1,11 @@ + + + + + diff --git a/test/FluentAssertions.Web.Tests/FluentAssertions.Web.Tests.csproj b/test/FluentAssertions.Web.Tests/FluentAssertions.Web.Tests.csproj index fe23b7f..a5dc9c4 100644 --- a/test/FluentAssertions.Web.Tests/FluentAssertions.Web.Tests.csproj +++ b/test/FluentAssertions.Web.Tests/FluentAssertions.Web.Tests.csproj @@ -1,5 +1,9 @@  + + + + diff --git a/test/FluentAssertions.Web.Tests/HeadersAssertionsSpecs.cs b/test/FluentAssertions.Web.Tests/HeadersAssertionsSpecs.cs index ebc084a..0d78619 100644 --- a/test/FluentAssertions.Web.Tests/HeadersAssertionsSpecs.cs +++ b/test/FluentAssertions.Web.Tests/HeadersAssertionsSpecs.cs @@ -404,7 +404,7 @@ public void When_asserting_response_with_header_with_multiple_values_indicated_b // Assert act.Should().Throw() - .WithMessage("*the*custom-header*HTTP header*equivalent*but they differ at*value1,value2*value1*reason*"); + .WithMessage("*the*custom-header*HTTP header*equivalent*value1*value2*reason*"); } [Fact] @@ -425,7 +425,7 @@ public void When_asserting_response_with_header_without_some_value_to_be_differe // Assert act.Should().Throw() - .WithMessage("*the *custom-header* HTTP header*value* to be equivalent to the same string, but they differ at*reason*"); + .WithMessage("*custom-header*HTTP*header*value*equivalent*but*value1*reason*"); } [Fact] diff --git a/test/FluentAssertions.Web.Tests/HttpResponseContentAssertionsSpecs.cs b/test/FluentAssertions.Web.Tests/HttpResponseContentAssertionsSpecs.cs index 79f5bd0..d4b58b8 100644 --- a/test/FluentAssertions.Web.Tests/HttpResponseContentAssertionsSpecs.cs +++ b/test/FluentAssertions.Web.Tests/HttpResponseContentAssertionsSpecs.cs @@ -339,7 +339,11 @@ public void When_asserting_response_to_be_as_model_with_null_equivalency_asserti // Act Action act = () => +#if FAV8 subject.Should().BeAs(new { }, options: (Func, EquivalencyOptions>)(null!)); +#else + subject.Should().BeAs(new { }, options: (Func, EquivalencyAssertionOptions>)(null!)); +#endif // Assert act.Should().Throw() @@ -375,7 +379,7 @@ public void When_asserting_null_response_to_be_as_it_should_throw_with_descripti act.Should().Throw() .WithMessage("Expected a * to assert because we want to test the failure message, but found ."); } - #endregion +#endregion #region MatchInContent [Theory] diff --git a/test/FluentAssertions.Web.Tests/Internal/ApiAccessibilityTests.cs b/test/FluentAssertions.Web.Tests/Internal/ApiAccessibilityTests.cs index 38d881f..838e228 100644 --- a/test/FluentAssertions.Web.Tests/Internal/ApiAccessibilityTests.cs +++ b/test/FluentAssertions.Web.Tests/Internal/ApiAccessibilityTests.cs @@ -80,6 +80,62 @@ public void Each_HttpResponseMessage_Assertion_Extension_Should_Be_In_The_Fluent .Should().OnlyContain(type => type.Namespace == "FluentAssertions"); } +#if !FAV8 + + [Fact] + public void Each_HttpResponseMessage_Assertion_ShouldHaveAnExtensionOverPrimitivesHttpResponseMessageAssertions() + { + // Arrange + var baseAssertionsType = typeof(ReferenceTypeAssertions); + var httpResponseMessageAssertions = typeof(HttpResponseMessageAssertions).Assembly + .GetTypes() + .Where(c => c.BaseType == baseAssertionsType) + .ToList(); + httpResponseMessageAssertions.Should().NotBeEmpty(); + + var allExtensions = typeof(HttpResponseMessageAssertions).Assembly + .GetTypes() + .Where(c => c.Name.EndsWith("AssertionsExtensions")) + .SelectMany(c => c.GetMethods(BindingFlags.Static | BindingFlags.Public)) + .ToList(); + + // Assert + foreach (var assertionType in httpResponseMessageAssertions) + { + foreach (var assertionMethod in assertionType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) + { + allExtensions.Should().Contain(extensionMethod => + extensionMethod.Name == assertionMethod.Name + && extensionMethod.ReturnType.GetType() == assertionMethod.ReturnType.GetType() + && SameParameters(extensionMethod, assertionMethod), + "\n we wanted to check \n" + + "the assertion method {0} \n" + + "from assertion type {1} \n" + + "and return type {2} \n" + + "and arguments {3} \n" + + "has a corresponding extension method", + assertionMethod.Name, + assertionType.FullName, + assertionMethod.ReturnType.FullName, + string.Join(", ", assertionMethod.GetParameters().Select(c => $"{c.Name} of type {c.ParameterType.FullName}"))); + } + } + } + + [Fact] + public void Each_HttpResponseMessage_Assertion_Extension_Should_Have_The_CustomAssertion_Attribute() + { + // Arrange + var allExtensions = typeof(HttpResponseMessageAssertions).Assembly + .GetTypes() + .Where(c => c.Name.EndsWith("AssertionsExtensions")) + .SelectMany(c => c.GetMethods(BindingFlags.Static | BindingFlags.Public)) + .ToList(); + + // Assert + allExtensions.Should().AllSatisfy(method => method.Should().BeDecoratedWith()); + } + private static bool SameParameters(MethodInfo extensionMethod, MethodInfo assertionMethod) { var extensionMethodParameters = extensionMethod.GetParameters(); @@ -104,4 +160,5 @@ private static bool SameParameters(MethodInfo extensionMethod, MethodInfo assert return true; } +#endif } diff --git a/test/FluentAssertions.Web.Tests/Internal/ContentProcessors/FallbackProcessorTests.cs b/test/FluentAssertions.Web.Tests/Internal/ContentProcessors/FallbackProcessorTests.cs index 3fa2b45..c485074 100644 --- a/test/FluentAssertions.Web.Tests/Internal/ContentProcessors/FallbackProcessorTests.cs +++ b/test/FluentAssertions.Web.Tests/Internal/ContentProcessors/FallbackProcessorTests.cs @@ -1,5 +1,4 @@ using FluentAssertions.Web.Internal.ContentProcessors; -using System.Net.Http.Headers; namespace FluentAssertions.Web.Tests.Internal.ContentProcessors; diff --git a/test/FluentAssertions.Web.v8.Tests/FluentAssertions.Web.v8.Tests.csproj b/test/FluentAssertions.Web.v8.Tests/FluentAssertions.Web.v8.Tests.csproj new file mode 100644 index 0000000..7559fe8 --- /dev/null +++ b/test/FluentAssertions.Web.v8.Tests/FluentAssertions.Web.v8.Tests.csproj @@ -0,0 +1,22 @@ + + + + $(DefineConstants);FAV8 + + + + + + + + + + + + + + %(RecursiveDir)%(Filename)%(Extension) + + + + diff --git a/test/Sample.Api.Tests/CommentsControllerTests.cs b/test/Sample.Api.Tests/CommentsControllerTests.cs index 030aafe..3b14267 100644 --- a/test/Sample.Api.Tests/CommentsControllerTests.cs +++ b/test/Sample.Api.Tests/CommentsControllerTests.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Xunit; + namespace Sample.Api.Tests { public class CommentsControllerTests : IClassFixture> diff --git a/test/Sample.Api.v8.Tests/Sample.Api.v8.Tests.csproj b/test/Sample.Api.v8.Tests/Sample.Api.v8.Tests.csproj new file mode 100644 index 0000000..4615d69 --- /dev/null +++ b/test/Sample.Api.v8.Tests/Sample.Api.v8.Tests.csproj @@ -0,0 +1,33 @@ + + + + net8.0;net9.0 + $(DefineConstants);FAV8 + + + + + + + + + + + + + + + + + + + + + + + %(RecursiveDir)%(Filename)%(Extension) + PreserveNewest + + + +