From bc73c16df7705baae267acf4e44d60e61a0ce1aa Mon Sep 17 00:00:00 2001 From: link2xt Date: Fri, 21 Jul 2023 09:33:59 +0000 Subject: [PATCH 1/5] chore: fix compiler warnings --- src/configure.rs | 2 +- src/mimeparser.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/configure.rs b/src/configure.rs index 59f7a02ab..4ef4ed3e3 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -318,7 +318,7 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> { } // respect certificate setting from function parameters - for mut server in &mut servers { + for server in &mut servers { let certificate_checks = match server.protocol { Protocol::Imap => param.imap.certificate_checks, Protocol::Smtp => param.smtp.certificate_checks, diff --git a/src/mimeparser.rs b/src/mimeparser.rs index 93e5d947c..c6d9e340b 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -643,7 +643,7 @@ impl MimeMessage { .parts .iter_mut() .find(|part| !part.msg.is_empty() && !part.is_reaction); - if let Some(mut part) = part_with_text { + if let Some(part) = part_with_text { part.msg = format!("{} – {}", subject, part.msg); } } From fbd2fc8eaddd4fd2eb09f70fd395883f36980e3d Mon Sep 17 00:00:00 2001 From: link2xt Date: Thu, 20 Jul 2023 01:00:14 +0000 Subject: [PATCH 2/5] test: add test_webxdc_download_on_demand The test checks that if webxdc update is too large to download with the current `download_limit`, it is applied afterwards when the user manually downloads the update message. --- python/src/deltachat/message.py | 3 +++ python/tests/test_1_online.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/python/src/deltachat/message.py b/python/src/deltachat/message.py index e58d97d05..be42b3059 100644 --- a/python/src/deltachat/message.py +++ b/python/src/deltachat/message.py @@ -486,6 +486,9 @@ class Message: dc_msg = ffi.gc(lib.dc_get_msg(self.account._dc_context, self.id), lib.dc_msg_unref) return lib.dc_msg_get_download_state(dc_msg) + def download_full(self) -> None: + lib.dc_download_full_msg(self.account._dc_context, self.id) + # some code for handling DC_MSG_* view types diff --git a/python/tests/test_1_online.py b/python/tests/test_1_online.py index 798deda23..53d933b59 100644 --- a/python/tests/test_1_online.py +++ b/python/tests/test_1_online.py @@ -2,6 +2,7 @@ import os import queue import sys import time +import base64 from datetime import datetime, timezone import pytest @@ -323,6 +324,33 @@ def test_webxdc_message(acfactory, data, lp): assert len(list(ac2.direct_imap.conn.fetch(AND(seen=True)))) == 1 +def test_webxdc_download_on_demand(acfactory, data, lp): + ac1, ac2 = acfactory.get_online_accounts(2) + acfactory.introduce_each_other([ac1, ac2]) + chat = acfactory.get_accepted_chat(ac1, ac2) + + msg1 = Message.new_empty(ac1, "webxdc") + msg1.set_text("message1") + msg1.set_file(data.get_path("webxdc/minimal.xdc")) + msg1 = chat.send_msg(msg1) + assert msg1.is_webxdc() + assert msg1.filename + + msg2 = ac2._evtracker.wait_next_incoming_message() + assert msg2.is_webxdc() + + lp.sec("ac2 sets download limit") + ac2.set_config("download_limit", "100") + assert msg1.send_status_update({"payload": base64.b64encode(os.urandom(50000))}, "some test data") + ac2_update = ac2._evtracker.wait_next_incoming_message() + assert ac2_update.download_state == dc.const.DC_DOWNLOAD_AVAILABLE + assert not msg2.get_status_updates() + + ac2_update.download_full() + ac2._evtracker.get_matching("DC_EVENT_WEBXDC_STATUS_UPDATE") + assert msg2.get_status_updates() + + def test_mvbox_sentbox_threads(acfactory, lp): lp.sec("ac1: start with mvbox thread") ac1 = acfactory.new_online_configuring_account(mvbox_move=True, sentbox_watch=True) From 5db75128ba2c7ccc3efb17c193e17136f3363c05 Mon Sep 17 00:00:00 2001 From: link2xt Date: Fri, 21 Jul 2023 18:39:26 +0000 Subject: [PATCH 3/5] fix: accept WebXDC updates in mailing lists --- src/webxdc.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/webxdc.rs b/src/webxdc.rs index 1f3215365..c876b6328 100644 --- a/src/webxdc.rs +++ b/src/webxdc.rs @@ -13,6 +13,7 @@ use serde_json::Value; use tokio::io::AsyncReadExt; use crate::chat::Chat; +use crate::constants::Chattype; use crate::contact::ContactId; use crate::context::Context; use crate::download::DownloadState; @@ -560,6 +561,7 @@ impl Context { json: &str, ) -> Result<()> { let msg = Message::load_from_db(self, msg_id).await?; + let chat_id = msg.chat_id; let (timestamp, mut instance, can_info_msg) = if msg.viewtype == Viewtype::Webxdc { (msg.timestamp_sort, msg, false) } else if let Some(parent) = msg.parent(self).await? { @@ -577,7 +579,14 @@ impl Context { if from_id != ContactId::SELF && !chat::is_contact_in_chat(self, instance.chat_id, from_id).await? { - bail!("receive_status_update: status sender not chat member.") + let chat_type: Chattype = self + .sql + .query_get_value("SELECT type FROM chats WHERE id=?", (chat_id,)) + .await? + .with_context(|| format!("Chat type for chat {chat_id} not found"))?; + if chat_type != Chattype::Mailinglist { + bail!("receive_status_update: status sender not chat member.") + } } let updates: StatusUpdates = serde_json::from_str(json)?; From d572d960e5b506c5c69ac0f8206e269e9930198f Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sat, 22 Jul 2023 00:30:14 +0200 Subject: [PATCH 4/5] delete old webxdc status updates during housekeeping --- src/sql.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/sql.rs b/src/sql.rs index 9cee3404d..90549dd4b 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -755,6 +755,17 @@ pub async fn housekeeping(context: &Context) -> Result<()> { .log_err(context) .ok(); + context + .sql + .execute( + "DELETE FROM msgs_status_updates WHERE msg_id NOT IN (SELECT id FROM msgs)", + (), + ) + .await + .context("failed to remove old webxdc status updates") + .log_err(context) + .ok(); + info!(context, "Housekeeping done."); Ok(()) } From 200b808c27715f8ddb45c2e7f7c2631dbaa6dc75 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sat, 22 Jul 2023 14:33:57 +0200 Subject: [PATCH 5/5] add tests for deletion of webxdc status-updates --- src/webxdc.rs | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/src/webxdc.rs b/src/webxdc.rs index c876b6328..b2e9a9a35 100644 --- a/src/webxdc.rs +++ b/src/webxdc.rs @@ -837,9 +837,9 @@ mod tests { use crate::chatlist::Chatlist; use crate::config::Config; use crate::contact::Contact; - use crate::message; use crate::receive_imf::{receive_imf, receive_imf_inner}; use crate::test_utils::TestContext; + use crate::{message, sql}; #[allow(clippy::assertions_on_constants)] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] @@ -1216,6 +1216,66 @@ mod tests { async fn test_delete_webxdc_instance() -> Result<()> { let t = TestContext::new_alice().await; let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?; + let instance = send_webxdc_instance(&t, chat_id).await?; + t.receive_status_update( + ContactId::SELF, + instance.id, + r#"{"updates":[{"payload":1}]}"#, + ) + .await?; + assert_eq!( + t.sql + .count("SELECT COUNT(*) FROM msgs_status_updates;", ()) + .await?, + 1 + ); + + message::delete_msgs(&t, &[instance.id]).await?; + sql::housekeeping(&t).await?; + assert_eq!( + t.sql + .count("SELECT COUNT(*) FROM msgs_status_updates;", ()) + .await?, + 0 + ); + + Ok(()) + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_delete_chat_with_webxdc() -> Result<()> { + let t = TestContext::new_alice().await; + let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?; + let instance = send_webxdc_instance(&t, chat_id).await?; + t.receive_status_update( + ContactId::SELF, + instance.id, + r#"{"updates":[{"payload":1}, {"payload":2}]}"#, + ) + .await?; + assert_eq!( + t.sql + .count("SELECT COUNT(*) FROM msgs_status_updates;", ()) + .await?, + 2 + ); + + chat_id.delete(&t).await?; + sql::housekeeping(&t).await?; + assert_eq!( + t.sql + .count("SELECT COUNT(*) FROM msgs_status_updates;", ()) + .await?, + 0 + ); + + Ok(()) + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_delete_webxdc_draft() -> Result<()> { + let t = TestContext::new_alice().await; + let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?; let mut instance = create_webxdc_instance( &t,