use ig_trading_api::common::*;
use ig_trading_api::rest_models::*;
use ig_trading_api::rest_api::*;
use regex::Regex;
use std::sync::Arc;
use tokio::sync::OnceCell;
static API: OnceCell<Arc<RestApi>> = OnceCell::const_new();
static DEFAULT_TEST_DELAY_SECONDS: u64 = 10;
async fn get_or_init_rest_api() -> Arc<RestApi> {
API.get_or_init(|| async {
let api_config = ApiConfig::default();
let auto_login = api_config.auto_login.unwrap_or(false);
let mut rest_api = match RestApi::new(api_config).await {
Ok(api) => api,
Err(e) => panic!("Failed to create and initialize REST API: {}", e),
};
if !auto_login {
let _ = rest_api.client.login();
}
Arc::new(rest_api)
})
.await
.clone()
}
fn sleep() {
let seconds: u64 = std::env::var("RUST_TEST_DELAY")
.unwrap_or(DEFAULT_TEST_DELAY_SECONDS.to_string())
.parse::<u64>()
.unwrap_or(DEFAULT_TEST_DELAY_SECONDS);
std::thread::sleep(std::time::Duration::from_secs(seconds));
}
#[tokio::test]
async fn aaa_rest_api_is_properly_initialized() {
let api = get_or_init_rest_api().await;
println!("API instance: {:?}", api);
assert!(api.client.auth_headers.is_some());
if let Some(session_version) = api.client.config.session_version.as_ref() {
match session_version {
1 | 2 => {
assert!(api
.client
.auth_headers
.as_ref()
.unwrap()
.contains_key("cst"));
assert!(api
.client
.auth_headers
.as_ref()
.unwrap()
.contains_key("x-security-token"));
let cst_value = api
.client
.auth_headers
.as_ref()
.unwrap()
.get("cst")
.unwrap()
.to_str()
.unwrap();
let re = Regex::new(r"^[a-fA-F0-9]{69}$").unwrap();
assert!(re.is_match(cst_value));
let security_token_value = api
.client
.auth_headers
.as_ref()
.unwrap()
.get("x-security-token")
.unwrap()
.to_str()
.unwrap();
let re = Regex::new(r"^[a-fA-F0-9]{69}$").unwrap();
assert!(re.is_match(security_token_value));
}
3 => {
assert!(api
.client
.auth_headers
.as_ref()
.unwrap()
.contains_key("authorization"));
let authorization_value = api
.client
.auth_headers
.as_ref()
.unwrap()
.get("authorization")
.unwrap()
.to_str()
.unwrap();
let re = regex::Regex::new(r"^Bearer [0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$").unwrap();
assert!(re.is_match(authorization_value));
}
_ => panic!("Invalid session version: {}", session_version),
}
} else {
panic!("Session version is not set in the configuration.");
}
sleep();
}
#[tokio::test]
async fn get_session_works() {
let api = get_or_init_rest_api().await;
let response = match api.get_session(None).await {
Ok(response) => response,
Err(e) => {
println!("Error getting session details: {:?}", e);
panic!("Test failed due to error.");
}
};
println!(
"Response headers: {}",
serde_json::to_string_pretty(&response.0).unwrap()
);
println!(
"Response body: {}",
serde_json::to_string_pretty(&response.1).unwrap()
);
sleep();
}
#[tokio::test]
async fn put_session_works() {
let api = get_or_init_rest_api().await;
let new_account_number = match api.config.execution_environment {
ExecutionEnvironment::Demo => api.config.account_number_live.clone(),
ExecutionEnvironment::Live => api.config.account_number_demo.clone(),
};
let body = AccountSwitchRequest {
account_id: new_account_number.clone(),
default_account: None,
};
let response = match api.put_session(&body).await {
Ok(response) => response,
Err(e) => {
println!("Error switching session to account '{}': {:?}", new_account_number, e);
panic!("Test failed due to error.");
}
};
println!(
"Response headers: {}",
serde_json::to_string_pretty(&response.0).unwrap()
);
println!(
"Response body: {}",
serde_json::to_string_pretty(&response.1).unwrap()
);
sleep();
}
#[tokio::test]
async fn zzz_delete_session_works() {
let api = get_or_init_rest_api().await;
let response = match api.delete_session().await {
Ok(response) => response,
Err(e) => {
println!("Error getting session details: {:?}", e);
panic!("Test failed due to error.");
}
};
println!(
"Response headers: {}",
serde_json::to_string_pretty(&response.0).unwrap()
);
sleep();
}