use ratatui::crossterm::event::KeyCode;
use super::*;
use crate::tui::api::ApiCall;
use crate::tui::effect::Effect;
use crate::tui::i18n::Lang;
use crate::tui::model::{ClusterView, Modal, Pane, TopicTab};
use crate::tui::testing::*;
fn menu_of(sim: &Sim) -> Menu {
match &sim.m.modal {
Some(Modal::Menu(menu)) => menu.clone(),
other => panic!("no menu: {other:?}"),
}
}
#[test]
fn enter_on_a_topic_lists_what_can_be_done_to_it_and_to_its_messages() {
let mut sim = Sim::on_topics(Lang::EnUs);
sim.press('j');
sim.code(KeyCode::Enter);
let menu = menu_of(&sim);
assert_eq!(menu.title, "Topic orders");
assert_eq!(menu.items, TOPIC.to_vec());
let tx = sim.m.tx();
assert_eq!(tx.t(label_key(Action::TopicEdit)), "Edit the topic");
assert_eq!(tx.t(label_key(Action::MsgPublish)), "Publish a message");
assert_eq!(shortcut(Tab::Topics, Action::TopicCharts), Some("g"));
assert_eq!(shortcut(Tab::Topics, Action::MsgPublish), None);
sim.code(KeyCode::Esc);
assert!(sim.m.modal.is_none());
}
#[test]
fn the_charts_and_the_messages_open_from_the_menu_as_dialogs_and_esc_returns_to_the_list() {
let mut sim = Sim::on_topics(Lang::EnUs);
sim.press('j');
sim.code(KeyCode::Enter);
sim.code(KeyCode::Down);
sim.code(KeyCode::Enter);
let open = sim.m.topics.monitor.clone().expect("the charts are open");
assert_eq!((open.name.as_str(), open.tab), ("orders", TopicTab::Charts));
assert!(sim.m.modal.is_none());
sim.code(KeyCode::Esc);
assert!(sim.m.topics.monitor.is_none());
assert!(!TOPIC.contains(&Action::TopicMessages));
sim.press('g');
assert_eq!(sim.m.topics.monitor.as_ref().unwrap().tab, TopicTab::Charts);
sim.code(KeyCode::Esc);
sim.press('x');
assert_eq!(
sim.m.topics.monitor.as_ref().unwrap().tab,
TopicTab::Messages
);
}
#[test]
fn publishing_from_the_menu_opens_the_messages_and_the_form() {
let mut sim = Sim::on_topics(Lang::EnUs);
sim.press('j');
sim.code(KeyCode::Enter);
for _ in 0..2 {
sim.code(KeyCode::Down);
}
assert_eq!(
menu_of(&sim).items[menu_of(&sim).selected],
Action::MsgPublish
);
sim.code(KeyCode::Enter);
assert!(sim.m.topics.monitor.is_some());
assert!(
matches!(sim.m.modal, Some(Modal::Editor(_))),
"{:?}",
sim.m.modal
);
}
#[test]
fn an_entry_that_cannot_run_says_why_and_the_menu_closes() {
let mut sim = Sim::on_topics(Lang::EnUs);
sim.code(KeyCode::Enter);
assert_eq!(menu_of(&sim).title, "Topic fanout");
assert_eq!(
gate(&sim.m, Action::TopicCharts),
Some("gate.topic-no-charts")
);
assert_eq!(
gate(&sim.m, Action::MsgReceive),
Some("gate.topic-no-receive")
);
sim.code(KeyCode::Down);
sim.code(KeyCode::Enter);
assert!(sim.m.modal.is_none());
assert!(sim.m.topics.monitor.is_none());
assert!(sim.m.notice.is_some());
}
#[test]
fn on_the_nodes_the_menu_opens_with_the_detail_and_the_conditions_still_explain_themselves() {
let mut sim = Sim::root_with_status(Lang::EnUs);
sim.m.cluster.pane = Pane::Nodes;
sim.code(KeyCode::Enter);
let menu = menu_of(&sim);
assert_eq!(menu.items[0], Action::Detail);
sim.code(KeyCode::Enter);
assert_eq!(sim.m.cluster.view, ClusterView::Detail);
}
#[test]
fn the_summary_of_a_topic_is_a_dialog_of_its_own_and_the_strip_under_the_list_follows_the_selection(
) {
let mut sim = Sim::on_topics(Lang::EnUs);
sim.press('j');
sim.press('i');
assert_eq!(sim.m.modal, Some(Modal::TopicSummary));
sim.code(KeyCode::Esc);
assert!(sim.m.modal.is_none());
let asked: Vec<_> = sim
.tick(3_000)
.into_iter()
.filter_map(|e| match e {
Effect::Call {
call: ApiCall::TopicDetail(name),
..
} => Some(name),
_ => None,
})
.collect();
assert_eq!(asked, vec!["orders".to_owned()]);
assert_eq!(sim.m.topics.previews.len(), 1);
sim.code(KeyCode::Up);
let asked = sim.tick(9_000);
assert!(!asked.iter().any(|e| matches!(
e,
Effect::Call {
call: ApiCall::TopicDetail(_),
..
}
)));
}