Files
claw/tests/report_artifact_postprocess_test.rs

121 lines
3.9 KiB
Rust

use std::fs;
use std::path::{Path, PathBuf};
use serde_json::json;
use sgclaw::compat::report_artifact::interpret_report_artifact_and_postprocess;
use sgclaw::scene_contract::PostprocessSection;
use uuid::Uuid;
fn temp_workspace(prefix: &str) -> PathBuf {
let root = std::env::temp_dir().join(format!("{prefix}-{}", Uuid::new_v4()));
fs::create_dir_all(&root).unwrap();
root
}
fn report_postprocess_xlsx() -> PostprocessSection {
PostprocessSection {
exporter: "xlsx_report".to_string(),
auto_open: None,
}
}
fn exported_xlsx_files(workspace_root: &Path) -> Vec<PathBuf> {
let out_dir = workspace_root.join("out");
if !out_dir.exists() {
return Vec::new();
}
fs::read_dir(out_dir)
.unwrap()
.filter_map(Result::ok)
.map(|entry| entry.path())
.filter(|path| path.extension().and_then(|ext| ext.to_str()) == Some("xlsx"))
.collect()
}
#[test]
fn report_artifact_postprocess_exports_xlsx_for_ok_or_partial_scene() {
let workspace_root = temp_workspace("sgclaw-report-artifact-export");
let artifact = json!({
"type": "report-artifact",
"report_name": "tq-lineloss-report",
"status": "partial",
"columns": ["ORG_NAME", "LINE_LOSS_RATE"],
"column_defs": [["ORG_NAME", "供电单位"], ["LINE_LOSS_RATE", "综合线损率(%)"]],
"rows": [{"ORG_NAME": "国网兰州供电公司", "LINE_LOSS_RATE": "1.23"}],
"counts": {"rows": 1},
"partial_reasons": ["report_log_failed"]
});
let outcome = interpret_report_artifact_and_postprocess(
&artifact,
Some(&report_postprocess_xlsx()),
&workspace_root,
)
.unwrap();
assert!(outcome.success);
assert!(outcome.summary.contains("tq-lineloss-report"));
assert!(outcome.summary.contains("status=partial"));
assert!(outcome.summary.contains("detail_rows=1"));
assert!(outcome
.summary
.contains("partial_reasons=report_log_failed"));
assert!(outcome.summary.contains("export_path="));
assert_eq!(exported_xlsx_files(&workspace_root).len(), 1);
}
#[test]
fn report_artifact_postprocess_skips_export_for_blocked_or_error_scene() {
for status in ["blocked", "error"] {
let workspace_root = temp_workspace(&format!("sgclaw-report-artifact-{status}"));
let artifact = json!({
"type": "report-artifact",
"report_name": "generic-report",
"status": status,
"columns": ["ORG_NAME"],
"rows": [{"ORG_NAME": "国网兰州供电公司"}],
"counts": {"rows": 1},
"reasons": ["login_required"]
});
let outcome = interpret_report_artifact_and_postprocess(
&artifact,
Some(&report_postprocess_xlsx()),
&workspace_root,
)
.unwrap();
assert!(!outcome.success, "{status} should fail");
assert!(outcome.summary.contains(&format!("status={status}")));
assert!(!outcome.summary.contains("export_path="));
assert!(exported_xlsx_files(&workspace_root).is_empty());
}
}
#[test]
fn report_artifact_postprocess_exports_with_columns_when_column_defs_are_absent() {
let workspace_root = temp_workspace("sgclaw-report-artifact-columns-fallback");
let artifact = json!({
"type": "report-artifact",
"report_name": "generic-report",
"status": "ok",
"columns": ["ORG_NAME", "VALUE"],
"rows": [{"ORG_NAME": "国网兰州供电公司", "VALUE": "42"}],
"counts": {"rows": 1}
});
let outcome = interpret_report_artifact_and_postprocess(
&artifact,
Some(&report_postprocess_xlsx()),
&workspace_root,
)
.unwrap();
assert!(outcome.success);
assert!(outcome.summary.contains("generic-report"));
assert!(outcome.summary.contains("detail_rows=1"));
assert!(outcome.summary.contains("export_path="));
assert_eq!(exported_xlsx_files(&workspace_root).len(), 1);
}