use std::path::PathBuf; use std::process::Command as ProcessCommand; use serde_json::json; use sgclaw::compat::openxml_office_tool::OpenXmlOfficeTool; use uuid::Uuid; use zeroclaw::tools::Tool; fn temp_workspace_root() -> PathBuf { let root = std::env::temp_dir().join(format!("sgclaw-openxml-office-{}", Uuid::new_v4())); std::fs::create_dir_all(&root).unwrap(); root } #[tokio::test] async fn openxml_office_tool_renders_hotlist_xlsx_from_rows() { let workspace_root = temp_workspace_root(); let output_path = workspace_root.join("out/zhihu-hotlist.xlsx"); let tool = OpenXmlOfficeTool::new(workspace_root.clone()); let result = tool .execute(json!({ "sheet_name": "知乎热榜", "columns": ["rank", "title", "heat"], "rows": [ [1, "问题一", "344万"], [2, "问题二", "266万"] ], "output_path": output_path })) .await .unwrap(); assert!(result.success, "{result:?}"); assert!(output_path.exists()); assert!(result.output.contains(output_path.to_str().unwrap())); let unzip = ProcessCommand::new("unzip") .args([ "-p", output_path.to_str().unwrap(), "xl/worksheets/sheet1.xml", ]) .output() .unwrap(); assert!(unzip.status.success()); let xml = String::from_utf8(unzip.stdout).unwrap(); assert!(xml.contains("问题一")); assert!(xml.contains("344万")); assert!(xml.contains("问题二")); assert!(!xml.contains("{{TITLE_1}}")); } #[tokio::test] async fn openxml_office_tool_accepts_reordered_columns_when_rows_are_structured() { let workspace_root = temp_workspace_root(); let output_path = workspace_root.join("out/zhihu-hotlist-reordered.xlsx"); let tool = OpenXmlOfficeTool::new(workspace_root.clone()); let result = tool .execute(json!({ "sheet_name": "知乎热榜", "columns": ["title", "heat", "rank"], "rows": [ ["问题一", "344万", 1], ["问题二", "266万", 2] ], "output_path": output_path })) .await .unwrap(); assert!(result.success, "{result:?}"); assert!(output_path.exists()); let unzip = ProcessCommand::new("unzip") .args([ "-p", output_path.to_str().unwrap(), "xl/worksheets/sheet1.xml", ]) .output() .unwrap(); assert!(unzip.status.success()); let xml = String::from_utf8(unzip.stdout).unwrap(); assert!(xml.contains("问题一")); assert!(xml.contains("344万")); assert!(xml.contains(">1<")); } #[tokio::test] async fn openxml_office_tool_accepts_localized_hotlist_column_aliases() { let workspace_root = temp_workspace_root(); let output_path = workspace_root.join("out/zhihu-hotlist-localized.xlsx"); let tool = OpenXmlOfficeTool::new(workspace_root.clone()); let result = tool .execute(json!({ "sheet_name": "知乎热榜", "columns": ["排名", "标题", "热度"], "rows": [ [1, "问题一", "344万"], [2, "问题二", "266万"] ], "output_path": output_path })) .await .unwrap(); assert!(result.success, "{result:?}"); assert!(output_path.exists()); let unzip = ProcessCommand::new("unzip") .args([ "-p", output_path.to_str().unwrap(), "xl/worksheets/sheet1.xml", ]) .output() .unwrap(); assert!(unzip.status.success()); let xml = String::from_utf8(unzip.stdout).unwrap(); assert!(xml.contains("问题一")); assert!(xml.contains("344万")); assert!(xml.contains(">1<")); }