#![allow(
clippy::indexing_slicing,
clippy::panic,
clippy::unwrap_used,
reason = "test code with known-structure parsed data"
)]
use crate::{json, schema, tariff, test, warning, Version, Warning as _};
use super::{apply, edits, Edit, Fixable as _};
fn validated(json: &str) -> (tariff::Versioned<'_>, warning::Set<schema::Warning>) {
let doc = json::parse_object(json).unwrap();
tariff::from_json(doc, Version::V221).into_parts()
}
fn only_field(json: &str) -> (json::Document<'_>, json::ElemId) {
let doc = json::parse_object(json).unwrap();
let id = doc.root().find_field("a").unwrap().element().id();
(doc, id)
}
#[test]
fn a_null_field_is_removed() {
let (doc, id) = only_field(r#"{"a": null}"#);
let element = doc.element(id).unwrap();
assert_eq!(
schema::Warning::NullField.fix(element),
Some(Edit::remove(id))
);
}
#[test]
fn an_unexpected_field_is_removed() {
let (doc, id) = only_field(r#"{"a": 1}"#);
let element = doc.element(id).unwrap();
assert_eq!(
schema::Warning::UnexpectedField.fix(element),
Some(Edit::remove(id))
);
}
#[test]
fn a_non_spec_field_is_left_alone() {
let (doc, id) = only_field(r#"{"a": 1}"#);
let element = doc.element(id).unwrap();
assert_eq!(schema::Warning::NonSpecField.fix(element), None);
}
#[test]
fn a_miscased_enum_value_is_rewritten_in_the_spec_case() {
let (doc, id) = only_field(r#"{"a": "energy"}"#);
let element = doc.element(id).unwrap();
let warning = schema::Warning::IncorrectCase {
expected: "ENERGY",
actual: "energy".to_owned(),
};
assert_eq!(
warning.fix(element),
Some(Edit::replace(id, super::Json::string("ENERGY")))
);
}
#[test]
fn a_tariff_has_its_miscased_enum_value_rewritten() {
const TARIFF: &str = r#"{
"country_code": "NL",
"party_id": "TDR",
"id": "TEST",
"currency": "EUR",
"elements": [
{
"price_components": [
{
"type": "energy",
"price": 0.38,
"step_size": 1
}
]
}
],
"last_updated": "2020-01-01T00:00:00Z"
}"#;
test::setup();
let (tariff, warnings) = validated(TARIFF);
let doc = tariff.as_doc();
let proposed = edits(doc, &warnings).unwrap();
let fixed = apply(doc, &proposed).unwrap();
assert_eq!(fixed, TARIFF.replace(r#""energy""#, r#""ENERGY""#));
}
#[test]
fn a_warning_needing_a_human_decision_proposes_nothing() {
let (doc, id) = only_field(r#"{"a": 1}"#);
let element = doc.element(id).unwrap();
let unfixable = [
schema::Warning::MissingField { name: "currency" },
schema::Warning::Cardinality,
];
for warning in unfixable {
assert_eq!(warning.fix(element), None, "for `{warning:?}`");
}
}
#[test]
fn a_tariff_loses_its_null_and_unexpected_fields() {
const TARIFF: &str = r#"{
"country_code": "NL",
"party_id": "TDR",
"id": "TEST",
"currency": "EUR",
"tariff_alt_url": null,
"made_up_field": "nonsense",
"elements": [
{
"price_components": [
{
"type": "ENERGY",
"price": 0.38,
"step_size": 1
}
]
}
],
"last_updated": "2020-01-01T00:00:00Z"
}"#;
test::setup();
let (tariff, warnings) = validated(TARIFF);
let doc = tariff.as_doc();
let proposed = edits(doc, &warnings).unwrap();
let fixed = apply(doc, &proposed).unwrap();
assert!(
!fixed.contains("tariff_alt_url") && !fixed.contains("made_up_field"),
"both fields should be gone, got:\n{fixed}"
);
assert!(fixed.contains("\"currency\": \"EUR\""), "got:\n{fixed}");
assert!(fixed.contains("\"price\": 0.38"), "got:\n{fixed}");
let (_tariff, after) = validated(&fixed);
let remaining: Vec<String> = after
.iter()
.flat_map(|group| group.warnings())
.map(|warning| warning.id().as_str().to_owned())
.collect();
assert_eq!(remaining, Vec::<String>::new());
}
#[test]
fn filtering_the_set_leaves_the_unexpected_field_in_place() {
const TARIFF: &str = r#"{"made_up_field": "nonsense", "currency": null}"#;
test::setup();
let (tariff, mut warnings) = validated(TARIFF);
warnings.remove_unexpected_fields();
let doc = tariff.as_doc();
let proposed = edits(doc, &warnings).unwrap();
let fixed = apply(doc, &proposed).unwrap();
assert_eq!(fixed, r#"{"made_up_field": "nonsense"}"#.to_owned());
}