From dfbeb8b1f8c66758fc1becb679d6cd0a0cd95b83 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 8 Apr 2025 18:38:18 +0200 Subject: [PATCH] reformatting, tidying up --- nym-api/tests/public-api/api_status.rs | 53 +++-- .../tests/public-api/circulating_supply.rs | 47 ++--- nym-api/tests/public-api/contract_cache.rs | 33 ++-- nym-api/tests/public-api/network.rs | 44 +++-- nym-api/tests/public-api/nym_nodes.rs | 142 ++++++-------- nym-api/tests/public-api/status.rs | 29 +-- .../tests/public-api/unstable_nym_nodes.rs | 183 +++++------------- nym-api/tests/public-api/unstable_status.rs | 101 ++++------ nym-api/tests/public-api/utils.rs | 98 ++++++---- 9 files changed, 292 insertions(+), 438 deletions(-) diff --git a/nym-api/tests/public-api/api_status.rs b/nym-api/tests/public-api/api_status.rs index 15a90636e8..f6e6230ff2 100644 --- a/nym-api/tests/public-api/api_status.rs +++ b/nym-api/tests/public-api/api_status.rs @@ -1,43 +1,40 @@ -use crate::utils::{base_url, test_client, validate_json_response}; +use crate::utils::{base_url, make_request, validate_json_response}; #[tokio::test] -async fn test_health() { - let url = format!("{}/v1/api-status/health", base_url()); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; +async fn test_health() -> Result<(), String> { + let url = format!("{}/v1/api-status/health", base_url()?); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; assert_eq!(json["status"], "up", "Expected status is 'up'"); + Ok(()) } #[tokio::test] -async fn test_build_information() { - let url = format!("{}/v1/api-status/build-information", base_url()); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; +async fn test_build_information() -> Result<(), String> { + let url = format!("{}/v1/api-status/build-information", base_url()?); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; assert!( json.get("build_version").is_some(), "Expected a value for 'build_version'" ); + Ok(()) } -// ECASH API TEST -// #[tokio::test] -// async fn test_signer_information() { -// let url = format!("{}/v1/api-status/signer-information", base_url()); -// println!("{}", url); -// let res = test_client().get(&url).send().await.unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); +// ECASH API Test +/* +#[tokio::test] +async fn test_signer_information() -> Result<(), String> { + let url = format!("{}/v1/api-status/signer-information", base_url()?); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; -// assert!(res.status().is_success(), "Expected 2xx but got {}", res.status()); -// let json: Value = res.json().await.unwrap_or_else(|err| panic!("Invalid JSON response: {}", err)); - -// assert!(json.get("signer_address").is_some(), "Expected a value for 'signer_address'"); -// } + assert!( + json.get("signer_address").is_some(), + "Expected a value for 'signer_address'" + ); + Ok(()) +} +*/ diff --git a/nym-api/tests/public-api/circulating_supply.rs b/nym-api/tests/public-api/circulating_supply.rs index 171cdfb07e..105c48dd07 100644 --- a/nym-api/tests/public-api/circulating_supply.rs +++ b/nym-api/tests/public-api/circulating_supply.rs @@ -1,53 +1,44 @@ -use crate::utils::{base_url, test_client, validate_json_response}; +use crate::utils::{base_url, make_request, validate_json_response}; #[tokio::test] -async fn test_get_circulating_supply() { - let url = format!("{}/v1/circulating-supply", base_url()); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; +async fn test_get_circulating_supply() -> Result<(), String> { + let url = format!("{}/v1/circulating-supply", base_url()?); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; assert!( json.get("circulating_supply").is_some(), "Expected a value for 'circulating_supply'" ); + Ok(()) } #[tokio::test] -async fn test_get_circulating_supply_value() { +async fn test_get_circulating_supply_value() -> Result<(), String> { let url = format!( "{}/v1/circulating-supply/circulating-supply-value", - base_url() + base_url()? ); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; assert!( json.is_number(), "Expected a number for the circulating supply value" ); - let number = json.as_f64().unwrap(); + let number = json.as_f64().unwrap_or(-1.0); assert!(number >= 0.0, "Circulating supply should not be negative"); + Ok(()) } #[tokio::test] -async fn test_get_total_supply_value() { - let url = format!("{}/v1/circulating-supply/total-supply-value", base_url()); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; +async fn test_get_total_supply_value() -> Result<(), String> { + let url = format!("{}/v1/circulating-supply/total-supply-value", base_url()?); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; assert!(json.is_number(), "Expected a number for total supply value"); - let number = json.as_f64().unwrap(); - assert!(number >= 0.0, "Total supply should not be negative"); + let number = json.as_f64().unwrap_or(-1.0); + assert!(number >= 0.0, "Total supply shouldn't be negative"); + Ok(()) } diff --git a/nym-api/tests/public-api/contract_cache.rs b/nym-api/tests/public-api/contract_cache.rs index cad56cdd51..8510f30d95 100644 --- a/nym-api/tests/public-api/contract_cache.rs +++ b/nym-api/tests/public-api/contract_cache.rs @@ -1,14 +1,10 @@ -use crate::utils::{base_url, test_client, validate_json_response}; +use crate::utils::{base_url, make_request, validate_json_response}; #[tokio::test] -async fn test_get_current_epoch() { - let url = format!("{}/v1/epoch/current", base_url()); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; +async fn test_get_current_epoch() -> Result<(), String> { + let url = format!("{}/v1/epoch/current", base_url()?); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; assert!(json.get("id").is_some(), "Expected a value for 'id'"); assert!( @@ -19,21 +15,17 @@ async fn test_get_current_epoch() { json.get("total_elapsed_epochs").is_some(), "Expected a value for `total_elapsed_epochs`" ); + Ok(()) } #[tokio::test] -async fn test_get_reward_params() { - let url = format!("{}/v1/epoch/reward_params", base_url()); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; - +async fn test_get_reward_params() -> Result<(), String> { + let url = format!("{}/v1/epoch/reward_params", base_url()?); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let interval = json .get("interval") - .expect("Expected a value for 'interval'"); + .ok_or("Expected a value for 'interval'")?; assert!( interval.get("reward_pool").is_some(), "Expected a value for 'interval.reward_pool'" @@ -41,9 +33,10 @@ async fn test_get_reward_params() { let rewarded_set = json .get("rewarded_set") - .expect("Expected a value for 'rewarded_set'"); + .ok_or("Expected a value for 'rewarded_set'")?; assert!( rewarded_set.get("exit_gateways").is_some(), "Expected a value for 'rewarded_set.exit_gateways'" ); + Ok(()) } diff --git a/nym-api/tests/public-api/network.rs b/nym-api/tests/public-api/network.rs index 4c45a2ed02..62f2440011 100644 --- a/nym-api/tests/public-api/network.rs +++ b/nym-api/tests/public-api/network.rs @@ -1,21 +1,21 @@ use crate::utils::{base_url, test_client, validate_json_response}; #[tokio::test] -async fn test_get_chain_status() { - let url = format!("{}/v1/network/chain-status", base_url()); +async fn test_get_chain_status() -> Result<(), String> { + let url = format!("{}/v1/network/chain-status", base_url()?); let res = test_client() .get(&url) .send() .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; + .map_err(|err| format!("Failed to send request to {}: {}", url, err))?; + let json = validate_json_response(res).await?; let block_header = json .get("status") .and_then(|s| s.get("latest_block")) .and_then(|b| b.get("block")) .and_then(|b| b.get("header")) - .expect("Expected a value for 'status.block.header'"); + .ok_or("Expected a value for 'status.block.header'")?; assert!( block_header.get("chain_id").is_some(), @@ -25,17 +25,18 @@ async fn test_get_chain_status() { block_header.get("height").is_some(), "Expected a value for 'height'" ); + Ok(()) } #[tokio::test] -async fn test_get_network_details() { - let url = format!("{}/v1/network/details", base_url()); +async fn test_get_network_details() -> Result<(), String> { + let url = format!("{}/v1/network/details", base_url()?); let res = test_client() .get(&url) .send() .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; + .map_err(|err| format!("Failed to send request to {}: {}", url, err))?; + let json = validate_json_response(res).await?; assert!( json.get("connected_nyxd").is_some(), @@ -44,22 +45,23 @@ async fn test_get_network_details() { let contracts = json .get("network") .and_then(|s| s.get("contracts")) - .expect("Expected a value for 'contracts'"); + .ok_or("Expected a value for 'contracts'")?; assert!( contracts.get("mixnet_contract_address").is_some(), "Expected a value for 'mixnet_contract_address'" ); + Ok(()) } #[tokio::test] -async fn test_get_nym_contracts() { - let url = format!("{}/v1/network/nym-contracts", base_url()); +async fn test_get_nym_contracts() -> Result<(), String> { + let url = format!("{}/v1/network/nym-contracts", base_url()?); let res = test_client() .get(&url) .send() .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; + .map_err(|err| format!("Failed to send request to {}: {}", url, err))?; + let json = validate_json_response(res).await?; assert!( json.get("nym-mixnet-contract").is_some(), @@ -69,22 +71,23 @@ async fn test_get_nym_contracts() { json.get("nym-ecash-contract").is_some(), "Expected a value for 'nym-ecash-contract'" ); + Ok(()) } #[tokio::test] -async fn test_get_nym_contracts_detailed() { - let url = format!("{}/v1/network/nym-contracts-detailed", base_url()); +async fn test_get_nym_contracts_detailed() -> Result<(), String> { + let url = format!("{}/v1/network/nym-contracts-detailed", base_url()?); let res = test_client() .get(&url) .send() .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; + .map_err(|err| format!("Failed to send request to {}: {}", url, err))?; + let json = validate_json_response(res).await?; let mixnet_contract = json .get("nym-mixnet-contract") .and_then(|s| s.get("details")) - .expect("Expected details for the mixnet contract"); + .ok_or("Expected details for the mixnet contract")?; assert!( mixnet_contract.get("commit_branch").is_some(), "Expected a value for 'commit_branch'" @@ -93,9 +96,10 @@ async fn test_get_nym_contracts_detailed() { let ecash_contract = json .get("nym-ecash-contract") .and_then(|s| s.get("details")) - .expect("Expected details for the ecash contract"); + .ok_or("Expected details for the ecash contract")?; assert!( ecash_contract.get("commit_branch").is_some(), "Expected a value for 'commit_branch'" ); + Ok(()) } diff --git a/nym-api/tests/public-api/nym_nodes.rs b/nym-api/tests/public-api/nym_nodes.rs index 4686e59116..63ff057d45 100644 --- a/nym-api/tests/public-api/nym_nodes.rs +++ b/nym-api/tests/public-api/nym_nodes.rs @@ -1,145 +1,131 @@ -use crate::utils::{base_url, get_any_node_id, test_client, validate_json_response}; +use crate::utils::{base_url, get_any_node_id, make_request, test_client, validate_json_response}; use chrono::Utc; #[tokio::test] -async fn test_get_bonded_nodes() { - let url = format!("{}/v1/nym-nodes/bonded", base_url()); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; - let data = json.get("data").expect("Expected a value for 'data' field"); +async fn test_get_bonded_nodes() -> Result<(), String> { + let url = format!("{}/v1/nym-nodes/bonded", base_url()?); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; + let data = json + .get("data") + .ok_or("Expected a value for 'data' field")?; assert!(data.is_array(), "Expected 'data' to be an array"); assert!( !data.as_array().unwrap().is_empty(), "Expected at least one bonded node" ); + Ok(()) } #[tokio::test] -async fn test_get_described_nodes() { - let url = format!("{}/v1/nym-nodes/described", base_url()); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; - let data = json.get("data").expect("Expected a value for 'data' field"); +async fn test_get_described_nodes() -> Result<(), String> { + let url = format!("{}/v1/nym-nodes/described", base_url()?); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; + let data = json + .get("data") + .ok_or("Expected a value for 'data' field")?; assert!(data.is_array(), "Expected 'data' to be an array"); assert!( !data.as_array().unwrap().is_empty(), "Expected at least one node to appear" ); + Ok(()) } // TODO enable this once noise is properly integrated // #[tokio::test] -// async fn test_get_noise() { -// let url = format!("{}/v1/nym-nodes/noise", base_url()); -// let res = test_client().get(&url).send().await.unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); +// async fn test_get_noise() -> Result<(), String> { +// let url = format!("{}/v1/nym-nodes/noise", base_url()?); +// let res = test_client().get(&url).send().await.map_err(|err| panic!("Failed to send request to {}: {}", url, err))?; // let json = validate_json_response(res).await; // } #[tokio::test] -async fn test_get_rewarded_set() { - let url = format!("{}/v1/nym-nodes/rewarded-set", base_url()); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; +async fn test_get_rewarded_set() -> Result<(), String> { + let url = format!("{}/v1/nym-nodes/rewarded-set", base_url()?); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let exit_gateways = json .get("exit_gateways") - .expect("Expected a value for 'exit_gateways' field"); + .ok_or("Expected a value for 'exit_gateways' field")?; assert!( exit_gateways.is_array(), "Expected 'exit_gateways' to be an array" ); assert!( - exit_gateways.as_array().unwrap().len() > 0, + !exit_gateways.as_array().unwrap().is_empty(), "We have no exit gateways!!" ); + Ok(()) } #[tokio::test] -async fn test_get_annotation_for_node() { - let id = get_any_node_id().await; - println!("Using node_id: {}", id); - let url = format!("{}/v1/nym-nodes/annotation/{}", base_url(), id); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; +async fn test_get_annotation_for_node() -> Result<(), String> { + let id = get_any_node_id().await?; + let url = format!("{}/v1/nym-nodes/annotation/{}", base_url()?, id); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let annotation = json .get("annotation") - .expect("Expected a value for 'annotation' field"); + .ok_or("Expected a value for 'annotation' field")?; assert!( annotation.get("last_24h_performance").is_some(), "Expected a value for 'last_24h_performance'" ); + Ok(()) } -#[tokio::test] -async fn test_get_historical_performance() { - let id = get_any_node_id().await; - let date = Utc::now().date_naive().to_string(); - let url = format!("{}/v1/nym-nodes/historical-performance/{}", base_url(), id); +#[tokio::test] +async fn test_get_historical_performance() -> Result<(), String> { + let id = get_any_node_id().await?; + let date = Utc::now().date_naive().to_string(); + let url = format!("{}/v1/nym-nodes/historical-performance/{}", base_url()?, id); let res = test_client() .get(&url) .query(&[("date", date)]) .send() .await - .unwrap(); + .map_err(|err| format!("Failed to send request to {}: {}", url, err))?; + let json = validate_json_response(res).await?; - let json = validate_json_response(res).await; assert!( json.get("performance").is_some(), "Expected a value for 'performance' field" ); + Ok(()) } #[tokio::test] -async fn test_get_performance_history() { - let id = get_any_node_id().await; - let url = format!("{}/v1/nym-nodes/performance-history/{}", base_url(), id); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; +async fn test_get_performance_history() -> Result<(), String> { + let id = get_any_node_id().await?; + let url = format!("{}/v1/nym-nodes/performance-history/{}", base_url()?, id); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let data = json .get("history") .and_then(|h| h.get("data")) - .expect("Expected a value for 'history.data'"); + .ok_or("Expected a value for 'history.data'")?; assert!(data.is_array(), "Expected 'history.data' to be an array"); assert!( !data.as_array().unwrap().is_empty(), "Expected at least one performance history entry" ); + Ok(()) } #[tokio::test] -async fn test_get_performance() { - let id = get_any_node_id().await; - let url = format!("{}/v1/nym-nodes/performance/{}", base_url(), id); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; +async fn test_get_performance() -> Result<(), String> { + let id = get_any_node_id().await?; + let url = format!("{}/v1/nym-nodes/performance/{}", base_url()?, id); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; + assert!( json.get("node_id").is_some(), "Expected a value for 'node_id'" @@ -148,28 +134,26 @@ async fn test_get_performance() { json.get("performance").is_some(), "Expected a value for 'performance'" ); + Ok(()) } #[tokio::test] -async fn test_get_uptime_history() { - let id = get_any_node_id().await; - let url = format!("{}/v1/nym-nodes/uptime-history/{}", base_url(), id); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - let json = validate_json_response(res).await; +async fn test_get_uptime_history() -> Result<(), String> { + let id = get_any_node_id().await?; + let url = format!("{}/v1/nym-nodes/uptime-history/{}", base_url()?, id); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let data = json .get("history") .and_then(|h| h.get("data")) - .expect("Expected a value for 'history.data'"); + .ok_or("Expected a value for 'history.data'")?; assert!(data.is_array(), "Expected 'history.data' to be an array"); assert!( !data.as_array().unwrap().is_empty(), "Expected at least one performance history entry" ); + Ok(()) } // TODO add the POST request test for `refresh-described` diff --git a/nym-api/tests/public-api/status.rs b/nym-api/tests/public-api/status.rs index c1ac4d6e7d..d0631fb68f 100644 --- a/nym-api/tests/public-api/status.rs +++ b/nym-api/tests/public-api/status.rs @@ -1,29 +1,15 @@ -use crate::utils::{base_url, test_client}; -use serde_json::Value; +use crate::utils::{base_url, make_request, validate_json_response}; #[tokio::test] -async fn test_get_config_score_details() { - let url = format!("{}/v1/status/config-score-details", base_url()); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - assert!( - res.status().is_success(), - "Expected 200 OK, got {}", - res.status() - ); - - let json: Value = res - .json() - .await - .unwrap_or_else(|err| panic!("Failed to parse response as JSON: {}", err)); +async fn test_get_config_score_details() -> Result<(), String> { + let url = format!("{}/v1/status/config-score-details", base_url()?); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let version_history = json .get("version_history") .and_then(|v| v.as_array()) - .expect("Missing or invalid 'version_history' array"); + .ok_or("Missing or invalid 'version_history' array")?; assert!( !version_history.is_empty(), @@ -33,7 +19,7 @@ async fn test_get_config_score_details() { let max_entry = version_history .iter() .max_by_key(|entry| entry.get("id").and_then(|id| id.as_u64()).unwrap_or(0)) - .expect("Unable to find max id entry"); + .ok_or("Unable to find max id entry")?; let semver = max_entry .get("version_information") @@ -44,6 +30,7 @@ async fn test_get_config_score_details() { semver.is_some(), "Expected a value for 'semver' in the highest id entry" ); + Ok(()) } // TODO add the POST request tests for: diff --git a/nym-api/tests/public-api/unstable_nym_nodes.rs b/nym-api/tests/public-api/unstable_nym_nodes.rs index c73a18a0c2..e83aea6297 100644 --- a/nym-api/tests/public-api/unstable_nym_nodes.rs +++ b/nym-api/tests/public-api/unstable_nym_nodes.rs @@ -1,253 +1,168 @@ -use crate::utils::{base_url, test_client}; -use serde_json::Value; +use crate::utils::{base_url, make_request, validate_json_response}; #[tokio::test] -async fn test_get_skimmed_nodes_active() { - let url = format!("{}/v1/unstable/nym-nodes/skimmed/active", base_url()); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - assert!( - res.status().is_success(), - "Expected 2xx but got {}", - res.status() - ); - - let json: Value = res - .json() - .await - .unwrap_or_else(|err| panic!("Failed to parse response as JSON: {}", err)); +async fn test_get_skimmed_nodes_active() -> Result<(), String> { + let url = format!("{}/v1/unstable/nym-nodes/skimmed/active", base_url()?); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let data = json .get("nodes") .and_then(|r| r.get("data")) - .expect("Missing 'data' field"); + .ok_or("Missing 'data' field")?; assert!(data.is_array(), "Expected 'data' to be an array"); assert!( !data.as_array().unwrap().is_empty(), "Expected at least one node to appear" ); + Ok(()) } #[tokio::test] -async fn test_get_skimmed_active_mixnodes() { +async fn test_get_skimmed_active_mixnodes() -> Result<(), String> { let url = format!( "{}/v1/unstable/nym-nodes/skimmed/mixnodes/active", - base_url() + base_url()? ); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - assert!( - res.status().is_success(), - "Expected 2xx but got {}", - res.status() - ); - - let json: Value = res - .json() - .await - .unwrap_or_else(|err| panic!("Failed to parse response as JSON: {}", err)); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let current_epoch_id = json .get("status") .and_then(|r| r.get("fresh")) .and_then(|r| r.get("current_epoch_id")) - .expect("Missing 'current_epoch_id'"); + .ok_or("Missing 'current_epoch_id'")?; assert!( current_epoch_id.is_number(), - "Expected 'current_epoch_id' to be an array" + "Expected 'current_epoch_id' to be a number" ); assert!( json.get("refreshed_at").is_some(), "Expected a value for 'refreshed_at'" ); + Ok(()) } #[tokio::test] -async fn test_get_skimmed_all_mixnodes() { - let url = format!("{}/v1/unstable/nym-nodes/skimmed/mixnodes/all", base_url()); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - assert!( - res.status().is_success(), - "Expected 2xx but got {}", - res.status() - ); - - let json: Value = res - .json() - .await - .unwrap_or_else(|err| panic!("Failed to parse response as JSON: {}", err)); +async fn test_get_skimmed_all_mixnodes() -> Result<(), String> { + let url = format!("{}/v1/unstable/nym-nodes/skimmed/mixnodes/all", base_url()?); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let current_epoch_id = json .get("status") .and_then(|r| r.get("fresh")) .and_then(|r| r.get("current_epoch_id")) - .expect("Expected a value for 'current_epoch_id'"); + .ok_or("Missing 'current_epoch_id'")?; assert!( current_epoch_id.is_number(), - "Expected 'current_epoch_id' to be an array" + "Expected 'current_epoch_id' to be a number" ); assert!( json.get("refreshed_at").is_some(), "Expected a value for 'refreshed_at'" ); + Ok(()) } #[tokio::test] -async fn test_get_skimmed_active_exit_gateways() { +async fn test_get_skimmed_active_exit_gateways() -> Result<(), String> { let url = format!( "{}/v1/unstable/nym-nodes/skimmed/exit-gateways/active", - base_url() + base_url()? ); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - assert!( - res.status().is_success(), - "Expected 2xx but got {}", - res.status() - ); - - let json: Value = res - .json() - .await - .unwrap_or_else(|err| panic!("Failed to parse response as JSON: {}", err)); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let current_epoch_id = json .get("status") .and_then(|r| r.get("fresh")) .and_then(|r| r.get("current_epoch_id")) - .expect("Expected a value for 'current_epoch_id'"); + .ok_or("Missing 'current_epoch_id'")?; assert!( current_epoch_id.is_number(), - "Expected 'current_epoch_id' to be an array" + "Expected 'current_epoch_id' to be a number" ); assert!( json.get("refreshed_at").is_some(), "Expected a value for 'refreshed_at'" ); + Ok(()) } #[tokio::test] -async fn test_get_skimmed_all_exit_gateways() { +async fn test_get_skimmed_all_exit_gateways() -> Result<(), String> { let url = format!( "{}/v1/unstable/nym-nodes/skimmed/exit-gateways/all", - base_url() + base_url()? ); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - assert!( - res.status().is_success(), - "Expected 2xx but got {}", - res.status() - ); - - let json: Value = res - .json() - .await - .unwrap_or_else(|err| panic!("Failed to parse response as JSON: {}", err)); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let current_epoch_id = json .get("status") .and_then(|r| r.get("fresh")) .and_then(|r| r.get("current_epoch_id")) - .expect("Expected a value for 'current_epoch_id'"); + .ok_or("Missing 'current_epoch_id'")?; assert!( current_epoch_id.is_number(), - "Expected 'current_epoch_id' to be an array" + "Expected 'current_epoch_id' to be a number" ); assert!( json.get("refreshed_at").is_some(), "Expected a value for 'refreshed_at'" ); + Ok(()) } #[tokio::test] -async fn test_get_skimmed_active_entry_gateways() { +async fn test_get_skimmed_active_entry_gateways() -> Result<(), String> { let url = format!( "{}/v1/unstable/nym-nodes/skimmed/entry-gateways/active", - base_url() + base_url()? ); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - assert!( - res.status().is_success(), - "Expected 2xx but got {}", - res.status() - ); - - let json: Value = res - .json() - .await - .unwrap_or_else(|err| panic!("Failed to parse response as JSON: {}", err)); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let current_epoch_id = json .get("status") .and_then(|r| r.get("fresh")) .and_then(|r| r.get("current_epoch_id")) - .expect("Expected a value for 'current_epoch_id'"); + .ok_or("Missing 'current_epoch_id'")?; assert!( current_epoch_id.is_number(), - "Expected 'current_epoch_id' to be an array" + "Expected 'current_epoch_id' to be a number" ); assert!( json.get("refreshed_at").is_some(), "Expected a value for 'refreshed_at'" ); + Ok(()) } #[tokio::test] -async fn test_get_skimmed_all_entry_gateways() { +async fn test_get_skimmed_all_entry_gateways() -> Result<(), String> { let url = format!( "{}/v1/unstable/nym-nodes/skimmed/entry-gateways/all", - base_url() + base_url()? ); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - assert!( - res.status().is_success(), - "Expected 2xx but got {}", - res.status() - ); - - let json: Value = res - .json() - .await - .unwrap_or_else(|err| panic!("Failed to parse response as JSON: {}", err)); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let current_epoch_id = json .get("status") .and_then(|r| r.get("fresh")) .and_then(|r| r.get("current_epoch_id")) - .expect("Expected a value for 'current_epoch_id'"); + .ok_or("Missing 'current_epoch_id'")?; assert!( current_epoch_id.is_number(), - "Expected 'current_epoch_id' to be an array" + "Expected 'current_epoch_id' to be a number" ); assert!( json.get("refreshed_at").is_some(), "Expected a value for 'refreshed_at'" ); + Ok(()) } // Add the remining tests as the endpoints become active diff --git a/nym-api/tests/public-api/unstable_status.rs b/nym-api/tests/public-api/unstable_status.rs index 361c87e998..0c4ade9b23 100644 --- a/nym-api/tests/public-api/unstable_status.rs +++ b/nym-api/tests/public-api/unstable_status.rs @@ -1,41 +1,29 @@ -use crate::utils::{base_url, get_gateway_identity_key, get_mixnode_node_id, test_client}; -use serde_json::Value; +mod utils; +use crate::utils::{ + base_url, get_gateway_identity_key, get_mixnode_node_id, make_request, test_client, + validate_json_response, +}; #[tokio::test] -async fn test_get_gateway_unstable_test_results() { - let identity = get_gateway_identity_key().await; +async fn test_get_gateway_unstable_test_results() -> Result<(), String> { + let identity = get_gateway_identity_key().await?; let url = format!( "{}/v1/status/gateways/unstable/{}/test-results", - base_url(), + base_url()?, identity ); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - assert!( - res.status().is_success(), - "Expected 2xx but got {}", - res.status() - ); - - let json: Value = res - .json() - .await - .unwrap_or_else(|err| panic!("Invalid JSON response: {}", err)); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let data_array = json .get("data") .and_then(|v| v.as_array()) - .expect("Missing or invalid 'data' array"); - + .ok_or("Missing or invalid 'data' array")?; assert!(!data_array.is_empty(), "'data' array is empty"); let gateway = data_array[0] .get("test_routes") .and_then(|r| r.get("gateway")) - .expect("Expected a value for 'test_routes.gateway'"); - + .ok_or("Expected a value for 'test_routes.gateway'")?; assert!( gateway.get("node_id").is_some(), "Expected a value for 'node_id' in gateway" @@ -44,43 +32,29 @@ async fn test_get_gateway_unstable_test_results() { gateway.get("identity_key").is_some(), "Expected a value for 'identity_key' in gateway" ); + Ok(()) } #[tokio::test] -async fn test_get_mixnode_unstable_test_results() { - let mix_id = get_mixnode_node_id().await; +async fn test_get_mixnode_unstable_test_results() -> Result<(), String> { + let mix_id = get_mixnode_node_id().await?; let url = format!( "{}/v1/status/mixnodes/unstable/{}/test-results", - base_url(), + base_url()?, mix_id ); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - assert!( - res.status().is_success(), - "Expected 2xx but got {}", - res.status() - ); - - let json: Value = res - .json() - .await - .unwrap_or_else(|err| panic!("Invalid JSON response: {}", err)); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let data_array = json .get("data") .and_then(|v| v.as_array()) - .expect("Missing or invalid 'data' array"); - + .ok_or("Missing or invalid 'data' array")?; assert!(!data_array.is_empty(), "'data' array is empty"); let layer3 = data_array[0] .get("test_routes") .and_then(|r| r.get("layer3")) - .expect("Expected a value for 'test_routes.layer3'"); - + .ok_or("Expected a value for 'test_routes.layer3'")?; assert!( layer3.get("node_id").is_some(), "Expected a value for 'node_id' in layer3" @@ -89,39 +63,32 @@ async fn test_get_mixnode_unstable_test_results() { layer3.get("identity_key").is_some(), "Expected a value for 'identity_key' in layer3" ); + Ok(()) } #[tokio::test] -async fn test_get_latest_network_monitor_run_details() { +async fn test_get_latest_network_monitor_run_details() -> Result<(), String> { let url = format!( "{}/v1/status/network-monitor/unstable/run/latest/details", - base_url() + base_url()? ); - let res = test_client() - .get(&url) - .send() - .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); - assert!( - res.status().is_success(), - "Expected 2xx but got {}", - res.status() - ); - - let json: Value = res - .json() - .await - .unwrap_or_else(|err| panic!("Failed to parse response as JSON: {}", err)); + let res = make_request(&url).await?; + let json = validate_json_response(res).await?; let monitor_run_id = json .get("monitor_run_id") - .and_then(|v| v.as_number()) - .expect("Missing or invalid 'monitor_run_id'"); + .and_then(|v| v.as_u64()) + .ok_or("Missing or invalid 'monitor_run_id'")?; let follow_up_url = format!( "{}/v1/status/network-monitor/unstable/run/{}/details", - base_url(), + base_url()?, monitor_run_id ); - let follow_up_res = test_client().get(&follow_up_url).send().await.unwrap(); + let follow_up_res = test_client() + .get(&follow_up_url) + .send() + .await + .map_err(|err| format!("Failed to follow up with URL {}: {}", follow_up_url, err))?; assert!(follow_up_res.status().is_success()); + Ok(()) } diff --git a/nym-api/tests/public-api/utils.rs b/nym-api/tests/public-api/utils.rs index bf7b162f05..96c8c3b61e 100644 --- a/nym-api/tests/public-api/utils.rs +++ b/nym-api/tests/public-api/utils.rs @@ -1,80 +1,94 @@ use dotenv::dotenv; -use reqwest::Client; -use reqwest::Response; +use reqwest::{Client, Response}; use serde_json::Value; +#[allow(dead_code)] +#[allow(clippy::panic)] pub fn test_client() -> Client { Client::new() } +#[allow(dead_code)] #[allow(clippy::panic)] -pub fn base_url() -> String { +pub fn base_url() -> Result { dotenv().ok(); - std::env::var("NYM_API").unwrap_or_else(|_err| { - std::env::var("NYM_API") - .unwrap_or_else(|_| panic!("Couldn't find NYM_API env var")) - .trim_end_matches('/') - .to_string() - }) + std::env::var("NYM_API") + .map(|url| url.trim_end_matches('/').to_string()) + .map_err(|_| "Couldn't find NYM_API env var".to_string()) } #[allow(dead_code)] #[allow(clippy::panic)] -pub async fn validate_json_response(res: Response) -> Value { - assert!( - res.status().is_success(), - "Expected 2xx but got {}", - res.status() - ); - let json: Value = res - .json() +pub async fn make_request(url: &str) -> Result { + let res = test_client() + .get(url) + .send() .await - .unwrap_or_else(|err| panic!("Invalid JSON response: {}", err)); - json + .map_err(|err| format!("Failed to send request to {}: {}", url, err))?; + + if res.status().is_success() { + Ok(res) + } else { + Err(format!("Expected 2xx but got {}", res.status())) + } } #[allow(dead_code)] #[allow(clippy::panic)] -pub async fn get_any_node_id() -> String { - let url = format!("{}/v1/nym-nodes/bonded", base_url()); +pub async fn validate_json_response(res: Response) -> Result { + if !res.status().is_success() { + return Err(format!("Expected 2xx but got {}", res.status())); + } + + res.json::() + .await + .map_err(|err| format!("Invalid JSON response: {}", err)) +} + +#[allow(dead_code)] +#[allow(clippy::panic)] +pub async fn get_any_node_id() -> Result { + let url = format!("{}/v1/nym-nodes/bonded", base_url()?); let res = test_client() .get(&url) .send() .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); + .map_err(|err| format!("Failed to send request to {}: {}", url, err))?; let json: Value = res .json() .await - .unwrap_or_else(|err| panic!("Failed to parse response as JSON: {}", err)); + .map_err(|err| format!("Failed to parse response as JSON: {}", err))?; - json.get("data") + let id = json + .get("data") .and_then(|list| list.as_array()) .and_then(|arr| arr.first()) .and_then(|node| node.get("bond_information")) .and_then(|n| n.get("node_id")) .and_then(|v| v.as_u64()) - .unwrap_or(0) - .to_string() + .unwrap_or(0); + + Ok(id.to_string()) } #[allow(dead_code)] #[allow(clippy::panic)] -pub async fn get_mixnode_node_id() -> u64 { - let url = format!("{}/v1/nym-nodes/described", base_url()); +pub async fn get_mixnode_node_id() -> Result { + let url = format!("{}/v1/nym-nodes/described", base_url()?); let res = test_client() .get(&url) .send() .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); + .map_err(|err| format!("Failed to send request to {}: {}", url, err))?; let json: Value = res .json() .await - .unwrap_or_else(|err| panic!("Failed to parse response as JSON: {}", err)); + .map_err(|err| format!("Failed to parse response as JSON: {}", err))?; json.get("data") .and_then(|v| v.as_array()) - .unwrap_or_else(|| panic!("Expected 'data' to be an array")) + .ok_or("Expected 'data' to be an array".to_string())? .iter() .find(|entry| { entry @@ -85,26 +99,27 @@ pub async fn get_mixnode_node_id() -> u64 { .unwrap_or(true) }) .and_then(|node| node.get("node_id").and_then(|v| v.as_u64())) - .expect("Unable to find mixnode node id") + .ok_or("Unable to find mixnode node id".to_string()) } #[allow(dead_code)] #[allow(clippy::panic)] -pub async fn get_gateway_identity_key() -> String { - let url = format!("{}/v1/nym-nodes/described", base_url()); +pub async fn get_gateway_identity_key() -> Result { + let url = format!("{}/v1/nym-nodes/described", base_url()?); let res = test_client() .get(&url) .send() .await - .unwrap_or_else(|err| panic!("Failed to send request to {}: {}", url, err)); + .map_err(|err| format!("Failed to send request to {}: {}", url, err))?; let json: Value = res .json() .await - .unwrap_or_else(|err| panic!("Failed to parse response as JSON: {}", err)); + .map_err(|err| format!("Failed to parse response as JSON: {}", err))?; - json.get("data") + let key = json + .get("data") .and_then(|v| v.as_array()) - .unwrap_or_else(|| panic!("Expected 'data' to be an array")) + .ok_or("Expected 'data' to be an array".to_string())? .iter() .find(|entry| { entry @@ -112,7 +127,7 @@ pub async fn get_gateway_identity_key() -> String { .and_then(|d| d.get("declared_role")) .and_then(|r| r.get("mixnode")) .and_then(|m| m.as_bool()) - .map(|is_mixnode| !is_mixnode) // we want gateways, not mixnodes + .map(|is_mixnode| !is_mixnode) .unwrap_or(false) }) .and_then(|node| { @@ -122,6 +137,7 @@ pub async fn get_gateway_identity_key() -> String { .and_then(|k| k.get("ed25519")) .and_then(|v| v.as_str()) }) - .expect("Unable to find gateway identity key with mixnode = false") - .to_string() + .ok_or("Unable to find gateway identity key with mixnode = false".to_string())?; + + Ok(key.to_string()) }