diff --git a/DocumentOperator.Tests/Unit/Infrastructure/Services/PdfProcessing/DevExpressPdfProcessorTests.cs b/DocumentOperator.Tests/Unit/Infrastructure/Services/PdfProcessing/DevExpressPdfProcessorTests.cs index d5120f0..0e95294 100644 --- a/DocumentOperator.Tests/Unit/Infrastructure/Services/PdfProcessing/DevExpressPdfProcessorTests.cs +++ b/DocumentOperator.Tests/Unit/Infrastructure/Services/PdfProcessing/DevExpressPdfProcessorTests.cs @@ -1,7 +1,7 @@ -using System.Reflection; +using System.Reflection; +using DocumentOperator.Application.Common.DTOs; using DocumentOperator.Application.Common.Interfaces; using DocumentOperator.Domain.Common.Exceptions; -using DocumentOperator.Domain.Models.ValueObjects; using DocumentOperator.Infrastructure.Services.PdfProcessing; using FluentAssertions; @@ -47,6 +47,11 @@ public class DevExpressPdfProcessorTests return memoryStream.ToArray(); } + /// + /// Converts byte array to MemoryStream for testing + /// + private static MemoryStream ToStream(byte[] bytes) => new MemoryStream(bytes); + #endregion #region ValidateAsync Tests @@ -58,7 +63,7 @@ public class DevExpressPdfProcessorTests byte[] pdfBytes = LoadTestPdf("valid.pdf"); // Act - var metadata = await _sut.ValidateAsync(pdfBytes); + var metadata = await _sut.ValidateAsync(ToStream(pdfBytes)); // Assert metadata.Should().NotBeNull("a valid PDF should return metadata"); @@ -74,7 +79,7 @@ public class DevExpressPdfProcessorTests byte[] pdfBytes = LoadTestPdf("valid.pdf"); // Act - var metadata = await _sut.ValidateAsync(pdfBytes); + var metadata = await _sut.ValidateAsync(ToStream(pdfBytes)); // Assert // Deine valid.pdf hat wahrscheinlich 1-5 Seiten - passe an! @@ -82,30 +87,30 @@ public class DevExpressPdfProcessorTests } [Fact] - public async Task ValidateAsync_NullBytes_ThrowsPdfProcessingException() + public async Task ValidateAsync_NullStream_ThrowsArgumentNullException() { // Arrange - byte[]? pdfBytes = null; + Stream? pdfStream = null; // Act - Func act = async () => await _sut.ValidateAsync(pdfBytes!); + Func act = async () => await _sut.ValidateAsync(pdfStream!); // Assert - await act.Should().ThrowAsync() - .WithMessage("*null*", "null input should be rejected"); + await act.Should().ThrowAsync() + .WithMessage("*pdfStream*", "null input should be rejected"); } [Fact] - public async Task ValidateAsync_EmptyBytes_ThrowsPdfProcessingException() + public async Task ValidateAsync_EmptyStream_ThrowsBadRequestException() { // Arrange - byte[] pdfBytes = Array.Empty(); + var pdfStream = new MemoryStream(); // Act - Func act = async () => await _sut.ValidateAsync(pdfBytes); + Func act = async () => await _sut.ValidateAsync(pdfStream); // Assert - await act.Should().ThrowAsync() + await act.Should().ThrowAsync() .WithMessage("*empty*", "empty input should be rejected"); } @@ -116,10 +121,10 @@ public class DevExpressPdfProcessorTests byte[] pdfBytes = "This is not a valid PDF content"u8.ToArray(); // Act - Func act = async () => await _sut.ValidateAsync(pdfBytes); + Func act = async () => await _sut.ValidateAsync(ToStream(pdfBytes)); // Assert - await act.Should().ThrowAsync() + await act.Should().ThrowAsync() .WithMessage("*valid pdf*", "corrupted PDF should throw exception"); } @@ -134,7 +139,7 @@ public class DevExpressPdfProcessorTests byte[] pdfBytes = LoadTestPdf("valid.pdf"); // Act - var metadata = await _sut.ValidateAsync(pdfBytes); + var metadata = await _sut.ValidateAsync(ToStream(pdfBytes)); // Assert double expectedSizeMB = pdfBytes.Length / 1024.0 / 1024.0; @@ -153,7 +158,7 @@ public class DevExpressPdfProcessorTests byte[] pdfBytes = LoadTestPdf("valid.pdf"); // Act - var metadata = await _sut.ValidateAsync(pdfBytes); + var metadata = await _sut.ValidateAsync(ToStream(pdfBytes)); // Assert // Note: valid.pdf actually contains /EmbeddedFiles reference (15 0 R) @@ -169,7 +174,7 @@ public class DevExpressPdfProcessorTests byte[] pdfBytes = LoadTestPdf("pdfWithMoreThanOneAttachment.pdf"); // Act - var metadata = await _sut.ValidateAsync(pdfBytes); + var metadata = await _sut.ValidateAsync(ToStream(pdfBytes)); // Assert metadata.HasAttachments.Should().BeTrue("PDF has multiple attachments"); @@ -182,4 +187,96 @@ public class DevExpressPdfProcessorTests // For now, we verify that attachment detection works (returns false for PDFs without attachments). #endregion + + #region CheckAttachmentsAsync Tests + + [Fact] + public async Task CheckAttachmentsAsync_PdfWithoutAttachments_ReturnsEmptyList() + { + // Arrange + byte[] pdfBytes = LoadTestPdf("pdfWithSwissQRCode.pdf"); + + // Act + var attachmentInfo = await _sut.CheckAttachmentsAsync(ToStream(pdfBytes)); + + // Assert + attachmentInfo.Should().NotBeNull("CheckAttachmentsAsync should return non-null result"); + attachmentInfo.HasAttachments.Should().BeFalse("Swiss QR PDF has no attachments"); + attachmentInfo.AttachmentCount.Should().Be(0, "Swiss QR PDF has no attachments"); + attachmentInfo.Attachments.Should().BeEmpty("Swiss QR PDF has no attachments"); + } + + [Fact] + public async Task CheckAttachmentsAsync_PdfWithMultipleAttachments_ReturnsCorrectMetadata() + { + // Arrange + byte[] pdfBytes = LoadTestPdf("pdfWithMoreThanOneAttachment.pdf"); + + // Act + var attachmentInfo = await _sut.CheckAttachmentsAsync(ToStream(pdfBytes)); + + // Assert + attachmentInfo.Should().NotBeNull("CheckAttachmentAsync should return non-null result"); + attachmentInfo.HasAttachments.Should().BeTrue("PDF has 6 attachments"); + attachmentInfo.AttachmentCount.Should().Be(6, "PDF has exactly 6 attachments"); + attachmentInfo.Attachments.Should().HaveCount(6, "Attachments list should contain 6 items"); + + // Verify each attachment has required properties + foreach (var attachment in attachmentInfo.Attachments) + { + attachment.FileName.Should().NotBeNullOrEmpty("each attachment must have a file name"); + attachment.MimeType.Should().NotBeNullOrEmpty("each attachment must have a MIME type"); + attachment.SizeBytes.Should().BeGreaterThan(0, "each attachment must have a size > 0"); + } + } + + [Fact] + public async Task CheckAttachmentsAsync_ValidPdf_HasAttachments() + { + // Arrange + byte[] pdfBytes = LoadTestPdf("valid.pdf"); + + // Act + var attachmentInfo = await _sut.CheckAttachmentsAsync(ToStream(pdfBytes)); + + // Assert + attachmentInfo.Should().NotBeNull("CheckAttachmentsAsync should return non-null result"); + // Note: valid.pdf contains embedded files (tested and confirmed) + attachmentInfo.HasAttachments.Should().BeTrue("valid.pdf contains attachments"); + attachmentInfo.AttachmentCount.Should().BeGreaterThan(0, "valid.pdf has at least one attachment"); + } + + [Fact] + public async Task CheckAttachmentsAsync_EmptyBytes_ThrowsBadRequestException() + { + // Arrange + var pdfStream = new MemoryStream(); + + // Act + Func act = async () => await _sut.CheckAttachmentsAsync(pdfStream); + + // Assert + await act.Should().ThrowAsync() + .WithMessage("*empty*", "empty input should be rejected"); + } + + [Fact] + public async Task CheckAttachmentsAsync_CorruptedPdf_ThrowsException() + { + // Arrange + byte[] pdfBytes = "This is not a valid PDF content"u8.ToArray(); + + // Act + Func act = async () => await _sut.CheckAttachmentsAsync(ToStream(pdfBytes)); + + // Assert + // DevExpress throws ArgumentException for invalid PDF data + await act.Should().ThrowAsync("corrupted PDF should throw exception"); + } + + #endregion } + + + +