add test and docs for EventEmitter, fix review issues
parent
55c25ce6ba
commit
187734f449
|
@ -1,14 +1,11 @@
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::Deref;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::Arc;
|
||||||
use std::{env, process::exit};
|
use std::{env, process::exit};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
self,
|
self,
|
||||||
events::{
|
events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
||||||
collections::all::RoomEvent,
|
|
||||||
room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
|
||||||
},
|
|
||||||
AsyncClient, AsyncClientConfig, EventEmitter, Room, SyncSettings,
|
AsyncClient, AsyncClientConfig, EventEmitter, Room, SyncSettings,
|
||||||
};
|
};
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
|
@ -270,7 +270,9 @@ impl AsyncClient {
|
||||||
self.base_client.write().await.event_emitter = Some(emitter);
|
self.base_client.write().await.event_emitter = Some(emitter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the room name from a `RoomId`, returning a string.
|
/// Returns an `Option` of the room name from a `RoomId`.
|
||||||
|
///
|
||||||
|
/// This is a human readable room name.
|
||||||
pub async fn get_room_name(&self, room_id: &str) -> Option<String> {
|
pub async fn get_room_name(&self, room_id: &str) -> Option<String> {
|
||||||
self.base_client
|
self.base_client
|
||||||
.read()
|
.read()
|
||||||
|
@ -279,21 +281,20 @@ impl AsyncClient {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the room names this client knows about.
|
/// Returns a `Vec` of the room names this client knows about.
|
||||||
|
///
|
||||||
|
/// This is a human readable list of room names.
|
||||||
pub async fn get_room_names(&self) -> Vec<String> {
|
pub async fn get_room_names(&self) -> Vec<String> {
|
||||||
self.base_client.read().await.calculate_room_names().await
|
self.base_client.read().await.calculate_room_names().await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the room names this client knows about.
|
/// Returns the rooms this client knows about.
|
||||||
|
///
|
||||||
|
/// A `HashMap` of room id to `matrix::models::Room`
|
||||||
pub async fn get_rooms(&self) -> HashMap<String, Arc<tokio::sync::Mutex<Room>>> {
|
pub async fn get_rooms(&self) -> HashMap<String, Arc<tokio::sync::Mutex<Room>>> {
|
||||||
self.base_client.read().await.joined_rooms.clone()
|
self.base_client.read().await.joined_rooms.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the room that the client last interacted with.
|
|
||||||
pub async fn current_room_id(&self) -> Option<RoomId> {
|
|
||||||
self.base_client.read().await.current_room_id()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Login to the server.
|
/// Login to the server.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
|
|
@ -35,7 +35,6 @@ use crate::models::Room;
|
||||||
use crate::session::Session;
|
use crate::session::Session;
|
||||||
use crate::EventEmitter;
|
use crate::EventEmitter;
|
||||||
|
|
||||||
use js_int::UInt;
|
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
|
@ -61,33 +60,6 @@ pub struct RoomName {
|
||||||
aliases: Vec<RoomAliasId>,
|
aliases: Vec<RoomAliasId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
|
||||||
pub struct CurrentRoom {
|
|
||||||
last_active: Option<UInt>,
|
|
||||||
current_room_id: Option<RoomId>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CurrentRoom {
|
|
||||||
// TODO when UserId is isomorphic to &str clean this up.
|
|
||||||
pub(crate) fn comes_after(&self, user: &Uid, event: &PresenceEvent) -> bool {
|
|
||||||
if user == &event.sender {
|
|
||||||
if self.last_active.is_none() {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
event.content.last_active_ago < self.last_active
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn update(&mut self, room_id: &str, event: &PresenceEvent) {
|
|
||||||
self.last_active = event.content.last_active_ago;
|
|
||||||
self.current_room_id =
|
|
||||||
Some(RoomId::try_from(room_id).expect("room id failed CurrentRoom::update"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A no IO Client implementation.
|
/// A no IO Client implementation.
|
||||||
///
|
///
|
||||||
/// This Client is a state machine that receives responses and events and
|
/// This Client is a state machine that receives responses and events and
|
||||||
|
@ -100,8 +72,6 @@ pub struct Client {
|
||||||
pub sync_token: Option<Token>,
|
pub sync_token: Option<Token>,
|
||||||
/// A map of the rooms our user is joined in.
|
/// A map of the rooms our user is joined in.
|
||||||
pub joined_rooms: HashMap<String, Arc<Mutex<Room>>>,
|
pub joined_rooms: HashMap<String, Arc<Mutex<Room>>>,
|
||||||
/// The most recent room the logged in user used by `RoomId`.
|
|
||||||
pub current_room_id: CurrentRoom,
|
|
||||||
/// A list of ignored users.
|
/// A list of ignored users.
|
||||||
pub ignored_users: Vec<UserId>,
|
pub ignored_users: Vec<UserId>,
|
||||||
/// The push ruleset for the logged in user.
|
/// The push ruleset for the logged in user.
|
||||||
|
@ -120,7 +90,6 @@ impl fmt::Debug for Client {
|
||||||
.field("session", &self.session)
|
.field("session", &self.session)
|
||||||
.field("sync_token", &self.sync_token)
|
.field("sync_token", &self.sync_token)
|
||||||
.field("joined_rooms", &self.joined_rooms)
|
.field("joined_rooms", &self.joined_rooms)
|
||||||
.field("current_room_id", &self.current_room_id)
|
|
||||||
.field("ignored_users", &self.ignored_users)
|
.field("ignored_users", &self.ignored_users)
|
||||||
.field("push_ruleset", &self.push_ruleset)
|
.field("push_ruleset", &self.push_ruleset)
|
||||||
.field("event_emitter", &"EventEmitter<...>")
|
.field("event_emitter", &"EventEmitter<...>")
|
||||||
|
@ -146,7 +115,6 @@ impl Client {
|
||||||
session,
|
session,
|
||||||
sync_token: None,
|
sync_token: None,
|
||||||
joined_rooms: HashMap::new(),
|
joined_rooms: HashMap::new(),
|
||||||
current_room_id: CurrentRoom::default(),
|
|
||||||
ignored_users: Vec::new(),
|
ignored_users: Vec::new(),
|
||||||
push_ruleset: None,
|
push_ruleset: None,
|
||||||
event_emitter: None,
|
event_emitter: None,
|
||||||
|
@ -160,6 +128,16 @@ impl Client {
|
||||||
self.session.is_some()
|
self.session.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add `EventEmitter` to `Client`.
|
||||||
|
///
|
||||||
|
/// The methods of `EventEmitter` are called when the respective `RoomEvents` occur.
|
||||||
|
pub async fn add_event_emitter(
|
||||||
|
&mut self,
|
||||||
|
emitter: Arc<tokio::sync::Mutex<Box<dyn EventEmitter>>>,
|
||||||
|
) {
|
||||||
|
self.event_emitter = Some(emitter);
|
||||||
|
}
|
||||||
|
|
||||||
/// Receive a login response and update the session of the client.
|
/// Receive a login response and update the session of the client.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
@ -204,10 +182,6 @@ impl Client {
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn current_room_id(&self) -> Option<RoomId> {
|
|
||||||
self.current_room_id.current_room_id.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_or_create_room(&mut self, room_id: &str) -> &mut Arc<Mutex<Room>> {
|
pub(crate) fn get_or_create_room(&mut self, room_id: &str) -> &mut Arc<Mutex<Room>> {
|
||||||
#[allow(clippy::or_fun_call)]
|
#[allow(clippy::or_fun_call)]
|
||||||
self.joined_rooms
|
self.joined_rooms
|
||||||
|
@ -336,15 +310,6 @@ impl Client {
|
||||||
///
|
///
|
||||||
/// * `event` - The event that should be handled by the client.
|
/// * `event` - The event that should be handled by the client.
|
||||||
pub async fn receive_presence_event(&mut self, room_id: &str, event: &PresenceEvent) -> bool {
|
pub async fn receive_presence_event(&mut self, room_id: &str, event: &PresenceEvent) -> bool {
|
||||||
let user_id = &self
|
|
||||||
.session
|
|
||||||
.as_ref()
|
|
||||||
.expect("to receive events you must be logged in")
|
|
||||||
.user_id;
|
|
||||||
|
|
||||||
if self.current_room_id.comes_after(user_id, event) {
|
|
||||||
self.current_room_id.update(room_id, event);
|
|
||||||
}
|
|
||||||
// this should be the room that was just created in the `Client::sync` loop.
|
// this should be the room that was just created in the `Client::sync` loop.
|
||||||
if let Some(room) = self.get_room(room_id) {
|
if let Some(room) = self.get_room(room_id) {
|
||||||
let mut room = room.lock().await;
|
let mut room = room.lock().await;
|
||||||
|
@ -361,6 +326,8 @@ impl Client {
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
|
/// * `room_id` - The unique id of the room the event belongs to.
|
||||||
|
///
|
||||||
/// * `event` - The presence event for a specified room member.
|
/// * `event` - The presence event for a specified room member.
|
||||||
pub async fn receive_account_data(&mut self, room_id: &str, event: &NonRoomEvent) -> bool {
|
pub async fn receive_account_data(&mut self, room_id: &str, event: &NonRoomEvent) -> bool {
|
||||||
match event {
|
match event {
|
||||||
|
|
|
@ -16,53 +16,69 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::events::{
|
use crate::events::{
|
||||||
call::{
|
|
||||||
answer::AnswerEvent, candidates::CandidatesEvent, hangup::HangupEvent, invite::InviteEvent,
|
|
||||||
},
|
|
||||||
direct::DirectEvent,
|
|
||||||
dummy::DummyEvent,
|
|
||||||
forwarded_room_key::ForwardedRoomKeyEvent,
|
|
||||||
fully_read::FullyReadEvent,
|
fully_read::FullyReadEvent,
|
||||||
ignored_user_list::IgnoredUserListEvent,
|
ignored_user_list::IgnoredUserListEvent,
|
||||||
key::verification::{
|
|
||||||
accept::AcceptEvent, cancel::CancelEvent, key::KeyEvent, mac::MacEvent,
|
|
||||||
request::RequestEvent, start::StartEvent,
|
|
||||||
},
|
|
||||||
presence::PresenceEvent,
|
presence::PresenceEvent,
|
||||||
push_rules::PushRulesEvent,
|
push_rules::PushRulesEvent,
|
||||||
receipt::ReceiptEvent,
|
|
||||||
room::{
|
room::{
|
||||||
aliases::AliasesEvent,
|
aliases::AliasesEvent,
|
||||||
avatar::AvatarEvent,
|
avatar::AvatarEvent,
|
||||||
canonical_alias::CanonicalAliasEvent,
|
canonical_alias::CanonicalAliasEvent,
|
||||||
create::CreateEvent,
|
|
||||||
encrypted::EncryptedEvent,
|
|
||||||
encryption::EncryptionEvent,
|
|
||||||
guest_access::GuestAccessEvent,
|
|
||||||
history_visibility::HistoryVisibilityEvent,
|
|
||||||
join_rules::JoinRulesEvent,
|
join_rules::JoinRulesEvent,
|
||||||
member::MemberEvent,
|
member::MemberEvent,
|
||||||
message::{feedback::FeedbackEvent, MessageEvent},
|
message::{feedback::FeedbackEvent, MessageEvent},
|
||||||
name::NameEvent,
|
name::NameEvent,
|
||||||
pinned_events::PinnedEventsEvent,
|
|
||||||
power_levels::PowerLevelsEvent,
|
power_levels::PowerLevelsEvent,
|
||||||
redaction::RedactionEvent,
|
redaction::RedactionEvent,
|
||||||
server_acl::ServerAclEvent,
|
|
||||||
third_party_invite::ThirdPartyInviteEvent,
|
|
||||||
tombstone::TombstoneEvent,
|
|
||||||
topic::TopicEvent,
|
|
||||||
},
|
},
|
||||||
room_key::RoomKeyEvent,
|
|
||||||
room_key_request::RoomKeyRequestEvent,
|
|
||||||
sticker::StickerEvent,
|
|
||||||
tag::TagEvent,
|
|
||||||
typing::TypingEvent,
|
|
||||||
CustomEvent, CustomRoomEvent, CustomStateEvent,
|
|
||||||
};
|
};
|
||||||
use crate::models::Room;
|
use crate::models::Room;
|
||||||
|
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
/// This trait allows any type implementing `EventEmitter` to specify event callbacks for each event.
|
||||||
|
/// The `AsyncClient` calls each method when the corresponding event is received.
|
||||||
///
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::ops::Deref;
|
||||||
|
/// # use std::sync::Arc;
|
||||||
|
/// # use std::{env, process::exit};
|
||||||
|
/// # use url::Url;
|
||||||
|
/// use matrix_sdk::{
|
||||||
|
/// self,
|
||||||
|
/// events::{
|
||||||
|
/// room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
||||||
|
/// },
|
||||||
|
/// AsyncClient, AsyncClientConfig, EventEmitter, Room, SyncSettings,
|
||||||
|
/// };
|
||||||
|
/// use tokio::sync::Mutex;
|
||||||
|
///
|
||||||
|
/// struct EventCallback;
|
||||||
|
///
|
||||||
|
/// #[async_trait::async_trait]
|
||||||
|
/// impl EventEmitter for EventCallback {
|
||||||
|
/// async fn on_room_message(&mut self, room: Arc<Mutex<Room>>, event: Arc<Mutex<MessageEvent>>) {
|
||||||
|
/// if let MessageEvent {
|
||||||
|
/// content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||||
|
/// sender,
|
||||||
|
/// ..
|
||||||
|
/// } = event.lock().await.deref()
|
||||||
|
/// {
|
||||||
|
/// let rooms = room.lock().await;
|
||||||
|
/// let member = rooms.members.get(&sender.to_string()).unwrap();
|
||||||
|
/// println!(
|
||||||
|
/// "{}: {}",
|
||||||
|
/// member
|
||||||
|
/// .user
|
||||||
|
/// .display_name
|
||||||
|
/// .as_ref()
|
||||||
|
/// .unwrap_or(&sender.to_string()),
|
||||||
|
/// msg_body
|
||||||
|
/// );
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
pub trait EventEmitter: Send + Sync {
|
pub trait EventEmitter: Send + Sync {
|
||||||
// ROOM EVENTS from `IncomingTimeline`
|
// ROOM EVENTS from `IncomingTimeline`
|
||||||
|
@ -146,3 +162,173 @@ pub trait EventEmitter: Send + Sync {
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomAliases` event.
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomAliases` event.
|
||||||
async fn on_presence_event(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<PresenceEvent>>) {}
|
async fn on_presence_event(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<PresenceEvent>>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub struct EvEmitterTest(Arc<Mutex<Vec<String>>>);
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl EventEmitter for EvEmitterTest {
|
||||||
|
async fn on_room_member(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<MemberEvent>>) {
|
||||||
|
self.0.lock().await.push("member".to_string())
|
||||||
|
}
|
||||||
|
async fn on_room_name(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<NameEvent>>) {
|
||||||
|
self.0.lock().await.push("name".to_string())
|
||||||
|
}
|
||||||
|
async fn on_room_canonical_alias(
|
||||||
|
&mut self,
|
||||||
|
r: Arc<Mutex<Room>>,
|
||||||
|
_: Arc<Mutex<CanonicalAliasEvent>>,
|
||||||
|
) {
|
||||||
|
self.0.lock().await.push("canonical".to_string())
|
||||||
|
}
|
||||||
|
async fn on_room_aliases(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<AliasesEvent>>) {
|
||||||
|
self.0.lock().await.push("aliases".to_string())
|
||||||
|
}
|
||||||
|
async fn on_room_avatar(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<AvatarEvent>>) {
|
||||||
|
self.0.lock().await.push("avatar".to_string())
|
||||||
|
}
|
||||||
|
async fn on_room_message(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<MessageEvent>>) {
|
||||||
|
self.0.lock().await.push("message".to_string())
|
||||||
|
}
|
||||||
|
async fn on_room_message_feedback(
|
||||||
|
&mut self,
|
||||||
|
_: Arc<Mutex<Room>>,
|
||||||
|
_: Arc<Mutex<FeedbackEvent>>,
|
||||||
|
) {
|
||||||
|
self.0.lock().await.push("feedback".to_string())
|
||||||
|
}
|
||||||
|
async fn on_room_redaction(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<RedactionEvent>>) {
|
||||||
|
self.0.lock().await.push("redaction".to_string())
|
||||||
|
}
|
||||||
|
async fn on_room_power_levels(
|
||||||
|
&mut self,
|
||||||
|
_: Arc<Mutex<Room>>,
|
||||||
|
_: Arc<Mutex<PowerLevelsEvent>>,
|
||||||
|
) {
|
||||||
|
self.0.lock().await.push("power".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn on_state_member(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<MemberEvent>>) {
|
||||||
|
self.0.lock().await.push("state member".to_string())
|
||||||
|
}
|
||||||
|
async fn on_state_name(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<NameEvent>>) {
|
||||||
|
self.0.lock().await.push("state name".to_string())
|
||||||
|
}
|
||||||
|
async fn on_state_canonical_alias(
|
||||||
|
&mut self,
|
||||||
|
_: Arc<Mutex<Room>>,
|
||||||
|
_: Arc<Mutex<CanonicalAliasEvent>>,
|
||||||
|
) {
|
||||||
|
self.0.lock().await.push("state canonical".to_string())
|
||||||
|
}
|
||||||
|
async fn on_state_aliases(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<AliasesEvent>>) {
|
||||||
|
self.0.lock().await.push("state aliases".to_string())
|
||||||
|
}
|
||||||
|
async fn on_state_avatar(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<AvatarEvent>>) {
|
||||||
|
self.0.lock().await.push("state avatar".to_string())
|
||||||
|
}
|
||||||
|
async fn on_state_power_levels(
|
||||||
|
&mut self,
|
||||||
|
_: Arc<Mutex<Room>>,
|
||||||
|
_: Arc<Mutex<PowerLevelsEvent>>,
|
||||||
|
) {
|
||||||
|
self.0.lock().await.push("state power".to_string())
|
||||||
|
}
|
||||||
|
async fn on_state_join_rules(
|
||||||
|
&mut self,
|
||||||
|
_: Arc<Mutex<Room>>,
|
||||||
|
_: Arc<Mutex<JoinRulesEvent>>,
|
||||||
|
) {
|
||||||
|
self.0.lock().await.push("state rules".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn on_account_presence(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<PresenceEvent>>) {
|
||||||
|
self.0.lock().await.push("account presence".to_string())
|
||||||
|
}
|
||||||
|
async fn on_account_ignored_users(
|
||||||
|
&mut self,
|
||||||
|
_: Arc<Mutex<Room>>,
|
||||||
|
_: Arc<Mutex<IgnoredUserListEvent>>,
|
||||||
|
) {
|
||||||
|
self.0.lock().await.push("account ignore".to_string())
|
||||||
|
}
|
||||||
|
async fn on_account_push_rules(
|
||||||
|
&mut self,
|
||||||
|
_: Arc<Mutex<Room>>,
|
||||||
|
_: Arc<Mutex<PushRulesEvent>>,
|
||||||
|
) {
|
||||||
|
self.0.lock().await.push("".to_string())
|
||||||
|
}
|
||||||
|
async fn on_account_data_fully_read(
|
||||||
|
&mut self,
|
||||||
|
_: Arc<Mutex<Room>>,
|
||||||
|
_: Arc<Mutex<FullyReadEvent>>,
|
||||||
|
) {
|
||||||
|
self.0.lock().await.push("account read".to_string())
|
||||||
|
}
|
||||||
|
async fn on_presence_event(&mut self, _: Arc<Mutex<Room>>, _: Arc<Mutex<PresenceEvent>>) {
|
||||||
|
self.0.lock().await.push("presence event".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use crate::identifiers::UserId;
|
||||||
|
use crate::{AsyncClient, Session, SyncSettings};
|
||||||
|
|
||||||
|
use mockito::{mock, Matcher};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn event_emitter() {
|
||||||
|
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
||||||
|
|
||||||
|
let session = Session {
|
||||||
|
access_token: "1234".to_owned(),
|
||||||
|
user_id: UserId::try_from("@example:example.com").unwrap(),
|
||||||
|
device_id: "DEVICEID".to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let _m = mock(
|
||||||
|
"GET",
|
||||||
|
Matcher::Regex(r"^/_matrix/client/r0/sync\?.*$".to_string()),
|
||||||
|
)
|
||||||
|
.with_status(200)
|
||||||
|
.with_body_from_file("tests/data/sync.json")
|
||||||
|
.create();
|
||||||
|
|
||||||
|
let vec = Arc::new(Mutex::new(Vec::new()));
|
||||||
|
let test_vec = Arc::clone(&vec);
|
||||||
|
let mut emitter = Arc::new(Mutex::new(
|
||||||
|
Box::new(EvEmitterTest(vec)) as Box<(dyn EventEmitter)>
|
||||||
|
));
|
||||||
|
let mut client = AsyncClient::new(homeserver, Some(session)).unwrap();
|
||||||
|
client.add_event_emitter(Arc::clone(&emitter)).await;
|
||||||
|
|
||||||
|
let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
|
||||||
|
let _response = client.sync(sync_settings).await.unwrap();
|
||||||
|
|
||||||
|
let v = test_vec.lock().await;
|
||||||
|
assert_eq!(
|
||||||
|
v.as_slice(),
|
||||||
|
[
|
||||||
|
"state rules",
|
||||||
|
"state member",
|
||||||
|
"state aliases",
|
||||||
|
"state power",
|
||||||
|
"state canonical",
|
||||||
|
"state member",
|
||||||
|
"state member",
|
||||||
|
"message",
|
||||||
|
"account read",
|
||||||
|
"account ignore",
|
||||||
|
"presence event",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -28,12 +28,11 @@
|
||||||
|
|
||||||
pub use crate::{error::Error, error::Result, session::Session};
|
pub use crate::{error::Error, error::Result, session::Session};
|
||||||
pub use reqwest::header::InvalidHeaderValue;
|
pub use reqwest::header::InvalidHeaderValue;
|
||||||
|
pub use ruma_api;
|
||||||
pub use ruma_client_api as api;
|
pub use ruma_client_api as api;
|
||||||
pub use ruma_events as events;
|
pub use ruma_events as events;
|
||||||
pub use ruma_identifiers as identifiers;
|
pub use ruma_identifiers as identifiers;
|
||||||
|
|
||||||
pub use ruma_api as ruma_traits;
|
|
||||||
|
|
||||||
mod async_client;
|
mod async_client;
|
||||||
mod base_client;
|
mod base_client;
|
||||||
mod error;
|
mod error;
|
||||||
|
|
|
@ -87,33 +87,3 @@ async fn room_names() {
|
||||||
client.get_room_name("!SVkFJHzfwvuaIEawgC:localhost").await
|
client.get_room_name("!SVkFJHzfwvuaIEawgC:localhost").await
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn current_room() {
|
|
||||||
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(
|
|
||||||
"GET",
|
|
||||||
Matcher::Regex(r"^/_matrix/client/r0/sync\?.*$".to_string()),
|
|
||||||
)
|
|
||||||
.with_status(200)
|
|
||||||
.with_body_from_file("tests/data/sync.json")
|
|
||||||
.create();
|
|
||||||
|
|
||||||
let mut client = AsyncClient::new(homeserver, Some(session)).unwrap();
|
|
||||||
|
|
||||||
let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
|
|
||||||
|
|
||||||
let _response = client.sync(sync_settings).await.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
Some("!SVkFJHzfwvuaIEawgC:localhost".into()),
|
|
||||||
client.current_room_id().await.map(|id| id.to_string())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue