diff --git a/TUnit.Assertions.Tests/HttpResponseMessageAssertionTests.cs b/TUnit.Assertions.Tests/HttpResponseMessageAssertionTests.cs new file mode 100644 index 0000000000..efa3161bf4 --- /dev/null +++ b/TUnit.Assertions.Tests/HttpResponseMessageAssertionTests.cs @@ -0,0 +1,157 @@ +using System.Net; +using System.Net.Http; +using System.Text; +using TUnit.Assertions.Extensions; + +namespace TUnit.Assertions.Tests; + +public class HttpResponseMessageAssertionTests +{ + // Specific status code assertions + + [Test] + public async Task Test_HttpResponseMessage_IsOk() + { + using var response = new HttpResponseMessage(HttpStatusCode.OK); + await Assert.That(response).IsOk(); + } + + [Test] + public async Task Test_HttpResponseMessage_IsCreated() + { + using var response = new HttpResponseMessage(HttpStatusCode.Created); + await Assert.That(response).IsCreated(); + } + + [Test] + public async Task Test_HttpResponseMessage_IsNoContent() + { + using var response = new HttpResponseMessage(HttpStatusCode.NoContent); + await Assert.That(response).IsNoContent(); + } + + [Test] + public async Task Test_HttpResponseMessage_IsBadRequest() + { + using var response = new HttpResponseMessage(HttpStatusCode.BadRequest); + await Assert.That(response).IsBadRequest(); + } + + [Test] + public async Task Test_HttpResponseMessage_IsUnauthorized() + { + using var response = new HttpResponseMessage(HttpStatusCode.Unauthorized); + await Assert.That(response).IsUnauthorized(); + } + + [Test] + public async Task Test_HttpResponseMessage_IsForbidden() + { + using var response = new HttpResponseMessage(HttpStatusCode.Forbidden); + await Assert.That(response).IsForbidden(); + } + + [Test] + public async Task Test_HttpResponseMessage_IsNotFound() + { + using var response = new HttpResponseMessage(HttpStatusCode.NotFound); + await Assert.That(response).IsNotFound(); + } + + [Test] + public async Task Test_HttpResponseMessage_IsConflict() + { + using var response = new HttpResponseMessage(HttpStatusCode.Conflict); + await Assert.That(response).IsConflict(); + } + + // Parameterized status code assertion + + [Test] + public async Task Test_HttpResponseMessage_HasStatusCode() + { + using var response = new HttpResponseMessage(HttpStatusCode.Accepted); + await Assert.That(response).HasStatusCode(HttpStatusCode.Accepted); + } + + // Range check assertions + + [Test] + public async Task Test_HttpResponseMessage_IsRedirectStatusCode() + { + using var response = new HttpResponseMessage(HttpStatusCode.MovedPermanently); + await Assert.That(response).IsRedirectStatusCode(); + } + + [Test] + public async Task Test_HttpResponseMessage_IsClientErrorStatusCode() + { + using var response = new HttpResponseMessage(HttpStatusCode.BadRequest); + await Assert.That(response).IsClientErrorStatusCode(); + } + + [Test] + public async Task Test_HttpResponseMessage_IsServerErrorStatusCode() + { + using var response = new HttpResponseMessage(HttpStatusCode.InternalServerError); + await Assert.That(response).IsServerErrorStatusCode(); + } + + // Content assertions + + [Test] + public async Task Test_HttpResponseMessage_HasJsonContent() + { + using var response = new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent("{}", Encoding.UTF8, "application/json") + }; + await Assert.That(response).HasJsonContent(); + } + + [Test] + public async Task Test_HttpResponseMessage_HasContentType() + { + using var response = new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent("", Encoding.UTF8, "text/html") + }; + await Assert.That(response).HasContentType("text/html"); + } + + // Header assertion + + [Test] + public async Task Test_HttpResponseMessage_HasHeader() + { + using var response = new HttpResponseMessage(HttpStatusCode.OK); + response.Headers.Add("X-Custom-Header", "value"); + await Assert.That(response).HasHeader("X-Custom-Header"); + } + + [Test] + public async Task Test_HttpResponseMessage_HasHeader_ContentHeader() + { + using var response = new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent("{}", Encoding.UTF8, "application/json") + }; + await Assert.That(response).HasHeader("Content-Type"); + } + + // Existing assertions still work + + [Test] + public async Task Test_HttpResponseMessage_IsSuccessStatusCode() + { + using var response = new HttpResponseMessage(HttpStatusCode.OK); + await Assert.That(response).IsSuccessStatusCode(); + } + + [Test] + public async Task Test_HttpResponseMessage_IsNotSuccessStatusCode() + { + using var response = new HttpResponseMessage(HttpStatusCode.NotFound); + await Assert.That(response).IsNotSuccessStatusCode(); + } +} diff --git a/TUnit.Assertions/Conditions/HttpResponseMessageAssertionExtensions.cs b/TUnit.Assertions/Conditions/HttpResponseMessageAssertionExtensions.cs index e999d11c70..2759c14f3d 100644 --- a/TUnit.Assertions/Conditions/HttpResponseMessageAssertionExtensions.cs +++ b/TUnit.Assertions/Conditions/HttpResponseMessageAssertionExtensions.cs @@ -1,14 +1,110 @@ +using System.Net; using System.Net.Http; using TUnit.Assertions.Attributes; namespace TUnit.Assertions.Conditions; /// -/// Source-generated assertions for HttpResponseMessage type using [AssertionFrom<HttpResponseMessage>] attributes. -/// These wrap HTTP response validation checks as extension methods. +/// Source-generated assertions for HttpResponseMessage type. +/// Provides fluent assertions for HTTP status codes, content types, and headers. /// [AssertionFrom(nameof(HttpResponseMessage.IsSuccessStatusCode), ExpectationMessage = "have a success status code")] [AssertionFrom(nameof(HttpResponseMessage.IsSuccessStatusCode), CustomName = "IsNotSuccessStatusCode", NegateLogic = true, ExpectationMessage = "have a success status code")] public static partial class HttpResponseMessageAssertionExtensions { + // Specific status code assertions + + [GenerateAssertion(ExpectationMessage = "have status code 200 OK", InlineMethodBody = true)] + public static bool IsOk(this HttpResponseMessage response) + => response.StatusCode == HttpStatusCode.OK; + + [GenerateAssertion(ExpectationMessage = "have status code 201 Created", InlineMethodBody = true)] + public static bool IsCreated(this HttpResponseMessage response) + => response.StatusCode == HttpStatusCode.Created; + + [GenerateAssertion(ExpectationMessage = "have status code 204 No Content", InlineMethodBody = true)] + public static bool IsNoContent(this HttpResponseMessage response) + => response.StatusCode == HttpStatusCode.NoContent; + + [GenerateAssertion(ExpectationMessage = "have status code 400 Bad Request", InlineMethodBody = true)] + public static bool IsBadRequest(this HttpResponseMessage response) + => response.StatusCode == HttpStatusCode.BadRequest; + + [GenerateAssertion(ExpectationMessage = "have status code 401 Unauthorized", InlineMethodBody = true)] + public static bool IsUnauthorized(this HttpResponseMessage response) + => response.StatusCode == HttpStatusCode.Unauthorized; + + [GenerateAssertion(ExpectationMessage = "have status code 403 Forbidden", InlineMethodBody = true)] + public static bool IsForbidden(this HttpResponseMessage response) + => response.StatusCode == HttpStatusCode.Forbidden; + + [GenerateAssertion(ExpectationMessage = "have status code 404 Not Found", InlineMethodBody = true)] + public static bool IsNotFound(this HttpResponseMessage response) + => response.StatusCode == HttpStatusCode.NotFound; + + [GenerateAssertion(ExpectationMessage = "have status code 409 Conflict", InlineMethodBody = true)] + public static bool IsConflict(this HttpResponseMessage response) + => response.StatusCode == HttpStatusCode.Conflict; + + // Parameterized status code assertion + + [GenerateAssertion(ExpectationMessage = "have status code {statusCode}", InlineMethodBody = true)] + public static bool HasStatusCode(this HttpResponseMessage response, HttpStatusCode statusCode) + => response.StatusCode == statusCode; + + // Range check assertions + + [GenerateAssertion(ExpectationMessage = "have a redirection status code (3xx)", InlineMethodBody = true)] + public static bool IsRedirectStatusCode(this HttpResponseMessage response) + => (int)response.StatusCode is >= 300 and < 400; + + [GenerateAssertion(ExpectationMessage = "have a client error status code (4xx)", InlineMethodBody = true)] + public static bool IsClientErrorStatusCode(this HttpResponseMessage response) + => (int)response.StatusCode is >= 400 and < 500; + + [GenerateAssertion(ExpectationMessage = "have a server error status code (5xx)", InlineMethodBody = true)] + public static bool IsServerErrorStatusCode(this HttpResponseMessage response) + => (int)response.StatusCode is >= 500 and < 600; + + // Content assertions + + [GenerateAssertion(ExpectationMessage = "have JSON content type", InlineMethodBody = true)] + public static bool HasJsonContent(this HttpResponseMessage response) + => response.Content.Headers.ContentType?.MediaType == "application/json"; + + [GenerateAssertion(ExpectationMessage = "have content type {contentType}", InlineMethodBody = true)] + public static bool HasContentType(this HttpResponseMessage response, string contentType) + => response.Content.Headers.ContentType?.MediaType == contentType; + + // Header assertion + + [GenerateAssertion(ExpectationMessage = "have header '{headerName}'")] + public static bool HasHeader(this HttpResponseMessage response, string headerName) + { + try + { + if (response.Headers.Contains(headerName)) + { + return true; + } + } + catch (InvalidOperationException) + { + // Header name is a known content header - check content headers instead + } + + try + { + if (response.Content?.Headers.Contains(headerName) ?? false) + { + return true; + } + } + catch (InvalidOperationException) + { + // Header name is a known response header - already checked above + } + + return false; + } } diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet10_0.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet10_0.verified.txt index b214b21021..59497a2138 100644 --- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet10_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet10_0.verified.txt @@ -1218,7 +1218,39 @@ namespace .Conditions } [.<.>("IsSuccessStatusCode", CustomName="IsNotSuccessStatusCode", ExpectationMessage="have a success status code", NegateLogic=true)] [.<.>("IsSuccessStatusCode", ExpectationMessage="have a success status code")] - public static class HttpResponseMessageAssertionExtensions { } + public static class HttpResponseMessageAssertionExtensions + { + [.(ExpectationMessage="have content type {contentType}", InlineMethodBody=true)] + public static bool HasContentType(this . response, string contentType) { } + [.(ExpectationMessage="have header \'{headerName}\'")] + public static bool HasHeader(this . response, string headerName) { } + [.(ExpectationMessage="have JSON content type", InlineMethodBody=true)] + public static bool HasJsonContent(this . response) { } + [.(ExpectationMessage="have status code {statusCode}", InlineMethodBody=true)] + public static bool HasStatusCode(this . response, .HttpStatusCode statusCode) { } + [.(ExpectationMessage="have status code 400 Bad Request", InlineMethodBody=true)] + public static bool IsBadRequest(this . response) { } + [.(ExpectationMessage="have a client error status code (4xx)", InlineMethodBody=true)] + public static bool IsClientErrorStatusCode(this . response) { } + [.(ExpectationMessage="have status code 409 Conflict", InlineMethodBody=true)] + public static bool IsConflict(this . response) { } + [.(ExpectationMessage="have status code 201 Created", InlineMethodBody=true)] + public static bool IsCreated(this . response) { } + [.(ExpectationMessage="have status code 403 Forbidden", InlineMethodBody=true)] + public static bool IsForbidden(this . response) { } + [.(ExpectationMessage="have status code 204 No Content", InlineMethodBody=true)] + public static bool IsNoContent(this . response) { } + [.(ExpectationMessage="have status code 404 Not Found", InlineMethodBody=true)] + public static bool IsNotFound(this . response) { } + [.(ExpectationMessage="have status code 200 OK", InlineMethodBody=true)] + public static bool IsOk(this . response) { } + [.(ExpectationMessage="have a redirection status code (3xx)", InlineMethodBody=true)] + public static bool IsRedirectStatusCode(this . response) { } + [.(ExpectationMessage="have a server error status code (5xx)", InlineMethodBody=true)] + public static bool IsServerErrorStatusCode(this . response) { } + [.(ExpectationMessage="have status code 401 Unauthorized", InlineMethodBody=true)] + public static bool IsUnauthorized(this . response) { } + } [.<.IPAddress>("IsIPv4MappedToIPv6", CustomName="IsNotIPv4MappedToIPv6", ExpectationMessage="be an IPv4-mapped IPv6 address", NegateLogic=true)] [.<.IPAddress>("IsIPv4MappedToIPv6", ExpectationMessage="be an IPv4-mapped IPv6 address")] [.<.IPAddress>("IsIPv6LinkLocal", CustomName="IsNotIPv6LinkLocal", ExpectationMessage="be an IPv6 link-local address", NegateLogic=true)] @@ -3779,8 +3811,23 @@ namespace .Extensions } public static class HttpResponseMessageAssertionExtensions { + public static ._HasContentType_String_Assertion HasContentType(this .<.> source, string contentType, [.("contentType")] string? contentTypeExpression = null) { } + public static ._HasHeader_String_Assertion HasHeader(this .<.> source, string headerName, [.("headerName")] string? headerNameExpression = null) { } + public static ._HasJsonContent_Assertion HasJsonContent(this .<.> source) { } + public static ._HasStatusCode_HttpStatusCode_Assertion HasStatusCode(this .<.> source, .HttpStatusCode statusCode, [.("statusCode")] string? statusCodeExpression = null) { } + public static ._IsBadRequest_Assertion IsBadRequest(this .<.> source) { } + public static ._IsClientErrorStatusCode_Assertion IsClientErrorStatusCode(this .<.> source) { } + public static ._IsConflict_Assertion IsConflict(this .<.> source) { } + public static ._IsCreated_Assertion IsCreated(this .<.> source) { } + public static ._IsForbidden_Assertion IsForbidden(this .<.> source) { } + public static ._IsNoContent_Assertion IsNoContent(this .<.> source) { } + public static ._IsNotFound_Assertion IsNotFound(this .<.> source) { } public static . IsNotSuccessStatusCode(this .<.> source) { } + public static ._IsOk_Assertion IsOk(this .<.> source) { } + public static ._IsRedirectStatusCode_Assertion IsRedirectStatusCode(this .<.> source) { } + public static ._IsServerErrorStatusCode_Assertion IsServerErrorStatusCode(this .<.> source) { } public static . IsSuccessStatusCode(this .<.> source) { } + public static ._IsUnauthorized_Assertion IsUnauthorized(this .<.> source) { } } public class HttpResponseMessageIsSuccessStatusCodeAssertion : .<.> { @@ -3788,6 +3835,96 @@ namespace .Extensions protected override .<.> CheckAsync(.<.> metadata) { } protected override string GetExpectation() { } } + public sealed class HttpResponseMessage_HasContentType_String_Assertion : .<.> + { + public HttpResponseMessage_HasContentType_String_Assertion(.<.> context, string contentType) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_HasHeader_String_Assertion : .<.> + { + public HttpResponseMessage_HasHeader_String_Assertion(.<.> context, string headerName) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_HasJsonContent_Assertion : .<.> + { + public HttpResponseMessage_HasJsonContent_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_HasStatusCode_HttpStatusCode_Assertion : .<.> + { + public HttpResponseMessage_HasStatusCode_HttpStatusCode_Assertion(.<.> context, .HttpStatusCode statusCode) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsBadRequest_Assertion : .<.> + { + public HttpResponseMessage_IsBadRequest_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsClientErrorStatusCode_Assertion : .<.> + { + public HttpResponseMessage_IsClientErrorStatusCode_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsConflict_Assertion : .<.> + { + public HttpResponseMessage_IsConflict_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsCreated_Assertion : .<.> + { + public HttpResponseMessage_IsCreated_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsForbidden_Assertion : .<.> + { + public HttpResponseMessage_IsForbidden_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsNoContent_Assertion : .<.> + { + public HttpResponseMessage_IsNoContent_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsNotFound_Assertion : .<.> + { + public HttpResponseMessage_IsNotFound_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsOk_Assertion : .<.> + { + public HttpResponseMessage_IsOk_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsRedirectStatusCode_Assertion : .<.> + { + public HttpResponseMessage_IsRedirectStatusCode_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsServerErrorStatusCode_Assertion : .<.> + { + public HttpResponseMessage_IsServerErrorStatusCode_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsUnauthorized_Assertion : .<.> + { + public HttpResponseMessage_IsUnauthorized_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } public static class HttpStatusCodeAssertionExtensions { public static ._IsClientError_Assertion IsClientError(this .<.HttpStatusCode> source) { } diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt index 35a861522e..c01ad50b4b 100644 --- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt @@ -1201,7 +1201,39 @@ namespace .Conditions } [.<.>("IsSuccessStatusCode", CustomName="IsNotSuccessStatusCode", ExpectationMessage="have a success status code", NegateLogic=true)] [.<.>("IsSuccessStatusCode", ExpectationMessage="have a success status code")] - public static class HttpResponseMessageAssertionExtensions { } + public static class HttpResponseMessageAssertionExtensions + { + [.(ExpectationMessage="have content type {contentType}", InlineMethodBody=true)] + public static bool HasContentType(this . response, string contentType) { } + [.(ExpectationMessage="have header \'{headerName}\'")] + public static bool HasHeader(this . response, string headerName) { } + [.(ExpectationMessage="have JSON content type", InlineMethodBody=true)] + public static bool HasJsonContent(this . response) { } + [.(ExpectationMessage="have status code {statusCode}", InlineMethodBody=true)] + public static bool HasStatusCode(this . response, .HttpStatusCode statusCode) { } + [.(ExpectationMessage="have status code 400 Bad Request", InlineMethodBody=true)] + public static bool IsBadRequest(this . response) { } + [.(ExpectationMessage="have a client error status code (4xx)", InlineMethodBody=true)] + public static bool IsClientErrorStatusCode(this . response) { } + [.(ExpectationMessage="have status code 409 Conflict", InlineMethodBody=true)] + public static bool IsConflict(this . response) { } + [.(ExpectationMessage="have status code 201 Created", InlineMethodBody=true)] + public static bool IsCreated(this . response) { } + [.(ExpectationMessage="have status code 403 Forbidden", InlineMethodBody=true)] + public static bool IsForbidden(this . response) { } + [.(ExpectationMessage="have status code 204 No Content", InlineMethodBody=true)] + public static bool IsNoContent(this . response) { } + [.(ExpectationMessage="have status code 404 Not Found", InlineMethodBody=true)] + public static bool IsNotFound(this . response) { } + [.(ExpectationMessage="have status code 200 OK", InlineMethodBody=true)] + public static bool IsOk(this . response) { } + [.(ExpectationMessage="have a redirection status code (3xx)", InlineMethodBody=true)] + public static bool IsRedirectStatusCode(this . response) { } + [.(ExpectationMessage="have a server error status code (5xx)", InlineMethodBody=true)] + public static bool IsServerErrorStatusCode(this . response) { } + [.(ExpectationMessage="have status code 401 Unauthorized", InlineMethodBody=true)] + public static bool IsUnauthorized(this . response) { } + } [.<.IPAddress>("IsIPv4MappedToIPv6", CustomName="IsNotIPv4MappedToIPv6", ExpectationMessage="be an IPv4-mapped IPv6 address", NegateLogic=true)] [.<.IPAddress>("IsIPv4MappedToIPv6", ExpectationMessage="be an IPv4-mapped IPv6 address")] [.<.IPAddress>("IsIPv6LinkLocal", CustomName="IsNotIPv6LinkLocal", ExpectationMessage="be an IPv6 link-local address", NegateLogic=true)] @@ -3745,8 +3777,23 @@ namespace .Extensions } public static class HttpResponseMessageAssertionExtensions { + public static ._HasContentType_String_Assertion HasContentType(this .<.> source, string contentType, [.("contentType")] string? contentTypeExpression = null) { } + public static ._HasHeader_String_Assertion HasHeader(this .<.> source, string headerName, [.("headerName")] string? headerNameExpression = null) { } + public static ._HasJsonContent_Assertion HasJsonContent(this .<.> source) { } + public static ._HasStatusCode_HttpStatusCode_Assertion HasStatusCode(this .<.> source, .HttpStatusCode statusCode, [.("statusCode")] string? statusCodeExpression = null) { } + public static ._IsBadRequest_Assertion IsBadRequest(this .<.> source) { } + public static ._IsClientErrorStatusCode_Assertion IsClientErrorStatusCode(this .<.> source) { } + public static ._IsConflict_Assertion IsConflict(this .<.> source) { } + public static ._IsCreated_Assertion IsCreated(this .<.> source) { } + public static ._IsForbidden_Assertion IsForbidden(this .<.> source) { } + public static ._IsNoContent_Assertion IsNoContent(this .<.> source) { } + public static ._IsNotFound_Assertion IsNotFound(this .<.> source) { } public static . IsNotSuccessStatusCode(this .<.> source) { } + public static ._IsOk_Assertion IsOk(this .<.> source) { } + public static ._IsRedirectStatusCode_Assertion IsRedirectStatusCode(this .<.> source) { } + public static ._IsServerErrorStatusCode_Assertion IsServerErrorStatusCode(this .<.> source) { } public static . IsSuccessStatusCode(this .<.> source) { } + public static ._IsUnauthorized_Assertion IsUnauthorized(this .<.> source) { } } public class HttpResponseMessageIsSuccessStatusCodeAssertion : .<.> { @@ -3754,6 +3801,96 @@ namespace .Extensions protected override .<.> CheckAsync(.<.> metadata) { } protected override string GetExpectation() { } } + public sealed class HttpResponseMessage_HasContentType_String_Assertion : .<.> + { + public HttpResponseMessage_HasContentType_String_Assertion(.<.> context, string contentType) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_HasHeader_String_Assertion : .<.> + { + public HttpResponseMessage_HasHeader_String_Assertion(.<.> context, string headerName) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_HasJsonContent_Assertion : .<.> + { + public HttpResponseMessage_HasJsonContent_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_HasStatusCode_HttpStatusCode_Assertion : .<.> + { + public HttpResponseMessage_HasStatusCode_HttpStatusCode_Assertion(.<.> context, .HttpStatusCode statusCode) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsBadRequest_Assertion : .<.> + { + public HttpResponseMessage_IsBadRequest_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsClientErrorStatusCode_Assertion : .<.> + { + public HttpResponseMessage_IsClientErrorStatusCode_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsConflict_Assertion : .<.> + { + public HttpResponseMessage_IsConflict_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsCreated_Assertion : .<.> + { + public HttpResponseMessage_IsCreated_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsForbidden_Assertion : .<.> + { + public HttpResponseMessage_IsForbidden_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsNoContent_Assertion : .<.> + { + public HttpResponseMessage_IsNoContent_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsNotFound_Assertion : .<.> + { + public HttpResponseMessage_IsNotFound_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsOk_Assertion : .<.> + { + public HttpResponseMessage_IsOk_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsRedirectStatusCode_Assertion : .<.> + { + public HttpResponseMessage_IsRedirectStatusCode_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsServerErrorStatusCode_Assertion : .<.> + { + public HttpResponseMessage_IsServerErrorStatusCode_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsUnauthorized_Assertion : .<.> + { + public HttpResponseMessage_IsUnauthorized_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } public static class HttpStatusCodeAssertionExtensions { public static ._IsClientError_Assertion IsClientError(this .<.HttpStatusCode> source) { } diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet9_0.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet9_0.verified.txt index f068600f0e..2a4e6c380f 100644 --- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet9_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet9_0.verified.txt @@ -1218,7 +1218,39 @@ namespace .Conditions } [.<.>("IsSuccessStatusCode", CustomName="IsNotSuccessStatusCode", ExpectationMessage="have a success status code", NegateLogic=true)] [.<.>("IsSuccessStatusCode", ExpectationMessage="have a success status code")] - public static class HttpResponseMessageAssertionExtensions { } + public static class HttpResponseMessageAssertionExtensions + { + [.(ExpectationMessage="have content type {contentType}", InlineMethodBody=true)] + public static bool HasContentType(this . response, string contentType) { } + [.(ExpectationMessage="have header \'{headerName}\'")] + public static bool HasHeader(this . response, string headerName) { } + [.(ExpectationMessage="have JSON content type", InlineMethodBody=true)] + public static bool HasJsonContent(this . response) { } + [.(ExpectationMessage="have status code {statusCode}", InlineMethodBody=true)] + public static bool HasStatusCode(this . response, .HttpStatusCode statusCode) { } + [.(ExpectationMessage="have status code 400 Bad Request", InlineMethodBody=true)] + public static bool IsBadRequest(this . response) { } + [.(ExpectationMessage="have a client error status code (4xx)", InlineMethodBody=true)] + public static bool IsClientErrorStatusCode(this . response) { } + [.(ExpectationMessage="have status code 409 Conflict", InlineMethodBody=true)] + public static bool IsConflict(this . response) { } + [.(ExpectationMessage="have status code 201 Created", InlineMethodBody=true)] + public static bool IsCreated(this . response) { } + [.(ExpectationMessage="have status code 403 Forbidden", InlineMethodBody=true)] + public static bool IsForbidden(this . response) { } + [.(ExpectationMessage="have status code 204 No Content", InlineMethodBody=true)] + public static bool IsNoContent(this . response) { } + [.(ExpectationMessage="have status code 404 Not Found", InlineMethodBody=true)] + public static bool IsNotFound(this . response) { } + [.(ExpectationMessage="have status code 200 OK", InlineMethodBody=true)] + public static bool IsOk(this . response) { } + [.(ExpectationMessage="have a redirection status code (3xx)", InlineMethodBody=true)] + public static bool IsRedirectStatusCode(this . response) { } + [.(ExpectationMessage="have a server error status code (5xx)", InlineMethodBody=true)] + public static bool IsServerErrorStatusCode(this . response) { } + [.(ExpectationMessage="have status code 401 Unauthorized", InlineMethodBody=true)] + public static bool IsUnauthorized(this . response) { } + } [.<.IPAddress>("IsIPv4MappedToIPv6", CustomName="IsNotIPv4MappedToIPv6", ExpectationMessage="be an IPv4-mapped IPv6 address", NegateLogic=true)] [.<.IPAddress>("IsIPv4MappedToIPv6", ExpectationMessage="be an IPv4-mapped IPv6 address")] [.<.IPAddress>("IsIPv6LinkLocal", CustomName="IsNotIPv6LinkLocal", ExpectationMessage="be an IPv6 link-local address", NegateLogic=true)] @@ -3779,8 +3811,23 @@ namespace .Extensions } public static class HttpResponseMessageAssertionExtensions { + public static ._HasContentType_String_Assertion HasContentType(this .<.> source, string contentType, [.("contentType")] string? contentTypeExpression = null) { } + public static ._HasHeader_String_Assertion HasHeader(this .<.> source, string headerName, [.("headerName")] string? headerNameExpression = null) { } + public static ._HasJsonContent_Assertion HasJsonContent(this .<.> source) { } + public static ._HasStatusCode_HttpStatusCode_Assertion HasStatusCode(this .<.> source, .HttpStatusCode statusCode, [.("statusCode")] string? statusCodeExpression = null) { } + public static ._IsBadRequest_Assertion IsBadRequest(this .<.> source) { } + public static ._IsClientErrorStatusCode_Assertion IsClientErrorStatusCode(this .<.> source) { } + public static ._IsConflict_Assertion IsConflict(this .<.> source) { } + public static ._IsCreated_Assertion IsCreated(this .<.> source) { } + public static ._IsForbidden_Assertion IsForbidden(this .<.> source) { } + public static ._IsNoContent_Assertion IsNoContent(this .<.> source) { } + public static ._IsNotFound_Assertion IsNotFound(this .<.> source) { } public static . IsNotSuccessStatusCode(this .<.> source) { } + public static ._IsOk_Assertion IsOk(this .<.> source) { } + public static ._IsRedirectStatusCode_Assertion IsRedirectStatusCode(this .<.> source) { } + public static ._IsServerErrorStatusCode_Assertion IsServerErrorStatusCode(this .<.> source) { } public static . IsSuccessStatusCode(this .<.> source) { } + public static ._IsUnauthorized_Assertion IsUnauthorized(this .<.> source) { } } public class HttpResponseMessageIsSuccessStatusCodeAssertion : .<.> { @@ -3788,6 +3835,96 @@ namespace .Extensions protected override .<.> CheckAsync(.<.> metadata) { } protected override string GetExpectation() { } } + public sealed class HttpResponseMessage_HasContentType_String_Assertion : .<.> + { + public HttpResponseMessage_HasContentType_String_Assertion(.<.> context, string contentType) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_HasHeader_String_Assertion : .<.> + { + public HttpResponseMessage_HasHeader_String_Assertion(.<.> context, string headerName) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_HasJsonContent_Assertion : .<.> + { + public HttpResponseMessage_HasJsonContent_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_HasStatusCode_HttpStatusCode_Assertion : .<.> + { + public HttpResponseMessage_HasStatusCode_HttpStatusCode_Assertion(.<.> context, .HttpStatusCode statusCode) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsBadRequest_Assertion : .<.> + { + public HttpResponseMessage_IsBadRequest_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsClientErrorStatusCode_Assertion : .<.> + { + public HttpResponseMessage_IsClientErrorStatusCode_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsConflict_Assertion : .<.> + { + public HttpResponseMessage_IsConflict_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsCreated_Assertion : .<.> + { + public HttpResponseMessage_IsCreated_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsForbidden_Assertion : .<.> + { + public HttpResponseMessage_IsForbidden_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsNoContent_Assertion : .<.> + { + public HttpResponseMessage_IsNoContent_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsNotFound_Assertion : .<.> + { + public HttpResponseMessage_IsNotFound_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsOk_Assertion : .<.> + { + public HttpResponseMessage_IsOk_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsRedirectStatusCode_Assertion : .<.> + { + public HttpResponseMessage_IsRedirectStatusCode_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsServerErrorStatusCode_Assertion : .<.> + { + public HttpResponseMessage_IsServerErrorStatusCode_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsUnauthorized_Assertion : .<.> + { + public HttpResponseMessage_IsUnauthorized_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } public static class HttpStatusCodeAssertionExtensions { public static ._IsClientError_Assertion IsClientError(this .<.HttpStatusCode> source) { } diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt index 1f0b7c8a11..d8f7e630fd 100644 --- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt +++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt @@ -1050,7 +1050,39 @@ namespace .Conditions } [.<.>("IsSuccessStatusCode", CustomName="IsNotSuccessStatusCode", ExpectationMessage="have a success status code", NegateLogic=true)] [.<.>("IsSuccessStatusCode", ExpectationMessage="have a success status code")] - public static class HttpResponseMessageAssertionExtensions { } + public static class HttpResponseMessageAssertionExtensions + { + [.(ExpectationMessage="have content type {contentType}", InlineMethodBody=true)] + public static bool HasContentType(this . response, string contentType) { } + [.(ExpectationMessage="have header \'{headerName}\'")] + public static bool HasHeader(this . response, string headerName) { } + [.(ExpectationMessage="have JSON content type", InlineMethodBody=true)] + public static bool HasJsonContent(this . response) { } + [.(ExpectationMessage="have status code {statusCode}", InlineMethodBody=true)] + public static bool HasStatusCode(this . response, .HttpStatusCode statusCode) { } + [.(ExpectationMessage="have status code 400 Bad Request", InlineMethodBody=true)] + public static bool IsBadRequest(this . response) { } + [.(ExpectationMessage="have a client error status code (4xx)", InlineMethodBody=true)] + public static bool IsClientErrorStatusCode(this . response) { } + [.(ExpectationMessage="have status code 409 Conflict", InlineMethodBody=true)] + public static bool IsConflict(this . response) { } + [.(ExpectationMessage="have status code 201 Created", InlineMethodBody=true)] + public static bool IsCreated(this . response) { } + [.(ExpectationMessage="have status code 403 Forbidden", InlineMethodBody=true)] + public static bool IsForbidden(this . response) { } + [.(ExpectationMessage="have status code 204 No Content", InlineMethodBody=true)] + public static bool IsNoContent(this . response) { } + [.(ExpectationMessage="have status code 404 Not Found", InlineMethodBody=true)] + public static bool IsNotFound(this . response) { } + [.(ExpectationMessage="have status code 200 OK", InlineMethodBody=true)] + public static bool IsOk(this . response) { } + [.(ExpectationMessage="have a redirection status code (3xx)", InlineMethodBody=true)] + public static bool IsRedirectStatusCode(this . response) { } + [.(ExpectationMessage="have a server error status code (5xx)", InlineMethodBody=true)] + public static bool IsServerErrorStatusCode(this . response) { } + [.(ExpectationMessage="have status code 401 Unauthorized", InlineMethodBody=true)] + public static bool IsUnauthorized(this . response) { } + } [.<.IPAddress>("IsIPv4MappedToIPv6", CustomName="IsNotIPv4MappedToIPv6", ExpectationMessage="be an IPv4-mapped IPv6 address", NegateLogic=true)] [.<.IPAddress>("IsIPv4MappedToIPv6", ExpectationMessage="be an IPv4-mapped IPv6 address")] [.<.IPAddress>("IsIPv6LinkLocal", CustomName="IsNotIPv6LinkLocal", ExpectationMessage="be an IPv6 link-local address", NegateLogic=true)] @@ -3354,8 +3386,23 @@ namespace .Extensions } public static class HttpResponseMessageAssertionExtensions { + public static ._HasContentType_String_Assertion HasContentType(this .<.> source, string contentType, [.("contentType")] string? contentTypeExpression = null) { } + public static ._HasHeader_String_Assertion HasHeader(this .<.> source, string headerName, [.("headerName")] string? headerNameExpression = null) { } + public static ._HasJsonContent_Assertion HasJsonContent(this .<.> source) { } + public static ._HasStatusCode_HttpStatusCode_Assertion HasStatusCode(this .<.> source, .HttpStatusCode statusCode, [.("statusCode")] string? statusCodeExpression = null) { } + public static ._IsBadRequest_Assertion IsBadRequest(this .<.> source) { } + public static ._IsClientErrorStatusCode_Assertion IsClientErrorStatusCode(this .<.> source) { } + public static ._IsConflict_Assertion IsConflict(this .<.> source) { } + public static ._IsCreated_Assertion IsCreated(this .<.> source) { } + public static ._IsForbidden_Assertion IsForbidden(this .<.> source) { } + public static ._IsNoContent_Assertion IsNoContent(this .<.> source) { } + public static ._IsNotFound_Assertion IsNotFound(this .<.> source) { } public static . IsNotSuccessStatusCode(this .<.> source) { } + public static ._IsOk_Assertion IsOk(this .<.> source) { } + public static ._IsRedirectStatusCode_Assertion IsRedirectStatusCode(this .<.> source) { } + public static ._IsServerErrorStatusCode_Assertion IsServerErrorStatusCode(this .<.> source) { } public static . IsSuccessStatusCode(this .<.> source) { } + public static ._IsUnauthorized_Assertion IsUnauthorized(this .<.> source) { } } public class HttpResponseMessageIsSuccessStatusCodeAssertion : .<.> { @@ -3363,6 +3410,96 @@ namespace .Extensions protected override .<.> CheckAsync(.<.> metadata) { } protected override string GetExpectation() { } } + public sealed class HttpResponseMessage_HasContentType_String_Assertion : .<.> + { + public HttpResponseMessage_HasContentType_String_Assertion(.<.> context, string contentType) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_HasHeader_String_Assertion : .<.> + { + public HttpResponseMessage_HasHeader_String_Assertion(.<.> context, string headerName) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_HasJsonContent_Assertion : .<.> + { + public HttpResponseMessage_HasJsonContent_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_HasStatusCode_HttpStatusCode_Assertion : .<.> + { + public HttpResponseMessage_HasStatusCode_HttpStatusCode_Assertion(.<.> context, .HttpStatusCode statusCode) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsBadRequest_Assertion : .<.> + { + public HttpResponseMessage_IsBadRequest_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsClientErrorStatusCode_Assertion : .<.> + { + public HttpResponseMessage_IsClientErrorStatusCode_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsConflict_Assertion : .<.> + { + public HttpResponseMessage_IsConflict_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsCreated_Assertion : .<.> + { + public HttpResponseMessage_IsCreated_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsForbidden_Assertion : .<.> + { + public HttpResponseMessage_IsForbidden_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsNoContent_Assertion : .<.> + { + public HttpResponseMessage_IsNoContent_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsNotFound_Assertion : .<.> + { + public HttpResponseMessage_IsNotFound_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsOk_Assertion : .<.> + { + public HttpResponseMessage_IsOk_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsRedirectStatusCode_Assertion : .<.> + { + public HttpResponseMessage_IsRedirectStatusCode_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsServerErrorStatusCode_Assertion : .<.> + { + public HttpResponseMessage_IsServerErrorStatusCode_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } + public sealed class HttpResponseMessage_IsUnauthorized_Assertion : .<.> + { + public HttpResponseMessage_IsUnauthorized_Assertion(.<.> context) { } + protected override .<.> CheckAsync(.<.> metadata) { } + protected override string GetExpectation() { } + } public static class HttpStatusCodeAssertionExtensions { public static ._IsClientError_Assertion IsClientError(this .<.HttpStatusCode> source) { } diff --git a/examples/CloudShop/CloudShop.Tests/Assertions/HttpAssertionExtensions.cs b/examples/CloudShop/CloudShop.Tests/Assertions/HttpAssertionExtensions.cs deleted file mode 100644 index cf64bf42dc..0000000000 --- a/examples/CloudShop/CloudShop.Tests/Assertions/HttpAssertionExtensions.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System.Net; -using System.Net.Http; -using TUnit.Assertions.Attributes; - -namespace CloudShop.Tests.Assertions; - -/// -/// Custom HTTP assertion extensions for CloudShop API testing. -/// These complement the built-in TUnit HttpResponseMessage assertions. -/// -public static partial class HttpAssertionExtensions -{ - /// - /// Asserts that the HTTP response has a JSON content type. - /// Usage: await Assert.That(response).HasJsonContent(); - /// - [GenerateAssertion(ExpectationMessage = "have JSON content type")] - public static bool HasJsonContent(this HttpResponseMessage response) - => response.Content.Headers.ContentType?.MediaType == "application/json"; - - /// - /// Asserts that the HTTP response has the expected status code. - /// Usage: await Assert.That(response).HasStatusCode(HttpStatusCode.Created); - /// - [GenerateAssertion(ExpectationMessage = "have status code {expected}")] - public static bool HasStatusCode(this HttpResponseMessage response, HttpStatusCode expected) - => response.StatusCode == expected; - - /// - /// Asserts that the HTTP response has a 201 Created status code. - /// Usage: await Assert.That(response).IsCreated(); - /// - [GenerateAssertion(ExpectationMessage = "have status code 201 Created")] - public static bool IsCreated(this HttpResponseMessage response) - => response.StatusCode == HttpStatusCode.Created; - - /// - /// Asserts that the HTTP response has a 404 Not Found status code. - /// Usage: await Assert.That(response).IsNotFound(); - /// - [GenerateAssertion(ExpectationMessage = "have status code 404 Not Found")] - public static bool IsNotFound(this HttpResponseMessage response) - => response.StatusCode == HttpStatusCode.NotFound; - - /// - /// Asserts that the HTTP response has a 400 Bad Request status code. - /// Usage: await Assert.That(response).IsBadRequest(); - /// - [GenerateAssertion(ExpectationMessage = "have status code 400 Bad Request")] - public static bool IsBadRequest(this HttpResponseMessage response) - => response.StatusCode == HttpStatusCode.BadRequest; - - /// - /// Asserts that the HTTP response has a 401 Unauthorized status code. - /// Usage: await Assert.That(response).IsUnauthorized(); - /// - [GenerateAssertion(ExpectationMessage = "have status code 401 Unauthorized")] - public static bool IsUnauthorized(this HttpResponseMessage response) - => response.StatusCode == HttpStatusCode.Unauthorized; - - /// - /// Asserts that the HTTP response has a 403 Forbidden status code. - /// Usage: await Assert.That(response).IsForbidden(); - /// - [GenerateAssertion(ExpectationMessage = "have status code 403 Forbidden")] - public static bool IsForbidden(this HttpResponseMessage response) - => response.StatusCode == HttpStatusCode.Forbidden; -} diff --git a/examples/CloudShop/CloudShop.Tests/CloudShop.Tests.csproj b/examples/CloudShop/CloudShop.Tests/CloudShop.Tests.csproj index 05a4894ba0..b867bf3b0b 100644 --- a/examples/CloudShop/CloudShop.Tests/CloudShop.Tests.csproj +++ b/examples/CloudShop/CloudShop.Tests/CloudShop.Tests.csproj @@ -3,6 +3,14 @@ net10.0 Exe + true + true + true + true + false + false + true + true @@ -11,11 +19,20 @@ - + + + + + + TUnit + TUnit.Engine.Framework.TestingPlatformBuilderHook + + + diff --git a/examples/CloudShop/CloudShop.Tests/Tests/Auth/AuthenticationTests.cs b/examples/CloudShop/CloudShop.Tests/Tests/Auth/AuthenticationTests.cs index 8361b93895..ccf22d4f58 100644 --- a/examples/CloudShop/CloudShop.Tests/Tests/Auth/AuthenticationTests.cs +++ b/examples/CloudShop/CloudShop.Tests/Tests/Auth/AuthenticationTests.cs @@ -1,7 +1,5 @@ -using System.Net; using System.Net.Http.Json; using CloudShop.Shared.Contracts; -using CloudShop.Tests.Assertions; using CloudShop.Tests.DataSources; using CloudShop.Tests.Infrastructure; using TUnit.Core; @@ -30,7 +28,7 @@ public async Task Valid_Login_Returns_Token() var response = await Api.Client.PostAsJsonAsync("/api/auth/login", new LoginRequest("admin@cloudshop.test", "Admin123!")); - await Assert.That(response.IsSuccessStatusCode).IsTrue(); + await Assert.That(response).IsSuccessStatusCode(); var token = await response.Content.ReadFromJsonAsync(); await Assert.That(token).IsNotNull(); @@ -46,7 +44,7 @@ public async Task Invalid_Login_Returns_Unauthorized(LoginRequest credentials) { var response = await Api.Client.PostAsJsonAsync("/api/auth/login", credentials); - await Assert.That(response.StatusCode).IsEqualTo(HttpStatusCode.Unauthorized); + await Assert.That(response).IsUnauthorized(); } [Test] @@ -55,7 +53,7 @@ public async Task Can_Register_New_User(RegisterRequest registration) { var response = await Api.Client.PostAsJsonAsync("/api/auth/register", registration); - await Assert.That(response.IsSuccessStatusCode).IsTrue(); + await Assert.That(response).IsSuccessStatusCode(); var token = await response.Content.ReadFromJsonAsync(); await Assert.That(token).IsNotNull(); @@ -70,6 +68,6 @@ public async Task Duplicate_Registration_Returns_Conflict() var response = await Api.Client.PostAsJsonAsync("/api/auth/register", new RegisterRequest("admin@cloudshop.test", "NewPassword123!", "Duplicate User")); - await Assert.That(response.StatusCode).IsEqualTo(HttpStatusCode.Conflict); + await Assert.That(response).IsConflict(); } } diff --git a/examples/CloudShop/CloudShop.Tests/Tests/Orders/OrderPlacementTests.cs b/examples/CloudShop/CloudShop.Tests/Tests/Orders/OrderPlacementTests.cs index c269c1c29c..a923df8400 100644 --- a/examples/CloudShop/CloudShop.Tests/Tests/Orders/OrderPlacementTests.cs +++ b/examples/CloudShop/CloudShop.Tests/Tests/Orders/OrderPlacementTests.cs @@ -1,7 +1,6 @@ using System.Net.Http.Json; using CloudShop.Shared.Contracts; using CloudShop.Shared.Models; -using CloudShop.Tests.Assertions; using CloudShop.Tests.DataSources; using CloudShop.Tests.Infrastructure; using TUnit.Core; diff --git a/examples/CloudShop/CloudShop.Tests/Tests/Performance/LoadTests.cs b/examples/CloudShop/CloudShop.Tests/Tests/Performance/LoadTests.cs index 182f43ab39..d0185daff1 100644 --- a/examples/CloudShop/CloudShop.Tests/Tests/Performance/LoadTests.cs +++ b/examples/CloudShop/CloudShop.Tests/Tests/Performance/LoadTests.cs @@ -1,6 +1,5 @@ using System.Net.Http.Json; using CloudShop.Shared.Contracts; -using CloudShop.Tests.Assertions; using CloudShop.Tests.Infrastructure; using TUnit.Core; using TUnit.Core.Interfaces; @@ -29,7 +28,7 @@ public async Task Product_Listing_Handles_Concurrent_Load() { var response = await Customer.Client.GetAsync("/api/products?pageSize=10"); - await Assert.That(response.IsSuccessStatusCode).IsTrue(); + await Assert.That(response).IsSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync>(); await Assert.That(result).IsNotNull(); @@ -44,7 +43,7 @@ public async Task Product_Search_Handles_Concurrent_Load() var response = await Customer.Client.GetAsync( $"/api/products?category={category}&pageSize=5"); - await Assert.That(response.IsSuccessStatusCode).IsTrue(); + await Assert.That(response).IsSuccessStatusCode(); } [Test, Repeat(30), ParallelLimiter] @@ -52,7 +51,7 @@ public async Task Order_History_Handles_Concurrent_Load() { var response = await Customer.Client.GetAsync("/api/orders/mine?pageSize=5"); - await Assert.That(response.IsSuccessStatusCode).IsTrue(); + await Assert.That(response).IsSuccessStatusCode(); } } diff --git a/examples/CloudShop/CloudShop.Tests/Tests/Products/ProductCrudTests.cs b/examples/CloudShop/CloudShop.Tests/Tests/Products/ProductCrudTests.cs index fcc0cc34a7..21415cf350 100644 --- a/examples/CloudShop/CloudShop.Tests/Tests/Products/ProductCrudTests.cs +++ b/examples/CloudShop/CloudShop.Tests/Tests/Products/ProductCrudTests.cs @@ -1,7 +1,5 @@ -using System.Net; using System.Net.Http.Json; using CloudShop.Shared.Contracts; -using CloudShop.Tests.Assertions; using CloudShop.Tests.DataSources; using CloudShop.Tests.Infrastructure; using TUnit.Core; @@ -18,7 +16,7 @@ namespace CloudShop.Tests.Tests.Products; /// - [ClassDataSource] with SharedType.PerTestSession for fixture sharing /// - [MethodDataSource] for parameterized test data /// - [Category] for test filtering -/// - Custom [GenerateAssertion] assertions +/// - Built-in HTTP response assertions /// [Category("Integration"), Category("Products")] public class ProductCrudTests @@ -64,7 +62,7 @@ public async Task Can_Get_Product_By_Id() // Fetch it var response = await Customer.Client.GetAsync($"/api/products/{created!.Id}"); - await Assert.That(response.IsSuccessStatusCode).IsTrue(); + await Assert.That(response).IsSuccessStatusCode(); var product = await response.Content.ReadFromJsonAsync(); await Assert.That(product!.Name).IsEqualTo("GetById Test Product"); } @@ -81,7 +79,7 @@ public async Task Admin_Can_Update_Product(UpdateProductRequest update) // Update it var response = await Admin.Client.PutAsJsonAsync($"/api/products/{created!.Id}", update); - await Assert.That(response.IsSuccessStatusCode).IsTrue(); + await Assert.That(response).IsSuccessStatusCode(); var updated = await response.Content.ReadFromJsonAsync(); await Assert.That(updated).IsNotNull(); @@ -102,7 +100,7 @@ public async Task Admin_Can_Delete_Product() // Delete it var deleteResponse = await Admin.Client.DeleteAsync($"/api/products/{created!.Id}"); - await Assert.That(deleteResponse.StatusCode).IsEqualTo(HttpStatusCode.NoContent); + await Assert.That(deleteResponse).IsNoContent(); // Verify it's gone var getResponse = await Customer.Client.GetAsync($"/api/products/{created.Id}");