Skip to content

Commit

Permalink
sdk-ui: add PinnedEventsLoaderError::TimelineReloadFailed.
Browse files Browse the repository at this point in the history
This error will be returned when the room has pinned event ids but the timeline couldn't load any of them.

Also fix tests.
  • Loading branch information
jmartinesp committed Aug 5, 2024
1 parent efdd6d2 commit 91c10ae
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 15 deletions.
10 changes: 9 additions & 1 deletion crates/matrix-sdk-ui/src/timeline/pinned_events_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ impl PinnedEventsLoader {
.rev()
.collect();

let has_pinned_event_ids = !pinned_event_ids.is_empty();
let mut loaded_events = Vec::new();
let mut event_ids_to_request = Vec::new();
for ev_id in pinned_event_ids {
Expand Down Expand Up @@ -89,11 +90,15 @@ impl PinnedEventsLoader {

for handle in handles {
if let Ok(Ok(ev)) = handle.await {
loaded_events.push(ev)
loaded_events.push(ev);
}
}
}

if has_pinned_event_ids && loaded_events.is_empty() {
return Err(PinnedEventsLoaderError::TimelineReloadFailed);
}

info!("Saving {} pinned events to the cache", loaded_events.len());
cache.set_bulk(&loaded_events).await;

Expand Down Expand Up @@ -198,4 +203,7 @@ pub enum PinnedEventsLoaderError {

#[error("Timeline focus is not pinned events.")]
TimelineFocusNotPinnedEvents,

#[error("Could not load pinned events.")]
TimelineReloadFailed,
}
75 changes: 61 additions & 14 deletions crates/matrix-sdk-ui/tests/integration/timeline/pinned_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,21 +166,15 @@ async fn test_max_events_to_load_is_honored() {
.await;

let room = test_helper.client.get_room(&room_id).unwrap();
let timeline = Timeline::builder(&room)
let ret = Timeline::builder(&room)
.with_focus(TimelineFocus::PinnedEvents { max_events_to_load: 1 })
.build()
.await
.unwrap();

assert!(
timeline.live_back_pagination_status().await.is_none(),
"there should be no live back-pagination status for a focused timeline"
);
.await;

let (items, mut timeline_stream) = timeline.subscribe().await;
// We're only taking the last event id, `$2`, and it's not available so the
// timeline fails to initialise.
assert!(ret.is_err());

assert!(items.is_empty()); // We're only taking the last event id, `$2`, and it's not available
assert_pending!(timeline_stream);
test_helper.server.reset().await;
}

Expand Down Expand Up @@ -256,15 +250,68 @@ async fn test_cached_events_are_kept_for_different_room_instances() {
let room = test_helper.client.get_room(&room_id).unwrap();

// And a new timeline one
let timeline = Timeline::builder(&room)
let ret = Timeline::builder(&room)
.with_focus(TimelineFocus::PinnedEvents { max_events_to_load: 2 })
.build()
.await;

// Since the events are no longer in the cache the timeline couldn't load them
// and can't be initialised.
assert!(ret.is_err());

test_helper.server.reset().await;
}

#[async_test]
async fn test_pinned_timeline_with_pinned_event_ids_and_empty_result_fails() {
let mut test_helper = TestHelper::new().await;
let room_id = test_helper.room_id.clone();

// Join the room
let _ = test_helper.setup_initial_sync_response().await;
test_helper.server.reset().await;

// Load initial timeline items: a `m.room.pinned_events` with event $1 and $2
// pinned, but they're not available neither in the cache nor in the HS
let _ = test_helper.setup_sync_response(Vec::new(), Some(vec!["$1", "$2"])).await;

let room = test_helper.client.get_room(&room_id).unwrap();
let ret = Timeline::builder(&room)
.with_focus(TimelineFocus::PinnedEvents { max_events_to_load: 1 })
.build()
.await;

// The timeline couldn't load any events so it fails to initialise
assert!(ret.is_err());

test_helper.server.reset().await;
}

#[async_test]
async fn test_pinned_timeline_with_no_pinned_event_ids_is_just_empty() {
let mut test_helper = TestHelper::new().await;
let room_id = test_helper.room_id.clone();

// Join the room
let _ = test_helper.setup_initial_sync_response().await;
test_helper.server.reset().await;

// Load initial timeline items: an empty `m.room.pinned_events` event
let _ = test_helper.setup_sync_response(Vec::new(), Some(Vec::new())).await;

let room = test_helper.client.get_room(&room_id).unwrap();
let timeline = Timeline::builder(&room)
.with_focus(TimelineFocus::PinnedEvents { max_events_to_load: 1 })
.build()
.await
.unwrap();

// The timeline couldn't load any events, but it expected none, so it just
// returns an empty list
let (items, _) = timeline.subscribe().await;
assert!(items.is_empty()); // These events are no longer in the cache, so
// they couldn't be retrieved
assert!(items.is_empty());

test_helper.server.reset().await;
}

struct TestHelper {
Expand Down

0 comments on commit 91c10ae

Please sign in to comment.