//! Section form protection (`w:formProt` in `w:sectPr`, ECMA-376 Part 1 ยง17.6.6). Fixtures are //! hand-written from the spec. use std::io::{Read, Write}; fn docx(body: &str) -> Vec { let root = r#""#; let doc = format!( r#"{body}"# ); let mut zw = zip::ZipWriter::new(std::io::Cursor::new(Vec::new())); for (name, bytes) in [("_rels/.rels", root.as_bytes()), ("word/document.xml", doc.as_bytes())] { zw.start_file(name, zip::write::SimpleFileOptions::default()).unwrap(); zw.write_all(bytes).unwrap(); } zw.finish().unwrap().into_inner() } fn document_xml(bytes: &[u8]) -> String { let mut z = zip::ZipArchive::new(std::io::Cursor::new(bytes)).unwrap(); let mut s = String::new(); z.by_name("word/document.xml").unwrap().read_to_string(&mut s).unwrap(); s } #[test] fn form_protection_round_trips_in_schema_order() { // Three sections: protected, explicitly unprotected, and one that says nothing. let body = concat!( r#"A"#, r#"B"#, r#"C"# ); let d = craft_docx::read(&docx(body)).unwrap(); let flags: Vec> = d.sections().iter().map(|(_, s)| s.form_prot).collect(); assert_eq!(flags, vec![Some(true), Some(false), None]); let out = craft_docx::write(&d).unwrap(); let xml = document_xml(&out); // Before w:titlePg in CT_SectPr's sequence; a section that never said it writes none. assert!(xml.contains(r#""#), "{xml}"); assert!(xml.contains(r#""#), "{xml}"); assert_eq!(xml.matches("w:formProt").count(), 2); let again: Vec> = craft_docx::read(&out).unwrap().sections().iter().map(|(_, s)| s.form_prot).collect(); assert_eq!(again, flags); }