add test, AsyncClient room name methods
parent
20618e7a20
commit
a29ae2a62e
|
@ -14,11 +14,12 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use futures::future::{BoxFuture, Future, FutureExt};
|
use futures::future::{BoxFuture, Future, FutureExt};
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::{TryFrom, TryInto};
|
||||||
use std::sync::atomic::{AtomicU64, Ordering};
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
use std::sync::{Arc, Mutex, RwLock as SyncLock};
|
use std::sync::{Arc, Mutex, RwLock as SyncLock};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::{RwLock, RwLockReadGuard};
|
||||||
|
|
||||||
use async_std::task::sleep;
|
use async_std::task::sleep;
|
||||||
|
|
||||||
|
@ -261,6 +262,22 @@ impl AsyncClient {
|
||||||
&self.homeserver
|
&self.homeserver
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
/// Access to the underlying `BaseClient`. Used for testing and debugging so far.
|
||||||
|
pub async fn base_client(&self) -> RwLockReadGuard<'_, BaseClient> {
|
||||||
|
self.base_client.read().await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculate the room name from a `RoomId`, returning a string.
|
||||||
|
pub async fn get_room_name(&self, room_id: &str) -> Option<String> {
|
||||||
|
self.base_client.read().await.calculate_room_name(room_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculate the room names this client knows about.
|
||||||
|
pub async fn get_room_names(&self) -> Vec<String> {
|
||||||
|
self.base_client.read().await.calculate_room_names()
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a callback that will be called every time the client receives a room
|
/// Add a callback that will be called every time the client receives a room
|
||||||
/// event
|
/// event
|
||||||
///
|
///
|
||||||
|
|
|
@ -24,7 +24,7 @@ use crate::events::room::{
|
||||||
name::{NameEvent},
|
name::{NameEvent},
|
||||||
};
|
};
|
||||||
use crate::events::EventResult;
|
use crate::events::EventResult;
|
||||||
use crate::identifiers::{RoomAliasId};
|
use crate::identifiers::RoomAliasId;
|
||||||
use crate::session::Session;
|
use crate::session::Session;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ impl RoomName {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn calculate_name(&self, room_id: &RoomId, members: &HashMap<UserId, RoomMember>) -> String {
|
pub fn calculate_name(&self, room_id: &str, members: &HashMap<UserId, RoomMember>) -> String {
|
||||||
// https://github.com/matrix-org/matrix-js-sdk/blob/33941eb37bffe41958ba9887fc8070dfb1a0ee76/src/models/room.js#L1823
|
// https://github.com/matrix-org/matrix-js-sdk/blob/33941eb37bffe41958ba9887fc8070dfb1a0ee76/src/models/room.js#L1823
|
||||||
// the order in which we check for a name ^^
|
// the order in which we check for a name ^^
|
||||||
if let Some(name) = &self.name {
|
if let Some(name) = &self.name {
|
||||||
|
@ -113,9 +113,10 @@ impl RoomName {
|
||||||
let mut names = members.values().flat_map(|m| m.display_name.clone()).take(3).collect::<Vec<_>>();
|
let mut names = members.values().flat_map(|m| m.display_name.clone()).take(3).collect::<Vec<_>>();
|
||||||
|
|
||||||
if names.is_empty() {
|
if names.is_empty() {
|
||||||
|
// TODO implement the rest of matrix-js-sdk handling of room names
|
||||||
format!("Room {}", room_id)
|
format!("Room {}", room_id)
|
||||||
} else {
|
} else {
|
||||||
// stablize order
|
// stabilize order
|
||||||
names.sort();
|
names.sort();
|
||||||
names.join(", ").to_string()
|
names.join(", ").to_string()
|
||||||
}
|
}
|
||||||
|
@ -351,6 +352,17 @@ impl Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn calculate_room_name(&self, room_id: &str) -> Option<String> {
|
||||||
|
self.joined_rooms.get(room_id)
|
||||||
|
.and_then(|r| r.read().map(|r| r.room_name.calculate_name(room_id, &r.members)).ok())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn calculate_room_names(&self) -> Vec<String> {
|
||||||
|
self.joined_rooms.iter()
|
||||||
|
.flat_map(|(id, room)| room.read().map(|r| r.room_name.calculate_name(id, &r.members)).ok())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn get_or_create_room(&mut self, room_id: &str) -> &mut Arc<RwLock<Room>> {
|
fn get_or_create_room(&mut self, room_id: &str) -> &mut Arc<RwLock<Room>> {
|
||||||
#[allow(clippy::or_fun_call)]
|
#[allow(clippy::or_fun_call)]
|
||||||
self.joined_rooms
|
self.joined_rooms
|
||||||
|
|
|
@ -58,3 +58,36 @@ fn sync() {
|
||||||
|
|
||||||
assert!(rt.block_on(client.sync_token()).is_some());
|
assert!(rt.block_on(client.sync_token()).is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn timeline() {
|
||||||
|
let mut rt = Runtime::new().unwrap();
|
||||||
|
|
||||||
|
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/timeline.json")
|
||||||
|
.create();
|
||||||
|
|
||||||
|
let mut client = AsyncClient::new(homeserver, Some(session)).unwrap();
|
||||||
|
|
||||||
|
let sync_settings = SyncSettings::new().timeout(3000).unwrap();
|
||||||
|
|
||||||
|
let _response = rt.block_on(client.sync(sync_settings)).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(vec!["tutorial"], rt.block_on(client.get_room_names()));
|
||||||
|
assert_eq!(Some("tutorial".into()), rt.block_on(client.get_room_name("!SVkFJHzfwvuaIEawgC:localhost")));
|
||||||
|
|
||||||
|
// rt.block_on(async { println!("{:#?}", &client.base_client().await.joined_rooms ) });
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,226 @@
|
||||||
|
{
|
||||||
|
"device_one_time_keys_count": {},
|
||||||
|
"next_batch": "s526_47314_0_7_1_1_1_11444_1",
|
||||||
|
"device_lists": {
|
||||||
|
"changed": [
|
||||||
|
"@example:example.org"
|
||||||
|
],
|
||||||
|
"left": []
|
||||||
|
},
|
||||||
|
|
||||||
|
"rooms": {
|
||||||
|
"invite": {},
|
||||||
|
"join": {
|
||||||
|
"!SVkFJHzfwvuaIEawgC:localhost": {
|
||||||
|
"account_data": {
|
||||||
|
"events": []
|
||||||
|
},
|
||||||
|
"ephemeral": {
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"$151680659217152dPKjd:localhost": {
|
||||||
|
"m.read": {
|
||||||
|
"@example:localhost": {
|
||||||
|
"ts": 1516809890615
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "m.receipt"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"join_rule": "public"
|
||||||
|
},
|
||||||
|
"event_id": "$15139375514WsgmR:localhost",
|
||||||
|
"origin_server_ts": 1513937551539,
|
||||||
|
"sender": "@example:localhost",
|
||||||
|
"state_key": "",
|
||||||
|
"type": "m.room.join_rules",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 7034220355
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"avatar_url": null,
|
||||||
|
"displayname": "example",
|
||||||
|
"membership": "join"
|
||||||
|
},
|
||||||
|
"event_id": "$151800140517rfvjc:localhost",
|
||||||
|
"membership": "join",
|
||||||
|
"origin_server_ts": 1518001405556,
|
||||||
|
"sender": "@example:localhost",
|
||||||
|
"state_key": "@example:localhost",
|
||||||
|
"type": "m.room.member",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 2970366338,
|
||||||
|
"replaces_state": "$151800111315tsynI:localhost"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"history_visibility": "shared"
|
||||||
|
},
|
||||||
|
"event_id": "$15139375515VaJEY:localhost",
|
||||||
|
"origin_server_ts": 1513937551613,
|
||||||
|
"sender": "@example:localhost",
|
||||||
|
"state_key": "",
|
||||||
|
"type": "m.room.history_visibility",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 7034220281
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"creator": "@example:localhost"
|
||||||
|
},
|
||||||
|
"event_id": "$15139375510KUZHi:localhost",
|
||||||
|
"origin_server_ts": 1513937551203,
|
||||||
|
"sender": "@example:localhost",
|
||||||
|
"state_key": "",
|
||||||
|
"type": "m.room.create",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 7034220691
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"aliases": [
|
||||||
|
"#tutorial:localhost"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"event_id": "$15139375516NUgtD:localhost",
|
||||||
|
"origin_server_ts": 1513937551720,
|
||||||
|
"sender": "@example:localhost",
|
||||||
|
"state_key": "localhost",
|
||||||
|
"type": "m.room.aliases",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 7034220174
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"topic": "\ud83d\ude00"
|
||||||
|
},
|
||||||
|
"event_id": "$151957878228ssqrJ:localhost",
|
||||||
|
"origin_server_ts": 1519578782185,
|
||||||
|
"sender": "@example:localhost",
|
||||||
|
"state_key": "",
|
||||||
|
"type": "m.room.topic",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 1392989709,
|
||||||
|
"prev_content": {
|
||||||
|
"topic": "test"
|
||||||
|
},
|
||||||
|
"prev_sender": "@example:localhost",
|
||||||
|
"replaces_state": "$151957069225EVYKm:localhost"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"ban": 50,
|
||||||
|
"events": {
|
||||||
|
"m.room.avatar": 50,
|
||||||
|
"m.room.canonical_alias": 50,
|
||||||
|
"m.room.history_visibility": 100,
|
||||||
|
"m.room.name": 50,
|
||||||
|
"m.room.power_levels": 100
|
||||||
|
},
|
||||||
|
"events_default": 0,
|
||||||
|
"invite": 0,
|
||||||
|
"kick": 50,
|
||||||
|
"redact": 50,
|
||||||
|
"state_default": 50,
|
||||||
|
"users": {
|
||||||
|
"@example:localhost": 100
|
||||||
|
},
|
||||||
|
"users_default": 0
|
||||||
|
},
|
||||||
|
"event_id": "$15139375512JaHAW:localhost",
|
||||||
|
"origin_server_ts": 1513937551359,
|
||||||
|
"sender": "@example:localhost",
|
||||||
|
"state_key": "",
|
||||||
|
"type": "m.room.power_levels",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 7034220535
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"alias": "#tutorial:localhost"
|
||||||
|
},
|
||||||
|
"event_id": "$15139375513VdeRF:localhost",
|
||||||
|
"origin_server_ts": 1513937551461,
|
||||||
|
"sender": "@example:localhost",
|
||||||
|
"state_key": "",
|
||||||
|
"type": "m.room.canonical_alias",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 7034220433
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"avatar_url": null,
|
||||||
|
"displayname": "example2",
|
||||||
|
"membership": "join"
|
||||||
|
},
|
||||||
|
"event_id": "$152034824468gOeNB:localhost",
|
||||||
|
"membership": "join",
|
||||||
|
"origin_server_ts": 1520348244605,
|
||||||
|
"sender": "@example2:localhost",
|
||||||
|
"state_key": "@example2:localhost",
|
||||||
|
"type": "m.room.member",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 623527289,
|
||||||
|
"prev_content": {
|
||||||
|
"membership": "leave"
|
||||||
|
},
|
||||||
|
"prev_sender": "@example:localhost",
|
||||||
|
"replaces_state": "$152034819067QWJxM:localhost"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"timeline": {
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"body": "baba",
|
||||||
|
"format": "org.matrix.custom.html",
|
||||||
|
"formatted_body": "<strong>baba</strong>",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"event_id": "$152037280074GZeOm:localhost",
|
||||||
|
"origin_server_ts": 1520372800469,
|
||||||
|
"sender": "@example:localhost",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"unsigned": {
|
||||||
|
"age": 598971425
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"limited": true,
|
||||||
|
"prev_batch": "t392-516_47314_0_7_1_1_1_11444_1"
|
||||||
|
},
|
||||||
|
"unread_notifications": {
|
||||||
|
"highlight_count": 0,
|
||||||
|
"notification_count": 11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"leave": {}
|
||||||
|
},
|
||||||
|
"to_device": {
|
||||||
|
"events": []
|
||||||
|
},
|
||||||
|
|
||||||
|
"presence": {
|
||||||
|
"events": []
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue