tests/presence: Split MSN tests

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2022-12-27 08:44:29 +01:00
parent 7472bc1398
commit 9bd4adc880
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2
3 changed files with 210 additions and 176 deletions

View file

@ -15,5 +15,6 @@
mod iq;
mod presence;
mod presence_msn;
#[allow(dead_code)]
pub mod templates;

View file

@ -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<BareJid, Room> = 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<BareJid, Room> = 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<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);
}

206
src/tests/presence_msn.rs Normal file
View file

@ -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 <https://www.gnu.org/licenses/>.
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<BareJid, Room> = 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<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);
}