@@ -208,8 +208,12 @@ impl Session {
208208
209209#[ cfg( test) ]
210210mod tests {
211+ use mailparse:: MailHeaderMap ;
212+
211213 use super :: * ;
212- use crate :: chat:: send_msg;
214+ use crate :: chat:: { self , create_group, send_msg} ;
215+ use crate :: headerdef:: { HeaderDef , HeaderDefMap } ;
216+ use crate :: message:: Viewtype ;
213217 use crate :: test_utils:: TestContext ;
214218
215219 #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
@@ -243,4 +247,223 @@ mod tests {
243247
244248 Ok ( ( ) )
245249 }
250+
251+ /// Tests that pre message is sent for attachment larger than `PRE_MESSAGE_ATTACHMENT_SIZE_THRESHOLD`
252+ /// Also test that pre message is sent first, before the full message
253+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
254+ async fn test_sending_pre_message ( ) -> Result < ( ) > {
255+ let alice = TestContext :: new_alice ( ) . await ;
256+ let bob = TestContext :: new_bob ( ) . await ;
257+ let chat = alice. create_chat ( & bob) . await ;
258+
259+ let mut msg = Message :: new ( Viewtype :: File ) ;
260+ msg. set_file_from_bytes ( & alice. ctx , "test.bin" , & [ 0u8 ; 300_000 ] , None ) ?;
261+ msg. set_text ( "test" . to_owned ( ) ) ;
262+
263+ // assert that test attachment is bigger than limit
264+ assert ! (
265+ msg. get_filebytes( & alice. ctx) . await ?. unwrap( ) > PRE_MESSAGE_ATTACHMENT_SIZE_THRESHOLD
266+ ) ;
267+
268+ let msg_id = chat:: send_msg ( & alice. ctx , chat. id , & mut msg) . await . unwrap ( ) ;
269+ let smtp_rows = alice. get_smtp_rows_for_msg ( msg_id) . await ;
270+
271+ // pre-message and full message should be present
272+ // and test that correct headers are present on both messages
273+ assert_eq ! ( smtp_rows. len( ) , 2 ) ;
274+ let pre_message = mailparse:: parse_mail (
275+ smtp_rows
276+ . first ( )
277+ . expect ( "first element exists" )
278+ . 2
279+ . as_bytes ( ) ,
280+ ) ?;
281+ let full_message = mailparse:: parse_mail (
282+ smtp_rows
283+ . get ( 1 )
284+ . expect ( "second element exists" )
285+ . 2
286+ . as_bytes ( ) ,
287+ ) ?;
288+
289+ assert ! (
290+ pre_message
291+ . get_headers( )
292+ . get_first_header( HeaderDef :: ChatIsFullMessage . get_headername( ) )
293+ . is_none( )
294+ ) ;
295+ assert ! (
296+ full_message
297+ . get_headers( )
298+ . get_first_header( HeaderDef :: ChatIsFullMessage . get_headername( ) )
299+ . is_some( )
300+ ) ;
301+
302+ assert_eq ! (
303+ pre_message
304+ . headers
305+ . get_header_value( HeaderDef :: ChatFullMessageId ) ,
306+ full_message. headers. get_header_value( HeaderDef :: MessageId )
307+ ) ;
308+ assert ! (
309+ full_message
310+ . headers
311+ . get_header_value( HeaderDef :: ChatFullMessageId )
312+ . is_none( )
313+ ) ;
314+
315+ // full message should have the rfc message id
316+ assert_eq ! (
317+ full_message. headers. get_header_value( HeaderDef :: MessageId ) ,
318+ Some ( msg. rfc724_mid)
319+ ) ;
320+
321+ // test that message ids are different
322+ assert_ne ! (
323+ pre_message. headers. get_header_value( HeaderDef :: MessageId ) ,
324+ full_message. headers. get_header_value( HeaderDef :: MessageId )
325+ ) ;
326+
327+ // also test that Autocrypt-gossip and selfavatar should never go into full-messages
328+ // TODO: (this needs decryption, right?)
329+ Ok ( ( ) )
330+ }
331+
332+ /// Tests that no pre message is sent for normal message
333+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
334+ async fn test_not_sending_pre_message_no_attachment ( ) -> Result < ( ) > {
335+ let alice = TestContext :: new_alice ( ) . await ;
336+ let bob = TestContext :: new_bob ( ) . await ;
337+ let chat = alice. create_chat ( & bob) . await ;
338+
339+ // send normal text message
340+ let mut msg = Message :: new ( Viewtype :: Text ) ;
341+ msg. set_text ( "test" . to_owned ( ) ) ;
342+ let msg_id = chat:: send_msg ( & alice. ctx , chat. id , & mut msg) . await . unwrap ( ) ;
343+ let smtp_rows = alice. get_smtp_rows_for_msg ( msg_id) . await ;
344+
345+ // only one message and no "is full message" header should be present
346+ assert_eq ! ( smtp_rows. len( ) , 1 ) ;
347+
348+ let mime = smtp_rows. first ( ) . expect ( "first element exists" ) . 2 . clone ( ) ;
349+ let mail = mailparse:: parse_mail ( mime. as_bytes ( ) ) ?;
350+
351+ assert ! (
352+ mail. get_headers( )
353+ . get_first_header( HeaderDef :: ChatIsFullMessage . get_headername( ) )
354+ . is_none( )
355+ ) ;
356+ assert ! (
357+ mail. get_headers( )
358+ . get_first_header( HeaderDef :: ChatFullMessageId . get_headername( ) )
359+ . is_none( )
360+ ) ;
361+ Ok ( ( ) )
362+ }
363+
364+ /// Tests that no pre message is sent for attachment smaller than `PRE_MESSAGE_ATTACHMENT_SIZE_THRESHOLD`
365+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
366+ async fn test_not_sending_pre_message_for_small_attachment ( ) -> Result < ( ) > {
367+ let alice = TestContext :: new_alice ( ) . await ;
368+ let bob = TestContext :: new_bob ( ) . await ;
369+ let chat = alice. create_chat ( & bob) . await ;
370+
371+ let mut msg = Message :: new ( Viewtype :: File ) ;
372+ msg. set_file_from_bytes ( & alice. ctx , "test.bin" , & [ 0u8 ; 100_000 ] , None ) ?;
373+ msg. set_text ( "test" . to_owned ( ) ) ;
374+
375+ // assert that test attachment is smaller than limit
376+ assert ! (
377+ msg. get_filebytes( & alice. ctx) . await ?. unwrap( ) < PRE_MESSAGE_ATTACHMENT_SIZE_THRESHOLD
378+ ) ;
379+
380+ let msg_id = chat:: send_msg ( & alice. ctx , chat. id , & mut msg) . await . unwrap ( ) ;
381+ let smtp_rows = alice. get_smtp_rows_for_msg ( msg_id) . await ;
382+
383+ // only one message and no "is full message" header should be present
384+ assert_eq ! ( smtp_rows. len( ) , 1 ) ;
385+
386+ let mime = smtp_rows. first ( ) . expect ( "first element exists" ) . 2 . clone ( ) ;
387+ let mail = mailparse:: parse_mail ( mime. as_bytes ( ) ) ?;
388+
389+ assert ! (
390+ mail. get_headers( )
391+ . get_first_header( HeaderDef :: ChatIsFullMessage . get_headername( ) )
392+ . is_none( )
393+ ) ;
394+ assert ! (
395+ mail. get_headers( )
396+ . get_first_header( HeaderDef :: ChatFullMessageId . get_headername( ) )
397+ . is_none( )
398+ ) ;
399+
400+ Ok ( ( ) )
401+ }
402+
403+ /// Tests that pre message is not send for large webxdc updates
404+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
405+ async fn test_render_webxdc_status_update_object_range ( ) -> Result < ( ) > {
406+ let t = TestContext :: new_alice ( ) . await ;
407+ let chat_id = create_group ( & t, "a chat" ) . await ?;
408+
409+ let instance = {
410+ let mut instance = Message :: new ( Viewtype :: File ) ;
411+ instance. set_file_from_bytes (
412+ & t,
413+ "minimal.xdc" ,
414+ include_bytes ! ( "../test-data/webxdc/minimal.xdc" ) ,
415+ None ,
416+ ) ?;
417+ let instance_msg_id = send_msg ( & t, chat_id, & mut instance) . await ?;
418+ assert_eq ! ( instance. viewtype, Viewtype :: Webxdc ) ;
419+ Message :: load_from_db ( & t, instance_msg_id) . await
420+ }
421+ . unwrap ( ) ;
422+
423+ t. pop_sent_msg ( ) . await ;
424+ assert_eq ! ( t. sql. count( "SELECT COUNT(*) FROM smtp" , ( ) ) . await ?, 0 ) ;
425+
426+ let long_text = String :: from_utf8 ( vec ! [ b'a' ; 300_000 ] ) ?;
427+ assert ! ( long_text. len( ) > PRE_MESSAGE_ATTACHMENT_SIZE_THRESHOLD . try_into( ) . unwrap( ) ) ;
428+ t. send_webxdc_status_update ( instance. id , & format ! ( "{{\" payload\" : \" {long_text}\" }}" ) )
429+ . await ?;
430+ t. flush_status_updates ( ) . await ?;
431+
432+ assert_eq ! ( t. sql. count( "SELECT COUNT(*) FROM smtp" , ( ) ) . await ?, 1 ) ;
433+ Ok ( ( ) )
434+ }
435+
436+ // test that pre message is not send for large large text
437+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
438+ async fn test_not_sending_pre_message_for_large_text ( ) -> Result < ( ) > {
439+ let alice = TestContext :: new_alice ( ) . await ;
440+ let bob = TestContext :: new_bob ( ) . await ;
441+ let chat = alice. create_chat ( & bob) . await ;
442+
443+ // send normal text message
444+ let mut msg = Message :: new ( Viewtype :: Text ) ;
445+ let long_text = String :: from_utf8 ( vec ! [ b'a' ; 300_000 ] ) ?;
446+ assert ! ( long_text. len( ) > PRE_MESSAGE_ATTACHMENT_SIZE_THRESHOLD . try_into( ) . unwrap( ) ) ;
447+ msg. set_text ( long_text) ;
448+ let msg_id = chat:: send_msg ( & alice. ctx , chat. id , & mut msg) . await . unwrap ( ) ;
449+ let smtp_rows = alice. get_smtp_rows_for_msg ( msg_id) . await ;
450+
451+ // only one message and no "is full message" header should be present
452+ assert_eq ! ( smtp_rows. len( ) , 1 ) ;
453+
454+ let mime = smtp_rows. first ( ) . expect ( "first element exists" ) . 2 . clone ( ) ;
455+ let mail = mailparse:: parse_mail ( mime. as_bytes ( ) ) ?;
456+
457+ assert ! (
458+ mail. get_headers( )
459+ . get_first_header( HeaderDef :: ChatIsFullMessage . get_headername( ) )
460+ . is_none( )
461+ ) ;
462+ assert ! (
463+ mail. get_headers( )
464+ . get_first_header( HeaderDef :: ChatFullMessageId . get_headername( ) )
465+ . is_none( )
466+ ) ;
467+ Ok ( ( ) )
468+ }
246469}
0 commit comments