fix: set prev_batch first time from sync response correctly

This commit is contained in:
Karthikeyan S 2025-03-18 22:30:23 +05:30
parent d8b262b629
commit a3aede19e8
No known key found for this signature in database
GPG Key ID: 28BA6AEE539ECE2E
3 changed files with 134 additions and 14 deletions

View File

@ -331,6 +331,31 @@ class FakeMatrixApi extends BaseClient {
};
}
// since direction is b, the start and end are reversed
static const Map<String, dynamic> emptyHistoryResponse = {
'start': 'simpleHistoryResponse', // next_batch
'end': null, // prev_batch
'chunk': [],
'state': [],
};
static const Map<String, dynamic> simpleHistoryResponse = {
'start': '1', // next_batch
'end': 'emptyHistoryResponse', // prev_batch
'chunk': [
{
'content': {'body': '0'},
'type': 'm.room.message',
'event_id': '0',
'room_id': 'new_room_id',
'sender': '@example:example.org',
'origin_server_ts': 1432735824653,
'unsigned': {'age': 1234},
'state_key': '',
},
],
'state': [],
};
static const Map<String, dynamic> messagesResponsePast = {
'start': 't47429-4392820_219380_26003_2265',
'end': 't47409-4357353_219380_26003_2265',
@ -1724,6 +1749,10 @@ class FakeMatrixApi extends BaseClient {
'origin_server_ts': 1432735824653,
'unsigned': {'age': 1234},
},
'/client/v3/rooms/new_room_id/messages?from=emptyHistoryResponse&dir=b&limit=30&filter=%7B%22lazy_load_members%22%3Atrue%7D':
(var req) => emptyHistoryResponse,
'/client/v3/rooms/new_room_id/messages?from=1&dir=b&limit=30&filter=%7B%22lazy_load_members%22%3Atrue%7D':
(var req) => simpleHistoryResponse,
'/client/v3/rooms/!localpart%3Aserver.abc/messages?from=1234&dir=b&to=1234&limit=10&filter=%7B%22lazy_load_members%22%3Atrue%7D':
(var req) => messagesResponsePast,
'/client/v3/rooms/!localpart%3Aserver.abc/messages?from=&dir=b&limit=10&filter=%7B%22lazy_load_members%22%3Atrue%7D':

View File

@ -2984,14 +2984,18 @@ class Client extends MatrixApi {
(chatUpdate.unreadNotifications?.highlightCount ?? 0) ||
chatUpdate.summary != null ||
chatUpdate.timeline?.prevBatch != null)) {
/// [InvitedRoomUpdate] doesn't have prev_batch, so we want to set it in case
/// the room first appeared in sync update when membership was invite.
if (rooms[roomIndex].membership == Membership.invite &&
chatUpdate.timeline?.prevBatch != null) {
rooms[roomIndex].prev_batch = chatUpdate.timeline?.prevBatch;
}
rooms[roomIndex].membership = membership;
rooms[roomIndex].notificationCount =
chatUpdate.unreadNotifications?.notificationCount ?? 0;
rooms[roomIndex].highlightCount =
chatUpdate.unreadNotifications?.highlightCount ?? 0;
if (chatUpdate.timeline?.prevBatch != null) {
rooms[roomIndex].prev_batch = chatUpdate.timeline?.prevBatch;
}
final summary = chatUpdate.summary;
if (summary != null) {
final roomSummaryJson = rooms[roomIndex].summary.toJson()

View File

@ -761,21 +761,59 @@ void main() {
expect(room.lastEvent!.content['body'], '* foxies');
});
test('set prev_batch if in sync', () async {
final roomId = '!726s6s6q:example.com';
final room = matrix.getRoomById(roomId)!;
expect(room.prev_batch, 't44-23535_0_0');
// put an important state event in-memory
test('set prev_batch when invite then join', () async {
await matrix.handleSync(
SyncUpdate.fromJson({
'next_batch': 'fakesync',
'next_batch': '1',
'rooms': {
'invite': {
'new_room_id': {
'invite_state': {
'events': [
MatrixEvent(
eventId: '0',
type: EventTypes.RoomCreate,
content: {'body': '0'},
senderId: '@alice:example.com',
stateKey: '@alice:example.com',
originServerTs: DateTime.now(),
).toJson(),
],
},
},
},
},
}),
);
expect(
matrix.rooms.singleWhereOrNull(
(element) => element.id == 'new_room_id',
),
isNotNull,
);
final newRoom = matrix.getRoomById('new_room_id')!;
expect(newRoom.prev_batch, null);
await matrix.handleSync(
SyncUpdate.fromJson({
'next_batch': '3',
'rooms': {
'join': {
roomId: {
'new_room_id': {
'timeline': {
'events': [],
'prev_batch': 'prev_batch_1',
'events': [
MatrixEvent(
eventId: '2',
type: EventTypes.RoomCreate,
content: {'body': '2'},
senderId: '@alice:example.com',
stateKey: '@alice:example.com',
originServerTs: DateTime.now(),
).toJson(),
],
'prev_batch': '1',
},
},
},
@ -783,7 +821,56 @@ void main() {
}),
);
expect(room.prev_batch, 'prev_batch_1');
final timeline = await newRoom.getTimeline();
expect(newRoom.prev_batch, '1');
expect(timeline.events.length, 1);
expect(timeline.events.first.eventId, '2');
await matrix.handleSync(
SyncUpdate.fromJson({
'next_batch': '4',
'rooms': {
'join': {
'new_room_id': {
'timeline': {
'events': [
MatrixEvent(
eventId: '3',
type: EventTypes.Message,
content: {'body': '3'},
senderId: '@alice2:example.com',
stateKey: '@alice2:example.com',
originServerTs: DateTime.now(),
).toJson(),
],
'prev_batch': '2',
},
},
},
},
}),
);
expect(newRoom.prev_batch, '1');
expect(timeline.events.length, 2);
expect(timeline.events.last.eventId, '2');
expect(timeline.events.first.eventId, '3');
if (timeline.canRequestHistory) {
await timeline.requestHistory();
}
expect(newRoom.prev_batch, 'emptyHistoryResponse');
expect(timeline.events.length, 3);
expect(timeline.events.last.eventId, '0');
expect(timeline.events.first.eventId, '3');
while (timeline.canRequestHistory) {
await timeline.requestHistory();
}
expect(newRoom.prev_batch, null);
expect(timeline.events.length, 3);
expect(timeline.events.last.eventId, '0');
expect(timeline.events.first.eventId, '3');
});
test('getProfileFromUserId', () async {