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:
2026-08-30 21:33:25 +02:00
parent 050cb55bf9
commit 207c778f3a
108 changed files with 37 additions and 37 deletions

View File

@@ -0,0 +1,183 @@
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;
using Xunit;
namespace DocumentService.Tests.Unit.Client;
public class PdfValidationClientTests
{
private static (PdfValidationClient client, MockHttpMessageHandler handler) Build<T>(T responseBody)
{
var handler = MockHttpMessageHandler.ReturningJson(responseBody);
var httpClient = new HttpClient(handler) { BaseAddress = new Uri("http://localhost") };
return (new PdfValidationClient(httpClient, NullLogger<PdfValidationClient>.Instance), handler);
}
private static (PdfValidationClient client, MockHttpMessageHandler handler) BuildError(HttpStatusCode code)
{
var handler = MockHttpMessageHandler.ReturningStatus(code);
var httpClient = new HttpClient(handler) { BaseAddress = new Uri("http://localhost") };
return (new PdfValidationClient(httpClient, NullLogger<PdfValidationClient>.Instance), handler);
}
private static byte[] FakePdfBytes() => "fake-pdf"u8.ToArray();
// ── ValidatePdfAsync (Stream) ────────────────────────────────────────────
[Fact]
public async Task ValidatePdfAsync_Stream_SendsMultipartPost()
{
var expected = new PdfValidationResult { PageCount = 3, PdfVersion = "1.7", FileSizeBytes = 2048, IsEncrypted = false };
var (client, handler) = Build(expected);
var result = await client.ValidatePdfAsync(new MemoryStream(FakePdfBytes()));
result.PageCount.Should().Be(3);
result.PdfVersion.Should().Be("1.7");
result.FileSizeBytes.Should().Be(2048);
result.IsEncrypted.Should().BeFalse();
handler.LastRequest!.Method.Should().Be(HttpMethod.Post);
handler.LastRequest.RequestUri!.PathAndQuery.Should().Be("/api/pdf/validation/validate");
handler.LastRequest.Content.Should().BeOfType<MultipartFormDataContent>();
}
[Fact]
public async Task ValidatePdfAsync_Stream_EncryptedPdf_DeserializesIsEncryptedTrue()
{
var expected = new PdfValidationResult { PageCount = 1, IsEncrypted = true, PdfVersion = "1.6" };
var (client, _) = Build(expected);
var result = await client.ValidatePdfAsync(new MemoryStream(FakePdfBytes()));
result.IsEncrypted.Should().BeTrue("encrypted PDFs should surface IsEncrypted=true");
}
[Fact]
public async Task ValidatePdfAsync_Stream_ThrowsWhenApiReturnsNull()
{
var handler = MockHttpMessageHandler.ReturningJson<PdfValidationResult?>(null);
var httpClient = new HttpClient(handler) { BaseAddress = new Uri("http://localhost") };
var client = new PdfValidationClient(httpClient, NullLogger<PdfValidationClient>.Instance);
await client.Invoking(c => c.ValidatePdfAsync(new MemoryStream(FakePdfBytes())))
.Should().ThrowAsync<InvalidOperationException>();
}
[Fact]
public async Task ValidatePdfAsync_Stream_WhenApiReturns400_ThrowsHttpRequestException()
{
var (client, _) = BuildError(HttpStatusCode.BadRequest);
await client.Invoking(c => c.ValidatePdfAsync(new MemoryStream(FakePdfBytes())))
.Should().ThrowAsync<HttpRequestException>();
}
[Fact]
public async Task ValidatePdfAsync_Stream_WhenApiReturns500_ThrowsHttpRequestException()
{
var (client, _) = BuildError(HttpStatusCode.InternalServerError);
await client.Invoking(c => c.ValidatePdfAsync(new MemoryStream(FakePdfBytes())))
.Should().ThrowAsync<HttpRequestException>();
}
// ── ValidatePdfAsync (byte[]) ────────────────────────────────────────────
[Fact]
public async Task ValidatePdfAsync_Bytes_SendsJsonWithBase64()
{
var expected = new PdfValidationResult { PageCount = 1, IsEncrypted = false, HasAttachments = true, AttachmentCount = 2 };
var (client, handler) = Build(expected);
var result = await client.ValidatePdfAsync(FakePdfBytes());
result.PageCount.Should().Be(1);
result.HasAttachments.Should().BeTrue();
result.AttachmentCount.Should().Be(2);
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();
}
[Fact]
public async Task ValidatePdfAsync_Bytes_WhenApiReturns400_ThrowsHttpRequestException()
{
var (client, _) = BuildError(HttpStatusCode.BadRequest);
await client.Invoking(c => c.ValidatePdfAsync(FakePdfBytes()))
.Should().ThrowAsync<HttpRequestException>();
}
// ── ValidatePdfAAsync (Stream) ───────────────────────────────────────────
[Fact]
public async Task ValidatePdfAAsync_Stream_DeserializesAllFields()
{
var expected = new PdfAValidationResult
{
IsValid = true, PdfAVersion = "PDF/A-3b", PageCount = 2,
Errors = [], Warnings = []
};
var (client, handler) = Build(expected);
var result = await client.ValidatePdfAAsync(new MemoryStream(FakePdfBytes()));
result.IsValid.Should().BeTrue();
result.PdfAVersion.Should().Be("PDF/A-3b");
result.PageCount.Should().Be(2);
result.Errors.Should().BeEmpty();
handler.LastRequest!.RequestUri!.PathAndQuery.Should().Be("/api/pdf/validation/validate-pdfa");
handler.LastRequest.Content.Should().BeOfType<MultipartFormDataContent>();
}
[Fact]
public async Task ValidatePdfAAsync_Stream_NonCompliant_ReturnsErrors()
{
var expected = new PdfAValidationResult
{
IsValid = false,
Errors = ["Missing embedded font", "Encryption not allowed"],
Warnings = ["Manual verification recommended"]
};
var (client, _) = Build(expected);
var result = await client.ValidatePdfAAsync(new MemoryStream(FakePdfBytes()));
result.IsValid.Should().BeFalse();
result.Errors.Should().HaveCount(2).And.Contain("Missing embedded font");
result.Warnings.Should().HaveCount(1);
}
[Fact]
public async Task ValidatePdfAAsync_Stream_WhenApiReturns400_ThrowsHttpRequestException()
{
var (client, _) = BuildError(HttpStatusCode.BadRequest);
await client.Invoking(c => c.ValidatePdfAAsync(new MemoryStream(FakePdfBytes())))
.Should().ThrowAsync<HttpRequestException>();
}
// ── ValidatePdfAAsync (byte[]) ───────────────────────────────────────────
[Fact]
public async Task ValidatePdfAAsync_Bytes_SendsJsonToCorrectEndpoint()
{
var expected = new PdfAValidationResult { IsValid = true };
var (client, handler) = Build(expected);
await client.ValidatePdfAAsync(FakePdfBytes());
handler.LastRequest!.RequestUri!.PathAndQuery.Should().Be("/api/pdf/validation/validate-pdfa");
handler.LastRequest.Content!.Headers.ContentType!.MediaType.Should().Be("application/json");
}
[Fact]
public async Task ValidatePdfAAsync_Bytes_WhenApiReturns500_ThrowsHttpRequestException()
{
var (client, _) = BuildError(HttpStatusCode.InternalServerError);
await client.Invoking(c => c.ValidatePdfAAsync(FakePdfBytes()))
.Should().ThrowAsync<HttpRequestException>();
}
}