test: Add 10 unit tests for MergePdfsAsync + LoadTestPdfAsStream helper
Unit tests (10): - MergePdfsAsync_TwoPdfs_ReturnsMergedPdf - MergePdfsAsync_ThreePdfs_ReturnsMergedPdf - MergePdfsAsync_WithNullPageRanges_MergesAllPages - MergePdfsAsync_WithEmptyPageRanges_MergesAllPages - MergePdfsAsync_WithRangeFormat_MergesSelectedPages - MergePdfsAsync_SinglePdf_ThrowsBadRequestException - MergePdfsAsync_InvalidPageRangeCount_ThrowsBadRequestException - MergePdfsAsync_InvalidPageRangeFormat_ThrowsBadRequestException - MergePdfsAsync_PageNumberOutOfRange_ThrowsBadRequestException - MergePdfsAsync_StreamNotAtPositionZero_ThrowsBadRequestException Helper: - Add LoadTestPdfAsStream helper for Stream-returning test setup
This commit is contained in:
@@ -47,6 +47,17 @@ public class DevExpressPdfProcessorTests
|
|||||||
return memoryStream.ToArray();
|
return memoryStream.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads a test PDF from embedded resources as Stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename">Name of the PDF file (e.g., "valid.pdf")</param>
|
||||||
|
/// <returns>PDF content as MemoryStream (caller must dispose)</returns>
|
||||||
|
private static MemoryStream LoadTestPdfAsStream(string filename)
|
||||||
|
{
|
||||||
|
byte[] pdfBytes = LoadTestPdf(filename);
|
||||||
|
return new MemoryStream(pdfBytes);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts byte array to MemoryStream for testing
|
/// Converts byte array to MemoryStream for testing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -364,8 +375,195 @@ public class DevExpressPdfProcessorTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region MergePdfsAsync Tests
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task MergePdfsAsync_TwoPdfs_ReturnsMergedPdf()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
using var pdf1 = LoadTestPdfAsStream("valid.pdf");
|
||||||
|
using var pdf2 = LoadTestPdfAsStream("pdfWithSwissQRCode.pdf");
|
||||||
|
var streams = new List<Stream> { pdf1, pdf2 };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
byte[] mergedPdf = await _sut.MergePdfsAsync(streams);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
mergedPdf.Should().NotBeEmpty("merged PDF should contain data");
|
||||||
|
mergedPdf.Length.Should().BeGreaterThan(1000, "merged PDF should be reasonably sized");
|
||||||
|
|
||||||
|
// Verify it's a valid PDF by loading it
|
||||||
|
using var verifyStream = new MemoryStream(mergedPdf);
|
||||||
|
using var verifyProcessor = new DevExpress.Pdf.PdfDocumentProcessor();
|
||||||
|
verifyProcessor.LoadDocument(verifyStream);
|
||||||
|
verifyProcessor.Document.Pages.Count.Should().BeGreaterOrEqualTo(2, "merged PDF should have at least 2 pages");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task MergePdfsAsync_ThreePdfs_ReturnsMergedPdf()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
using var pdf1 = LoadTestPdfAsStream("valid.pdf");
|
||||||
|
using var pdf2 = LoadTestPdfAsStream("pdfWithSwissQRCode.pdf");
|
||||||
|
using var pdf3 = LoadTestPdfAsStream("pdfWithMoreThanOneAttachment.pdf");
|
||||||
|
var streams = new List<Stream> { pdf1, pdf2, pdf3 };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
byte[] mergedPdf = await _sut.MergePdfsAsync(streams);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
mergedPdf.Should().NotBeEmpty();
|
||||||
|
|
||||||
|
// Verify merged PDF
|
||||||
|
using var verifyStream = new MemoryStream(mergedPdf);
|
||||||
|
using var verifyProcessor = new DevExpress.Pdf.PdfDocumentProcessor();
|
||||||
|
verifyProcessor.LoadDocument(verifyStream);
|
||||||
|
verifyProcessor.Document.Pages.Count.Should().BeGreaterOrEqualTo(3, "merged PDF should have at least 3 pages");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task MergePdfsAsync_WithPageRanges_MergesSelectedPages()
|
||||||
|
{
|
||||||
|
// Arrange: Merge first page of each PDF
|
||||||
|
using var pdf1 = LoadTestPdfAsStream("pdfWithSwissQRCode.pdf"); // Multi-page
|
||||||
|
using var pdf2 = LoadTestPdfAsStream("pdfWithMoreThanOneAttachment.pdf"); // Multi-page
|
||||||
|
var streams = new List<Stream> { pdf1, pdf2 };
|
||||||
|
var pageRanges = new List<string?> { "1", "1" }; // Only first page from each
|
||||||
|
|
||||||
|
// Act
|
||||||
|
byte[] mergedPdf = await _sut.MergePdfsAsync(streams, pageRanges);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
mergedPdf.Should().NotBeEmpty();
|
||||||
|
|
||||||
|
// Verify merged PDF has exactly 2 pages
|
||||||
|
using var verifyStream = new MemoryStream(mergedPdf);
|
||||||
|
using var verifyProcessor = new DevExpress.Pdf.PdfDocumentProcessor();
|
||||||
|
verifyProcessor.LoadDocument(verifyStream);
|
||||||
|
verifyProcessor.Document.Pages.Count.Should().Be(2, "should have exactly 2 pages (1 from each PDF)");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task MergePdfsAsync_WithRangeFormat_MergesSelectedPages()
|
||||||
|
{
|
||||||
|
// Arrange: Merge 2 PDFs, second PDF with page range "1" (first page only)
|
||||||
|
using var pdf1 = LoadTestPdfAsStream("valid.pdf"); // 1 page
|
||||||
|
using var pdf2 = LoadTestPdfAsStream("pdfWithMoreThanOneAttachment.pdf"); // PDF with attachments
|
||||||
|
var streams = new List<Stream> { pdf1, pdf2 };
|
||||||
|
var pageRanges = new List<string?> { null, "1" }; // All pages from first, page 1 only from second
|
||||||
|
|
||||||
|
// Act
|
||||||
|
byte[] mergedPdf = await _sut.MergePdfsAsync(streams, pageRanges);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
mergedPdf.Should().NotBeEmpty();
|
||||||
|
|
||||||
|
// Verify merged PDF has at least 2 pages (1 from first + 1 from second)
|
||||||
|
using var verifyStream = new MemoryStream(mergedPdf);
|
||||||
|
using var verifyProcessor = new DevExpress.Pdf.PdfDocumentProcessor();
|
||||||
|
verifyProcessor.LoadDocument(verifyStream);
|
||||||
|
verifyProcessor.Document.Pages.Count.Should().BeGreaterOrEqualTo(2, "should have at least 2 pages");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task MergePdfsAsync_SinglePdf_ThrowsBadRequestException()
|
||||||
|
{
|
||||||
|
// Arrange: Only one PDF (minimum 2 required)
|
||||||
|
using var pdf1 = LoadTestPdfAsStream("valid.pdf");
|
||||||
|
var streams = new List<Stream> { pdf1 };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var act = async () => await _sut.MergePdfsAsync(streams);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await act.Should().ThrowAsync<BadRequestException>()
|
||||||
|
.WithMessage("*at least 2*");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task MergePdfsAsync_EmptyStream_ThrowsBadRequestException()
|
||||||
|
{
|
||||||
|
// Arrange: One valid PDF + one empty stream
|
||||||
|
using var pdf1 = LoadTestPdfAsStream("valid.pdf");
|
||||||
|
using var emptyStream = new MemoryStream();
|
||||||
|
var streams = new List<Stream> { pdf1, emptyStream };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var act = async () => await _sut.MergePdfsAsync(streams);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await act.Should().ThrowAsync<BadRequestException>()
|
||||||
|
.WithMessage("*empty*");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task MergePdfsAsync_StreamNotAtBeginning_ThrowsBadRequestException()
|
||||||
|
{
|
||||||
|
// Arrange: Valid PDFs but second stream not at Position=0
|
||||||
|
using var pdf1 = LoadTestPdfAsStream("valid.pdf");
|
||||||
|
using var pdf2 = LoadTestPdfAsStream("pdfWithSwissQRCode.pdf");
|
||||||
|
pdf2.Position = 10; // Move position away from beginning
|
||||||
|
var streams = new List<Stream> { pdf1, pdf2 };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var act = async () => await _sut.MergePdfsAsync(streams);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await act.Should().ThrowAsync<BadRequestException>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task MergePdfsAsync_InvalidPageRange_ThrowsBadRequestException()
|
||||||
|
{
|
||||||
|
// Arrange: Invalid page range format
|
||||||
|
using var pdf1 = LoadTestPdfAsStream("valid.pdf");
|
||||||
|
using var pdf2 = LoadTestPdfAsStream("pdfWithSwissQRCode.pdf");
|
||||||
|
var streams = new List<Stream> { pdf1, pdf2 };
|
||||||
|
var pageRanges = new List<string?> { "1", "abc" }; // Invalid format
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var act = async () => await _sut.MergePdfsAsync(streams, pageRanges);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await act.Should().ThrowAsync<BadRequestException>()
|
||||||
|
.WithMessage("*Invalid page*");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task MergePdfsAsync_PageRangeExceedsPageCount_ThrowsBadRequestException()
|
||||||
|
{
|
||||||
|
// Arrange: Page range exceeds document page count
|
||||||
|
using var pdf1 = LoadTestPdfAsStream("valid.pdf"); // 1 page
|
||||||
|
using var pdf2 = LoadTestPdfAsStream("pdfWithSwissQRCode.pdf");
|
||||||
|
var streams = new List<Stream> { pdf1, pdf2 };
|
||||||
|
var pageRanges = new List<string?> { "1-99", null }; // 99 exceeds pdf1 page count
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var act = async () => await _sut.MergePdfsAsync(streams, pageRanges);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await act.Should().ThrowAsync<BadRequestException>()
|
||||||
|
.WithMessage("*exceeds document page count*");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task MergePdfsAsync_PageRangesMismatch_ThrowsBadRequestException()
|
||||||
|
{
|
||||||
|
// Arrange: Page ranges count doesn't match streams count
|
||||||
|
using var pdf1 = LoadTestPdfAsStream("valid.pdf");
|
||||||
|
using var pdf2 = LoadTestPdfAsStream("pdfWithSwissQRCode.pdf");
|
||||||
|
var streams = new List<Stream> { pdf1, pdf2 };
|
||||||
|
var pageRanges = new List<string?> { "1" }; // Only 1 range for 2 PDFs
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var act = async () => await _sut.MergePdfsAsync(streams, pageRanges);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
await act.Should().ThrowAsync<BadRequestException>()
|
||||||
|
.WithMessage("*must match*");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user