use super::test_support::{build_test_docx, build_test_pptx, build_test_xlsx};
use super::*;
#[test]
fn test_e2e_docx_to_pdf() {
let docx_bytes = build_test_docx();
let result = convert_bytes(&docx_bytes, Format::Docx, &ConvertOptions::default()).unwrap();
assert!(
!result.pdf.is_empty(),
"DOCX→PDF should produce non-empty output"
);
assert!(
result.pdf.starts_with(b"%PDF"),
"Output should be valid PDF"
);
assert!(
result.warnings.is_empty(),
"Normal DOCX should produce no warnings"
);
}
#[test]
fn test_e2e_xlsx_to_pdf() {
let xlsx_bytes = build_test_xlsx();
let result = convert_bytes(&xlsx_bytes, Format::Xlsx, &ConvertOptions::default()).unwrap();
assert!(
!result.pdf.is_empty(),
"XLSX→PDF should produce non-empty output"
);
assert!(
result.pdf.starts_with(b"%PDF"),
"Output should be valid PDF"
);
}
#[test]
fn test_e2e_pptx_to_pdf() {
let pptx_bytes = build_test_pptx();
let result = convert_bytes(&pptx_bytes, Format::Pptx, &ConvertOptions::default()).unwrap();
assert!(
!result.pdf.is_empty(),
"PPTX→PDF should produce non-empty output"
);
assert!(
result.pdf.starts_with(b"%PDF"),
"Output should be valid PDF"
);
}
#[test]
fn test_e2e_docx_with_table_to_pdf() {
use std::io::Cursor;
let table = docx_rs::Table::new(vec![docx_rs::TableRow::new(vec![
docx_rs::TableCell::new().add_paragraph(
docx_rs::Paragraph::new().add_run(docx_rs::Run::new().add_text("Cell A")),
),
docx_rs::TableCell::new().add_paragraph(
docx_rs::Paragraph::new().add_run(docx_rs::Run::new().add_text("Cell B")),
),
])]);
let docx = docx_rs::Docx::new()
.add_paragraph(
docx_rs::Paragraph::new().add_run(docx_rs::Run::new().add_text("Table below:")),
)
.add_table(table);
let mut cursor = Cursor::new(Vec::new());
docx.build().pack(&mut cursor).unwrap();
let data = cursor.into_inner();
let result = convert_bytes(&data, Format::Docx, &ConvertOptions::default()).unwrap();
assert!(!result.pdf.is_empty());
assert!(result.pdf.starts_with(b"%PDF"));
}
#[test]
fn test_e2e_convert_with_options_from_temp_file() {
let docx_bytes = build_test_docx();
let dir = std::env::temp_dir();
let input = dir.join("office2pdf_test_input.docx");
let output = dir.join("office2pdf_test_output.pdf");
std::fs::write(&input, &docx_bytes).unwrap();
let result = convert(&input).unwrap();
assert!(!result.pdf.is_empty());
assert!(result.pdf.starts_with(b"%PDF"));
let result2 = convert_with_options(&input, &ConvertOptions::default()).unwrap();
assert!(!result2.pdf.is_empty());
assert!(result2.pdf.starts_with(b"%PDF"));
std::fs::write(&output, &result.pdf).unwrap();
assert!(output.exists());
let written = std::fs::read(&output).unwrap();
assert!(written.starts_with(b"%PDF"));
let _ = std::fs::remove_file(&input);
let _ = std::fs::remove_file(&output);
}
#[test]
fn test_e2e_unsupported_format_error_message() {
let result = convert("document.odt");
let err = result.unwrap_err();
match err {
ConvertError::UnsupportedFormat(ref ext) => {
assert_eq!(ext, "odt", "Error should mention the unsupported extension");
}
_ => panic!("Expected UnsupportedFormat error, got {err:?}"),
}
}
#[test]
fn test_e2e_missing_file_error() {
let result = convert("nonexistent_document.docx");
assert!(
matches!(result.unwrap_err(), ConvertError::Io(_)),
"Missing file should produce IO error"
);
}
#[test]
fn test_e2e_docx_with_list_produces_pdf() {
use std::io::Cursor;
let abstract_num = docx_rs::AbstractNumbering::new(0).add_level(docx_rs::Level::new(
0,
docx_rs::Start::new(1),
docx_rs::NumberFormat::new("bullet"),
docx_rs::LevelText::new("•"),
docx_rs::LevelJc::new("left"),
));
let numbering = docx_rs::Numbering::new(1, 0);
let nums = docx_rs::Numberings::new()
.add_abstract_numbering(abstract_num)
.add_numbering(numbering);
let docx = docx_rs::Docx::new()
.numberings(nums)
.add_paragraph(
docx_rs::Paragraph::new()
.add_run(docx_rs::Run::new().add_text("Bullet 1"))
.numbering(docx_rs::NumberingId::new(1), docx_rs::IndentLevel::new(0)),
)
.add_paragraph(
docx_rs::Paragraph::new()
.add_run(docx_rs::Run::new().add_text("Bullet 2"))
.numbering(docx_rs::NumberingId::new(1), docx_rs::IndentLevel::new(0)),
)
.add_paragraph(
docx_rs::Paragraph::new().add_run(docx_rs::Run::new().add_text("Regular text")),
);
let mut cursor = Cursor::new(Vec::new());
docx.build().pack(&mut cursor).unwrap();
let data = cursor.into_inner();
let result = convert_bytes(&data, Format::Docx, &ConvertOptions::default()).unwrap();
assert!(
result.pdf.starts_with(b"%PDF"),
"Should produce valid PDF with list content"
);
}
#[test]
fn test_normal_docx_has_no_warnings() {
let docx_bytes = build_test_docx();
let result = convert_bytes(&docx_bytes, Format::Docx, &ConvertOptions::default()).unwrap();
assert!(
result.warnings.is_empty(),
"Normal DOCX should produce no warnings"
);
}
#[test]
fn test_e2e_docx_with_header_footer_to_pdf() {
use std::io::Cursor;
let header = docx_rs::Header::new().add_paragraph(
docx_rs::Paragraph::new().add_run(docx_rs::Run::new().add_text("Document Title")),
);
let footer = docx_rs::Footer::new().add_paragraph(
docx_rs::Paragraph::new().add_run(
docx_rs::Run::new()
.add_text("Page ")
.add_field_char(docx_rs::FieldCharType::Begin, false)
.add_instr_text(docx_rs::InstrText::PAGE(docx_rs::InstrPAGE::new()))
.add_field_char(docx_rs::FieldCharType::Separate, false)
.add_text("1")
.add_field_char(docx_rs::FieldCharType::End, false),
),
);
let docx = docx_rs::Docx::new()
.header(header)
.footer(footer)
.add_paragraph(
docx_rs::Paragraph::new().add_run(docx_rs::Run::new().add_text("Body paragraph")),
);
let mut cursor = Cursor::new(Vec::new());
docx.build().pack(&mut cursor).unwrap();
let data = cursor.into_inner();
let result = convert_bytes(&data, Format::Docx, &ConvertOptions::default()).unwrap();
assert!(
result.pdf.starts_with(b"%PDF"),
"DOCX with header/footer should produce valid PDF"
);
}
#[test]
fn test_e2e_landscape_docx_to_pdf() {
use std::io::Cursor;
let docx = docx_rs::Docx::new()
.page_size(16838, 11906)
.page_orient(docx_rs::PageOrientationType::Landscape)
.page_margin(
docx_rs::PageMargin::new()
.top(1440)
.bottom(1440)
.left(1440)
.right(1440),
)
.add_paragraph(
docx_rs::Paragraph::new().add_run(docx_rs::Run::new().add_text("Landscape document")),
);
let mut cursor = Cursor::new(Vec::new());
docx.build().pack(&mut cursor).unwrap();
let data = cursor.into_inner();
let result = convert_bytes(&data, Format::Docx, &ConvertOptions::default()).unwrap();
assert!(
result.pdf.starts_with(b"%PDF"),
"Landscape DOCX should produce valid PDF"
);
}
#[test]
fn test_docx_toc_pipeline_produces_pdf() {
use std::io::Cursor;
let toc = docx_rs::TableOfContents::new()
.heading_styles_range(1, 3)
.alias("Table of contents")
.add_item(
docx_rs::TableOfContentsItem::new()
.text("Chapter 1")
.toc_key("_Toc00000001")
.level(1)
.page_ref("2"),
)
.add_item(
docx_rs::TableOfContentsItem::new()
.text("Chapter 2")
.toc_key("_Toc00000002")
.level(1)
.page_ref("5"),
);
let docx = docx_rs::Docx::new()
.add_style(docx_rs::Style::new("Heading1", docx_rs::StyleType::Paragraph).name("Heading 1"))
.add_table_of_contents(toc)
.add_paragraph(
docx_rs::Paragraph::new()
.add_run(docx_rs::Run::new().add_text("Chapter 1"))
.style("Heading1"),
)
.add_paragraph(
docx_rs::Paragraph::new().add_run(docx_rs::Run::new().add_text("Some body text")),
);
let mut cursor = Cursor::new(Vec::new());
docx.build().pack(&mut cursor).unwrap();
let data = cursor.into_inner();
let result = convert_bytes(&data, Format::Docx, &ConvertOptions::default()).unwrap();
assert!(
result.pdf.starts_with(b"%PDF"),
"DOCX with TOC should produce valid PDF"
);
}