tests/presence: test_presence_leave_msn

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2022-12-23 22:52:45 +01:00
parent a86a85cf19
commit b0fe077449
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2
3 changed files with 90 additions and 5 deletions

View file

@ -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)?;

View file

@ -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
}

View file

@ -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);
}