use edifact_mapper::{DataDir, IssueKind, Mapper, PidValidationError, ValidationLevel};
use serde_json::Value;
use std::path::PathBuf;
type Dynamic = mig_bo4e::model::Interchange<Value, Value>;
fn repo_root() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..")
}
fn bo4e_too_long(mapper: &Mapper, edi: &str, fv: &str) -> Vec<String> {
let ic: Dynamic = mapper
.from_edifact(edi, fv, "UTILMD_Strom", "55043")
.unwrap();
let mut out = Vec::new();
for tx in &ic.nachrichten[0].transaktionen {
let mut s = tx["stammdaten"].clone();
mig_bo4e::model::restore_entity(
&mut s,
mig_bo4e::model::TX_METADATA_ENTITY,
tx.get("transaktionsdaten").unwrap_or(&Value::Null),
);
for e in mapper
.validate_pid(&s, fv, "UTILMD_Strom", "55043")
.unwrap()
{
if let PidValidationError::TooLong { field, length, .. } = e {
out.push(format!("{field} {length}"));
}
}
}
out
}
fn edifact_too_long(mapper: &Mapper, edi: &str, fv: &str) -> Vec<String> {
mapper
.validate_edifact_for_pid(edi, fv, "UTILMD_Strom", "55043", ValidationLevel::Full)
.unwrap()
.issues
.iter()
.filter_map(|i| match &i.kind {
IssueKind::ValueTooLong { length, max, .. } => Some(format!(
"{} {length}>{max}",
i.actual_value.clone().unwrap_or_default()
)),
_ => None,
})
.collect()
}
#[test]
fn a_zaehlzeit_code_longer_than_three_characters_is_too_long_in_every_fv() {
let root = repo_root();
let Ok(mapper) = Mapper::from_data_dir(DataDir::path(root.join("dist"))) else {
eprintln!("skipping: no bundles");
return;
};
for fv in ["FV2504", "FV2510", "FV2604", "FV2610"] {
let path = root.join(format!(
"fixtures/generated/{}/utilmd/55043.edi",
fv.to_lowercase()
));
let edi = std::fs::read_to_string(&path).unwrap();
assert_eq!(
edifact_too_long(&mapper, &edi, fv),
Vec::<String>::new(),
"{fv}"
);
assert_eq!(
bo4e_too_long(&mapper, &edi, fv),
Vec::<String>::new(),
"{fv}"
);
let start = edi.find("CCI+Z39++").expect("a Zählzeit CCI") + "CCI+Z39++".len();
let end = start + edi[start..].find('\'').unwrap();
let long = format!("{}ZDNBNAPG56ZM{}", &edi[..start], &edi[end..]);
assert_eq!(
edifact_too_long(&mapper, &long, fv),
vec!["ZDNBNAPG56ZM 12>3".to_string()],
"{fv}"
);
assert_eq!(
bo4e_too_long(&mapper, &long, fv).len(),
1,
"{fv}: validate_pid must report the 12-character code"
);
}
}