use std::ops::Not;
use ruma::{OwnedRoomId, events::room::tombstone::RoomTombstoneEventContent};
use super::Room;
impl Room {
pub fn is_tombstoned(&self) -> bool {
self.info.read().base_info.tombstone.is_some()
}
pub fn tombstone_content(&self) -> Option<RoomTombstoneEventContent> {
self.info.read().tombstone().cloned()
}
pub fn successor_room(&self) -> Option<SuccessorRoom> {
self.tombstone_content().map(|tombstone_event| SuccessorRoom {
room_id: tombstone_event.replacement_room,
reason: tombstone_event.body.is_empty().not().then_some(tombstone_event.body),
})
}
pub fn predecessor_room(&self) -> Option<PredecessorRoom> {
self.create_content()
.and_then(|content_event| content_event.predecessor)
.map(|predecessor| PredecessorRoom { room_id: predecessor.room_id })
}
}
#[derive(Debug)]
pub struct SuccessorRoom {
pub room_id: OwnedRoomId,
pub reason: Option<String>,
}
#[derive(Debug)]
pub struct PredecessorRoom {
pub room_id: OwnedRoomId,
}
#[cfg(test)]
mod tests {
use std::ops::Not;
use assert_matches::assert_matches;
use matrix_sdk_test::{
JoinedRoomBuilder, SyncResponseBuilder, async_test, event_factory::EventFactory,
};
use ruma::{RoomVersionId, room_id, user_id};
use crate::{RoomState, test_utils::logged_in_base_client};
#[async_test]
async fn test_no_successor_room() {
let client = logged_in_base_client(None).await;
let room = client.get_or_create_room(room_id!("!r0"), RoomState::Joined);
assert!(room.is_tombstoned().not());
assert!(room.tombstone_content().is_none());
assert!(room.successor_room().is_none());
}
#[async_test]
async fn test_successor_room() {
let client = logged_in_base_client(None).await;
let sender = user_id!("@mnt_io:matrix.org");
let room_id = room_id!("!r0");
let successor_room_id = room_id!("!r1");
let room = client.get_or_create_room(room_id, RoomState::Joined);
let mut sync_builder = SyncResponseBuilder::new();
let response = sync_builder
.add_joined_room(
JoinedRoomBuilder::new(room_id).add_timeline_event(
EventFactory::new()
.sender(sender)
.room_tombstone("traces of you", successor_room_id),
),
)
.build_sync_response();
client.receive_sync_response(response).await.unwrap();
assert!(room.is_tombstoned());
assert!(room.tombstone_content().is_some());
assert_matches!(room.successor_room(), Some(successor_room) => {
assert_eq!(successor_room.room_id, successor_room_id);
assert_matches!(successor_room.reason, Some(reason) => {
assert_eq!(reason, "traces of you");
});
});
}
#[async_test]
async fn test_successor_room_no_reason() {
let client = logged_in_base_client(None).await;
let sender = user_id!("@mnt_io:matrix.org");
let room_id = room_id!("!r0");
let successor_room_id = room_id!("!r1");
let room = client.get_or_create_room(room_id, RoomState::Joined);
let mut sync_builder = SyncResponseBuilder::new();
let response = sync_builder
.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_event(
EventFactory::new().sender(sender).room_tombstone(
"",
successor_room_id,
),
))
.build_sync_response();
client.receive_sync_response(response).await.unwrap();
assert!(room.is_tombstoned());
assert!(room.tombstone_content().is_some());
assert_matches!(room.successor_room(), Some(successor_room) => {
assert_eq!(successor_room.room_id, successor_room_id);
assert!(successor_room.reason.is_none());
});
}
#[async_test]
async fn test_no_predecessor_room() {
let client = logged_in_base_client(None).await;
let room = client.get_or_create_room(room_id!("!r0"), RoomState::Joined);
assert!(room.create_content().is_none());
assert!(room.predecessor_room().is_none());
}
#[async_test]
async fn test_no_predecessor_room_with_create_event() {
let client = logged_in_base_client(None).await;
let sender = user_id!("@mnt_io:matrix.org");
let room_id = room_id!("!r1");
let room = client.get_or_create_room(room_id, RoomState::Joined);
let mut sync_builder = SyncResponseBuilder::new();
let response = sync_builder
.add_joined_room(
JoinedRoomBuilder::new(room_id).add_timeline_event(
EventFactory::new()
.create(sender, RoomVersionId::V11)
.no_predecessor()
.into_raw_sync(),
),
)
.build_sync_response();
client.receive_sync_response(response).await.unwrap();
assert!(room.create_content().is_some());
assert!(room.predecessor_room().is_none());
}
#[async_test]
async fn test_predecessor_room() {
let client = logged_in_base_client(None).await;
let sender = user_id!("@mnt_io:matrix.org");
let room_id = room_id!("!r1");
let predecessor_room_id = room_id!("!r0");
let room = client.get_or_create_room(room_id, RoomState::Joined);
let mut sync_builder = SyncResponseBuilder::new();
let response = sync_builder
.add_joined_room(
JoinedRoomBuilder::new(room_id).add_timeline_event(
EventFactory::new()
.create(sender, RoomVersionId::V11)
.predecessor(predecessor_room_id)
.into_raw_sync(),
),
)
.build_sync_response();
client.receive_sync_response(response).await.unwrap();
assert!(room.create_content().is_some());
assert_matches!(room.predecessor_room(), Some(predecessor_room) => {
assert_eq!(predecessor_room.room_id, predecessor_room_id);
});
}
}