Add test_0045_join_presence_nick_already_assigned

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2022-09-11 10:50:56 +02:00
parent f86ca3fa66
commit afd1f23ac3
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2
3 changed files with 78 additions and 6 deletions

View file

@ -28,7 +28,7 @@ use xmpp_parsers::{
message::Message,
muc::Muc,
ns,
presence::Presence,
presence::{Presence, Type as PresenceType},
stanza_error::{DefinedCondition, ErrorType, StanzaError},
BareJid, Element, Jid,
};
@ -128,7 +128,24 @@ async fn handle_presence<C: ComponentTrait>(
// Room already exists
if let Some(room) = rooms.get_mut(&roomjid) {
debug!("Presence received to existing room: {}", &roomjid);
room.add_session(component, realjid, nick).await.unwrap();
match room.add_session(component, realjid.clone(), nick).await {
Ok(_) => (),
Err(Error::NickAlreadyAssigned(nick)) => {
let error = Presence::new(PresenceType::Error)
.with_from(participant)
.with_to(realjid)
.with_payloads(vec![
StanzaError::new(
ErrorType::Cancel,
DefinedCondition::Conflict,
"en",
format!("Nickname conflict: {}", nick),
).into()
]);
component.send_stanza(error).await?;
},
err => err.unwrap(),
}
} else {
debug!("Presence received to new room: {}", &roomjid);
let mut room = Room::new(roomjid.clone());

View file

@ -83,7 +83,7 @@ impl Room {
// Add into occupants
let _ = self
.occupants
.insert(bare.clone(), Occupant::new(realjid.clone()));
.insert(bare.clone(), Occupant::new(realjid.clone(), nick.clone()));
// Self-presence
debug!("Sending self-presence for {}", realjid);
@ -125,10 +125,10 @@ pub struct Occupant {
}
impl Occupant {
fn new(fulljid: FullJid) -> Occupant {
fn new(fulljid: FullJid, nick: Nick) -> Occupant {
Occupant {
jid: BareJid::from(fulljid.clone()),
nick: fulljid.resource.clone(),
nick,
sessions: vec![fulljid],
}
}
@ -166,7 +166,7 @@ mod tests {
#[test]
fn occupant_ignore_dup_session() {
let fulljid = FullJid::from_str("foo@bar/meh").unwrap();
let mut occupant = Occupant::new(fulljid.clone());
let mut occupant = Occupant::new(fulljid.clone(), String::from("nick"));
occupant.add_session(fulljid.clone()).unwrap();
assert_eq!(occupant.iter().count(), 1);
}

View file

@ -146,3 +146,58 @@ async fn test_0045_join_presence_empty_room() {
None => panic!(),
}
}
#[tokio::test]
async fn test_0045_join_presence_nick_already_assigned() {
let nick = "nick";
let realjid1 = FullJid::from_str("foo@bar/qxx").unwrap();
let realjid2 = FullJid::from_str("qxx@bar/foo").unwrap();
let participant = COMPONENT_JID
.clone()
.with_node("room")
.with_resource(nick.clone());
let roomjid = COMPONENT_JID.clone().with_node("room");
// <x xmlns='http://jabber.org/protocol/muc'/>
let join1: Element = Presence::new(PresenceType::None)
.with_from(Jid::Full(realjid1.clone()))
.with_to(Jid::Full(participant.clone()))
.with_payloads(vec![Muc::new().into()])
.into();
let join2: Element = Presence::new(PresenceType::None)
.with_from(Jid::Full(realjid2.clone()))
.with_to(Jid::Full(participant.clone())) // Same participant JID
.with_payloads(vec![Muc::new().into()])
.into();
let mut component = TestComponent::new(vec![join1, join2]);
let mut rooms: HashMap<BareJid, Room> = HashMap::new();
// Ignore self-presence for first participant
component.expect_with(|_| ());
// Ignore message subject for first participant
component.expect_with(|_| ());
component.expect(
Presence::new(PresenceType::Error)
.with_from(participant)
.with_to(realjid2)
.with_payloads(vec![StanzaError::new(
ErrorType::Cancel,
DefinedCondition::Conflict,
"en",
format!("Nickname conflict: {}", nick),
)
.into()]),
);
handle_stanza(&mut component, &mut rooms).await.unwrap();
component.assert();
match rooms.get(&roomjid) {
Some(_) => (),
None => panic!(),
}
}