use mig_bo4e::model::{
DynamicInterchange, Interchange, Interchangedaten, Nachricht, Nachrichtendaten, Transaktion,
};
use mig_bo4e::MappingEngine;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct TestMsg {
marktteilnehmer: Option<Vec<serde_json::Value>>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct TestTxStamm {
marktlokation: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct TestTxDaten {
transaktionsgrund: Option<String>,
}
type TestTx = Transaktion<TestTxDaten, TestTxStamm>;
#[test]
fn test_typed_forward_deserializes_from_dynamic() {
let dynamic = DynamicInterchange {
interchangedaten: Interchangedaten {
absender_code: Some("9900123".into()),
..Default::default()
},
nachrichten: vec![Nachricht {
nachrichtendaten: Nachrichtendaten {
unh_referenz: "00001".into(),
nachrichten_typ: "UTILMD".into(),
nachricht: Default::default(),
},
stammdaten: serde_json::json!({
"marktteilnehmer": [{"rollencodenummer": "9900123"}]
}),
transaktionen: vec![mig_bo4e::Transaktion {
transaktionsdaten: serde_json::json!({"transaktionsgrund": "E01"}),
stammdaten: serde_json::json!({
"marktlokation": {"marktlokationsId": "DE000111"}
}),
}],
}],
};
let value = serde_json::to_value(&dynamic).unwrap();
let typed: Interchange<TestMsg, TestTx> = serde_json::from_value(value).unwrap();
assert_eq!(
typed.interchangedaten.absender_code.as_deref(),
Some("9900123")
);
assert_eq!(typed.nachrichten.len(), 1);
let msg = &typed.nachrichten[0];
assert_eq!(msg.nachrichtendaten.unh_referenz, "00001");
assert_eq!(msg.nachrichtendaten.nachrichten_typ, "UTILMD");
let teilnehmer = msg.stammdaten.marktteilnehmer.as_ref().unwrap();
assert_eq!(teilnehmer.len(), 1);
assert_eq!(
teilnehmer[0]["rollencodenummer"].as_str().unwrap(),
"9900123"
);
assert_eq!(msg.transaktionen.len(), 1);
let tx = &msg.transaktionen[0];
assert!(tx.stammdaten.marktlokation.is_some());
assert_eq!(
tx.transaktionsdaten.transaktionsgrund.as_deref(),
Some("E01")
);
assert_eq!(
tx.stammdaten.marktlokation.as_ref().unwrap()["marktlokationsId"]
.as_str()
.unwrap(),
"DE000111"
);
}
#[test]
fn test_typed_reverse_serializes_to_dynamic() {
let nachricht: Nachricht<TestMsg, TestTx> = Nachricht {
nachrichtendaten: Nachrichtendaten {
unh_referenz: "00002".into(),
nachrichten_typ: "UTILMD".into(),
nachricht: Default::default(),
},
stammdaten: TestMsg {
marktteilnehmer: Some(vec![serde_json::json!({"rollencodenummer": "9900456"})]),
},
transaktionen: vec![TestTx {
transaktionsdaten: TestTxDaten {
transaktionsgrund: Some("E03".into()),
},
stammdaten: TestTxStamm {
marktlokation: Some(serde_json::json!({"marktlokationsId": "DE000222"})),
},
}],
};
let stammdaten_value = serde_json::to_value(&nachricht.stammdaten).unwrap();
assert!(stammdaten_value["marktteilnehmer"].is_array());
let tx_value = serde_json::to_value(&nachricht.transaktionen[0]).unwrap();
assert_eq!(
tx_value["stammdaten"]["marktlokation"]["marktlokationsId"]
.as_str()
.unwrap(),
"DE000222"
);
assert_eq!(
tx_value["transaktionsdaten"]["transaktionsgrund"]
.as_str()
.unwrap(),
"E03"
);
}
#[test]
fn test_typed_interchange_full_roundtrip_via_json() {
let original: Interchange<TestMsg, TestTx> = Interchange {
interchangedaten: Interchangedaten {
absender_code: Some("9900111".into()),
empfaenger_code: Some("9900222".into()),
..Default::default()
},
nachrichten: vec![Nachricht {
nachrichtendaten: Nachrichtendaten {
unh_referenz: "00003".into(),
nachrichten_typ: "UTILMD".into(),
nachricht: Default::default(),
},
stammdaten: TestMsg {
marktteilnehmer: Some(vec![serde_json::json!({"marktrolle": "LF"})]),
},
transaktionen: vec![
TestTx {
transaktionsdaten: TestTxDaten {
transaktionsgrund: Some("E01".into()),
},
stammdaten: TestTxStamm {
marktlokation: Some(serde_json::json!({"marktlokationsId": "DE000AAA"})),
},
},
TestTx {
transaktionsdaten: TestTxDaten {
transaktionsgrund: None,
},
stammdaten: TestTxStamm {
marktlokation: Some(serde_json::json!({"marktlokationsId": "DE000BBB"})),
},
},
],
}],
};
let json = serde_json::to_string(&original).unwrap();
let restored: Interchange<TestMsg, TestTx> = serde_json::from_str(&json).unwrap();
assert_eq!(
restored.interchangedaten.absender_code.as_deref(),
Some("9900111")
);
assert_eq!(restored.nachrichten[0].transaktionen.len(), 2);
assert!(restored.nachrichten[0].transaktionen[1]
.transaktionsdaten
.transaktionsgrund
.is_none());
assert_eq!(
restored.nachrichten[0].transaktionen[0]
.stammdaten
.marktlokation
.as_ref()
.unwrap()["marktlokationsId"]
.as_str()
.unwrap(),
"DE000AAA"
);
}
#[test]
fn test_map_interchange_typed_method_exists() {
use mig_assembly::assembler::AssembledTree;
use std::collections::BTreeMap;
let tree = AssembledTree {
segments: vec![],
groups: vec![],
post_group_start: 0,
inter_group_segments: BTreeMap::new(),
};
let dir = tempfile::tempdir().unwrap();
let msg_engine = MappingEngine::load(dir.path()).unwrap();
let tx_engine = MappingEngine::load(dir.path()).unwrap();
let result = MappingEngine::map_interchange_typed::<TestMsg, TestTx>(
&msg_engine,
&tx_engine,
&tree,
"SG4",
false,
Nachrichtendaten {
unh_referenz: "00001".into(),
nachrichten_typ: "UTILMD".into(),
nachricht: Default::default(),
},
Interchangedaten::default(),
);
let interchange = result.unwrap();
assert_eq!(interchange.nachrichten.len(), 1);
assert!(interchange.nachrichten[0]
.stammdaten
.marktteilnehmer
.is_none());
assert!(interchange.nachrichten[0].transaktionen.is_empty());
}
#[test]
fn test_map_interchange_reverse_typed_method_exists() {
let nachricht: Nachricht<TestMsg, TestTx> = Nachricht {
nachrichtendaten: Nachrichtendaten {
unh_referenz: "00001".into(),
nachrichten_typ: "UTILMD".into(),
nachricht: Default::default(),
},
stammdaten: TestMsg {
marktteilnehmer: Some(vec![serde_json::json!({"rollencodenummer": "9900123"})]),
},
transaktionen: vec![TestTx {
transaktionsdaten: TestTxDaten {
transaktionsgrund: Some("E01".into()),
},
stammdaten: TestTxStamm {
marktlokation: Some(serde_json::json!({"marktlokationsId": "DE000111"})),
},
}],
};
let dir = tempfile::tempdir().unwrap();
let msg_engine = MappingEngine::load(dir.path()).unwrap();
let tx_engine = MappingEngine::load(dir.path()).unwrap();
let tree =
MappingEngine::map_interchange_reverse_typed(&msg_engine, &tx_engine, &nachricht, "SG4")
.unwrap();
assert!(tree.segments.is_empty());
let sg4 = tree.groups.iter().find(|g| g.group_id == "SG4");
assert!(sg4.is_some(), "Expected SG4 group from the one transaction");
assert_eq!(sg4.unwrap().repetitions.len(), 1);
}