test: add POST and bytes tests to ApiClientBaseTests
Added 11 new tests covering: - POST method tests (200 success, 401 unauthorized, no-body variant) - Bytes tests (GET 200, GET 404, POST 200) - Non-GET status code tests (POST 400 validation, bytes 500, multipart 401/200) All 23 ApiClientBaseTests now pass.
This commit is contained in:
@@ -219,4 +219,169 @@ public class ApiClientBaseTests
|
||||
result.IsError.ShouldBeTrue();
|
||||
result.Error.StatusCode.ShouldBe(400);
|
||||
}
|
||||
|
||||
// POST tests
|
||||
|
||||
[Fact]
|
||||
public async Task PostAsync_Returns200_MapsToSuccessValue()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new TestDto(99, "Created");
|
||||
_mockHttp.When(HttpMethod.Post, "/api/test")
|
||||
.Respond("application/json", JsonSerializer.Serialize(expected));
|
||||
|
||||
// Act
|
||||
var result = await _client.PostAsync<TestDto, TestDto>("/api/test", new TestDto(0, "Input"));
|
||||
|
||||
// Assert
|
||||
result.IsSuccess.ShouldBeTrue();
|
||||
result.Value.Id.ShouldBe(99);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PostAsync_Returns401_MapsToUnauthorized()
|
||||
{
|
||||
// Arrange
|
||||
_mockHttp.When(HttpMethod.Post, "/api/test")
|
||||
.Respond(HttpStatusCode.Unauthorized);
|
||||
|
||||
// Act
|
||||
var result = await _client.PostAsync<TestDto, TestDto>("/api/test", new TestDto(0, "Input"));
|
||||
|
||||
// Assert
|
||||
result.IsUnauthorized.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PostAsync_WithNoBody_Returns200()
|
||||
{
|
||||
// Arrange
|
||||
_mockHttp.When(HttpMethod.Post, "/api/test")
|
||||
.Respond("application/json", JsonSerializer.Serialize(new Unit()));
|
||||
|
||||
// Act
|
||||
var result = await _client.PostAsync<Unit>("/api/test");
|
||||
|
||||
// Assert
|
||||
result.IsSuccess.ShouldBeTrue();
|
||||
}
|
||||
|
||||
// Bytes tests
|
||||
|
||||
[Fact]
|
||||
public async Task GetBytesAsync_Returns200_MapsToSuccessBytes()
|
||||
{
|
||||
// Arrange
|
||||
var expectedBytes = new byte[] { 0x50, 0x4B, 0x03, 0x04 }; // ZIP header
|
||||
_mockHttp.When("/api/download")
|
||||
.Respond("application/octet-stream", new MemoryStream(expectedBytes));
|
||||
|
||||
// Act
|
||||
var result = await _client.GetBytesAsync("/api/download");
|
||||
|
||||
// Assert
|
||||
result.IsSuccess.ShouldBeTrue();
|
||||
result.Value.ShouldBe(expectedBytes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetBytesAsync_Returns404_MapsToNotFound()
|
||||
{
|
||||
// Arrange
|
||||
_mockHttp.When("/api/download")
|
||||
.Respond(HttpStatusCode.NotFound);
|
||||
|
||||
// Act
|
||||
var result = await _client.GetBytesAsync("/api/download");
|
||||
|
||||
// Assert
|
||||
result.IsNotFound.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PostForBytesAsync_Returns200_MapsToSuccessBytes()
|
||||
{
|
||||
// Arrange
|
||||
var expectedBytes = new byte[] { 0x50, 0x4B, 0x03, 0x04 };
|
||||
_mockHttp.When(HttpMethod.Post, "/api/download")
|
||||
.Respond("application/octet-stream", new MemoryStream(expectedBytes));
|
||||
|
||||
// Act
|
||||
var result = await _client.PostForBytesAsync("/api/download", new { filter = "test" });
|
||||
|
||||
// Assert
|
||||
result.IsSuccess.ShouldBeTrue();
|
||||
result.Value.ShouldBe(expectedBytes);
|
||||
}
|
||||
|
||||
// Non-GET status code tests
|
||||
|
||||
[Fact]
|
||||
public async Task PostAsync_Returns400_WithValidationErrors_MapsToValidationError()
|
||||
{
|
||||
// Arrange
|
||||
var validationProblem = new Microsoft.AspNetCore.Mvc.ValidationProblemDetails
|
||||
{
|
||||
Errors = { ["Field"] = new[] { "Required" } }
|
||||
};
|
||||
_mockHttp.When(HttpMethod.Post, "/api/test")
|
||||
.Respond(HttpStatusCode.BadRequest, "application/json",
|
||||
JsonSerializer.Serialize(validationProblem, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }));
|
||||
|
||||
// Act
|
||||
var result = await _client.PostAsync<TestDto, TestDto>("/api/test", new TestDto(0, "Input"));
|
||||
|
||||
// Assert
|
||||
result.IsValidationError.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetBytesAsync_Returns500_MapsToApiError()
|
||||
{
|
||||
// Arrange
|
||||
_mockHttp.When("/api/download")
|
||||
.Respond(HttpStatusCode.InternalServerError, "text/plain", "Server error");
|
||||
|
||||
// Act
|
||||
var result = await _client.GetBytesAsync("/api/download");
|
||||
|
||||
// Assert
|
||||
result.IsError.ShouldBeTrue();
|
||||
result.Error.StatusCode.ShouldBe(500);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PostMultipartAsync_Returns401_MapsToUnauthorized()
|
||||
{
|
||||
// Arrange
|
||||
_mockHttp.When(HttpMethod.Post, "/api/upload")
|
||||
.Respond(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var stream = new MemoryStream(new byte[] { 1, 2, 3 });
|
||||
|
||||
// Act
|
||||
var result = await _client.PostMultipartAsync<TestDto>("/api/upload", stream, "test.xlsx");
|
||||
|
||||
// Assert
|
||||
result.IsUnauthorized.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PostMultipartAsync_Returns200_MapsToSuccessValue()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new TestDto(1, "Uploaded");
|
||||
_mockHttp.When(HttpMethod.Post, "/api/upload")
|
||||
.With(req => req.Content?.Headers.ContentType?.MediaType == "multipart/form-data")
|
||||
.Respond("application/json", JsonSerializer.Serialize(expected));
|
||||
|
||||
using var stream = new MemoryStream(new byte[] { 1, 2, 3 });
|
||||
|
||||
// Act
|
||||
var result = await _client.PostMultipartAsync<TestDto>("/api/upload", stream, "test.xlsx");
|
||||
|
||||
// Assert
|
||||
result.IsSuccess.ShouldBeTrue();
|
||||
result.Value.Id.ShouldBe(1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user