Skip to content

Commit b4fe6b4

Browse files
committed
test(send queue): add a test for the ordering of media vs other events
1 parent 99b9c50 commit b4fe6b4

File tree

1 file changed

+105
-31
lines changed

1 file changed

+105
-31
lines changed

crates/matrix-sdk/tests/integration/send_queue.rs

+105-31
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use matrix_sdk::{
66
config::StoreConfig,
77
media::{MediaFormat, MediaRequestParameters, MediaThumbnailSettings},
88
send_queue::{
9-
LocalEcho, LocalEchoContent, RoomSendQueueError, RoomSendQueueStorageError,
9+
LocalEcho, LocalEchoContent, RoomSendQueue, RoomSendQueueError, RoomSendQueueStorageError,
1010
RoomSendQueueUpdate,
1111
},
1212
test_utils::{
@@ -40,6 +40,25 @@ use tokio::{
4040
};
4141
use wiremock::{Request, ResponseTemplate};
4242

43+
/// Queues an attachment whenever the actual data/mime type etc. don't matter.
44+
///
45+
/// Returns the filename, for sanity check purposes.
46+
async fn queue_attachment_no_thumbnail(q: &RoomSendQueue) -> &'static str {
47+
let filename = "surprise.jpeg.exe";
48+
let content_type = mime::IMAGE_JPEG;
49+
let data = b"hello world".to_vec();
50+
let config = AttachmentConfig::new().info(AttachmentInfo::Image(BaseImageInfo {
51+
height: Some(uint!(13)),
52+
width: Some(uint!(37)),
53+
size: Some(uint!(42)),
54+
blurhash: None,
55+
}));
56+
q.send_attachment(filename, content_type, data, config)
57+
.await
58+
.expect("queuing the attachment works");
59+
filename
60+
}
61+
4362
fn mock_jpeg_upload<'a>(
4463
mock: &'a MatrixMockServer,
4564
mxc: &MxcUri,
@@ -1936,18 +1955,6 @@ async fn test_media_upload_retry() {
19361955
let (local_echoes, mut watch) = q.subscribe().await.unwrap();
19371956
assert!(local_echoes.is_empty());
19381957

1939-
// Create the media to send (no thumbnails).
1940-
let filename = "surprise.jpeg.exe";
1941-
let content_type = mime::IMAGE_JPEG;
1942-
let data = b"hello world".to_vec();
1943-
1944-
let config = AttachmentConfig::new().info(AttachmentInfo::Image(BaseImageInfo {
1945-
height: Some(uint!(13)),
1946-
width: Some(uint!(37)),
1947-
size: Some(uint!(42)),
1948-
blurhash: None,
1949-
}));
1950-
19511958
// Prepare endpoints.
19521959
mock.mock_room_state_encryption().plain().mount().await;
19531960

@@ -1962,9 +1969,7 @@ async fn test_media_upload_retry() {
19621969

19631970
// Send the media.
19641971
assert!(watch.is_empty());
1965-
q.send_attachment(filename, content_type, data, config)
1966-
.await
1967-
.expect("queuing the attachment works");
1972+
let filename = queue_attachment_no_thumbnail(&q).await;
19681973

19691974
// Observe the local echo.
19701975
let (event_txn, _send_handle, content) = assert_update!(watch => local echo event);
@@ -2024,18 +2029,6 @@ async fn test_unwedging_media_upload() {
20242029
let (local_echoes, mut watch) = q.subscribe().await.unwrap();
20252030
assert!(local_echoes.is_empty());
20262031

2027-
// Create the media to send (no thumbnails).
2028-
let filename = "rickroll.gif";
2029-
let content_type = mime::IMAGE_JPEG;
2030-
let data = b"Never gonna give you up".to_vec();
2031-
2032-
let config = AttachmentConfig::new().info(AttachmentInfo::Image(BaseImageInfo {
2033-
height: Some(uint!(13)),
2034-
width: Some(uint!(37)),
2035-
size: Some(uint!(42)),
2036-
blurhash: None,
2037-
}));
2038-
20392032
// Prepare endpoints.
20402033
mock.mock_room_state_encryption().plain().mount().await;
20412034

@@ -2045,9 +2038,7 @@ async fn test_unwedging_media_upload() {
20452038

20462039
// Send the media.
20472040
assert!(watch.is_empty());
2048-
q.send_attachment(filename, content_type, data, config)
2049-
.await
2050-
.expect("queuing the attachment works");
2041+
let filename = queue_attachment_no_thumbnail(&q).await;
20512042

20522043
// Observe the local echo.
20532044
let (event_txn, send_handle, content) = assert_update!(watch => local echo event);
@@ -2085,3 +2076,86 @@ async fn test_unwedging_media_upload() {
20852076
// That's all, folks!
20862077
assert!(watch.is_empty());
20872078
}
2079+
2080+
#[async_test]
2081+
async fn test_media_upload_ordering() {
2082+
// Test that despite happening in multiple requests, sending a media maintains
2083+
// the ordering.
2084+
2085+
let mock = MatrixMockServer::new().await;
2086+
2087+
// Mark the room as joined.
2088+
let room_id = room_id!("!a:b.c");
2089+
let client = mock.client_builder().build().await;
2090+
let room = mock.sync_joined_room(&client, room_id).await;
2091+
2092+
let q = room.send_queue();
2093+
let (local_echoes, mut watch) = q.subscribe().await.unwrap();
2094+
assert!(local_echoes.is_empty());
2095+
2096+
// Prepare endpoints.
2097+
mock.mock_room_state_encryption().plain().mount().await;
2098+
mock.mock_upload().ok(mxc_uri!("mxc://sdk.rs/media")).mock_once().mount().await;
2099+
2100+
assert!(watch.is_empty());
2101+
2102+
{
2103+
// 1. Send a text message that will get wedged.
2104+
mock.mock_room_send().error_too_large().mock_once().mount().await;
2105+
q.send(RoomMessageEventContent::text_plain("error").into()).await.unwrap();
2106+
let (text_txn, _send_handle) = assert_update!(watch => local echo { body = "error" });
2107+
assert_update!(watch => error { recoverable = false, txn = text_txn });
2108+
}
2109+
2110+
// We'll then send a media event, and then a text event with success.
2111+
mock.mock_room_send().ok(event_id!("$media")).mock_once().mount().await;
2112+
mock.mock_room_send().ok(event_id!("$text")).mock_once().mount().await;
2113+
2114+
// 2. Queue the media.
2115+
let filename = queue_attachment_no_thumbnail(&q).await;
2116+
2117+
// 3. Queue the message.
2118+
q.send(RoomMessageEventContent::text_plain("hello world").into()).await.unwrap();
2119+
2120+
// Observe the local echo for the media.
2121+
let (event_txn, _send_handle, content) = assert_update!(watch => local echo event);
2122+
assert_let!(MessageType::Image(img_content) = content.msgtype);
2123+
assert_eq!(img_content.body, filename);
2124+
2125+
// Observe the local echo for the message.
2126+
let (text_txn, _send_handle) = assert_update!(watch => local echo { body = "hello world" });
2127+
2128+
// The media gets uploaded.
2129+
assert_update!(watch => uploaded {
2130+
related_to = event_txn,
2131+
mxc = mxc_uri!("mxc://sdk.rs/media")
2132+
});
2133+
2134+
let edit_msg = assert_update!(watch => edit local echo {
2135+
txn = event_txn
2136+
});
2137+
assert_let!(MessageType::Image(new_content) = edit_msg.msgtype);
2138+
assert_let!(MediaSource::Plain(new_uri) = &new_content.source);
2139+
assert_eq!(new_uri, mxc_uri!("mxc://sdk.rs/media"));
2140+
2141+
// The media event is sent, at some point.
2142+
assert_update!(watch => sent {
2143+
txn = event_txn,
2144+
event_id = event_id!("$media")
2145+
});
2146+
2147+
// Then the text event is sent.
2148+
assert_update!(watch => sent {
2149+
txn = text_txn,
2150+
event_id = event_id!("$text")
2151+
});
2152+
2153+
// That's all, folks!
2154+
assert!(watch.is_empty());
2155+
2156+
// When reopening the send queue, we still see the wedged event.
2157+
let (local_echoes, _watch) = q.subscribe().await.unwrap();
2158+
assert_eq!(local_echoes.len(), 1);
2159+
assert_let!(LocalEchoContent::Event { send_error, .. } = &local_echoes[0].content);
2160+
assert!(send_error.is_some());
2161+
}

0 commit comments

Comments
 (0)