add tests in models files, run coverage

master
Devin R 2020-03-31 09:01:48 -04:00
parent 0d79c3574e
commit df58c60d2e
6 changed files with 251 additions and 8 deletions

View File

@ -62,7 +62,7 @@ pub struct AsyncClient {
/// The underlying HTTP client. /// The underlying HTTP client.
http_client: reqwest::Client, http_client: reqwest::Client,
/// User session data. /// User session data.
base_client: Arc<RwLock<BaseClient>>, pub(crate) base_client: Arc<RwLock<BaseClient>>,
/// The transaction id. /// The transaction id.
transaction_id: Arc<AtomicU64>, transaction_id: Arc<AtomicU64>,
/// Event callbacks /// Event callbacks

View File

@ -71,9 +71,20 @@ pub struct CurrentRoom {
} }
impl CurrentRoom { impl CurrentRoom {
// TODO when UserId is isomorphic to &str clean this up.
pub(crate) fn comes_after(&self, user: &Uid, event: &PresenceEvent) -> bool { pub(crate) fn comes_after(&self, user: &Uid, event: &PresenceEvent) -> bool {
if user == &event.sender { let u = user.to_string();
let u = u.split(':').next();
let s = event.sender.to_string();
let s = s.split(':').next();
if u == s {
if self.last_active.is_none() {
true
} else {
event.content.last_active_ago < self.last_active event.content.last_active_ago < self.last_active
}
} else { } else {
false false
} }
@ -327,6 +338,7 @@ impl Client {
.as_ref() .as_ref()
.expect("to receive events you must be logged in") .expect("to receive events you must be logged in")
.user_id; .user_id;
if self.current_room_id.comes_after(user_id, event) { if self.current_room_id.comes_after(user_id, event) {
self.current_room_id.update(room_id, event); self.current_room_id.update(room_id, event);
} }
@ -424,3 +436,48 @@ impl Client {
Ok(()) Ok(())
} }
} }
#[cfg(test)]
mod test {
use super::*;
use crate::events::room::member::MembershipState;
use crate::identifiers::UserId;
use crate::{AsyncClient, Session, SyncSettings};
use mockito::{mock, Matcher};
use tokio::runtime::Runtime;
use url::Url;
use std::convert::TryFrom;
use std::str::FromStr;
use std::time::Duration;
#[tokio::test]
async fn account_data() {
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 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();
let bc = &client.base_client.read().await;
assert_eq!(1, bc.ignored_users.len())
}
}

View File

@ -296,3 +296,57 @@ impl Room {
} }
} }
} }
#[cfg(test)]
mod test {
use super::*;
use crate::events::room::member::MembershipState;
use crate::identifiers::UserId;
use crate::{AsyncClient, Session, SyncSettings};
use mockito::{mock, Matcher};
use tokio::runtime::Runtime;
use url::Url;
use std::convert::TryFrom;
use std::str::FromStr;
use std::time::Duration;
#[tokio::test]
async fn user_presence() {
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 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();
let rooms = &client.base_client.read().await.joined_rooms;
let room = &rooms
.get("!SVkFJHzfwvuaIEawgC:localhost")
.unwrap()
.read()
.unwrap();
assert_eq!(2, room.members.len());
for (id, member) in &room.members {
assert_eq!(MembershipState::Join, member.membership);
}
}
}

View File

@ -110,10 +110,10 @@ impl RoomMember {
let mut changed = false; let mut changed = false;
if let Some(user_power) = event.content.users.get(&self.user_id) { if let Some(user_power) = event.content.users.get(&self.user_id) {
changed = self.power_level == Some(*user_power); changed = self.power_level != Some(*user_power);
self.power_level = Some(*user_power); self.power_level = Some(*user_power);
} else { } else {
changed = self.power_level == Some(event.content.users_default); changed = self.power_level != Some(event.content.users_default);
self.power_level = Some(event.content.users_default); self.power_level = Some(event.content.users_default);
} }
@ -124,3 +124,89 @@ impl RoomMember {
changed changed
} }
} }
#[cfg(test)]
mod test {
use super::*;
use crate::identifiers::{EventId, RoomId, UserId};
use crate::{AsyncClient, Session, SyncSettings};
use js_int::{Int, UInt};
use mockito::{mock, Matcher};
use tokio::runtime::Runtime;
use url::Url;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::str::FromStr;
use std::time::Duration;
use crate::events::room::power_levels::{
NotificationPowerLevels, PowerLevelsEvent, PowerLevelsEventContent,
};
#[tokio::test]
async fn member_power() {
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 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();
let mut rooms = client.base_client.write().await.joined_rooms.clone();
let mut room = rooms
.get_mut("!SVkFJHzfwvuaIEawgC:localhost")
.unwrap()
.write()
.unwrap();
for (id, member) in &mut room.members {
let power = power_levels();
assert!(member.update_power(&power));
assert_eq!(MembershipState::Join, member.membership);
}
}
fn power_levels() -> PowerLevelsEvent {
PowerLevelsEvent {
content: PowerLevelsEventContent {
ban: Int::new(40).unwrap(),
events: HashMap::default(),
events_default: Int::new(40).unwrap(),
invite: Int::new(40).unwrap(),
kick: Int::new(40).unwrap(),
redact: Int::new(40).unwrap(),
state_default: Int::new(40).unwrap(),
users: HashMap::default(),
users_default: Int::new(40).unwrap(),
notifications: NotificationPowerLevels {
room: Int::new(35).unwrap(),
},
},
event_id: EventId::try_from("$h29iv0s8:example.com").unwrap(),
origin_server_ts: UInt::new(1520372800469).unwrap(),
prev_content: None,
room_id: RoomId::try_from("!roomid:room.com").ok(),
unsigned: None,
sender: UserId::try_from("@example:example.com").unwrap(),
state_key: "@example:example.com".into(),
}
}
}

View File

@ -59,7 +59,7 @@ async fn sync() {
} }
#[tokio::test] #[tokio::test]
async fn timeline() { async fn room_names() {
let homeserver = Url::from_str(&mockito::server_url()).unwrap(); let homeserver = Url::from_str(&mockito::server_url()).unwrap();
let session = Session { let session = Session {
@ -88,3 +88,33 @@ async fn timeline() {
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: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 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())
);
}

View File

@ -12,7 +12,23 @@
"join": { "join": {
"!SVkFJHzfwvuaIEawgC:localhost": { "!SVkFJHzfwvuaIEawgC:localhost": {
"account_data": { "account_data": {
"events": [] "events": [
{
"content": {
"event_id": "$someplace:example.org"
},
"room_id": "!roomid:room.com",
"type": "m.fully_read"
},
{
"content": {
"ignored_users": {
"@someone:example.org": {}
}
},
"type": "m.ignored_user_list"
}
]
}, },
"ephemeral": { "ephemeral": {
"events": [ "events": [
@ -248,7 +264,7 @@
"content": { "content": {
"avatar_url": "mxc://localhost:wefuiwegh8742w", "avatar_url": "mxc://localhost:wefuiwegh8742w",
"currently_active": false, "currently_active": false,
"last_active_ago": 2478593, "last_active_ago": 1,
"presence": "online", "presence": "online",
"status_msg": "Making cupcakes" "status_msg": "Making cupcakes"
}, },