using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using NUnit.Framework;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.UnitTests;
///
/// This test suite focus on executing various QPDF operations.
/// In most cases, it does not check the result but rather if any exception is thrown.
///
public class DocumentOperationTests
{
[Test]
public void TakePages()
{
GenerateSampleDocument("take-input.pdf", Colors.Red.Medium, 10);
DocumentOperation
.LoadFile("take-input.pdf")
.TakePages("2-5")
.Save("operation-take.pdf");
}
[Test]
public void MergeTest()
{
GenerateSampleDocument("merge-first.pdf", Colors.Red.Medium, 3);
GenerateSampleDocument("merge-second.pdf", Colors.Green.Medium, 5);
GenerateSampleDocument("merge-third.pdf", Colors.Blue.Medium, 7);
DocumentOperation
.LoadFile("merge-first.pdf")
.MergeFile("merge-second.pdf")
.MergeFile("merge-third.pdf")
.Save("operation-merged.pdf");
}
[Test]
public void OverlayTest()
{
GenerateSampleDocument("overlay-main.pdf", Colors.Red.Medium, 10);
GenerateSampleDocument("overlay-watermark.pdf", Colors.Green.Medium, 5);
DocumentOperation
.LoadFile("overlay-main.pdf")
.OverlayFile(new DocumentOperation.LayerConfiguration
{
FilePath = "overlay-watermark.pdf"
})
.Save("operation-overlay.pdf");
}
[Test]
public void UnderlayTest()
{
GenerateSampleDocument("underlay-main.pdf", Colors.Red.Medium, 10);
GenerateSampleDocument("underlay-watermark.pdf", Colors.Green.Medium, 5);
DocumentOperation
.LoadFile("underlay-main.pdf")
.UnderlayFile(new DocumentOperation.LayerConfiguration
{
FilePath = "underlay-watermark.pdf",
})
.Save("operation-underlay.pdf");
}
[Test]
public void AttachmentTest()
{
GenerateSampleDocument("attachment-main.pdf", Colors.Red.Medium, 10);
GenerateSampleDocument("attachment-file.pdf", Colors.Green.Medium, 5);
DocumentOperation
.LoadFile("attachment-main.pdf")
.AddAttachment(new DocumentOperation.DocumentAttachment
{
FilePath = "attachment-file.pdf"
})
.Save("operation-attachment.pdf");
}
[Test]
public void Encrypt40Test()
{
GenerateSampleDocument("encrypt40-input.pdf", Colors.Red.Medium, 10);
DocumentOperation
.LoadFile("encrypt40-input.pdf")
.Encrypt(new DocumentOperation.Encryption40Bit()
{
UserPassword = "user_password",
OwnerPassword = "owner_password"
})
.Save("operation-encrypt40.pdf");
}
[Test]
public void Encrypt128Test()
{
GenerateSampleDocument("encrypt128-input.pdf", Colors.Red.Medium, 10);
DocumentOperation
.LoadFile("encrypt128-input.pdf")
.Encrypt(new DocumentOperation.Encryption128Bit()
{
UserPassword = "user_password",
OwnerPassword = "owner_password"
})
.Save("operation-encrypt128.pdf");
}
[Test]
public void Encrypt256Test()
{
GenerateSampleDocument("encrypt256-input.pdf", Colors.Red.Medium, 10);
DocumentOperation
.LoadFile("encrypt256-input.pdf")
.Encrypt(new DocumentOperation.Encryption256Bit()
{
UserPassword = "user_password",
OwnerPassword = "owner_password"
})
.Save("operation-encrypt256.pdf");
}
[Test]
public void LinearizeTest()
{
GenerateSampleDocument("linearize-input.pdf", Colors.Red.Medium, 10);
DocumentOperation
.LoadFile("linearize-input.pdf")
.Linearize()
.Save("operation-linearize.pdf");
}
[Test]
public void DecryptTest()
{
GenerateSampleDocument("decrypt-input-not-encrypted.pdf", Colors.Red.Medium, 10);
DocumentOperation
.LoadFile("decrypt-input-not-encrypted.pdf")
.Encrypt(new DocumentOperation.Encryption256Bit()
{
UserPassword = "user_password",
OwnerPassword = "owner_password"
})
.Save("decrypt-input-encrypted.pdf");
DocumentOperation
.LoadFile("decrypt-input-encrypted.pdf", "owner_password")
.Decrypt()
.Save("operation-decrypt.pdf");
}
[Test]
public void RemoveRestrictionsTest()
{
GenerateSampleDocument("remove-restrictions-input-not-encrypted.pdf", Colors.Red.Medium, 10);
DocumentOperation
.LoadFile("remove-restrictions-input-not-encrypted.pdf")
.Encrypt(new DocumentOperation.Encryption256Bit()
{
UserPassword = string.Empty,
OwnerPassword = "owner_password",
AllowPrinting = false,
AllowContentExtraction = false
})
.Save("remove-restrictions-input-encrypted.pdf");
DocumentOperation
.LoadFile("remove-restrictions-input-encrypted.pdf", "owner_password")
.RemoveRestrictions()
.Save("operation-remove-restrictions.pdf");
}
[Test]
public void LoadEncryptedWithIncorrectPasswordTest()
{
GenerateSampleDocument("load-encrypted-input-not-encrypted.pdf", Colors.Red.Medium, 10);
DocumentOperation
.LoadFile("load-encrypted-input-not-encrypted.pdf")
.Encrypt(new DocumentOperation.Encryption256Bit()
{
UserPassword = "user_password",
OwnerPassword = "owner_password"
})
.Save("load-encrypted-input-encrypted.pdf");
Assert.Catch(() =>
{
DocumentOperation
.LoadFile("load-encrypted-input-encrypted.pdf", "wrong_password")
.Save("operation-load-encrypted.pdf");
});
}
[Test]
public void ExtendMetadataTest()
{
GenerateSampleDocument("extend-metadata-input.pdf", Colors.Red.Medium, 10);
// requires PDF/A-3b
DocumentOperation
.LoadFile("extend-metadata-input.pdf")
.ExtendMetadata("")
.Save("operation-extend-metadata.pdf");
}
private void GenerateSampleDocument(string filePath, Color color, int length)
{
Document
.Create(document =>
{
document.Page(page =>
{
page.Size(PageSizes.A4);
page.PageColor(Colors.Transparent);
page.Content().Column(column =>
{
foreach (var i in Enumerable.Range(1, length))
{
if (i != 1)
column.Item().PageBreak();
var width = Random.Shared.Next(100, 200);
var height = Random.Shared.Next(100, 200);
var horizontalTranslation = Random.Shared.Next(0, (int)PageSizes.A4.Width - width);
var verticalTranslation = Random.Shared.Next(0, (int)PageSizes.A4.Height - height);
column.Item()
.TranslateX(horizontalTranslation)
.TranslateY(verticalTranslation)
.Width(width)
.Height(height)
.Background(color.WithAlpha(64))
.AlignCenter()
.AlignMiddle()
.Text($"{filePath}\npage {i}")
.FontColor(color)
.Bold()
.FontSize(16);
}
});
});
})
.WithSettings(new DocumentSettings { PdfA = true })
.GeneratePdf(filePath);
}
}