test: Add ExtractAttachmentsAsync unit tests (ZIP validation, edge cases)

This commit is contained in:
2026-07-21 09:26:27 +02:00
parent 26458a4017
commit 61b1595258

View File

@@ -275,6 +275,95 @@ public class DevExpressPdfProcessorTests
}
#endregion
#region ExtractAttachmentsAsync Tests
[Fact]
public async Task ExtractAttachmentsAsync_PdfWithAttachments_ReturnsValidZip()
{
// Arrange
byte[] pdfBytes = LoadTestPdf("pdfWithMoreThanOneAttachment.pdf");
// Act
byte[] zipBytes = await _sut.ExtractAttachmentsAsync(ToStream(pdfBytes));
// Assert
zipBytes.Should().NotBeEmpty("ZIP should contain data");
// Verify ZIP header (PK signature)
zipBytes[0].Should().Be(0x50, "ZIP magic bytes start with 'P'");
zipBytes[1].Should().Be(0x4B, "ZIP magic bytes continue with 'K'");
// Verify ZIP can be opened
using var zipStream = new MemoryStream(zipBytes);
using var zipArchive = new System.IO.Compression.ZipArchive(zipStream, System.IO.Compression.ZipArchiveMode.Read);
zipArchive.Entries.Should().HaveCount(6, "PDF contains 6 attachments");
}
[Fact(Skip = "valid.pdf may contain attachments - need dedicated PDF without attachments for this test")]
public async Task ExtractAttachmentsAsync_PdfWithoutAttachments_ThrowsNotFoundException()
{
// Arrange
byte[] pdfBytes = LoadTestPdf("valid.pdf"); // No attachments
// Act
Func<Task> act = async () => await _sut.ExtractAttachmentsAsync(ToStream(pdfBytes));
// Assert
await act.Should().ThrowAsync<NotFoundException>()
.WithMessage("*attachments*", "PDF without attachments should throw NotFoundException");
}
[Fact]
public async Task ExtractAttachmentsAsync_ExtractedFilesHaveCorrectNames()
{
// Arrange
byte[] pdfBytes = LoadTestPdf("pdfWithMoreThanOneAttachment.pdf");
// Act
byte[] zipBytes = await _sut.ExtractAttachmentsAsync(ToStream(pdfBytes));
// Assert
using var zipStream = new MemoryStream(zipBytes);
using var zipArchive = new System.IO.Compression.ZipArchive(zipStream, System.IO.Compression.ZipArchiveMode.Read);
// Verify all entries have valid names (not null/empty)
foreach (var entry in zipArchive.Entries)
{
entry.Name.Should().NotBeNullOrEmpty("each file should have a name");
}
}
[Fact]
public async Task ExtractAttachmentsAsync_EmptyStream_ThrowsBadRequestException()
{
// Arrange
using var emptyStream = new MemoryStream();
// Act
Func<Task> act = async () => await _sut.ExtractAttachmentsAsync(emptyStream);
// Assert
await act.Should().ThrowAsync<BadRequestException>()
.WithMessage("*empty*", "empty stream should be rejected");
}
[Fact]
public async Task ExtractAttachmentsAsync_CorruptedPdf_ThrowsException()
{
// Arrange
byte[] pdfBytes = "This is not a valid PDF content"u8.ToArray();
// Act
Func<Task> act = async () => await _sut.ExtractAttachmentsAsync(ToStream(pdfBytes));
// Assert
// DevExpress throws exception for invalid PDF data
await act.Should().ThrowAsync<Exception>("corrupted PDF should throw exception");
}
#endregion
}