Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 157 additions & 0 deletions TUnit.Assertions.Tests/HttpResponseMessageAssertionTests.cs
Original file line number Diff line number Diff line change
@@ -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("<html></html>", 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();
}
}
100 changes: 98 additions & 2 deletions TUnit.Assertions/Conditions/HttpResponseMessageAssertionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,110 @@
using System.Net;
using System.Net.Http;
using TUnit.Assertions.Attributes;

namespace TUnit.Assertions.Conditions;

/// <summary>
/// Source-generated assertions for HttpResponseMessage type using [AssertionFrom&lt;HttpResponseMessage&gt;] 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.
/// </summary>
[AssertionFrom<HttpResponseMessage>(nameof(HttpResponseMessage.IsSuccessStatusCode), ExpectationMessage = "have a success status code")]
[AssertionFrom<HttpResponseMessage>(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;
}
}
Loading
Loading