@@ -113,7 +113,7 @@ async fn test_receive_messages() -> Result<Vec<Response>, Box<dyn std::error::Er
113113}
114114
115115#[ tokio:: test]
116- async fn receive_message ( ) {
116+ async fn functional ( ) {
117117 let join = tokio:: task:: spawn ( run ( ) ) ;
118118
119119 // wait for mailcrab to startup
@@ -148,13 +148,10 @@ async fn receive_message() {
148148 let mut sorted_messages = vec ! [ ] ;
149149 for id in & responses {
150150 if let Some ( message) = messages. iter ( ) . find ( |m| m. id . to_string ( ) == * id) {
151- sorted_messages. push ( message) ;
151+ sorted_messages. push ( message. clone ( ) ) ;
152152 }
153153 }
154154
155- // stop the server
156- join. abort ( ) ;
157-
158155 assert_eq ! ( sorted_messages. len( ) , 3 ) ;
159156 assert ! ( sorted_messages[ 0 ] . has_html) ;
160157 assert ! ( sorted_messages[ 0 ] . has_plain) ;
@@ -167,6 +164,53 @@ async fn receive_message() {
167164 assert ! ( !sorted_messages[ 2 ] . has_html) ;
168165 assert ! ( sorted_messages[ 2 ] . has_plain) ;
169166 assert_eq ! ( sorted_messages[ 2 ] . attachments. len( ) , 1 ) ;
167+
168+ // send a large attachment and verify it can be downloaded via the URL endpoint
169+ const SIZE : usize = 75 * 1024 * 1024 ; // 75 MiB
170+ send_large_file ( SIZE ) . await . expect ( "send failed" ) ;
171+
172+ let mut large_meta = None ;
173+ for _ in 0 ..300 {
174+ let messages = get_messages_metadata ( ) . await . unwrap ( ) ;
175+ if let Some ( m) = messages
176+ . into_iter ( )
177+ . find ( |m| m. attachments . iter ( ) . any ( |a| a. filename == "large.bin" ) )
178+ {
179+ large_meta = Some ( m) ;
180+ break ;
181+ }
182+ sleep ( Duration :: from_millis ( 100 ) ) . await ;
183+ }
184+ let meta = large_meta. expect ( "large attachment message not received within timeout" ) ;
185+
186+ assert_eq ! ( meta. attachments. len( ) , 1 ) ;
187+ assert_eq ! ( meta. attachments[ 0 ] . filename, "large.bin" ) ;
188+
189+ let http_port: u16 = parse_env_var ( "HTTP_PORT" , 1080 ) ;
190+ let client = Client :: builder ( )
191+ . timeout ( Duration :: from_secs ( 60 ) )
192+ . build ( )
193+ . unwrap ( ) ;
194+
195+ let attachment_bytes = client
196+ . get ( format ! (
197+ "http://127.0.0.1:{http_port}/api/message/{}/attachment/0" ,
198+ meta. id
199+ ) )
200+ . send ( )
201+ . await
202+ . expect ( "attachment request failed" )
203+ . bytes ( )
204+ . await
205+ . expect ( "reading body failed" ) ;
206+
207+ assert_eq ! ( attachment_bytes. len( ) , SIZE ) ;
208+
209+ let expected: Vec < u8 > = ( 0 ..SIZE ) . map ( |i| ( i % 251 ) as u8 ) . collect ( ) ;
210+ assert_eq ! ( attachment_bytes. as_ref( ) , expected. as_slice( ) ) ;
211+
212+ // stop the server
213+ join. abort ( ) ;
170214}
171215
172216#[ tokio:: test]
@@ -232,65 +276,3 @@ async fn send_large_file(size_bytes: usize) -> Result<Response, Box<dyn std::err
232276
233277 Ok ( mailer. send ( email) . await ?)
234278}
235-
236- #[ tokio:: test]
237- async fn receive_large_attachment ( ) {
238- const SIZE : usize = 75 * 1024 * 1024 ; // 75 MiB
239-
240- let join = tokio:: task:: spawn ( run ( ) ) ;
241-
242- for _ in 0 ..60 {
243- if get_messages_metadata ( ) . await . is_ok ( ) {
244- break ;
245- }
246- sleep ( Duration :: from_millis ( 100 ) ) . await ;
247- }
248-
249- let messages_before = get_messages_metadata ( ) . await . unwrap ( ) . len ( ) ;
250-
251- send_large_file ( SIZE ) . await . expect ( "send failed" ) ;
252-
253- let mut messages = Vec :: new ( ) ;
254- for _ in 0 ..100 {
255- messages = get_messages_metadata ( ) . await . unwrap ( ) ;
256- if messages. len ( ) > messages_before {
257- break ;
258- }
259- sleep ( Duration :: from_millis ( 50 ) ) . await ;
260- }
261- assert ! (
262- messages. len( ) > messages_before,
263- "no message received within timeout"
264- ) ;
265- let meta = messages. last ( ) . expect ( "no message received" ) ;
266-
267- assert_eq ! ( meta. attachments. len( ) , 1 ) ;
268- assert_eq ! ( meta. attachments[ 0 ] . filename, "large.bin" ) ;
269-
270- // fetch the full message and hit the new attachment URL
271- let http_port: u16 = parse_env_var ( "HTTP_PORT" , 1080 ) ;
272- let client = reqwest:: Client :: builder ( )
273- . timeout ( Duration :: from_secs ( 30 ) )
274- . build ( )
275- . unwrap ( ) ;
276-
277- let attachment_bytes = client
278- . get ( format ! (
279- "http://127.0.0.1:{http_port}/api/message/{}/attachment/0" ,
280- meta. id
281- ) )
282- . send ( )
283- . await
284- . expect ( "attachment request failed" )
285- . bytes ( )
286- . await
287- . expect ( "reading body failed" ) ;
288-
289- assert_eq ! ( attachment_bytes. len( ) , SIZE ) ;
290-
291- // verify content matches
292- let expected: Vec < u8 > = ( 0 ..SIZE ) . map ( |i| ( i % 251 ) as u8 ) . collect ( ) ;
293- assert_eq ! ( attachment_bytes. as_ref( ) , expected. as_slice( ) ) ;
294-
295- join. abort ( ) ;
296- }
0 commit comments