mirror of
https://github.com/chatmail/core.git
synced 2026-05-02 12:56:30 +03:00
allow adding info-message with defined commands, add tests for that and for set_protection()
This commit is contained in:
138
src/chat.rs
138
src/chat.rs
@@ -2900,18 +2900,22 @@ pub(crate) async fn delete_and_reset_all_device_msgs(context: &Context) -> Resul
|
|||||||
/// Adds an informational message to chat.
|
/// Adds an informational message to chat.
|
||||||
///
|
///
|
||||||
/// For example, it can be a message showing that a member was added to a group.
|
/// For example, it can be a message showing that a member was added to a group.
|
||||||
pub(crate) async fn add_info_msg(context: &Context, chat_id: ChatId, text: impl AsRef<str>) {
|
pub(crate) async fn add_info_msg_with_cmd(
|
||||||
|
context: &Context,
|
||||||
|
chat_id: ChatId,
|
||||||
|
text: impl AsRef<str>,
|
||||||
|
cmd: SystemMessage,
|
||||||
|
) -> Result<MsgId, Error> {
|
||||||
let rfc724_mid = dc_create_outgoing_rfc724_mid(None, "@device");
|
let rfc724_mid = dc_create_outgoing_rfc724_mid(None, "@device");
|
||||||
let ephemeral_timer = match chat_id.get_ephemeral_timer(context).await {
|
let ephemeral_timer = chat_id.get_ephemeral_timer(context).await?;
|
||||||
Err(e) => {
|
|
||||||
warn!(context, "Could not get timer for info msg: {}", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Ok(ephemeral_timer) => ephemeral_timer,
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Err(e) = context.sql.execute(
|
let mut param = Params::new();
|
||||||
"INSERT INTO msgs (chat_id,from_id,to_id, timestamp,type,state, txt,rfc724_mid,ephemeral_timer) VALUES (?,?,?, ?,?,?, ?,?,?);",
|
if cmd != SystemMessage::Unknown {
|
||||||
|
param.set_cmd(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
context.sql.execute(
|
||||||
|
"INSERT INTO msgs (chat_id,from_id,to_id, timestamp,type,state, txt,rfc724_mid,ephemeral_timer, param) VALUES (?,?,?, ?,?,?, ?,?,?, ?);",
|
||||||
paramsv![
|
paramsv![
|
||||||
chat_id,
|
chat_id,
|
||||||
DC_CONTACT_ID_INFO,
|
DC_CONTACT_ID_INFO,
|
||||||
@@ -2921,22 +2925,25 @@ pub(crate) async fn add_info_msg(context: &Context, chat_id: ChatId, text: impl
|
|||||||
MessageState::InNoticed,
|
MessageState::InNoticed,
|
||||||
text.as_ref().to_string(),
|
text.as_ref().to_string(),
|
||||||
rfc724_mid,
|
rfc724_mid,
|
||||||
ephemeral_timer
|
ephemeral_timer,
|
||||||
|
param.to_string(),
|
||||||
]
|
]
|
||||||
).await {
|
).await?;
|
||||||
warn!(context, "Could not add info msg: {}", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let row_id = context
|
let row_id = context
|
||||||
.sql
|
.sql
|
||||||
.get_rowid(context, "msgs", "rfc724_mid", &rfc724_mid)
|
.get_rowid(context, "msgs", "rfc724_mid", &rfc724_mid)
|
||||||
.await
|
.await
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
context.emit_event(EventType::MsgsChanged {
|
let msg_id = MsgId::new(row_id);
|
||||||
chat_id,
|
context.emit_event(EventType::MsgsChanged { chat_id, msg_id });
|
||||||
msg_id: MsgId::new(row_id),
|
Ok(msg_id)
|
||||||
});
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn add_info_msg(context: &Context, chat_id: ChatId, text: impl AsRef<str>) {
|
||||||
|
if let Err(e) = add_info_msg_with_cmd(context, chat_id, text, SystemMessage::Unknown).await {
|
||||||
|
warn!(context, "Could not add info msg: {}", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -3591,4 +3598,97 @@ mod tests {
|
|||||||
false
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_std::test]
|
||||||
|
async fn test_add_info_msg() {
|
||||||
|
let t = TestContext::new().await;
|
||||||
|
let chat_id = create_group_chat(&t.ctx, ProtectionStatus::Unprotected, "foo")
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let msg_id = add_info_msg_with_cmd(
|
||||||
|
&t.ctx,
|
||||||
|
chat_id,
|
||||||
|
"foo bar info",
|
||||||
|
SystemMessage::EphemeralTimerChanged,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let msg = Message::load_from_db(&t.ctx, msg_id).await.unwrap();
|
||||||
|
assert_eq!(msg.get_chat_id(), chat_id);
|
||||||
|
assert_eq!(msg.get_viewtype(), Viewtype::Text);
|
||||||
|
assert_eq!(msg.get_text().unwrap(), "foo bar info");
|
||||||
|
assert!(msg.is_info());
|
||||||
|
assert_eq!(msg.get_info_type(), SystemMessage::EphemeralTimerChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_std::test]
|
||||||
|
async fn test_set_protection() {
|
||||||
|
let t = TestContext::new_alice().await;
|
||||||
|
let chat_id = create_group_chat(&t.ctx, ProtectionStatus::Unprotected, "foo")
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let chat = Chat::load_from_db(&t.ctx, chat_id).await.unwrap();
|
||||||
|
assert!(!chat.is_protected());
|
||||||
|
assert!(chat.is_unpromoted());
|
||||||
|
|
||||||
|
// enable protection on unpromoted chat, the info-message is added via add_info_msg()
|
||||||
|
chat_id
|
||||||
|
.set_protection(&t.ctx, ProtectionStatus::Protected)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let chat = Chat::load_from_db(&t.ctx, chat_id).await.unwrap();
|
||||||
|
assert!(chat.is_protected());
|
||||||
|
assert!(chat.is_unpromoted());
|
||||||
|
|
||||||
|
let msgs = get_chat_msgs(&t.ctx, chat_id, 0, None).await;
|
||||||
|
assert_eq!(msgs.len(), 1);
|
||||||
|
|
||||||
|
let msg = t.get_last_msg(chat_id).await;
|
||||||
|
assert!(msg.is_info());
|
||||||
|
assert_eq!(msg.get_info_type(), SystemMessage::ChatProtectionEnabled);
|
||||||
|
assert_eq!(msg.get_state(), MessageState::InNoticed);
|
||||||
|
|
||||||
|
// disable protection again, still unpromoted
|
||||||
|
chat_id
|
||||||
|
.set_protection(&t.ctx, ProtectionStatus::Unprotected)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let chat = Chat::load_from_db(&t.ctx, chat_id).await.unwrap();
|
||||||
|
assert!(!chat.is_protected());
|
||||||
|
assert!(chat.is_unpromoted());
|
||||||
|
|
||||||
|
let msg = t.get_last_msg(chat_id).await;
|
||||||
|
assert!(msg.is_info());
|
||||||
|
assert_eq!(msg.get_info_type(), SystemMessage::ChatProtectionDisabled);
|
||||||
|
assert_eq!(msg.get_state(), MessageState::InNoticed);
|
||||||
|
|
||||||
|
// send a message, this switches to promoted state
|
||||||
|
send_text_msg(&t.ctx, chat_id, "hi!".to_string())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let chat = Chat::load_from_db(&t.ctx, chat_id).await.unwrap();
|
||||||
|
assert!(!chat.is_protected());
|
||||||
|
assert!(!chat.is_unpromoted());
|
||||||
|
|
||||||
|
let msgs = get_chat_msgs(&t.ctx, chat_id, 0, None).await;
|
||||||
|
assert_eq!(msgs.len(), 3);
|
||||||
|
|
||||||
|
// enable protection on promoted chat, the info-message is sent via send_msg() this time
|
||||||
|
chat_id
|
||||||
|
.set_protection(&t.ctx, ProtectionStatus::Protected)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let chat = Chat::load_from_db(&t.ctx, chat_id).await.unwrap();
|
||||||
|
assert!(chat.is_protected());
|
||||||
|
assert!(!chat.is_unpromoted());
|
||||||
|
|
||||||
|
let msg = t.get_last_msg(chat_id).await;
|
||||||
|
assert!(msg.is_info());
|
||||||
|
assert_eq!(msg.get_info_type(), SystemMessage::ChatProtectionEnabled);
|
||||||
|
assert_eq!(msg.get_state(), MessageState::OutDelivered); // as bcc-self is disabled and there is nobody else in the chat
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,15 @@ use async_std::path::PathBuf;
|
|||||||
use async_std::sync::RwLock;
|
use async_std::sync::RwLock;
|
||||||
use tempfile::{tempdir, TempDir};
|
use tempfile::{tempdir, TempDir};
|
||||||
|
|
||||||
use crate::chat::ChatId;
|
use crate::chat;
|
||||||
|
use crate::chat::{ChatId, ChatItem};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::dc_receive_imf::dc_receive_imf;
|
use crate::dc_receive_imf::dc_receive_imf;
|
||||||
use crate::dc_tools::EmailAddress;
|
use crate::dc_tools::EmailAddress;
|
||||||
use crate::job::Action;
|
use crate::job::Action;
|
||||||
use crate::key::{self, DcKey};
|
use crate::key::{self, DcKey};
|
||||||
|
use crate::message::Message;
|
||||||
use crate::mimeparser::MimeMessage;
|
use crate::mimeparser::MimeMessage;
|
||||||
use crate::param::{Param, Params};
|
use crate::param::{Param, Params};
|
||||||
|
|
||||||
@@ -187,6 +189,19 @@ impl TestContext {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the most recent message of a chat.
|
||||||
|
///
|
||||||
|
/// Panics on errors or if the most recent message is a marker.
|
||||||
|
pub async fn get_last_msg(&self, chat_id: ChatId) -> Message {
|
||||||
|
let msgs = chat::get_chat_msgs(&self.ctx, chat_id, 0, None).await;
|
||||||
|
let msg_id = if let ChatItem::Message { msg_id } = msgs.last().unwrap() {
|
||||||
|
msg_id
|
||||||
|
} else {
|
||||||
|
panic!("Wrong item type");
|
||||||
|
};
|
||||||
|
Message::load_from_db(&self.ctx, *msg_id).await.unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A raw message as it was scheduled to be sent.
|
/// A raw message as it was scheduled to be sent.
|
||||||
|
|||||||
Reference in New Issue
Block a user