#![allow(
clippy::indexing_slicing,
clippy::panic,
clippy::unwrap_used,
reason = "test code with known-structure parsed data"
)]
use crate::{json, lint, tariff, test, warning, Version, Warning as _};
use super::{apply, edits, Edit, Fixable as _, Json};
const TARIFF: &str = r#"{
"country_code": "NL",
"party_id": "TDR",
"id": "TEST",
"currency": "EUR",
"elements": [
{
"restrictions": {
"day_of_week": {DAYS}
},
"price_components": [
{
"type": "ENERGY",
"price": 0.38,
"step_size": 1
}
]
}
],
"last_updated": "2020-01-01T00:00:00Z"
}"#;
fn day_of_week(days: &str) -> (json::Document<'_>, json::ElemId) {
let doc = json::parse_object(days).unwrap();
let id = doc.root().find_field("day_of_week").unwrap().element().id();
(doc, id)
}
fn linted(json: &str) -> (tariff::Versioned<'_>, warning::Set<lint::tariff::Warning>) {
let doc = json::parse_object(json).unwrap();
let tariff = tariff::from_json(doc, Version::V221).ignore_warnings();
let report = tariff::lint(&tariff);
(tariff, report.warnings)
}
fn lint_warning_ids(json: &str) -> Vec<String> {
let (_tariff, warnings) = linted(json);
warnings
.iter()
.flat_map(|group| group.warnings())
.map(|warning| warning.id().as_str().to_owned())
.collect()
}
#[test]
fn a_list_of_every_day_is_removed() {
let days = r#"{"day_of_week": ["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"]}"#;
let (doc, id) = day_of_week(days);
let element = doc.element(id).unwrap();
assert_eq!(
lint::tariff::Warning::ContainsEntireWeek.fix(element),
Some(Edit::remove(id))
);
}
#[test]
fn an_unsorted_list_is_put_in_spec_order() {
let (doc, id) = day_of_week(r#"{"day_of_week": ["FRIDAY", "MONDAY"]}"#);
let element = doc.element(id).unwrap();
assert_eq!(
lint::tariff::Warning::DayOfWeekUnsorted.fix(element),
Some(Edit::replace(id, Json::string_array(&["MONDAY", "FRIDAY"])))
);
}
#[test]
fn a_repeating_list_keeps_one_of_each_day() {
let (doc, id) = day_of_week(r#"{"day_of_week": ["MONDAY", "MONDAY", "TUESDAY"]}"#);
let element = doc.element(id).unwrap();
assert_eq!(
lint::tariff::Warning::DayOfWeekDuplicates.fix(element),
Some(Edit::replace(
id,
Json::string_array(&["MONDAY", "TUESDAY"])
))
);
}
#[test]
fn an_unsorted_repeating_list_gets_the_same_text_from_either_warning() {
let (doc, id) = day_of_week(r#"{"day_of_week": ["FRIDAY", "MONDAY", "MONDAY"]}"#);
let element = doc.element(id).unwrap();
assert_eq!(
lint::tariff::Warning::DayOfWeekUnsorted.fix(element),
lint::tariff::Warning::DayOfWeekDuplicates.fix(element)
);
}
#[test]
fn an_empty_list_is_left_alone() {
let (doc, id) = day_of_week(r#"{"day_of_week": []}"#);
let element = doc.element(id).unwrap();
assert_eq!(lint::tariff::Warning::DayOfWeekEmpty.fix(element), None);
}
#[test]
fn a_list_naming_days_in_lower_case_is_left_alone_by_the_sort() {
let (doc, id) = day_of_week(r#"{"day_of_week": ["friday", "monday"]}"#);
let element = doc.element(id).unwrap();
assert_eq!(lint::tariff::Warning::DayOfWeekUnsorted.fix(element), None);
}
#[test]
fn a_list_holding_something_other_than_a_day_is_left_alone() {
let (doc, id) = day_of_week(r#"{"day_of_week": ["FRIDAY", 3]}"#);
let element = doc.element(id).unwrap();
assert_eq!(lint::tariff::Warning::DayOfWeekUnsorted.fix(element), None);
}
#[test]
fn a_warning_needing_a_human_decision_proposes_nothing() {
let (doc, id) = day_of_week(r#"{"day_of_week": ["FRIDAY", "MONDAY"]}"#);
let element = doc.element(id).unwrap();
let unfixable = [
lint::tariff::Warning::ContainsEntireDay,
lint::tariff::Warning::CpoCountryCodeShouldBeAlpha2,
lint::tariff::Warning::EndTimeIsNearEndOfDay,
lint::tariff::Warning::MaxZeroNeverMatch,
lint::tariff::Warning::MinPriceIsGreaterThanMax,
lint::tariff::Warning::NeverValid,
lint::tariff::Warning::StartDateTimeIsAfterEndDateTime,
];
for warning in unfixable {
assert_eq!(warning.fix(element), None, "for `{warning:?}`");
}
}
#[test]
fn a_tariff_has_its_day_of_week_list_normalized() {
test::setup();
let source = TARIFF.replace("{DAYS}", r#"["FRIDAY", "MONDAY", "MONDAY"]"#);
let (tariff, warnings) = linted(&source);
let doc = tariff.as_doc();
let proposed = edits(doc, &warnings).unwrap();
let fixed = apply(doc, &proposed).unwrap();
assert_eq!(fixed, TARIFF.replace("{DAYS}", r#"["MONDAY", "FRIDAY"]"#));
assert_eq!(lint_warning_ids(&fixed), Vec::<String>::new());
}
#[test]
fn a_tariff_loses_a_day_of_week_list_naming_every_day() {
test::setup();
let days = r#"["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"]"#;
let source = TARIFF.replace("{DAYS}", days);
let (tariff, warnings) = linted(&source);
let doc = tariff.as_doc();
let proposed = edits(doc, &warnings).unwrap();
let fixed = apply(doc, &proposed).unwrap();
assert!(!fixed.contains("day_of_week"), "got:\n{fixed}");
assert_eq!(
lint_warning_ids(&fixed),
vec!["restrictions_empty".to_owned()]
);
}
#[test]
fn removing_a_list_beats_sorting_it() {
test::setup();
let days = r#"["SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"]"#;
let source = TARIFF.replace("{DAYS}", days);
let (tariff, warnings) = linted(&source);
let doc = tariff.as_doc();
let proposed = edits(doc, &warnings).unwrap();
let fixed = apply(doc, &proposed).unwrap();
assert!(!fixed.contains("day_of_week"), "got:\n{fixed}");
assert_eq!(
lint_warning_ids(&fixed),
vec!["restrictions_empty".to_owned()]
);
}