Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sdk-ui: add PinnedEventsLoaderError::TimelineReloadFailed #3804

Merged
merged 1 commit into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -197,4 +202,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
Loading