Skip to content

Commit bbe35e8

Browse files
committed
fix(sdk): A new local LatestEventValue can be “cannot be sent”.
This patch fixes a bug where a new local `LatestEventValue` was always created as `LocalIsSending`. It must be created as `LocalCannotBeSent` if a previous local `LatestEventValue` exists and is `LocalCannotBeSent`. This patch adds the companion test too.
1 parent 107fc07 commit bbe35e8

File tree

1 file changed

+81
-5
lines changed

1 file changed

+81
-5
lines changed

crates/matrix-sdk/src/latest_events/latest_event.rs

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -554,11 +554,21 @@ impl LatestEventValueBuilder {
554554
match serialized_event_content.deserialize() {
555555
Ok(content) => {
556556
if filter_any_message_like_event_content(content) {
557-
let value =
558-
LatestEventValue::LocalIsSending(LocalLatestEventValue {
559-
timestamp: MilliSecondsSinceUnixEpoch::now(),
560-
content: serialized_event_content.clone(),
561-
});
557+
let local_value = LocalLatestEventValue {
558+
timestamp: MilliSecondsSinceUnixEpoch::now(),
559+
content: serialized_event_content.clone(),
560+
};
561+
562+
// If a local previous `LatestEventValue` exists and has been marked
563+
// as “cannot be sent”, it means the new `LatestEventValue` must
564+
// also be marked as “cannot be sent”.
565+
let value = if let Some(LatestEventValue::LocalCannotBeSent(_)) =
566+
buffer_of_values_for_local_events.last()
567+
{
568+
LatestEventValue::LocalCannotBeSent(local_value)
569+
} else {
570+
LatestEventValue::LocalIsSending(local_value)
571+
};
562572

563573
buffer_of_values_for_local_events
564574
.push(transaction_id.to_owned(), value.clone());
@@ -1820,6 +1830,72 @@ mod tests_latest_event_value_builder {
18201830
assert_eq!(buffer.buffer.len(), 2);
18211831
}
18221832

1833+
#[async_test]
1834+
async fn test_local_new_local_event_when_previous_local_event_cannot_be_sent() {
1835+
let (_client, _room_id, room_send_queue, room_event_cache) = local_prelude().await;
1836+
1837+
let mut buffer = LatestEventValuesForLocalEvents::new();
1838+
1839+
// Receiving one `NewLocalEvent`.
1840+
let transaction_id_0 = {
1841+
let transaction_id = OwnedTransactionId::from("txnid0");
1842+
let content = new_local_echo_content(&room_send_queue, &transaction_id, "A");
1843+
1844+
let update = RoomSendQueueUpdate::NewLocalEvent(LocalEcho {
1845+
transaction_id: transaction_id.clone(),
1846+
content,
1847+
});
1848+
1849+
// The `LatestEventValue` matches the new local event.
1850+
assert_local_value_matches_room_message_with_body!(
1851+
LatestEventValueBuilder::new_local(&update, &mut buffer, &room_event_cache, None, None).await,
1852+
LatestEventValue::LocalIsSending => with body = "A"
1853+
);
1854+
1855+
transaction_id
1856+
};
1857+
1858+
// Receiving a `SendError` targeting the first event. The
1859+
// `LatestEventValue` must change to indicate it “cannot be sent”.
1860+
{
1861+
let update = RoomSendQueueUpdate::SendError {
1862+
transaction_id: transaction_id_0.clone(),
1863+
error: Arc::new(Error::UnknownError("oopsy".to_owned().into())),
1864+
is_recoverable: true,
1865+
};
1866+
1867+
// The `LatestEventValue` has changed, it still matches the latest local
1868+
// event but it's marked as “cannot be sent”.
1869+
assert_local_value_matches_room_message_with_body!(
1870+
LatestEventValueBuilder::new_local(&update, &mut buffer, &room_event_cache, None, None).await,
1871+
LatestEventValue::LocalCannotBeSent => with body = "A"
1872+
);
1873+
1874+
assert_eq!(buffer.buffer.len(), 1);
1875+
assert_matches!(&buffer.buffer[0].1, LatestEventValue::LocalCannotBeSent(_));
1876+
}
1877+
1878+
// Receiving another `NewLocalEvent`, ensuring it's pushed back in the buffer,
1879+
// and as a `LocalCannotBeSent` because the previous value is itself
1880+
// `LocalCannotBeSent`.
1881+
{
1882+
let transaction_id = OwnedTransactionId::from("txnid1");
1883+
let content = new_local_echo_content(&room_send_queue, &transaction_id, "B");
1884+
1885+
let update = RoomSendQueueUpdate::NewLocalEvent(LocalEcho { transaction_id, content });
1886+
1887+
// The `LatestEventValue` matches the new local event.
1888+
assert_local_value_matches_room_message_with_body!(
1889+
LatestEventValueBuilder::new_local(&update, &mut buffer, &room_event_cache, None, None).await,
1890+
LatestEventValue::LocalCannotBeSent => with body = "B"
1891+
);
1892+
}
1893+
1894+
assert_eq!(buffer.buffer.len(), 2);
1895+
assert_matches!(&buffer.buffer[0].1, LatestEventValue::LocalCannotBeSent(_));
1896+
assert_matches!(&buffer.buffer[1].1, LatestEventValue::LocalCannotBeSent(_));
1897+
}
1898+
18231899
#[async_test]
18241900
async fn test_local_cancelled_local_event() {
18251901
let (_client, _room_id, room_send_queue, room_event_cache) = local_prelude().await;

0 commit comments

Comments
 (0)