ocpi-tariffs 0.46.0

OCPI tariff calculations
Documentation
#![allow(
    clippy::indexing_slicing,
    reason = "unwraps are allowed anywhere in tests"
)]

use assert_matches::assert_matches;
use rust_decimal::Decimal;
use rust_decimal_macros::dec;

use crate::{
    json::{self, FromJson as _},
    warning::test::VerdictTestExt,
};

use super::{Price, Warning};

#[test]
fn should_create_from_json_with_only_excl_vat_field() {
    const JSON: &str = r#"{
            "excl_vat": 10.2
        }"#;

    let elem = json::parse(JSON.into()).unwrap();
    let price = Price::from_json(&elem).unwrap().unwrap();

    assert!(price.incl_vat.is_none());
    assert_eq!(Decimal::from(price.excl_vat), dec!(10.2));
}

#[test]
fn should_create_from_json_with_excl_and_incl_vat_fields() {
    const JSON: &str = r#"{
            "excl_vat": 10.2,
            "incl_vat": 12.3
        }"#;

    let elem = json::parse(JSON.into()).unwrap();
    let price = Price::from_json(&elem).unwrap().unwrap();

    assert_eq!(Decimal::from(price.incl_vat.unwrap()), dec!(12.3));
    assert_eq!(Decimal::from(price.excl_vat), dec!(10.2));
}

#[test]
fn should_fail_to_create_from_non_object_json() {
    const JSON: &str = "12.3";

    let elem = json::parse(JSON.into()).unwrap();
    let error = Price::from_json(&elem).unwrap_only_error();

    assert_matches!(error.into_warning(), Warning::InvalidType { .. });
}

#[test]
fn should_fail_to_create_from_json_as_excl_vat_is_required() {
    const JSON: &str = r#"{
            "incl_vat": 12.3
        }"#;

    let elem = json::parse(JSON.into()).unwrap();
    let error = Price::from_json(&elem).unwrap_only_error();

    assert_matches!(error.into_warning(), Warning::MissingExclVatField);
}

#[test]
fn should_create_from_json_and_warn_about_excl_vat_greater_than_incl_vat() {
    const JSON: &str = r#"{
            "excl_vat": 12.3,
            "incl_vat": 10.2
        }"#;

    let elem = json::parse(JSON.into()).unwrap();
    let (_price, warnings) = Price::from_json(&elem).unwrap().into_parts();
    let warnings = warnings.into_path_as_str_map();
    let warnings = &warnings["$"];

    assert_matches!(
        warnings.as_slice(),
        [Warning::ExclusiveVatGreaterThanInclusive]
    );
}