From 2f3511121030932862226ba18db0c9ae197e4388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20=E2=80=9Cpep=E2=80=9D=20Buquet?= Date: Mon, 12 Sep 2022 00:53:29 +0200 Subject: [PATCH] Broadcast new occupant presence to existing occupants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime “pep” Buquet --- src/room.rs | 29 ++++++++++++++--- src/tests.rs | 90 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 80 insertions(+), 39 deletions(-) diff --git a/src/room.rs b/src/room.rs index 1c4aec0..9ad77cb 100644 --- a/src/room.rs +++ b/src/room.rs @@ -78,17 +78,36 @@ impl Room { // Send occupants debug!("Sending occupants for {}", realjid); - let presence = Presence::new(PresenceType::None) + // Other participants to new participant + let presence_to_new = Presence::new(PresenceType::None) // New occupant with a single session .with_to(new_occupant.sessions[0].clone()) .with_payloads(vec![MucUser { status: Vec::new(), items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)], - }.into()]); + } + .into()]); + // New participant to other participants + let presence_to_old = Presence::new(PresenceType::None) + .with_from(Jid::Full(new_occupant.participant.clone())) + .with_payloads(vec![MucUser { + status: Vec::new(), + items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)], + } + .into()]); for (_, occupant) in self.occupants.iter() { - let presence = presence.clone() - .with_from(occupant.participant.clone()); - component.send_stanza(presence).await?; + component + .send_stanza( + presence_to_new + .clone() + .with_from(occupant.participant.clone()), + ) + .await?; + for session in occupant.iter() { + component + .send_stanza(presence_to_old.clone().with_to(session.clone())) + .await?; + } } // Add into occupants diff --git a/src/tests.rs b/src/tests.rs index 6e9ce61..267abce 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -229,26 +229,40 @@ async fn test_join_presence_existing_room() { // Ignore message subject for first participant component.expect_message(|_| ()); - // Occupant presences for participant2 + // Participant1 presence for participant2 component.expect( Presence::new(PresenceType::None) - .with_from(Jid::Full(participant1.clone())) - .with_to(Jid::Full(realjid2.clone())) - .with_payloads(vec![MucUser { - status: Vec::new(), - items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)], - }.into()]) + .with_from(Jid::Full(participant1.clone())) + .with_to(Jid::Full(realjid2.clone())) + .with_payloads(vec![MucUser { + status: Vec::new(), + items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)], + } + .into()]), + ); + + // Participant2 presence for participant1 + component.expect( + Presence::new(PresenceType::None) + .with_from(Jid::Full(participant2.clone())) + .with_to(Jid::Full(realjid1.clone())) + .with_payloads(vec![MucUser { + status: Vec::new(), + items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)], + } + .into()]), ); // self-presence for participant2 component.expect( Presence::new(PresenceType::None) - .with_from(Jid::Full(participant2)) - .with_to(Jid::Full(realjid2.clone())) - .with_payloads(vec![MucUser { - status: vec![MucStatus::SelfPresence, MucStatus::AssignedNick], - items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)], - }.into()]) + .with_from(Jid::Full(participant2)) + .with_to(Jid::Full(realjid2.clone())) + .with_payloads(vec![MucUser { + status: vec![MucStatus::SelfPresence, MucStatus::AssignedNick], + items: vec![MucItem::new(Affiliation::Owner, Role::Moderator)], + } + .into()]), ); // Subject for participant2 @@ -334,13 +348,15 @@ async fn test_leave_last_participant() { // Ignore subject message for participant1 component.expect_message(|_| ()); - component.expect(Presence::new(PresenceType::Unavailable) - .with_from(Jid::Full(participant1.clone())) - .with_to(Jid::Full(realjid1.clone())) - .with_payloads(vec![MucUser { - status: vec![MucStatus::SelfPresence], - items: vec![MucItem::new(Affiliation::Owner, Role::None)], - }.into()]) + component.expect( + Presence::new(PresenceType::Unavailable) + .with_from(Jid::Full(participant1.clone())) + .with_to(Jid::Full(realjid1.clone())) + .with_payloads(vec![MucUser { + status: vec![MucStatus::SelfPresence], + items: vec![MucItem::new(Affiliation::Owner, Role::None)], + } + .into()]), ); handle_stanza(&mut component, &mut rooms).await.unwrap(); @@ -386,25 +402,31 @@ async fn test_leave_room_not_last() { component.expect_presence(|_| ()); // Ignore self-presence for participant2 component.expect_presence(|_| ()); + // Ignore participant2 presence for participant1 + component.expect_presence(|_| ()); // Ignore subject message for participant2 component.expect_message(|_| ()); - component.expect(Presence::new(PresenceType::Unavailable) - .with_from(Jid::Full(participant2.clone())) - .with_to(Jid::Full(realjid2.clone())) - .with_payloads(vec![MucUser { - status: vec![MucStatus::SelfPresence], - items: vec![MucItem::new(Affiliation::Owner, Role::None)], - }.into()]) + component.expect( + Presence::new(PresenceType::Unavailable) + .with_from(Jid::Full(participant2.clone())) + .with_to(Jid::Full(realjid2.clone())) + .with_payloads(vec![MucUser { + status: vec![MucStatus::SelfPresence], + items: vec![MucItem::new(Affiliation::Owner, Role::None)], + } + .into()]), ); - component.expect(Presence::new(PresenceType::Unavailable) - .with_from(Jid::Full(participant2.clone())) - .with_to(Jid::Full(realjid1.clone())) - .with_payloads(vec![MucUser { - status: Vec::new(), - items: vec![MucItem::new(Affiliation::Owner, Role::None)], - }.into()]) + component.expect( + Presence::new(PresenceType::Unavailable) + .with_from(Jid::Full(participant2.clone())) + .with_to(Jid::Full(realjid1.clone())) + .with_payloads(vec![MucUser { + status: Vec::new(), + items: vec![MucItem::new(Affiliation::Owner, Role::None)], + } + .into()]), ); handle_stanza(&mut component, &mut rooms).await.unwrap();