use serde_json;
use std::fs;
use std::path::Path;
fn load_fixture(filename: &str) -> serde_json::Value {
let path = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures")
.join(filename);
let content =
fs::read_to_string(path).expect(&format!("Failed to read fixture file: {}", filename));
serde_json::from_str(&content).expect(&format!("Failed to parse JSON from fixture: {}", filename))
}
#[test]
fn test_flight_v1_11_0_full_example() {
let json = load_fixture("flight_v1_11_0.json");
let receipt: versa::schema::v1_11_0::receipt::Receipt =
serde_json::from_value(json.clone()).expect("Failed to deserialize v1.11.0 flight receipt");
assert_eq!(&*receipt.schema_version, "1.11.0");
assert_eq!(receipt.header.total, 140220);
assert_eq!(
receipt.header.currency,
versa::schema::v1_11_0::receipt::Currency::Usd
);
assert_eq!(
receipt.header.invoice_number.as_ref().map(|s| s.as_str()),
Some("1MzFN1K8F4fqH0lBmFq8CjbU")
);
assert!(receipt.itemization.flight.is_some());
let flight = receipt.itemization.flight.as_ref().unwrap();
assert_eq!(flight.tickets.len(), 2);
let ticket1 = &flight.tickets[0];
assert_eq!(
ticket1.passenger.as_ref().map(|s| s.as_str()),
Some("Susy Smith")
);
assert_eq!(
ticket1.number.as_ref().map(|s| s.as_str()),
Some("0062698215636")
);
assert_eq!(
ticket1.record_locator.as_ref().map(|s| s.as_str()),
Some("CU9GEF")
);
assert_eq!(ticket1.segments.len(), 4);
let segment1 = &ticket1.segments[0];
assert_eq!(&segment1.departure_airport_code, "SEA");
assert_eq!(&segment1.arrival_airport_code, "MSP");
assert_eq!(segment1.flight_number.as_deref(), Some("DL1768"));
assert_eq!(segment1.seat.as_deref(), Some("15F"));
assert_eq!(segment1.fare, Some(15233));
assert_eq!(segment1.taxes.len(), 4);
assert_eq!(&segment1.taxes[0].name, "US Transportation Tax");
assert_eq!(segment1.taxes[0].amount, 1142);
assert_eq!(ticket1.metadata.len(), 1);
assert_eq!(ticket1.metadata[0].key, "AAdvantage #");
assert_eq!(ticket1.metadata[0].value, "TH4700");
let ticket2 = &flight.tickets[1];
assert_eq!(
ticket2.passenger.as_ref().map(|s| s.as_str()),
Some("John Smith")
);
assert_eq!(ticket2.metadata[0].value, "TH4703");
assert_eq!(receipt.payments.len(), 1);
let payment = &receipt.payments[0];
assert_eq!(payment.amount, 140220);
assert_eq!(
payment.payment_type,
Some(versa::schema::v1_11_0::receipt::PaymentPaymentType::Card)
);
assert!(payment.card_payment.is_some());
let card = payment.card_payment.as_ref().unwrap();
assert_eq!(&card.last_four, "4886");
assert_eq!(
card.network,
Some(versa::schema::v1_11_0::receipt::CardPaymentNetwork::Mastercard)
);
let serialized = serde_json::to_value(&receipt).unwrap();
let deserialized: versa::schema::v1_11_0::receipt::Receipt =
serde_json::from_value(serialized).unwrap();
assert_eq!(deserialized.header.total, receipt.header.total);
}
#[test]
fn test_flight_v2_0_0_full_example() {
let json = load_fixture("flight_v2_0_0.json");
let receipt: versa::schema::v2_0_0::receipt::Receipt =
serde_json::from_value(json.clone()).expect("Failed to deserialize v2.0.0 flight receipt");
assert_eq!(&*receipt.schema_version, "2.0.0");
assert_eq!(receipt.header.total, 140220);
assert_eq!(
receipt.header.currency,
versa::schema::v2_0_0::receipt::Currency::Usd
);
assert!(receipt.header.customer.is_some());
let customer = receipt.header.customer.as_ref().unwrap();
assert_eq!(
customer.website.as_ref().map(|s| s.as_str()),
Some("example.com")
);
assert!(receipt.itemization.flight.is_some());
let flight = receipt.itemization.flight.as_ref().unwrap();
assert_eq!(flight.tickets.len(), 2);
let ticket1 = &flight.tickets[0];
assert!(ticket1.passenger.is_some());
let passenger1 = ticket1.passenger.as_ref().unwrap();
assert_eq!(
passenger1.first_name.as_ref().map(|s| s.as_str()),
Some("Susy")
);
assert_eq!(
passenger1.last_name.as_ref().map(|s| s.as_str()),
Some("Smith")
);
assert_eq!(
passenger1.email.as_ref().map(|s| s.as_str()),
Some("susy.smith@example.com")
);
assert_eq!(passenger1.preferred_first_name, None);
assert_eq!(passenger1.phone, None);
assert_eq!(passenger1.metadata.as_ref().unwrap().len(), 1);
assert_eq!(passenger1.metadata.as_ref().unwrap()[0].key, "AAdvantage #");
assert_eq!(passenger1.metadata.as_ref().unwrap()[0].value, "TH4700");
let ticket2 = &flight.tickets[1];
assert!(ticket2.passenger.is_some());
let passenger2 = ticket2.passenger.as_ref().unwrap();
assert_eq!(
passenger2.first_name.as_ref().map(|s| s.as_str()),
Some("John")
);
assert_eq!(
passenger2.last_name.as_ref().map(|s| s.as_str()),
Some("Smith")
);
assert_eq!(
passenger2.email.as_ref().map(|s| s.as_str()),
Some("john.smith@example.com")
);
assert_eq!(passenger2.metadata.as_ref().unwrap()[0].value, "TH4703");
assert_eq!(ticket1.segments.len(), 4);
let segment1 = &ticket1.segments[0];
assert_eq!(&segment1.departure_airport_code.to_string(), "SEA");
assert_eq!(&segment1.arrival_airport_code.to_string(), "MSP");
let serialized = serde_json::to_value(&receipt).unwrap();
let deserialized: versa::schema::v2_0_0::receipt::Receipt =
serde_json::from_value(serialized).unwrap();
assert_eq!(deserialized.header.total, receipt.header.total);
}
#[test]
fn test_passenger_field_comparison() {
let v1_json = load_fixture("flight_v1_11_0.json");
let v2_json = load_fixture("flight_v2_0_0.json");
let v1_passenger1 = &v1_json["itemization"]["flight"]["tickets"][0]["passenger"];
let v1_passenger2 = &v1_json["itemization"]["flight"]["tickets"][1]["passenger"];
assert_eq!(v1_passenger1.as_str().unwrap(), "Susy Smith");
assert_eq!(v1_passenger2.as_str().unwrap(), "John Smith");
let v2_passenger1 = &v2_json["itemization"]["flight"]["tickets"][0]["passenger"];
let v2_passenger2 = &v2_json["itemization"]["flight"]["tickets"][1]["passenger"];
assert!(v2_passenger1.is_object());
assert_eq!(v2_passenger1["first_name"].as_str().unwrap(), "Susy");
assert_eq!(v2_passenger1["last_name"].as_str().unwrap(), "Smith");
assert_eq!(
v2_passenger1["email"].as_str().unwrap(),
"susy.smith@example.com"
);
assert!(v2_passenger2.is_object());
assert_eq!(v2_passenger2["first_name"].as_str().unwrap(), "John");
assert_eq!(v2_passenger2["last_name"].as_str().unwrap(), "Smith");
assert_eq!(
v2_passenger2["email"].as_str().unwrap(),
"john.smith@example.com"
);
let v1_metadata1 = &v1_json["itemization"]["flight"]["tickets"][0]["metadata"];
let v2_metadata1 = &v2_json["itemization"]["flight"]["tickets"][0]["passenger"]["metadata"];
assert_eq!(v1_metadata1[0]["key"].as_str().unwrap(), "AAdvantage #");
assert_eq!(v2_metadata1[0]["key"].as_str().unwrap(), "AAdvantage #");
}
#[test]
fn test_schema_compatibility() {
let v1_json = load_fixture("flight_v1_11_0.json");
let v2_json = load_fixture("flight_v2_0_0.json");
let v1_version = v1_json["schema_version"].as_str().unwrap();
let v2_version = v2_json["schema_version"].as_str().unwrap();
assert_eq!(v1_version, "1.11.0");
assert_eq!(v2_version, "2.0.0");
let v1_as_v2_result: Result<versa::schema::v2_0_0::receipt::Receipt, _> =
serde_json::from_value(v1_json.clone());
assert!(
v1_as_v2_result.is_err(),
"v1.11.0 should not deserialize as v2.0.0 due to passenger field difference"
);
let v2_as_v1_result: Result<versa::schema::v1_11_0::receipt::Receipt, _> =
serde_json::from_value(v2_json.clone());
assert!(
v2_as_v1_result.is_err(),
"v2.0.0 should not deserialize as v1.11.0 due to passenger field difference"
);
}
#[test]
fn test_tax_calculation() {
let v1_json = load_fixture("flight_v1_11_0.json");
let v2_json = load_fixture("flight_v2_0_0.json");
let v1_receipt: versa::schema::v1_11_0::receipt::Receipt =
serde_json::from_value(v1_json).unwrap();
let v2_receipt: versa::schema::v2_0_0::receipt::Receipt =
serde_json::from_value(v2_json).unwrap();
let v1_flight = v1_receipt.itemization.flight.as_ref().unwrap();
let v2_flight = v2_receipt.itemization.flight.as_ref().unwrap();
let v1_taxes = &v1_flight.tickets[0].segments[0].taxes;
let v2_taxes = &v2_flight.tickets[0].segments[0].taxes;
let v1_total_tax: i64 = v1_taxes.iter().map(|t| t.amount).sum();
let v2_total_tax: i64 = v2_taxes.as_ref().unwrap().iter().map(|t| t.amount).sum();
assert_eq!(v1_total_tax, v2_total_tax);
assert_eq!(v1_total_tax, 2272); }
#[test]
fn test_payment_details() {
let v1_json = load_fixture("flight_v1_11_0.json");
let v2_json = load_fixture("flight_v2_0_0.json");
let v1_receipt: versa::schema::v1_11_0::receipt::Receipt =
serde_json::from_value(v1_json).unwrap();
let v2_receipt: versa::schema::v2_0_0::receipt::Receipt =
serde_json::from_value(v2_json).unwrap();
assert_eq!(v1_receipt.payments.len(), 1);
assert_eq!(v2_receipt.payments.len(), 1);
let v1_payment = &v1_receipt.payments[0];
let v2_payment = &v2_receipt.payments[0];
assert_eq!(v1_payment.amount, v2_payment.amount);
assert_eq!(v1_payment.amount, 140220);
let v1_card = v1_payment.card_payment.as_ref().unwrap();
let v2_card = v2_payment.card_payment.as_ref().unwrap();
assert_eq!(v1_card.last_four, v2_card.last_four.to_string());
assert_eq!(
v1_card.network,
Some(versa::schema::v1_11_0::receipt::CardPaymentNetwork::Mastercard)
);
assert_eq!(
v2_card.network,
Some(versa::schema::v2_0_0::receipt::CardPaymentNetwork::Mastercard)
);
}