diff --git a/FluentAssertions.Web.sln b/FluentAssertions.Web.sln
index 86a7a02..4e9727d 100644
--- a/FluentAssertions.Web.sln
+++ b/FluentAssertions.Web.sln
@@ -25,10 +25,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
readme.md = readme.md
EndProjectSection
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Api.Net30", "samples\Sample.Api.Net30\Sample.Api.Net30.csproj", "{BAE9E107-74FE-4C37-A528-857AC73D2C55}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Api.Net22", "samples\Sample.Api.Net22\Sample.Api.Net22.csproj", "{75C52AB3-0B18-4B3D-B604-6C2EDD724402}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Api.Net31", "samples\Sample.Api.Net31\Sample.Api.Net31.csproj", "{A62ABBAE-BFB8-467A-9FBC-974172C718E2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Api.Tests", "samples\Sample.Api.Tests\Sample.Api.Tests.csproj", "{5E7E24A9-A31F-4EBB-A3BA-167B0DD9C37E}"
@@ -39,8 +35,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Api.Net50", "samples
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Sample.Api.Shared", "Samples\Sample.Api.Shared\Sample.Api.Shared.shproj", "{815C141D-4504-42B1-A6F7-672C2476A474}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Api.Net21", "samples\Sample.Api.Net21\Sample.Api.Net21.csproj", "{A0B5B518-714A-4731-B371-996D5FBC72A0}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentAssertions.Web.Serializers.NewtonsoftJson", "src\FluentAssertions.Web.Serializers.NewtonsoftJson\FluentAssertions.Web.Serializers.NewtonsoftJson.csproj", "{1BDE8312-1789-40EA-86B2-83784E560740}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentAssertions.Web.Serializers.NewtonsoftJson.Tests", "test\FluentAssertions.Web.Serializers.NewtonsoftJson.Tests\FluentAssertions.Web.Serializers.NewtonsoftJson.Tests.csproj", "{F2C0B6F2-4ACE-4688-8F96-9EB1D5718B60}"
@@ -63,18 +57,6 @@ Global
{3C892A67-86B1-491F-8BF6-6E782FE4F689}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3C892A67-86B1-491F-8BF6-6E782FE4F689}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3C892A67-86B1-491F-8BF6-6E782FE4F689}.Release|Any CPU.Build.0 = Release|Any CPU
- {BAE9E107-74FE-4C37-A528-857AC73D2C55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BAE9E107-74FE-4C37-A528-857AC73D2C55}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BAE9E107-74FE-4C37-A528-857AC73D2C55}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BAE9E107-74FE-4C37-A528-857AC73D2C55}.Release|Any CPU.Build.0 = Release|Any CPU
- {75C52AB3-0B18-4B3D-B604-6C2EDD724402}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {75C52AB3-0B18-4B3D-B604-6C2EDD724402}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {75C52AB3-0B18-4B3D-B604-6C2EDD724402}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {75C52AB3-0B18-4B3D-B604-6C2EDD724402}.Release|Any CPU.Build.0 = Release|Any CPU
- {A62ABBAE-BFB8-467A-9FBC-974172C718E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A62ABBAE-BFB8-467A-9FBC-974172C718E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A62ABBAE-BFB8-467A-9FBC-974172C718E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A62ABBAE-BFB8-467A-9FBC-974172C718E2}.Release|Any CPU.Build.0 = Release|Any CPU
{5E7E24A9-A31F-4EBB-A3BA-167B0DD9C37E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E7E24A9-A31F-4EBB-A3BA-167B0DD9C37E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E7E24A9-A31F-4EBB-A3BA-167B0DD9C37E}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -87,10 +69,6 @@ Global
{4C9619BF-7ED4-42A3-B25C-15E288264C6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C9619BF-7ED4-42A3-B25C-15E288264C6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C9619BF-7ED4-42A3-B25C-15E288264C6F}.Release|Any CPU.Build.0 = Release|Any CPU
- {A0B5B518-714A-4731-B371-996D5FBC72A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A0B5B518-714A-4731-B371-996D5FBC72A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A0B5B518-714A-4731-B371-996D5FBC72A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A0B5B518-714A-4731-B371-996D5FBC72A0}.Release|Any CPU.Build.0 = Release|Any CPU
{1BDE8312-1789-40EA-86B2-83784E560740}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1BDE8312-1789-40EA-86B2-83784E560740}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1BDE8312-1789-40EA-86B2-83784E560740}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -114,14 +92,10 @@ Global
GlobalSection(NestedProjects) = preSolution
{313919D0-7CE6-4118-A6A2-8963362A338F} = {BFF7517A-C9EA-458D-829E-28A10F8D61BF}
{3C892A67-86B1-491F-8BF6-6E782FE4F689} = {14FDD52D-B83A-445B-BD2F-04B3E7B8033C}
- {BAE9E107-74FE-4C37-A528-857AC73D2C55} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9}
- {75C52AB3-0B18-4B3D-B604-6C2EDD724402} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9}
- {A62ABBAE-BFB8-467A-9FBC-974172C718E2} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9}
{5E7E24A9-A31F-4EBB-A3BA-167B0DD9C37E} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9}
{FACC5AED-9978-441D-A359-DCD83F924BF8} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9}
{4C9619BF-7ED4-42A3-B25C-15E288264C6F} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9}
{815C141D-4504-42B1-A6F7-672C2476A474} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9}
- {A0B5B518-714A-4731-B371-996D5FBC72A0} = {B6E9FBF3-AC48-48B0-9CBB-CA260F59CCD9}
{1BDE8312-1789-40EA-86B2-83784E560740} = {14FDD52D-B83A-445B-BD2F-04B3E7B8033C}
{F2C0B6F2-4ACE-4688-8F96-9EB1D5718B60} = {BFF7517A-C9EA-458D-829E-28A10F8D61BF}
{538479CE-5922-4FF9-A09D-80C9E91FFFF1} = {BFF7517A-C9EA-458D-829E-28A10F8D61BF}
@@ -132,11 +106,7 @@ Global
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
Samples\Sample.Api.Shared\Sample.Api.Shared.projitems*{4c9619bf-7ed4-42a3-b25c-15e288264c6f}*SharedItemsImports = 5
- Samples\Sample.Api.Shared\Sample.Api.Shared.projitems*{75c52ab3-0b18-4b3d-b604-6c2edd724402}*SharedItemsImports = 5
Samples\Sample.Api.Shared\Sample.Api.Shared.projitems*{815c141d-4504-42b1-a6f7-672c2476a474}*SharedItemsImports = 13
- Samples\Sample.Api.Shared\Sample.Api.Shared.projitems*{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
diff --git a/appveyor.yml b/appveyor.yml
index 4707f7e..c30d259 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -47,14 +47,14 @@ before_build:
build_script:
# Begin SonarScanner
# Ensure Java 15, required by Sonar
- - set JAVA_HOME=C:\Program Files\Java\jdk15
+ - set JAVA_HOME=C:\Program Files\Java\jdk19
- if not exist "%JAVA_HOME%\bin\java.exe" (echo "%JAVA_HOME%\bin\java.exe does not exist" && exit 1)
- set PATH=%JAVA_HOME%\bin;%PATH%
- - ps: 'if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { & dotnet sonarscanner begin /k:"FluentAssertions.Web" /o:adrianiftode-github /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env:SONAR_TOKEN" /v:"$env:APPVEYOR_BUILD_NUMBER" /d:sonar.cs.opencover.reportsPaths="opencovercoverage.xml" /d:sonar.coverage.exclusions=test/**}'
+ - ps: 'if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { & dotnet sonarscanner begin /k:"adrianiftode_FluentAssertions.Web" /o:adrianiftode-github /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env:SONAR_TOKEN" /v:"$env:APPVEYOR_BUILD_NUMBER" /d:sonar.cs.opencover.reportsPaths="opencovercoverage.xml" /d:sonar.coverage.exclusions=test/**}'
- dotnet build -c %CONFIGURATION% /p:Version=%APPVEYOR_BUILD_VERSION%
- minicover instrument
test_script:
- - dotnet test --no-restore --no-build
+ - dotnet test --no-restore --no-build --nologo --verbosity:q
after_test:
- minicover uninstrument
- minicover opencoverreport
@@ -70,7 +70,7 @@ artifacts:
deploy:
- provider: NuGet
api_key:
- secure: 10kb6vZ2gElrxxz+w9R1HHXKllKB2eX1jn+08B46Z3kE9jofD14d9f41+I2DOnW1
+ secure: aHT1IlqkfTAZm236Pkjt84NdjfEIrPJqJt4IwO5QNvH0LpIWqx/L3oFRewdCwCQs
skip_symbols: true
artifact: /.*\.nupkg/
on:
@@ -79,7 +79,7 @@ deploy:
- provider: GitHub
release: $(APPVEYOR_BUILD_VERSION)
auth_token:
- secure: 7a4x3VBTP+NCJ2NFJ7oTeT70kYkdWcLrSzoZjThOB/wqw6DFIGp7I0KSAu+BRnq6
+ secure: WXU/Xj3ntIZVx89KDAa/V5km1nhPI924T8G9u8c/i2LBSegKtLVV2pJjfUFvNYFEQ2j6adP4YkP6AgotppXNcFVQ/uvEfx2TY304k+FzkQpRwIfxBZantESXUKIC6aa5
artifact: /.*\.nupkg/
on:
appveyor_repo_tag: true
\ No newline at end of file
diff --git a/common.tests.props b/common.tests.props
index 1da1a75..4640ee7 100644
--- a/common.tests.props
+++ b/common.tests.props
@@ -2,7 +2,6 @@
- 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 b906718..d4635b8 100644
--- a/readme.md
+++ b/readme.md
@@ -238,6 +238,7 @@ NewtonsoftJsonSerializerConfig.Options.Converters.Add(new YesNoBooleanJsonConver
| *HttpResponseMessageAssertions* | Contains a number of methods to assert that an HttpResponseMessage is in the expected state related to the HTTP content. |
| --- | --- |
+| **Should().BeEmpty()** | Asserts that HTTP response content is empty. |
| **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. |
diff --git a/samples/Sample.Api.Net21/Properties/launchSettings.json b/samples/Sample.Api.Net21/Properties/launchSettings.json
deleted file mode 100644
index 7f7cf14..0000000
--- a/samples/Sample.Api.Net21/Properties/launchSettings.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:51575/",
- "sslPort": 44351
- }
- },
- "profiles": {
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- "Sample.Api.Net22": {
- "commandName": "Project",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- },
- "applicationUrl": "https://localhost:5001;http://localhost:5000"
- }
- }
-}
\ No newline at end of file
diff --git a/samples/Sample.Api.Net21/Sample.Api.Net21.csproj b/samples/Sample.Api.Net21/Sample.Api.Net21.csproj
deleted file mode 100644
index f8fefdb..0000000
--- a/samples/Sample.Api.Net21/Sample.Api.Net21.csproj
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
- netcoreapp2.1
- true
- false
- false
-
-
-
-
-
-
-
-
-
diff --git a/samples/Sample.Api.Net22/Properties/launchSettings.json b/samples/Sample.Api.Net22/Properties/launchSettings.json
deleted file mode 100644
index 7f7cf14..0000000
--- a/samples/Sample.Api.Net22/Properties/launchSettings.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:51575/",
- "sslPort": 44351
- }
- },
- "profiles": {
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- "Sample.Api.Net22": {
- "commandName": "Project",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- },
- "applicationUrl": "https://localhost:5001;http://localhost:5000"
- }
- }
-}
\ No newline at end of file
diff --git a/samples/Sample.Api.Net22/Sample.Api.Net22.csproj b/samples/Sample.Api.Net22/Sample.Api.Net22.csproj
deleted file mode 100644
index fc40842..0000000
--- a/samples/Sample.Api.Net22/Sample.Api.Net22.csproj
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
- netcoreapp2.2
- true
- false
- false
-
-
-
-
-
-
-
-
-
diff --git a/samples/Sample.Api.Net30/Properties/launchSettings.json b/samples/Sample.Api.Net30/Properties/launchSettings.json
deleted file mode 100644
index b0f331f..0000000
--- a/samples/Sample.Api.Net30/Properties/launchSettings.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:51576/",
- "sslPort": 44382
- }
- },
- "profiles": {
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- "Sample.Api.Net30": {
- "commandName": "Project",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- },
- "applicationUrl": "https://localhost:5001;http://localhost:5000"
- }
- }
-}
\ No newline at end of file
diff --git a/samples/Sample.Api.Net30/Sample.Api.Net30.csproj b/samples/Sample.Api.Net30/Sample.Api.Net30.csproj
deleted file mode 100644
index 469bf43..0000000
--- a/samples/Sample.Api.Net30/Sample.Api.Net30.csproj
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
- netcoreapp3.0
- true
- false
- false
-
-
-
-
-
diff --git a/samples/Sample.Api.Net31/Properties/launchSettings.json b/samples/Sample.Api.Net31/Properties/launchSettings.json
deleted file mode 100644
index 0cf99a3..0000000
--- a/samples/Sample.Api.Net31/Properties/launchSettings.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:51574/",
- "sslPort": 44312
- }
- },
- "profiles": {
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- "Sample.Api.Net31": {
- "commandName": "Project",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- },
- "applicationUrl": "https://localhost:5001;http://localhost:5000"
- }
- }
-}
\ No newline at end of file
diff --git a/samples/Sample.Api.Net31/Sample.Api.Net31.csproj b/samples/Sample.Api.Net31/Sample.Api.Net31.csproj
deleted file mode 100644
index 55c78b3..0000000
--- a/samples/Sample.Api.Net31/Sample.Api.Net31.csproj
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
- netcoreapp3.1
- true
- false
-
-
-
-
-
diff --git a/samples/Sample.Api.Shared/Startup.cs b/samples/Sample.Api.Shared/Startup.cs
index 295a4d7..491d48c 100644
--- a/samples/Sample.Api.Shared/Startup.cs
+++ b/samples/Sample.Api.Shared/Startup.cs
@@ -1,17 +1,11 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
-#if NETCOREAPP2_1 || NETCOREAPP2_2
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-#endif
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Threading.Tasks;
-#if NETCOREAPP3_0_OR_GREATER
using Microsoft.Extensions.Hosting;
-#endif
using Microsoft.Extensions.Primitives;
+using System;
+using System.Threading.Tasks;
namespace Sample.Api
{
@@ -27,22 +21,12 @@ public Startup(IConfiguration configuration)
// This method gets called by the runtime. Use this method to add services to the container.
public static void ConfigureServices(IServiceCollection services)
{
-#if NETCOREAPP2_1 || NETCOREAPP2_2
- services.AddMvc();
-#endif
-#if NETCOREAPP3_0_OR_GREATER
services.AddControllers();
-#endif
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public static void Configure(IApplicationBuilder app,
-#if NETCOREAPP2_1 || NETCOREAPP2_2
- IHostingEnvironment env
-#endif
-#if NETCOREAPP3_0_OR_GREATER
IWebHostEnvironment env
-#endif
)
{
app.Use(async (context, next) =>
@@ -76,17 +60,12 @@ IWebHostEnvironment env
}
app.UseHttpsRedirection();
-#if NETCOREAPP2_1 || NETCOREAPP2_2
- app.UseMvc();
-#endif
-#if NETCOREAPP3_0_OR_GREATER
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
-#endif
}
}
}
diff --git a/samples/Sample.Api.Tests/Sample.Api.Tests.csproj b/samples/Sample.Api.Tests/Sample.Api.Tests.csproj
index 5e16866..12cbbe2 100644
--- a/samples/Sample.Api.Tests/Sample.Api.Tests.csproj
+++ b/samples/Sample.Api.Tests/Sample.Api.Tests.csproj
@@ -2,27 +2,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ net5.0;net6.0;net7.0
+
diff --git a/samples/Sample.Api.Tests/ValuesControllerTests.cs b/samples/Sample.Api.Tests/ValuesControllerTests.cs
index 2ba8ec6..405bde2 100644
--- a/samples/Sample.Api.Tests/ValuesControllerTests.cs
+++ b/samples/Sample.Api.Tests/ValuesControllerTests.cs
@@ -107,6 +107,19 @@ public async Task Patch_ReturnsMethodNotAllowed()
}
#endif
+ [Fact]
+ public async Task Post_ReturnsEmptyContent()
+ {
+ // Arrange
+ var client = _factory.CreateClient();
+
+ // Act
+ var response = await client.PostAsync("/api/values", new StringContent(@"""value""", Encoding.UTF8, "application/json"));
+
+ // Assert
+ response.Should().BeEmpty();
+ }
+
[Fact]
public async Task Post_ReturnsOk()
{
diff --git a/src/FluentAssertions.Web/HttpResponseContentAssertions.cs b/src/FluentAssertions.Web/HttpResponseContentAssertions.cs
index faf5a86..856cb75 100644
--- a/src/FluentAssertions.Web/HttpResponseContentAssertions.cs
+++ b/src/FluentAssertions.Web/HttpResponseContentAssertions.cs
@@ -5,6 +5,34 @@
///
public partial class HttpResponseMessageAssertions
{
+ ///
+ /// Asserts that the HTTP content is empty.
+ ///
+ ///
+ /// A formatted phrase as is supported by explaining why the assertion
+ /// is needed. If the phrase does not start with the word because, it is prepended automatically.
+ ///
+ ///
+ /// Zero or more objects to format using the placeholders in .
+ ///
+ [CustomAssertion]
+ public AndConstraint BeEmpty(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 .");
+
+ var content = GetContent();
+
+ Execute.Assertion
+ .ForCondition(string.IsNullOrEmpty(content))
+ .BecauseOf(because, becauseArgs)
+ .FailWith("Expected {context:response} to have no content. {0}", Subject);
+
+ return new AndConstraint(this);
+ }
+
///
/// Asserts that HTTP response content can be an equivalent representation of the expected model.
///
diff --git a/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs b/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs
index c2d7ad5..c4babeb 100644
--- a/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs
+++ b/src/FluentAssertions.Web/HttpResponseContentAssertionsExtensions.cs
@@ -6,6 +6,24 @@
[DebuggerNonUserCode]
public static class HttpResponseContentAssertionsExtensions
{
+ ///
+ /// Asserts that HTTP response content is empty
+ ///
+ ///
+ /// A formatted phrase as is supported by explaining why the assertion
+ /// is needed. If the phrase does not start with the word because, it is prepended automatically.
+ ///
+ ///
+ /// Zero or more objects to format using the placeholders in .
+ ///
+ [CustomAssertion]
+ public static AndConstraint BeEmpty(
+#pragma warning disable 1573
+ this Primitives.HttpResponseMessageAssertions parent,
+#pragma warning restore 1573
+ string because = "", params object[] becauseArgs)
+ => new HttpResponseMessageAssertions(parent.Subject).BeEmpty(because, becauseArgs);
+
///
/// Asserts that HTTP response content can be an equivalent representation of the expected model.
///
diff --git a/test/FluentAssertions.Web.FluentAssertionsWebConfig.Tests/FluentAssertions.Web.FluentAssertionsWebConfig.Tests.csproj b/test/FluentAssertions.Web.FluentAssertionsWebConfig.Tests/FluentAssertions.Web.FluentAssertionsWebConfig.Tests.csproj
index 9dd5b2c..2d03df1 100644
--- a/test/FluentAssertions.Web.FluentAssertionsWebConfig.Tests/FluentAssertions.Web.FluentAssertionsWebConfig.Tests.csproj
+++ b/test/FluentAssertions.Web.FluentAssertionsWebConfig.Tests/FluentAssertions.Web.FluentAssertionsWebConfig.Tests.csproj
@@ -2,6 +2,10 @@
+
+ netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0
+
+
diff --git a/test/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests.csproj b/test/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests.csproj
index 0144fb4..0df0728 100644
--- a/test/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests.csproj
+++ b/test/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests/FluentAssertions.Web.Serializers.NewtonsoftJson.Tests.csproj
@@ -2,6 +2,10 @@
+
+ netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0
+
+
diff --git a/test/FluentAssertions.Web.Tests/FluentAssertions.Web.Tests.csproj b/test/FluentAssertions.Web.Tests/FluentAssertions.Web.Tests.csproj
index 6a32c83..4efcd10 100644
--- a/test/FluentAssertions.Web.Tests/FluentAssertions.Web.Tests.csproj
+++ b/test/FluentAssertions.Web.Tests/FluentAssertions.Web.Tests.csproj
@@ -2,6 +2,10 @@
+
+ netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0
+
+
diff --git a/test/FluentAssertions.Web.Tests/HttpResponseContentAssertionsSpecs.cs b/test/FluentAssertions.Web.Tests/HttpResponseContentAssertionsSpecs.cs
index 1daabec..b9aa8f6 100644
--- a/test/FluentAssertions.Web.Tests/HttpResponseContentAssertionsSpecs.cs
+++ b/test/FluentAssertions.Web.Tests/HttpResponseContentAssertionsSpecs.cs
@@ -2,6 +2,60 @@
public class HttpResponseContentAssertionsSpecs
{
+ #region BeEmpty
+
+ [Fact]
+ public void When_asserting_response_with_no_content_it_should_succeed()
+ {
+ // Arrange
+ using var subject = new HttpResponseMessage();
+
+ // Act
+ Action act = () => subject.Should().BeEmpty();
+
+ // Assert
+ act.Should().NotThrow();
+ }
+
+ [Fact]
+ public void When_asserting_response_with_empty_content_it_should_succeed()
+ {
+ // Arrange
+ using var subject = new HttpResponseMessage()
+ {
+ Content = new StringContent("")
+ };
+
+ // Act
+ Action act = () => subject.Should().BeEmpty();
+
+ // Assert
+ act.Should().NotThrow();
+ }
+
+ [Fact]
+ public void When_asserting_response_with_content_it_should_throw_with_descriptive_message()
+ {
+ // Arrange
+ using var subject = new HttpResponseMessage
+ {
+ Content = new StringContent(/*lang=json*/"""
+ {
+ "comment": "Hey",
+ "author": "John"
+ }
+ """, Encoding.UTF8, "application/json")
+ };
+
+ // Act
+ Action act = () => subject.Should().BeEmpty("we want to test the {0}", "reason");
+
+ // Assert
+ act.Should().Throw()
+ .WithMessage("*to have no content*");
+ }
+ #endregion
+
#region BeAs
[Fact]
public void When_asserting_response_with_content_to_be_as_model_it_should_succeed()