use crate::client::JupiterApiClient;
use httpmock::prelude::*;
#[tokio::test]
async fn test_new_client() {
let client = JupiterApiClient::new("test-key".to_string());
assert!(client.is_ok());
}
#[tokio::test]
async fn test_get_prices_v3_exact_sample() {
let server = MockServer::start();
let api_key = "test-key".to_string();
let sample_response = r#"{
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v": {
"createdAt": "2024-06-05T08:55:25.527Z",
"liquidity": 4235561.009987704,
"usdPrice": 0.9997073145154354,
"blockId": 395374169,
"decimals": 6,
"priceChange24h": 0.0003915640587189741
},
"So11111111111111111111111111111111111111112": {
"createdAt": "2024-06-05T08:55:25.527Z",
"liquidity": 151608370.92457405,
"usdPrice": 127.02993218743363,
"blockId": 395374172,
"decimals": 9,
"priceChange24h": -2.231717089336497
}
}"#;
let mock = server.mock(|when, then| {
when.method(GET)
.path("/price/v3")
.header("x-api-key", "test-key")
.query_param("ids", "So11111111111111111111111111111111111111112,EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
then.status(200)
.header("content-type", "application/json")
.body(sample_response);
});
let mut client = JupiterApiClient::new(api_key).unwrap();
client.base_url = server.base_url();
let ids = vec![
"So11111111111111111111111111111111111111112".to_string(),
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v".to_string(),
];
let result = client.get_prices(&ids).await;
mock.assert();
assert!(result.is_ok());
let prices = result.unwrap();
assert_eq!(prices.len(), 2);
let sol = prices.get("So11111111111111111111111111111111111111112").unwrap();
assert!((sol.usd_price - 127.02993218743363).abs() < f64::EPSILON * 100.0);
assert_eq!(sol.decimals, 9);
assert_eq!(sol.created_at.as_deref(), Some("2024-06-05T08:55:25.527Z"));
assert!((sol.liquidity.unwrap() - 151608370.92457405).abs() < f64::EPSILON * 100000.0);
assert_eq!(sol.block_id, Some(395374172));
assert!((sol.price_change_24h.unwrap() - (-2.231717089336497)).abs() < f64::EPSILON * 100.0);
let usdc = prices.get("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v").unwrap();
assert!((usdc.usd_price - 0.9997073145154354).abs() < f64::EPSILON);
assert_eq!(usdc.decimals, 6);
assert_eq!(usdc.created_at.as_deref(), Some("2024-06-05T08:55:25.527Z"));
assert!((usdc.liquidity.unwrap() - 4235561.009987704).abs() < f64::EPSILON * 1000.0);
assert_eq!(usdc.block_id, Some(395374169));
assert!((usdc.price_change_24h.unwrap() - 0.0003915640587189741).abs() < f64::EPSILON);
}
#[tokio::test]
async fn test_get_prices_with_api_key() {
let server = MockServer::start();
let api_key = "test-api-key".to_string();
let mock = server.mock(|when, then| {
when.method(GET)
.path("/price/v3")
.header("x-api-key", "test-api-key");
then.status(200)
.header("content-type", "application/json")
.body("{}");
});
let mut client = JupiterApiClient::new(api_key).unwrap();
client.base_url = server.base_url();
let _ = client.get_prices(&["token".to_string()]).await;
mock.assert();
}
#[tokio::test]
async fn test_get_prices_v3_with_missing_usd_price() {
let server = MockServer::start();
let api_key = "test-key".to_string();
let sample_response = r#"{
"GPPEV4tZHesL1gztLTV31Zym6NhoQpUcrFZVjYpDpump": {
"createdAt": "2026-02-05T14:45:49Z",
"liquidity": 2711.8305892749604,
"usdPrice": 0.0000025286445588138423,
"blockId": 398243425,
"decimals": 6
},
"So11111111111111111111111111111111111111112": {
"createdAt": "2024-06-05T08:55:25.527Z",
"liquidity": 624230374.7176507,
"usdPrice": 76.66694161338336,
"blockId": 402386707,
"decimals": 9,
"priceChange24h": -4.47394415683684
},
"SupEmNudsbx5yeKipe7ipAy2P24weAUER15o5uYtv7t": {
"createdAt": "2025-07-21T07:20:44Z",
"liquidity": 18.22394062640557,
"blockId": 397779922,
"decimals": 9
},
"pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn": {
"createdAt": "2025-07-10T13:10:28Z",
"liquidity": 20474386.960526194,
"usdPrice": 0.0017541202126736364,
"blockId": 402386655,
"decimals": 6,
"priceChange24h": -9.104137129050581
}
}"#;
let mock = server.mock(|when, then| {
when.method(GET)
.path("/price/v3")
.header("x-api-key", "test-key");
then.status(200)
.header("content-type", "application/json")
.body(sample_response);
});
let mut client = JupiterApiClient::new(api_key).unwrap();
client.base_url = server.base_url();
let ids = vec![
"GPPEV4tZHesL1gztLTV31Zym6NhoQpUcrFZVjYpDpump".to_string(),
"So11111111111111111111111111111111111111112".to_string(),
"SupEmNudsbx5yeKipe7ipAy2P24weAUER15o5uYtv7t".to_string(),
"pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn".to_string(),
];
let result = client.get_prices(&ids).await;
mock.assert();
assert!(result.is_ok());
let prices = result.unwrap();
assert_eq!(prices.len(), 4);
let gppev = prices.get("GPPEV4tZHesL1gztLTV31Zym6NhoQpUcrFZVjYpDpump").unwrap();
assert!((gppev.usd_price - 0.0000025286445588138423).abs() < f64::EPSILON);
assert_eq!(gppev.decimals, 6);
assert_eq!(gppev.created_at.as_deref(), Some("2026-02-05T14:45:49Z"));
assert!((gppev.liquidity.unwrap() - 2711.8305892749604).abs() < f64::EPSILON);
assert_eq!(gppev.block_id, Some(398243425));
assert!(gppev.price_change_24h.is_none());
let sol = prices.get("So11111111111111111111111111111111111111112").unwrap();
assert!((sol.usd_price - 76.66694161338336).abs() < f64::EPSILON * 100.0);
assert_eq!(sol.decimals, 9);
assert_eq!(sol.created_at.as_deref(), Some("2024-06-05T08:55:25.527Z"));
assert!((sol.liquidity.unwrap() - 624230374.7176507).abs() < f64::EPSILON * 100000.0);
assert_eq!(sol.block_id, Some(402386707));
assert!((sol.price_change_24h.unwrap() - (-4.47394415683684)).abs() < f64::EPSILON * 100.0);
let sup = prices.get("SupEmNudsbx5yeKipe7ipAy2P24weAUER15o5uYtv7t").unwrap();
assert!((sup.usd_price - 0.0).abs() < f64::EPSILON);
assert_eq!(sup.decimals, 9);
assert_eq!(sup.created_at.as_deref(), Some("2025-07-21T07:20:44Z"));
assert!((sup.liquidity.unwrap() - 18.22394062640557).abs() < f64::EPSILON);
assert_eq!(sup.block_id, Some(397779922));
assert!(sup.price_change_24h.is_none());
let pump = prices.get("pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn").unwrap();
assert!((pump.usd_price - 0.0017541202126736364).abs() < f64::EPSILON);
assert_eq!(pump.decimals, 6);
assert_eq!(pump.created_at.as_deref(), Some("2025-07-10T13:10:28Z"));
assert!((pump.liquidity.unwrap() - 20474386.960526194).abs() < 1e-3);
assert_eq!(pump.block_id, Some(402386655));
assert!((pump.price_change_24h.unwrap() - (-9.104137129050581)).abs() < f64::EPSILON * 100.0);
}