aboutsummaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
authorMishio595 <[email protected]>2018-08-01 15:38:12 -0600
committerMishio595 <[email protected]>2018-08-01 15:38:12 -0600
commitc5fb7b4b331ef5a66179539b065913078e55b668 (patch)
tree99bc28270eaad9acf3da3871e72ba67dac5b87eb /src/model
parentMerge branch 'asref_messageid_for_message' (diff)
parentDon't delay Ready with cache enabled (diff)
downloadserenity-c5fb7b4b331ef5a66179539b065913078e55b668.tar.xz
serenity-c5fb7b4b331ef5a66179539b065913078e55b668.zip
Merge branch 'upstream'
Diffstat (limited to 'src/model')
-rw-r--r--src/model/channel/channel_id.rs6
-rw-r--r--src/model/channel/mod.rs90
-rw-r--r--src/model/gateway.rs52
-rw-r--r--src/model/guild/guild_id.rs12
-rw-r--r--src/model/guild/mod.rs106
-rw-r--r--src/model/misc.rs80
-rw-r--r--src/model/user.rs73
7 files changed, 413 insertions, 6 deletions
diff --git a/src/model/channel/channel_id.rs b/src/model/channel/channel_id.rs
index 48003ef..ceb05c3 100644
--- a/src/model/channel/channel_id.rs
+++ b/src/model/channel/channel_id.rs
@@ -557,9 +557,9 @@ impl ChannelId {
/// over the limit.
///
/// [`Channel`]: enum.Channel.html
- /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong
- /// [`CreateMessage`]: ../builder/struct.CreateMessage.html
- /// [Send Messages]: permissions/constant.SEND_MESSAGES.html
+ /// [`ModelError::MessageTooLong`]: ../error/enum.Error.html#variant.MessageTooLong
+ /// [`CreateMessage`]: ../../builder/struct.CreateMessage.html
+ /// [Send Messages]: ../permissions/struct.Permissions.html#associatedconstant.SEND_MESSAGES
#[cfg(feature = "utils")]
pub fn send_message<F>(&self, f: F) -> Result<Message>
where F: FnOnce(CreateMessage) -> CreateMessage {
diff --git a/src/model/channel/mod.rs b/src/model/channel/mod.rs
index 8d586a6..e0ef085 100644
--- a/src/model/channel/mod.rs
+++ b/src/model/channel/mod.rs
@@ -677,3 +677,93 @@ pub enum PermissionOverwriteType {
/// A role which is having its permission overwrites edited.
Role(RoleId),
}
+
+#[cfg(test)]
+mod test {
+ #[cfg(feature = "utils")]
+ mod utils {
+ use model::prelude::*;
+ use parking_lot::RwLock;
+ use std::collections::HashMap;
+ use std::sync::Arc;
+
+ fn group() -> Group {
+ Group {
+ channel_id: ChannelId(1),
+ icon: None,
+ last_message_id: None,
+ last_pin_timestamp: None,
+ name: None,
+ owner_id: UserId(2),
+ recipients: HashMap::new(),
+ }
+ }
+
+ fn guild_channel() -> GuildChannel {
+ GuildChannel {
+ id: ChannelId(1),
+ bitrate: None,
+ category_id: None,
+ guild_id: GuildId(2),
+ kind: ChannelType::Text,
+ last_message_id: None,
+ last_pin_timestamp: None,
+ name: "nsfw-stuff".to_string(),
+ permission_overwrites: vec![],
+ position: 0,
+ topic: None,
+ user_limit: None,
+ nsfw: false,
+ }
+ }
+
+ fn private_channel() -> PrivateChannel {
+ PrivateChannel {
+ id: ChannelId(1),
+ last_message_id: None,
+ last_pin_timestamp: None,
+ kind: ChannelType::Private,
+ recipient: Arc::new(RwLock::new(User {
+ id: UserId(2),
+ avatar: None,
+ bot: false,
+ discriminator: 1,
+ name: "ab".to_string(),
+ })),
+ }
+ }
+
+ #[test]
+ fn nsfw_checks() {
+ let mut channel = guild_channel();
+ assert!(channel.is_nsfw());
+ channel.kind = ChannelType::Voice;
+ assert!(!channel.is_nsfw());
+
+ channel.kind = ChannelType::Text;
+ channel.name = "nsfw-".to_string();
+ assert!(!channel.is_nsfw());
+
+ channel.name = "nsfw".to_string();
+ assert!(channel.is_nsfw());
+ channel.kind = ChannelType::Voice;
+ assert!(!channel.is_nsfw());
+ channel.kind = ChannelType::Text;
+
+ channel.name = "nsf".to_string();
+ channel.nsfw = true;
+ assert!(channel.is_nsfw());
+ channel.nsfw = false;
+ assert!(!channel.is_nsfw());
+
+ let channel = Channel::Guild(Arc::new(RwLock::new(channel)));
+ assert!(!channel.is_nsfw());
+
+ let group = group();
+ assert!(!group.is_nsfw());
+
+ let private_channel = private_channel();
+ assert!(!private_channel.is_nsfw());
+ }
+ }
+}
diff --git a/src/model/gateway.rs b/src/model/gateway.rs
index b73d900..9af4a7e 100644
--- a/src/model/gateway.rs
+++ b/src/model/gateway.rs
@@ -131,6 +131,58 @@ impl Game {
}
}
+impl<'a> From<&'a str> for Game {
+ fn from(name: &'a str) -> Self {
+ Game::playing(name)
+ }
+}
+
+impl From<String> for Game {
+ fn from(name: String) -> Self {
+ Game::playing(&name)
+ }
+}
+
+impl<'a> From<(String, GameType)> for Game {
+ fn from((name, kind): (String, GameType)) -> Self {
+ Self {
+ url: None,
+ kind,
+ name,
+ }
+ }
+}
+
+impl<'a> From<(&'a str, &'a str)> for Game {
+ fn from((name, url): (&'a str, &'a str)) -> Self {
+ Self {
+ kind: GameType::Streaming,
+ name: name.to_owned(),
+ url: Some(url.to_owned()),
+ }
+ }
+}
+
+impl From<(String, String)> for Game {
+ fn from((name, url): (String, String)) -> Self {
+ Self {
+ kind: GameType::Streaming,
+ url: Some(url),
+ name,
+ }
+ }
+}
+
+impl From<(String, GameType, String)> for Game {
+ fn from((name, kind, url): (String, GameType, String)) -> Self {
+ Self {
+ url: Some(url),
+ kind,
+ name,
+ }
+ }
+}
+
impl<'de> Deserialize<'de> for Game {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
let mut map = JsonMap::deserialize(deserializer)?;
diff --git a/src/model/guild/guild_id.rs b/src/model/guild/guild_id.rs
index 9c3120a..ebe930e 100644
--- a/src/model/guild/guild_id.rs
+++ b/src/model/guild/guild_id.rs
@@ -444,7 +444,10 @@ impl GuildId {
#[inline]
pub fn leave(&self) -> Result<()> { http::leave_guild(self.0) }
- /// Gets a user's [`Member`] for the guild by Id.
+ /// Gets a user's [`Member`] for the guild by Id.
+ ///
+ /// If the cache feature is enabled the cache will be checked
+ /// first. If not found it will resort to an http request.
///
/// [`Guild`]: struct.Guild.html
/// [`Member`]: struct.Member.html
@@ -454,6 +457,13 @@ impl GuildId {
}
fn _member(&self, user_id: UserId) -> Result<Member> {
+ #[cfg(feature = "cache")]
+ {
+ if let Some(member) = CACHE.read().member(self.0, user_id) {
+ return Ok(member);
+ }
+ }
+
http::get_member(self.0, user_id.0)
}
diff --git a/src/model/guild/mod.rs b/src/model/guild/mod.rs
index 67b0f0e..30651d6 100644
--- a/src/model/guild/mod.rs
+++ b/src/model/guild/mod.rs
@@ -2015,3 +2015,109 @@ impl VerificationLevel {
}
}
}
+
+#[cfg(test)]
+mod test {
+ #[cfg(feature = "model")]
+ mod model {
+ use chrono::prelude::*;
+ use model::prelude::*;
+ use std::collections::*;
+ use std::sync::Arc;
+
+ fn gen_user() -> User {
+ User {
+ id: UserId(210),
+ avatar: Some("abc".to_string()),
+ bot: true,
+ discriminator: 1432,
+ name: "test".to_string(),
+ }
+ }
+
+ fn gen_member() -> Member {
+ let dt: DateTime<FixedOffset> = FixedOffset::east(5 * 3600)
+ .ymd(2016, 11, 08)
+ .and_hms(0, 0, 0);
+ let vec1 = Vec::new();
+ let u = Arc::new(RwLock::new(gen_user()));
+
+ Member {
+ deaf: false,
+ guild_id: GuildId(1),
+ joined_at: Some(dt),
+ mute: false,
+ nick: Some("aaaa".to_string()),
+ roles: vec1,
+ user: u,
+ }
+ }
+
+ fn gen() -> Guild {
+ let u = gen_user();
+ let m = gen_member();
+
+ let hm1 = HashMap::new();
+ let hm2 = HashMap::new();
+ let vec1 = Vec::new();
+ let dt: DateTime<FixedOffset> = FixedOffset::east(5 * 3600)
+ .ymd(2016, 11, 08)
+ .and_hms(0, 0, 0);
+ let mut hm3 = HashMap::new();
+ let hm4 = HashMap::new();
+ let hm5 = HashMap::new();
+ let hm6 = HashMap::new();
+
+ hm3.insert(u.id, m);
+
+ let notifications = DefaultMessageNotificationLevel::All;
+
+ Guild {
+ afk_channel_id: Some(ChannelId(0)),
+ afk_timeout: 0,
+ channels: hm1,
+ default_message_notifications: notifications,
+ emojis: hm2,
+ features: vec1,
+ icon: Some("/avatars/210/a_aaa.webp?size=1024".to_string()),
+ id: GuildId(1),
+ joined_at: dt,
+ large: false,
+ member_count: 1,
+ members: hm3,
+ mfa_level: MfaLevel::Elevated,
+ name: "Spaghetti".to_string(),
+ owner_id: UserId(210),
+ presences: hm4,
+ region: "NA".to_string(),
+ roles: hm5,
+ splash: Some("asdf".to_string()),
+ verification_level: VerificationLevel::None,
+ voice_states: hm6,
+ application_id: Some(ApplicationId(0)),
+ explicit_content_filter: ExplicitContentFilter::None,
+ system_channel_id: Some(ChannelId(0)),
+ }
+ }
+
+
+ #[test]
+ fn member_named_username() {
+ let guild = gen();
+ let lhs = guild
+ .member_named("test#1432")
+ .unwrap()
+ .display_name();
+
+ assert_eq!(lhs, gen_member().display_name());
+ }
+
+ #[test]
+ fn member_named_nickname() {
+ let guild = gen();
+ let lhs = guild.member_named("aaaa").unwrap().display_name();
+
+ assert_eq!(lhs, gen_member().display_name());
+ }
+ }
+}
diff --git a/src/model/misc.rs b/src/model/misc.rs
index 3195c55..62a002a 100644
--- a/src/model/misc.rs
+++ b/src/model/misc.rs
@@ -308,3 +308,83 @@ pub struct Maintenance {
pub start: String,
pub stop: String,
}
+
+#[cfg(test)]
+mod test {
+ use model::prelude::*;
+ use parking_lot::RwLock;
+ use std::sync::Arc;
+ use utils::Colour;
+
+ #[test]
+ fn test_formatters() {
+ assert_eq!(ChannelId(1).to_string(), "1");
+ assert_eq!(EmojiId(2).to_string(), "2");
+ assert_eq!(GuildId(3).to_string(), "3");
+ assert_eq!(RoleId(4).to_string(), "4");
+ assert_eq!(UserId(5).to_string(), "5");
+ }
+
+ #[cfg(feature = "utils")]
+ #[test]
+ fn test_mention() {
+ let channel = Channel::Guild(Arc::new(RwLock::new(GuildChannel {
+ bitrate: None,
+ category_id: None,
+ guild_id: GuildId(1),
+ kind: ChannelType::Text,
+ id: ChannelId(4),
+ last_message_id: None,
+ last_pin_timestamp: None,
+ name: "a".to_string(),
+ permission_overwrites: vec![],
+ position: 1,
+ topic: None,
+ user_limit: None,
+ nsfw: false,
+ })));
+ let emoji = Emoji {
+ animated: false,
+ id: EmojiId(5),
+ name: "a".to_string(),
+ managed: true,
+ require_colons: true,
+ roles: vec![],
+ };
+ let role = Role {
+ id: RoleId(2),
+ colour: Colour::ROSEWATER,
+ hoist: false,
+ managed: false,
+ mentionable: false,
+ name: "fake role".to_string(),
+ permissions: Permissions::empty(),
+ position: 1,
+ };
+ let user = User {
+ id: UserId(6),
+ avatar: None,
+ bot: false,
+ discriminator: 4132,
+ name: "fake".to_string(),
+ };
+ let member = Member {
+ deaf: false,
+ guild_id: GuildId(2),
+ joined_at: None,
+ mute: false,
+ nick: None,
+ roles: vec![],
+ user: Arc::new(RwLock::new(user.clone())),
+ };
+
+ assert_eq!(ChannelId(1).mention(), "<#1>");
+ assert_eq!(channel.mention(), "<#4>");
+ assert_eq!(emoji.mention(), "<:a:5>");
+ assert_eq!(member.mention(), "<@6>");
+ assert_eq!(role.mention(), "<@&2>");
+ assert_eq!(role.id.mention(), "<@&2>");
+ assert_eq!(user.mention(), "<@6>");
+ assert_eq!(user.id.mention(), "<@6>");
+ }
+}
diff --git a/src/model/user.rs b/src/model/user.rs
index a378be5..d76b135 100644
--- a/src/model/user.rs
+++ b/src/model/user.rs
@@ -738,9 +738,10 @@ impl UserId {
#[cfg(feature = "cache")]
pub fn find(&self) -> Option<Arc<RwLock<User>>> { CACHE.read().user(*self) }
- /// Gets a user by its Id over the REST API.
+ /// Gets a user by its Id from either the cache or the REST API.
///
- /// **Note**: The current user must be a bot user.
+ /// Searches the cache for the user first, if the cache is enabled. If the
+ /// user was not found, then the user is searched via the REST API.
#[inline]
pub fn get(&self) -> Result<User> {
#[cfg(feature = "cache")]
@@ -843,3 +844,71 @@ fn tag(name: &str, discriminator: u16) -> String {
tag
}
+
+#[cfg(test)]
+mod test {
+ #[cfg(feature = "model")]
+ mod model {
+ use model::id::UserId;
+ use model::user::User;
+
+ fn gen() -> User {
+ User {
+ id: UserId(210),
+ avatar: Some("abc".to_string()),
+ bot: true,
+ discriminator: 1432,
+ name: "test".to_string(),
+ }
+ }
+
+ #[test]
+ fn test_core() {
+ let mut user = gen();
+
+ assert!(
+ user.avatar_url()
+ .unwrap()
+ .ends_with("/avatars/210/abc.webp?size=1024")
+ );
+ assert!(
+ user.static_avatar_url()
+ .unwrap()
+ .ends_with("/avatars/210/abc.webp?size=1024")
+ );
+
+ user.avatar = Some("a_aaa".to_string());
+ assert!(
+ user.avatar_url()
+ .unwrap()
+ .ends_with("/avatars/210/a_aaa.gif?size=1024")
+ );
+ assert!(
+ user.static_avatar_url()
+ .unwrap()
+ .ends_with("/avatars/210/a_aaa.webp?size=1024")
+ );
+
+ user.avatar = None;
+ assert!(user.avatar_url().is_none());
+
+ assert_eq!(user.tag(), "test#1432");
+ }
+
+ #[test]
+ fn default_avatars() {
+ let mut user = gen();
+
+ user.discriminator = 0;
+ assert!(user.default_avatar_url().ends_with("0.png"));
+ user.discriminator = 1;
+ assert!(user.default_avatar_url().ends_with("1.png"));
+ user.discriminator = 2;
+ assert!(user.default_avatar_url().ends_with("2.png"));
+ user.discriminator = 3;
+ assert!(user.default_avatar_url().ends_with("3.png"));
+ user.discriminator = 4;
+ assert!(user.default_avatar_url().ends_with("4.png"));
+ }
+ }
+}