use super::super::tick;
use super::asking;
use crate::test_support::Scratch;
use crate::test_support::wire::{entry, flat, wired};
use crate::ui::Model;
use serde_json::json;
#[test]
fn every_channel_is_asked_for_its_own_roster_and_stamped_with_it() {
let scratch = Scratch::new();
let roster = |name: &str| {
json!({"ok": true, "kind": "workspaces",
"rows": [{"workspace": name, "kind": "named", "attention": 0,
"agents": 1, "running": false}]})
};
wired(&scratch, &flat(), vec![vec![roster("here")]]);
wired(&scratch, &entry("home"), vec![vec![roster("personal")]]);
let model = Model {
roster: crate::seat::channels(scratch.path()),
..Model::default()
};
let link = asking(&model);
tick(&link, scratch.path());
let mut settled = model.clone();
link.settle(&mut settled);
let seen: Vec<(String, String)> = settled
.roster
.iter()
.map(|chunk| {
(
chunk.channel.name.clone(),
chunk
.walls
.first()
.map(|row| row.workspace.clone())
.unwrap_or_default(),
)
})
.collect();
assert_eq!(
seen,
vec![
(crate::seat::OWN.to_owned(), "here".to_owned()),
("home".to_owned(), "personal".to_owned()),
]
);
}
#[test]
fn a_channel_that_will_not_answer_leaves_the_others_standing() {
let scratch = Scratch::new();
wired(
&scratch,
&flat(),
vec![vec![json!({"ok": true, "kind": "workspaces", "rows": []})]],
);
std::fs::create_dir_all(scratch.path().join(entry("hollow"))).expect("mkdir");
let model = Model {
roster: crate::seat::channels(scratch.path()),
..Model::default()
};
let link = asking(&model);
tick(&link, scratch.path());
let mut settled = model.clone();
link.settle(&mut settled);
assert_eq!(settled.roster.len(), 2);
let hollow = settled
.roster
.iter()
.find(|chunk| chunk.channel.name == "hollow")
.expect("the entry has a section");
let crate::ui::Held::Unheld(why) = &hollow.held else {
panic!("the hollow entry said nothing: {:?}", hollow.held);
};
assert!(why.contains("empty entry"), "{why}");
assert_eq!(settled.notice, None, "and nothing reached the shell's bar");
}
#[test]
fn the_trail_read_stands_only_while_its_pane_is_open_and_goes_down_every_channel() {
let scratch = Scratch::new();
let engine = wired(
&scratch,
&flat(),
vec![
vec![json!({"ok": true, "kind": "workspaces", "rows": []})],
vec![json!({"ok": true, "kind": "workspaces", "rows": []})],
vec![json!({"ok": true, "kind": "ops", "rows": []})],
],
);
let own = crate::ui::Channel {
name: crate::seat::OWN.to_owned(),
named_there: None,
dials: None,
};
let mut model = Model {
roster: vec![crate::ui::Chunk::of(own)],
..Model::default()
};
let link = asking(&model);
tick(&link, scratch.path());
model.begin_trail();
link.settle(&mut model);
tick(&link, scratch.path());
let asked: Vec<serde_json::Value> = engine.heard();
let ops: Vec<String> = asked
.iter()
.filter_map(|said| said.get("op").and_then(serde_json::Value::as_str))
.map(str::to_owned)
.collect();
assert_eq!(ops, vec!["workspaces", "workspaces", "ops"]);
let read = asked
.iter()
.find(|said| said.get("op").and_then(serde_json::Value::as_str) == Some("ops"))
.expect("the trail was asked for");
assert_eq!(
read.get("max").and_then(serde_json::Value::as_u64),
Some(crate::verbs::DEPTH)
);
link.settle(&mut model);
assert_eq!(model.trails.len(), 1, "the answer is filed by channel");
}