From 9bd4adc8804c3bae393b58b4ad6185ba0576519e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20=E2=80=9Cpep=E2=80=9D=20Buquet?= Date: Tue, 27 Dec 2022 08:44:29 +0100 Subject: [PATCH] tests/presence: Split MSN tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime “pep” Buquet --- src/tests/mod.rs | 1 + src/tests/presence.rs | 179 +-------------------------------- src/tests/presence_msn.rs | 206 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 210 insertions(+), 176 deletions(-) create mode 100644 src/tests/presence_msn.rs diff --git a/src/tests/mod.rs b/src/tests/mod.rs index c662c1e..33e80a5 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -15,5 +15,6 @@ mod iq; mod presence; +mod presence_msn; #[allow(dead_code)] pub mod templates; diff --git a/src/tests/presence.rs b/src/tests/presence.rs index 604f36b..57f0155 100644 --- a/src/tests/presence.rs +++ b/src/tests/presence.rs @@ -17,9 +17,9 @@ use crate::component::TestComponent; use crate::handlers::handle_stanza; use crate::room::Room; use crate::tests::templates::{ - new_room, two_participant_room, LOUISE_FULL1, LOUISE_FULL2, LOUISE_NICK, LOUISE_ROOM1_PART, - PETER_FULL1, PETER_NICK, PETER_ROOM1_PART, ROOM1_BARE, ROSA_FULL1, ROSA_ROOM1_PART, - SUGAKO_FULL1, SUGAKO_NICK, SUGAKO_ROOM1_PART, + new_room, two_participant_room, LOUISE_FULL1, LOUISE_NICK, LOUISE_ROOM1_PART, PETER_FULL1, + PETER_NICK, PETER_ROOM1_PART, ROOM1_BARE, ROSA_FULL1, ROSA_ROOM1_PART, SUGAKO_FULL1, + SUGAKO_NICK, SUGAKO_ROOM1_PART, }; use std::collections::{BTreeMap, HashMap}; @@ -503,108 +503,6 @@ async fn test_leave_room_not_last() { } } -#[tokio::test] -async fn test_join_msn() { - let join1: Element = Presence::new(PresenceType::None) - .with_from(Jid::Full(LOUISE_FULL1.clone())) - .with_to(Jid::Full(LOUISE_ROOM1_PART.clone())) - .with_payloads(vec![Muc::new().into()]) - .into(); - - let join2: Element = Presence::new(PresenceType::None) - .with_from(Jid::Full(LOUISE_FULL2.clone())) - .with_to(Jid::Full(LOUISE_ROOM1_PART.clone())) - .with_payloads(vec![Muc::new().into()]) - .into(); - - let mut component = TestComponent::new(vec![join1, join2]); - let mut rooms: HashMap = HashMap::new(); - - component.expect( - Presence::new(PresenceType::None) - .with_from(Jid::Full(LOUISE_ROOM1_PART.clone())) - .with_to(Jid::Full(LOUISE_FULL1.clone())) - .with_payloads(vec![MucUser { - status: vec![MucStatus::SelfPresence, MucStatus::AssignedNick], - items: vec![{ - let mut item = MucItem::new(Affiliation::Owner, Role::Moderator); - item.jid = Some(LOUISE_FULL1.clone()); - item - }], - } - .into()]), - ); - - component.expect_message( - Jid::Full(LOUISE_FULL1.clone()), - |_| (), - "Subject message for session1", - ); - - // New session joins - // Participant1 presence for session2 - component.expect( - Presence::new(PresenceType::None) - .with_from(Jid::Full(LOUISE_ROOM1_PART.clone())) - .with_to(Jid::Full(LOUISE_FULL1.clone())) - .with_payloads(vec![MucUser { - status: Vec::new(), - items: { - let item = MucItem::new(Affiliation::Owner, Role::Moderator); - let mut item1 = item.clone(); - item1.jid = Some(LOUISE_FULL1.clone()); - let mut item2 = item.clone(); - item2.jid = Some(LOUISE_FULL2.clone()); - vec![item1, item2] - }, - } - .into()]), - ); - - // Self-presence for session2 - component.expect( - Presence::new(PresenceType::None) - .with_from(Jid::Full(LOUISE_ROOM1_PART.clone())) - .with_to(Jid::Full(LOUISE_FULL2.clone())) - .with_payloads(vec![MucUser { - status: vec![MucStatus::SelfPresence, MucStatus::AssignedNick], - items: { - let item = MucItem::new(Affiliation::Owner, Role::Moderator); - let mut item1 = item.clone(); - item1.jid = Some(LOUISE_FULL1.clone()); - let mut item2 = item.clone(); - item2.jid = Some(LOUISE_FULL2.clone()); - vec![item1, item2] - }, - } - .into()]), - ); - - component.expect_message( - Jid::Full(LOUISE_FULL2.clone()), - |_| (), - "Subject message for session2", - ); - - handle_stanza(&mut component, &mut rooms).await.unwrap(); - - assert_eq!(rooms.len(), 1); - match rooms.get(&ROOM1_BARE) { - Some(room) => { - assert_eq!(room.occupants.len(), 1); - assert_eq!( - room.occupants - .get(&LOUISE_ROOM1_PART.resource) - .unwrap() - .sessions - .len(), - 2 - ); - } - None => panic!(), - } -} - #[tokio::test] async fn test_presence_update_joined() { let mut rooms: HashMap = HashMap::new(); @@ -678,74 +576,3 @@ async fn test_presence_update_not_joined() { handle_stanza(&mut component, &mut rooms).await.unwrap(); } - -#[tokio::test] -async fn test_presence_leave_msn() { - // Ensure the occupant is still valid even though a first session left - - 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 = 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); -} diff --git a/src/tests/presence_msn.rs b/src/tests/presence_msn.rs new file mode 100644 index 0000000..7a75389 --- /dev/null +++ b/src/tests/presence_msn.rs @@ -0,0 +1,206 @@ +// Copyright (C) 2022-2099 The crate authors. +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published by the +// Free Software Foundation, either version 3 of the License, or (at your +// option) any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License +// for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +use crate::component::TestComponent; +use crate::handlers::handle_stanza; +use crate::room::Room; +use crate::tests::templates::{ + new_room, LOUISE_FULL1, LOUISE_FULL2, LOUISE_NICK, LOUISE_ROOM1_PART, ROOM1_BARE, SUGAKO_FULL1, + SUGAKO_NICK, +}; + +use std::collections::HashMap; + +use xmpp_parsers::{ + muc::{ + user::{Affiliation, Item as MucItem, Role, Status as MucStatus}, + Muc, MucUser, + }, + presence::{Presence, Type as PresenceType}, + BareJid, Element, Jid, +}; + +#[tokio::test] +async fn join() { + let join1: Element = Presence::new(PresenceType::None) + .with_from(Jid::Full(LOUISE_FULL1.clone())) + .with_to(Jid::Full(LOUISE_ROOM1_PART.clone())) + .with_payloads(vec![Muc::new().into()]) + .into(); + + let join2: Element = Presence::new(PresenceType::None) + .with_from(Jid::Full(LOUISE_FULL2.clone())) + .with_to(Jid::Full(LOUISE_ROOM1_PART.clone())) + .with_payloads(vec![Muc::new().into()]) + .into(); + + let mut component = TestComponent::new(vec![join1, join2]); + let mut rooms: HashMap = HashMap::new(); + + component.expect( + Presence::new(PresenceType::None) + .with_from(Jid::Full(LOUISE_ROOM1_PART.clone())) + .with_to(Jid::Full(LOUISE_FULL1.clone())) + .with_payloads(vec![MucUser { + status: vec![MucStatus::SelfPresence, MucStatus::AssignedNick], + items: vec![{ + let mut item = MucItem::new(Affiliation::Owner, Role::Moderator); + item.jid = Some(LOUISE_FULL1.clone()); + item + }], + } + .into()]), + ); + + component.expect_message( + Jid::Full(LOUISE_FULL1.clone()), + |_| (), + "Subject message for session1", + ); + + // New session joins + // Participant1 presence for session2 + component.expect( + Presence::new(PresenceType::None) + .with_from(Jid::Full(LOUISE_ROOM1_PART.clone())) + .with_to(Jid::Full(LOUISE_FULL1.clone())) + .with_payloads(vec![MucUser { + status: Vec::new(), + items: { + let item = MucItem::new(Affiliation::Owner, Role::Moderator); + let mut item1 = item.clone(); + item1.jid = Some(LOUISE_FULL1.clone()); + let mut item2 = item.clone(); + item2.jid = Some(LOUISE_FULL2.clone()); + vec![item1, item2] + }, + } + .into()]), + ); + + // Self-presence for session2 + component.expect( + Presence::new(PresenceType::None) + .with_from(Jid::Full(LOUISE_ROOM1_PART.clone())) + .with_to(Jid::Full(LOUISE_FULL2.clone())) + .with_payloads(vec![MucUser { + status: vec![MucStatus::SelfPresence, MucStatus::AssignedNick], + items: { + let item = MucItem::new(Affiliation::Owner, Role::Moderator); + let mut item1 = item.clone(); + item1.jid = Some(LOUISE_FULL1.clone()); + let mut item2 = item.clone(); + item2.jid = Some(LOUISE_FULL2.clone()); + vec![item1, item2] + }, + } + .into()]), + ); + + component.expect_message( + Jid::Full(LOUISE_FULL2.clone()), + |_| (), + "Subject message for session2", + ); + + handle_stanza(&mut component, &mut rooms).await.unwrap(); + + assert_eq!(rooms.len(), 1); + match rooms.get(&ROOM1_BARE) { + Some(room) => { + assert_eq!(room.occupants.len(), 1); + assert_eq!( + room.occupants + .get(&LOUISE_ROOM1_PART.resource) + .unwrap() + .sessions + .len(), + 2 + ); + } + None => panic!(), + } +} + +#[tokio::test] +async fn leave() { + // Ensure the occupant is still valid even though a first session left + + 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 = 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); +}