From bfddc1e4c1cef2cc2ef09bcf3b31ce02ca34d331 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 25 Mar 2025 10:36:50 +0100 Subject: [PATCH] clean up the test dir --- .../workflows/nym-api-integration-tests.yml | 4 +- Cargo.lock | 1 + Makefile | 1 + nym-api/Cargo.toml | 1 + nym-api/tests/public-api/README.md | 30 ----------- nym-api/tests/public-api/api_status.rs | 39 ++++++-------- .../tests/public-api/circulating_supply.rs | 14 ++--- nym-api/tests/public-api/contract_cache.rs | 11 ++-- nym-api/tests/public-api/network.rs | 23 +++----- nym-api/tests/public-api/nym_nodes.rs | 52 +++++++++---------- .../tests/public-api/unstable_nym_nodes.rs | 14 ++--- nym-api/tests/public-api/unstable_status.rs | 10 ++-- nym-api/tests/public-api/utils.rs | 26 +++++++--- 13 files changed, 92 insertions(+), 134 deletions(-) delete mode 100644 nym-api/tests/public-api/README.md diff --git a/.github/workflows/nym-api-integration-tests.yml b/.github/workflows/nym-api-integration-tests.yml index e92b13e54c..c2accf1d77 100644 --- a/.github/workflows/nym-api-integration-tests.yml +++ b/.github/workflows/nym-api-integration-tests.yml @@ -29,11 +29,11 @@ jobs: - name: Build nym-api run: cargo build --package nym-api - - name: Launch nym-api in background + - name: Run nym-api in the background run: | ./target/debug/nym-api & - - name: Wait for nym-api to become ready + - name: Wait for nym-api to come alive run: | for i in {1..20}; do curl -sSf http://localhost:8000/v1/status/config-score-details && break diff --git a/Cargo.lock b/Cargo.lock index 7686a9e431..222ec036d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4696,6 +4696,7 @@ dependencies = [ "bip39", "bs58", "cfg-if", + "chrono", "clap", "console-subscriber", "cosmwasm-std", diff --git a/Makefile b/Makefile index 1abef64c6e..8bbd4618c3 100644 --- a/Makefile +++ b/Makefile @@ -168,6 +168,7 @@ generate-typescript: cd tools/ts-rs-cli && cargo run && cd ../.. yarn types:lint:fix +# Run the integration tests for public nym-api endpoints run-api-tests: cargo test --test public-api-tests diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 8366580eb8..a5f4bc39f4 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -120,6 +120,7 @@ nym-http-api-common = { path = "../common/http-api-common", features = ["utoipa" nym-serde-helpers = { path = "../common/serde-helpers", features = ["date"] } nym-ticketbooks-merkle = { path = "../common/ticketbooks-merkle" } nym-statistics-common = { path = "../common/statistics" } +chrono.workspace = true [features] no-reward = [] diff --git a/nym-api/tests/public-api/README.md b/nym-api/tests/public-api/README.md deleted file mode 100644 index baf72a79aa..0000000000 --- a/nym-api/tests/public-api/README.md +++ /dev/null @@ -1,30 +0,0 @@ - -## nym-api-test suite - -A Typescript test framework utilising Jest and Node to perform tests against the NYM validator-apis. - - -## Getting Started - -### Installation -1. Having `yarn` install on your machine -1. Install all the packages - `yarn install` -2. Peeping the package.json will show you the commands to run for the tests - - - -## Usage - -1. Run the testsuite - currently the configuration hasn't fully been set up to switch envs - ``` - yarn test - ``` - -## ToDo -1. Finish happy and negative test scenarios -2. Full reporting -3. Fully functioniting env switching -4. Run in CI -5. Docker? - -Kudos to jmfiola21@gmail.com for the baseline of this framework diff --git a/nym-api/tests/public-api/api_status.rs b/nym-api/tests/public-api/api_status.rs index fcf0a9f383..2f03ccb672 100644 --- a/nym-api/tests/public-api/api_status.rs +++ b/nym-api/tests/public-api/api_status.rs @@ -1,39 +1,34 @@ -// tests/api_status.rs -use serde_json::Value; use tokio; mod utils; -use utils::{base_url, test_client}; +use utils::{base_url, test_client, 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(); + let json = validate_json_response(res).await; - assert!(res.status().is_success(), "Expected 2xx but got {}", res.status()); - let json: Value = res.json().await.expect("Invalid JSON"); - - assert_eq!(json["status"], "up", "Expected status to be 'up'"); + assert_eq!(json["status"], "up", "Expected status is 'up'"); } -// #[tokio::test] -// async fn test_signer_information() { -// let url = format!("{}/v1/api-status/signer-information", base_url()); -// let res = test_client().get(&url).send().await.unwrap(); - -// assert!(res.status().is_success()); -// let json: Value = res.json().await.expect("Invalid JSON"); - -// assert!(json.get("signer_address").is_some(), "Missing 'signer_address'"); -// // TODO add an OR for "this api does not expose zk-nym signing functionalities" when checkign the main api -// } - #[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(); - - assert!(res.status().is_success()); - let json: Value = res.json().await.expect("Invalid JSON"); + let json = validate_json_response(res).await; assert!(json.get("build_version").is_some(), "Missing 'build_version'"); } + +// 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(); + +// 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(), "Missing 'signer_address'"); +// } \ No newline at end of file diff --git a/nym-api/tests/public-api/circulating_supply.rs b/nym-api/tests/public-api/circulating_supply.rs index d406fd4421..5594a3b4b7 100644 --- a/nym-api/tests/public-api/circulating_supply.rs +++ b/nym-api/tests/public-api/circulating_supply.rs @@ -1,5 +1,5 @@ mod utils; -use utils::{base_url, test_client}; +use utils::{base_url, test_client, validate_json_response}; use serde_json::Value; use tokio; @@ -7,9 +7,7 @@ use tokio; async fn test_get_circulating_supply() { let url = format!("{}/v1/circulating-supply", base_url()); let res = test_client().get(&url).send().await.unwrap(); - - assert!(res.status().is_success(), "Expected 200 OK, got {}", res.status()); - let json: Value = res.json().await.expect("Invalid JSON response"); + let json = validate_json_response(res).await; assert!(json.get("circulating_supply").is_some(), "Missing 'circulating_supply' field"); } @@ -18,9 +16,7 @@ async fn test_get_circulating_supply() { async fn test_get_circulating_supply_value() { let url = format!("{}/v1/circulating-supply/circulating-supply-value", base_url()); let res = test_client().get(&url).send().await.unwrap(); - - assert!(res.status().is_success(), "Expected 200 OK, got {}", res.status()); - let json: Value = res.json().await.expect("Invalid JSON"); + 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(); @@ -31,9 +27,7 @@ async fn test_get_circulating_supply_value() { 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(); - - assert!(res.status().is_success(), "Expected 200 OK, got {}", res.status()); - let json: Value = res.json().await.expect("Invalid JSON"); + let json = validate_json_response(res).await; assert!(json.is_number(), "Expected a number for total supply value"); let number = json.as_f64().unwrap(); diff --git a/nym-api/tests/public-api/contract_cache.rs b/nym-api/tests/public-api/contract_cache.rs index 89832b638c..6032290560 100644 --- a/nym-api/tests/public-api/contract_cache.rs +++ b/nym-api/tests/public-api/contract_cache.rs @@ -1,15 +1,12 @@ mod utils; -use utils::{base_url, test_client}; -use serde_json::Value; +use utils::{base_url, test_client, validate_json_response}; use tokio; #[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(); - - assert!(res.status().is_success(), "Expected 200 OK, got {}", res.status()); - let json: Value = res.json().await.expect("Invalid JSON"); + let json = validate_json_response(res).await; assert!(json.get("id").is_some(), "Missing 'id'"); assert!(json.get("current_epoch_start").is_some(), "Missing 'current_epoch_start'"); @@ -20,9 +17,7 @@ async fn test_get_current_epoch() { async fn test_get_reward_params() { let url = format!("{}/v1/epoch/reward_params", base_url()); let res = test_client().get(&url).send().await.unwrap(); - - assert!(res.status().is_success(), "Expected 200 OK, got {}", res.status()); - let json: Value = res.json().await.expect("Invalid JSON"); + let json = validate_json_response(res).await; let interval = json.get("interval").expect("Missing 'interval' field"); assert!(interval.get("reward_pool").is_some(), "Missing 'interval.reward_pool'"); diff --git a/nym-api/tests/public-api/network.rs b/nym-api/tests/public-api/network.rs index 8860347944..71705b0d18 100644 --- a/nym-api/tests/public-api/network.rs +++ b/nym-api/tests/public-api/network.rs @@ -1,15 +1,12 @@ mod utils; -use utils::{base_url, test_client}; -use serde_json::Value; +use utils::{base_url, test_client, validate_json_response}; use tokio; #[tokio::test] async fn test_get_chain_status() { let url = format!("{}/v1/network/chain-status", base_url()); let res = test_client().get(&url).send().await.unwrap(); - - assert!(res.status().is_success(), "Expected 200 OK, got {}", res.status()); - let json: Value = res.json().await.expect("Invalid JSON"); + let json = validate_json_response(res).await; let block_header = json .get("status") @@ -27,9 +24,7 @@ async fn test_get_chain_status() { async fn test_get_network_details() { let url = format!("{}/v1/network/details", base_url()); let res = test_client().get(&url).send().await.unwrap(); - - assert!(res.status().is_success(), "Expected 200 OK, got {}", res.status()); - let json: Value = res.json().await.expect("Invalid JSON"); + let json = validate_json_response(res).await; assert!(json.get("connected_nyxd").is_some(), "Missing 'connected_nyxd'"); let contracts = json @@ -43,9 +38,7 @@ async fn test_get_network_details() { async fn test_get_nym_contracts() { let url = format!("{}/v1/network/nym-contracts", base_url()); let res = test_client().get(&url).send().await.unwrap(); - - assert!(res.status().is_success(), "Expected 200 OK, got {}", res.status()); - let json: Value = res.json().await.expect("Invalid JSON"); + let json = validate_json_response(res).await; assert!(json.get("nym-mixnet-contract").is_some(), "Missing 'nym-mixnet-contract'"); assert!(json.get("nym-ecash-contract").is_some(), "Missing 'nym-ecash-contract'"); @@ -55,9 +48,7 @@ async fn test_get_nym_contracts() { async fn test_get_nym_contracts_detailed() { let url = format!("{}/v1/network/nym-contracts-detailed", base_url()); let res = test_client().get(&url).send().await.unwrap(); - - assert!(res.status().is_success(), "Expected 200 OK, got {}", res.status()); - let json: Value = res.json().await.expect("Invalid JSON"); + let json = validate_json_response(res).await; let mixnet_contract = json .get("nym-mixnet-contract") @@ -65,9 +56,9 @@ async fn test_get_nym_contracts_detailed() { .expect("Missing details for mixnet contract"); assert!(mixnet_contract.get("commit_branch").is_some(), "Missing 'commit_branch'"); - let mixnet_contract = json + let ecash_contract = json .get("nym-ecash-contract") .and_then(|s| s.get("details")) .expect("Missing details for ecash contract"); - assert!(mixnet_contract.get("commit_branch").is_some(), "Missing 'commit_branch'"); + assert!(ecash_contract.get("commit_branch").is_some(), "Missing 'commit_branch'"); } diff --git a/nym-api/tests/public-api/nym_nodes.rs b/nym-api/tests/public-api/nym_nodes.rs index 303f6160da..740c3bc94d 100644 --- a/nym-api/tests/public-api/nym_nodes.rs +++ b/nym-api/tests/public-api/nym_nodes.rs @@ -1,14 +1,13 @@ mod utils; -use utils::{base_url, test_client, get_any_node_id}; -use serde_json::Value; +use utils::{base_url, test_client, get_any_node_id, validate_json_response}; use tokio; +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(); - assert!(res.status().is_success()); - let json: Value = res.json().await.unwrap(); + let json = validate_json_response(res).await; let data = json.get("data").expect("Missing 'data' field"); assert!(data.is_array(), "Expected 'data' to be an array"); @@ -22,8 +21,7 @@ async fn test_get_bonded_nodes() { async fn test_get_described_nodes() { let url = format!("{}/v1/nym-nodes/described", base_url()); let res = test_client().get(&url).send().await.unwrap(); - assert!(res.status().is_success()); - let json: Value = res.json().await.unwrap(); + let json = validate_json_response(res).await; let data = json.get("data").expect("Missing 'data' field"); assert!(data.is_array(), "Expected 'data' to be an array"); @@ -33,20 +31,19 @@ async fn test_get_described_nodes() { ); } -// TODO enable this once noise is properly integrated? +// 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(); -// assert!(res.status().is_success()); +// 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(); - assert!(res.status().is_success()); - let json: Value = res.json().await.unwrap(); + let json = validate_json_response(res).await; let exit_gateways = json.get("exit_gateways").expect("Missing 'exit_gateways' field"); assert!(exit_gateways.is_array(), "Expected 'exit_gateways' to be an array"); @@ -62,29 +59,34 @@ async fn test_get_annotation_for_node() { println!("Using node_id: {}", id); let url = format!("{}/v1/nym-nodes/annotation/{}", base_url(), id); let res = test_client().get(&url).send().await.unwrap(); - assert!(res.status().is_success()); - let json: Value = res.json().await.unwrap(); + let json = validate_json_response(res).await; let annotation = json.get("annotation").expect("Missing 'annotation' field"); assert!(annotation.get("last_24h_performance").is_some(), "Missing 'last_24h_performance'"); } +#[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); + let res = test_client() + .get(&url) + .query(&[("date", date)]) + .send() + .await + .unwrap(); -// TODO add the date section here to the request too (1970-01-01 format) -// #[tokio::test] -// async fn test_get_historical_performance() { -// let id = get_any_node_id().await; -// let url = format!("{}/v1/nym-nodes/historical-performance/{}", base_url(), id); -// let res = test_client().get(&url).send().await.unwrap(); -// assert!(res.status().is_success()); -// } + let json = validate_json_response(res).await; + assert!(json.get("performance").is_some(), "Missing 'performance' field"); +} #[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(); - assert!(res.status().is_success()); - let json: Value = res.json().await.unwrap(); + let json = validate_json_response(res).await; let data = json .get("history") .and_then(|h| h.get("data")) @@ -102,8 +104,7 @@ 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(); - assert!(res.status().is_success()); - let json: Value = res.json().await.unwrap(); + let json = validate_json_response(res).await; assert!(json.get("node_id").is_some(), "Missing 'node_id'"); assert!(json.get("performance").is_some(), "Missing 'performance'"); } @@ -113,8 +114,7 @@ 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(); - assert!(res.status().is_success()); - let json: Value = res.json().await.unwrap(); + let json = validate_json_response(res).await; let data = json .get("history") .and_then(|h| h.get("data")) diff --git a/nym-api/tests/public-api/unstable_nym_nodes.rs b/nym-api/tests/public-api/unstable_nym_nodes.rs index 0eaf77ac28..5cff0f5101 100644 --- a/nym-api/tests/public-api/unstable_nym_nodes.rs +++ b/nym-api/tests/public-api/unstable_nym_nodes.rs @@ -8,7 +8,7 @@ use tokio; 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(); - assert!(res.status().is_success()); + assert!(res.status().is_success(), "Expected 2xx but got {}", res.status()); let json: Value = res.json().await.unwrap(); let data = json.get("nodes").and_then(|r| r.get("data")).expect("Missing 'data' field"); @@ -24,7 +24,7 @@ async fn test_get_skimmed_nodes_active() { async fn test_get_skimmed_active_mixnodes() { let url = format!("{}/v1/unstable/nym-nodes/skimmed/mixnodes/active", base_url()); let res = test_client().get(&url).send().await.unwrap(); - assert!(res.status().is_success()); + assert!(res.status().is_success(), "Expected 2xx but got {}", res.status()); let json: Value = res.json().await.unwrap(); 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' field"); @@ -37,7 +37,7 @@ async fn test_get_skimmed_active_mixnodes() { 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(); - assert!(res.status().is_success()); + assert!(res.status().is_success(), "Expected 2xx but got {}", res.status()); let json: Value = res.json().await.unwrap(); 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' field"); @@ -50,7 +50,7 @@ async fn test_get_skimmed_all_mixnodes() { async fn test_get_skimmed_active_exit_gateways() { let url = format!("{}/v1/unstable/nym-nodes/skimmed/exit-gateways/active", base_url()); let res = test_client().get(&url).send().await.unwrap(); - assert!(res.status().is_success()); + assert!(res.status().is_success(), "Expected 2xx but got {}", res.status()); let json: Value = res.json().await.unwrap(); 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' field"); @@ -63,7 +63,7 @@ async fn test_get_skimmed_active_exit_gateways() { async fn test_get_skimmed_all_exit_gateways() { let url = format!("{}/v1/unstable/nym-nodes/skimmed/exit-gateways/all", base_url()); let res = test_client().get(&url).send().await.unwrap(); - assert!(res.status().is_success()); + assert!(res.status().is_success(), "Expected 2xx but got {}", res.status()); let json: Value = res.json().await.unwrap(); 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' field"); @@ -76,7 +76,7 @@ async fn test_get_skimmed_all_exit_gateways() { async fn test_get_skimmed_active_entry_gateways() { let url = format!("{}/v1/unstable/nym-nodes/skimmed/entry-gateways/active", base_url()); let res = test_client().get(&url).send().await.unwrap(); - assert!(res.status().is_success()); + assert!(res.status().is_success(), "Expected 2xx but got {}", res.status()); let json: Value = res.json().await.unwrap(); 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' field"); @@ -89,7 +89,7 @@ async fn test_get_skimmed_active_entry_gateways() { async fn test_get_skimmed_all_entry_gateways() { let url = format!("{}/v1/unstable/nym-nodes/skimmed/entry-gateways/all", base_url()); let res = test_client().get(&url).send().await.unwrap(); - assert!(res.status().is_success()); + assert!(res.status().is_success(), "Expected 2xx but got {}", res.status()); let json: Value = res.json().await.unwrap(); 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' field"); diff --git a/nym-api/tests/public-api/unstable_status.rs b/nym-api/tests/public-api/unstable_status.rs index 193028041b..52c6b0cc03 100644 --- a/nym-api/tests/public-api/unstable_status.rs +++ b/nym-api/tests/public-api/unstable_status.rs @@ -13,9 +13,9 @@ async fn test_get_gateway_unstable_test_results() { identity ); let res = test_client().get(&url).send().await.unwrap(); - assert!(res.status().is_success()); + assert!(res.status().is_success(), "Expected 2xx but got {}", res.status()); - let json: Value = res.json().await.expect("Invalid JSON"); + let json: Value = res.json().await.unwrap_or_else(|err| panic!("Invalid JSON response: {}", err)); let data_array = json .get("data") .and_then(|v| v.as_array()) @@ -43,9 +43,9 @@ async fn test_get_mixnode_unstable_test_results() { mix_id ); let res = test_client().get(&url).send().await.unwrap(); - assert!(res.status().is_success()); + assert!(res.status().is_success(), "Expected 2xx but got {}", res.status()); - let json: Value = res.json().await.expect("Invalid JSON"); + let json: Value = res.json().await.unwrap_or_else(|err| panic!("Invalid JSON response: {}", err)); let data_array = json .get("data") .and_then(|v| v.as_array()) @@ -69,7 +69,7 @@ async fn test_get_latest_network_monitor_run_details() { base_url() ); let res = test_client().get(&url).send().await.unwrap(); - assert!(res.status().is_success()); + assert!(res.status().is_success(), "Expected 2xx but got {}", res.status()); let json: Value = res.json().await.unwrap(); let monitor_run_id = json diff --git a/nym-api/tests/public-api/utils.rs b/nym-api/tests/public-api/utils.rs index 6e8672fad3..81de9e3334 100644 --- a/nym-api/tests/public-api/utils.rs +++ b/nym-api/tests/public-api/utils.rs @@ -1,13 +1,27 @@ - use reqwest::Client; use serde_json::Value; +use reqwest::Response; pub fn test_client() -> Client { Client::new() } pub fn base_url() -> String { - std::env::var("API_BASE_URL").unwrap_or_else(|_| "https://sandbox-nym-api1.nymtech.net/api".into()) + std::env::var("API_BASE_URL") + .unwrap_or_else(|_| "https://sandbox-nym-api1.nymtech.net/api".into()) +} + +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() + .await + .unwrap_or_else(|err| panic!("Invalid JSON response: {}", err)); + json } pub async fn get_any_node_id() -> String { @@ -41,17 +55,13 @@ pub async fn get_mixnode_node_id() -> u64 { .and_then(|d| d.get("declared_role")) .and_then(|r| r.get("mixnode")) .and_then(|m| m.as_bool()) - .map(|is_mixnode| is_mixnode) + .map(|is_mixnode| is_mixnode) .unwrap_or(true) }) - .and_then(|node| { - node.get("node_id") - .and_then(|v| v.as_u64()) - }) + .and_then(|node| node.get("node_id").and_then(|v| v.as_u64())) .expect("Unable to find mixnode node id") } - pub async fn get_gateway_identity_key() -> String { let url = format!("{}/v1/nym-nodes/described", base_url()); let res = test_client().get(&url).send().await.unwrap();