Add ValidatePDF feature with API, Swagger, and tests

Implemented the ValidatePDF feature end-to-end:
- Added `/api/v1/documents/validate` Minimal API endpoint.
- Introduced centralized ExceptionHandlingMiddleware.
- Configured Swagger with `AddSwaggerDocumentation` extension.
- Enabled XML comments in `DocumentOperator.API.csproj`.
- Updated DTOs with XML comments and added `FileSizeMB`.
- Added integration tests for the ValidatePDF endpoint (3 tests).
- Registered infrastructure services (e.g., `IPdfProcessor`).
- Refactored `Program.cs` to include middleware and endpoints.
- Updated PHASENPLAN.md and ROADMAP.md to reflect progress.
- Cleaned up code and made `Program` accessible for tests.
This commit is contained in:
OlgunR
2026-06-25 16:01:33 +02:00
parent afc0e34312
commit 930b76ecb5
12 changed files with 493 additions and 143 deletions

View File

@@ -0,0 +1,89 @@
using DocumentOperator.Application.Common.DTOs;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;
using System.Net;
using System.Net.Http.Json;
using Xunit;
namespace DocumentOperator.Tests.Integration.API;
public class DocumentEndpointsTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly WebApplicationFactory<Program> _factory;
private readonly HttpClient _client;
public DocumentEndpointsTests(WebApplicationFactory<Program> factory)
{
_factory = factory;
_client = _factory.CreateClient();
}
[Fact]
public async Task POST_ValidatePdf_ValidPdf_Returns200()
{
// Arrange
// Verwende ein echtes Test-PDF (embedded resource aus Unit Tests)
var assembly = typeof(DocumentEndpointsTests).Assembly;
var resourceName = "DocumentOperator.Tests.TestData.Pdfs.valid.pdf";
byte[] pdfBytes;
using (var stream = assembly.GetManifestResourceStream(resourceName))
{
if (stream == null)
{
throw new InvalidOperationException($"Test resource '{resourceName}' not found");
}
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
pdfBytes = ms.ToArray();
}
var base64Pdf = Convert.ToBase64String(pdfBytes);
var request = new ValidatePdfRequest(base64Pdf);
// Act
var response = await _client.PostAsJsonAsync("/api/v1/documents/validate", request);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var result = await response.Content.ReadFromJsonAsync<ValidatePdfResponse>();
result.Should().NotBeNull();
result!.PageCount.Should().BeGreaterThan(0);
result.FileSizeBytes.Should().BeGreaterThan(0);
result.PdfVersion.Should().NotBeNullOrEmpty();
}
[Fact]
public async Task POST_ValidatePdf_InvalidBase64_Returns400()
{
// Arrange
var request = new ValidatePdfRequest("invalid-base64!!!"); // Kein gültiges Base64
// Act
var response = await _client.PostAsJsonAsync("/api/v1/documents/validate", request);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
var problemDetails = await response.Content.ReadAsStringAsync();
problemDetails.Should().Contain("Base64");
}
[Fact]
public async Task POST_ValidatePdf_EmptyPdf_Returns400()
{
// Arrange
var request = new ValidatePdfRequest(string.Empty); // Leerer String
// Act
var response = await _client.PostAsJsonAsync("/api/v1/documents/validate", request);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
var problemDetails = await response.Content.ReadAsStringAsync();
problemDetails.Should().Contain("cannot be empty");
}
}