use super::*;
use crate::cli_outbound::Cli;
use serde_json::json;
use tempfile::tempdir;
#[test]
fn a_wire_client_enumerates_only_its_registrations() {
let root = tempdir().unwrap();
let data = tempdir().unwrap();
let ctx = over(
root.path(),
world_of(data.path(), &["home", "corp"]),
data.path().to_path_buf(),
Cli::new("/no/such/litany"),
);
let phone = seat("phone");
crate::registry::register(root.path(), &phone.client, "home").unwrap();
let reply = ctx.answer_as(&phone, &json!({"op": "workspaces"}));
assert_eq!(listed(&reply), ["home".to_owned()]);
assert_eq!(
listed(&ctx.answer(&json!({"op": "workspaces"}))),
["corp".to_owned(), "home".to_owned()]
);
assert!(listed(&ctx.answer_as(&seat("stranger"), &json!({"op": "workspaces"}))).is_empty());
}
#[test]
fn an_unregistered_workspace_refuses_exactly_as_an_unknown_one() {
let root = tempdir().unwrap();
let data = tempdir().unwrap();
let ctx = over(
root.path(),
world_of(data.path(), &["home", "corp"]),
data.path().to_path_buf(),
Cli::new("/no/such/litany"),
);
let phone = seat("phone");
crate::registry::register(root.path(), &phone.client, "home").unwrap();
let hidden = ctx.answer_as(&phone, &json!({"op": "conversations", "workspace": "corp"}));
let absent = ctx.answer_as(
&phone,
&json!({"op": "conversations", "workspace": "corp2"}),
);
assert_eq!(hidden["ok"], false);
assert_eq!(hidden["error"], "unknown workspace \"corp\" — known: home");
assert_eq!(absent["error"], "unknown workspace \"corp2\" — known: home");
assert_eq!(
ctx.answer_as(&phone, &json!({"op": "conversations", "workspace": "home"}))["ok"],
true
);
}
#[test]
fn a_torn_envelope_refuses_over_the_wire_too() {
let root = tempdir().unwrap();
let refusal = ctx(root.path()).answer_as(&seat("phone"), &json!({"op": "enhance"}));
assert_eq!(refusal["ok"], false);
assert!(
refusal["error"]
.as_str()
.unwrap_or_default()
.contains("enhance")
);
}
#[test]
fn a_workspace_created_over_the_wire_registers_its_creator() {
let root = tempdir().unwrap();
let data = tempdir().unwrap();
let bin = tempdir().unwrap();
seed(data.path());
let ctx = over(
root.path(),
world_of(data.path(), &[]),
data.path().to_path_buf(),
fake_litany(bin.path()),
);
let phone = seat("phone");
let reply = ctx.answer_as(
&phone,
&json!({"op": "prepare", "workspace": "fresh", "payload": {"rung": "bare"}}),
);
assert_eq!(reply["kind"], "prepared", "{reply}");
assert!(
crate::binding::workspace_path(data.path(), "fresh").is_dir(),
"the raise founded it under yog's flat names root"
);
assert_eq!(
crate::registry::registered(root.path(), &phone.client),
std::collections::BTreeSet::from(["fresh".to_owned()])
);
assert!(crate::registry::registered(root.path(), &client("laptop")).is_empty());
}
#[test]
fn a_create_naming_a_workspace_that_exists_refuses_rather_than_joining_it() {
let root = tempdir().unwrap();
let data = tempdir().unwrap();
let bin = tempdir().unwrap();
seed(data.path());
let taken = crate::binding::workspace_path(data.path(), "corp");
std::fs::create_dir_all(&taken).unwrap();
let ctx = over(
root.path(),
world_of(data.path(), &["corp"]),
data.path().to_path_buf(),
fake_litany(bin.path()),
);
let phone = seat("phone");
let refusal = ctx.answer_as(
&phone,
&json!({"op": "prepare", "workspace": "corp", "payload": {"rung": "bare"}}),
);
assert_eq!(refusal["ok"], false);
assert_eq!(
refusal["error"],
"unknown workspace \"corp\" — none is enumerated here"
);
assert!(crate::registry::registered(root.path(), &phone.client).is_empty());
}
#[test]
fn a_raise_naming_something_that_is_not_a_plain_component_refuses() {
let root = tempdir().unwrap();
let data = tempdir().unwrap();
let ctx = over(
root.path(),
world_of(data.path(), &[]),
data.path().to_path_buf(),
Cli::new("/no/such/litany"),
);
for name in ["../elsewhere", ".."] {
let refusal = ctx.answer_as(
&seat("phone"),
&json!({"op": "prepare", "workspace": name, "payload": {"rung": "bare"}}),
);
assert_eq!(refusal["ok"], false, "{name}");
assert_eq!(
refusal["error"],
format!("unknown workspace {name:?} — none is enumerated here")
);
}
assert!(crate::registry::registered(root.path(), &client("phone")).is_empty());
}
#[test]
fn a_client_registered_nowhere_is_told_so_rather_than_answered_empty() {
let root = tempdir().unwrap();
let data = tempdir().unwrap();
let ctx = over(
root.path(),
world_of(data.path(), &["home"]),
data.path().to_path_buf(),
Cli::new("/no/such/litany"),
);
let stranger = seat("stranger");
for gesture in [json!({"op": "workspaces"}), json!({"op": "attention"})] {
let refusal = ctx.answer_as(&stranger, &gesture);
assert_eq!(refusal["ok"], false, "{refusal}");
let said = refusal["error"].as_str().unwrap_or_default();
assert!(said.contains("registered in no workspace"), "{said}");
assert!(said.contains("/enroll stranger"), "{said}");
assert!(!said.contains("home"), "it names no workspace: {said}");
}
crate::registry::register(root.path(), &stranger.client, "elsewhere").unwrap();
let listed = ctx.answer_as(&stranger, &json!({"op": "workspaces"}));
assert_eq!(listed["kind"], "workspaces", "{listed}");
assert!(
listed_is_empty(&listed),
"and it enumerates nothing it may not see"
);
}
#[test]
fn an_unregistered_client_may_still_found_a_workspace() {
let (root, data, bin) = (tempdir().unwrap(), tempdir().unwrap(), tempdir().unwrap());
seed(data.path());
let ctx = over(
root.path(),
world_of(data.path(), &[]),
data.path().to_path_buf(),
fake_litany(bin.path()),
);
let fresh = seat("fresh");
let born = ctx.answer_as(
&fresh,
&json!({"op": "prepare", "workspace": "home", "payload": {"rung": "bare"}}),
);
assert_eq!(born["kind"], "prepared", "{born}");
assert!(
crate::registry::registered(root.path(), &fresh.client).contains("home"),
"and founding it seated the founder"
);
assert_eq!(
ctx.answer_as(&fresh, &json!({"op": "workspaces"}))["kind"],
"workspaces",
"so the next gesture is answered rather than refused"
);
}
fn listed_is_empty(reply: &serde_json::Value) -> bool {
reply["rows"].as_array().is_some_and(Vec::is_empty)
}