tests/presence: test_presence_leave_msn
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
parent
a86a85cf19
commit
b0fe077449
3 changed files with 90 additions and 5 deletions
|
@ -42,6 +42,12 @@ impl Occupant {
|
|||
})
|
||||
}
|
||||
|
||||
/// Return the primary session used in MSN context
|
||||
// TODO: Criteria for primary session may change later on.
|
||||
pub fn get_primary_session(&self) -> &Session {
|
||||
&self.sessions[0]
|
||||
}
|
||||
|
||||
/// Add a new session to the occupant
|
||||
pub fn add_session(&mut self, presence: Presence) -> Result<(), Error> {
|
||||
let new_session = Session::try_from(presence)?;
|
||||
|
|
17
src/room.rs
17
src/room.rs
|
@ -77,6 +77,7 @@ impl Room {
|
|||
let update = matches!(mode, BroadcastPresence::Join | BroadcastPresence::Update);
|
||||
|
||||
let own_session = Session::try_from(presence)?;
|
||||
let own_session_is_primary = own_occupant.get_primary_session() == &own_session;
|
||||
|
||||
// All participants to new participant
|
||||
let presence_to_new = Presence::new(if leave {
|
||||
|
@ -126,6 +127,11 @@ impl Room {
|
|||
if session.real == own_session.real {
|
||||
continue;
|
||||
}
|
||||
// If own_session is leaving, and it is not the primary
|
||||
// session, don't advertize the leave.
|
||||
if leave && !own_session_is_primary {
|
||||
continue;
|
||||
}
|
||||
|
||||
let presence = presence_to_old
|
||||
.clone()
|
||||
|
@ -140,7 +146,11 @@ impl Room {
|
|||
.iter()
|
||||
.map(|session| MucItem {
|
||||
affiliation: Affiliation::Owner,
|
||||
role: if leave { Role::None } else { Role::Moderator },
|
||||
role: if leave && session == &own_session {
|
||||
Role::None
|
||||
} else {
|
||||
Role::Moderator
|
||||
},
|
||||
jid: Some(session.real.clone()),
|
||||
nick: None,
|
||||
actor: None,
|
||||
|
@ -338,6 +348,11 @@ impl Room {
|
|||
.await?;
|
||||
|
||||
occupant.remove_session(session.presence)?;
|
||||
if occupant.iter().len() > 0 {
|
||||
let _ = self
|
||||
.occupants
|
||||
.insert(session.participant.resource.clone(), occupant);
|
||||
}
|
||||
} else {
|
||||
// TODO: Error
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@ use crate::component::TestComponent;
|
|||
use crate::handlers::handle_stanza;
|
||||
use crate::room::Room;
|
||||
use crate::tests::templates::{
|
||||
two_participant_room, LOUISE_FULL1, LOUISE_FULL2, LOUISE_NICK, LOUISE_ROOM1_PART, ROOM1_BARE,
|
||||
ROSA_FULL1, ROSA_ROOM1_PART, SUGAKO_FULL1, SUGAKO_ROOM1_PART,
|
||||
new_room, two_participant_room, LOUISE_FULL1, LOUISE_FULL2, LOUISE_NICK, LOUISE_ROOM1_PART,
|
||||
ROOM1_BARE, ROSA_FULL1, ROSA_ROOM1_PART, SUGAKO_FULL1, SUGAKO_NICK, SUGAKO_ROOM1_PART,
|
||||
};
|
||||
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
|
@ -669,9 +669,73 @@ async fn test_presence_update_not_joined() {
|
|||
handle_stanza(&mut component, &mut rooms).await.unwrap();
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[tokio::test]
|
||||
async fn test_presence_leave_msn() {
|
||||
// Ensure the occupant is still valid even though a first session left
|
||||
todo!()
|
||||
|
||||
let leave: Element = Presence::new(PresenceType::Unavailable)
|
||||
.with_from(Jid::Full(LOUISE_FULL2.clone())) // Not the first session
|
||||
.with_to(Jid::Full(LOUISE_ROOM1_PART.clone()))
|
||||
.into();
|
||||
|
||||
let mut component = TestComponent::new(vec![leave]);
|
||||
let mut rooms: HashMap<BareJid, Room> = HashMap::new();
|
||||
rooms.insert(
|
||||
ROOM1_BARE.clone(),
|
||||
new_room(
|
||||
ROOM1_BARE.clone(),
|
||||
vec![
|
||||
(LOUISE_FULL1.clone(), LOUISE_NICK),
|
||||
(SUGAKO_FULL1.clone(), SUGAKO_NICK),
|
||||
(LOUISE_FULL2.clone(), LOUISE_NICK),
|
||||
],
|
||||
)
|
||||
.await,
|
||||
);
|
||||
|
||||
// 110 to the leaving session
|
||||
component.expect(
|
||||
Presence::new(PresenceType::Unavailable)
|
||||
.with_from(Jid::Full(LOUISE_ROOM1_PART.clone()))
|
||||
.with_to(Jid::Full(LOUISE_FULL2.clone()))
|
||||
.with_payloads(vec![MucUser {
|
||||
status: vec![MucStatus::SelfPresence],
|
||||
items: {
|
||||
let mut item1 = MucItem::new(Affiliation::Owner, Role::Moderator);
|
||||
item1.jid = Some(LOUISE_FULL1.clone());
|
||||
let mut item2 = MucItem::new(Affiliation::Owner, Role::None);
|
||||
item2.jid = Some(LOUISE_FULL2.clone());
|
||||
vec![item1, item2]
|
||||
},
|
||||
}
|
||||
.into()]),
|
||||
);
|
||||
|
||||
// Unavailable presence to the other MSN session with @jid of the leaving session
|
||||
component.expect(
|
||||
Presence::new(PresenceType::Unavailable)
|
||||
.with_from(Jid::Full(LOUISE_ROOM1_PART.clone()))
|
||||
.with_to(Jid::Full(LOUISE_FULL1.clone()))
|
||||
.with_payloads(vec![MucUser {
|
||||
status: vec![],
|
||||
items: {
|
||||
let mut item1 = MucItem::new(Affiliation::Owner, Role::Moderator);
|
||||
item1.jid = Some(LOUISE_FULL1.clone());
|
||||
let mut item2 = MucItem::new(Affiliation::Owner, Role::None);
|
||||
item2.jid = Some(LOUISE_FULL2.clone());
|
||||
vec![item1, item2]
|
||||
},
|
||||
}
|
||||
.into()]),
|
||||
);
|
||||
|
||||
// Presence update to other participants is not necessary as the main session (LOUISE_FULL1) is
|
||||
// still alive
|
||||
|
||||
handle_stanza(&mut component, &mut rooms).await.unwrap();
|
||||
|
||||
let occupants = &rooms.get(&ROOM1_BARE).unwrap().occupants;
|
||||
let louise = occupants.get(LOUISE_NICK);
|
||||
assert!(louise.is_some());
|
||||
assert_eq!(louise.unwrap().sessions.len(), 1);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue