use crate::error::Result;
use crate::tests::setup_clients;
use crate::types::{AttachmentKind, ClientEvent};
#[tokio::test]
async fn attachment_flow_is_ordered() -> Result<()> {
let mut pair = setup_clients()?;
let size = 200 * 1024;
let mut payload = vec![0u8; size];
for (i, byte) in payload.iter_mut().enumerate() {
*byte = (i % 251) as u8;
}
let chunk_size = 8 * 1024;
let chunks = ((payload.len() + chunk_size - 1) / chunk_size) as u32;
let attachment_id = pair
.alice
.send_attachment_bytes(
"bob",
AttachmentKind::File,
Some("blob.bin"),
Some("application/octet-stream"),
&payload,
chunk_size,
)
.await?;
let mut received_chunks = 0u32;
let mut completed = false;
let mut next_chunk_index = 0u32;
while !completed {
let event = pair.bob.poll_once().await?.expect("event");
match event {
ClientEvent::MessageReceived { message, .. } => match message.msg_type {
enigma_packet::MessageType::AttachmentInit => {
if let enigma_packet::MessageMeta::AttachmentInit(meta) = message.meta {
assert_eq!(meta.chunk_count, chunks);
assert_eq!(meta.total_size, payload.len() as u64);
assert_eq!(meta.attachment_id, attachment_id);
} else {
panic!("missing attachment init meta");
}
}
enigma_packet::MessageType::AttachmentChunk => {
if let enigma_packet::MessageMeta::AttachmentChunk(meta) = message.meta {
assert_eq!(meta.index, next_chunk_index);
let start = (meta.index as usize) * chunk_size;
let end = usize::min(start + message.payload.len(), payload.len());
assert_eq!(&message.payload[..end - start], &payload[start..end]);
next_chunk_index += 1;
} else {
panic!("missing chunk meta");
}
}
enigma_packet::MessageType::AttachmentEnd => {
if let enigma_packet::MessageMeta::AttachmentEnd {
attachment_id: end_id,
chunk_count,
total_size,
..
} = message.meta
{
assert_eq!(end_id, attachment_id);
assert_eq!(chunk_count, chunks);
assert_eq!(total_size, payload.len() as u64);
} else {
panic!("missing attachment end meta");
}
}
_ => {}
},
ClientEvent::AttachmentProgress {
attachment_id: id,
received_chunks: progress,
total_chunks,
..
} => {
assert_eq!(id, attachment_id);
assert_eq!(total_chunks, chunks);
received_chunks = progress;
}
ClientEvent::AttachmentCompleted {
attachment_id: id,
total_size,
..
} => {
assert_eq!(id, attachment_id);
assert_eq!(total_size, payload.len() as u64);
completed = true;
}
}
}
assert_eq!(received_chunks, chunks);
Ok(())
}