use rust_xmpp::{muc::Muc, protocol::ModuleResult};
use serde_json::json;
fn send(m: &mut Muc, who: &str, packet: &str) -> ModuleResult {
let doc = roxmltree::Document::parse(packet).unwrap();
m.handle(who, doc.root_element()).unwrap().unwrap()
}
fn join(m: &mut Muc, who: &str, nick: &str) -> ModuleResult {
send(
m,
who,
&format!(
""
),
)
}
#[test]
fn probes_and_invalid_presence_cannot_join_or_rename() {
let dir = tempfile::tempdir().unwrap();
let mut m = Muc::new(dir.path().into(), "rooms.test".into());
m.set_component_options(serde_json::json!({"muc_room_locking":false}), false);
assert!(
send(
&mut m,
"alice@test/r",
""
)
.replies[0]
.contains("item-not-found")
);
join(&mut m, "alice@test/r", "Alice");
assert!(
send(
&mut m,
"bob@test/r",
""
)
.replies[0]
.contains("not-acceptable")
);
assert!(
send(
&mut m,
"bob@test/r",
""
)
.replies[0]
.contains("bad-request")
);
let probe = send(
&mut m,
"alice@test/r",
"",
);
assert!(probe.replies[0].contains("role='moderator'"));
assert!(probe.deliveries.is_empty());
assert!(
send(
&mut m,
"alice@test/r",
""
)
.replies
.is_empty()
);
}
#[test]
fn error_messages_kick_only_on_delivery_failure_and_presence_errors_kick() {
let dir = tempfile::tempdir().unwrap();
let mut m = Muc::new(dir.path().into(), "rooms.test".into());
m.set_component_options(serde_json::json!({"muc_room_locking":false}), false);
join(&mut m, "alice@test/r", "Alice");
join(&mut m, "bob@test/r", "Bob");
let denied = send(
&mut m,
"bob@test/r",
"",
);
assert!(denied.replies.is_empty() && denied.deliveries.is_empty());
let forwarded = send(
&mut m,
"bob@test/r",
"",
);
assert_eq!(forwarded.deliveries.len(), 1);
assert!(forwarded.deliveries[0].1.contains("type='error'"));
let kicked = send(
&mut m,
"bob@test/r",
"",
);
assert!(
kicked
.deliveries
.iter()
.any(|(_, p)| p.contains("code='333'") && p.contains("Kicked: service unavailable"))
);
join(&mut m, "bob@test/r", "Bob");
let kicked = send(
&mut m,
"bob@test/r",
"",
);
assert!(
kicked
.deliveries
.iter()
.any(|(_, p)| p.contains("code='333'"))
);
}
#[test]
fn room_creation_policies_apply_only_to_new_rooms() {
let dir = tempfile::tempdir().unwrap();
let mut m = Muc::new(dir.path().into(), "rooms.test".into());
m.set_component_options(serde_json::json!({"muc_room_locking":false}), false);
m.set_local_domain("test".into());
m.set_component_options(json!({"muc_room_locking":false,"restrict_room_creation":true,"admins":["admin@test"],"muc_max_rooms":1}), false);
assert!(join(&mut m, "alice@test/r", "Alice").replies[0].contains("not-allowed"));
assert!(
join(&mut m, "admin@test/r", "Admin")
.replies
.iter()
.any(|p| p.contains("code='201'"))
);
assert!(
join(&mut m, "alice@remote/r", "Alice")
.replies
.iter()
.any(|p| p.contains("code='110'"))
);
let full = send(
&mut m,
"admin@test/r",
"",
);
assert!(full.replies[0].contains("resource-constraint"));
m.set_component_options(json!({"restrict_room_creation":"local"}), false);
assert!(send(&mut m, "alice@remote/r", "").replies[0].contains("not-allowed"));
m.set_component_options(json!({}), false);
assert!(send(&mut m, "alice@remote/r", "").replies.iter().any(|p|p.contains("code='201'")));
}
#[test]
fn ordinary_presence_extensions_survive_but_client_identity_is_filtered() {
let dir = tempfile::tempdir().unwrap();
let mut m = Muc::new(dir.path().into(), "rooms.test".into());
m.set_component_options(serde_json::json!({"muc_room_locking":false}), false);
join(&mut m, "alice@test/r", "Alice");
let result = send(
&mut m,
"bob@test/r",
"",
);
let p = &result.deliveries[0].1;
assert!(p.contains("http://jabber.org/protocol/caps") && p.contains("urn:xmpp:idle:1"));
assert!(!p.contains("forged"));
}
#[test]
fn subject_with_body_remains_an_ordinary_groupchat_message() {
let dir = tempfile::tempdir().unwrap();
let mut m = Muc::new(dir.path().into(), "rooms.test".into());
m.set_component_options(json!({"muc_room_locking":false}), false);
join(&mut m, "alice@test/r", "Alice");
join(&mut m, "bob@test/r", "Bob");
let ordinary = send(
&mut m,
"bob@test/r",
"HeadingMessage text",
);
assert!(ordinary.replies.is_empty());
assert_eq!(ordinary.deliveries.len(), 2);
let subject = send(
&mut m,
"bob@test/r",
"Room title",
);
assert!(subject.replies[0].contains("forbidden"));
}