use revolt_result::Result;
use crate::Database;
auto_derived_partial!(
pub struct Bot {
#[serde(rename = "_id")]
pub id: String,
pub owner: String,
pub token: String,
pub public: bool,
#[serde(skip_serializing_if = "crate::if_false", default)]
pub analytics: bool,
#[serde(skip_serializing_if = "crate::if_false", default)]
pub discoverable: bool,
#[serde(skip_serializing_if = "String::is_empty", default)]
pub interactions_url: String,
#[serde(skip_serializing_if = "String::is_empty", default)]
pub terms_of_service_url: String,
#[serde(skip_serializing_if = "String::is_empty", default)]
pub privacy_policy_url: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub flags: Option<i32>,
},
"PartialBot"
);
auto_derived!(
#[repr(i32)]
pub enum BotFlags {
Verified = 1,
Official = 2,
}
pub enum FieldsBot {
Token,
InteractionsURL,
}
);
#[allow(clippy::disallowed_methods)]
impl Bot {
pub fn remove_field(&mut self, field: &FieldsBot) {
match field {
FieldsBot::Token => self.token = nanoid::nanoid!(64),
FieldsBot::InteractionsURL => {
self.interactions_url = String::new();
}
}
}
pub async fn update(
&mut self,
db: &Database,
mut partial: PartialBot,
remove: Vec<FieldsBot>,
) -> Result<()> {
if remove.contains(&FieldsBot::Token) {
partial.token = Some(nanoid::nanoid!(64));
}
for field in &remove {
self.remove_field(field);
}
db.update_bot(&self.id, &partial, remove).await?;
self.apply_options(partial);
Ok(())
}
pub async fn delete(&self, db: &Database) -> Result<()> {
db.delete_bot(&self.id).await
}
}
#[cfg(test)]
mod tests {
use crate::{Bot, FieldsBot, PartialBot};
#[async_std::test]
async fn crud() {
database_test!(|db| async move {
let bot_id = "bot";
let user_id = "user";
let token = "my_token";
let bot = Bot {
id: bot_id.to_string(),
owner: user_id.to_string(),
token: token.to_string(),
interactions_url: "some url".to_string(),
..Default::default()
};
db.insert_bot(&bot).await.unwrap();
let mut updated_bot = bot.clone();
updated_bot
.update(
&db,
PartialBot {
public: Some(true),
..Default::default()
},
vec![FieldsBot::Token, FieldsBot::InteractionsURL],
)
.await
.unwrap();
let fetched_bot1 = db.fetch_bot(bot_id).await.unwrap();
let fetched_bot2 = db.fetch_bot_by_token(&fetched_bot1.token).await.unwrap();
let fetched_bots = db.fetch_bots_by_user(user_id).await.unwrap();
assert!(!bot.public);
assert!(fetched_bot1.public);
assert!(!bot.interactions_url.is_empty());
assert!(fetched_bot1.interactions_url.is_empty());
assert_ne!(bot.token, fetched_bot1.token);
assert_eq!(updated_bot, fetched_bot1);
assert_eq!(fetched_bot1, fetched_bot2);
assert_eq!(fetched_bot1, fetched_bots[0]);
assert_eq!(1, db.get_number_of_bots_by_user(user_id).await.unwrap());
bot.delete(&db).await.unwrap();
assert!(db.fetch_bot(bot_id).await.is_err());
assert_eq!(0, db.get_number_of_bots_by_user(user_id).await.unwrap())
});
}
}