use std::path::PathBuf;
use pdfluent::prelude::*;
use pdfluent::redact::RedactOptions;
fn mini(name: &str) -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../../tests/corpus-mini")
.join(name)
}
fn open(name: &str) -> Option<PdfDocument> {
std::fs::read(mini(name))
.ok()
.and_then(|b| PdfDocument::from_bytes(&b).ok())
}
#[test]
fn qr15_signature_read_and_verify_is_typed_no_panic() {
if let Some(doc) = open("signed-rsa.pdf") {
let sigs = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| doc.signatures()))
.expect("signatures() must not panic");
let _ = sigs; let rep =
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| doc.verify_signatures()))
.expect("verify_signatures() must not panic");
let _ = rep;
}
if let Some(doc) = open("simple.pdf") {
if let Ok(list) = doc.signatures() {
assert!(list.is_empty(), "unsigned doc must not report signatures");
}
}
}
#[test]
fn qr15_redaction_removes_content() {
let Some(doc) = open("multi-page.pdf") else {
return;
};
let Ok(text) = doc.extract_text() else { return };
let Some(token) = text
.split(|c: char| !c.is_ascii_alphabetic())
.find(|w| w.len() >= 4)
.map(str::to_string)
else {
return;
};
let mut doc = open("multi-page.pdf").unwrap();
if doc.redact(&token, RedactOptions::new()).is_err() {
return;
}
let out = doc.to_bytes().expect("persist redacted");
let reopened = PdfDocument::from_bytes(&out).expect("reopen");
let after = reopened.extract_text().unwrap_or_default().to_lowercase();
assert!(
!after.contains(&token.to_lowercase()),
"redacted token '{token}' must not be extractable after redaction"
);
}
#[test]
fn qr15_attachment_extraction_size_matches_bytes() {
let Some(doc) = open("zugferd.pdf") else {
return;
};
let Ok(list) = doc.attachments() else { return };
for att in list {
if let Ok(Some(bytes)) = doc.attachment_bytes(&att.name) {
assert_eq!(
bytes.len(),
att.size,
"attachment '{}' reported size must equal extracted byte length",
att.name
);
}
}
}