use crate::model::response::common::{FigiData, FigiResult, ResponseResult};
use serde::{Deserialize, Serialize};
pub type MappingResponse = Vec<ResponseResult<MappingData>>;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MappingData {
pub data: Vec<FigiResult>,
}
impl FigiData for MappingData {
fn figi_data(&self) -> &[FigiResult] {
&self.data
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
fn load_test_data(filename: &str) -> String {
let path = format!("tests/data/mapping/{filename}");
fs::read_to_string(&path).unwrap_or_else(|e| panic!("Failed to read test file {path}: {e}"))
}
#[test]
fn test_deserialize_isin_example() {
let json_str = load_test_data("isin_example.json");
let results: MappingResponse = serde_json::from_str(&json_str).unwrap();
assert_eq!(results.len(), 1);
let result = &results[0];
assert!(result.is_success());
let data = result.data().unwrap();
assert!(!data.is_empty());
let first_entry = &data[0];
assert_eq!(first_entry.figi, "BBG000BLNNH6");
assert_eq!(first_entry.ticker, Some("IBM".to_string()));
assert_eq!(first_entry.display_name(), "INTL BUSINESS MACHINES CORP");
assert!(first_entry.has_composite_figi());
assert!(first_entry.has_share_class_figi());
assert_eq!(first_entry.composite_figi, Some("BBG000BLNNH6".to_string()));
assert_eq!(
first_entry.share_class_figi,
Some("BBG001S5S399".to_string())
);
}
#[test]
fn test_deserialize_invalid_identifier() {
let json_str = load_test_data("invalid_identifier.json");
let results: MappingResponse = serde_json::from_str(&json_str).unwrap();
assert_eq!(results.len(), 1);
let result = &results[0];
assert!(result.is_error());
assert_eq!(result.error(), Some("Invalid idValue format."));
assert!(result.data().is_none());
}
#[test]
fn test_deserialize_bulk_request() {
let json_str = load_test_data("bulk_request.json");
let results: MappingResponse = serde_json::from_str(&json_str).unwrap();
assert_eq!(results.len(), 2);
let ibm_result = &results[0];
assert!(ibm_result.is_success());
let ibm_data = ibm_result.data().unwrap();
assert!(!ibm_data.is_empty());
assert_eq!(ibm_data[0].ticker, Some("IBM".to_string()));
let aapl_result = &results[1];
assert!(aapl_result.is_success());
let aapl_data = aapl_result.data().unwrap();
assert!(!aapl_data.is_empty());
assert_eq!(aapl_data[0].ticker, Some("AAPL".to_string()));
}
#[test]
fn test_deserialize_cusip_with_exchange() {
let json_str = load_test_data("cusip_with_exchange.json");
let results: MappingResponse = serde_json::from_str(&json_str).unwrap();
assert_eq!(results.len(), 1);
let result = &results[0];
assert!(result.is_success());
let data = result.data().unwrap();
assert!(!data.is_empty());
for figi_result in data {
assert!(!figi_result.figi.is_empty());
assert!(figi_result.ticker.is_some());
}
}
#[test]
fn test_deserialize_ticker_with_security_type() {
let json_str = load_test_data("ticker_with_security_type.json");
let results: MappingResponse = serde_json::from_str(&json_str).unwrap();
assert_eq!(results.len(), 1);
let result = &results[0];
assert!(result.is_success());
let data = result.data().unwrap();
assert!(!data.is_empty());
for figi_result in data {
assert!(figi_result.security_type.is_some());
assert!(figi_result.market_sector.is_some());
}
}
#[test]
fn test_deserialize_option_example() {
let json_str = load_test_data("option_example.json");
let results: MappingResponse = serde_json::from_str(&json_str).unwrap();
assert_eq!(results.len(), 1);
let result = &results[0];
if result.is_success() {
let data = result.data().unwrap();
for figi_result in data {
assert!(!figi_result.figi.is_empty());
}
} else {
assert!(result.error().is_some());
}
}
#[test]
fn test_deserialize_currency_mic_example() {
let json_str = load_test_data("currency_mic_example.json");
let results: MappingResponse = serde_json::from_str(&json_str).unwrap();
assert_eq!(results.len(), 1);
let result = &results[0];
if result.is_success() {
let data = result.data().unwrap();
for figi_result in data {
assert!(!figi_result.figi.is_empty());
}
} else {
assert!(result.error().is_some());
}
}
#[test]
fn test_figi_result_display_name_fallback() {
let figi_with_ticker = FigiResult {
figi: "BBG000BLNNH6".to_string(),
name: None,
ticker: Some("IBM".to_string()),
security_type: None,
market_sector: None,
exch_code: None,
share_class_figi: None,
composite_figi: None,
security_type2: None,
security_description: None,
metadata: None,
};
assert_eq!(figi_with_ticker.display_name(), "IBM");
let figi_only = FigiResult {
figi: "BBG000BLNNH6".to_string(),
name: None,
ticker: None,
security_type: None,
market_sector: None,
exch_code: None,
share_class_figi: None,
composite_figi: None,
security_type2: None,
security_description: None,
metadata: None,
};
assert_eq!(figi_only.display_name(), "BBG000BLNNH6");
}
}