From 9a33555604551d72bb3b40b7acc40d991b4aa9b0 Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 25 Aug 2026 13:52:33 +0000 Subject: [PATCH] test: test dc_send_msg_sync() --- python/src/deltachat/chat.py | 34 ++++++++++++++++++++++++++++------ python/tests/test_1_online.py | 26 ++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/python/src/deltachat/chat.py b/python/src/deltachat/chat.py index b83ee3081..950d7c1c2 100644 --- a/python/src/deltachat/chat.py +++ b/python/src/deltachat/chat.py @@ -259,6 +259,15 @@ class Chat: # ------ chat messaging API ------------------------------ + def _reload_sent_msg(self, msg: Message, sent_id: int) -> Message: + """Helper to reload just sent message""" + sent_msg = Message.from_db(self.account, sent_id) + if sent_msg is None: + raise ValueError("cannot load just sent message from the database") + # modify message in place to avoid bad state for the caller + msg._dc_msg = sent_msg._dc_msg + return msg + def send_msg(self, msg: Message) -> Message: """send a message by using a ready Message object. @@ -274,12 +283,25 @@ class Chat: sent_id = lib.dc_send_msg(self.account._dc_context, self.id, msg._dc_msg) if sent_id == 0: raise ValueError("message could not be sent") - # modify message in place to avoid bad state for the caller - sent_msg = Message.from_db(self.account, sent_id) - if sent_msg is None: - raise ValueError("cannot load just sent message from the database") - msg._dc_msg = sent_msg._dc_msg - return msg + return self._reload_sent_msg(msg, sent_id) + + def send_msg_sync(self, msg: Message) -> Message: + """Send a message synchronously. + This bypasses the IO scheduler and creates its own SMTP connection. + + :param msg: a :class:`deltachat.message.Message` instance + previously returned by + e.g. :meth:`deltachat.message.Message.new_empty`. + :raises ValueError: if message can not be sent. + + :returns: a :class:`deltachat.message.Message` instance as + sent out. This is the same object as was passed in, which + has been modified with the new state of the core. + """ + sent_id = lib.dc_send_msg_sync(self.account._dc_context, self.id, msg._dc_msg) + if sent_id == 0: + raise ValueError("message could not be sent") + return self._reload_sent_msg(msg, sent_id) def send_text(self, text): """send a text message and return the resulting Message instance. diff --git a/python/tests/test_1_online.py b/python/tests/test_1_online.py index d88746ea9..2d0292af1 100644 --- a/python/tests/test_1_online.py +++ b/python/tests/test_1_online.py @@ -291,6 +291,32 @@ def test_forward_own_message(acfactory, lp): assert msg_in.is_forwarded() +def test_send_msg_sync(acfactory, lp): + ac1, ac2 = acfactory.get_online_accounts(2) + chat1 = acfactory.get_accepted_chat(ac1, ac2) + + # Send some message from ac1 + # so we are testing not the first message + # being sent synchronously. + lp.sec("ac1: send message to ac2") + chat1.send_text("message") + + lp.sec("ac2: receive message") + msg_in = ac2._evtracker.wait_next_incoming_message() + assert msg_in.text == "message" + + # Stop I/O and send message synchronously. + ac1.stop_io() + msg1 = Message.new_empty(ac1, "text") + msg1.set_text("message1") + chat1.send_msg_sync(msg1) + msg1.is_out_delivered() + + lp.sec("ac2: receive message") + msg_in = ac2._evtracker.wait_next_incoming_message() + assert msg_in.text == "message1" + + def test_resend_message(acfactory, lp): ac1, ac2 = acfactory.get_online_accounts(2) chat1 = acfactory.get_accepted_chat(ac1, ac2)