Files
DocumentService/DocumentOperator.Tests/Integration/API/PdfValidationControllerTests.cs

321 lines
11 KiB
C#

using DocumentService.Application.Common.DTOs;
using DocumentService.Client.Models.Requests;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;
using System.Net;
using System.Net.Http.Json;
using Xunit;
namespace DocumentService.Tests.Integration.API;
public class PdfValidationControllerTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly WebApplicationFactory<Program> _factory;
private readonly HttpClient _client;
public PdfValidationControllerTests(WebApplicationFactory<Program> factory)
{
_factory = factory;
_client = _factory.CreateClient();
}
#region Base64 JSON Tests
[Fact]
public async Task POST_ValidatePdf_Base64_ValidPdf_Returns200()
{
// Arrange
// Verwende ein echtes Test-PDF (embedded resource aus Unit Tests)
var assembly = typeof(PdfValidationControllerTests).Assembly;
var resourceName = "DocumentService.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 ValidatePdfBase64Request { Base64Pdf = base64Pdf };
// Act
var response = await _client.PostAsJsonAsync("/api/pdf/validation/validate", request);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var result = await response.Content.ReadFromJsonAsync<PdfValidationResult>();
result.Should().NotBeNull();
result!.PageCount.Should().BeGreaterThan(0);
result.FileSizeBytes.Should().BeGreaterThan(0);
result.PdfVersion.Should().NotBeNullOrEmpty();
}
[Fact]
public async Task POST_ValidatePdf_Base64_InvalidBase64_Returns400()
{
// Arrange
var request = new ValidatePdfBase64Request { Base64Pdf = "invalid-base64!!!" }; // Kein gültiges Base64
// Act
var response = await _client.PostAsJsonAsync("/api/pdf/validation/validate", request);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
var problemDetails = await response.Content.ReadAsStringAsync();
// FormatException message contains "Base-64" (with hyphen)
problemDetails.Should().MatchRegex("(?i)base.?64", "should contain Base64 validation error");
}
[Fact]
public async Task POST_ValidatePdf_Base64_EmptyPdf_Returns400()
{
// Arrange
var request = new ValidatePdfBase64Request { Base64Pdf = string.Empty }; // Leerer String
// Act
var response = await _client.PostAsJsonAsync("/api/pdf/validation/validate", request);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
var problemDetails = await response.Content.ReadAsStringAsync();
// Empty Base64 causes FormatException or empty stream error
problemDetails.Should().MatchRegex("(Base64|empty|stream)", "should contain validation error message");
}
#endregion
#region Multipart/Form-Data Tests
[Fact]
public async Task POST_ValidatePdf_Multipart_ValidPdf_Returns200()
{
// Arrange
var assembly = typeof(PdfValidationControllerTests).Assembly;
var resourceName = "DocumentService.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();
}
// Create multipart/form-data content
using var content = new MultipartFormDataContent();
var fileContent = new ByteArrayContent(pdfBytes);
fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
content.Add(fileContent, "file", "test.pdf");
// Act
var response = await _client.PostAsync("/api/pdf/validation/validate", content);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var result = await response.Content.ReadFromJsonAsync<PdfValidationResult>();
result.Should().NotBeNull();
result!.PageCount.Should().BeGreaterThan(0);
result.FileSizeBytes.Should().BeGreaterThan(0);
result.PdfVersion.Should().NotBeNullOrEmpty();
}
[Fact]
public async Task POST_ValidatePdf_Multipart_EmptyFile_Returns400()
{
// Arrange
using var content = new MultipartFormDataContent();
var fileContent = new ByteArrayContent(Array.Empty<byte>());
fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
content.Add(fileContent, "file", "empty.pdf");
// Act
var response = await _client.PostAsync("/api/pdf/validation/validate", content);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
var problemDetails = await response.Content.ReadAsStringAsync();
problemDetails.Should().Contain("cannot be empty");
}
[Fact]
public async Task POST_ValidatePdf_Multipart_NoFile_Returns400()
{
// Arrange
using var content = new MultipartFormDataContent();
// Act
var response = await _client.PostAsync("/api/pdf/validation/validate", content);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
}
#endregion
#region PDF/A Validation Tests (Base64)
[Fact]
public async Task POST_ValidatePdfA_Base64_ValidPdf_Returns200()
{
// Arrange
var assembly = typeof(PdfValidationControllerTests).Assembly;
var resourceName = "DocumentService.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 ValidatePdfABase64Request { Base64Pdf = base64Pdf };
// Act
var response = await _client.PostAsJsonAsync("/api/pdf/validation/validate-pdfa", request);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var result = await response.Content.ReadFromJsonAsync<PdfAValidationResult>();
result.Should().NotBeNull();
result!.IsValid.Should().BeTrue();
result.PageCount.Should().BeGreaterThan(0);
result.PdfVersion.Should().NotBeNullOrEmpty();
}
[Fact]
public async Task POST_ValidatePdfA_Base64_InvalidBase64_Returns400()
{
// Arrange
var request = new ValidatePdfABase64Request { Base64Pdf = "invalid-base64!!!" };
// Act
var response = await _client.PostAsJsonAsync("/api/pdf/validation/validate-pdfa", request);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
var problemDetails = await response.Content.ReadAsStringAsync();
// FormatException message contains "Base-64" (with hyphen)
problemDetails.Should().MatchRegex("(?i)base.?64", "should contain Base64 validation error");
}
[Fact]
public async Task POST_ValidatePdfA_Base64_EmptyPdf_Returns400()
{
// Arrange
var request = new ValidatePdfABase64Request { Base64Pdf = string.Empty };
// Act
var response = await _client.PostAsJsonAsync("/api/pdf/validation/validate-pdfa", request);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
var problemDetails = await response.Content.ReadAsStringAsync();
// Empty Base64 causes FormatException or empty stream error
problemDetails.Should().MatchRegex("(Base64|empty|stream)", "should contain validation error message");
}
#endregion
#region PDF/A Validation Tests (Multipart)
[Fact]
public async Task POST_ValidatePdfA_Multipart_ValidPdf_Returns200()
{
// Arrange
var assembly = typeof(PdfValidationControllerTests).Assembly;
var resourceName = "DocumentService.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();
}
// Create multipart/form-data content
using var content = new MultipartFormDataContent();
var fileContent = new ByteArrayContent(pdfBytes);
fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
content.Add(fileContent, "file", "test.pdf");
// Act
var response = await _client.PostAsync("/api/pdf/validation/validate-pdfa", content);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var result = await response.Content.ReadFromJsonAsync<PdfAValidationResult>();
result.Should().NotBeNull();
result!.IsValid.Should().BeTrue();
result.PageCount.Should().BeGreaterThan(0);
result.PdfVersion.Should().NotBeNullOrEmpty();
}
[Fact]
public async Task POST_ValidatePdfA_Multipart_EmptyFile_Returns400()
{
// Arrange
using var content = new MultipartFormDataContent();
var fileContent = new ByteArrayContent(Array.Empty<byte>());
fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
content.Add(fileContent, "file", "empty.pdf");
// Act
var response = await _client.PostAsync("/api/pdf/validation/validate-pdfa", content);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
var problemDetails = await response.Content.ReadAsStringAsync();
problemDetails.Should().Contain("cannot be empty");
}
[Fact]
public async Task POST_ValidatePdfA_Multipart_NoFile_Returns400()
{
// Arrange
using var content = new MultipartFormDataContent();
// Act
var response = await _client.PostAsync("/api/pdf/validation/validate-pdfa", content);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
}
#endregion
}