Delete messages more thoroughly (and at all) (#2114)

- Make sure delete_expired_messages and housekeeping runs once a day
- delete more info about messages when putting them to trash (esp. also
delete txt_raw, from_id and to_id as we don't need those anymore, so
they are data that was unnecessarily kept)

fix #1926, fix #2090

Also:

* Nicer test_utils: add send_text() and print_chat()

* Adapt ephemeral messages for testing (make them accurate to the second)

* Add test for ephemeral messages

* Make pop_sent_msg() really pop the last sent message
This commit is contained in:
Hocuri
2020-12-26 18:29:43 +01:00
committed by GitHub
parent 86a8767d94
commit 78fd0c285b
7 changed files with 212 additions and 15 deletions

View File

@@ -278,10 +278,10 @@ pub(crate) async fn delete_expired_messages(context: &Context) -> Result<bool, E
.sql
.execute(
"UPDATE msgs \
SET txt = 'DELETED', chat_id = ? \
SET chat_id=?, txt='', txt_raw='', from_id=0, to_id=0, param='' \
WHERE \
ephemeral_timestamp != 0 \
AND ephemeral_timestamp < ? \
AND ephemeral_timestamp <= ? \
AND chat_id != ?",
paramsv![DC_CHAT_ID_TRASH, time(), DC_CHAT_ID_TRASH],
)
@@ -417,7 +417,7 @@ pub(crate) async fn load_imap_deletion_msgid(context: &Context) -> sql::Result<O
"SELECT id FROM msgs \
WHERE ( \
timestamp < ? \
OR (ephemeral_timestamp != 0 AND ephemeral_timestamp < ?) \
OR (ephemeral_timestamp != 0 AND ephemeral_timestamp <= ?) \
) \
AND server_uid != 0 \
LIMIT 1",
@@ -459,9 +459,14 @@ pub(crate) async fn start_ephemeral_timers(context: &Context) -> sql::Result<()>
#[cfg(test)]
mod tests {
use async_std::task::sleep;
use super::*;
use crate::chat;
use crate::test_utils::*;
use crate::{
chat::{self, Chat, ChatItem},
dc_tools::IsNoneOrEmpty,
};
#[async_std::test]
async fn test_stock_ephemeral_messages() {
@@ -588,4 +593,51 @@ mod tests {
Ok(())
}
#[async_std::test]
async fn test_ephemeral_delete_msgs() {
let t = TestContext::new_alice().await;
let chat = t.get_self_chat().await;
t.send_text(chat.id, "Saved message, which we delete manually")
.await;
let msg = t.get_last_msg(chat.id).await;
msg.id.delete_from_db(&t).await.unwrap();
check_msg_was_deleted(&t, &chat, msg.id).await;
chat.id
.set_ephemeral_timer(&t, Timer::Enabled { duration: 1 })
.await
.unwrap();
let msg = t
.send_text(chat.id, "Saved message, disappearing after 1s")
.await;
sleep(Duration::from_millis(1100)).await;
check_msg_was_deleted(&t, &chat, msg.sender_msg_id).await;
}
async fn check_msg_was_deleted(t: &TestContext, chat: &Chat, msg_id: MsgId) {
let chat_items = chat::get_chat_msgs(&t, chat.id, 0, None).await;
// Check that the chat is empty except for possibly info messages:
for item in &chat_items {
if let ChatItem::Message { msg_id } = item {
let msg = Message::load_from_db(t, *msg_id).await.unwrap();
assert!(msg.is_info())
}
}
// Check that if there is a message left, the text and metadata are gone
if let Ok(msg) = Message::load_from_db(&t, msg_id).await {
assert_eq!(msg.from_id, 0);
assert_eq!(msg.to_id, 0);
assert!(msg.text.is_none_or_empty(), msg.text);
let rawtxt: Option<String> = t
.sql
.query_get_value(&t, "SELECT txt_raw FROM msgs WHERE id=?;", paramsv![msg_id])
.await;
assert!(rawtxt.is_none_or_empty(), rawtxt);
}
}
}