matrix-dart-sdk/test/event_timeout_test.dart

118 lines
3.8 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:path/path.dart';
import 'package:test/test.dart';
import 'package:matrix/matrix.dart';
import 'fake_client.dart';
void main() {
group('Event timeout tests', () {
late Client client;
late Room room;
setUp(() async {
client = await getClient(
sendTimelineEventTimeout: const Duration(seconds: 5),
databasePath: join(Directory.current.path, 'test.sqlite'),
);
room = Room(
id: '!1234:example.com',
client: client,
roomAccountData: {},
);
client.rooms.add(room);
});
tearDown(() async {
await client.logout();
await client.dispose(closeDatabase: true);
});
test('Event constructor correctly checks timeout from originServerTs',
() async {
final completer = Completer();
room.sendingQueue.add(completer); // to block the events from being sent
String? eventId;
// we don't await this because the actual sending will only be done after
// `sendingQueue` is unblocked.
// but the fake sync will be called with this event in sending state right away
unawaited(
room.sendTextEvent('test', txid: '1234').then((value) {
eventId = value;
}),
);
// do the timeout
final timeout =
Duration(seconds: client.sendTimelineEventTimeout.inSeconds + 2);
await Future.delayed(timeout);
// this will trigger the check in the Event constructor to see if the
// event is in error state (and call fake sync with updated error status)
await client.oneShotSync();
Timeline timeline = await room.getTimeline();
expect(timeline.events.length, 1);
expect(timeline.events.first.status, EventStatus.sending);
// fake sync would have been triggered by now (if there was one), which shouldn't happen
await client.oneShotSync();
timeline = await room.getTimeline();
expect(timeline.events.length, 1);
expect(timeline.events.first.status, EventStatus.sending);
// now we unblock the sending queue and this will make `sendTextEvent`
// actually send the event and the fake sync that's used to update the
// event status to sent
completer.complete();
room.sendingQueue.remove(completer);
await FakeMatrixApi.firstWhere(
(a) => a.startsWith(
'/client/v3/rooms/!1234%3Aexample.com/send/m.room.message/1234',
),
);
await Future.delayed(const Duration(seconds: 1));
expect(eventId, isNotNull);
// now the event should be in sent state after the fake sync is called
await client.oneShotSync();
timeline = await room.getTimeline();
expect(timeline.events.length, 1);
expect(timeline.events.first.status, EventStatus.sent);
// simulate the event being synced from server
await client.handleSync(
SyncUpdate(
nextBatch: '1',
rooms: RoomsUpdate(
join: {
room.id: JoinedRoomUpdate(
timeline: TimelineUpdate(
events: [
Event(
eventId: eventId!,
content: {'msgtype': 'm.text', 'body': 'test'},
type: 'm.room.message',
senderId: '@test:example.com',
originServerTs: DateTime.now(),
room: room,
unsigned: {
'transaction_id': '1234',
},
),
],
),
),
},
),
),
);
timeline = await room.getTimeline();
expect(timeline.events.length, 1);
expect(timeline.events.first.status, EventStatus.synced);
});
});
}