Merge pull request #1992 from famedly/krille/remove-event-update-type

refactor: Use Event instead of EventUpdate for storing in db
This commit is contained in:
Krille-chan 2025-01-08 09:06:37 +01:00 committed by GitHub
commit b23ad952a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 594 additions and 578 deletions

View File

@ -154,20 +154,20 @@ class Encryption {
}
}
Future<void> handleEventUpdate(EventUpdate update) async {
if (update.type == EventUpdateType.history) {
Future<void> handleEventUpdate(Event event, EventUpdateType type) async {
if (type == EventUpdateType.history) {
return;
}
if (update.content['type'].startsWith('m.key.verification.') ||
(update.content['type'] == EventTypes.Message &&
(update.content['content']['msgtype'] is String) &&
update.content['content']['msgtype']
.startsWith('m.key.verification.'))) {
if (event.type.startsWith('m.key.verification.') ||
(event.type == EventTypes.Message &&
event.content
.tryGet<String>('msgtype')
?.startsWith('m.key.verification.') ==
true)) {
// "just" key verification, no need to do this in sync
runInRoot(() => keyVerificationManager.handleEventUpdate(update));
runInRoot(() => keyVerificationManager.handleEventUpdate(event));
}
if (update.content['sender'] == client.userID &&
update.content['unsigned']?['transaction_id'] == null) {
if (event.senderId == client.userID && event.status.isSynced) {
// maybe we need to re-try SSSS secrets
runInRoot(() => ssss.periodicallyRequestMissingCache());
}
@ -348,11 +348,9 @@ class Encryption {
event.room.setState(event);
}
await client.database?.storeEventUpdate(
EventUpdate(
content: event.toJson(),
roomID: event.room.id,
type: updateType,
),
event.room.id,
event,
updateType,
client,
);
}

View File

@ -88,29 +88,29 @@ class KeyVerificationManager {
}
}
Future<void> handleEventUpdate(EventUpdate update) async {
final event = update.content;
final type = event['type'].startsWith('m.key.verification.')
? event['type']
: event['content']['msgtype'];
Future<void> handleEventUpdate(Event update) async {
final type = update.type.startsWith('m.key.verification.')
? update.type
: update.content.tryGet<String>('msgtype');
if (type == null ||
!type.startsWith('m.key.verification.') ||
client.verificationMethods.isEmpty) {
return;
}
if (type == EventTypes.KeyVerificationRequest) {
event['content']['timestamp'] = event['origin_server_ts'];
update.content['timestamp'] =
update.originServerTs.millisecondsSinceEpoch;
}
final transactionId =
KeyVerification.getTransactionId(event['content']) ?? event['event_id'];
KeyVerification.getTransactionId(update.content) ?? update.eventId;
final req = _requests[transactionId];
if (req != null) {
final otherDeviceId = event['content']['from_device'];
if (event['sender'] != client.userID) {
await req.handlePayload(type, event['content'], event['event_id']);
} else if (event['sender'] == client.userID &&
final otherDeviceId = update.content.tryGet<String>('from_device');
if (update.senderId != client.userID) {
await req.handlePayload(type, update.content, update.eventId);
} else if (update.senderId == client.userID &&
otherDeviceId != null &&
otherDeviceId != client.deviceID) {
// okay, another of our devices answered
@ -118,22 +118,22 @@ class KeyVerificationManager {
req.dispose();
_requests.remove(transactionId);
}
} else if (event['sender'] != client.userID) {
} else if (update.senderId != client.userID) {
if (!{EventTypes.KeyVerificationRequest, EventTypes.KeyVerificationStart}
.contains(type)) {
return; // we can only start on these
}
final room = client.getRoomById(update.roomID) ??
Room(id: update.roomID, client: client);
final room = client.getRoomById(update.roomId!) ??
Room(id: update.roomId!, client: client);
final newKeyRequest = KeyVerification(
encryption: encryption,
userId: event['sender'],
userId: update.senderId,
room: room,
);
await newKeyRequest.handlePayload(
type,
event['content'],
event['event_id'],
update.content,
update.eventId,
);
if (newKeyRequest.state != KeyVerificationState.askAccept) {
// something went wrong, let's just dispose the request

View File

@ -1647,8 +1647,28 @@ class Client extends MatrixApi {
/// the app receives a new synchronization, this event is called for every signal
/// to update the GUI. For example, for a new message, it is called:
/// onRoomEvent( "m.room.message", "!chat_id:server.com", "timeline", {sender: "@bob:server.com", body: "Hello world"} )
// ignore: deprecated_member_use_from_same_package
@Deprecated(
'Use `onTimelineEvent`, `onHistoryEvent` or `onNotification` instead.',
)
final CachedStreamController<EventUpdate> onEvent = CachedStreamController();
/// A stream of all incoming timeline events for all rooms **after**
/// decryption. The events are coming in the same order as they come down from
/// the sync.
final CachedStreamController<Event> onTimelineEvent =
CachedStreamController();
/// A stream for all incoming historical timeline events **after** decryption
/// triggered by a `Room.requestHistory()` call or a method which calls it.
final CachedStreamController<Event> onHistoryEvent = CachedStreamController();
/// A stream of incoming Events **after** decryption which **should** trigger
/// a (local) notification. This includes timeline events but also
/// invite states. Excluded events are those sent by the user themself or
/// not matching the push rules.
final CachedStreamController<Event> onNotification = CachedStreamController();
/// The onToDeviceEvent is called when there comes a new to device event. It is
/// already decrypted if necessary.
final CachedStreamController<ToDeviceEvent> onToDeviceEvent =
@ -1889,11 +1909,9 @@ class Client extends MatrixApi {
if (storeInDatabase) {
await database?.transaction(() async {
await database.storeEventUpdate(
EventUpdate(
roomID: roomId,
type: EventUpdateType.timeline,
content: event.toJson(),
),
roomId,
event,
EventUpdateType.timeline,
this,
);
});
@ -2768,12 +2786,6 @@ class Client extends MatrixApi {
}
}
final update = EventUpdate(
roomID: room.id,
type: type,
content: event.toJson(),
);
// Any kind of member change? We should invalidate the profile then:
if (event.type == EventTypes.RoomMember) {
final userId = event.stateKey;
@ -2797,23 +2809,70 @@ class Client extends MatrixApi {
room.setState(user);
}
}
_updateRoomsByEventUpdate(room, update);
_updateRoomsByEventUpdate(room, event, type);
if (store) {
await database?.storeEventUpdate(update, this);
await database?.storeEventUpdate(room.id, event, type, this);
}
if (encryptionEnabled) {
await encryption?.handleEventUpdate(update);
if (event is MatrixEvent && encryptionEnabled) {
await encryption?.handleEventUpdate(
Event.fromMatrixEvent(event, room),
type,
);
}
// ignore: deprecated_member_use_from_same_package
onEvent.add(
// ignore: deprecated_member_use_from_same_package
EventUpdate(
roomID: room.id,
type: type,
content: event.toJson(),
),
);
if (event is MatrixEvent) {
final timelineEvent = Event.fromMatrixEvent(event, room);
switch (type) {
case EventUpdateType.timeline:
onTimelineEvent.add(timelineEvent);
if (prevBatch != null &&
timelineEvent.senderId != userID &&
room.notificationCount > 0 &&
pushruleEvaluator.match(timelineEvent).notify) {
onNotification.add(timelineEvent);
}
break;
case EventUpdateType.history:
onHistoryEvent.add(timelineEvent);
break;
default:
break;
}
}
// Trigger local notification for a new invite:
if (prevBatch != null &&
type == EventUpdateType.inviteState &&
event.type == EventTypes.RoomMember &&
event.stateKey == userID) {
onNotification.add(
Event(
type: event.type,
eventId: 'invite_for_${room.id}',
senderId: event.senderId,
originServerTs: DateTime.now(),
stateKey: event.stateKey,
content: event.content,
room: room,
),
);
}
onEvent.add(update);
if (prevBatch != null &&
(type == EventUpdateType.timeline ||
type == EventUpdateType.decryptedTimelineQueue)) {
if ((update.content
.tryGet<String>('type')
?.startsWith(CallConstants.callEventsRegxp) ??
false)) {
final callEvent = Event.fromJson(update.content, room);
if (event is MatrixEvent &&
(event.type.startsWith(CallConstants.callEventsRegxp))) {
final callEvent = Event.fromMatrixEvent(event, room);
callEvents.add(callEvent);
}
}
@ -2913,23 +2972,34 @@ class Client extends MatrixApi {
return room;
}
void _updateRoomsByEventUpdate(Room room, EventUpdate eventUpdate) {
if (eventUpdate.type == EventUpdateType.history) return;
void _updateRoomsByEventUpdate(
Room room,
StrippedStateEvent eventUpdate,
EventUpdateType type,
) {
if (type == EventUpdateType.history) return;
switch (eventUpdate.type) {
switch (type) {
case EventUpdateType.inviteState:
room.setState(StrippedStateEvent.fromJson(eventUpdate.content));
room.setState(eventUpdate);
break;
case EventUpdateType.state:
case EventUpdateType.timeline:
final event = Event.fromJson(eventUpdate.content, room);
if (eventUpdate is! MatrixEvent) {
Logs().wtf(
'Passed in a ${eventUpdate.runtimeType} with $type to _updateRoomsByEventUpdate(). This should never happen!',
);
assert(eventUpdate is! MatrixEvent);
return;
}
final event = Event.fromMatrixEvent(eventUpdate, room);
// Update the room state:
if (event.stateKey != null &&
(!room.partial || importantStateEvents.contains(event.type))) {
room.setState(event);
}
if (eventUpdate.type != EventUpdateType.timeline) break;
if (type != EventUpdateType.timeline) break;
// If last event is null or not a valid room preview event anyway,
// just use this:

View File

@ -80,7 +80,12 @@ abstract class DatabaseApi {
/// Stores an EventUpdate object in the database. Must be called inside of
/// [transaction].
Future<void> storeEventUpdate(EventUpdate eventUpdate, Client client);
Future<void> storeEventUpdate(
String roomId,
StrippedStateEvent event,
EventUpdateType type,
Client client,
);
Future<Event?> getEventById(String eventId, Room room);

View File

@ -1105,7 +1105,17 @@ class HiveCollectionsDatabase extends DatabaseApi {
}
@override
Future<void> storeEventUpdate(EventUpdate eventUpdate, Client client) async {
Future<void> storeEventUpdate(
String roomId,
StrippedStateEvent event,
EventUpdateType type,
Client client,
) async {
final eventUpdate = EventUpdate(
roomID: roomId,
content: event.toJson(),
type: type,
);
final tmpRoom = client.getRoomById(eventUpdate.roomID) ??
Room(id: eventUpdate.roomID, client: client);

View File

@ -1093,45 +1093,37 @@ class MatrixSdkDatabase extends DatabaseApi with DatabaseFileStorage {
}
@override
Future<void> storeEventUpdate(EventUpdate eventUpdate, Client client) async {
final tmpRoom = client.getRoomById(eventUpdate.roomID) ??
Room(id: eventUpdate.roomID, client: client);
Future<void> storeEventUpdate(
String roomId,
StrippedStateEvent event,
EventUpdateType type,
Client client,
) async {
final tmpRoom =
client.getRoomById(roomId) ?? Room(id: roomId, client: client);
// In case of this is a redaction event
if (eventUpdate.content['type'] == EventTypes.Redaction) {
final eventId = eventUpdate.content.tryGet<String>('redacts');
final event =
if (event.type == EventTypes.Redaction && event is MatrixEvent) {
final redactionEvent = Event.fromMatrixEvent(event, tmpRoom);
final eventId = redactionEvent.redacts;
final redactedEvent =
eventId != null ? await getEventById(eventId, tmpRoom) : null;
if (event != null) {
event.setRedactionEvent(Event.fromJson(eventUpdate.content, tmpRoom));
if (redactedEvent != null) {
redactedEvent.setRedactionEvent(redactionEvent);
await _eventsBox.put(
TupleKey(eventUpdate.roomID, event.eventId).toString(),
event.toJson(),
TupleKey(roomId, redactedEvent.eventId).toString(),
redactedEvent.toJson(),
);
if (tmpRoom.lastEvent?.eventId == event.eventId) {
if (client.importantStateEvents.contains(event.type)) {
await _preloadRoomStateBox.put(
TupleKey(eventUpdate.roomID, event.type, '').toString(),
event.toJson(),
);
} else {
await _nonPreloadRoomStateBox.put(
TupleKey(eventUpdate.roomID, event.type, '').toString(),
event.toJson(),
);
}
}
}
}
// Store a common message event
if ({EventUpdateType.timeline, EventUpdateType.history}
.contains(eventUpdate.type)) {
final eventId = eventUpdate.content['event_id'];
if ({EventUpdateType.timeline, EventUpdateType.history}.contains(type) &&
event is MatrixEvent) {
final timelineEvent = Event.fromMatrixEvent(event, tmpRoom);
// Is this ID already in the store?
final prevEvent = await _eventsBox
.get(TupleKey(eventUpdate.roomID, eventId).toString());
final prevEvent =
await _eventsBox.get(TupleKey(roomId, event.eventId).toString());
final prevStatus = prevEvent == null
? null
: () {
@ -1144,13 +1136,7 @@ class MatrixSdkDatabase extends DatabaseApi with DatabaseFileStorage {
}();
// calculate the status
final newStatus = eventStatusFromInt(
eventUpdate.content.tryGet<int>('status') ??
eventUpdate.content
.tryGetMap<String, dynamic>('unsigned')
?.tryGet<int>(messageSendingStatusKey) ??
EventStatus.synced.intValue,
);
final newStatus = timelineEvent.status;
// Is this the response to a sending event which is already synced? Then
// there is nothing to do here.
@ -1165,29 +1151,25 @@ class MatrixSdkDatabase extends DatabaseApi with DatabaseFileStorage {
newStatus,
);
// Add the status and the sort order to the content so it get stored
eventUpdate.content['unsigned'] ??= <String, dynamic>{};
eventUpdate.content['unsigned'][messageSendingStatusKey] =
eventUpdate.content['status'] = status.intValue;
timelineEvent.status = status;
final eventId = timelineEvent.eventId;
// In case this event has sent from this account we have a transaction ID
final transactionId = eventUpdate.content
.tryGetMap<String, dynamic>('unsigned')
?.tryGet<String>('transaction_id');
final transactionId =
timelineEvent.unsigned?.tryGet<String>('transaction_id');
await _eventsBox.put(
TupleKey(eventUpdate.roomID, eventId).toString(),
eventUpdate.content,
TupleKey(roomId, eventId).toString(),
timelineEvent.toJson(),
);
// Update timeline fragments
final key = TupleKey(eventUpdate.roomID, status.isSent ? '' : 'SENDING')
.toString();
final key = TupleKey(roomId, status.isSent ? '' : 'SENDING').toString();
final eventIds =
List<String>.from(await _timelineFragmentsBox.get(key) ?? []);
if (!eventIds.contains(eventId)) {
if (eventUpdate.type == EventUpdateType.history) {
if (type == EventUpdateType.history) {
eventIds.add(eventId);
} else {
eventIds.insert(0, eventId);
@ -1196,7 +1178,7 @@ class MatrixSdkDatabase extends DatabaseApi with DatabaseFileStorage {
} else if (status.isSynced &&
prevStatus != null &&
prevStatus.isSent &&
eventUpdate.type != EventUpdateType.history) {
type != EventUpdateType.history) {
// Status changes from 1 -> 2? Make sure event is correctly sorted.
eventIds.remove(eventId);
eventIds.insert(0, eventId);
@ -1204,7 +1186,7 @@ class MatrixSdkDatabase extends DatabaseApi with DatabaseFileStorage {
// If event comes from server timeline, remove sending events with this ID
if (status.isSent) {
final key = TupleKey(eventUpdate.roomID, 'SENDING').toString();
final key = TupleKey(roomId, 'SENDING').toString();
final eventIds =
List<String>.from(await _timelineFragmentsBox.get(key) ?? []);
final i = eventIds.indexWhere((id) => id == eventId);
@ -1215,37 +1197,38 @@ class MatrixSdkDatabase extends DatabaseApi with DatabaseFileStorage {
// Is there a transaction id? Then delete the event with this id.
if (!status.isError && !status.isSending && transactionId != null) {
await removeEvent(transactionId, eventUpdate.roomID);
await removeEvent(transactionId, roomId);
}
}
final stateKey = eventUpdate.content['state_key'];
final stateKey = event.stateKey;
// Store a common state event
if (stateKey != null &&
// Don't store events as state updates when paginating backwards.
(eventUpdate.type == EventUpdateType.timeline ||
eventUpdate.type == EventUpdateType.state ||
eventUpdate.type == EventUpdateType.inviteState)) {
if (eventUpdate.content['type'] == EventTypes.RoomMember) {
{
EventUpdateType.timeline,
EventUpdateType.state,
EventUpdateType.inviteState,
}.contains(type)) {
if (event.type == EventTypes.RoomMember) {
await _roomMembersBox.put(
TupleKey(
eventUpdate.roomID,
eventUpdate.content['state_key'],
roomId,
stateKey,
).toString(),
eventUpdate.content,
event.toJson(),
);
} else {
final type = eventUpdate.content['type'] as String;
final roomStateBox = client.importantStateEvents.contains(type)
final roomStateBox = client.importantStateEvents.contains(event.type)
? _preloadRoomStateBox
: _nonPreloadRoomStateBox;
final key = TupleKey(
eventUpdate.roomID,
type,
roomId,
event.type,
stateKey,
).toString();
await roomStateBox.put(key, eventUpdate.content);
await roomStateBox.put(key, event.toJson());
}
}
}

View File

@ -88,6 +88,7 @@ class Event extends MatrixEvent {
Map<String, dynamic>? unsigned,
Map<String, dynamic>? prevContent,
String? stateKey,
super.redacts,
required this.room,
MatrixEvent? originalSource,
}) : _originalSource = originalSource,
@ -171,7 +172,7 @@ class Event extends MatrixEvent {
status: status ??
eventStatusFromInt(
matrixEvent.unsigned
?.tryGet<int>('messageSendingStatusKey') ??
?.tryGet<int>(messageSendingStatusKey) ??
defaultStatus.intValue,
),
content: matrixEvent.content,
@ -212,6 +213,7 @@ class Event extends MatrixEvent {
),
unsigned: unsigned,
room: room,
redacts: jsonPayload['redacts'],
originalSource:
originalSource.isEmpty ? null : MatrixEvent.fromJson(originalSource),
);

View File

@ -1674,11 +1674,9 @@ class Room {
for (final user in users) {
setState(user); // at *least* cache this in-memory
await client.database?.storeEventUpdate(
EventUpdate(
roomID: id,
type: EventUpdateType.state,
content: user.toJson(),
),
id,
user,
EventUpdateType.state,
client,
);
}
@ -1755,11 +1753,9 @@ class Room {
// Store user in database:
await client.database?.transaction(() async {
await client.database?.storeEventUpdate(
EventUpdate(
content: foundUser.toJson(),
roomID: id,
type: EventUpdateType.state,
),
id,
foundUser,
EventUpdateType.state,
client,
);
});

View File

@ -41,7 +41,8 @@ class Timeline {
final void Function(int index)? onRemove;
final void Function()? onNewEvent;
StreamSubscription<EventUpdate>? sub;
StreamSubscription<Event>? timelineSub;
StreamSubscription<Event>? historySub;
StreamSubscription<SyncUpdate>? roomSub;
StreamSubscription<String>? sessionIdReceivedSub;
StreamSubscription<String>? cancelSendEventSub;
@ -322,7 +323,18 @@ class Timeline {
this.onNewEvent,
required this.chunk,
}) {
sub = room.client.onEvent.stream.listen(_handleEventUpdate);
timelineSub = room.client.onTimelineEvent.stream.listen(
(event) => _handleEventUpdate(
event,
EventUpdateType.timeline,
),
);
historySub = room.client.onHistoryEvent.stream.listen(
(event) => _handleEventUpdate(
event,
EventUpdateType.history,
),
);
// If the timeline is limited we want to clear our events cache
roomSub = room.client.onSync.stream
@ -368,7 +380,9 @@ class Timeline {
/// Don't forget to call this before you dismiss this object!
void cancelSubscriptions() {
// ignore: discarded_futures
sub?.cancel();
timelineSub?.cancel();
// ignore: discarded_futures
historySub?.cancel();
// ignore: discarded_futures
roomSub?.cancel();
// ignore: discarded_futures
@ -512,43 +526,35 @@ class Timeline {
}
}
void _handleEventUpdate(EventUpdate eventUpdate, {bool update = true}) {
void _handleEventUpdate(
Event event,
EventUpdateType type, {
bool update = true,
}) {
try {
if (eventUpdate.roomID != room.id) return;
if (event.roomId != room.id) return;
if (eventUpdate.type != EventUpdateType.timeline &&
eventUpdate.type != EventUpdateType.history) {
if (type != EventUpdateType.timeline && type != EventUpdateType.history) {
return;
}
if (eventUpdate.type == EventUpdateType.timeline) {
if (type == EventUpdateType.timeline) {
onNewEvent?.call();
}
if (!allowNewEvent) return;
final status = eventStatusFromInt(
eventUpdate.content['status'] ??
(eventUpdate.content['unsigned'] is Map<String, dynamic>
? eventUpdate.content['unsigned'][messageSendingStatusKey]
: null) ??
EventStatus.synced.intValue,
);
final status = event.status;
final i = _findEvent(
event_id: eventUpdate.content['event_id'],
unsigned_txid: eventUpdate.content['unsigned'] is Map
? eventUpdate.content['unsigned']['transaction_id']
: null,
event_id: event.eventId,
unsigned_txid: event.unsigned?.tryGet<String>('transaction_id'),
);
if (i < events.length) {
// if the old status is larger than the new one, we also want to preserve the old status
final oldStatus = events[i].status;
events[i] = Event.fromJson(
eventUpdate.content,
room,
);
events[i] = event;
// do we preserve the status? we should allow 0 -> -1 updates and status increases
if ((latestEventStatus(status, oldStatus) == oldStatus) &&
!(status.isError && oldStatus.isSending)) {
@ -557,34 +563,28 @@ class Timeline {
addAggregatedEvent(events[i]);
onChange?.call(i);
} else {
final newEvent = Event.fromJson(
eventUpdate.content,
room,
);
if (eventUpdate.type == EventUpdateType.history &&
if (type == EventUpdateType.history &&
events.indexWhere(
(e) => e.eventId == eventUpdate.content['event_id'],
(e) => e.eventId == event.eventId,
) !=
-1) {
return;
}
var index = events.length;
if (eventUpdate.type == EventUpdateType.history) {
events.add(newEvent);
if (type == EventUpdateType.history) {
events.add(event);
} else {
index = events.firstIndexWhereNotError;
events.insert(index, newEvent);
events.insert(index, event);
}
onInsert?.call(index);
addAggregatedEvent(newEvent);
addAggregatedEvent(event);
}
// Handle redaction events
if (eventUpdate.content['type'] == EventTypes.Redaction) {
final index =
_findEvent(event_id: eventUpdate.content.tryGet<String>('redacts'));
if (event.type == EventTypes.Redaction) {
final index = _findEvent(event_id: event.redacts);
if (index < events.length) {
removeAggregatedEvent(events[index]);
@ -598,12 +598,7 @@ class Timeline {
}
}
events[index].setRedactionEvent(
Event.fromJson(
eventUpdate.content,
room,
),
);
events[index].setRedactionEvent(event);
onChange?.call(index);
}
}

View File

@ -33,8 +33,7 @@ enum EventUpdateType {
decryptedTimelineQueue,
}
/// Represents a new event (e.g. a message in a room) or an update for an
/// already known event.
@Deprecated('Use `Event` class directly instead.')
class EventUpdate {
/// Usually 'timeline', 'state' or whatever.
final EventUpdateType type;

View File

@ -114,7 +114,7 @@ void main() {
httpClient: FakeMatrixApi(),
databaseBuilder: getDatabase,
);
final eventUpdateListFuture = matrix.onEvent.stream.toList();
final eventUpdateListFuture = matrix.onTimelineEvent.stream.toList();
final toDeviceUpdateListFuture = matrix.onToDeviceEvent.stream.toList();
var presenceCounter = 0;
var accountDataCounter = 0;
@ -278,43 +278,20 @@ void main() {
null,
);
await matrix.onEvent.close();
await matrix.onTimelineEvent.close();
final eventUpdateList = await eventUpdateListFuture;
expect(eventUpdateList.length, 13);
expect(eventUpdateList.length, 3);
expect(eventUpdateList[0].content['type'], 'm.room.member');
expect(eventUpdateList[0].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[0].type, EventUpdateType.state);
expect(eventUpdateList[0].type, 'm.room.member');
expect(eventUpdateList[0].roomId, '!726s6s6q:example.com');
expect(eventUpdateList[1].content['type'], 'm.room.canonical_alias');
expect(eventUpdateList[1].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[1].type, EventUpdateType.state);
expect(eventUpdateList[1].type, 'm.room.message');
expect(eventUpdateList[1].roomId, '!726s6s6q:example.com');
expect(eventUpdateList[2].content['type'], 'm.room.encryption');
expect(eventUpdateList[2].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[2].type, EventUpdateType.state);
expect(eventUpdateList[3].content['type'], 'm.room.pinned_events');
expect(eventUpdateList[3].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[3].type, EventUpdateType.state);
expect(eventUpdateList[4].content['type'], 'm.room.member');
expect(eventUpdateList[4].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[4].type, EventUpdateType.timeline);
expect(eventUpdateList[5].content['type'], 'm.room.message');
expect(eventUpdateList[5].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[5].type, EventUpdateType.timeline);
expect(eventUpdateList[6].content['type'], 'm.room.member');
expect(eventUpdateList[6].roomID, '!calls:example.com');
expect(eventUpdateList[6].type, EventUpdateType.state);
expect(eventUpdateList[7].content['type'], 'm.room.member');
expect(eventUpdateList[7].roomID, '!calls:example.com');
expect(eventUpdateList[7].type, EventUpdateType.state);
expect(eventUpdateList[2].type, 'm.room.message');
expect(eventUpdateList[2].roomId, '!726s6s6f:example.com');
expect(
matrix

View File

@ -219,10 +219,9 @@ void main() {
});
test('storeEventUpdate', () async {
await database.storeEventUpdate(
EventUpdate(
roomID: '!testroom:example.com',
type: EventUpdateType.timeline,
content: {
'!testroom:example.com',
MatrixEvent.fromJson(
{
'type': EventTypes.Message,
'content': {
'body': '* edit 3',
@ -236,10 +235,12 @@ void main() {
'rel_type': RelationshipTypes.edit,
},
},
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
'event_id': '\$event:example.com',
'sender': '@bob:example.org',
},
),
EventUpdateType.timeline,
Client('testclient'),
);
});
@ -263,10 +264,9 @@ void main() {
);
await database.storeEventUpdate(
EventUpdate(
roomID: roomid,
type: EventUpdateType.timeline,
content: {
roomid,
MatrixEvent.fromJson(
{
'type': EventTypes.RoomName,
'content': {
'name': 'start',
@ -274,8 +274,10 @@ void main() {
'event_id': '\$eventstart:example.com',
'sender': '@bob:example.org',
'state_key': '',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
),
EventUpdateType.timeline,
client,
);
@ -288,10 +290,9 @@ void main() {
expect(room?.roomAccountData['m.test']?.content, {'foo': 'bar'});
await database.storeEventUpdate(
EventUpdate(
roomID: roomid,
type: EventUpdateType.timeline,
content: {
roomid,
MatrixEvent.fromJson(
{
'type': EventTypes.RoomName,
'content': {
'name': 'update',
@ -299,8 +300,10 @@ void main() {
'event_id': '\$eventupdate:example.com',
'sender': '@bob:example.org',
'state_key': '',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
),
EventUpdateType.timeline,
client,
);
@ -309,10 +312,9 @@ void main() {
expect(room?.name, 'update');
await database.storeEventUpdate(
EventUpdate(
roomID: roomid,
type: EventUpdateType.state,
content: {
roomid,
MatrixEvent.fromJson(
{
'type': EventTypes.RoomName,
'content': {
'name': 'update2',
@ -320,8 +322,10 @@ void main() {
'event_id': '\$eventupdate2:example.com',
'sender': '@bob:example.org',
'state_key': '',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
),
EventUpdateType.state,
client,
);
@ -330,10 +334,9 @@ void main() {
expect(room?.name, 'update2');
await database.storeEventUpdate(
EventUpdate(
roomID: roomid,
type: EventUpdateType.inviteState,
content: {
roomid,
StrippedStateEvent.fromJson(
{
'type': EventTypes.RoomName,
'content': {
'name': 'update3',
@ -343,6 +346,7 @@ void main() {
'state_key': '',
},
),
EventUpdateType.inviteState,
client,
);
@ -351,10 +355,9 @@ void main() {
expect(room?.name, 'update3');
await database.storeEventUpdate(
EventUpdate(
roomID: roomid,
type: EventUpdateType.history,
content: {
roomid,
MatrixEvent.fromJson(
{
'type': EventTypes.RoomName,
'content': {
'name': 'notupdate',
@ -362,8 +365,10 @@ void main() {
'event_id': '\$eventnotupdate:example.com',
'sender': '@bob:example.org',
'state_key': '',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
),
EventUpdateType.history,
client,
);

View File

@ -28,21 +28,20 @@ import 'package:matrix/matrix.dart';
import '../fake_client.dart';
import '../fake_database.dart';
EventUpdate getLastSentEvent(KeyVerification req) {
Event getLastSentEvent(KeyVerification req) {
final entry = FakeMatrixApi.calledEndpoints.entries
.firstWhere((p) => p.key.contains('/send/'));
final type = entry.key.split('/')[6];
final content = json.decode(entry.value.first);
return EventUpdate(
content: {
return Event.fromJson(
{
'event_id': req.transactionId,
'type': type,
'content': content,
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
'sender': req.client.userID,
},
type: EventUpdateType.timeline,
roomID: req.room!.id,
req.room!,
);
}
@ -615,8 +614,8 @@ void main() async {
await sub.cancel();
await client2.encryption!.keyVerificationManager.handleEventUpdate(
EventUpdate(
content: {
Event.fromJson(
{
'event_id': req2.transactionId,
'type': EventTypes.KeyVerificationReady,
'content': {
@ -630,8 +629,7 @@ void main() async {
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
'sender': client2.userID,
},
type: EventUpdateType.timeline,
roomID: req2.room!.id,
req2.room!,
),
);
expect(req2.state, KeyVerificationState.error);

View File

@ -46,26 +46,28 @@ void main() {
final client = Client('testclient');
final database = await getDatabase(client);
// store a simple update
var update = EventUpdate(
type: EventUpdateType.timeline,
roomID: room.id,
content: {
await database.storeEventUpdate(
room.id,
MatrixEvent.fromJson(
{
'type': 'm.room.message',
'origin_server_ts': 100,
'content': <String, dynamic>{'blah': 'blubb'},
'event_id': '\$event-1',
'sender': '@blah:blubb',
},
),
EventUpdateType.timeline,
client,
);
await database.storeEventUpdate(update, client);
var event = await database.getEventById('\$event-1', room);
expect(event?.eventId, '\$event-1');
// insert a transaction id
update = EventUpdate(
type: EventUpdateType.timeline,
roomID: room.id,
content: {
await database.storeEventUpdate(
room.id,
Event.fromJson(
{
'type': 'm.room.message',
'origin_server_ts': 100,
'content': <String, dynamic>{'blah': 'blubb'},
@ -73,14 +75,18 @@ void main() {
'sender': '@blah:blubb',
'status': EventStatus.sending.intValue,
},
room,
),
EventUpdateType.timeline,
client,
);
await database.storeEventUpdate(update, client);
event = await database.getEventById('transaction-1', room);
expect(event?.eventId, 'transaction-1');
update = EventUpdate(
type: EventUpdateType.timeline,
roomID: room.id,
content: {
await database.storeEventUpdate(
room.id,
Event.fromJson(
{
'type': 'm.room.message',
'origin_server_ts': 100,
'content': <String, dynamic>{'blah': 'blubb'},
@ -91,17 +97,20 @@ void main() {
},
'status': EventStatus.sent.intValue,
},
room,
),
EventUpdateType.timeline,
client,
);
await database.storeEventUpdate(update, client);
event = await database.getEventById('transaction-1', room);
expect(event, null);
event = await database.getEventById('\$event-2', room);
// insert a transaction id if the event id for it already exists
update = EventUpdate(
type: EventUpdateType.timeline,
roomID: room.id,
content: {
await database.storeEventUpdate(
room.id,
Event.fromJson(
{
'type': 'm.room.message',
'origin_server_ts': 100,
'content': {'blah': 'blubb'},
@ -109,14 +118,18 @@ void main() {
'sender': '@blah:blubb',
'status': EventStatus.sending.intValue,
},
room,
),
EventUpdateType.timeline,
client,
);
await database.storeEventUpdate(update, client);
event = await database.getEventById('\$event-3', room);
expect(event?.eventId, '\$event-3');
update = EventUpdate(
type: EventUpdateType.timeline,
roomID: room.id,
content: {
await database.storeEventUpdate(
room.id,
Event.fromJson(
{
'type': 'm.room.message',
'origin_server_ts': 100,
'content': {'blah': 'blubb'},
@ -127,8 +140,11 @@ void main() {
'transaction_id': 'transaction-2',
},
},
room,
),
EventUpdateType.timeline,
client,
);
await database.storeEventUpdate(update, client);
event = await database.getEventById('\$event-3', room);
expect(event?.eventId, '\$event-3');
expect(event?.status, EventStatus.sent);
@ -136,10 +152,10 @@ void main() {
expect(event, null);
// insert transaction id and not update status
update = EventUpdate(
type: EventUpdateType.timeline,
roomID: room.id,
content: {
await database.storeEventUpdate(
room.id,
Event.fromJson(
{
'type': 'm.room.message',
'origin_server_ts': 100,
'content': {'blah': 'blubb'},
@ -147,14 +163,18 @@ void main() {
'sender': '@blah:blubb',
'status': EventStatus.synced.intValue,
},
room,
),
EventUpdateType.timeline,
client,
);
await database.storeEventUpdate(update, client);
event = await database.getEventById('\$event-4', room);
expect(event?.eventId, '\$event-4');
update = EventUpdate(
type: EventUpdateType.timeline,
roomID: room.id,
content: {
await database.storeEventUpdate(
room.id,
Event.fromJson(
{
'type': 'm.room.message',
'origin_server_ts': 100,
'content': {'blah': 'blubb'},
@ -165,8 +185,11 @@ void main() {
'transaction_id': 'transaction-3',
},
},
room,
),
EventUpdateType.timeline,
client,
);
await database.storeEventUpdate(update, client);
event = await database.getEventById('\$event-4', room);
expect(event?.eventId, '\$event-4');
expect(event?.status, EventStatus.synced);

View File

@ -142,11 +142,9 @@ void main() {
); // expect no new events to have been added
final eventId = '1844295642248BcDkn:example.org';
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'test'},
'sender': '@alice:example.com',
@ -155,6 +153,7 @@ void main() {
'unsigned': {'transaction_id': '1234'},
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
room,
),
); // just assume that it was on the server for this call but not for the following.
@ -208,11 +207,9 @@ void main() {
expect(eventId.startsWith('\$event'), true);
expect(timeline.events[0].status, EventStatus.sent);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'test'},
'sender': '@alice:example.com',
@ -221,6 +218,7 @@ void main() {
'unsigned': {'transaction_id': '1234'},
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
room,
),
);
@ -238,11 +236,9 @@ void main() {
await timeline.requestFuture();
await waitForCount(6);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -250,6 +246,7 @@ void main() {
'event_id': 'abc',
'origin_server_ts': testTimeStamp,
},
room,
),
);
@ -296,11 +293,9 @@ void main() {
await timeline.requestFuture();
await timeline.requestFuture();
// send a failed message
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -308,6 +303,7 @@ void main() {
'event_id': 'abc',
'origin_server_ts': testTimeStamp,
},
room,
),
);
await waitForCount(7);
@ -327,11 +323,9 @@ void main() {
test('getEventById', () async {
await timeline.requestFuture();
await timeline.requestFuture();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -339,6 +333,7 @@ void main() {
'event_id': 'abc',
'origin_server_ts': testTimeStamp,
},
room,
),
);
await waitForCount(7);
@ -360,11 +355,9 @@ void main() {
timeline.events.clear();
await timeline.requestFuture();
await timeline.requestFuture();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -373,6 +366,7 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'newresend'},
},
room,
),
);
await waitForCount(7);
@ -438,11 +432,9 @@ void main() {
timeline.events.clear();
await timeline.requestFuture();
await timeline.requestFuture();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -450,13 +442,12 @@ void main() {
'event_id': 'abc',
'origin_server_ts': testTimeStamp,
},
room,
),
);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -464,6 +455,7 @@ void main() {
'event_id': 'def',
'origin_server_ts': testTimeStamp + 5,
},
room,
),
);
await waitForCount(8);
@ -475,11 +467,9 @@ void main() {
timeline.events.clear();
await timeline.requestFuture();
await timeline.requestFuture();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -487,16 +477,15 @@ void main() {
'event_id': 'will-fail',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
room,
),
);
await waitForCount(7);
expect(timeline.events[0].status, EventStatus.sending);
expect(timeline.events.length, 4);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -504,6 +493,7 @@ void main() {
'event_id': 'will-fail',
'origin_server_ts': testTimeStamp,
},
room,
),
);
await waitForCount(8);
@ -513,11 +503,9 @@ void main() {
test('setReadMarker', () async {
await timeline.requestFuture();
await timeline.requestFuture();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -525,6 +513,7 @@ void main() {
'event_id': 'will-work',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
room,
),
);
await waitForCount(7);
@ -539,11 +528,9 @@ void main() {
await timeline.requestFuture();
await timeline.requestFuture();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -551,16 +538,15 @@ void main() {
'event_id': 'transaction',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
room,
),
);
await waitForCount(7);
expect(timeline.events[0].status, EventStatus.sending);
expect(timeline.events.length, 4);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -569,16 +555,15 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'transaction'},
},
room,
),
);
await waitForCount(8);
expect(timeline.events[0].status, EventStatus.sent);
expect(timeline.events.length, 4);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -587,6 +572,7 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'transaction'},
},
room,
),
);
await waitForCount(9);
@ -599,11 +585,9 @@ void main() {
await timeline.requestFuture();
await timeline.requestFuture();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -614,16 +598,15 @@ void main() {
'transaction_id': 'transaction',
},
},
room,
),
);
await waitForCount(7);
expect(timeline.events[0].status, EventStatus.sending);
expect(timeline.events.length, 4);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -634,16 +617,15 @@ void main() {
messageSendingStatusKey: EventStatus.synced.intValue,
},
},
room,
),
);
await waitForCount(8);
expect(timeline.events[0].status, EventStatus.synced);
expect(timeline.events.length, 4);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -654,6 +636,7 @@ void main() {
messageSendingStatusKey: EventStatus.sent.intValue,
},
},
room,
),
);
await waitForCount(9);
@ -665,11 +648,9 @@ void main() {
await timeline.requestFuture();
await timeline.requestFuture();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -677,16 +658,15 @@ void main() {
'event_id': 'transaction',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
room,
),
);
await waitForCount(7);
expect(timeline.events[0].status, EventStatus.sending);
expect(timeline.events.length, 4);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -694,16 +674,15 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'transaction'},
},
room,
),
);
await waitForCount(8);
expect(timeline.events[0].status, EventStatus.error);
expect(timeline.events.length, 4);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -712,6 +691,7 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'transaction'},
},
room,
),
);
await waitForCount(9);
@ -723,11 +703,9 @@ void main() {
await timeline.requestFuture();
await timeline.requestFuture();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -735,16 +713,15 @@ void main() {
'event_id': 'transaction',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
room,
),
);
await waitForCount(7);
expect(timeline.events[0].status, EventStatus.sending);
expect(timeline.events.length, 4);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -753,16 +730,15 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'transaction'},
},
room,
),
);
await waitForCount(8);
expect(timeline.events[0].status, EventStatus.synced);
expect(timeline.events.length, 4);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -770,6 +746,7 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'transaction'},
},
room,
),
);
await waitForCount(9);

View File

@ -115,11 +115,9 @@ void main() {
);
test('Create', () async {
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -127,13 +125,12 @@ void main() {
'event_id': '2',
'origin_server_ts': testTimeStamp - 1000,
},
room,
),
);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -141,10 +138,12 @@ void main() {
'event_id': '\$1',
'origin_server_ts': testTimeStamp,
},
room,
),
);
expect(timeline.sub != null, true);
expect(timeline.timelineSub != null, true);
expect(timeline.historySub != null, true);
await waitForCount(2);
@ -202,11 +201,9 @@ void main() {
expect(timeline.events[0].receipts.length, 1);
expect(timeline.events[0].receipts[0].user.id, '@alice:example.com');
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.redaction',
'content': {'reason': 'spamming'},
'sender': '@alice:example.com',
@ -214,6 +211,7 @@ void main() {
'event_id': '3',
'origin_server_ts': testTimeStamp + 1000,
},
room,
),
);
@ -269,7 +267,8 @@ void main() {
),
);
expect(timeline.sub != null, true);
expect(timeline.timelineSub != null, true);
expect(timeline.historySub != null, true);
await waitForCount(3);
@ -584,7 +583,8 @@ void main() {
),
);
expect(timeline.sub != null, true);
expect(timeline.timelineSub != null, true);
expect(timeline.historySub != null, true);
await waitForCount(1);
@ -604,11 +604,9 @@ void main() {
expect(eventId.startsWith('\$event'), true);
expect(timeline.events[0].status, EventStatus.sent);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'test'},
'sender': '@alice:example.com',
@ -617,6 +615,7 @@ void main() {
'unsigned': {'transaction_id': '1234'},
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
room,
),
);
@ -629,11 +628,9 @@ void main() {
});
test('Send message with error', () async {
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {
'msgtype': 'm.text',
@ -644,6 +641,7 @@ void main() {
'event_id': 'abc',
'origin_server_ts': testTimeStamp,
},
room,
),
);
await waitForCount(1);
@ -668,11 +666,9 @@ void main() {
test('Remove message', () async {
// send a failed message
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -680,6 +676,7 @@ void main() {
'event_id': 'abc',
'origin_server_ts': testTimeStamp,
},
room,
),
);
await waitForCount(1);
@ -695,11 +692,9 @@ void main() {
});
test('getEventById', () async {
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -707,6 +702,7 @@ void main() {
'event_id': 'abc',
'origin_server_ts': testTimeStamp,
},
room,
),
);
await waitForCount(1);
@ -726,11 +722,9 @@ void main() {
test('Resend message', () async {
timeline.events.clear();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -739,6 +733,7 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'newresend'},
},
room,
),
);
await waitForCount(1);
@ -799,11 +794,9 @@ void main() {
test('sort errors on top', () async {
timeline.events.clear();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -811,13 +804,12 @@ void main() {
'event_id': 'abc',
'origin_server_ts': testTimeStamp,
},
room,
),
);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -825,6 +817,7 @@ void main() {
'event_id': 'def',
'origin_server_ts': testTimeStamp + 5,
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
@ -834,11 +827,9 @@ void main() {
test('sending event to failed update', () async {
timeline.events.clear();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -846,16 +837,15 @@ void main() {
'event_id': 'will-fail',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
expect(timeline.events[0].status, EventStatus.sending);
expect(timeline.events.length, 1);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -863,6 +853,7 @@ void main() {
'event_id': 'will-fail',
'origin_server_ts': testTimeStamp,
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
@ -870,11 +861,9 @@ void main() {
expect(timeline.events.length, 1);
});
test('setReadMarker', () async {
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -882,6 +871,7 @@ void main() {
'event_id': 'will-work',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
@ -892,11 +882,9 @@ void main() {
test('sending an event and the http request finishes first, 0 -> 1 -> 2',
() async {
timeline.events.clear();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -904,16 +892,15 @@ void main() {
'event_id': 'transaction',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
expect(timeline.events[0].status, EventStatus.sending);
expect(timeline.events.length, 1);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -922,16 +909,15 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'transaction'},
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
expect(timeline.events[0].status, EventStatus.sent);
expect(timeline.events.length, 1);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -940,6 +926,7 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'transaction'},
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
@ -949,11 +936,9 @@ void main() {
test('sending an event where the sync reply arrives first, 0 -> 2 -> 1',
() async {
timeline.events.clear();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -964,16 +949,15 @@ void main() {
'transaction_id': 'transaction',
},
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
expect(timeline.events[0].status, EventStatus.sending);
expect(timeline.events.length, 1);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -984,16 +968,15 @@ void main() {
messageSendingStatusKey: EventStatus.synced.intValue,
},
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
expect(timeline.events[0].status, EventStatus.synced);
expect(timeline.events.length, 1);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -1004,6 +987,7 @@ void main() {
messageSendingStatusKey: EventStatus.sent.intValue,
},
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
@ -1012,11 +996,9 @@ void main() {
});
test('sending an event 0 -> -1 -> 2', () async {
timeline.events.clear();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -1024,16 +1006,15 @@ void main() {
'event_id': 'transaction',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
expect(timeline.events[0].status, EventStatus.sending);
expect(timeline.events.length, 1);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -1041,16 +1022,15 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'transaction'},
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
expect(timeline.events[0].status, EventStatus.error);
expect(timeline.events.length, 1);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -1059,6 +1039,7 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'transaction'},
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
@ -1067,11 +1048,9 @@ void main() {
});
test('sending an event 0 -> 2 -> -1', () async {
timeline.events.clear();
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -1079,16 +1058,15 @@ void main() {
'event_id': 'transaction',
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
expect(timeline.events[0].status, EventStatus.sending);
expect(timeline.events.length, 1);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -1097,16 +1075,15 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'transaction'},
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));
expect(timeline.events[0].status, EventStatus.synced);
expect(timeline.events.length, 1);
client.onEvent.add(
EventUpdate(
type: EventUpdateType.timeline,
roomID: roomID,
content: {
client.onTimelineEvent.add(
Event.fromJson(
{
'type': 'm.room.message',
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
'sender': '@alice:example.com',
@ -1114,6 +1091,7 @@ void main() {
'origin_server_ts': testTimeStamp,
'unsigned': {'transaction_id': 'transaction'},
},
room,
),
);
await Future.delayed(Duration(milliseconds: 50));