diff --git a/core/bin/zksync_api/src/bin/providers/proxy_price_provider.rs b/core/bin/zksync_api/src/bin/providers/proxy_price_provider.rs index 46c4b903f..93b74af04 100644 --- a/core/bin/zksync_api/src/bin/providers/proxy_price_provider.rs +++ b/core/bin/zksync_api/src/bin/providers/proxy_price_provider.rs @@ -38,7 +38,7 @@ async fn fetch_coins_list(_: web::Data, _: web::Path<(bool,)>) -> Http async fn fetch_market_chart(reqest: HttpRequest) -> HttpResponse { let data: &web::Data = reqest.app_data().unwrap(); let query = reqest.query_string(); - let path = reqest.path().to_string(); + let path: String = reqest.path().to_string(); let forward_url = match query.is_empty() { true => reqest.uri().to_string(), false => format!("{}{}/{}?{}", API_URL, API_PATH, path, query), @@ -69,42 +69,171 @@ pub(crate) fn create_price_service() -> Scope { ) } -// TODO: finish test -// #[cfg(test)] +#[cfg(test)] // test that the fetch_market_chart forwards any path arguments after question mark to the proxy_request -// mod fetch_market_chart_tests { -// use super::*; -// use actix_web::{test, App}; - -// #[actix_web::test] -// async fn forwards_path_arguments() { -// let proxied_app = test::init_service( -// App::new() -// .app_data(ProxyState { -// cache: std::sync::Arc::new(Mutex::new(HashMap::new())), -// }) -// .route( -// "/coins/{coin_id}/market_chart", -// web::get().to(|| async move { HttpResponse::Ok().body("proxied") }), -// ), -// ); - -// let test_app = test::init_service( -// App::new() -// .app_data(ProxyState { -// cache: std::sync::Arc::new(Mutex::new(HashMap::new())), -// }) -// .route( -// "/coins/{coin_id}/market_chart", -// web::get().to(fetch_market_chart), -// ), -// ) -// .await; - -// let req = test::TestRequest::get() -// .uri("/coins/rif-token/market_chart?vs_currency=usd&days=1") -// .to_request(); -// let resp = test::call_service(&test_app, req).await; -// assert!(resp.status().is_success()); -// } -// } +mod fetch_market_chart_tests { + use crate::providers::test_utils::{FakeBody, FakeHttpClient}; + + use super::*; + use actix_web::{test, App}; + + #[actix_web::test] + async fn changes_url() { + let test_app = test::init_service( + #[allow(deprecated)] + // Allowed deprecated .data function as .app_data is not working inside the test service + App::new() + .data(AppState { + proxy_state: ProxyState { + cache: std::sync::Arc::new(Mutex::new(HashMap::new())), + }, + proxy_client: Box::new(FakeHttpClient::default()), + }) + .route( + "/coins/{coin_id}/market_chart", + web::get().to(fetch_market_chart), + ), + ) + .await; + let req = test::TestRequest::get() + .uri("/coins/rif-token/market_chart?vs_currency=usd&days=1") + .to_request(); + let response = test::call_service(&test_app, req).await; + assert!(response.status().is_success()); + + let body_bytes = match response.response().body() { + actix_web::body::Body::Bytes(b) => b.clone(), + _ => actix_web::web::Bytes::default(), + }; + let body: FakeBody = serde_json::from_slice(&body_bytes).unwrap(); + + assert!(body + .called_url + .starts_with(&(API_URL.to_owned() + API_PATH))); + } + + #[actix_web::test] + async fn forwards_no_path_arguments() { + let test_app = test::init_service( + #[allow(deprecated)] + // Allowed deprecated .data function as .app_data is not working inside the test service + App::new() + .data(AppState { + proxy_state: ProxyState { + cache: std::sync::Arc::new(Mutex::new(HashMap::new())), + }, + proxy_client: Box::new(FakeHttpClient::default()), + }) + .route( + "/coins/{coin_id}/market_chart", + web::get().to(fetch_market_chart), + ), + ) + .await; + let req = test::TestRequest::get() + .uri("/coins/rif-token/market_chart") + .to_request(); + let response = test::call_service(&test_app, req).await; + assert!(response.status().is_success()); + + let body_bytes = match response.response().body() { + actix_web::body::Body::Bytes(b) => b.clone(), + _ => actix_web::web::Bytes::default(), + }; + let body: FakeBody = serde_json::from_slice(&body_bytes).unwrap(); + + assert!(body.called_url.ends_with("/coins/rif-token/market_chart")); + } + + #[actix_web::test] + async fn forwards_path_arguments() { + let test_app = test::init_service( + #[allow(deprecated)] + // Allowed deprecated .data function as .app_data is not working inside the test service + App::new() + .data(AppState { + proxy_state: ProxyState { + cache: std::sync::Arc::new(Mutex::new(HashMap::new())), + }, + proxy_client: Box::new(FakeHttpClient::default()), + }) + .route( + "/coins/{coin_id}/market_chart", + web::get().to(fetch_market_chart), + ), + ) + .await; + let expected_arguments = "?vs_currency=usd&days=1"; + let req = test::TestRequest::get() + .uri(&("/coins/rif-token/market_chart".to_owned() + expected_arguments)) + .to_request(); + let response = test::call_service(&test_app, req).await; + assert!(response.status().is_success()); + + let body_bytes = match response.response().body() { + actix_web::body::Body::Bytes(b) => b.clone(), + _ => actix_web::web::Bytes::default(), + }; + let body: FakeBody = serde_json::from_slice(&body_bytes).unwrap(); + + assert!(body.called_url.ends_with(expected_arguments)); + } +} + +#[cfg(test)] +mod fetch_coins_list_tests { + use crate::providers::test_utils::FakeHttpClient; + + use super::*; + + #[actix_web::test] + async fn returns_hardcoded_tokens() { + let response: HttpResponse = fetch_coins_list( + web::Data::new(AppState { + proxy_state: ProxyState { + cache: std::sync::Arc::new(Mutex::new(HashMap::new())), + }, + proxy_client: Box::new(FakeHttpClient::default()), + }), + web::Path::from((true,)), + ) + .await; + assert!(response.status().is_success()); + + let body_bytes = match response.body() { + actix_web::body::Body::Bytes(b) => b.clone(), + _ => actix_web::web::Bytes::default(), + }; + let body: Vec = serde_json::from_slice(&body_bytes).unwrap(); + + let rif_token = body.iter().find(|coin| coin.id == "rif-token").unwrap(); + let rbtc = body.iter().find(|coin| coin.id == "rootstock").unwrap(); + + assert_eq!(body.len(), 2); + assert_eq!(rif_token.name, "RIF Token"); + assert_eq!(rif_token.symbol, "TRIF"); + assert_eq!( + rif_token + .platforms + .as_ref() + .unwrap() + .get("rootstock") + .unwrap() + .as_ref() + .unwrap(), + RIF_TOKEN_TESTNET_ADDRESS + ); + assert_eq!(rbtc.name, "Rootstock RSK"); + assert_eq!(rbtc.symbol, "TRBTC"); + assert_eq!( + rbtc.platforms + .as_ref() + .unwrap() + .get("rootstock") + .unwrap() + .as_ref() + .unwrap(), + RIF_TOKEN_TESTNET_ADDRESS + ); + } +} diff --git a/core/bin/zksync_api/src/bin/providers/proxy_utils.rs b/core/bin/zksync_api/src/bin/providers/proxy_utils.rs index be2f7cd21..77cdbda30 100644 --- a/core/bin/zksync_api/src/bin/providers/proxy_utils.rs +++ b/core/bin/zksync_api/src/bin/providers/proxy_utils.rs @@ -57,7 +57,7 @@ pub(crate) async fn cache_proxy_request( } // Fetch data if not in cache or stale - match client.get(url.clone()).await { + match client.get(url).await { Ok(response) => match response.json::().await { Ok(data) => { // Cache the fetched data diff --git a/etc/env/base/dev_ticker.toml b/etc/env/base/dev_ticker.toml index 27c09c11f..ecf58bf7b 100644 --- a/etc/env/base/dev_ticker.toml +++ b/etc/env/base/dev_ticker.toml @@ -2,4 +2,4 @@ blacklisted_tokens="0x0000000000000000000000000000000000000001" default_volume=500 regime="whitelist" -proxy_cache_timout=5 \ No newline at end of file +proxy_cache_timout=5