@@ -5630,3 +5630,62 @@ async fn test_outgoing_determined_by_signature() -> Result<()> {
56305630
56315631 Ok ( ( ) )
56325632}
5633+
5634+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
5635+ async fn test_mark_message_as_delivered_only_after_sent_out_fully ( ) -> Result < ( ) > {
5636+ let mut tcm = TestContextManager :: new ( ) ;
5637+ let alice = & tcm. alice ( ) . await ;
5638+ let bob = & tcm. bob ( ) . await ;
5639+ alice. set_config_bool ( Config :: BccSelf , true ) . await ?;
5640+ let alice_chat_id = alice. create_chat_id ( bob) . await ;
5641+
5642+ let file_bytes = include_bytes ! ( "../../test-data/image/screenshot.gif" ) ;
5643+ let mut msg = Message :: new ( Viewtype :: Image ) ;
5644+ msg. set_file_from_bytes ( alice, "a.jpg" , file_bytes, None ) ?;
5645+ let msg_id = chat:: send_msg ( alice, alice_chat_id, & mut msg)
5646+ . await
5647+ . unwrap ( ) ;
5648+
5649+ let ( pre_msg_id, pre_msg_payload) = first_row_in_smtp_queue ( alice) . await ;
5650+ assert_eq ! ( msg_id, pre_msg_id) ;
5651+ assert ! ( pre_msg_payload. len( ) < file_bytes. len( ) ) ;
5652+
5653+ assert_eq ! ( msg_id. get_state( alice) . await ?, MessageState :: OutPending ) ;
5654+ // Alice receives her own pre-message because of bcc_self
5655+ // This should not yet mark the message as delivered,
5656+ // because not everything was sent,
5657+ // but it does remove the pre-message from the SMTP queue
5658+ receive_imf ( alice, pre_msg_payload. as_bytes ( ) , false ) . await ?;
5659+ assert_eq ! ( msg_id. get_state( alice) . await ?, MessageState :: OutPending ) ;
5660+
5661+ let ( post_msg_id, post_msg_payload) = first_row_in_smtp_queue ( alice) . await ;
5662+ assert_eq ! ( msg_id, post_msg_id) ;
5663+ assert ! ( post_msg_payload. len( ) > file_bytes. len( ) ) ;
5664+
5665+ assert_eq ! ( msg_id. get_state( alice) . await ?, MessageState :: OutPending ) ;
5666+ // Alice receives her own post-message because of bcc_self
5667+ // This should now mark the message as delivered,
5668+ // because everything was sent by now.
5669+ receive_imf ( alice, post_msg_payload. as_bytes ( ) , false ) . await ?;
5670+ assert_eq ! ( msg_id. get_state( alice) . await ?, MessageState :: OutDelivered ) ;
5671+
5672+ Ok ( ( ) )
5673+ }
5674+
5675+ /// Queries the first sent message in the SMTP queue
5676+ /// without removing it from the SMTP queue.
5677+ /// This simulates the case that a message is successfully sent out,
5678+ /// but the 'OK' answer from the server doesn't arrive,
5679+ /// so that the SMTP row stays in the database.
5680+ pub ( crate ) async fn first_row_in_smtp_queue ( alice : & TestContext ) -> ( MsgId , String ) {
5681+ alice
5682+ . sql
5683+ . query_row_optional ( "SELECT msg_id, mime FROM smtp ORDER BY id" , ( ) , |row| {
5684+ let msg_id: MsgId = row. get ( 0 ) ?;
5685+ let mime: String = row. get ( 1 ) ?;
5686+ Ok ( ( msg_id, mime) )
5687+ } )
5688+ . await
5689+ . expect ( "query_row_optional failed" )
5690+ . expect ( "No SMTP row found" )
5691+ }
0 commit comments