diff --git a/FluentAssertions.Web.sln b/FluentAssertions.Web.sln
index 7410898..86a7a02 100644
--- a/FluentAssertions.Web.sln
+++ b/FluentAssertions.Web.sln
@@ -47,6 +47,8 @@ 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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -101,6 +103,10 @@ 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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -119,6 +125,7 @@ Global
{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}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {81F41C75-2F8A-4E70-BA17-38146C4BB6E6}
@@ -130,6 +137,7 @@ Global
Samples\Sample.Api.Shared\Sample.Api.Shared.projitems*{a0b5b518-714a-4731-b371-996d5fbc72a0}*SharedItemsImports = 5
Samples\Sample.Api.Shared\Sample.Api.Shared.projitems*{a62abbae-bfb8-467a-9fbc-974172c718e2}*SharedItemsImports = 5
Samples\Sample.Api.Shared\Sample.Api.Shared.projitems*{bae9e107-74fe-4c37-a528-857ac73d2c55}*SharedItemsImports = 5
+ 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
EndGlobalSection
EndGlobal
diff --git a/common.tests.props b/common.tests.props
index 7637d9c..1da1a75 100644
--- a/common.tests.props
+++ b/common.tests.props
@@ -2,7 +2,7 @@
- netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0
+ netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0
latest
enable
CS8600;CS8602;CS8603
diff --git a/readme.md b/readme.md
index 877bf67..b906718 100644
--- a/readme.md
+++ b/readme.md
@@ -15,10 +15,13 @@ public async Task Post_ReturnsOk()
var client = _factory.CreateClient();
// Act
- var response = await client.PostAsync("/api/comments", new StringContent(@"{
- ""author"": ""John"",
- ""content"": ""Hey, you...""
- }", Encoding.UTF8, "application/json"));
+ var response = await client.PostAsync("/api/comments", new StringContent(
+ """
+ {
+ "author": "John",
+ "content": "Hey, you..."
+ }
+ """, Encoding.UTF8, "application/json"));
// Assert
response.Should().Be200Ok();
@@ -58,10 +61,13 @@ public async Task Post_ReturnsOkAndWithContent()
var client = _factory.CreateClient();
// Act
- var response = await client.PostAsync("/api/comments", new StringContent(@"{
- ""author"": ""John"",
- ""content"": ""Hey, you...""
- }", Encoding.UTF8, "application/json"));
+ var response = await client.PostAsync("/api/comments", new StringContent(
+ """
+ {
+ "author": "John",
+ "content": "Hey, you..."
+ }
+ """, Encoding.UTF8, "application/json"));
// Assert
response.Should().BeAs(new
@@ -102,9 +108,12 @@ public async Task Post_WithNoAuthorButWithContent_ReturnsBadRequestWithAnErrorMe
var client = _factory.CreateClient();
// Act
- var response = await client.PostAsync("/api/comments", new StringContent(@"{
- ""content"": ""Hey, you...""
- }", Encoding.UTF8, "application/json"));
+ var response = await client.PostAsync("/api/comments", new StringContent(
+ """
+ {
+ "content": "Hey, you..."
+ }
+ """, Encoding.UTF8, "application/json"));
// Assert
response.Should().Be400BadRequest()
@@ -155,7 +164,7 @@ public async Task Get_WithCommentId_Returns_A_NonSpam_Comment()
}
```
-- Asserting the response has a header like `X-Correlation-ID` header of `application/json; charset=utf-8`
+- Asserting the response has a header with the name `X-Correlation-ID` and the value matches a certain pattern
```csharp
[Fact]
@@ -172,6 +181,23 @@ public async Task Get_Should_Contain_a_Header_With_Correlation_Id()
}
```
+- Asserting the response has a header with the name `X-Correlation-ID` and the value is not empty
+
+```csharp
+[Fact]
+public async Task Get_Should_Contain_a_Header_With_Correlation_Id()
+{
+ // Arrange
+ var client = _factory.CreateClient();
+
+ // Act
+ var response = await client.GetAsync("/api/values");
+
+ // Assert
+ response.Should().HaveHeader("X-Correlation-ID").And.NotBeEmpty();
+}
+```
+
Many more examples can be found in the [Samples](https://github.com/adrianiftode/FluentAssertions.Web/tree/master/samples) projects and in the Specs files from the [FluentAssertions.Web.Tests](https://github.com/adrianiftode/FluentAssertions.Web/tree/master/test/FluentAssertions.Web.Tests) project
## Optional Global Configuration
@@ -210,86 +236,88 @@ NewtonsoftJsonSerializerConfig.Options.Converters.Add(new YesNoBooleanJsonConver
## Full API
-| *HttpResponseMessageAssertions* | Contains a number of methods to assert that an HttpResponseMessage is in the expected state related to the HTTP content. |
+| *HttpResponseMessageAssertions* | Contains a number of methods to assert that an HttpResponseMessage is in the expected state related to the HTTP content. |
+| --- | --- |
+| **Should().BeAs<TModel>()** | Asserts that HTTP response content can be an equivalent representation of the expected model. |
+| **Should().HaveHeader()** | Asserts that an HTTP response has a named header. |
+| **Should().NotHaveHeader()** | Asserts that an HTTP response does not have a named header. |
+| **Should().HaveHttpStatus()** | Asserts that a HTTP response has a HTTP status with the specified code. |
+| **Should().NotHaveHttpStatus()** | that a HTTP response does not have a HTTP status with the specified code. |
+| **Should().MatchInContent()** | Asserts that HTTP response has content that matches a wildcard pattern. |
+| **Should().Satisfy<TModel>()** | Asserts that an HTTP response content can be a model that satisfies an assertion. |
+| **Should().Satisfy<HttpResponseMessage>()** | Asserts that an HTTP response content can be a model that satisfies an assertion. |
+
+| *Should().HaveHeader().And.* | Contains a number of methods to assert that an HttpResponseMessage is in the expected state related to HTTP headers. |
| --- | --- |
-| **Should().BeAs<TModel>()** | Asserts that HTTP response content can be an equivalent representation of the expected model. |
-| **Should().HaveHeader()** | Asserts that an HTTP response has a named header. |
-| **Should().NotHaveHeader()** | Asserts that an HTTP response does not have a named header. |
-| **Should().HaveHttpStatus()** | Asserts that a HTTP response has a HTTP status with the specified code. |
-| **Should().NotHaveHttpStatus()** | that a HTTP response does not have a HTTP status with the specified code. |
-| **Should().MatchInContent()** | Asserts that HTTP response has content that matches a wildcard pattern. |
-| **Should().Satisfy<TModel>()** | Asserts that an HTTP response content can be a model that satisfies an assertion. |
-| **Should().Satisfy<HttpResponseMessage>()** | Asserts that an HTTP response content can be a model that satisfies an assertion. |
-
-| *Should().HaveHeader().And.* | Contains a number of methods to assert that an HttpResponseMessage is in the expected state related to HTTP headers. |
-| --- | --- |
-| **BeEmpty()** | Asserts that an existing HTTP header in a HTTP response has no values. |
-| **BeValues()** | Asserts that an existing HTTP header in a HTTP response has an expected list of header values. |
-| **Match()** | Asserts that an existing HTTP header in a HTTP response contains at least a value that matches a wildcard pattern. |
-
-| *Should().Be400BadRequest().And.* | Contains a number of methods to assert that an HttpResponseMessage is in the expected state related to HTTP Bad Request response |
-| --- | --- |
-| **HaveError()** | Asserts that a Bad Request HTTP response content contains an error message identifiable by an expected field name and a wildcard error text. |
-| **OnlyHaveError()** | 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. |
-| **NotHaveError()** | Asserts that a Bad Request HTTP response content does not contain an error message identifiable by an expected field name and a wildcard error text. |
-| **HaveErrorMessage()** | Asserts that a Bad Request HTTP response content contains an error message identifiable by an wildcard error text. |
-
-| *Fine grained status assertions.* | |
+| **BeEmpty()** | Asserts that an existing HTTP header in a HTTP response has no values. |
+| **NotBeEmpty()** | Asserts that an existing HTTP header in a HTTP response has any values. |
+| **BeValue()** |Asserts that an existing HTTP header in a HTTP response has an expected value. |
+| **BeValues()** | Asserts that an existing HTTP header in a HTTP response has an expected list of header values. |
+| **Match()** | Asserts that an existing HTTP header in a HTTP response contains at least a value that matches a wildcard pattern. |
+
+| *Should().Be400BadRequest().And.* | Contains a number of methods to assert that an HttpResponseMessage is in the expected state related to HTTP Bad Request response |
+| --- | --- |
+| **HaveError()** | Asserts that a Bad Request HTTP response content contains an error message identifiable by an expected field name and a wildcard error text. |
+| **OnlyHaveError()** | 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. |
+| **NotHaveError()** | Asserts that a Bad Request HTTP response content does not contain an error message identifiable by an expected field name and a wildcard error text. |
+| **HaveErrorMessage()** | Asserts that a Bad Request HTTP response content contains an error message identifiable by an wildcard error text. |
+
+| *Fine grained status assertions.* | |
| --- | --- |
-| **Should().Be1XXInformational()** | Asserts that a HTTP response has a HTTP status code representing an informational response. |
-| **Should().Be2XXSuccessful()** | Asserts that a HTTP response has a successful HTTP status code. |
-| **Should().Be4XXClientError()** | Asserts that a HTTP response has a HTTP status code representing a client error. |
-| **Should().Be3XXRedirection()** | Asserts that a HTTP response has a HTTP status code representing a redirection response. |
-| **Should().Be5XXServerError()** | Asserts that a HTTP response has a HTTP status code representing a server error. |
-| **Should().Be100Continue()** | Asserts that a HTTP response has the HTTP status 100 Continue |
-| **Should().Be101SwitchingProtocols()** | Asserts that a HTTP response has the HTTP status 101 Switching Protocols |
-| **Should().Be200Ok()** | Asserts that a HTTP response has the HTTP status 200 Ok |
-| **Should().Be201Created()** | Asserts that a HTTP response has the HTTP status 201 Created |
-| **Should().Be202Accepted()** | Asserts that a HTTP response has the HTTP status 202 Accepted |
-| **Should().Be203NonAuthoritativeInformation()** | Asserts that a HTTP response has the HTTP status 203 Non Authoritative Information |
-| **Should().Be204NoContent()** | Asserts that a HTTP response has the HTTP status 204 No Content |
-| **Should().Be205ResetContent()** | Asserts that a HTTP response has the HTTP status 205 Reset Content |
-| **Should().Be206PartialContent()** | Asserts that a HTTP response has the HTTP status 206 Partial Content |
-| **Should().Be300Ambiguous()** | Asserts that a HTTP response has the HTTP status 300 Ambiguous |
-| **Should().Be300MultipleChoices()** | Asserts that a HTTP response has the HTTP status 300 Multiple Choices |
-| **Should().Be301Moved()** | Asserts that a HTTP response has the HTTP status 301 Moved Permanently |
-| **Should().Be301MovedPermanently()** | Asserts that a HTTP response has the HTTP status 301 Moved Permanently |
-| **Should().Be302Found()** | Asserts that a HTTP response has the HTTP status 302 Found |
-| **Should().Be302Redirect()** | Asserts that a HTTP response has the HTTP status 302 Redirect |
-| **Should().Be303RedirectMethod()** | Asserts that a HTTP response has the HTTP status 303 Redirect Method |
-| **Should().Be303SeeOther()** | Asserts that a HTTP response has the HTTP status 303 See Other |
-| **Should().Be304NotModified()** | Asserts that a HTTP response has the HTTP status 304 Not Modified |
-| **Should().Be305UseProxy()** | Asserts that a HTTP response has the HTTP status 305 Use Proxy |
-| **Should().Be306Unused()** | Asserts that a HTTP response has the HTTP status 306 Unused |
-| **Should().Be307RedirectKeepVerb()** | Asserts that a HTTP response has the HTTP status 307 Redirect Keep Verb |
-| **Should().Be307TemporaryRedirect()** | Asserts that a HTTP response has the HTTP status 307 Temporary Redirect |
-| **Should().Be400BadRequest()** | Asserts that a HTTP response has the HTTP status 400 BadRequest |
-| **Should().Be401Unauthorized()** | Asserts that a HTTP response has the HTTP status 401 Unauthorized |
-| **Should().Be402PaymentRequired()** | Asserts that a HTTP response has the HTTP status 402 Payment Required |
-| **Should().Be403Forbidden()** | Asserts that a HTTP response has the HTTP status 403 Forbidden |
-| **Should().Be404NotFound()** | Asserts that a HTTP response has the HTTP status 404 Not Found |
-| **Should().Be405MethodNotAllowed()** | Asserts that a HTTP response has the HTTP status 405 Method Not Allowed |
-| **Should().Be406NotAcceptable()** | Asserts that a HTTP response has the HTTP status 406 Not Acceptable |
-| **Should().Be407ProxyAuthenticationRequired()** | Asserts that a HTTP response has the HTTP status 407 Proxy Authentication Required |
-| **Should().Be408RequestTimeout()** | Asserts that a HTTP response has the HTTP status 408 Request Timeout |
-| **Should().Be409Conflict()** | Asserts that a HTTP response has the HTTP status 409 Conflict |
-| **Should().Be410Gone()** | Asserts that a HTTP response has the HTTP status 410 Gone |
-| **Should().Be411LengthRequired()** | Asserts that a HTTP response has the HTTP status 411 Length Required |
-| **Should().Be412PreconditionFailed()** | Asserts that a HTTP response has the HTTP status 412 Precondition Failed |
-| **Should().Be413RequestEntityTooLarge()** | Asserts that a HTTP response has the HTTP status 413 Request Entity Too Large |
-| **Should().Be414RequestUriTooLong()** | Asserts that a HTTP response has the HTTP status 414 Request Uri Too Long |
-| **Should().Be415UnsupportedMediaType()** | Asserts that a HTTP response has the HTTP status 415 Unsupported Media Type |
-| **Should().Be416RequestedRangeNotSatisfiable()** | Asserts that a HTTP response has the HTTP status 416 Requested Range Not Satisfiable |
-| **Should().Be417ExpectationFailed()** | Asserts that a HTTP response has the HTTP status 417 Expectation Failed |
-| **Should().Be422UnprocessableEntity()** | Asserts that a HTTP response has the HTTP status 422 Unprocessable Entity |
-| **Should().Be426UpgradeRequired()** | Asserts that a HTTP response has the HTTP status 426 UpgradeRequired |
-| **Should().Be429TooManyRequests()** | Asserts that a HTTP response has the HTTP status 422 Too Many Requests |
-| **Should().Be500InternalServerError()** | Asserts that a HTTP response has the HTTP status 500 Internal Server Error |
-| **Should().Be501NotImplemented()** | Asserts that a HTTP response has the HTTP status 501 Not Implemented |
-| **Should().Be502BadGateway()** | Asserts that a HTTP response has the HTTP status 502 Bad Gateway |
-| **Should().Be503ServiceUnavailable()** | Asserts that a HTTP response has the HTTP status 503 Service Unavailable |
-| **Should().Be504GatewayTimeout()** | Asserts that a HTTP response has the HTTP status 504 Gateway Timeout |
-| **Should().Be505HttpVersionNotSupported()** | Asserts that a HTTP response has the HTTP status 505 Http Version Not Supported |
+| **Should().Be1XXInformational()** | Asserts that a HTTP response has a HTTP status code representing an informational response. |
+| **Should().Be2XXSuccessful()** | Asserts that a HTTP response has a successful HTTP status code. |
+| **Should().Be4XXClientError()** | Asserts that a HTTP response has a HTTP status code representing a client error. |
+| **Should().Be3XXRedirection()** | Asserts that a HTTP response has a HTTP status code representing a redirection response. |
+| **Should().Be5XXServerError()** | Asserts that a HTTP response has a HTTP status code representing a server error. |
+| **Should().Be100Continue()** | Asserts that a HTTP response has the HTTP status 100 Continue |
+| **Should().Be101SwitchingProtocols()** | Asserts that a HTTP response has the HTTP status 101 Switching Protocols |
+| **Should().Be200Ok()** | Asserts that a HTTP response has the HTTP status 200 Ok |
+| **Should().Be201Created()** | Asserts that a HTTP response has the HTTP status 201 Created |
+| **Should().Be202Accepted()** | Asserts that a HTTP response has the HTTP status 202 Accepted |
+| **Should().Be203NonAuthoritativeInformation()** | Asserts that a HTTP response has the HTTP status 203 Non Authoritative Information |
+| **Should().Be204NoContent()** | Asserts that a HTTP response has the HTTP status 204 No Content |
+| **Should().Be205ResetContent()** | Asserts that a HTTP response has the HTTP status 205 Reset Content |
+| **Should().Be206PartialContent()** | Asserts that a HTTP response has the HTTP status 206 Partial Content |
+| **Should().Be300Ambiguous()** | Asserts that a HTTP response has the HTTP status 300 Ambiguous |
+| **Should().Be300MultipleChoices()** | Asserts that a HTTP response has the HTTP status 300 Multiple Choices |
+| **Should().Be301Moved()** | Asserts that a HTTP response has the HTTP status 301 Moved Permanently |
+| **Should().Be301MovedPermanently()** | Asserts that a HTTP response has the HTTP status 301 Moved Permanently |
+| **Should().Be302Found()** | Asserts that a HTTP response has the HTTP status 302 Found |
+| **Should().Be302Redirect()** | Asserts that a HTTP response has the HTTP status 302 Redirect |
+| **Should().Be303RedirectMethod()** | Asserts that a HTTP response has the HTTP status 303 Redirect Method |
+| **Should().Be303SeeOther()** | Asserts that a HTTP response has the HTTP status 303 See Other |
+| **Should().Be304NotModified()** | Asserts that a HTTP response has the HTTP status 304 Not Modified |
+| **Should().Be305UseProxy()** | Asserts that a HTTP response has the HTTP status 305 Use Proxy |
+| **Should().Be306Unused()** | Asserts that a HTTP response has the HTTP status 306 Unused |
+| **Should().Be307RedirectKeepVerb()** | Asserts that a HTTP response has the HTTP status 307 Redirect Keep Verb |
+| **Should().Be307TemporaryRedirect()** | Asserts that a HTTP response has the HTTP status 307 Temporary Redirect |
+| **Should().Be400BadRequest()** | Asserts that a HTTP response has the HTTP status 400 BadRequest |
+| **Should().Be401Unauthorized()** | Asserts that a HTTP response has the HTTP status 401 Unauthorized |
+| **Should().Be402PaymentRequired()** | Asserts that a HTTP response has the HTTP status 402 Payment Required |
+| **Should().Be403Forbidden()** | Asserts that a HTTP response has the HTTP status 403 Forbidden |
+| **Should().Be404NotFound()** | Asserts that a HTTP response has the HTTP status 404 Not Found |
+| **Should().Be405MethodNotAllowed()** | Asserts that a HTTP response has the HTTP status 405 Method Not Allowed |
+| **Should().Be406NotAcceptable()** | Asserts that a HTTP response has the HTTP status 406 Not Acceptable |
+| **Should().Be407ProxyAuthenticationRequired()** | Asserts that a HTTP response has the HTTP status 407 Proxy Authentication Required |
+| **Should().Be408RequestTimeout()** | Asserts that a HTTP response has the HTTP status 408 Request Timeout |
+| **Should().Be409Conflict()** | Asserts that a HTTP response has the HTTP status 409 Conflict |
+| **Should().Be410Gone()** | Asserts that a HTTP response has the HTTP status 410 Gone |
+| **Should().Be411LengthRequired()** | Asserts that a HTTP response has the HTTP status 411 Length Required |
+| **Should().Be412PreconditionFailed()** | Asserts that a HTTP response has the HTTP status 412 Precondition Failed |
+| **Should().Be413RequestEntityTooLarge()** | Asserts that a HTTP response has the HTTP status 413 Request Entity Too Large |
+| **Should().Be414RequestUriTooLong()** | Asserts that a HTTP response has the HTTP status 414 Request Uri Too Long |
+| **Should().Be415UnsupportedMediaType()** | Asserts that a HTTP response has the HTTP status 415 Unsupported Media Type |
+| **Should().Be416RequestedRangeNotSatisfiable()** | Asserts that a HTTP response has the HTTP status 416 Requested Range Not Satisfiable |
+| **Should().Be417ExpectationFailed()** | Asserts that a HTTP response has the HTTP status 417 Expectation Failed |
+| **Should().Be422UnprocessableEntity()** | Asserts that a HTTP response has the HTTP status 422 Unprocessable Entity |
+| **Should().Be426UpgradeRequired()** | Asserts that a HTTP response has the HTTP status 426 UpgradeRequired |
+| **Should().Be429TooManyRequests()** | Asserts that a HTTP response has the HTTP status 422 Too Many Requests |
+| **Should().Be500InternalServerError()** | Asserts that a HTTP response has the HTTP status 500 Internal Server Error |
+| **Should().Be501NotImplemented()** | Asserts that a HTTP response has the HTTP status 501 Not Implemented |
+| **Should().Be502BadGateway()** | Asserts that a HTTP response has the HTTP status 502 Bad Gateway |
+| **Should().Be503ServiceUnavailable()** | Asserts that a HTTP response has the HTTP status 503 Service Unavailable |
+| **Should().Be504GatewayTimeout()** | Asserts that a HTTP response has the HTTP status 504 Gateway Timeout |
+| **Should().Be505HttpVersionNotSupported()** | Asserts that a HTTP response has the HTTP status 505 Http Version Not Supported |
### The HttpResponsesMessage assertions from FluentAssertions vs. FluentAssertions.Web
diff --git a/samples/Sample.Api.Net50/Sample.Api.Net50.csproj b/samples/Sample.Api.Net50/Sample.Api.Net50.csproj
index 221c18d..25488b5 100644
--- a/samples/Sample.Api.Net50/Sample.Api.Net50.csproj
+++ b/samples/Sample.Api.Net50/Sample.Api.Net50.csproj
@@ -3,7 +3,9 @@
net5.0
true
+ false
false
+ false
diff --git a/samples/Sample.Api.Net70/Properties/launchSettings.json b/samples/Sample.Api.Net70/Properties/launchSettings.json
new file mode 100644
index 0000000..77e49fd
--- /dev/null
+++ b/samples/Sample.Api.Net70/Properties/launchSettings.json
@@ -0,0 +1,30 @@
+{
+ "$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
new file mode 100644
index 0000000..c9cfb8c
--- /dev/null
+++ b/samples/Sample.Api.Net70/Sample.Api.Net70.csproj
@@ -0,0 +1,11 @@
+
+
+
+ net7.0
+ true
+ false
+
+
+
+
+
diff --git a/samples/Sample.Api.Shared/Controllers/CommentsController.cs b/samples/Sample.Api.Shared/Controllers/CommentsController.cs
index 9b9e8d4..c554bb0 100644
--- a/samples/Sample.Api.Shared/Controllers/CommentsController.cs
+++ b/samples/Sample.Api.Shared/Controllers/CommentsController.cs
@@ -16,7 +16,11 @@ public IEnumerable Get() => new[]
};
[HttpGet("{id}")]
- public Comment Get(int id) => new Comment { Author = "Adrian", Content = "Hey", CommentId = id };
+ public Comment Get(int id)
+ {
+ Response.Headers.Add("x-vendor", "vendor");
+ return new Comment { Author = "Adrian", Content = "Hey", CommentId = id };
+ }
[HttpPost]
public Comment Post([FromBody] Comment value) => value;
diff --git a/samples/Sample.Api.Tests/CommentsControllerTests.cs b/samples/Sample.Api.Tests/CommentsControllerTests.cs
index 820514f..030aafe 100644
--- a/samples/Sample.Api.Tests/CommentsControllerTests.cs
+++ b/samples/Sample.Api.Tests/CommentsControllerTests.cs
@@ -106,6 +106,19 @@ public async Task Get_WithCommentId_Returns_Response_That_Satisfies_Several_Asse
);
}
+ [Fact]
+ public async Task Get_Returns_Response_With_A_Certain_Header()
+ {
+ // Arrange
+ var client = _factory.CreateClient();
+
+ // Act
+ var response = await client.GetAsync("/api/comments/1");
+
+ // Assert
+ response.Should().HaveHeader("x-vendor").And.BeValue("vendor", "we want to test the header has a specific value");
+ }
+
[Fact]
public async Task Post_ReturnsOk()
{
@@ -113,7 +126,7 @@ public async Task Post_ReturnsOk()
var client = _factory.CreateClient();
// Act
- var response = await client.PostAsync("/api/comments", new StringContent(@"{
+ var response = await client.PostAsync("/api/comments", new StringContent(/*lang=json,strict*/ @"{
""author"": ""John"",
""content"": ""Hey, you...""
}", Encoding.UTF8, "application/json"));
@@ -129,7 +142,7 @@ public async Task Post_ReturnsOkAndWithContent()
var client = _factory.CreateClient();
// Act
- var response = await client.PostAsync("/api/comments", new StringContent(@"{
+ var response = await client.PostAsync("/api/comments", new StringContent(/*lang=json,strict*/ @"{
""author"": ""John"",
""content"": ""Hey, you...""
}", Encoding.UTF8, "application/json"));
@@ -168,7 +181,7 @@ public async Task Post_WithNoAuthorAndNoContent_ReturnsBadRequest()
var client = _factory.CreateClient();
// Act
- var response = await client.PostAsync("/api/comments", new StringContent(@"{
+ var response = await client.PostAsync("/api/comments", new StringContent(/*lang=json,strict*/ @"{
""author"": """",
""content"": """"
}", Encoding.UTF8, "application/json"));
@@ -186,7 +199,7 @@ public async Task Post_WithNoAuthor_ReturnsBadRequestWithUsefulMessage()
var client = _factory.CreateClient();
// Act
- var response = await client.PostAsync("/api/comments", new StringContent(@"{
+ var response = await client.PostAsync("/api/comments", new StringContent(/*lang=json,strict*/ @"{
""content"": ""Hey, you...""
}", Encoding.UTF8, "application/json"));
@@ -203,7 +216,7 @@ public async Task Post_WithNoAuthorButWithContent_ReturnsBadRequestWithAnErrorMe
var client = _factory.CreateClient();
// Act
- var response = await client.PostAsync("/api/comments", new StringContent(@"{
+ var response = await client.PostAsync("/api/comments", new StringContent(/*lang=json,strict*/ @"{
""content"": ""Hey, you...""
}", Encoding.UTF8, "application/json"));
diff --git a/samples/Sample.Api.Tests/Sample.Api.Tests.csproj b/samples/Sample.Api.Tests/Sample.Api.Tests.csproj
index 258eb76..5e16866 100644
--- a/samples/Sample.Api.Tests/Sample.Api.Tests.csproj
+++ b/samples/Sample.Api.Tests/Sample.Api.Tests.csproj
@@ -26,6 +26,8 @@
+
+
@@ -34,6 +36,11 @@
+
+
+
+
+
diff --git a/samples/Sample.Api.Tests/ValuesControllerTests.cs b/samples/Sample.Api.Tests/ValuesControllerTests.cs
index 71874dc..2ba8ec6 100644
--- a/samples/Sample.Api.Tests/ValuesControllerTests.cs
+++ b/samples/Sample.Api.Tests/ValuesControllerTests.cs
@@ -140,7 +140,7 @@ public async Task Post_WithNoContent_ReturnsBadRequest()
}
[Fact]
- public async Task Get_Should_Contain_a_Header_With_Correlation_Id()
+ public async Task Get_Should_Contain_a_Header_With_Correlation_Id_That_Matches_A_Guid_Like_Pattern()
{
// Arrange
var client = _factory.CreateClient();
@@ -151,5 +151,18 @@ public async Task Get_Should_Contain_a_Header_With_Correlation_Id()
// Assert
response.Should().HaveHeader("X-Correlation-ID").And.Match("*-*", "we want to test the correlation id is a Guid like one");
}
+
+ [Fact]
+ public async Task Get_Should_Contain_a_Header_With_Correlation_Id()
+ {
+ // Arrange
+ var client = _factory.CreateClient();
+
+ // Act
+ var response = await client.GetAsync("/api/values");
+
+ // Assert
+ response.Should().HaveHeader("X-Correlation-ID").And.NotBeEmpty("we want to test the correlation id header has some value");
+ }
}
}
diff --git a/src/FluentAssertions.Web.Serializers.NewtonsoftJson/GlobalUsings.cs b/src/FluentAssertions.Web.Serializers.NewtonsoftJson/GlobalUsings.cs
new file mode 100644
index 0000000..bafb58d
--- /dev/null
+++ b/src/FluentAssertions.Web.Serializers.NewtonsoftJson/GlobalUsings.cs
@@ -0,0 +1,5 @@
+global using Newtonsoft.Json;
+global using System;
+global using System.IO;
+global using System.Text;
+global using System.Threading.Tasks;
diff --git a/src/FluentAssertions.Web.Serializers.NewtonsoftJson/NewtonsoftJsonSerializer.cs b/src/FluentAssertions.Web.Serializers.NewtonsoftJson/NewtonsoftJsonSerializer.cs
index 29da43b..a21cbd0 100644
--- a/src/FluentAssertions.Web.Serializers.NewtonsoftJson/NewtonsoftJsonSerializer.cs
+++ b/src/FluentAssertions.Web.Serializers.NewtonsoftJson/NewtonsoftJsonSerializer.cs
@@ -1,34 +1,27 @@
// ReSharper disable once CheckNamespace
-using Newtonsoft.Json;
-using System;
-using System.IO;
-using System.Text;
-using System.Threading.Tasks;
+namespace FluentAssertions;
-namespace FluentAssertions
+///
+/// Newtonsoft.Json based serializer
+///
+public class NewtonsoftJsonSerializer : ISerializer
{
- ///
- /// Newtonsoft.Json based serializer
- ///
- public class NewtonsoftJsonSerializer : ISerializer
+ ///
+ public Task Deserialize(Stream content, Type modelType)
{
- ///
- public Task Deserialize(Stream content, Type modelType)
+ try
{
- try
- {
- var serializer = JsonSerializer.Create(NewtonsoftJsonSerializerConfig.Options);
+ var serializer = JsonSerializer.Create(NewtonsoftJsonSerializerConfig.Options);
- using var sr = new StreamReader(content, Encoding.UTF8, true, 1024, leaveOpen: true);
- using var reader = new JsonTextReader(sr);
- var result = serializer.Deserialize(reader, modelType);
- return Task.FromResult((object?)result);
- }
+ using var sr = new StreamReader(content, Encoding.UTF8, true, 1024, leaveOpen: true);
+ using var reader = new JsonTextReader(sr);
+ var result = serializer.Deserialize(reader, modelType);
+ return Task.FromResult((object?)result);
+ }
- catch (JsonException ex)
- {
- throw new DeserializationException($"Exception while deserializing the model with {nameof(NewtonsoftJsonSerializer)}", ex);
- }
+ catch (JsonException ex)
+ {
+ throw new DeserializationException($"Exception while deserializing the model with {nameof(NewtonsoftJsonSerializer)}", ex);
}
}
}
diff --git a/src/FluentAssertions.Web.Serializers.NewtonsoftJson/NewtonsoftJsonSerializerConfig.cs b/src/FluentAssertions.Web.Serializers.NewtonsoftJson/NewtonsoftJsonSerializerConfig.cs
index 5513341..00edda7 100644
--- a/src/FluentAssertions.Web.Serializers.NewtonsoftJson/NewtonsoftJsonSerializerConfig.cs
+++ b/src/FluentAssertions.Web.Serializers.NewtonsoftJson/NewtonsoftJsonSerializerConfig.cs
@@ -1,17 +1,13 @@
-using System.Text.Json;
-using Newtonsoft.Json;
+// ReSharper disable once CheckNamespace
+namespace FluentAssertions;
-// ReSharper disable once CheckNamespace
-namespace FluentAssertions
+///
+/// Holder of the global
+///
+public static class NewtonsoftJsonSerializerConfig
{
///
- /// Holder of the global
+ /// The options used to deserialize a JSON into a C# object
///
- public static class NewtonsoftJsonSerializerConfig
- {
- ///
- /// The options used to deserialize a JSON into a C# object
- ///
- public static readonly JsonSerializerSettings Options = new();
- }
+ public static readonly JsonSerializerSettings Options = new();
}
diff --git a/src/FluentAssertions.Web/BadRequestAssertions.cs b/src/FluentAssertions.Web/BadRequestAssertions.cs
index 5b93b45..9a1aa9e 100644
--- a/src/FluentAssertions.Web/BadRequestAssertions.cs
+++ b/src/FluentAssertions.Web/BadRequestAssertions.cs
@@ -1,271 +1,262 @@
-using FluentAssertions.Execution;
-using FluentAssertions.Web.Internal;
-using System;
-using System.Linq;
-using System.Net.Http;
-using System.Text.Json;
-using System.Threading.Tasks;
-
-namespace FluentAssertions.Web
+namespace FluentAssertions.Web;
+
+///
+/// Contains a number of methods to assert that an is in the expected state related to HTTP Bad Request response
+///
+public class BadRequestAssertions : HttpResponseMessageAssertions
{
+ private const string ErrorsPropertyName = "errors";
+
///
- /// Contains a number of methods to assert that an is in the expected state related to HTTP Bad Request response
+ /// Initialized a new instance of the
+ /// class.
///
- public class BadRequestAssertions : HttpResponseMessageAssertions
+ /// The subject value to be asserted.
+ public BadRequestAssertions(HttpResponseMessage value) : base(value)
{
- private const string ErrorsPropertyName = "errors";
-
- ///
- /// Initialized a new instance of the
- /// class.
- ///
- /// The subject value to be asserted.
- public BadRequestAssertions(HttpResponseMessage value) : base(value)
- {
- }
-
- ///
- /// Returns the type of the subject the assertion applies on.
- ///
- protected override string Identifier => "BadRequest";
-
- ///
- /// 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 AndConstraint HaveError(string expectedErrorField, string expectedWildcardErrorMessage,
- string because = "", params object[] becauseArgs)
- {
- Guard.ThrowIfArgumentIsNullOrEmpty(expectedErrorField, nameof(expectedErrorField), "Cannot verify having an error against a or empty field name.");
- Guard.ThrowIfArgumentIsNullOrEmpty(expectedWildcardErrorMessage, nameof(expectedWildcardErrorMessage), "Cannot verify having an error against a or empty wildcard error message.");
-
- Func> jsonFunc = () => Subject.GetJsonDocument();
- using var json = jsonFunc.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
-
- var errorsProperty = json.GetPropertiesByName(ErrorsPropertyName).ToList();
- var hasErrorsProperty = errorsProperty.Any();
- var fieldsOfErrorsProperty = json.GetChildrenNames(ErrorsPropertyName);
- var allFields = json.GetChildrenNames("");
- var fields = hasErrorsProperty ? fieldsOfErrorsProperty : allFields;
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(fields.Any(field => string.Equals(field, expectedErrorField, StringComparison.OrdinalIgnoreCase)))
- .FailWith("Expected {context:response} " +
- "to contain an error message related to the {0} field, but was not found." +
- "{1}",
- expectedErrorField, Subject);
-
- var errorsMessages = hasErrorsProperty ? errorsProperty.First().GetStringValuesOf(expectedErrorField) : json.GetStringValuesOf(expectedErrorField);
- var matchFound = errorsMessages.Any(errorMessage =>
- {
- using var scope = new AssertionScope();
- errorMessage.Should().Match(expectedWildcardErrorMessage);
- return !scope.Discard().Any();
- });
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(matchFound)
- .FailWith("Expected {context:response} to contain " +
- "the error message {0} related to the {1} field, " +
- "but no such message was found in the actual error messages list: " +
- "{2}",
- expectedWildcardErrorMessage,
- expectedErrorField,
- Subject);
-
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint OnlyHaveError(string expectedErrorField, string expectedWildcardErrorMessage,
- string because = "", params object[] becauseArgs)
+ }
+
+ ///
+ /// Returns the type of the subject the assertion applies on.
+ ///
+ protected override string Identifier => "BadRequest";
+
+ ///
+ /// 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 AndConstraint HaveError(string expectedErrorField, string expectedWildcardErrorMessage,
+ string because = "", params object[] becauseArgs)
+ {
+ Guard.ThrowIfArgumentIsNullOrEmpty(expectedErrorField, nameof(expectedErrorField), "Cannot verify having an error against a or empty field name.");
+ Guard.ThrowIfArgumentIsNullOrEmpty(expectedWildcardErrorMessage, nameof(expectedWildcardErrorMessage), "Cannot verify having an error against a or empty wildcard error message.");
+
+ Func> jsonFunc = () => Subject.GetJsonDocument();
+ using var json = jsonFunc.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
+
+ var errorsProperty = json.GetPropertiesByName(ErrorsPropertyName).ToList();
+ var hasErrorsProperty = errorsProperty.Any();
+ var fieldsOfErrorsProperty = json.GetChildrenNames(ErrorsPropertyName);
+ var allFields = json.GetChildrenNames("");
+ var fields = hasErrorsProperty ? fieldsOfErrorsProperty : allFields;
+
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(fields.Any(field => string.Equals(field, expectedErrorField, StringComparison.OrdinalIgnoreCase)))
+ .FailWith("Expected {context:response} " +
+ "to contain an error message related to the {0} field, but was not found." +
+ "{1}",
+ expectedErrorField, Subject);
+
+ var errorsMessages = hasErrorsProperty ? errorsProperty.First().GetStringValuesOf(expectedErrorField) : json.GetStringValuesOf(expectedErrorField);
+ var matchFound = errorsMessages.Any(errorMessage =>
{
- Guard.ThrowIfArgumentIsNullOrEmpty(expectedErrorField, nameof(expectedErrorField), "Cannot verify having only an error against a or empty field name.");
- Guard.ThrowIfArgumentIsNullOrEmpty(expectedWildcardErrorMessage, nameof(expectedWildcardErrorMessage), "Cannot verify having only an error against a or empty wildcard error message.");
-
- Func> jsonFunc = () => Subject.GetJsonDocument();
- using var json = jsonFunc.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
-
- var errorsProperty = json.GetPropertiesByName(ErrorsPropertyName).ToList();
- var hasErrorsProperty = errorsProperty.Any();
- var fieldsOfErrorsProperty = json.GetChildrenNames(ErrorsPropertyName);
- var allFields = json.GetChildrenNames("");
- var fields = hasErrorsProperty ? fieldsOfErrorsProperty : allFields;
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(fields.Any(field => string.Equals(field, expectedErrorField, StringComparison.OrdinalIgnoreCase)))
- .FailWith("Expected {context:response} " +
- "to contain an error message related to the {0} field, but was not found." +
- "{1}",
- expectedErrorField, Subject);
-
- var parent = hasErrorsProperty ? ErrorsPropertyName : json.GetParentKey(expectedErrorField);
- var children = json.GetChildrenNames(parent);
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(children.Count() == 1)
- .FailWith("Expected {context:response} " +
- "to only contain an error message related to the {0} field, but more than this one was found." +
- "{1}",
- expectedErrorField, Subject);
-
- var values = json.GetStringValuesOf(expectedErrorField);
- var expectedWildcardErrorMessageMatchFound = values.Any(headerValue =>
- {
- using var scope = new AssertionScope();
- headerValue.Should().Match(expectedWildcardErrorMessage);
- return !scope.Discard().Any();
- });
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(expectedWildcardErrorMessageMatchFound)
- .FailWith("Expected {context:response} to contain " +
- "the error message {0} related to the {1} field, " +
- "but no such message was found in the actual error messages list: " +
- "{2}",
- expectedWildcardErrorMessage,
- expectedErrorField,
- Subject);
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(values.Count() == 1)
- .FailWith("Expected {context:response} " +
- "to only contain an error message related to the {0} field and message {1}, but more than this one was found." +
- "{2}",
- expectedErrorField, expectedWildcardErrorMessage, Subject);
-
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint NotHaveError(string expectedErrorField, string because = "", params object[] becauseArgs)
+ using var scope = new AssertionScope();
+ errorMessage.Should().Match(expectedWildcardErrorMessage);
+ return !scope.Discard().Any();
+ });
+
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(matchFound)
+ .FailWith("Expected {context:response} to contain " +
+ "the error message {0} related to the {1} field, " +
+ "but no such message was found in the actual error messages list: " +
+ "{2}",
+ expectedWildcardErrorMessage,
+ expectedErrorField,
+ Subject);
+
+ return new AndConstraint(this);
+ }
+
+ ///
+ /// 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 AndConstraint OnlyHaveError(string expectedErrorField, string expectedWildcardErrorMessage,
+ string because = "", params object[] becauseArgs)
+ {
+ Guard.ThrowIfArgumentIsNullOrEmpty(expectedErrorField, nameof(expectedErrorField), "Cannot verify having only an error against a or empty field name.");
+ Guard.ThrowIfArgumentIsNullOrEmpty(expectedWildcardErrorMessage, nameof(expectedWildcardErrorMessage), "Cannot verify having only an error against a or empty wildcard error message.");
+
+ Func> jsonFunc = () => Subject.GetJsonDocument();
+ using var json = jsonFunc.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
+
+ var errorsProperty = json.GetPropertiesByName(ErrorsPropertyName).ToList();
+ var hasErrorsProperty = errorsProperty.Any();
+ var fieldsOfErrorsProperty = json.GetChildrenNames(ErrorsPropertyName);
+ var allFields = json.GetChildrenNames("");
+ var fields = hasErrorsProperty ? fieldsOfErrorsProperty : allFields;
+
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(fields.Any(field => string.Equals(field, expectedErrorField, StringComparison.OrdinalIgnoreCase)))
+ .FailWith("Expected {context:response} " +
+ "to contain an error message related to the {0} field, but was not found." +
+ "{1}",
+ expectedErrorField, Subject);
+
+ var parent = hasErrorsProperty ? ErrorsPropertyName : json.GetParentKey(expectedErrorField);
+ var children = json.GetChildrenNames(parent);
+
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(children.Count() == 1)
+ .FailWith("Expected {context:response} " +
+ "to only contain an error message related to the {0} field, but more than this one was found." +
+ "{1}",
+ expectedErrorField, Subject);
+
+ var values = json.GetStringValuesOf(expectedErrorField);
+ var expectedWildcardErrorMessageMatchFound = values.Any(headerValue =>
{
- Guard.ThrowIfArgumentIsNullOrEmpty(expectedErrorField, nameof(expectedErrorField), "Cannot verify not having an error against a or empty field name.");
-
- Func> jsonFunc = () => Subject.GetJsonDocument();
- using var json = jsonFunc.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
-
- var errorsProperty = json.GetPropertiesByName(ErrorsPropertyName).ToList();
- var hasErrorsProperty = errorsProperty.Any();
- var fieldsOfErrorsProperty = json.GetChildrenNames(ErrorsPropertyName);
- var allFields = json.GetChildrenNames("");
- var fields = hasErrorsProperty ? fieldsOfErrorsProperty : allFields;
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(!fields.Any(c => string.Equals(c, expectedErrorField, StringComparison.OrdinalIgnoreCase)))
- .FailWith("Expected {context:response} " +
- "to not contain an error message related to the {0} field, but was found.{1}",
- expectedErrorField, Subject);
-
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint HaveErrorMessage(string expectedWildcardErrorMessage,
- string because = "", params object[] becauseArgs)
+ using var scope = new AssertionScope();
+ headerValue.Should().Match(expectedWildcardErrorMessage);
+ return !scope.Discard().Any();
+ });
+
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(expectedWildcardErrorMessageMatchFound)
+ .FailWith("Expected {context:response} to contain " +
+ "the error message {0} related to the {1} field, " +
+ "but no such message was found in the actual error messages list: " +
+ "{2}",
+ expectedWildcardErrorMessage,
+ expectedErrorField,
+ Subject);
+
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(values.Count() == 1)
+ .FailWith("Expected {context:response} " +
+ "to only contain an error message related to the {0} field and message {1}, but more than this one was found." +
+ "{2}",
+ expectedErrorField, expectedWildcardErrorMessage, Subject);
+
+ return new AndConstraint(this);
+ }
+
+ ///
+ /// 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 AndConstraint NotHaveError(string expectedErrorField, string because = "", params object[] becauseArgs)
+ {
+ Guard.ThrowIfArgumentIsNullOrEmpty(expectedErrorField, nameof(expectedErrorField), "Cannot verify not having an error against a or empty field name.");
+
+ Func> jsonFunc = () => Subject.GetJsonDocument();
+ using var json = jsonFunc.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
+
+ var errorsProperty = json.GetPropertiesByName(ErrorsPropertyName).ToList();
+ var hasErrorsProperty = errorsProperty.Any();
+ var fieldsOfErrorsProperty = json.GetChildrenNames(ErrorsPropertyName);
+ var allFields = json.GetChildrenNames("");
+ var fields = hasErrorsProperty ? fieldsOfErrorsProperty : allFields;
+
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(!fields.Any(c => string.Equals(c, expectedErrorField, StringComparison.OrdinalIgnoreCase)))
+ .FailWith("Expected {context:response} " +
+ "to not contain an error message related to the {0} field, but was found.{1}",
+ expectedErrorField, Subject);
+
+ return new AndConstraint(this);
+ }
+
+ ///
+ /// 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 AndConstraint HaveErrorMessage(string expectedWildcardErrorMessage,
+ string because = "", params object[] becauseArgs)
+ {
+ Guard.ThrowIfArgumentIsNullOrEmpty(expectedWildcardErrorMessage, nameof(expectedWildcardErrorMessage), "Cannot verify having an error against a or empty wildcard error message.");
+
+ Func> jsonFunc = () => Subject.GetJsonDocument();
+ using var json = jsonFunc.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
+
+ var errorsPropertyList = json.GetPropertiesByName(ErrorsPropertyName).ToList();
+ var hasErrorsProperty = errorsPropertyList.Any();
+ var errorsProperty = errorsPropertyList.FirstOrDefault();
+ var allErrors = hasErrorsProperty ? json.GetChildrenNames(ErrorsPropertyName).SelectMany(field => errorsProperty.GetStringValuesOf(field)) : json.GetChildrenNames("").SelectMany(field => json.GetStringValuesOf(field));
+
+ var matchFound = allErrors.Any(errorMessage =>
{
- Guard.ThrowIfArgumentIsNullOrEmpty(expectedWildcardErrorMessage, nameof(expectedWildcardErrorMessage), "Cannot verify having an error against a or empty wildcard error message.");
-
- Func> jsonFunc = () => Subject.GetJsonDocument();
- using var json = jsonFunc.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
-
- var errorsPropertyList = json.GetPropertiesByName(ErrorsPropertyName).ToList();
- var hasErrorsProperty = errorsPropertyList.Any();
- var errorsProperty = errorsPropertyList.FirstOrDefault();
- var allErrors = hasErrorsProperty ? json.GetChildrenNames(ErrorsPropertyName).SelectMany(field => errorsProperty.GetStringValuesOf(field)) : json.GetChildrenNames("").SelectMany(field => json.GetStringValuesOf(field));
-
- var matchFound = allErrors.Any(errorMessage =>
- {
- using var scope = new AssertionScope();
- errorMessage.Should().Match(expectedWildcardErrorMessage);
- return !scope.Discard().Any();
- });
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(matchFound)
- .FailWith("Expected {context:response} to contain " +
- "the error message {0}, " +
- "but no such message was found in the actual error messages list: " +
- "{1}",
- expectedWildcardErrorMessage,
- Subject);
-
- return new AndConstraint(this);
- }
+ using var scope = new AssertionScope();
+ errorMessage.Should().Match(expectedWildcardErrorMessage);
+ return !scope.Discard().Any();
+ });
+
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(matchFound)
+ .FailWith("Expected {context:response} to contain " +
+ "the error message {0}, " +
+ "but no such message was found in the actual error messages list: " +
+ "{1}",
+ expectedWildcardErrorMessage,
+ Subject);
+
+ return new AndConstraint(this);
}
}
\ No newline at end of file
diff --git a/src/FluentAssertions.Web/BadRequestAssertionsExtensions.cs b/src/FluentAssertions.Web/BadRequestAssertionsExtensions.cs
index cb7f376..ce11c79 100644
--- a/src/FluentAssertions.Web/BadRequestAssertionsExtensions.cs
+++ b/src/FluentAssertions.Web/BadRequestAssertionsExtensions.cs
@@ -1,115 +1,111 @@
-using FluentAssertions.Web;
-using System.Diagnostics;
+// ReSharper disable once CheckNamespace
+namespace FluentAssertions;
-// ReSharper disable once CheckNamespace
-namespace FluentAssertions
+///
+/// Contains extension methods for custom assertions in unit tests related to .
+///
+[DebuggerNonUserCode]
+public static class BadRequestAssertionsExtensions
{
///
- /// Contains extension methods for custom assertions in unit tests related to .
+ /// Asserts that a Bad Request HTTP response content contains an error message identifiable by an expected field name and a wildcard error text.
///
- [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(
+ ///
+ /// 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,
+ 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);
+ 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(
+ ///
+ /// 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,
+ 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);
+ 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(
+ ///
+ /// 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,
+ this Primitives.HttpResponseMessageAssertions parent,
#pragma warning restore 1573
- string expectedErrorField, string because = "", params object[] becauseArgs)
- => new BadRequestAssertions(parent.Subject).NotHaveError(expectedErrorField, because, becauseArgs);
+ 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(
+ ///
+ /// 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,
+ this Primitives.HttpResponseMessageAssertions parent,
#pragma warning restore 1573
- string expectedWildcardErrorMessage,
- string because = "", params object[] becauseArgs)
- => new BadRequestAssertions(parent.Subject).HaveErrorMessage(expectedWildcardErrorMessage, because, becauseArgs);
- }
+ 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/DeserializationException.cs b/src/FluentAssertions.Web/DeserializationException.cs
index e22ebda..b7b45c3 100644
--- a/src/FluentAssertions.Web/DeserializationException.cs
+++ b/src/FluentAssertions.Web/DeserializationException.cs
@@ -1,49 +1,47 @@
// ReSharper disable once CheckNamespace
-using System;
using System.Runtime.Serialization;
-namespace FluentAssertions
+namespace FluentAssertions;
+
+///
+/// Captures serialization exceptions.
+///
+[Serializable]
+public class DeserializationException : Exception
{
///
- /// Captures serialization exceptions.
+ /// Argless constructor used to created new instances of this class.
+ ///
+ public DeserializationException()
+ {
+ }
+
+ ///
+ /// Constructor used to created new instances of this class given a certain message.
///
- [Serializable]
- public class DeserializationException : Exception
+ /// The exception message.
+
+ public DeserializationException(string message) : base(message)
+ {
+ }
+
+ ///
+ /// Constructor used to created new instances of this class given a certain message and an exception.
+ ///
+ /// The exception message.
+ /// Usually the caught inner exception.
+
+ public DeserializationException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+
+ ///
+ /// Specialized constructor used to deserialize eventually serialized exceptions of this type.
+ ///
+ /// Serialization info.
+ /// Streaming context
+
+ protected DeserializationException(SerializationInfo info, StreamingContext context) : base(info, context)
{
- ///
- /// Argless constructor used to created new instances of this class.
- ///
- public DeserializationException()
- {
- }
-
- ///
- /// Constructor used to created new instances of this class given a certain message.
- ///
- /// The exception message.
-
- public DeserializationException(string message) : base(message)
- {
- }
-
- ///
- /// Constructor used to created new instances of this class given a certain message and an exception.
- ///
- /// The exception message.
- /// Usually the caught inner exception.
-
- public DeserializationException(string message, Exception innerException) : base(message, innerException)
- {
- }
-
- ///
- /// Specialized constructor used to deserialize eventually serialized exceptions of this type.
- ///
- /// Serialization info.
- /// Streaming context
-
- protected DeserializationException(SerializationInfo info, StreamingContext context) : base(info, context)
- {
- }
}
}
diff --git a/src/FluentAssertions.Web/FluentAssertionsWebConfig.cs b/src/FluentAssertions.Web/FluentAssertionsWebConfig.cs
index 46b7372..4f0317f 100644
--- a/src/FluentAssertions.Web/FluentAssertionsWebConfig.cs
+++ b/src/FluentAssertions.Web/FluentAssertionsWebConfig.cs
@@ -1,26 +1,22 @@
-using FluentAssertions.Web.Internal.Serializers;
-using System;
+// ReSharper disable once CheckNamespace
+namespace FluentAssertions;
-// ReSharper disable once CheckNamespace
-namespace FluentAssertions
+///
+/// Holder of the global
+///
+public static class FluentAssertionsWebConfig
{
+ private static ISerializer? _serializer;
+
+ static FluentAssertionsWebConfig() => Serializer = new SystemTextJsonSerializer();
+
///
- /// Holder of the global
+ /// The serializer instance used to deserialize the responses into a model of a specified typed
///
- public static class FluentAssertionsWebConfig
+ public static ISerializer Serializer
{
- private static ISerializer? _serializer;
-
- static FluentAssertionsWebConfig() => Serializer = new SystemTextJsonSerializer();
-
- ///
- /// The serializer instance used to deserialize the responses into a model of a specified typed
- ///
- public static ISerializer Serializer
- {
- get => _serializer ?? throw new InvalidOperationException("Serializer cannot be null");
+ get => _serializer ?? throw new InvalidOperationException("Serializer cannot be null");
- set => _serializer = value ?? throw new ArgumentNullException(nameof(value), "Serializer cannot be null.");
- }
+ set => _serializer = value ?? throw new ArgumentNullException(nameof(value), "Serializer cannot be null.");
}
}
diff --git a/src/FluentAssertions.Web/GlobalUsings.cs b/src/FluentAssertions.Web/GlobalUsings.cs
new file mode 100644
index 0000000..d6b1d98
--- /dev/null
+++ b/src/FluentAssertions.Web/GlobalUsings.cs
@@ -0,0 +1,14 @@
+global using FluentAssertions.Equivalency;
+global using FluentAssertions.Execution;
+global using FluentAssertions.Web;
+global using FluentAssertions.Web.Internal;
+global using FluentAssertions.Web.Internal.Serializers;
+global using System;
+global using System.Collections.Generic;
+global using System.Diagnostics;
+global using System.IO;
+global using System.Linq;
+global using System.Net;
+global using System.Net.Http;
+global using System.Text.Json;
+global using System.Threading.Tasks;
diff --git a/src/FluentAssertions.Web/HaveHeaderAssertions.cs b/src/FluentAssertions.Web/HaveHeaderAssertions.cs
index 1190640..5a2215a 100644
--- a/src/FluentAssertions.Web/HaveHeaderAssertions.cs
+++ b/src/FluentAssertions.Web/HaveHeaderAssertions.cs
@@ -1,217 +1,285 @@
-using FluentAssertions.Execution;
-using FluentAssertions.Web.Internal;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net.Http;
-
-namespace FluentAssertions.Web
+namespace FluentAssertions.Web;
+
+///
+/// Contains a number of methods to assert that an is in the expected state related to HTTP headers.
+///
+public class HeadersAssertions : HttpResponseMessageAssertions
{
+ private readonly string _header;
+
+ ///
+ /// Initialized a new instance of the
+ /// class.
+ ///
+ /// The subject value to be asserted.
+ /// The HTTP header name to be asserted.
+ public HeadersAssertions(HttpResponseMessage value, string header) : base(value) => _header = header;
+
///
- /// Contains a number of methods to assert that an is in the expected state related to HTTP headers.
+ /// Asserts that an existing HTTP header in a HTTP response contains at least a value that matches a wildcard pattern.
///
- public class HeadersAssertions : HttpResponseMessageAssertions
+ ///
+ /// 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 AndConstraint Match(string expectedWildcardValue, string because = "", params object[] becauseArgs)
{
- private readonly string _header;
-
- ///
- /// Initialized a new instance of the
- /// class.
- ///
- /// The subject value to be asserted.
- /// The HTTP header name to be asserted.
- public HeadersAssertions(HttpResponseMessage value, string header) : base(value) => _header = header;
-
- ///
- /// Asserts that an existing HTTP header in a HTTP response contains at least a value that matches a wildcard pattern.
- ///
- ///
- /// The wildcard pattern with which the subject 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 AndConstraint Match(string expectedWildcardValue, string because = "", params object[] becauseArgs)
- {
- 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
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- IEnumerable headerValues = Subject!.GetHeaderValues(_header);
-
- var matchFound = headerValues.Any(headerValue =>
- {
- using var scope = new AssertionScope();
- headerValue.Should().Match(expectedWildcardValue);
- return !scope.Discard().Any();
- });
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(matchFound)
- .FailWith("Expected {context:response} to contain " +
- "the HTTP header {0} having a value matching {1}, but there was no match{reason}. {2}",
- _header,
- expectedWildcardValue,
- Subject);
-
- return new AndConstraint(this);
- }
+ 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.");
- ///
- /// Asserts that an existing HTTP header in a HTTP response has no values.
- ///
- ///
- /// 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 AndConstraint BeEmpty(string because = "", params object[] becauseArgs)
- {
- var headerValues = Subject.GetHeaderValues(_header);
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(!headerValues.Any())
- .FailWith("Expected {context:response} to contain " +
- "the HTTP header {0} with no header values, but the found the header and it has values {1} in the actual response{reason}. {2}",
- _header,
- headerValues,
- Subject);
-
- return new AndConstraint(this);
- }
+ Execute.Assertion
+ .ForCondition(Subject is not null)
+ .BecauseOf(because, becauseArgs)
+ .FailWith("Expected a {context:response} to assert{reason}, but found .");
- ///
- /// Asserts that an existing HTTP header in a HTTP response has an expected list of header values.
- ///
- ///
- /// The expected values with which the HTTP headers values list is compared.
- ///
- ///
- /// 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 AndConstraint BeValues(IEnumerable expectedValues,
- string because = "", params object[] becauseArgs)
- {
- Guard.ThrowIfArgumentIsNull(expectedValues, nameof(expectedValues), "Cannot verify a HTTP header to be a collection of expected values against a collection. Use And.BeEmpty to test if the HTTP header has no values.");
- if (!expectedValues.Any())
- {
- throw new ArgumentException("Cannot verify a HTTP header to be a collection of expected values against an empty collection. Use And.BeEmpty to test if the HTTP header has no values.", nameof(expectedValues));
- }
+ IEnumerable headerValues = Subject!.GetHeaderValues(_header);
- var values = Subject.GetHeaders().FirstOrDefault(c => c.Key == _header).Value;
+ var matchFound = headerValues.Any(headerValue =>
+ {
+ using var scope = new AssertionScope();
+ headerValue.Should().Match(expectedWildcardValue);
+ return !scope.Discard().Any();
+ });
- string[] failures;
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(matchFound)
+ .FailWith("Expected {context:response} to contain " +
+ "the HTTP header {0} having a value matching {1}, but there was no match{reason}. {2}",
+ _header,
+ expectedWildcardValue,
+ Subject);
- using (var scope = new AssertionScope())
- {
- values.Should().BeEquivalentTo(expectedValues);
+ return new AndConstraint(this);
+ }
- failures = scope.Discard();
- }
+ ///
+ /// Asserts that an existing HTTP header in a HTTP response has no values.
+ ///
+ ///
+ /// 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 AndConstraint BeEmpty(string because = "", params object[] becauseArgs)
+ {
+ var headerValues = Subject.GetHeaderValues(_header);
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(failures.Length == 0)
- .FailWith("Expected {context:response} to contain " +
- "the HTTP header {0} having values {1}, but the found values have differences{reason}. {2}",
- _header,
- expectedValues,
- Subject);
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(!headerValues.Any())
+ .FailWith("Expected {context:response} to contain " +
+ "the HTTP header {0} with no header values, but found the header and it has values {1} in the actual response{reason}. {2}",
+ _header,
+ headerValues,
+ Subject);
- return new AndConstraint(this);
- }
+ return new AndConstraint(this);
+ }
+ ///
+ /// Asserts that an existing HTTP header in a HTTP response has any values.
+ ///
+ ///
+ /// 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 AndConstraint NotBeEmpty(string because = "", params object[] becauseArgs)
+ {
+ var headerValues = Subject.GetHeaderValues(_header);
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(headerValues.Any())
+ .FailWith("Expected {context:response} to contain " +
+ "the HTTP header {0} with any header values, but found the header and it has no values in the actual response{reason}. {2}",
+ _header,
+ headerValues,
+ Subject);
- ///
- /// Returns the type of the subject the assertion applies on.
- ///
- protected override string Identifier => "Header";
+ return new AndConstraint(this);
}
- public partial class HttpResponseMessageAssertions
+ ///
+ /// Asserts that an existing HTTP header in a HTTP response has an expected list of header values.
+ ///
+ ///
+ /// The expected values with which the HTTP headers values list is compared.
+ ///
+ ///
+ /// 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 AndConstraint BeValues(IEnumerable expectedValues,
+ string because = "", params object[] becauseArgs)
{
- ///
- /// 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 AndConstraint HaveHeader(string expectedHeader,
- string because = "", params object[] becauseArgs)
+ Guard.ThrowIfArgumentIsNull(expectedValues, nameof(expectedValues), "Cannot verify a HTTP header to be a collection of expected values against a collection. Use And.BeEmpty to test if the HTTP header has no values.");
+ if (!expectedValues.Any())
{
- Guard.ThrowIfArgumentIsNull(expectedHeader, nameof(expectedHeader), "Cannot verify having a header against a header.");
+ throw new ArgumentException("Cannot verify a HTTP header to be a collection of expected values against an empty collection. Use And.BeEmpty to test if the HTTP header has no values.", nameof(expectedValues));
+ }
- Execute.Assertion
- .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);
+ var values = Subject.GetHeaders().FirstOrDefault(c => c.Key == _header).Value;
- return new AndConstraint(new HeadersAssertions(Subject, expectedHeader));
- }
+ string[] failures;
- ///
- /// 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 AndConstraint NotHaveHeader(string expectedHeader,
- string because = "", params object[] becauseArgs)
+ using (var scope = new AssertionScope())
{
- Guard.ThrowIfArgumentIsNull(expectedHeader, nameof(expectedHeader), "Cannot verify not having a header against a header.");
+ values.Should().BeEquivalentTo(expectedValues);
+
+ failures = scope.Discard();
+ }
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(!IsHeaderPresent(expectedHeader))
- .FailWith("Expected {context:response} to not to contain " +
- "the HTTP header {0}, but the header was found in the actual response{reason}.{1}",
- expectedHeader,
- Subject);
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(failures.Length == 0)
+ .FailWith("Expected {context:response} to contain " +
+ "the HTTP header {0} having values {1}, but the found values have differences{reason}. {2}",
+ _header,
+ expectedValues,
+ Subject);
- return new AndConstraint(this);
+ return new AndConstraint(this);
+ }
+
+ ///
+ /// Asserts that an existing HTTP header in a HTTP response has an expected value.
+ ///
+ ///
+ /// The expected value with which the HTTP header value list is compared.
+ ///
+ ///
+ /// 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 AndConstraint BeValue(string expectedValue,
+ string because = "", params object[] becauseArgs)
+ {
+ 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
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(Subject.GetHeaderValues(_header).Count() == 1)
+ .FailWith($$"""
+ Expected {context:response} to contain the {0} HTTP header and the value to be equivalent to "{{expectedValue}}", but found the header and has more or no values{reason}.{1}
+ """, _header, Subject);
+
+ var value = Subject.GetFirstHeaderValue(_header);
+
+ string[] failures;
+
+ using (var scope = new AssertionScope("header value"))
+ {
+ value.Should().BeEquivalentTo(expectedValue);
+
+ failures = scope.Discard();
}
- private bool IsHeaderPresent(string expectedHeader)
- => Subject
- .GetHeaders()
- .Any(c => string.Equals(c.Key, expectedHeader, StringComparison.OrdinalIgnoreCase));
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(failures.Length == 0)
+ .FailWith($$"""
+ Expected {context:response} to contain the {0} HTTP header and the {{ failures.FirstOrDefault()?.ReplaceFirstWithLowercase().TrimDot() }}{reason}.{1}
+ """, _header, Subject);
+
+ return new AndConstraint(this);
+ }
+
+ ///
+ /// Returns the type of the subject the assertion applies on.
+ ///
+ protected override string Identifier => "Header";
+}
+
+public partial class HttpResponseMessageAssertions
+{
+ ///
+ /// 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 AndConstraint HaveHeader(string expectedHeader,
+ string because = "", params object[] becauseArgs)
+ {
+ Guard.ThrowIfArgumentIsNull(expectedHeader, nameof(expectedHeader), "Cannot verify having a header against a header.");
+
+ Execute.Assertion
+ .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);
+
+ return new AndConstraint(new HeadersAssertions(Subject, expectedHeader));
+ }
+
+ ///
+ /// 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 AndConstraint NotHaveHeader(string expectedHeader,
+ string because = "", params object[] becauseArgs)
+ {
+ Guard.ThrowIfArgumentIsNull(expectedHeader, nameof(expectedHeader), "Cannot verify not having a header against a header.");
+
+ Execute.Assertion
+ .BecauseOf(because, becauseArgs)
+ .ForCondition(!IsHeaderPresent(expectedHeader))
+ .FailWith("Expected {context:response} to not to contain " +
+ "the HTTP header {0}, but the header was found in the actual response{reason}.{1}",
+ expectedHeader,
+ Subject);
+
+ return new AndConstraint(this);
}
+
+ private bool IsHeaderPresent(string expectedHeader)
+ => Subject
+ .GetHeaders()
+ .Any(c => string.Equals(c.Key, expectedHeader, StringComparison.OrdinalIgnoreCase));
}
\ No newline at end of file
diff --git a/src/FluentAssertions.Web/HaveHeaderAssertionsExtensions.cs b/src/FluentAssertions.Web/HaveHeaderAssertionsExtensions.cs
index a32ff53..e565ff9 100644
--- a/src/FluentAssertions.Web/HaveHeaderAssertionsExtensions.cs
+++ b/src/FluentAssertions.Web/HaveHeaderAssertionsExtensions.cs
@@ -1,56 +1,52 @@
-using FluentAssertions.Web;
-using System.Diagnostics;
+namespace FluentAssertions;
-namespace FluentAssertions
+///
+/// Contains extension methods for custom assertions in unit tests related to .
+///
+[DebuggerNonUserCode]
+public static class HeadersAssertionsExtensions
{
///
- /// Contains extension methods for custom assertions in unit tests related to .
+ /// Asserts that an HTTP response has a named header.
///
- [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(
+ ///
+ /// 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,
+ this Primitives.HttpResponseMessageAssertions parent,
#pragma warning restore 1573
- string expectedHeader,
- string because = "", params object[] becauseArgs)
- => new HttpResponseMessageAssertions(parent.Subject).HaveHeader(expectedHeader, because, becauseArgs);
+ 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(
+ ///
+ /// 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,
+ this Primitives.HttpResponseMessageAssertions parent,
#pragma warning restore 1573
- string expectedHeader,
- string because = "", params object[] becauseArgs)
- => new HttpResponseMessageAssertions(parent.Subject).NotHaveHeader(expectedHeader, because, becauseArgs);
- }
+ 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 eb9560a..faf5a86 100644
--- a/src/FluentAssertions.Web/HttpResponseContentAssertions.cs
+++ b/src/FluentAssertions.Web/HttpResponseContentAssertions.cs
@@ -1,154 +1,144 @@
-using FluentAssertions.Equivalency;
-using FluentAssertions.Execution;
-using FluentAssertions.Web.Internal;
-using System;
-using System.Net.Http;
+namespace FluentAssertions.Web;
-namespace FluentAssertions.Web
+///
+/// Contains a number of methods to assert that an is in the expected state related to the HTTP content.
+///
+public partial class HttpResponseMessageAssertions
{
///
- /// Contains a number of methods to assert that an is in the expected state related to the HTTP content.
+ /// Asserts that HTTP response content can be an equivalent representation of the expected model.
///
- public partial class HttpResponseMessageAssertions
- {
- ///
- /// 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 AndConstraint BeAs(TModel expectedModel, string because = "", params object[] becauseArgs)
- => BeAs(expectedModel, options => options, 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 AndConstraint BeAs(TModel expectedModel, Func, EquivalencyAssertionOptions> options, string because = "", params object[] becauseArgs)
- {
- Guard.ThrowIfArgumentIsNull(options, nameof(options));
+ ///
+ /// 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 AndConstraint BeAs(TModel expectedModel, string because = "", params object[] becauseArgs)
+ => BeAs(expectedModel, options => options, because, becauseArgs);
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
+ ///
+ /// 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 AndConstraint BeAs(TModel expectedModel, Func, EquivalencyAssertionOptions> options, string because = "", params object[] becauseArgs)
+ {
+ Guard.ThrowIfArgumentIsNull(options, nameof(options));
- if (expectedModel == null)
- {
- throw new ArgumentNullException(nameof(expectedModel), "Cannot verify having a content equivalent to a model against a model.");
- }
+ Execute.Assertion
+ .ForCondition(Subject is not null)
+ .BecauseOf(because, becauseArgs)
+ .FailWith("Expected a {context:response} to assert{reason}, but found .");
- var expectedModelType = expectedModel.GetType();
+ if (expectedModel == null)
+ {
+ throw new ArgumentNullException(nameof(expectedModel), "Cannot verify having a content equivalent to a model against a model.");
+ }
- var (success, errorMessage) = TryGetSubjectModel(out var subjectModel, expectedModelType);
+ var expectedModelType = expectedModel.GetType();
- Execute.Assertion
- .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}",
- expectedModelType?.ToString() ?? "unknown type", Subject, errorMessage);
-
- string[] failures;
-
- using (var scope = new AssertionScope())
- {
- if (options != null)
- {
- subjectModel.Should().BeEquivalentTo(expectedModel, options);
- }
- else
- {
- subjectModel.Should().BeEquivalentTo(expectedModel);
- }
-
- failures = scope.Discard();
- }
+ var (success, errorMessage) = TryGetSubjectModel(out var subjectModel, expectedModelType);
- Execute.Assertion
- .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}",
- new AssertionsFailures(failures),
- Subject);
+ Execute.Assertion
+ .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}",
+ expectedModelType.ToString() ?? "unknown type", Subject, errorMessage);
- return new AndConstraint(this);
- }
+ string[] failures;
- ///
- /// 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.
- ///
- ///
- /// 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 AndConstraint MatchInContent(string expectedWildcardText, string because = "", params object[] becauseArgs)
+ using (var scope = new AssertionScope())
{
- Guard.ThrowIfArgumentIsNull(expectedWildcardText, nameof(expectedWildcardText), "Cannot verify a HTTP response content match a wildcard pattern.");
+ subjectModel.Should().BeEquivalentTo(expectedModel, options);
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
+ failures = scope.Discard();
+ }
- var content = GetContent();
+ Execute.Assertion
+ .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}",
+ new AssertionsFailures(failures),
+ Subject);
- if (string.IsNullOrEmpty(content))
- {
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected {context:response} to match the wildcard pattern {0} in its content, but content was {reason}. {1}",
- expectedWildcardText,
- Subject);
- }
+ return new AndConstraint(this);
+ }
- string[] failures;
+ ///
+ /// 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 AndConstraint MatchInContent(string expectedWildcardText, string because = "", params object[] becauseArgs)
+ {
+ Guard.ThrowIfArgumentIsNull(expectedWildcardText, nameof(expectedWildcardText), "Cannot verify a HTTP response content match a wildcard pattern.");
- using (var scope = new AssertionScope())
- {
- content.Should().Match(expectedWildcardText);
+ Execute.Assertion
+ .ForCondition(Subject is not null)
+ .BecauseOf(because, becauseArgs)
+ .FailWith("Expected a {context:response} to assert{reason}, but found .");
- failures = scope.Discard();
- }
+ var content = GetContent();
+ if (string.IsNullOrEmpty(content))
+ {
Execute.Assertion
- .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}",
- new AssertionsFailures(failures),
- Subject);
+ .BecauseOf(because, becauseArgs)
+ .FailWith("Expected {context:response} to match the wildcard pattern {0} in its content, but content was {reason}. {1}",
+ expectedWildcardText,
+ Subject);
+ }
- return new AndConstraint(this);
+ string[] failures;
+
+ using (var scope = new AssertionScope())
+ {
+ content.Should().Match(expectedWildcardText);
+
+ failures = scope.Discard();
}
+
+ Execute.Assertion
+ .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}",
+ new AssertionsFailures(failures),
+ Subject);
+
+ return new AndConstraint(this);
}
}
\ No newline at end of file
diff --git a/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs b/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs
index b08ee52..c2d7ad5 100644
--- a/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs
+++ b/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs
@@ -1,83 +1,81 @@
-using FluentAssertions.Equivalency;
-using FluentAssertions.Web;
-using System;
-using System.Diagnostics;
+namespace FluentAssertions;
-namespace FluentAssertions
+///
+/// Contains extension methods for custom assertions in unit tests related to Http Response Content Assertions
+///
+[DebuggerNonUserCode]
+public static class HttpResponseContentAssertionsExtensions
{
///
- /// Contains extension methods for custom assertions in unit tests related to Http Response Content Assertions
+ /// Asserts that HTTP response content can be an equivalent representation of the expected model.
///
- [DebuggerNonUserCode]
- public static class HttpResponseContentAssertionsExtensions
- {
- ///
- /// 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(
+ ///
+ /// 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,
+ 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);
+ 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(
+ ///
+ /// 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,
+ this Primitives.HttpResponseMessageAssertions parent,
#pragma warning restore 1573
- TModel expectedModel, string because = "", params object[] becauseArgs)
- => new HttpResponseMessageAssertions(parent.Subject).BeAs(expectedModel, because, becauseArgs);
+ 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.
- ///
- ///
- /// 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(
+ ///
+ /// 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,
+ this Primitives.HttpResponseMessageAssertions parent,
#pragma warning restore 1573,
- string expectedWildcardText, string because = "", params object[] becauseArgs)
- => new HttpResponseMessageAssertions(parent.Subject).MatchInContent(expectedWildcardText, because, becauseArgs);
- }
+ 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 98bf7fa..eedc382 100644
--- a/src/FluentAssertions.Web/HttpResponseMessageAssertions.cs
+++ b/src/FluentAssertions.Web/HttpResponseMessageAssertions.cs
@@ -1,95 +1,88 @@
-using FluentAssertions.Execution;
-using FluentAssertions.Formatting;
+using FluentAssertions.Formatting;
using FluentAssertions.Primitives;
-using FluentAssertions.Web.Internal;
-using System;
-using System.Net;
-using System.Net.Http;
-using System.Threading.Tasks;
-namespace FluentAssertions.Web
+namespace FluentAssertions.Web;
+
+///
+/// Contains a number of methods to assert that an is in the expected state.
+///
+public partial class HttpResponseMessageAssertions : ReferenceTypeAssertions
{
+ static HttpResponseMessageAssertions()
+ {
+ Formatter.AddFormatter(new HttpResponseMessageFormatter());
+ Formatter.AddFormatter(new AssertionsFailuresFormatter());
+ }
+
///
- /// Contains a number of methods to assert that an is in the expected state.
+ /// Initialized a new instance of the
+ /// class.
///
- public partial class HttpResponseMessageAssertions : ReferenceTypeAssertions
- {
- static HttpResponseMessageAssertions()
- {
- Formatter.AddFormatter(new HttpResponseMessageFormatter());
- Formatter.AddFormatter(new AssertionsFailuresFormatter());
- }
+ /// The subject value to be asserted.
+ public HttpResponseMessageAssertions(HttpResponseMessage value) : base(value) { }
- ///
- /// Initialized a new instance of the
- /// class.
- ///
- /// The subject value to be asserted.
- public HttpResponseMessageAssertions(HttpResponseMessage value) : base(value) { }
+ ///
+ /// Returns the type of the subject the assertion applies on.
+ ///
+ protected override string Identifier => $"{nameof(HttpResponseMessage)}";
- ///
- /// Returns the type of the subject the assertion applies on.
- ///
- protected override string Identifier => $"{nameof(HttpResponseMessage)}";
+ private protected string? GetContent()
+ {
+ Func> content = () => Subject.GetStringContent();
+ return content.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
+ }
- private protected string? GetContent()
- {
- Func> content = () => Subject.GetStringContent();
- return content.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
- }
+ private protected (bool success, string? errorMessage) TryGetSubjectModel(out TModel? model)
+ {
+ var (success, errorMessage) = TryGetSubjectModel(out var subjectModel, typeof(TModel));
+ model = (TModel?)subjectModel;
+ return (success, errorMessage);
+ }
- private protected (bool success, string? errorMessage) TryGetSubjectModel(out TModel? model)
+ private protected (bool success, string? errorMessage) TryGetSubjectModel(out object? model, Type modelType)
+ {
+ Func> readModel = () => Subject.Content.ReadAsAsync(modelType, FluentAssertionsWebConfig.Serializer);
+ try
{
- var (success, errorMessage) = TryGetSubjectModel(out var subjectModel, typeof(TModel));
- model = (TModel?)subjectModel;
- return (success, errorMessage);
+ model = readModel.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
+ return (true, null);
}
-
- private protected (bool success, string? errorMessage) TryGetSubjectModel(out object? model, Type modelType)
+ catch (Exception ex) when (ex is DeserializationException or NotSupportedException)
{
- Func> readModel = () => Subject.Content.ReadAsAsync(modelType, FluentAssertionsWebConfig.Serializer);
- try
+ model = default;
+ var message = ex.Message;
+ if (ex.InnerException != null)
{
- model = readModel.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
- return (true, null);
+ message += $": {ex.InnerException.Message}";
}
- catch (Exception ex) when (ex is DeserializationException || ex is NotSupportedException)
- {
- model = default;
- var message = ex.Message;
- if (ex.InnerException != null)
- {
- message += $": {ex.InnerException.Message}";
- }
- return (false, message);
- }
+ return (false, message);
}
+ }
- private string[] CollectFailuresFromAssertion(Action assertion, TAsserted subject)
+ private string[] CollectFailuresFromAssertion(Action assertion, TAsserted subject)
+ {
+ using var collectionScope = new AssertionScope();
+ string[] assertionFailures;
+ using (var itemScope = new AssertionScope())
{
- using var collectionScope = new AssertionScope();
- string[] assertionFailures;
- using (var itemScope = new AssertionScope())
+ try
{
- try
- {
- assertion(subject);
- assertionFailures = itemScope.Discard();
- }
- catch (Exception ex)
- {
- assertionFailures = new[] { $"Expected to successfully verify an assertion, but the following exception occurred: { ex }" };
- }
-
+ assertion(subject);
+ assertionFailures = itemScope.Discard();
}
-
- foreach (var assertionFailure in assertionFailures)
+ catch (Exception ex)
{
- collectionScope.AddPreFormattedFailure($"{assertionFailure}");
+ assertionFailures = new[] { $"Expected to successfully verify an assertion, but the following exception occurred: { ex }" };
}
- return collectionScope.Discard();
}
+
+ foreach (var assertionFailure in assertionFailures)
+ {
+ collectionScope.AddPreFormattedFailure($"{assertionFailure}");
+ }
+
+ return collectionScope.Discard();
}
}
\ No newline at end of file
diff --git a/src/FluentAssertions.Web/HttpResponseMessageFormatter.cs b/src/FluentAssertions.Web/HttpResponseMessageFormatter.cs
index 79bb982..fc14ab3 100644
--- a/src/FluentAssertions.Web/HttpResponseMessageFormatter.cs
+++ b/src/FluentAssertions.Web/HttpResponseMessageFormatter.cs
@@ -1,119 +1,113 @@
using FluentAssertions.Formatting;
-using FluentAssertions.Web.Internal;
using FluentAssertions.Web.Internal.ContentProcessors;
-using System;
-using System.Collections.Generic;
-using System.Net.Http;
using System.Text;
-using System.Threading.Tasks;
-namespace FluentAssertions.Web
+namespace FluentAssertions.Web;
+
+internal class HttpResponseMessageFormatter : IValueFormatter
{
- internal class HttpResponseMessageFormatter : IValueFormatter
+ public bool CanHandle(object value) => value is HttpResponseMessage;
+
+ ///
+ public void Format(object value,
+ FormattedObjectGraph formattedGraph,
+ FormattingContext context,
+ FormatChild formatChild)
{
- public bool CanHandle(object value) => value is HttpResponseMessage;
+ var response = (HttpResponseMessage)value;
- ///
- public void Format(object value,
- FormattedObjectGraph formattedGraph,
- FormattingContext context,
- FormatChild formatChild)
- {
- var response = (HttpResponseMessage)value;
+ var messageBuilder = new StringBuilder();
+ messageBuilder.AppendLine();
+ messageBuilder.AppendLine();
+ messageBuilder.AppendLine("The HTTP response was:");
- var messageBuilder = new StringBuilder();
- messageBuilder.AppendLine();
- messageBuilder.AppendLine();
- messageBuilder.AppendLine("The HTTP response was:");
+ Func contentResolver = async () => await AppendHttpResponseMessage(messageBuilder, response);
+ contentResolver.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
- Func contentResolver = async () => await AppendHttpResponseMessage(messageBuilder, response);
- contentResolver.ExecuteInDefaultSynchronizationContext().GetAwaiter().GetResult();
+ formattedGraph.AddFragment(messageBuilder.ToString());
+ }
- formattedGraph.AddFragment(messageBuilder.ToString());
+ private static async Task AppendHttpResponseMessage(StringBuilder messageBuilder, HttpResponseMessage response)
+ {
+ try
+ {
+ await AppendResponse(messageBuilder, response);
}
-
- private static async Task AppendHttpResponseMessage(StringBuilder messageBuilder, HttpResponseMessage response)
+ catch (Exception e)
{
- try
- {
- await AppendResponse(messageBuilder, response);
- }
- catch (Exception e)
- {
- messageBuilder.AppendLine();
- messageBuilder.AppendLine($"An exception occurred while trying to output the some of the response details: {e}");
- }
- try
- {
- await AppendRequest(messageBuilder, response);
- }
- catch (Exception e)
- {
- messageBuilder.AppendLine();
- messageBuilder.AppendLine($"An exception occurred while trying to output some of the request details: {e}");
- }
+ messageBuilder.AppendLine();
+ messageBuilder.AppendLine($"An exception occurred while trying to output the some of the response details: {e}");
}
-
- private static async Task AppendResponse(StringBuilder messageBuilder, HttpResponseMessage response)
+ try
{
- AppendProtocolAndStatusCode(messageBuilder, response);
- Appender.AppendHeaders(messageBuilder, response.GetHeaders());
- AppendContentLength(messageBuilder, response.Content);
- await AppendResponseContent(messageBuilder, response);
+ await AppendRequest(messageBuilder, response);
}
-
- private static async Task AppendRequest(StringBuilder messageBuilder, HttpResponseMessage response)
+ catch (Exception e)
{
messageBuilder.AppendLine();
- var request = response.RequestMessage;
- if (request == null)
- {
- messageBuilder.AppendLine("The originated HTTP request was .");
- return;
- }
- messageBuilder.AppendLine("The originated HTTP request was:");
- messageBuilder.AppendLine();
-
- messageBuilder.AppendLine($"{request.Method.ToString().ToUpper()} {request.RequestUri} HTTP {request.Version}");
+ messageBuilder.AppendLine($"An exception occurred while trying to output some of the request details: {e}");
+ }
+ }
- Appender.AppendHeaders(messageBuilder, request.GetHeaders());
- AppendContentLength(messageBuilder, request.Content);
+ private static async Task AppendResponse(StringBuilder messageBuilder, HttpResponseMessage response)
+ {
+ AppendProtocolAndStatusCode(messageBuilder, response);
+ Appender.AppendHeaders(messageBuilder, response.GetHeaders());
+ AppendContentLength(messageBuilder, response.Content);
+ await AppendResponseContent(messageBuilder, response);
+ }
- await AppendRequestContent(messageBuilder, request.Content);
+ private static async Task AppendRequest(StringBuilder messageBuilder, HttpResponseMessage response)
+ {
+ messageBuilder.AppendLine();
+ var request = response.RequestMessage;
+ if (request == null)
+ {
+ messageBuilder.AppendLine("The originating HTTP request was .");
+ return;
}
+ messageBuilder.AppendLine("The originating HTTP request was:");
+ messageBuilder.AppendLine();
- private static async Task AppendResponseContent(StringBuilder messageBuilder, HttpResponseMessage response)
- {
- var content = response.Content;
- if (content == null)
- {
- return;
- }
+ messageBuilder.AppendLine($"{request.Method.ToString().ToUpper()} {request.RequestUri} HTTP {request.Version}");
- var processors = new List();
- processors.Add(new InternalServerErrorProcessor(response, content));
- processors.AddRange(ProcessorsRunner.CommonProcessors(content));
+ Appender.AppendHeaders(messageBuilder, request.GetHeaders());
+ AppendContentLength(messageBuilder, request.Content);
- var contentBuilder = await ProcessorsRunner.RunProcessors(processors);
- messageBuilder.AppendLine();
- messageBuilder.Append(contentBuilder);
- }
+ await AppendRequestContent(messageBuilder, request.Content);
+ }
- private static async Task AppendRequestContent(StringBuilder messageBuilder, HttpContent content)
+ private static async Task AppendResponseContent(StringBuilder messageBuilder, HttpResponseMessage response)
+ {
+ var content = response.Content;
+ if (content == null)
{
- await Appender.AppendContent(messageBuilder, content, false);
+ return;
}
- private static void AppendProtocolAndStatusCode(StringBuilder messageBuilder, HttpResponseMessage response)
- {
- messageBuilder.AppendLine();
- messageBuilder.AppendLine($@"HTTP/{response.Version} {(int)response.StatusCode} {response.StatusCode}");
- }
+ var processors = new List();
+ processors.Add(new InternalServerErrorProcessor(response, content));
+ processors.AddRange(ProcessorsRunner.CommonProcessors(content));
- private static void AppendContentLength(StringBuilder messageBuilder, HttpContent content)
- {
- content.TryGetContentLength(out var length);
- messageBuilder.AppendLine($"Content-Length: {length}");
- }
+ var contentBuilder = await ProcessorsRunner.RunProcessors(processors);
+ messageBuilder.AppendLine();
+ messageBuilder.Append(contentBuilder);
+ }
+
+ private static async Task AppendRequestContent(StringBuilder messageBuilder, HttpContent content)
+ {
+ await Appender.AppendContent(messageBuilder, content, false);
+ }
+
+ private static void AppendProtocolAndStatusCode(StringBuilder messageBuilder, HttpResponseMessage response)
+ {
+ messageBuilder.AppendLine();
+ messageBuilder.AppendLine($@"HTTP/{response.Version} {(int)response.StatusCode} {response.StatusCode}");
+ }
+
+ private static void AppendContentLength(StringBuilder messageBuilder, HttpContent content)
+ {
+ content.TryGetContentLength(out var length);
+ messageBuilder.AppendLine($"Content-Length: {length}");
}
}
\ No newline at end of file
diff --git a/src/FluentAssertions.Web/HttpStatusCodeAssertions.cs b/src/FluentAssertions.Web/HttpStatusCodeAssertions.cs
index 5c1810d..46c63bc 100644
--- a/src/FluentAssertions.Web/HttpStatusCodeAssertions.cs
+++ b/src/FluentAssertions.Web/HttpStatusCodeAssertions.cs
@@ -1,1501 +1,1497 @@
-using FluentAssertions.Execution;
-using System.Net;
+namespace FluentAssertions.Web;
-namespace FluentAssertions.Web
+public partial class HttpResponseMessageAssertions
{
- public partial class HttpResponseMessageAssertions
+ #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 AndConstraint Be1XXInformational(string because = "", params object[] becauseArgs)
{
- #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 AndConstraint Be1XXInformational(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .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}",
- Subject!.StatusCode, Subject);
-
- return new AndConstraint(this);
- }
- #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 AndConstraint Be2XXSuccessful(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(Subject!.IsSuccessStatusCode)
- .FailWith("Expected {context:response} to have a successful HTTP status code, but it was {0}{reason}.{1}",
- Subject!.StatusCode, Subject);
-
- return new AndConstraint(this);
- }
- #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 AndConstraint Be3XXRedirection(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .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}",
- Subject!.StatusCode, Subject);
-
- return new AndConstraint(this);
- }
- #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 AndConstraint Be4XXClientError(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .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}",
- Subject!.StatusCode, Subject);
-
- return new AndConstraint(this);
- }
- #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 AndConstraint Be5XXServerError(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .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}",
- Subject!.StatusCode, Subject);
-
- return new AndConstraint(this);
- }
- #endregion
-
- #region HaveHttpStatus
- ///
- /// 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 AndConstraint HaveHttpStatusCode(HttpStatusCode expected, string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(expected == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , expected, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
- #endregion
-
- #region NotHaveHttpStatus
- ///
- /// 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 AndConstraint NotHaveHttpStatusCode(HttpStatusCode unexpected, string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(unexpected != Subject!.StatusCode)
- .FailWith("Did not expect {context:response} to have status {0}{reason}.{1}",
- Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
- #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 AndConstraint Be100Continue(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.Continue == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.Continue, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be101SwitchingProtocols(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.SwitchingProtocols == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.SwitchingProtocols, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be200Ok(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.OK == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.OK, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be201Created(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.Created == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.Created, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be202Accepted(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.Accepted == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.Accepted, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be203NonAuthoritativeInformation(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.NonAuthoritativeInformation == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.NonAuthoritativeInformation, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be204NoContent(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.NoContent == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.NoContent, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be205ResetContent(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.ResetContent == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.ResetContent, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be206PartialContent(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.PartialContent == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.PartialContent, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be300MultipleChoices(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.MultipleChoices == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , "HttpStatusCode.MultipleChoices {value: 300}", Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be300Ambiguous(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.Ambiguous == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.Ambiguous, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be301MovedPermanently(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.MovedPermanently == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , "HttpStatusCode.MovedPermanently {value: 301}", Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be301Moved(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.Moved == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.Moved, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be302Found(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.Found == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , "HttpStatusCode.Found {value: 302}", Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be302Redirect(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.Redirect == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.Redirect, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be303SeeOther(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.SeeOther == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , "HttpStatusCode.SeeOther {value: 303}", Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be303RedirectMethod(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.RedirectMethod == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.RedirectMethod, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be304NotModified(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.NotModified == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.NotModified, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be305UseProxy(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.UseProxy == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.UseProxy, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be306Unused(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.Unused == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.Unused, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///
- /// 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 AndConstraint Be307TemporaryRedirect(string because = "", params object[] becauseArgs)
- {
- Execute.Assertion
- .ForCondition(Subject is not null)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected a {context:response} to assert{reason}, but found .");
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(HttpStatusCode.TemporaryRedirect == Subject!.StatusCode)
- .FailWith("Expected {context:response} to be {0}{reason}, but found {1}.{2}"
- , HttpStatusCode.TemporaryRedirect, Subject!.StatusCode, Subject);
- return new AndConstraint(this);
- }
-
- ///