#![allow(dead_code)]
use color_eyre::eyre::{WrapErr, eyre};
use crate::config::NodeConfig;
#[derive(Clone, Debug)]
pub struct ApiClient {
pub name: String,
pub url: String,
pub authenticated: bool,
inner: bee::Client,
}
impl ApiClient {
pub fn from_node(node: &NodeConfig) -> color_eyre::Result<Self> {
let url = node.url.trim_end_matches('/').to_string();
let token = node.resolved_token();
let authenticated = token.is_some();
let inner = match token.as_deref() {
Some(t) => bee::Client::with_token(&url, t)
.map_err(|e| eyre!("invalid bee endpoint or token: {e}"))?,
None => bee::Client::new(&url).map_err(|e| eyre!("invalid bee endpoint: {e}"))?,
};
Ok(Self {
name: node.name.clone(),
url,
authenticated,
inner,
})
}
pub fn bee(&self) -> &bee::Client {
&self.inner
}
pub async fn ping(&self) -> color_eyre::Result<std::time::Duration> {
self.inner
.ping()
.await
.wrap_err_with(|| format!("ping {} ({}) failed", self.name, self.url))
}
}
#[cfg(test)]
mod tests {
use super::*;
fn node(url: &str, token: Option<&str>) -> NodeConfig {
NodeConfig {
name: "test".into(),
url: url.into(),
token: token.map(String::from),
default: false,
}
}
#[test]
fn from_node_strips_trailing_slash() {
let c = ApiClient::from_node(&node("http://localhost:1633/", None)).unwrap();
assert_eq!(c.url, "http://localhost:1633");
assert!(!c.authenticated);
}
#[test]
fn from_node_with_token_marks_authenticated() {
let c = ApiClient::from_node(&node("http://localhost:1633", Some("dummy-jwt"))).unwrap();
assert!(c.authenticated);
}
#[test]
fn from_node_rejects_bogus_url() {
let err = ApiClient::from_node(&node("not a url", None)).unwrap_err();
assert!(format!("{err}").contains("invalid"));
}
}