diff --git a/lib/encryption/encryption.dart b/lib/encryption/encryption.dart index 1714c786..5df41a8d 100644 --- a/lib/encryption/encryption.dart +++ b/lib/encryption/encryption.dart @@ -270,7 +270,6 @@ class Encryption { type: decryptedPayload['type'], senderId: event.senderId, eventId: event.eventId, - roomId: event.roomId, room: event.room, originServerTs: event.originServerTs, unsigned: event.unsigned, @@ -304,7 +303,7 @@ class Encryption { } if (event.type != EventTypes.Encrypted && store) { if (updateType != EventUpdateType.history) { - event.room?.setState(event); + event.room.setState(event); } await client.database?.storeEventUpdate( EventUpdate( diff --git a/lib/src/database/hive_database.dart b/lib/src/database/hive_database.dart index 076a764d..4a96a3e4 100644 --- a/lib/src/database/hive_database.dart +++ b/lib/src/database/hive_database.dart @@ -886,13 +886,18 @@ class FamedlySdkHiveDatabase extends DatabaseApi { .contains(eventUpdate.type)) { final eventId = eventUpdate.content['event_id']; // Is this ID already in the store? - final prevEvent = _eventsBox - .containsKey(MultiKey(eventUpdate.roomID, eventId).toString()) - ? Event.fromJson( - convertToJson(await _eventsBox - .get(MultiKey(eventUpdate.roomID, eventId).toString())), - null) - : null; + final Map? prevEvent = await _eventsBox + .get(MultiKey(eventUpdate.roomID, eventId).toString()); + final prevStatus = prevEvent == null + ? null + : () { + final json = convertToJson(prevEvent); + final statusInt = json.tryGet('status') ?? + json + .tryGetMap('unsigned') + ?.tryGet(messageSendingStatusKey); + return statusInt == null ? null : eventStatusFromInt(statusInt); + }(); // calculate the status final newStatus = eventStatusFromInt( @@ -905,16 +910,14 @@ class FamedlySdkHiveDatabase extends DatabaseApi { // Is this the response to a sending event which is already synced? Then // there is nothing to do here. - if (!newStatus.isSynced && - prevEvent != null && - prevEvent.status.isSynced) { + if (!newStatus.isSynced && prevStatus != null && prevStatus.isSynced) { return; } final status = newStatus.isError || prevEvent == null ? newStatus : latestEventStatus( - prevEvent.status, + prevStatus!, newStatus, ); @@ -945,8 +948,8 @@ class FamedlySdkHiveDatabase extends DatabaseApi { } await _timelineFragmentsBox.put(key, eventIds); } else if (status.isSynced && - prevEvent != null && - prevEvent.status.isSent && + prevStatus != null && + prevStatus.isSent && eventUpdate.type != EventUpdateType.history) { // Status changes from 1 -> 2? Make sure event is correctly sorted. eventIds.remove(eventId); diff --git a/lib/src/event.dart b/lib/src/event.dart index fc81e213..da3b1f84 100644 --- a/lib/src/event.dart +++ b/lib/src/event.dart @@ -38,13 +38,7 @@ abstract class RelationshipTypes { /// All data exchanged over Matrix is expressed as an "event". Typically each client action (e.g. sending a message) correlates with exactly one event. class Event extends MatrixEvent { - User get sender => - room?.getUserByMXIDSync(senderId) ?? - User.fromState( - stateKey: senderId, - typeKey: EventTypes.RoomMember, - originServerTs: DateTime.now(), - ); + User get sender => room.getUserByMXIDSync(senderId); @Deprecated('Use [originServerTs] instead') DateTime get time => originServerTs; @@ -56,7 +50,7 @@ class Event extends MatrixEvent { String? get senderName => sender.calcDisplayname(); /// The room this event belongs to. May be null. - final Room? room; + final Room room; /// The status of this event. EventStatus status; @@ -74,27 +68,26 @@ class Event extends MatrixEvent { bool get redacted => redactedBecause != null; - User? get stateKeyUser => room?.getUserByMXIDSync(stateKey!); + User? get stateKeyUser => room.getUserByMXIDSync(stateKey!); Event({ this.status = defaultStatus, required Map content, required String type, required String eventId, - String? roomId, required String senderId, required DateTime originServerTs, Map? unsigned, Map? prevContent, String? stateKey, - this.room, + required this.room, }) : super( content: content, type: type, eventId: eventId, senderId: senderId, originServerTs: originServerTs, - roomId: roomId ?? room?.id, + roomId: room.id, ) { this.eventId = eventId; this.unsigned = unsigned; @@ -118,13 +111,13 @@ class Event extends MatrixEvent { // Mark event as failed to send if status is `sending` and event is older // than the timeout. This should not happen with the deprecated Moor // database! - if (status.isSending && room?.client.database != null) { + if (status.isSending && room.client.database != null) { // Age of this event in milliseconds final age = DateTime.now().millisecondsSinceEpoch - originServerTs.millisecondsSinceEpoch; final room = this.room; - if (room != null && age > room.client.sendMessageTimeoutSeconds * 1000) { + if (age > room.client.sendMessageTimeoutSeconds * 1000) { // Update this event in database and open timelines final json = toJson(); json['unsigned'] ??= {}; @@ -161,7 +154,6 @@ class Event extends MatrixEvent { content: matrixEvent.content, type: matrixEvent.type, eventId: matrixEvent.eventId, - roomId: room.id, senderId: matrixEvent.senderId, originServerTs: matrixEvent.originServerTs, unsigned: matrixEvent.unsigned, @@ -173,7 +165,7 @@ class Event extends MatrixEvent { /// Get a State event from a table row or from the event stream. factory Event.fromJson( Map jsonPayload, - Room? room, + Room room, ) { final content = Event.getMapFromPayload(jsonPayload['content']); final unsigned = Event.getMapFromPayload(jsonPayload['unsigned']); @@ -187,7 +179,6 @@ class Event extends MatrixEvent { content: content, type: jsonPayload['type'], eventId: jsonPayload['event_id'] ?? '', - roomId: jsonPayload['room_id'], senderId: jsonPayload['sender'], originServerTs: jsonPayload.containsKey('origin_server_ts') ? DateTime.fromMillisecondsSinceEpoch(jsonPayload['origin_server_ts']) @@ -295,8 +286,8 @@ class Event extends MatrixEvent { /// Returns a list of [Receipt] instances for this event. List get receipts { final room = this.room; - final receipt = room?.roomAccountData['m.receipt']; - if (receipt == null || room == null) return []; + final receipt = room.roomAccountData['m.receipt']; + if (receipt == null) return []; return receipt.content.entries .where((entry) => entry.value['event_id'] == eventId) .map((entry) => Receipt(room.getUserByMXIDSync(entry.key), @@ -309,9 +300,6 @@ class Event extends MatrixEvent { /// Returns [false] if not removed. Future remove() async { final room = this.room; - if (room == null) { - return false; - } if (!status.isSent) { await room.client.database?.removeEvent(eventId, room.id); @@ -335,7 +323,7 @@ class Event extends MatrixEvent { if (!status.isError) return null; // we do not remove the event here. It will automatically be updated // in the `sendEvent` method to transition -1 -> 0 -> 1 -> 2 - final newEventId = await room?.sendEvent( + final newEventId = await room.sendEvent( content, txid: txid ?? unsigned?['transaction_id'] ?? eventId, ); @@ -343,12 +331,11 @@ class Event extends MatrixEvent { } /// Whether the client is allowed to redact this event. - bool get canRedact => - senderId == room?.client.userID || (room?.canRedact ?? false); + bool get canRedact => senderId == room.client.userID || room.canRedact; /// Redacts this event. Throws `ErrorResponse` on error. Future redactEvent({String? reason, String? txid}) async => - await room?.redactEvent(eventId, reason: reason, txid: txid); + await room.redactEvent(eventId, reason: reason, txid: txid); /// Searches for the reply event in the given timeline. Future getReplyEvent(Timeline timeline) async { @@ -369,7 +356,7 @@ class Event extends MatrixEvent { content['can_request_session'] != true) { throw ('Session key not requestable'); } - await room?.requestSessionKey(content['session_id'], content['sender_key']); + await room.requestSessionKey(content['session_id'], content['sender_key']); return; } @@ -456,10 +443,6 @@ class Event extends MatrixEvent { ThumbnailMethod method = ThumbnailMethod.scale, int minNoThumbSize = _minNoThumbSize, bool animated = false}) { - final client = room?.client; - if (client == null) { - return null; - } if (![EventTypes.Message, EventTypes.Sticker].contains(type) || !hasAttachment || isAttachmentEncrypted) { @@ -481,14 +464,14 @@ class Event extends MatrixEvent { // now generate the actual URLs if (getThumbnail) { return Uri.parse(thisMxcUrl).getThumbnail( - client, + room.client, width: width, height: height, method: method, animated: animated, ); } else { - return Uri.parse(thisMxcUrl).getDownloadLink(client); + return Uri.parse(thisMxcUrl).getDownloadLink(room.client); } } @@ -504,7 +487,7 @@ class Event extends MatrixEvent { getThumbnail = mxcUrl != attachmentMxcUrl; // Is this file storeable? final thisInfoMap = getThumbnail ? thumbnailInfoMap : infoMap; - final database = room?.client.database; + final database = room.client.database; if (database == null) { return false; } @@ -529,11 +512,7 @@ class Event extends MatrixEvent { if (![EventTypes.Message, EventTypes.Sticker].contains(type)) { throw ("This event has the type '$type' and so it can't contain an attachment."); } - final client = room?.client; - final database = room?.client.database; - if (client == null) { - throw 'This event has no valid client.'; - } + final database = room.client.database; final mxcUrl = attachmentOrThumbnailMxcUrl(getThumbnail: getThumbnail); if (mxcUrl == null) { throw "This event hasn't any attachment or thumbnail."; @@ -541,7 +520,7 @@ class Event extends MatrixEvent { getThumbnail = mxcUrl != attachmentMxcUrl; final isEncrypted = getThumbnail ? isThumbnailEncrypted : isAttachmentEncrypted; - if (isEncrypted && !client.encryptionEnabled) { + if (isEncrypted && !room.client.encryptionEnabled) { throw ('Encryption is not enabled in your Client.'); } @@ -553,13 +532,13 @@ class Event extends MatrixEvent { Uint8List? uint8list; if (storeable) { - uint8list = await client.database?.getFile(mxcUrl); + uint8list = await room.client.database?.getFile(mxcUrl); } // Download the file if (uint8list == null) { downloadCallback ??= (Uri url) async => (await http.get(url)).bodyBytes; - uint8list = await downloadCallback(mxcUrl.getDownloadLink(client)); + uint8list = await downloadCallback(mxcUrl.getDownloadLink(room.client)); storeable = database != null && storeable && uint8list.lengthInBytes < database.maxFileSize; @@ -582,7 +561,7 @@ class Event extends MatrixEvent { k: fileMap['key']['k'], sha256: fileMap['hashes']['sha256'], ); - uint8list = await client.runInBackground( + uint8list = await room.client.runInBackground( decryptFile, encryptedFile); if (uint8list == null) { throw ('Unable to decrypt file'); @@ -649,7 +628,7 @@ class Event extends MatrixEvent { if (withSenderNamePrefix && type == EventTypes.Message && textOnlyMessageTypes.contains(messageType)) { - final senderNameOrYou = senderId == room?.client.userID + final senderNameOrYou = senderId == room.client.userID ? i18n.you : (sender.calcDisplayname()); localizedBody = '$senderNameOrYou: $localizedBody'; diff --git a/lib/src/user.dart b/lib/src/user.dart index 73306433..e980b64b 100644 --- a/lib/src/user.dart +++ b/lib/src/user.dart @@ -28,7 +28,7 @@ class User extends Event { String? membership, String? displayName, String? avatarUrl, - Room? room, + required Room room, }) { return User.fromState( stateKey: id, @@ -38,34 +38,34 @@ class User extends Event { if (avatarUrl != null) 'avatar_url': avatarUrl, }, typeKey: EventTypes.RoomMember, - roomId: room?.id, + roomId: room.id, room: room, originServerTs: DateTime.now(), ); } - User.fromState( - {dynamic prevContent, - required String stateKey, - dynamic content, - required String typeKey, - String eventId = 'fakevent', - String? roomId, - String senderId = 'fakesender', - required DateTime originServerTs, - dynamic unsigned, - Room? room}) - : super( - stateKey: stateKey, - prevContent: prevContent, - content: content, - type: typeKey, - eventId: eventId, - roomId: roomId, - senderId: senderId, - originServerTs: originServerTs, - unsigned: unsigned, - room: room); + User.fromState({ + dynamic prevContent, + required String stateKey, + dynamic content, + required String typeKey, + String eventId = 'fakevent', + String? roomId, + String senderId = 'fakesender', + required DateTime originServerTs, + dynamic unsigned, + required Room room, + }) : super( + stateKey: stateKey, + prevContent: prevContent, + content: content, + type: typeKey, + eventId: eventId, + senderId: senderId, + originServerTs: originServerTs, + unsigned: unsigned, + room: room, + ); /// The full qualified Matrix ID in the format @username:server.abc. String get id => stateKey ?? '@unknown:unknown'; @@ -76,7 +76,7 @@ class User extends Event { prevContent?.tryGet('displayname'); /// Returns the power level of this user. - int get powerLevel => room?.getPowerLevelByUserId(id) ?? 0; + int get powerLevel => room.getPowerLevelByUserId(id); /// The membership status of the user. One of: /// join @@ -112,8 +112,8 @@ class User extends Event { bool? formatLocalpart, bool? mxidLocalPartFallback, }) { - formatLocalpart ??= room?.client.formatLocalpart ?? true; - mxidLocalPartFallback ??= room?.client.mxidLocalPartFallback ?? true; + formatLocalpart ??= room.client.formatLocalpart; + mxidLocalPartFallback ??= room.client.mxidLocalPartFallback; final displayName = this.displayName; if (displayName != null && displayName.isNotEmpty) { return displayName; @@ -135,40 +135,37 @@ class User extends Event { } /// Call the Matrix API to kick this user from this room. - Future kick() async => await room?.kick(id); + Future kick() async => await room.kick(id); /// Call the Matrix API to ban this user from this room. - Future ban() async => await room?.ban(id); + Future ban() async => await room.ban(id); /// Call the Matrix API to unban this banned user from this room. - Future unban() async => await room?.unban(id); + Future unban() async => await room.unban(id); /// Call the Matrix API to change the power level of this user. - Future setPower(int power) async => await room?.setPower(id, power); + Future setPower(int power) async => await room.setPower(id, power); /// Returns an existing direct chat ID with this user or creates a new one. /// Returns null on error. - Future startDirectChat() async => room?.client.startDirectChat(id); + Future startDirectChat() async => room.client.startDirectChat(id); /// The newest presence of this user if there is any and null if not. - Presence? get presence => room?.client.presences[id]; + Presence? get presence => room.client.presences[id]; /// Whether the client is able to ban/unban this user. - bool get canBan => - (room?.canBan ?? false) && - powerLevel < (room?.ownPowerLevel ?? powerLevel); + bool get canBan => room.canBan && powerLevel < room.ownPowerLevel; /// Whether the client is able to kick this user. bool get canKick => [Membership.join, Membership.invite].contains(membership) && - (room?.canKick ?? false) && - powerLevel < (room?.ownPowerLevel ?? powerLevel); + room.canKick && + powerLevel < room.ownPowerLevel; /// Whether the client is allowed to change the power level of this user. /// Please be aware that you can only set the power level to at least your own! bool get canChangePowerLevel => - (room?.canChangePowerLevel ?? false) && - powerLevel < (room?.ownPowerLevel ?? powerLevel); + room.canChangePowerLevel && powerLevel < room.ownPowerLevel; @override bool operator ==(dynamic other) => (other is User && @@ -196,7 +193,7 @@ class User extends Event { : '[$displayName]'); // get all the users with the same display name - final allUsersWithSameDisplayname = room?.getParticipants() ?? []; + final allUsersWithSameDisplayname = room.getParticipants(); allUsersWithSameDisplayname.removeWhere((user) => user.id == id || (user.displayName?.isEmpty ?? true) || diff --git a/lib/src/utils/event_localizations.dart b/lib/src/utils/event_localizations.dart index 84685625..350a621c 100644 --- a/lib/src/utils/event_localizations.dart +++ b/lib/src/utils/event_localizations.dart @@ -197,7 +197,7 @@ abstract class EventLocalizations { EventTypes.Encryption: (event, i18n, body) { var localizedBody = i18n.activatedEndToEndEncryption(event.sender.calcDisplayname()); - if (event.room?.client.encryptionEnabled == false) { + if (event.room.client.encryptionEnabled == false) { localizedBody += '. ' + i18n.needPantalaimonWarning; } return localizedBody; diff --git a/test/commands_test.dart b/test/commands_test.dart index 04898d08..1084db88 100644 --- a/test/commands_test.dart +++ b/test/commands_test.dart @@ -151,6 +151,7 @@ void main() { }, originServerTs: DateTime.now(), senderId: client.userID!, + room: room, )); final sent = getLastMessagePayload('m.reaction'); expect(sent, { diff --git a/test/encryption/encrypt_decrypt_room_message_test.dart b/test/encryption/encrypt_decrypt_room_message_test.dart index 6c0c4f89..bc2e007e 100644 --- a/test/encryption/encrypt_decrypt_room_message_test.dart +++ b/test/encryption/encrypt_decrypt_room_message_test.dart @@ -67,7 +67,6 @@ void main() { final encryptedEvent = Event( type: EventTypes.Encrypted, content: payload, - roomId: roomId, room: room, originServerTs: now, eventId: '\$event', @@ -86,7 +85,6 @@ void main() { final encryptedEvent = Event( type: EventTypes.Encrypted, content: payload, - roomId: roomId, room: room, originServerTs: now, eventId: '\$event', diff --git a/test/encryption/key_manager_test.dart b/test/encryption/key_manager_test.dart index c73af662..5d9b9a26 100644 --- a/test/encryption/key_manager_test.dart +++ b/test/encryption/key_manager_test.dart @@ -368,7 +368,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.encrypted', - roomId: room.id, room: room, eventId: '12345', originServerTs: DateTime.now(), diff --git a/test/event_test.dart b/test/event_test.dart index 28d43c0e..9fb32afa 100644 --- a/test/event_test.dart +++ b/test/event_test.dart @@ -52,13 +52,14 @@ void main() { 'sender': senderID, 'origin_server_ts': timestamp, 'type': type, - 'room_id': '1234', + 'room_id': '!testroom:example.abc', 'status': EventStatus.synced.intValue, 'content': contentJson, }; final client = Client('testclient', httpClient: FakeMatrixApi()); + final room = Room(id: '!testroom:example.abc', client: client); final event = Event.fromJson( - jsonObj, Room(id: '!localpart:server.abc', client: client)); + jsonObj, Room(id: '!testroom:example.abc', client: client)); test('setup', () async { try { @@ -86,7 +87,7 @@ void main() { expect(event.type, EventTypes.Message); expect(event.relationshipType, RelationshipTypes.reply); jsonObj['state_key'] = ''; - final state = Event.fromJson(jsonObj, null); + final state = Event.fromJson(jsonObj, room); expect(state.eventId, id); expect(state.stateKey, ''); expect(state.status, EventStatus.synced); @@ -95,47 +96,47 @@ void main() { Event event; jsonObj['type'] = 'm.room.avatar'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.type, EventTypes.RoomAvatar); jsonObj['type'] = 'm.room.name'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.type, EventTypes.RoomName); jsonObj['type'] = 'm.room.topic'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.type, EventTypes.RoomTopic); jsonObj['type'] = 'm.room.aliases'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.type, EventTypes.RoomAliases); jsonObj['type'] = 'm.room.canonical_alias'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.type, EventTypes.RoomCanonicalAlias); jsonObj['type'] = 'm.room.create'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.type, EventTypes.RoomCreate); jsonObj['type'] = 'm.room.join_rules'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.type, EventTypes.RoomJoinRules); jsonObj['type'] = 'm.room.member'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.type, EventTypes.RoomMember); jsonObj['type'] = 'm.room.power_levels'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.type, EventTypes.RoomPowerLevels); jsonObj['type'] = 'm.room.guest_access'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.type, EventTypes.GuestAccess); jsonObj['type'] = 'm.room.history_visibility'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.type, EventTypes.HistoryVisibility); jsonObj['type'] = 'm.room.message'; @@ -143,36 +144,36 @@ void main() { jsonObj['content'].remove('m.relates_to'); jsonObj['content']['msgtype'] = 'm.notice'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.messageType, MessageTypes.Notice); jsonObj['content']['msgtype'] = 'm.emote'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.messageType, MessageTypes.Emote); jsonObj['content']['msgtype'] = 'm.image'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.messageType, MessageTypes.Image); jsonObj['content']['msgtype'] = 'm.video'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.messageType, MessageTypes.Video); jsonObj['content']['msgtype'] = 'm.audio'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.messageType, MessageTypes.Audio); jsonObj['content']['msgtype'] = 'm.file'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.messageType, MessageTypes.File); jsonObj['content']['msgtype'] = 'm.location'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.messageType, MessageTypes.Location); jsonObj['type'] = 'm.sticker'; jsonObj['content']['msgtype'] = null; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.messageType, MessageTypes.Sticker); jsonObj['type'] = 'm.room.message'; @@ -181,7 +182,7 @@ void main() { jsonObj['content']['m.relates_to']['m.in_reply_to'] = { 'event_id': '1234', }; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.messageType, MessageTypes.Text); expect(event.relationshipType, RelationshipTypes.reply); expect(event.relationshipEventId, '1234'); @@ -194,7 +195,7 @@ void main() { 'msgtype': 'm.text', 'text': 'beep', }; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.relationshipType, null); expect(event.relationshipEventId, null); @@ -202,12 +203,12 @@ void main() { 'rel_type': 'm.replace', 'event_id': 'abc', }; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.relationshipType, RelationshipTypes.edit); expect(event.relationshipEventId, 'abc'); jsonObj['content']['m.relates_to']['rel_type'] = 'm.annotation'; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.relationshipType, RelationshipTypes.reaction); expect(event.relationshipEventId, 'abc'); @@ -216,7 +217,7 @@ void main() { 'event_id': 'def', }, }; - event = Event.fromJson(jsonObj, null); + event = Event.fromJson(jsonObj, room); expect(event.relationshipType, RelationshipTypes.reply); expect(event.relationshipEventId, 'def'); }); @@ -1000,6 +1001,7 @@ void main() { }); test('aggregations', () { + final room = Room(id: '!1234', client: client); final event = Event.fromJson({ 'content': { 'body': 'blah', @@ -1008,7 +1010,7 @@ void main() { 'type': 'm.room.message', 'sender': '@example:example.org', 'event_id': '\$source', - }, null); + }, room); final edit1 = Event.fromJson({ 'content': { 'body': 'blah', @@ -1021,7 +1023,7 @@ void main() { 'type': 'm.room.message', 'sender': '@example:example.org', 'event_id': '\$edit1', - }, null); + }, room); final edit2 = Event.fromJson({ 'content': { 'body': 'blah', @@ -1034,8 +1036,7 @@ void main() { 'type': 'm.room.message', 'sender': '@example:example.org', 'event_id': '\$edit2', - }, null); - final room = Room(client: client, id: '!id:fakeserver.nonexisting'); + }, room); final timeline = Timeline(events: [event, edit1, edit2], room: room); expect(event.hasAggregatedEvents(timeline, RelationshipTypes.edit), true); @@ -1067,10 +1068,11 @@ void main() { }, 'event_id': '\$source', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.plaintextBody, '**blah**'); }); test('getDisplayEvent', () { + final room = Room(id: '!1234', client: client); var event = Event.fromJson({ 'type': EventTypes.Message, 'content': { @@ -1079,7 +1081,7 @@ void main() { }, 'event_id': '\$source', 'sender': '@alice:example.org', - }, null); + }, room); final edit1 = Event.fromJson({ 'type': EventTypes.Message, 'content': { @@ -1096,7 +1098,7 @@ void main() { }, 'event_id': '\$edit1', 'sender': '@alice:example.org', - }, null); + }, room); final edit2 = Event.fromJson({ 'type': EventTypes.Message, 'content': { @@ -1113,7 +1115,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); final edit3 = Event.fromJson({ 'type': EventTypes.Message, 'content': { @@ -1130,8 +1132,7 @@ void main() { }, 'event_id': '\$edit3', 'sender': '@bob:example.org', - }, null); - final room = Room(id: '!localpart:server.abc', client: client); + }, room); // no edits var displayEvent = event.getDisplayEvent(Timeline(events: [event], room: room)); @@ -1167,7 +1168,7 @@ void main() { 'type': 'm.room.redaction', }, }, - }, null); + }, room); displayEvent = event.getDisplayEvent( Timeline(events: [event, edit1, edit2, edit3], room: room)); expect(displayEvent.body, 'Redacted'); @@ -1388,14 +1389,14 @@ void main() { var buffer = await event.downloadAndDecryptAttachment( downloadCallback: downloadCallback); expect(await event.isAttachmentInLocalStore(), - event.room?.client.database?.supportsFileStoring); + event.room.client.database?.supportsFileStoring); expect(buffer.bytes, FILE_BUFF); expect(serverHits, 1); buffer = await event.downloadAndDecryptAttachment( downloadCallback: downloadCallback); expect(buffer.bytes, FILE_BUFF); expect( - serverHits, event.room!.client.database!.supportsFileStoring ? 1 : 2); + serverHits, event.room.client.database!.supportsFileStoring ? 1 : 2); await room.client.dispose(closeDatabase: true); }); @@ -1408,7 +1409,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, false); expect(event.numberEmotes, 0); event = Event.fromJson({ @@ -1419,7 +1420,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, false); expect(event.numberEmotes, 0); event = Event.fromJson({ @@ -1430,7 +1431,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, false); expect(event.numberEmotes, 1); event = Event.fromJson({ @@ -1441,7 +1442,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, true); expect(event.numberEmotes, 1); event = Event.fromJson({ @@ -1452,7 +1453,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, true); expect(event.numberEmotes, 5); event = Event.fromJson({ @@ -1465,7 +1466,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, false); expect(event.numberEmotes, 0); event = Event.fromJson({ @@ -1478,7 +1479,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, true); expect(event.numberEmotes, 1); event = Event.fromJson({ @@ -1491,7 +1492,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, true); expect(event.numberEmotes, 1); event = Event.fromJson({ @@ -1504,7 +1505,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, true); expect(event.numberEmotes, 2); // with variant selector @@ -1516,7 +1517,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, true); expect(event.numberEmotes, 1); event = Event.fromJson({ @@ -1532,7 +1533,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, true); expect(event.numberEmotes, 3); event = Event.fromJson({ @@ -1548,7 +1549,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, true); expect(event.numberEmotes, 2); event = Event.fromJson({ @@ -1564,7 +1565,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, false); expect(event.numberEmotes, 2); event = Event.fromJson({ @@ -1580,7 +1581,7 @@ void main() { }, 'event_id': '\$edit2', 'sender': '@alice:example.org', - }, null); + }, room); expect(event.onlyEmotes, false); expect(event.numberEmotes, 2); }); diff --git a/test/room_test.dart b/test/room_test.dart index 2bfb8147..494748eb 100644 --- a/test/room_test.dart +++ b/test/room_test.dart @@ -70,7 +70,6 @@ void main() { roomAccountData: { 'com.test.foo': BasicRoomEvent( type: 'com.test.foo', - roomId: id, content: {'foo': 'bar'}, ), }, @@ -78,7 +77,6 @@ void main() { room.setState(Event( room: room, eventId: '143273582443PhrSn:example.org', - roomId: id, originServerTs: DateTime.fromMillisecondsSinceEpoch(1432735824653), senderId: '@example:example.org', type: 'm.room.join_rules', @@ -103,7 +101,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.canonical_alias', - roomId: room.id, room: room, eventId: '123', content: {'alias': '#testalias:example.com'}, @@ -117,7 +114,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.name', - roomId: room.id, room: room, eventId: '123', content: {'name': 'testname'}, @@ -131,7 +127,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.topic', - roomId: room.id, room: room, eventId: '123', content: {'topic': 'testtopic'}, @@ -145,7 +140,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.avatar', - roomId: room.id, room: room, eventId: '123', content: {'url': 'mxc://testurl'}, @@ -159,7 +153,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.pinned_events', - roomId: room.id, room: room, eventId: '123', content: { @@ -173,7 +166,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.message', - roomId: room.id, room: room, eventId: '12345', originServerTs: DateTime.now(), @@ -191,7 +183,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.encrypted', - roomId: room.id, room: room, eventId: '1', originServerTs: DateTime.now(), @@ -204,7 +195,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.encrypted', - roomId: room.id, room: room, eventId: '2', originServerTs: DateTime.now(), @@ -217,7 +207,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.encrypted', - roomId: room.id, room: room, eventId: '3', originServerTs: DateTime.now(), @@ -235,7 +224,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.encrypted', - roomId: room.id, room: room, eventId: '4', originServerTs: DateTime.now(), @@ -255,7 +243,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.encrypted', - roomId: room.id, room: room, eventId: '5', originServerTs: DateTime.now(), @@ -269,7 +256,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.encrypted', - roomId: room.id, room: room, eventId: '6', originServerTs: DateTime.now(), @@ -286,7 +272,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.encrypted', - roomId: room.id, room: room, eventId: '7', originServerTs: DateTime.now(), @@ -313,7 +298,7 @@ void main() { expect(user.displayName, 'Alice Margatroid'); expect(user.membership, Membership.join); expect(user.avatarUrl.toString(), 'mxc://example.org/SEsfnsuifSDFSSEF'); - expect(user.room?.id, '!localpart:server.abc'); + expect(user.room.id, '!localpart:server.abc'); }); test('getEventByID', () async { @@ -348,7 +333,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.power_levels', - roomId: room.id, room: room, eventId: '123', content: { @@ -387,7 +371,6 @@ void main() { Event( senderId: '@test:example.com', type: 'm.room.power_levels', - roomId: room.id, room: room, eventId: '123abc', content: { @@ -433,7 +416,6 @@ void main() { room.setState(Event( senderId: '@alice:test.abc', type: 'm.room.member', - roomId: room.id, room: room, eventId: '12345', originServerTs: DateTime.now(), @@ -720,7 +702,6 @@ void main() { Event( senderId: '@alice:test.abc', type: 'm.room.encryption', - roomId: room.id, room: room, eventId: '12345', originServerTs: DateTime.now(), diff --git a/test/user_test.dart b/test/user_test.dart index f63d6d22..61e09978 100644 --- a/test/user_test.dart +++ b/test/user_test.dart @@ -85,7 +85,7 @@ void main() { 'state_key': id }; - final user = Event.fromJson(jsonObj, null).asUser; + final user = Event.fromJson(jsonObj, room).asUser; expect(user.id, id); expect(user.membership, membership); @@ -95,9 +95,9 @@ void main() { }); test('calcDisplayname', () async { - final user1 = User('@alice:example.com'); - final user2 = User('@SuperAlice:example.com'); - final user3 = User('@alice_mep:example.com'); + final user1 = User('@alice:example.com', room: room); + final user2 = User('@SuperAlice:example.com', room: room); + final user3 = User('@alice_mep:example.com', room: room); expect(user1.calcDisplayname(), 'Alice'); expect(user2.calcDisplayname(), 'SuperAlice'); expect(user3.calcDisplayname(), 'Alice Mep');