Skip to content

Commit fd6e21e

Browse files
committed
supa test
1 parent 2a69868 commit fd6e21e

File tree

2 files changed

+183
-20
lines changed

2 files changed

+183
-20
lines changed

crates/matrix-sdk-ui/tests/integration/main.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,17 @@ async fn mock_context(
7575
"event": event.event,
7676
"events_after": events_after.into_iter().map(|ev| ev.event).collect_vec(),
7777
"state": state,
78-
"prev_batch_token": prev_batch_token,
79-
"next_batch_token": next_batch_token
78+
"start": prev_batch_token,
79+
"end": next_batch_token
8080
})))
8181
.mount(&server)
8282
.await;
8383
}
8484

85+
/// Mocks the /messages endpoint.
86+
///
87+
/// Note: pass `chunk` in the correct order: topological for forward pagination,
88+
/// reverse topological for backwards pagination.
8589
async fn mock_messages(
8690
server: &MockServer,
8791
start: String,

crates/matrix-sdk-ui/tests/integration/timeline/focus_event.rs

Lines changed: 177 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
1717
use std::time::Duration;
1818

19-
use assert_matches::assert_matches;
2019
use assert_matches2::assert_let;
2120
use eyeball_im::VectorDiff;
2221
use futures_util::StreamExt;
@@ -25,33 +24,29 @@ use matrix_sdk::{
2524
test_utils::{events::EventFactory, logged_in_client_with_server},
2625
};
2726
use matrix_sdk_test::{
28-
async_test, sync_timeline_event, JoinedRoomBuilder, RoomAccountDataTestEvent, StateTestEvent,
29-
SyncResponseBuilder, ALICE, BOB,
27+
async_test, sync_timeline_event, JoinedRoomBuilder, SyncResponseBuilder, ALICE, BOB,
3028
};
31-
use matrix_sdk_ui::{
32-
timeline::{RoomExt, TimelineFocus, TimelineItemContent, VirtualTimelineItem},
33-
Timeline,
34-
};
35-
use ruma::{event_id, room_id, user_id};
29+
use matrix_sdk_ui::{timeline::TimelineFocus, Timeline};
30+
use ruma::{event_id, room_id};
3631
use stream_assert::assert_pending;
3732

38-
use crate::{mock_context, mock_sync};
33+
use crate::{mock_context, mock_messages, mock_sync};
3934

4035
#[async_test]
4136
async fn test_new_focused() {
4237
let room_id = room_id!("!a98sd12bjh:example.org");
4338
let (client, server) = logged_in_client_with_server().await;
4439
let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
4540

46-
let mut ev_builder = SyncResponseBuilder::new();
47-
ev_builder.add_joined_room(JoinedRoomBuilder::new(room_id));
41+
let mut sync_response_builder = SyncResponseBuilder::new();
42+
sync_response_builder.add_joined_room(JoinedRoomBuilder::new(room_id));
4843

4944
// Mark the room as joined.
50-
mock_sync(&server, ev_builder.build_json_sync_response(), None).await;
45+
mock_sync(&server, sync_response_builder.build_json_sync_response(), None).await;
5146
let _response = client.sync_once(sync_settings.clone()).await.unwrap();
5247
server.reset().await;
5348

54-
let factory = EventFactory::new().room(room_id);
49+
let f = EventFactory::new().room(room_id);
5550
let target_event = event_id!("$1");
5651

5752
mock_context(
@@ -60,13 +55,13 @@ async fn test_new_focused() {
6055
target_event,
6156
Some("prev1".to_owned()),
6257
vec![
63-
factory.text_msg("i tried so hard").sender(*ALICE).into_timeline(),
64-
factory.text_msg("and got so far").sender(*ALICE).into_timeline(),
58+
f.text_msg("i tried so hard").sender(*ALICE).into_timeline(),
59+
f.text_msg("and got so far").sender(*ALICE).into_timeline(),
6560
],
66-
factory.text_msg("in the end").sender(*BOB).into_timeline(),
61+
f.text_msg("in the end").event_id(target_event).sender(*BOB).into_timeline(),
6762
vec![
68-
factory.text_msg("it doesn't even").sender(*ALICE).into_timeline(),
69-
factory.text_msg("matter").sender(*ALICE).into_timeline(),
63+
f.text_msg("it doesn't even").sender(*ALICE).into_timeline(),
64+
f.text_msg("matter").sender(*ALICE).into_timeline(),
7065
],
7166
Some("next1".to_owned()),
7267
vec![],
@@ -105,4 +100,168 @@ async fn test_new_focused() {
105100
assert_eq!(items[5].as_event().unwrap().content().as_message().unwrap().body(), "matter");
106101

107102
assert_pending!(timeline_stream);
103+
104+
// Now trigger a backward pagination.
105+
mock_messages(
106+
&server,
107+
"prev1".to_owned(),
108+
None,
109+
vec![
110+
// reversed manually here
111+
f.text_msg("And even though I tried, it all fell apart").sender(*BOB).into_timeline(),
112+
f.text_msg("I kept everything inside").sender(*BOB).into_timeline(),
113+
],
114+
vec![],
115+
)
116+
.await;
117+
118+
let hit_start = timeline.focused_paginate_backwards(20).await.unwrap();
119+
assert!(hit_start);
120+
121+
server.reset().await;
122+
123+
assert_let!(Some(VectorDiff::PushFront { value: message }) = timeline_stream.next().await);
124+
assert_eq!(
125+
message.as_event().unwrap().content().as_message().unwrap().body(),
126+
"And even though I tried, it all fell apart"
127+
);
128+
129+
assert_let!(Some(VectorDiff::PushFront { value: message }) = timeline_stream.next().await);
130+
assert_eq!(
131+
message.as_event().unwrap().content().as_message().unwrap().body(),
132+
"I kept everything inside"
133+
);
134+
135+
// Day divider post processing.
136+
assert_let!(Some(VectorDiff::PushFront { value: item }) = timeline_stream.next().await);
137+
assert!(item.is_day_divider());
138+
assert_let!(Some(VectorDiff::Remove { index }) = timeline_stream.next().await);
139+
assert_eq!(index, 3);
140+
141+
// Now trigger a forward pagination.
142+
mock_messages(
143+
&server,
144+
"next1".to_owned(),
145+
Some("next2".to_owned()),
146+
vec![
147+
f.text_msg("I had to fall, to lose it all").sender(*BOB).into_timeline(),
148+
f.text_msg("But in the end, it doesn't event matter").sender(*BOB).into_timeline(),
149+
],
150+
vec![],
151+
)
152+
.await;
153+
154+
let hit_start = timeline.focused_paginate_forwards(20).await.unwrap();
155+
assert!(!hit_start); // because we gave it another next2 token.
156+
157+
server.reset().await;
158+
159+
assert_let!(Some(VectorDiff::PushBack { value: message }) = timeline_stream.next().await);
160+
assert_eq!(
161+
message.as_event().unwrap().content().as_message().unwrap().body(),
162+
"I had to fall, to lose it all"
163+
);
164+
165+
assert_let!(Some(VectorDiff::PushBack { value: message }) = timeline_stream.next().await);
166+
assert_eq!(
167+
message.as_event().unwrap().content().as_message().unwrap().body(),
168+
"But in the end, it doesn't event matter"
169+
);
170+
171+
assert_pending!(timeline_stream);
172+
}
173+
174+
#[async_test]
175+
async fn test_focused_timeline_reacts() {
176+
let room_id = room_id!("!a98sd12bjh:example.org");
177+
let (client, server) = logged_in_client_with_server().await;
178+
let sync_settings = SyncSettings::new().timeout(Duration::from_millis(3000));
179+
180+
let mut sync_response_builder = SyncResponseBuilder::new();
181+
sync_response_builder.add_joined_room(JoinedRoomBuilder::new(room_id));
182+
183+
// Mark the room as joined.
184+
mock_sync(&server, sync_response_builder.build_json_sync_response(), None).await;
185+
let _response = client.sync_once(sync_settings.clone()).await.unwrap();
186+
server.reset().await;
187+
188+
// Start a focused timeline.
189+
let f = EventFactory::new().room(room_id);
190+
let target_event = event_id!("$1");
191+
192+
mock_context(
193+
&server,
194+
room_id,
195+
target_event,
196+
None,
197+
vec![],
198+
f.text_msg("yolo").event_id(target_event).sender(*BOB).into_timeline(),
199+
vec![],
200+
None,
201+
vec![],
202+
)
203+
.await;
204+
205+
let room = client.get_room(room_id).unwrap();
206+
let timeline = Timeline::builder(&room)
207+
.with_focus(TimelineFocus::Event {
208+
target: target_event.to_owned(),
209+
num_context_events: 20,
210+
})
211+
.build()
212+
.await
213+
.unwrap();
214+
215+
server.reset().await;
216+
217+
let (items, mut timeline_stream) = timeline.subscribe().await;
218+
219+
assert_eq!(items.len(), 1 + 1); // event items + a day divider
220+
assert!(items[0].is_day_divider());
221+
222+
let event_item = items[1].as_event().unwrap();
223+
assert_eq!(event_item.content().as_message().unwrap().body(), "yolo");
224+
assert_eq!(event_item.reactions().len(), 0);
225+
226+
assert_pending!(timeline_stream);
227+
228+
// Now simulate a sync that returns a new message-like event, and a reaction
229+
// to the $1 event.
230+
sync_response_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_timeline_bulk([
231+
// This event must be ignored.
232+
f.text_msg("this is a sync event").sender(*ALICE).into_raw_sync(),
233+
// This event must not be ignored.
234+
sync_timeline_event!({
235+
"content": {
236+
"m.relates_to": {
237+
"event_id": "$1",
238+
"key": "👍",
239+
"rel_type": "m.annotation"
240+
}
241+
},
242+
"event_id": "$15275047031IXQRi:localhost",
243+
"origin_server_ts": 159027581000000_u64,
244+
"sender": *BOB,
245+
"type": "m.reaction",
246+
"unsigned": {
247+
"age": 85
248+
}
249+
}),
250+
]));
251+
252+
// Sync the room.
253+
mock_sync(&server, sync_response_builder.build_json_sync_response(), None).await;
254+
let _response = client.sync_once(sync_settings.clone()).await.unwrap();
255+
server.reset().await;
256+
257+
assert_let!(Some(VectorDiff::Set { index: 1, value: item }) = timeline_stream.next().await);
258+
259+
let event_item = item.as_event().unwrap();
260+
// Text hasn't changed.
261+
assert_eq!(event_item.content().as_message().unwrap().body(), "yolo");
262+
// But now there's one reaction to the event.
263+
assert_eq!(event_item.reactions().len(), 1);
264+
265+
// And nothing more.
266+
assert_pending!(timeline_stream);
108267
}

0 commit comments

Comments
 (0)