diff --git a/NEW/tests/JdeScoping.Client.Tests/Services/ApiClientBaseTests.cs b/NEW/tests/JdeScoping.Client.Tests/Services/ApiClientBaseTests.cs index efc5f98..ecdbacc 100644 --- a/NEW/tests/JdeScoping.Client.Tests/Services/ApiClientBaseTests.cs +++ b/NEW/tests/JdeScoping.Client.Tests/Services/ApiClientBaseTests.cs @@ -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("/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("/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("/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("/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("/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("/api/upload", stream, "test.xlsx"); + + // Assert + result.IsSuccess.ShouldBeTrue(); + result.Value.Id.ShouldBe(1); + } }