async_client: add tests for all current endpoints, event emitter typeing/receipt events, set unread notifications
parent
14580bc383
commit
4f96ac96e2
|
@ -324,16 +324,14 @@ impl AsyncClient {
|
||||||
/// Returns the invited rooms this client knows about.
|
/// Returns the invited rooms this client knows about.
|
||||||
///
|
///
|
||||||
/// A `HashMap` of room id to `matrix::models::Room`
|
/// A `HashMap` of room id to `matrix::models::Room`
|
||||||
pub async fn invited_rooms(
|
pub fn invited_rooms(&self) -> Arc<RwLock<HashMap<RoomId, Arc<tokio::sync::RwLock<Room>>>>> {
|
||||||
&self,
|
|
||||||
) -> Arc<RwLock<HashMap<RoomId, Arc<tokio::sync::RwLock<Room>>>>> {
|
|
||||||
self.base_client.invited_rooms()
|
self.base_client.invited_rooms()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the left rooms this client knows about.
|
/// Returns the left rooms this client knows about.
|
||||||
///
|
///
|
||||||
/// A `HashMap` of room id to `matrix::models::Room`
|
/// A `HashMap` of room id to `matrix::models::Room`
|
||||||
pub async fn left_rooms(&self) -> Arc<RwLock<HashMap<RoomId, Arc<tokio::sync::RwLock<Room>>>>> {
|
pub fn left_rooms(&self) -> Arc<RwLock<HashMap<RoomId, Arc<tokio::sync::RwLock<Room>>>>> {
|
||||||
self.base_client.left_rooms()
|
self.base_client.left_rooms()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1196,10 +1194,11 @@ impl AsyncClient {
|
||||||
mod test {
|
mod test {
|
||||||
use super::{
|
use super::{
|
||||||
ban_user, create_receipt, create_typing_event, forget_room, invite_user, kick_user,
|
ban_user, create_receipt, create_typing_event, forget_room, invite_user, kick_user,
|
||||||
leave_room,
|
leave_room, Invite3pid, MessageEventContent, RoomIdOrAliasId,
|
||||||
};
|
};
|
||||||
use super::{AsyncClient, AsyncClientConfig, Session, SyncSettings, Url};
|
use super::{AsyncClient, AsyncClientConfig, Session, SyncSettings, Url};
|
||||||
use crate::events::room::member::MembershipState;
|
use crate::events::room::member::MembershipState;
|
||||||
|
use crate::events::room::message::TextMessageEventContent;
|
||||||
use crate::identifiers::{EventId, RoomId, UserId};
|
use crate::identifiers::{EventId, RoomId, UserId};
|
||||||
use matrix_sdk_base::JsonStore;
|
use matrix_sdk_base::JsonStore;
|
||||||
|
|
||||||
|
@ -1339,7 +1338,7 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn join_room() {
|
async fn join_room_by_id() {
|
||||||
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
||||||
|
|
||||||
let session = Session {
|
let session = Session {
|
||||||
|
@ -1366,9 +1365,41 @@ mod test {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn join_room_by_id_or_alias() {
|
||||||
|
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
||||||
|
|
||||||
|
let session = Session {
|
||||||
|
access_token: "1234".to_owned(),
|
||||||
|
user_id: UserId::try_from("@example:localhost").unwrap(),
|
||||||
|
device_id: "DEVICEID".to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let _m = mock(
|
||||||
|
"POST",
|
||||||
|
Matcher::Regex(r"^/_matrix/client/r0/join/".to_string()),
|
||||||
|
)
|
||||||
|
.with_status(200)
|
||||||
|
.with_body_from_file("../test_data/room_id.json")
|
||||||
|
.create();
|
||||||
|
|
||||||
|
let client = AsyncClient::new(homeserver, Some(session)).unwrap();
|
||||||
|
let room_id = RoomIdOrAliasId::try_from("!testroom:example.org").unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
// this is the `join_by_room_id::Response` but since no PartialEq we check the RoomId field
|
||||||
|
client
|
||||||
|
.join_room_by_id_or_alias(&room_id, &["server.com".to_string()])
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.room_id,
|
||||||
|
RoomId::try_from("!testroom:example.org").unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[allow(irrefutable_let_patterns)]
|
#[allow(irrefutable_let_patterns)]
|
||||||
async fn invite_room() {
|
async fn invite_user_by_id() {
|
||||||
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
||||||
let user = UserId::try_from("@example:localhost").unwrap();
|
let user = UserId::try_from("@example:localhost").unwrap();
|
||||||
let room_id = RoomId::try_from("!testroom:example.org").unwrap();
|
let room_id = RoomId::try_from("!testroom:example.org").unwrap();
|
||||||
|
@ -1392,6 +1423,44 @@ mod test {
|
||||||
if let invite_user::Response = client.invite_user_by_id(&room_id, &user).await.unwrap() {}
|
if let invite_user::Response = client.invite_user_by_id(&room_id, &user).await.unwrap() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
async fn invite_user_by_3pid() {
|
||||||
|
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
||||||
|
let user = UserId::try_from("@example:localhost").unwrap();
|
||||||
|
let room_id = RoomId::try_from("!testroom:example.org").unwrap();
|
||||||
|
|
||||||
|
let session = Session {
|
||||||
|
access_token: "1234".to_owned(),
|
||||||
|
user_id: user.clone(),
|
||||||
|
device_id: "DEVICEID".to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let _m = mock(
|
||||||
|
"POST",
|
||||||
|
Matcher::Regex(r"^/_matrix/client/r0/rooms/.*/invite".to_string()),
|
||||||
|
)
|
||||||
|
.with_status(200)
|
||||||
|
.with_body_from_file("../test_data/logout_response.json")
|
||||||
|
.create();
|
||||||
|
|
||||||
|
let client = AsyncClient::new(homeserver, Some(session)).unwrap();
|
||||||
|
|
||||||
|
if let invite_user::Response = client
|
||||||
|
.invite_user_by_3pid(
|
||||||
|
&room_id,
|
||||||
|
&Invite3pid {
|
||||||
|
id_server: "example.org".to_string(),
|
||||||
|
id_access_token: "IdToken".to_string(),
|
||||||
|
medium: crate::api::r0::thirdparty::Medium::Email,
|
||||||
|
address: "address".to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[allow(irrefutable_let_patterns)]
|
#[allow(irrefutable_let_patterns)]
|
||||||
async fn leave_room() {
|
async fn leave_room() {
|
||||||
|
@ -1604,6 +1673,48 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn room_message_send() {
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
||||||
|
let user = UserId::try_from("@example:localhost").unwrap();
|
||||||
|
let room_id = RoomId::try_from("!testroom:example.org").unwrap();
|
||||||
|
|
||||||
|
let session = Session {
|
||||||
|
access_token: "1234".to_owned(),
|
||||||
|
user_id: user.clone(),
|
||||||
|
device_id: "DEVICEID".to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let _m = mock(
|
||||||
|
"PUT",
|
||||||
|
Matcher::Regex(r"^/_matrix/client/r0/rooms/.*/send/".to_string()),
|
||||||
|
)
|
||||||
|
.with_status(200)
|
||||||
|
.with_body_from_file("../test_data/event_id.json")
|
||||||
|
.create();
|
||||||
|
|
||||||
|
let client = AsyncClient::new(homeserver, Some(session)).unwrap();
|
||||||
|
|
||||||
|
let content = MessageEventContent::Text(TextMessageEventContent {
|
||||||
|
body: "Hello world".to_owned(),
|
||||||
|
format: None,
|
||||||
|
formatted_body: None,
|
||||||
|
relates_to: None,
|
||||||
|
});
|
||||||
|
let txn_id = Uuid::new_v4();
|
||||||
|
let response = client
|
||||||
|
.room_send(&room_id, content, Some(txn_id))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
EventId::try_from("$h29iv0s8:example.com").ok(),
|
||||||
|
response.event_id
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn user_presence() {
|
async fn user_presence() {
|
||||||
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
||||||
|
@ -1644,35 +1755,102 @@ mod test {
|
||||||
assert!(room.power_levels.is_some())
|
assert!(room.power_levels.is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[tokio::test]
|
#[tokio::test]
|
||||||
// async fn calculate_room_names_from_summary() {
|
async fn calculate_room_names_from_summary() {
|
||||||
// let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
||||||
|
|
||||||
// let mut bld = EventBuilder::default().build_with_response(
|
let session = Session {
|
||||||
// // this sync has no room.name or room.alias events so only relies on summary
|
access_token: "1234".to_owned(),
|
||||||
// "../test_data/sync_with_summary.json",
|
user_id: UserId::try_from("@example:localhost").unwrap(),
|
||||||
// "GET",
|
device_id: "DEVICEID".to_owned(),
|
||||||
// Matcher::Regex(r"^/_matrix/client/r0/sync\?.*$".to_string()),
|
};
|
||||||
// );
|
|
||||||
|
|
||||||
// let session = Session {
|
let _m = mock(
|
||||||
// access_token: "1234".to_owned(),
|
"GET",
|
||||||
// user_id: UserId::try_from("@example:localhost").unwrap(),
|
Matcher::Regex(r"^/_matrix/client/r0/sync\?.*$".to_string()),
|
||||||
// device_id: "DEVICEID".to_owned(),
|
)
|
||||||
// };
|
.with_status(200)
|
||||||
// let client = AsyncClient::new(homeserver, Some(session)).unwrap();
|
.with_body_from_file("../test_data/sync_with_summary.json")
|
||||||
// let client = bld.set_client(client).to_client().await.unwrap();
|
.create();
|
||||||
|
|
||||||
// let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
|
let client = AsyncClient::new(homeserver, Some(session)).unwrap();
|
||||||
// let _response = client.sync(sync_settings).await.unwrap();
|
|
||||||
|
|
||||||
// let mut room_names = vec![];
|
let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
|
||||||
// for room in client.joined_rooms().read().await.values() {
|
let _response = client.sync(sync_settings).await.unwrap();
|
||||||
// room_names.push(room.read().await.display_name())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// assert_eq!(vec!["example, example2"], room_names);
|
let mut room_names = vec![];
|
||||||
// }
|
for room in client.joined_rooms().read().await.values() {
|
||||||
|
room_names.push(room.read().await.display_name())
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(vec!["example, example2"], room_names);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn invited_rooms() {
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
let session = crate::Session {
|
||||||
|
access_token: "12345".to_owned(),
|
||||||
|
user_id: UserId::try_from("@example:localhost").unwrap(),
|
||||||
|
device_id: "DEVICEID".to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let homeserver = url::Url::parse(&mockito::server_url()).unwrap();
|
||||||
|
let client = AsyncClient::new(homeserver, Some(session)).unwrap();
|
||||||
|
|
||||||
|
let _m = mock(
|
||||||
|
"GET",
|
||||||
|
Matcher::Regex(r"^/_matrix/client/r0/sync\?.*$".to_string()),
|
||||||
|
)
|
||||||
|
.with_status(200)
|
||||||
|
.with_body_from_file("../test_data/invite_sync.json")
|
||||||
|
.create();
|
||||||
|
|
||||||
|
let _response = client.sync(SyncSettings::default()).await.unwrap();
|
||||||
|
|
||||||
|
assert!(client.joined_rooms().read().await.is_empty());
|
||||||
|
assert!(client.left_rooms().read().await.is_empty());
|
||||||
|
assert!(!client.invited_rooms().read().await.is_empty());
|
||||||
|
|
||||||
|
assert!(client
|
||||||
|
.get_invited_room(&RoomId::try_from("!696r7674:example.com").unwrap())
|
||||||
|
.await
|
||||||
|
.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn left_rooms() {
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
let session = crate::Session {
|
||||||
|
access_token: "12345".to_owned(),
|
||||||
|
user_id: UserId::try_from("@example:localhost").unwrap(),
|
||||||
|
device_id: "DEVICEID".to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let homeserver = url::Url::parse(&mockito::server_url()).unwrap();
|
||||||
|
let client = AsyncClient::new(homeserver, Some(session)).unwrap();
|
||||||
|
|
||||||
|
let _m = mock(
|
||||||
|
"GET",
|
||||||
|
Matcher::Regex(r"^/_matrix/client/r0/sync\?.*$".to_string()),
|
||||||
|
)
|
||||||
|
.with_status(200)
|
||||||
|
.with_body_from_file("../test_data/leave_sync.json")
|
||||||
|
.create();
|
||||||
|
|
||||||
|
let _response = client.sync(SyncSettings::default()).await.unwrap();
|
||||||
|
|
||||||
|
assert!(client.joined_rooms().read().await.is_empty());
|
||||||
|
assert!(!client.left_rooms().read().await.is_empty());
|
||||||
|
assert!(client.invited_rooms().read().await.is_empty());
|
||||||
|
|
||||||
|
assert!(client
|
||||||
|
.get_left_room(&RoomId::try_from("!SVkFJHzfwvuaIEawgC:localhost").unwrap())
|
||||||
|
.await
|
||||||
|
.is_some())
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_client_sync_store() {
|
async fn test_client_sync_store() {
|
||||||
|
|
|
@ -662,6 +662,12 @@ impl Client {
|
||||||
.await
|
.await
|
||||||
.set_room_summary(&joined_room.summary);
|
.set_room_summary(&joined_room.summary);
|
||||||
|
|
||||||
|
// set unread notification count
|
||||||
|
matrix_room
|
||||||
|
.write()
|
||||||
|
.await
|
||||||
|
.set_unread_notice_count(&joined_room.unread_notifications);
|
||||||
|
|
||||||
// re looping is not ideal here
|
// re looping is not ideal here
|
||||||
for event in &mut joined_room.state.events {
|
for event in &mut joined_room.state.events {
|
||||||
if let Ok(e) = event.deserialize() {
|
if let Ok(e) = event.deserialize() {
|
||||||
|
|
|
@ -18,6 +18,7 @@ use crate::events::{
|
||||||
ignored_user_list::IgnoredUserListEvent,
|
ignored_user_list::IgnoredUserListEvent,
|
||||||
presence::PresenceEvent,
|
presence::PresenceEvent,
|
||||||
push_rules::PushRulesEvent,
|
push_rules::PushRulesEvent,
|
||||||
|
receipt::ReceiptEvent,
|
||||||
room::{
|
room::{
|
||||||
aliases::AliasesEvent,
|
aliases::AliasesEvent,
|
||||||
avatar::AvatarEvent,
|
avatar::AvatarEvent,
|
||||||
|
@ -34,6 +35,7 @@ use crate::events::{
|
||||||
StrippedRoomAliases, StrippedRoomAvatar, StrippedRoomCanonicalAlias, StrippedRoomJoinRules,
|
StrippedRoomAliases, StrippedRoomAvatar, StrippedRoomCanonicalAlias, StrippedRoomJoinRules,
|
||||||
StrippedRoomMember, StrippedRoomName, StrippedRoomPowerLevels,
|
StrippedRoomMember, StrippedRoomName, StrippedRoomPowerLevels,
|
||||||
},
|
},
|
||||||
|
typing::TypingEvent,
|
||||||
};
|
};
|
||||||
use crate::RoomState;
|
use crate::RoomState;
|
||||||
|
|
||||||
|
@ -143,7 +145,7 @@ pub trait EventEmitter: Send + Sync {
|
||||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomJoinRules` event.
|
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomJoinRules` event.
|
||||||
async fn on_stripped_state_join_rules(&self, _: RoomState, _: &StrippedRoomJoinRules) {}
|
async fn on_stripped_state_join_rules(&self, _: RoomState, _: &StrippedRoomJoinRules) {}
|
||||||
|
|
||||||
// `NonRoomEvent` (this is a type alias from ruma_events) from `IncomingAccountData`
|
// `NonRoomEvent` (this is a type alias from ruma_events)
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomMember` event.
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomMember` event.
|
||||||
async fn on_account_presence(&self, _: RoomState, _: &PresenceEvent) {}
|
async fn on_account_presence(&self, _: RoomState, _: &PresenceEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomName` event.
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomName` event.
|
||||||
|
@ -152,6 +154,12 @@ pub trait EventEmitter: Send + Sync {
|
||||||
async fn on_account_push_rules(&self, _: RoomState, _: &PushRulesEvent) {}
|
async fn on_account_push_rules(&self, _: RoomState, _: &PushRulesEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomAliases` event.
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomAliases` event.
|
||||||
async fn on_account_data_fully_read(&self, _: RoomState, _: &FullyReadEvent) {}
|
async fn on_account_data_fully_read(&self, _: RoomState, _: &FullyReadEvent) {}
|
||||||
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::Typing` event.
|
||||||
|
async fn on_account_data_typing(&self, _: RoomState, _: &TypingEvent) {}
|
||||||
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::Receipt` event.
|
||||||
|
///
|
||||||
|
/// This is always a read receipt.
|
||||||
|
async fn on_account_data_receipt(&self, _: RoomState, _: &ReceiptEvent) {}
|
||||||
|
|
||||||
// `PresenceEvent` is a struct so there is only the one method
|
// `PresenceEvent` is a struct so there is only the one method
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomAliases` event.
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomAliases` event.
|
||||||
|
|
|
@ -20,7 +20,7 @@ use std::convert::TryFrom;
|
||||||
use super::message::MessageQueue;
|
use super::message::MessageQueue;
|
||||||
use super::RoomMember;
|
use super::RoomMember;
|
||||||
|
|
||||||
use crate::api::r0::sync::sync_events::RoomSummary;
|
use crate::api::r0::sync::sync_events::{RoomSummary, UnreadNotificationsCount};
|
||||||
use crate::events::collections::all::{RoomEvent, StateEvent};
|
use crate::events::collections::all::{RoomEvent, StateEvent};
|
||||||
use crate::events::presence::PresenceEvent;
|
use crate::events::presence::PresenceEvent;
|
||||||
use crate::events::room::{
|
use crate::events::room::{
|
||||||
|
@ -320,6 +320,11 @@ impl Room {
|
||||||
self.room_name.joined_member_count = *joined_member_count;
|
self.room_name.joined_member_count = *joined_member_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_unread_notice_count(&mut self, notifications: &UnreadNotificationsCount) {
|
||||||
|
self.unread_highlight = notifications.highlight_count;
|
||||||
|
self.unread_notifications = notifications.notification_count;
|
||||||
|
}
|
||||||
|
|
||||||
/// Handle a room.member updating the room state if necessary.
|
/// Handle a room.member updating the room state if necessary.
|
||||||
///
|
///
|
||||||
/// Returns true if the joined member list changed, false otherwise.
|
/// Returns true if the joined member list changed, false otherwise.
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"event_id": "$h29iv0s8:example.com"
|
||||||
|
}
|
Loading…
Reference in New Issue