Refactor: Rename DocumentOperator to DocumentService
Updated project and solution files to rename and restructure `DocumentOperator` to `DocumentService`. Modified project references in `DocumentService.API.csproj`, `DocumentService.Application.csproj`, and `DocumentService.Infrastructure.csproj` to reflect the new naming convention. Updated `DocumentService.sln` to remove old project references, add new ones, and adjust configuration and nested project mappings accordingly. This change aligns the project structure with the new naming convention.
This commit is contained in:
199
DocumentService.Tests/Unit/Client/ZugferdClientTests.cs
Normal file
199
DocumentService.Tests/Unit/Client/ZugferdClientTests.cs
Normal file
@@ -0,0 +1,199 @@
|
||||
using DocumentService.Client.Clients;
|
||||
using DocumentService.Client.Interfaces;
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace DocumentService.Tests.Unit.Client;
|
||||
|
||||
/// <summary>
|
||||
/// Unit tests for <see cref="ZugferdClient"/>.
|
||||
/// All tests use a fake <see cref="MockHttpMessageHandler"/> — no real HTTP calls are made.
|
||||
/// </summary>
|
||||
public class ZugferdClientTests
|
||||
{
|
||||
// ?? helpers ?????????????????????????????????????????????????????????????
|
||||
|
||||
private static (ZugferdClient client, MockHttpMessageHandler handler) BuildJson<T>(T body)
|
||||
{
|
||||
var handler = MockHttpMessageHandler.ReturningJson(body);
|
||||
var httpClient = new HttpClient(handler) { BaseAddress = new Uri("http://localhost") };
|
||||
var client = new ZugferdClient(httpClient, NullLogger<ZugferdClient>.Instance);
|
||||
return (client, handler);
|
||||
}
|
||||
|
||||
private static (ZugferdClient client, MockHttpMessageHandler handler) BuildBytes(byte[] bytes, string mediaType = "application/xml")
|
||||
{
|
||||
var handler = MockHttpMessageHandler.ReturningBytes(bytes, mediaType);
|
||||
var httpClient = new HttpClient(handler) { BaseAddress = new Uri("http://localhost") };
|
||||
var client = new ZugferdClient(httpClient, NullLogger<ZugferdClient>.Instance);
|
||||
return (client, handler);
|
||||
}
|
||||
|
||||
private static byte[] FakePdfBytes() => "fake-pdf-content"u8.ToArray();
|
||||
private static byte[] FakeXmlBytes() => "<invoice>test</invoice>"u8.ToArray();
|
||||
|
||||
// ?? HasZugferdAsync (Stream) ?????????????????????????????????????????????
|
||||
|
||||
[Fact]
|
||||
public async Task HasZugferdAsync_Stream_WhenZugferdPresent_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new ZugferdCheckResult { HasZugferd = true, Version = "2.1", Profile = "EN 16931" };
|
||||
var (client, handler) = BuildJson(expected);
|
||||
|
||||
// Act
|
||||
var result = await client.HasZugferdAsync(new MemoryStream(FakePdfBytes()));
|
||||
|
||||
// Assert
|
||||
result.HasZugferd.Should().BeTrue();
|
||||
result.Version.Should().Be("2.1");
|
||||
result.Profile.Should().Be("EN 16931");
|
||||
handler.LastRequest!.RequestUri!.PathAndQuery.Should().Be("/api/pdf/zugferd/has-zugferd");
|
||||
handler.LastRequest.Content.Should().BeOfType<MultipartFormDataContent>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HasZugferdAsync_Stream_WhenNoZugferd_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new ZugferdCheckResult { HasZugferd = false };
|
||||
var (client, _) = BuildJson(expected);
|
||||
|
||||
// Act
|
||||
var result = await client.HasZugferdAsync(new MemoryStream(FakePdfBytes()));
|
||||
|
||||
// Assert
|
||||
result.HasZugferd.Should().BeFalse();
|
||||
result.Version.Should().BeNull();
|
||||
}
|
||||
|
||||
// ?? HasZugferdAsync (byte[]) ?????????????????????????????????????????????
|
||||
|
||||
[Fact]
|
||||
public async Task HasZugferdAsync_Bytes_SendsJsonWithBase64()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new ZugferdCheckResult { HasZugferd = true };
|
||||
var (client, handler) = BuildJson(expected);
|
||||
|
||||
// Act
|
||||
await client.HasZugferdAsync(FakePdfBytes());
|
||||
|
||||
// Assert
|
||||
handler.LastRequest!.Content.Should().NotBeNull();
|
||||
handler.LastRequest.Content!.Headers.ContentType!.MediaType.Should().Be("application/json");
|
||||
var body = await handler.LastRequest.Content!.ReadAsStringAsync();
|
||||
var doc = JsonDocument.Parse(body);
|
||||
doc.RootElement.GetProperty("base64Pdf").GetString().Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
// ?? ExtractZugferdAsync (Stream) — raw XML stream ?????????????????????????
|
||||
|
||||
[Fact]
|
||||
public async Task ExtractZugferdAsync_Stream_SendsMultipartWithAsFileTrue()
|
||||
{
|
||||
// Arrange
|
||||
var (client, handler) = BuildBytes(FakeXmlBytes());
|
||||
|
||||
// Act
|
||||
using var result = await client.ExtractZugferdAsync(new MemoryStream(FakePdfBytes()));
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
handler.LastRequest!.RequestUri!.PathAndQuery.Should().Be("/api/pdf/zugferd/extract?asFile=true");
|
||||
handler.LastRequest.Content.Should().BeOfType<MultipartFormDataContent>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExtractZugferdAsync_Stream_ReturnsXmlContent()
|
||||
{
|
||||
// Arrange
|
||||
var xmlBytes = "<root><invoice/></root>"u8.ToArray();
|
||||
var (client, _) = BuildBytes(xmlBytes);
|
||||
|
||||
// Act
|
||||
using var result = await client.ExtractZugferdAsync(new MemoryStream(FakePdfBytes()));
|
||||
var content = await new StreamReader(result).ReadToEndAsync();
|
||||
|
||||
// Assert
|
||||
content.Should().Be("<root><invoice/></root>");
|
||||
}
|
||||
|
||||
// ?? ExtractZugferdAsync (byte[]) ?????????????????????????????????????????
|
||||
|
||||
[Fact]
|
||||
public async Task ExtractZugferdAsync_Bytes_SendsJsonWithFormatFile()
|
||||
{
|
||||
// Arrange
|
||||
var (client, handler) = BuildBytes(FakeXmlBytes());
|
||||
|
||||
// Act
|
||||
using var result = await client.ExtractZugferdAsync(FakePdfBytes());
|
||||
|
||||
// Assert
|
||||
handler.LastRequest!.RequestUri!.PathAndQuery.Should().Be("/api/pdf/zugferd/extract?format=file");
|
||||
handler.LastRequest.Content.Should().NotBeNull();
|
||||
handler.LastRequest.Content!.Headers.ContentType!.MediaType.Should().Be("application/json");
|
||||
}
|
||||
|
||||
// ?? ExtractZugferdAsResultAsync (Stream) ?????????????????????????????????
|
||||
|
||||
[Fact]
|
||||
public async Task ExtractZugferdAsResultAsync_Stream_ReturnsStructuredResult()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new ZugferdExtractionResult
|
||||
{
|
||||
FileName = "factur-x.xml",
|
||||
XmlContent = "<invoice/>",
|
||||
Version = "2.1",
|
||||
Profile = "EN 16931"
|
||||
};
|
||||
var (client, handler) = BuildJson(expected);
|
||||
|
||||
// Act
|
||||
var result = await client.ExtractZugferdAsResultAsync(new MemoryStream(FakePdfBytes()));
|
||||
|
||||
// Assert
|
||||
result.FileName.Should().Be("factur-x.xml");
|
||||
result.XmlContent.Should().Be("<invoice/>");
|
||||
result.Version.Should().Be("2.1");
|
||||
handler.LastRequest!.RequestUri!.PathAndQuery.Should().Be("/api/pdf/zugferd/extract?asFile=false");
|
||||
}
|
||||
|
||||
// ?? ExtractZugferdAsResultAsync (byte[]) ?????????????????????????????????
|
||||
|
||||
[Fact]
|
||||
public async Task ExtractZugferdAsResultAsync_Bytes_SendsJsonWithFormatJson()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new ZugferdExtractionResult { FileName = "zugferd.xml", XmlContent = "<x/>" };
|
||||
var (client, handler) = BuildJson(expected);
|
||||
|
||||
// Act
|
||||
await client.ExtractZugferdAsResultAsync(FakePdfBytes());
|
||||
|
||||
// Assert
|
||||
handler.LastRequest!.RequestUri!.PathAndQuery.Should().Be("/api/pdf/zugferd/extract?format=json");
|
||||
handler.LastRequest.Content.Should().NotBeNull();
|
||||
handler.LastRequest.Content!.Headers.ContentType!.MediaType.Should().Be("application/json");
|
||||
}
|
||||
|
||||
// ?? HTTP error propagation ???????????????????????????????????????????????
|
||||
|
||||
[Fact]
|
||||
public async Task HasZugferdAsync_WhenApiReturns400_ThrowsHttpRequestException()
|
||||
{
|
||||
// Arrange
|
||||
var handler = MockHttpMessageHandler.ReturningStatus(HttpStatusCode.BadRequest);
|
||||
var httpClient = new HttpClient(handler) { BaseAddress = new Uri("http://localhost") };
|
||||
var client = new ZugferdClient(httpClient, NullLogger<ZugferdClient>.Instance);
|
||||
|
||||
// Act & Assert
|
||||
await client.Invoking(c => c.HasZugferdAsync(new MemoryStream(FakePdfBytes())))
|
||||
.Should().ThrowAsync<HttpRequestException>();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user