Skip to content

Commit c37c8c5

Browse files
committed
sdk: add RequestConfig to Room::event_with_context to match Room::event, save its results to the event cache too.
1 parent 77d52c6 commit c37c8c5

File tree

6 files changed

+125
-33
lines changed

6 files changed

+125
-33
lines changed

crates/matrix-sdk-ui/src/notification_client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ impl NotificationClient {
478478
return Err(Error::UnknownRoom);
479479
};
480480

481-
let response = room.event_with_context(event_id, true, uint!(0)).await?;
481+
let response = room.event_with_context(event_id, true, uint!(0), None).await?;
482482

483483
let mut timeline_event = response.event.ok_or(Error::ContextMissingEvent)?;
484484
let state_events = response.state;

crates/matrix-sdk/src/event_cache/mod.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -554,15 +554,10 @@ impl RoomEventCache {
554554
// be no distinction between the linked chunk and the separate cache.
555555
pub(crate) async fn save_event(&self, event: SyncTimelineEvent) {
556556
if let Some(event_id) = event.event_id() {
557-
let mut cache = self.inner
558-
.all_events_cache
559-
.write()
560-
.await;
557+
let mut cache = self.inner.all_events_cache.write().await;
561558

562559
self.inner.append_related_event(&mut cache, &event);
563-
cache.events
564-
.insert(event_id, (self.inner.room_id.clone(), event));
565-
560+
cache.events.insert(event_id, (self.inner.room_id.clone(), event));
566561
} else {
567562
warn!("couldn't save event without event id in the event cache");
568563
}

crates/matrix-sdk/src/event_cache/paginator.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -469,24 +469,24 @@ impl PaginableRoom for Room {
469469
lazy_load_members: bool,
470470
num_events: UInt,
471471
) -> Result<EventWithContextResponse, PaginatorError> {
472-
let response = match self.event_with_context(event_id, lazy_load_members, num_events).await
473-
{
474-
Ok(result) => result,
475-
476-
Err(err) => {
477-
// If the error was a 404, then the event wasn't found on the server; special
478-
// case this to make it easy to react to such an error.
479-
if let Some(error) = err.as_client_api_error() {
480-
if error.status_code == 404 {
481-
// Event not found
482-
return Err(PaginatorError::EventNotFound(event_id.to_owned()));
472+
let response =
473+
match self.event_with_context(event_id, lazy_load_members, num_events, None).await {
474+
Ok(result) => result,
475+
476+
Err(err) => {
477+
// If the error was a 404, then the event wasn't found on the server; special
478+
// case this to make it easy to react to such an error.
479+
if let Some(error) = err.as_client_api_error() {
480+
if error.status_code == 404 {
481+
// Event not found
482+
return Err(PaginatorError::EventNotFound(event_id.to_owned()));
483+
}
483484
}
484-
}
485485

486-
// Otherwise, just return a wrapped error.
487-
return Err(PaginatorError::SdkError(Box::new(err)));
488-
}
489-
};
486+
// Otherwise, just return a wrapped error.
487+
return Err(PaginatorError::SdkError(Box::new(err)));
488+
}
489+
};
490490

491491
Ok(response)
492492
}

crates/matrix-sdk/src/room/mod.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use matrix_sdk_base::{
2323
ComposerDraft, RoomInfoNotableUpdateReasons, RoomMemberships, StateChanges, StateStoreDataKey,
2424
StateStoreDataValue,
2525
};
26-
use matrix_sdk_common::timeout::timeout;
26+
use matrix_sdk_common::{deserialized_responses::SyncTimelineEvent, timeout::timeout};
2727
use mime::Mime;
2828
#[cfg(feature = "e2e-encryption")]
2929
use ruma::events::{
@@ -417,6 +417,7 @@ impl Room {
417417
event_id: &EventId,
418418
lazy_load_members: bool,
419419
context_size: UInt,
420+
request_config: Option<RequestConfig>,
420421
) -> Result<EventWithContextResponse> {
421422
let mut request =
422423
context::get_context::v3::Request::new(self.room_id().to_owned(), event_id.to_owned());
@@ -428,7 +429,7 @@ impl Room {
428429
LazyLoadOptions::Enabled { include_redundant_members: false };
429430
}
430431

431-
let response = self.client.send(request, None).await?;
432+
let response = self.client.send(request, request_config).await?;
432433

433434
let target_event = if let Some(event) = response.event {
434435
Some(self.try_decrypt_event(event).await?)
@@ -445,6 +446,24 @@ impl Room {
445446
)
446447
.await?;
447448

449+
// Save the loaded events into the event cache, if it's set up.
450+
if let Ok((cache, _handles)) = self.event_cache().await {
451+
let mut events_to_save: Vec<SyncTimelineEvent> = Vec::new();
452+
if let Some(event) = &target_event {
453+
events_to_save.push(event.clone().into());
454+
}
455+
456+
for event in &events_before {
457+
events_to_save.push(event.clone().into());
458+
}
459+
460+
for event in &events_after {
461+
events_to_save.push(event.clone().into());
462+
}
463+
464+
cache.save_events(events_to_save).await;
465+
}
466+
448467
Ok(EventWithContextResponse {
449468
event: target_event,
450469
events_before,

crates/matrix-sdk/tests/integration/room/common.rs

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
use std::{iter, time::Duration};
22

33
use assert_matches2::assert_let;
4-
use matrix_sdk::{config::SyncSettings, room::RoomMember, DisplayName, RoomMemberships};
4+
use js_int::uint;
5+
use matrix_sdk::{
6+
config::SyncSettings, room::RoomMember, test_utils::events::EventFactory, DisplayName,
7+
RoomMemberships,
8+
};
59
use matrix_sdk_test::{
610
async_test, bulk_room_members, sync_state_event, sync_timeline_event, test_json,
711
GlobalAccountDataTestEvent, JoinedRoomBuilder, LeftRoomBuilder, StateTestEvent,
@@ -10,14 +14,14 @@ use matrix_sdk_test::{
1014
use ruma::{
1115
event_id,
1216
events::{
13-
room::member::MembershipState, AnyStateEvent, AnySyncStateEvent, AnyTimelineEvent,
14-
StateEventType,
17+
room::{member::MembershipState, message::RoomMessageEventContent},
18+
AnyStateEvent, AnySyncStateEvent, AnyTimelineEvent, StateEventType,
1519
},
1620
room_id,
1721
};
1822
use serde_json::json;
1923
use wiremock::{
20-
matchers::{body_json, header, method, path_regex},
24+
matchers::{body_json, header, method, path, path_regex},
2125
Mock, ResponseTemplate,
2226
};
2327

@@ -620,6 +624,9 @@ async fn test_event() {
620624
let event_id = event_id!("$foun39djjod0f");
621625

622626
let (client, server) = logged_in_client_with_server().await;
627+
let cache = client.event_cache();
628+
let _ = cache.subscribe();
629+
623630
let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
624631

625632
let mut sync_builder = SyncResponseBuilder::new();
@@ -668,6 +675,76 @@ async fn test_event() {
668675
let push_actions = timeline_event.push_actions.unwrap();
669676
assert!(push_actions.iter().any(|a| a.is_highlight()));
670677
assert!(push_actions.iter().any(|a| a.should_notify()));
678+
679+
// Requested event was saved to the cache
680+
assert!(cache.event(event_id).await.is_some());
681+
}
682+
683+
#[async_test]
684+
async fn test_event_with_context() {
685+
let event_id = event_id!("$cur1234");
686+
let prev_event_id = event_id!("$prev1234");
687+
let next_event_id = event_id!("$next_1234");
688+
689+
let (client, server) = logged_in_client_with_server().await;
690+
let cache = client.event_cache();
691+
let _ = cache.subscribe();
692+
693+
let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
694+
695+
let mut sync_builder = SyncResponseBuilder::new();
696+
sync_builder
697+
// We need the member event and power levels locally so the push rules processor works.
698+
.add_joined_room(
699+
JoinedRoomBuilder::new(&DEFAULT_TEST_ROOM_ID)
700+
.add_state_event(StateTestEvent::Member)
701+
.add_state_event(StateTestEvent::PowerLevels),
702+
);
703+
704+
mock_sync(&server, sync_builder.build_json_sync_response(), None).await;
705+
let _response = client.sync_once(sync_settings.clone()).await.unwrap();
706+
server.reset().await;
707+
708+
let room = client.get_room(&DEFAULT_TEST_ROOM_ID).unwrap();
709+
let room_id = room.room_id();
710+
711+
let f = EventFactory::new().room(room_id).sender(*BOB);
712+
let event =
713+
f.event(RoomMessageEventContent::text_plain("The requested message")).event_id(event_id);
714+
let event_before =
715+
f.event(RoomMessageEventContent::text_plain("A previous message")).event_id(prev_event_id);
716+
let event_next =
717+
f.event(RoomMessageEventContent::text_plain("A newer message")).event_id(next_event_id);
718+
Mock::given(method("GET"))
719+
.and(path(format!("/_matrix/client/r0/rooms/{room_id}/context/{event_id}")))
720+
.and(header("authorization", "Bearer 1234"))
721+
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
722+
"events_before": [event_before.into_raw_timeline()],
723+
"event": event.into_raw_timeline(),
724+
"events_after": [event_next.into_raw_timeline()],
725+
"state": [],
726+
})))
727+
.mount(&server)
728+
.await;
729+
730+
let context_ret = room.event_with_context(event_id, false, uint!(1), None).await.unwrap();
731+
732+
assert_let!(Some(timeline_event) = context_ret.event);
733+
assert_let!(Ok(event) = timeline_event.event.deserialize());
734+
assert_eq!(event.event_id(), event_id);
735+
736+
assert_eq!(1, context_ret.events_before.len());
737+
assert_let!(Ok(event) = context_ret.events_before[0].event.deserialize());
738+
assert_eq!(event.event_id(), prev_event_id);
739+
740+
assert_eq!(1, context_ret.events_after.len());
741+
assert_let!(Ok(event) = context_ret.events_after[0].event.deserialize());
742+
assert_eq!(event.event_id(), next_event_id);
743+
744+
// Requested event and their context ones were saved to the cache
745+
assert!(cache.event(event_id).await.is_some());
746+
assert!(cache.event(prev_event_id).await.is_some());
747+
assert!(cache.event(next_event_id).await.is_some());
671748
}
672749

673750
#[async_test]

testing/matrix-sdk-integration-testing/src/tests/room.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ async fn test_event_with_context() -> Result<()> {
9494

9595
{
9696
// First /context query: only the target event, no context around it.
97-
let response = room.event_with_context(&event_id, false, uint!(0)).await?;
97+
let response = room.event_with_context(&event_id, false, uint!(0), None).await?;
9898

9999
let target = response
100100
.event
@@ -113,7 +113,8 @@ async fn test_event_with_context() -> Result<()> {
113113

114114
{
115115
// Next query: an event that doesn't exist (hopefully!).
116-
let response = room.event_with_context(event_id!("$lolololol"), false, uint!(0)).await;
116+
let response =
117+
room.event_with_context(event_id!("$lolololol"), false, uint!(0), None).await;
117118

118119
// Servers answers with 404.
119120
assert_let!(Err(err) = response);
@@ -123,7 +124,7 @@ async fn test_event_with_context() -> Result<()> {
123124
{
124125
// Next query: target event with a context of 3 events. There
125126
// should be some previous and next tokens.
126-
let response = room.event_with_context(&event_id, false, uint!(3)).await?;
127+
let response = room.event_with_context(&event_id, false, uint!(3), None).await?;
127128

128129
let target = response
129130
.event

0 commit comments

Comments
 (0)