@@ -208,10 +208,13 @@ impl Session {
208208
209209#[ cfg( test) ]
210210mod tests {
211+ use mailparse:: MailHeaderMap ;
211212 use num_traits:: FromPrimitive ;
212213
213214 use super :: * ;
214- use crate :: chat:: send_msg;
215+ use crate :: chat:: { self , create_group, send_msg} ;
216+ use crate :: headerdef:: { HeaderDef , HeaderDefMap } ;
217+ use crate :: message:: Viewtype ;
215218 use crate :: receive_imf:: receive_imf_from_inbox;
216219 use crate :: test_utils:: TestContext ;
217220
@@ -310,4 +313,222 @@ mod tests {
310313
311314 Ok ( ( ) )
312315 }
316+ /// Tests that pre message is sent for attachment larger than `PRE_MESSAGE_ATTACHMENT_SIZE_THRESHOLD`
317+ /// Also test that pre message is sent first, before the full message
318+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
319+ async fn test_sending_pre_message ( ) -> Result < ( ) > {
320+ let alice = TestContext :: new_alice ( ) . await ;
321+ let bob = TestContext :: new_bob ( ) . await ;
322+ let chat = alice. create_chat ( & bob) . await ;
323+
324+ let mut msg = Message :: new ( Viewtype :: File ) ;
325+ msg. set_file_from_bytes ( & alice. ctx , "test.bin" , & [ 0u8 ; 300_000 ] , None ) ?;
326+ msg. set_text ( "test" . to_owned ( ) ) ;
327+
328+ // assert that test attachment is bigger than limit
329+ assert ! (
330+ msg. get_filebytes( & alice. ctx) . await ?. unwrap( ) > PRE_MESSAGE_ATTACHMENT_SIZE_THRESHOLD
331+ ) ;
332+
333+ let msg_id = chat:: send_msg ( & alice. ctx , chat. id , & mut msg) . await . unwrap ( ) ;
334+ let smtp_rows = alice. get_smtp_rows_for_msg ( msg_id) . await ;
335+
336+ // pre-message and full message should be present
337+ // and test that correct headers are present on both messages
338+ assert_eq ! ( smtp_rows. len( ) , 2 ) ;
339+ let pre_message = mailparse:: parse_mail (
340+ smtp_rows
341+ . first ( )
342+ . expect ( "first element exists" )
343+ . 2
344+ . as_bytes ( ) ,
345+ ) ?;
346+ let full_message = mailparse:: parse_mail (
347+ smtp_rows
348+ . get ( 1 )
349+ . expect ( "second element exists" )
350+ . 2
351+ . as_bytes ( ) ,
352+ ) ?;
353+
354+ assert ! (
355+ pre_message
356+ . get_headers( )
357+ . get_first_header( HeaderDef :: ChatIsFullMessage . get_headername( ) )
358+ . is_none( )
359+ ) ;
360+ assert ! (
361+ full_message
362+ . get_headers( )
363+ . get_first_header( HeaderDef :: ChatIsFullMessage . get_headername( ) )
364+ . is_some( )
365+ ) ;
366+
367+ assert_eq ! (
368+ pre_message
369+ . headers
370+ . get_header_value( HeaderDef :: ChatFullMessageId ) ,
371+ full_message. headers. get_header_value( HeaderDef :: MessageId )
372+ ) ;
373+ assert ! (
374+ full_message
375+ . headers
376+ . get_header_value( HeaderDef :: ChatFullMessageId )
377+ . is_none( )
378+ ) ;
379+
380+ // full message should have the rfc message id
381+ assert_eq ! (
382+ full_message. headers. get_header_value( HeaderDef :: MessageId ) ,
383+ Some ( msg. rfc724_mid)
384+ ) ;
385+
386+ // test that message ids are different
387+ assert_ne ! (
388+ pre_message. headers. get_header_value( HeaderDef :: MessageId ) ,
389+ full_message. headers. get_header_value( HeaderDef :: MessageId )
390+ ) ;
391+
392+ // also test that Autocrypt-gossip and selfavatar should never go into full-messages
393+ // TODO: (this needs decryption, right?)
394+ Ok ( ( ) )
395+ }
396+
397+ /// Tests that no pre message is sent for normal message
398+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
399+ async fn test_not_sending_pre_message_no_attachment ( ) -> Result < ( ) > {
400+ let alice = TestContext :: new_alice ( ) . await ;
401+ let bob = TestContext :: new_bob ( ) . await ;
402+ let chat = alice. create_chat ( & bob) . await ;
403+
404+ // send normal text message
405+ let mut msg = Message :: new ( Viewtype :: Text ) ;
406+ msg. set_text ( "test" . to_owned ( ) ) ;
407+ let msg_id = chat:: send_msg ( & alice. ctx , chat. id , & mut msg) . await . unwrap ( ) ;
408+ let smtp_rows = alice. get_smtp_rows_for_msg ( msg_id) . await ;
409+
410+ // only one message and no "is full message" header should be present
411+ assert_eq ! ( smtp_rows. len( ) , 1 ) ;
412+
413+ let mime = smtp_rows. first ( ) . expect ( "first element exists" ) . 2 . clone ( ) ;
414+ let mail = mailparse:: parse_mail ( mime. as_bytes ( ) ) ?;
415+
416+ assert ! (
417+ mail. get_headers( )
418+ . get_first_header( HeaderDef :: ChatIsFullMessage . get_headername( ) )
419+ . is_none( )
420+ ) ;
421+ assert ! (
422+ mail. get_headers( )
423+ . get_first_header( HeaderDef :: ChatFullMessageId . get_headername( ) )
424+ . is_none( )
425+ ) ;
426+ Ok ( ( ) )
427+ }
428+
429+ /// Tests that no pre message is sent for attachment smaller than `PRE_MESSAGE_ATTACHMENT_SIZE_THRESHOLD`
430+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
431+ async fn test_not_sending_pre_message_for_small_attachment ( ) -> Result < ( ) > {
432+ let alice = TestContext :: new_alice ( ) . await ;
433+ let bob = TestContext :: new_bob ( ) . await ;
434+ let chat = alice. create_chat ( & bob) . await ;
435+
436+ let mut msg = Message :: new ( Viewtype :: File ) ;
437+ msg. set_file_from_bytes ( & alice. ctx , "test.bin" , & [ 0u8 ; 100_000 ] , None ) ?;
438+ msg. set_text ( "test" . to_owned ( ) ) ;
439+
440+ // assert that test attachment is smaller than limit
441+ assert ! (
442+ msg. get_filebytes( & alice. ctx) . await ?. unwrap( ) < PRE_MESSAGE_ATTACHMENT_SIZE_THRESHOLD
443+ ) ;
444+
445+ let msg_id = chat:: send_msg ( & alice. ctx , chat. id , & mut msg) . await . unwrap ( ) ;
446+ let smtp_rows = alice. get_smtp_rows_for_msg ( msg_id) . await ;
447+
448+ // only one message and no "is full message" header should be present
449+ assert_eq ! ( smtp_rows. len( ) , 1 ) ;
450+
451+ let mime = smtp_rows. first ( ) . expect ( "first element exists" ) . 2 . clone ( ) ;
452+ let mail = mailparse:: parse_mail ( mime. as_bytes ( ) ) ?;
453+
454+ assert ! (
455+ mail. get_headers( )
456+ . get_first_header( HeaderDef :: ChatIsFullMessage . get_headername( ) )
457+ . is_none( )
458+ ) ;
459+ assert ! (
460+ mail. get_headers( )
461+ . get_first_header( HeaderDef :: ChatFullMessageId . get_headername( ) )
462+ . is_none( )
463+ ) ;
464+
465+ Ok ( ( ) )
466+ }
467+
468+ /// Tests that pre message is not send for large webxdc updates
469+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
470+ async fn test_render_webxdc_status_update_object_range ( ) -> Result < ( ) > {
471+ let t = TestContext :: new_alice ( ) . await ;
472+ let chat_id = create_group ( & t, "a chat" ) . await ?;
473+
474+ let instance = {
475+ let mut instance = Message :: new ( Viewtype :: File ) ;
476+ instance. set_file_from_bytes (
477+ & t,
478+ "minimal.xdc" ,
479+ include_bytes ! ( "../test-data/webxdc/minimal.xdc" ) ,
480+ None ,
481+ ) ?;
482+ let instance_msg_id = send_msg ( & t, chat_id, & mut instance) . await ?;
483+ assert_eq ! ( instance. viewtype, Viewtype :: Webxdc ) ;
484+ Message :: load_from_db ( & t, instance_msg_id) . await
485+ }
486+ . unwrap ( ) ;
487+
488+ t. pop_sent_msg ( ) . await ;
489+ assert_eq ! ( t. sql. count( "SELECT COUNT(*) FROM smtp" , ( ) ) . await ?, 0 ) ;
490+
491+ let long_text = String :: from_utf8 ( vec ! [ b'a' ; 300_000 ] ) ?;
492+ assert ! ( long_text. len( ) > PRE_MESSAGE_ATTACHMENT_SIZE_THRESHOLD . try_into( ) . unwrap( ) ) ;
493+ t. send_webxdc_status_update ( instance. id , & format ! ( "{{\" payload\" : \" {long_text}\" }}" ) )
494+ . await ?;
495+ t. flush_status_updates ( ) . await ?;
496+
497+ assert_eq ! ( t. sql. count( "SELECT COUNT(*) FROM smtp" , ( ) ) . await ?, 1 ) ;
498+ Ok ( ( ) )
499+ }
500+
501+ // test that pre message is not send for large large text
502+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
503+ async fn test_not_sending_pre_message_for_large_text ( ) -> Result < ( ) > {
504+ let alice = TestContext :: new_alice ( ) . await ;
505+ let bob = TestContext :: new_bob ( ) . await ;
506+ let chat = alice. create_chat ( & bob) . await ;
507+
508+ // send normal text message
509+ let mut msg = Message :: new ( Viewtype :: Text ) ;
510+ let long_text = String :: from_utf8 ( vec ! [ b'a' ; 300_000 ] ) ?;
511+ assert ! ( long_text. len( ) > PRE_MESSAGE_ATTACHMENT_SIZE_THRESHOLD . try_into( ) . unwrap( ) ) ;
512+ msg. set_text ( long_text) ;
513+ let msg_id = chat:: send_msg ( & alice. ctx , chat. id , & mut msg) . await . unwrap ( ) ;
514+ let smtp_rows = alice. get_smtp_rows_for_msg ( msg_id) . await ;
515+
516+ // only one message and no "is full message" header should be present
517+ assert_eq ! ( smtp_rows. len( ) , 1 ) ;
518+
519+ let mime = smtp_rows. first ( ) . expect ( "first element exists" ) . 2 . clone ( ) ;
520+ let mail = mailparse:: parse_mail ( mime. as_bytes ( ) ) ?;
521+
522+ assert ! (
523+ mail. get_headers( )
524+ . get_first_header( HeaderDef :: ChatIsFullMessage . get_headername( ) )
525+ . is_none( )
526+ ) ;
527+ assert ! (
528+ mail. get_headers( )
529+ . get_first_header( HeaderDef :: ChatFullMessageId . get_headername( ) )
530+ . is_none( )
531+ ) ;
532+ Ok ( ( ) )
533+ }
313534}
0 commit comments