ocpi-tariffs 0.52.0

OCPI tariff calculations
Documentation
use crate::{cdr, json, test, Version, Versioned as _};

/// Read a CDR that sets every `v2.2.1` field against the `v2.1.1` schema, and assert everything
/// the walk reports about the version difference.
///
/// The walk records an unexpected or wrongly typed field but does not descend into it, so a
/// `v2.2.1`-only field is reported once, at the shallowest point `v2.1.1` still understands:
/// `$.cdr_location` and `$.cdr_token` appear but their children do not.
#[test]
fn should_parse_v221_cdr_as_v211_with_warnings() {
    const JSON: &str = include_str!("../../test_data/v221/every_field_set/cdr.json");

    test::setup();

    let (cdr, warnings) =
        cdr::from_json(json::parse_object(JSON).unwrap(), Version::V211).into_parts();

    assert_eq!(
        cdr.version(),
        Version::V211,
        "The v221 CDR was forced to be parsed as v211"
    );

    test::assert_schema_warnings(
        &warnings,
        &[
            // `v2.2.1` renamed three required CDR fields, so each is reported from both sides:
            // the new name is unexpected here and the old one is missing.
            ("$.cdr_token", &["unexpected_field"]),
            ("$.cdr_location", &["unexpected_field"]),
            ("$.end_date_time", &["unexpected_field"]),
            (
                "$",
                &[
                    "missing_field(auth_id)",
                    "missing_field(location)",
                    "missing_field(stop_date_time)",
                ],
            ),
            // `total_cost` is a number in `v2.1.1` and a `Price` object in `v2.2.1`, so it is a
            // type mismatch rather than an unexpected field.
            ("$.total_cost", &["invalid_type(object)"]),
            // Fields `v2.2.1` added to the CDR, which `v2.1.1` does not define.
            ("$.country_code", &["unexpected_field"]),
            ("$.party_id", &["unexpected_field"]),
            ("$.session_id", &["unexpected_field"]),
            ("$.total_energy_cost", &["unexpected_field"]),
            ("$.total_time_cost", &["unexpected_field"]),
            ("$.charging_periods[0].tariff_id", &["unexpected_field"]),
            ("$.charging_periods[1].tariff_id", &["unexpected_field"]),
            // The same additions on the tariffs embedded in the CDR; see the tariff's own
            // `test_every_field_set` for the tariff read on its own.
            ("$.tariffs[0].country_code", &["unexpected_field"]),
            ("$.tariffs[0].party_id", &["unexpected_field"]),
            ("$.tariffs[0].type", &["unexpected_field"]),
            ("$.tariffs[0].end_date_time", &["unexpected_field"]),
            ("$.tariffs[0].max_price", &["unexpected_field"]),
            ("$.tariffs[0].min_price", &["unexpected_field"]),
            (
                "$.tariffs[0].elements[0].price_components[0].vat",
                &["unexpected_field"],
            ),
            (
                "$.tariffs[0].elements[1].price_components[0].vat",
                &["unexpected_field"],
            ),
            (
                "$.tariffs[0].elements[2].price_components[0].vat",
                &["unexpected_field"],
            ),
            (
                "$.tariffs[0].elements[0].restrictions.max_current",
                &["unexpected_field"],
            ),
            (
                "$.tariffs[0].elements[0].restrictions.min_current",
                &["unexpected_field"],
            ),
            (
                "$.tariffs[0].elements[0].restrictions.reservation",
                &["unexpected_field"],
            ),
            // `EnvironmentalImpact` names its required category field `source` in `v2.1.1` and
            // `category` in `v2.2.1`, so each entry reports the rename from both sides.
            (
                "$.tariffs[0].energy_mix.environ_impact[0].category",
                &["unexpected_field"],
            ),
            (
                "$.tariffs[0].energy_mix.environ_impact[1].category",
                &["unexpected_field"],
            ),
            (
                "$.tariffs[0].energy_mix.environ_impact[0]",
                &["missing_field(source)"],
            ),
            (
                "$.tariffs[0].energy_mix.environ_impact[1]",
                &["missing_field(source)"],
            ),
        ],
    );
}