|
| 1 | +use clap::{App, SubCommand}; |
| 2 | +use masq_lib::{as_any_ref_in_trait_impl, short_writeln}; |
| 3 | + |
| 4 | +use crate::command_context::CommandContext; |
| 5 | +use crate::commands::commands_common::CommandError::Payload; |
| 6 | +use crate::commands::commands_common::{ |
| 7 | + transaction, Command, CommandError, STANDARD_COMMAND_TIMEOUT_MILLIS, |
| 8 | +}; |
| 9 | +use masq_lib::messages::{UiGetNeighborhoodGraphRequest, UiGetNeighborhoodGraphResponse}; |
| 10 | + |
| 11 | +const NEIGHBORHOOD_GRAPH_HELP: &str = "Use this command plainly, without any flags or arguments. The result will be delivered in digraph format, documentation at https://graphviz.org/documentation/"; |
| 12 | + |
| 13 | +pub fn get_neighborhood_graph_subcommand() -> App<'static, 'static> { |
| 14 | + SubCommand::with_name("neighborhood-graph").about(NEIGHBORHOOD_GRAPH_HELP) |
| 15 | +} |
| 16 | + |
| 17 | +#[derive(Debug, PartialEq, Eq)] |
| 18 | +pub struct GetNeighborhoodGraphCommand {} |
| 19 | + |
| 20 | +impl GetNeighborhoodGraphCommand { |
| 21 | + pub fn new(pieces: &[String]) -> Result<Self, String> { |
| 22 | + match get_neighborhood_graph_subcommand().get_matches_from_safe(pieces) { |
| 23 | + Ok(_) => Ok(GetNeighborhoodGraphCommand {}), |
| 24 | + Err(e) => Err(format!("GetNeighborhoodGraphCommand {}", e)), |
| 25 | + } |
| 26 | + } |
| 27 | +} |
| 28 | + |
| 29 | +impl Command for GetNeighborhoodGraphCommand { |
| 30 | + fn execute(&self, context: &mut dyn CommandContext) -> Result<(), CommandError> { |
| 31 | + let input = UiGetNeighborhoodGraphRequest {}; |
| 32 | + let output: Result<UiGetNeighborhoodGraphResponse, CommandError> = |
| 33 | + transaction(input, context, STANDARD_COMMAND_TIMEOUT_MILLIS); |
| 34 | + match output { |
| 35 | + Ok(neighborhood_graph) => { |
| 36 | + short_writeln!( |
| 37 | + context.stdout(), |
| 38 | + "Graph of the Node's neighborhood database: {}", |
| 39 | + neighborhood_graph.graph.as_str() |
| 40 | + ); |
| 41 | + Ok(()) |
| 42 | + } |
| 43 | + Err(Payload(code, message)) => { |
| 44 | + short_writeln!(context.stderr(), "code: {}\nmessage: {}", code, message); |
| 45 | + Err(Payload(code, message)) |
| 46 | + } |
| 47 | + Err(err) => { |
| 48 | + short_writeln!(context.stderr(), "Error: {}", err); |
| 49 | + Err(err) |
| 50 | + } |
| 51 | + } |
| 52 | + } |
| 53 | + |
| 54 | + as_any_ref_in_trait_impl!(); |
| 55 | +} |
| 56 | + |
| 57 | +#[cfg(test)] |
| 58 | +pub mod tests { |
| 59 | + use super::*; |
| 60 | + use crate::test_utils::mocks::CommandContextMock; |
| 61 | + use masq_lib::messages::ToMessageBody; |
| 62 | + use std::sync::{Arc, Mutex}; |
| 63 | + |
| 64 | + #[test] |
| 65 | + fn can_deserialize_ui_get_neighborhood_graph() { |
| 66 | + let transact_params_arc = Arc::new(Mutex::new(vec![])); |
| 67 | + let mut context = CommandContextMock::new() |
| 68 | + .transact_params(&transact_params_arc) |
| 69 | + .transact_result(Ok(UiGetNeighborhoodGraphResponse { |
| 70 | + graph: "digraph db { \"AQIDBA\" [label=\"AR v0 AU\\nAQIDBA\\n1.2.3.4:1234\"]; \"HZ5vwwJPhfUZVy85E76GZUUam9SMgyaw+QaZvAMuizo\" [label=\"AR v0 ZZ\\nHZ5vwwJP\\n9.9.9.9:9999\"] [style=filled]; \"AgMEBQ\" [label=\"AR v0 FR\\nAgMEBQ\\n2.3.4.5:2345\"]; \"AwQFBg\" [label=\"AR v0 CN\\nAwQFBg\\n3.4.5.6:3456\"]; \"BAUGBw\" [label=\"AR v0 US\\nBAUGBw\\n4.5.6.7:4567\"]; \"AQIDBA\" -> \"HZ5vwwJPhfUZVy85E76GZUUam9SMgyaw+QaZvAMuizo\"; \"AQIDBA\" -> \"AgMEBQ\"; \"HZ5vwwJPhfUZVy85E76GZUUam9SMgyaw+QaZvAMuizo\" -> \"AQIDBA\"; \"AgMEBQ\" -> \"AwQFBg\"; \"AgMEBQ\" -> \"AQIDBA\"; \"AwQFBg\" -> \"BAUGBw\"; \"AwQFBg\" -> \"AgMEBQ\"; \"BAUGBw\" -> \"AwQFBg\"; }".to_string() |
| 71 | + }.tmb(0))); |
| 72 | + let stderr_arc = context.stderr_arc(); |
| 73 | + let stdout_arc = context.stdout_arc(); |
| 74 | + let subject = |
| 75 | + GetNeighborhoodGraphCommand::new(&["neighborhood-graph".to_string()]).unwrap(); |
| 76 | + |
| 77 | + let result = subject.execute(&mut context); |
| 78 | + |
| 79 | + assert_eq!(result, Ok(())); |
| 80 | + let expected_request = UiGetNeighborhoodGraphRequest {}; |
| 81 | + let transact_params = transact_params_arc.lock().unwrap(); |
| 82 | + let expected_message_body = expected_request.tmb(0); |
| 83 | + assert_eq!( |
| 84 | + transact_params.as_slice(), |
| 85 | + &[(expected_message_body, STANDARD_COMMAND_TIMEOUT_MILLIS)] |
| 86 | + ); |
| 87 | + let stdout = stdout_arc.lock().unwrap(); |
| 88 | + let graph_str = "Graph of the Node's neighborhood database: digraph db { \"AQIDBA\" [label=\"AR v0 AU\\nAQIDBA\\n1.2.3.4:1234\"]; \"HZ5vwwJPhfUZVy85E76GZUUam9SMgyaw+QaZvAMuizo\" [label=\"AR v0 ZZ\\nHZ5vwwJP\\n9.9.9.9:9999\"] [style=filled]; \"AgMEBQ\" [label=\"AR v0 FR\\nAgMEBQ\\n2.3.4.5:2345\"]; \"AwQFBg\" [label=\"AR v0 CN\\nAwQFBg\\n3.4.5.6:3456\"]; \"BAUGBw\" [label=\"AR v0 US\\nBAUGBw\\n4.5.6.7:4567\"]; \"AQIDBA\" -> \"HZ5vwwJPhfUZVy85E76GZUUam9SMgyaw+QaZvAMuizo\"; \"AQIDBA\" -> \"AgMEBQ\"; \"HZ5vwwJPhfUZVy85E76GZUUam9SMgyaw+QaZvAMuizo\" -> \"AQIDBA\"; \"AgMEBQ\" -> \"AwQFBg\"; \"AgMEBQ\" -> \"AQIDBA\"; \"AwQFBg\" -> \"BAUGBw\"; \"AwQFBg\" -> \"AgMEBQ\"; \"BAUGBw\" -> \"AwQFBg\"; }\n"; |
| 89 | + assert_eq!(&stdout.get_string(), graph_str); |
| 90 | + let stderr = stderr_arc.lock().unwrap(); |
| 91 | + assert_eq!(&stderr.get_string(), ""); |
| 92 | + } |
| 93 | +} |
0 commit comments