Merge branch 'krille/refactor-room-states' into 'main'
refactor: Room states Closes #143 See merge request famedly/famedlysdk!663
This commit is contained in:
		
						commit
						4bd8359518
					
				|  | @ -27,7 +27,6 @@ export 'src/utils/matrix_id_string_extension.dart'; | |||
| export 'src/utils/uri_extension.dart'; | ||||
| export 'src/utils/matrix_localizations.dart'; | ||||
| export 'src/utils/receipt.dart'; | ||||
| export 'src/utils/states_map.dart'; | ||||
| export 'src/utils/sync_update_extension.dart'; | ||||
| export 'src/utils/to_device_event.dart'; | ||||
| export 'src/utils/uia_request.dart'; | ||||
|  |  | |||
|  | @ -271,8 +271,12 @@ class Client extends MatrixApi { | |||
|     } | ||||
|     for (var i = 0; i < rooms.length; i++) { | ||||
|       if (rooms[i].membership == Membership.invite && | ||||
|           rooms[i].states[userID]?.senderId == userId && | ||||
|           rooms[i].states[userID].content['is_direct'] == true) { | ||||
|           rooms[i].getState(EventTypes.RoomMember, userID)?.senderId == | ||||
|               userId && | ||||
|           rooms[i] | ||||
|                   .getState(EventTypes.RoomMember, userID) | ||||
|                   .content['is_direct'] == | ||||
|               true) { | ||||
|         return rooms[i].id; | ||||
|       } | ||||
|     } | ||||
|  | @ -1412,7 +1416,7 @@ sort order of ${prevState.sortOrder}. This should never happen...'''); | |||
|         } | ||||
|         if (stateEvent.type == EventTypes.Redaction) { | ||||
|           final String redacts = eventUpdate.content['redacts']; | ||||
|           room.states.states.forEach( | ||||
|           room.states.forEach( | ||||
|             (String key, Map<String, Event> states) => states.forEach( | ||||
|               (String key, Event state) { | ||||
|                 if (state.eventId == redacts) { | ||||
|  |  | |||
|  | @ -33,7 +33,6 @@ import 'utils/markdown.dart'; | |||
| import 'utils/marked_unread.dart'; | ||||
| import 'utils/matrix_file.dart'; | ||||
| import 'utils/matrix_localizations.dart'; | ||||
| import 'utils/states_map.dart'; | ||||
| 
 | ||||
| enum PushRuleState { notify, mentions_only, dont_notify } | ||||
| enum JoinRules { public, knock, invite, private } | ||||
|  | @ -70,7 +69,10 @@ class Room { | |||
|   /// The number of users with membership of invite. | ||||
|   int mInvitedMemberCount; | ||||
| 
 | ||||
|   StatesMap states = StatesMap(); | ||||
|   /// The room states are a key value store of the key ([type],[state_key]) => State(event). | ||||
|   /// In a lot of cases the [state_key] might be an empty string. You **should** use the | ||||
|   /// methods [getState] and [setState] to interact with the room states. | ||||
|   Map<String, Map<String, Event>> states = {}; | ||||
| 
 | ||||
|   /// Key-Value store for ephemerals. | ||||
|   Map<String, BasicRoomEvent> ephemerals = {}; | ||||
|  | @ -128,7 +130,7 @@ class Room { | |||
|   /// Returns the [Event] for the given [typeKey] and optional [stateKey]. | ||||
|   /// If no [stateKey] is provided, it defaults to an empty string. | ||||
|   Event getState(String typeKey, [String stateKey = '']) => | ||||
|       states.states[typeKey] != null ? states.states[typeKey][stateKey] : null; | ||||
|       states[typeKey] != null ? states[typeKey][stateKey] : null; | ||||
| 
 | ||||
|   /// Adds the [state] to this room and overwrites a state with the same | ||||
|   /// typeKey/stateKey key pair if there is one. | ||||
|  | @ -152,10 +154,10 @@ class Room { | |||
|     if (oldStateEvent != null && oldStateEvent.sortOrder >= state.sortOrder) { | ||||
|       return; | ||||
|     } | ||||
|     if (!states.states.containsKey(state.type)) { | ||||
|       states.states[state.type] = {}; | ||||
|     if (!states.containsKey(state.type)) { | ||||
|       states[state.type] = {}; | ||||
|     } | ||||
|     states.states[state.type][state.stateKey ?? ''] = state; | ||||
|     states[state.type][state.stateKey ?? ''] = state; | ||||
|   } | ||||
| 
 | ||||
|   /// ID of the fully read marker event. | ||||
|  | @ -173,16 +175,17 @@ class Room { | |||
|       StreamController.broadcast(); | ||||
| 
 | ||||
|   /// The name of the room if set by a participant. | ||||
|   String get name => states[EventTypes.RoomName] != null && | ||||
|           states[EventTypes.RoomName].content['name'] is String | ||||
|       ? states[EventTypes.RoomName].content['name'] | ||||
|   String get name => getState(EventTypes.RoomName) != null && | ||||
|           getState(EventTypes.RoomName).content['name'] is String | ||||
|       ? getState(EventTypes.RoomName).content['name'] | ||||
|       : ''; | ||||
| 
 | ||||
|   /// The pinned events for this room. If there are none this returns an empty | ||||
|   /// list. | ||||
|   List<String> get pinnedEventIds => states[EventTypes.RoomPinnedEvents] != null | ||||
|       ? (states[EventTypes.RoomPinnedEvents].content['pinned'] is List<String> | ||||
|           ? states[EventTypes.RoomPinnedEvents].content['pinned'] | ||||
|   List<String> get pinnedEventIds => getState(EventTypes.RoomPinnedEvents) != | ||||
|           null | ||||
|       ? (getState(EventTypes.RoomPinnedEvents).content['pinned'] is List<String> | ||||
|           ? getState(EventTypes.RoomPinnedEvents).content['pinned'] | ||||
|           : <String>[]) | ||||
|       : <String>[]; | ||||
| 
 | ||||
|  | @ -205,19 +208,21 @@ class Room { | |||
|   } | ||||
| 
 | ||||
|   /// The topic of the room if set by a participant. | ||||
|   String get topic => states[EventTypes.RoomTopic] != null && | ||||
|           states[EventTypes.RoomTopic].content['topic'] is String | ||||
|       ? states[EventTypes.RoomTopic].content['topic'] | ||||
|   String get topic => getState(EventTypes.RoomTopic) != null && | ||||
|           getState(EventTypes.RoomTopic).content['topic'] is String | ||||
|       ? getState(EventTypes.RoomTopic).content['topic'] | ||||
|       : ''; | ||||
| 
 | ||||
|   /// The avatar of the room if set by a participant. | ||||
|   Uri get avatar { | ||||
|     if (states[EventTypes.RoomAvatar] != null && | ||||
|         states[EventTypes.RoomAvatar].content['url'] is String) { | ||||
|       return Uri.tryParse(states[EventTypes.RoomAvatar].content['url']); | ||||
|     if (getState(EventTypes.RoomAvatar) != null && | ||||
|         getState(EventTypes.RoomAvatar).content['url'] is String) { | ||||
|       return Uri.tryParse(getState(EventTypes.RoomAvatar).content['url']); | ||||
|     } | ||||
|     if (mHeroes != null && mHeroes.length == 1 && states[mHeroes[0]] != null) { | ||||
|       return states[mHeroes[0]].asUser.avatarUrl; | ||||
|     if (mHeroes != null && | ||||
|         mHeroes.length == 1 && | ||||
|         getState(EventTypes.RoomMember, mHeroes.first) != null) { | ||||
|       return getState(EventTypes.RoomMember, mHeroes.first).asUser.avatarUrl; | ||||
|     } | ||||
|     if (membership == Membership.invite && | ||||
|         getState(EventTypes.RoomMember, client.userID) != null) { | ||||
|  | @ -227,10 +232,11 @@ class Room { | |||
|   } | ||||
| 
 | ||||
|   /// The address in the format: #roomname:homeserver.org. | ||||
|   String get canonicalAlias => states[EventTypes.RoomCanonicalAlias] != null && | ||||
|           states[EventTypes.RoomCanonicalAlias].content['alias'] is String | ||||
|       ? states[EventTypes.RoomCanonicalAlias].content['alias'] | ||||
|       : ''; | ||||
|   String get canonicalAlias => | ||||
|       getState(EventTypes.RoomCanonicalAlias) != null && | ||||
|               getState(EventTypes.RoomCanonicalAlias).content['alias'] is String | ||||
|           ? getState(EventTypes.RoomCanonicalAlias).content['alias'] | ||||
|           : ''; | ||||
| 
 | ||||
|   /// If this room is a direct chat, this is the matrix ID of the user. | ||||
|   /// Returns null otherwise. | ||||
|  | @ -289,7 +295,7 @@ class Room { | |||
|     if (lastEvent == null) { | ||||
|       states.forEach((final String key, final entry) { | ||||
|         if (!entry.containsKey('')) return; | ||||
|         final Event state = entry['']; | ||||
|         final state = entry['']; | ||||
|         if (state.originServerTs != null && | ||||
|             state.originServerTs.millisecondsSinceEpoch > | ||||
|                 lastTime.millisecondsSinceEpoch) { | ||||
|  | @ -358,7 +364,7 @@ class Room { | |||
|     } else { | ||||
|       if (states[EventTypes.RoomMember] is Map<String, dynamic>) { | ||||
|         for (var entry in states[EventTypes.RoomMember].entries) { | ||||
|           Event state = entry.value; | ||||
|           final state = entry.value; | ||||
|           if (state.type == EventTypes.RoomMember && | ||||
|               state.stateKey != client?.userID) heroes.add(state.stateKey); | ||||
|         } | ||||
|  | @ -565,7 +571,7 @@ class Room { | |||
|       } | ||||
|     } | ||||
|     // finally add all the room emotes | ||||
|     final allRoomEmotes = states.states['im.ponies.room_emotes']; | ||||
|     final allRoomEmotes = states['im.ponies.room_emotes']; | ||||
|     if (allRoomEmotes != null) { | ||||
|       for (final entry in allRoomEmotes.entries) { | ||||
|         final stateKey = entry.key; | ||||
|  | @ -923,9 +929,9 @@ class Room { | |||
|   /// Returns the event ID of the new state event. If there is no known | ||||
|   /// power level event, there might something broken and this returns null. | ||||
|   Future<String> setPower(String userID, int power) async { | ||||
|     if (states[EventTypes.RoomPowerLevels] == null) return null; | ||||
|     if (getState(EventTypes.RoomPowerLevels) == null) return null; | ||||
|     final powerMap = <String, dynamic>{} | ||||
|       ..addAll(states[EventTypes.RoomPowerLevels].content); | ||||
|       ..addAll(getState(EventTypes.RoomPowerLevels).content); | ||||
|     if (powerMap['users'] == null) powerMap['users'] = {}; | ||||
|     powerMap['users'][userID] = power; | ||||
| 
 | ||||
|  | @ -1171,7 +1177,7 @@ class Room { | |||
|     var userList = <User>[]; | ||||
|     if (states[EventTypes.RoomMember] is Map<String, dynamic>) { | ||||
|       for (var entry in states[EventTypes.RoomMember].entries) { | ||||
|         Event state = entry.value; | ||||
|         final state = entry.value; | ||||
|         if (state.type == EventTypes.RoomMember) userList.add(state.asUser); | ||||
|       } | ||||
|     } | ||||
|  | @ -1218,7 +1224,9 @@ class Room { | |||
|   /// the homeserver and waits for a response. | ||||
|   @Deprecated('Use [requestUser] instead') | ||||
|   Future<User> getUserByMXID(String mxID) async { | ||||
|     if (states[mxID] != null) return states[mxID].asUser; | ||||
|     if (getState(EventTypes.RoomMember, mxID) != null) { | ||||
|       return getState(EventTypes.RoomMember, mxID).asUser; | ||||
|     } | ||||
|     return requestUser(mxID); | ||||
|   } | ||||
| 
 | ||||
|  | @ -1351,7 +1359,7 @@ class Room { | |||
|   /// Returns the power level of the given user ID. | ||||
|   int getPowerLevelByUserId(String userId) { | ||||
|     var powerLevel = 0; | ||||
|     Event powerLevelState = states[EventTypes.RoomPowerLevels]; | ||||
|     final powerLevelState = getState(EventTypes.RoomPowerLevels); | ||||
|     if (powerLevelState == null) return powerLevel; | ||||
|     if (powerLevelState.content['users_default'] is int) { | ||||
|       powerLevel = powerLevelState.content['users_default']; | ||||
|  | @ -1370,7 +1378,7 @@ class Room { | |||
| 
 | ||||
|   /// Returns the power levels from all users for this room or null if not given. | ||||
|   Map<String, int> get powerLevels { | ||||
|     Event powerLevelState = states[EventTypes.RoomPowerLevels]; | ||||
|     final powerLevelState = getState(EventTypes.RoomPowerLevels); | ||||
|     if (powerLevelState.content['users'] is Map<String, int>) { | ||||
|       return powerLevelState.content['users']; | ||||
|     } | ||||
|  | @ -1653,7 +1661,7 @@ class Room { | |||
|   /// Returns all aliases for this room. | ||||
|   List<String> get aliases { | ||||
|     var aliases = <String>[]; | ||||
|     for (var aliasEvent in states.states[EventTypes.RoomAliases].values) { | ||||
|     for (var aliasEvent in states[EventTypes.RoomAliases].values) { | ||||
|       if (aliasEvent.content['aliases'] is List) { | ||||
|         aliases.addAll(aliasEvent.content['aliases']); | ||||
|       } | ||||
|  |  | |||
|  | @ -1,62 +0,0 @@ | |||
| /* | ||||
|  *   Famedly Matrix SDK | ||||
|  *   Copyright (C) 2020, 2021 Famedly GmbH | ||||
|  * | ||||
|  *   This program is free software: you can redistribute it and/or modify | ||||
|  *   it under the terms of the GNU Affero General Public License as | ||||
|  *   published by the Free Software Foundation, either version 3 of the | ||||
|  *   License, or (at your option) any later version. | ||||
|  * | ||||
|  *   This program is distributed in the hope that it will be useful, | ||||
|  *   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
|  *   GNU Affero General Public License for more details. | ||||
|  * | ||||
|  *   You should have received a copy of the GNU Affero General Public License | ||||
|  *   along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| 
 | ||||
| import '../../famedlysdk.dart'; | ||||
| 
 | ||||
| /// Matrix room states are addressed by a tuple of the [type] and an | ||||
| /// optional [stateKey]. | ||||
| class StatesMap { | ||||
|   Map<String, Map<String, Event>> states = {}; | ||||
| 
 | ||||
|   /// Returns either the [Event] or a map of state_keys to [Event] objects. | ||||
|   /// If you just enter a MatrixID, it will try to return the corresponding m.room.member event. | ||||
|   dynamic operator [](String key) { | ||||
|     //print("[Warning] This method will be depracated in the future!"); | ||||
|     if (key == null) return null; | ||||
|     if (key.startsWith('@') && key.contains(':')) { | ||||
|       if (!states.containsKey(EventTypes.RoomMember)) { | ||||
|         states[EventTypes.RoomMember] = {}; | ||||
|       } | ||||
|       return states[EventTypes.RoomMember][key]; | ||||
|     } | ||||
|     if (!states.containsKey(key)) states[key] = {}; | ||||
|     if (states[key][''] is Event) { | ||||
|       return states[key]['']; | ||||
|     } else if (states[key].isEmpty) { | ||||
|       return null; | ||||
|     } else { | ||||
|       return states[key]; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void operator []=(String key, Event val) { | ||||
|     //print("[Warning] This method will be depracated in the future!"); | ||||
|     if (key.startsWith('@') && key.contains(':')) { | ||||
|       if (!states.containsKey(EventTypes.RoomMember)) { | ||||
|         states[EventTypes.RoomMember] = {}; | ||||
|       } | ||||
|       states[EventTypes.RoomMember][key] = val; | ||||
|     } | ||||
|     if (!states.containsKey(key)) states[key] = {}; | ||||
|     states[key][val.stateKey ?? ''] = val; | ||||
|   } | ||||
| 
 | ||||
|   bool containsKey(String key) => states.containsKey(key); | ||||
| 
 | ||||
|   void forEach(f) => states.forEach(f); | ||||
| } | ||||
|  | @ -339,25 +339,27 @@ void main() { | |||
|       final room = Room(id: roomId, client: client); | ||||
|       client.rooms.add(room); | ||||
|       // we build up an encrypted message so that we can test if it successfully decrypted afterwards | ||||
|       room.states['m.room.encrypted'] = Event( | ||||
|         senderId: '@test:example.com', | ||||
|         type: 'm.room.encrypted', | ||||
|         roomId: room.id, | ||||
|         room: room, | ||||
|         eventId: '12345', | ||||
|         originServerTs: DateTime.now(), | ||||
|         content: { | ||||
|           'algorithm': AlgorithmTypes.megolmV1AesSha2, | ||||
|           'ciphertext': session.encrypt(json.encode({ | ||||
|             'type': 'm.room.message', | ||||
|             'content': {'msgtype': 'm.text', 'body': 'foxies'}, | ||||
|           })), | ||||
|           'device_id': client.deviceID, | ||||
|           'sender_key': client.identityKey, | ||||
|           'session_id': sessionId, | ||||
|         }, | ||||
|         stateKey: '', | ||||
|         sortOrder: 42.0, | ||||
|       room.setState( | ||||
|         Event( | ||||
|           senderId: '@test:example.com', | ||||
|           type: 'm.room.encrypted', | ||||
|           roomId: room.id, | ||||
|           room: room, | ||||
|           eventId: '12345', | ||||
|           originServerTs: DateTime.now(), | ||||
|           content: { | ||||
|             'algorithm': AlgorithmTypes.megolmV1AesSha2, | ||||
|             'ciphertext': session.encrypt(json.encode({ | ||||
|               'type': 'm.room.message', | ||||
|               'content': {'msgtype': 'm.text', 'body': 'foxies'}, | ||||
|             })), | ||||
|             'device_id': client.deviceID, | ||||
|             'sender_key': client.identityKey, | ||||
|             'session_id': sessionId, | ||||
|           }, | ||||
|           stateKey: '', | ||||
|           sortOrder: 42.0, | ||||
|         ), | ||||
|       ); | ||||
|       expect(room.lastEvent.type, 'm.room.encrypted'); | ||||
|       // set a payload... | ||||
|  |  | |||
|  | @ -112,97 +112,113 @@ void main() { | |||
|       expect(room.getState('m.room.join_rules').content['join_rule'], 'public'); | ||||
|       expect(room.roomAccountData['com.test.foo'].content['foo'], 'bar'); | ||||
| 
 | ||||
|       room.states['m.room.canonical_alias'] = Event( | ||||
|           senderId: '@test:example.com', | ||||
|           type: 'm.room.canonical_alias', | ||||
|           roomId: room.id, | ||||
|           room: room, | ||||
|           eventId: '123', | ||||
|           content: {'alias': '#testalias:example.com'}, | ||||
|           stateKey: ''); | ||||
|       room.setState( | ||||
|         Event( | ||||
|             senderId: '@test:example.com', | ||||
|             type: 'm.room.canonical_alias', | ||||
|             roomId: room.id, | ||||
|             room: room, | ||||
|             eventId: '123', | ||||
|             content: {'alias': '#testalias:example.com'}, | ||||
|             stateKey: ''), | ||||
|       ); | ||||
|       expect(room.displayname, 'testalias'); | ||||
|       expect(room.canonicalAlias, '#testalias:example.com'); | ||||
| 
 | ||||
|       room.states['m.room.name'] = Event( | ||||
|           senderId: '@test:example.com', | ||||
|           type: 'm.room.name', | ||||
|           roomId: room.id, | ||||
|           room: room, | ||||
|           eventId: '123', | ||||
|           content: {'name': 'testname'}, | ||||
|           stateKey: ''); | ||||
|       room.setState( | ||||
|         Event( | ||||
|             senderId: '@test:example.com', | ||||
|             type: 'm.room.name', | ||||
|             roomId: room.id, | ||||
|             room: room, | ||||
|             eventId: '123', | ||||
|             content: {'name': 'testname'}, | ||||
|             stateKey: ''), | ||||
|       ); | ||||
|       expect(room.displayname, 'testname'); | ||||
| 
 | ||||
|       expect(room.topic, ''); | ||||
|       room.states['m.room.topic'] = Event( | ||||
|           senderId: '@test:example.com', | ||||
|           type: 'm.room.topic', | ||||
|           roomId: room.id, | ||||
|           room: room, | ||||
|           eventId: '123', | ||||
|           content: {'topic': 'testtopic'}, | ||||
|           stateKey: ''); | ||||
|       room.setState( | ||||
|         Event( | ||||
|             senderId: '@test:example.com', | ||||
|             type: 'm.room.topic', | ||||
|             roomId: room.id, | ||||
|             room: room, | ||||
|             eventId: '123', | ||||
|             content: {'topic': 'testtopic'}, | ||||
|             stateKey: ''), | ||||
|       ); | ||||
|       expect(room.topic, 'testtopic'); | ||||
| 
 | ||||
|       expect(room.avatar, null); | ||||
|       room.states['m.room.avatar'] = Event( | ||||
|           senderId: '@test:example.com', | ||||
|           type: 'm.room.avatar', | ||||
|           roomId: room.id, | ||||
|           room: room, | ||||
|           eventId: '123', | ||||
|           content: {'url': 'mxc://testurl'}, | ||||
|           stateKey: ''); | ||||
|       room.setState( | ||||
|         Event( | ||||
|             senderId: '@test:example.com', | ||||
|             type: 'm.room.avatar', | ||||
|             roomId: room.id, | ||||
|             room: room, | ||||
|             eventId: '123', | ||||
|             content: {'url': 'mxc://testurl'}, | ||||
|             stateKey: ''), | ||||
|       ); | ||||
|       expect(room.avatar.toString(), 'mxc://testurl'); | ||||
| 
 | ||||
|       expect(room.pinnedEventIds, <String>[]); | ||||
|       room.states['m.room.pinned_events'] = Event( | ||||
|           senderId: '@test:example.com', | ||||
|           type: 'm.room.pinned_events', | ||||
|           roomId: room.id, | ||||
|           room: room, | ||||
|           eventId: '123', | ||||
|           content: { | ||||
|             'pinned': ['1234'] | ||||
|           }, | ||||
|           stateKey: ''); | ||||
|       room.setState( | ||||
|         Event( | ||||
|             senderId: '@test:example.com', | ||||
|             type: 'm.room.pinned_events', | ||||
|             roomId: room.id, | ||||
|             room: room, | ||||
|             eventId: '123', | ||||
|             content: { | ||||
|               'pinned': ['1234'] | ||||
|             }, | ||||
|             stateKey: ''), | ||||
|       ); | ||||
|       expect(room.pinnedEventIds.first, '1234'); | ||||
|       room.states['m.room.message'] = Event( | ||||
|           senderId: '@test:example.com', | ||||
|           type: 'm.room.message', | ||||
|           roomId: room.id, | ||||
|           room: room, | ||||
|           eventId: '12345', | ||||
|           originServerTs: DateTime.now(), | ||||
|           content: {'msgtype': 'm.text', 'body': 'test'}, | ||||
|           stateKey: ''); | ||||
|       room.setState( | ||||
|         Event( | ||||
|             senderId: '@test:example.com', | ||||
|             type: 'm.room.message', | ||||
|             roomId: room.id, | ||||
|             room: room, | ||||
|             eventId: '12345', | ||||
|             originServerTs: DateTime.now(), | ||||
|             content: {'msgtype': 'm.text', 'body': 'test'}, | ||||
|             stateKey: ''), | ||||
|       ); | ||||
|       expect(room.lastEvent.eventId, '12345'); | ||||
|       expect(room.lastEvent.body, 'test'); | ||||
|       expect(room.timeCreated, room.lastEvent.originServerTs); | ||||
|     }); | ||||
| 
 | ||||
|     test('multiple last event with same sort order', () { | ||||
|       room.states['m.room.encrypted'] = Event( | ||||
|           senderId: '@test:example.com', | ||||
|           type: 'm.room.encrypted', | ||||
|           roomId: room.id, | ||||
|           room: room, | ||||
|           eventId: '12345', | ||||
|           originServerTs: DateTime.now(), | ||||
|           content: {'msgtype': 'm.text', 'body': 'test'}, | ||||
|           stateKey: '', | ||||
|           sortOrder: 42.0); | ||||
|       room.setState( | ||||
|         Event( | ||||
|             senderId: '@test:example.com', | ||||
|             type: 'm.room.encrypted', | ||||
|             roomId: room.id, | ||||
|             room: room, | ||||
|             eventId: '12345', | ||||
|             originServerTs: DateTime.now(), | ||||
|             content: {'msgtype': 'm.text', 'body': 'test'}, | ||||
|             stateKey: '', | ||||
|             sortOrder: 42.0), | ||||
|       ); | ||||
|       expect(room.lastEvent.type, 'm.room.encrypted'); | ||||
|       room.states['m.room.messge'] = Event( | ||||
|           senderId: '@test:example.com', | ||||
|           type: 'm.room.messge', | ||||
|           roomId: room.id, | ||||
|           room: room, | ||||
|           eventId: '12345', | ||||
|           originServerTs: DateTime.now(), | ||||
|           content: {'msgtype': 'm.text', 'body': 'test'}, | ||||
|           stateKey: '', | ||||
|           sortOrder: 42.0); | ||||
|       room.setState( | ||||
|         Event( | ||||
|             senderId: '@test:example.com', | ||||
|             type: 'm.room.messge', | ||||
|             roomId: room.id, | ||||
|             room: room, | ||||
|             eventId: '12345', | ||||
|             originServerTs: DateTime.now(), | ||||
|             content: {'msgtype': 'm.text', 'body': 'test'}, | ||||
|             stateKey: '', | ||||
|             sortOrder: 42.0), | ||||
|       ); | ||||
|       expect(room.lastEvent.type, 'm.room.encrypted'); | ||||
|     }); | ||||
| 
 | ||||
|  | @ -249,25 +265,27 @@ void main() { | |||
|     }); | ||||
| 
 | ||||
|     test('PowerLevels', () async { | ||||
|       room.states['m.room.power_levels'] = Event( | ||||
|           senderId: '@test:example.com', | ||||
|           type: 'm.room.power_levels', | ||||
|           roomId: room.id, | ||||
|           room: room, | ||||
|           eventId: '123', | ||||
|           content: { | ||||
|             'ban': 50, | ||||
|             'events': {'m.room.name': 100, 'm.room.power_levels': 100}, | ||||
|             'events_default': 0, | ||||
|             'invite': 50, | ||||
|             'kick': 50, | ||||
|             'notifications': {'room': 20}, | ||||
|             'redact': 50, | ||||
|             'state_default': 50, | ||||
|             'users': {'@test:fakeServer.notExisting': 100}, | ||||
|             'users_default': 10 | ||||
|           }, | ||||
|           stateKey: ''); | ||||
|       room.setState( | ||||
|         Event( | ||||
|             senderId: '@test:example.com', | ||||
|             type: 'm.room.power_levels', | ||||
|             roomId: room.id, | ||||
|             room: room, | ||||
|             eventId: '123', | ||||
|             content: { | ||||
|               'ban': 50, | ||||
|               'events': {'m.room.name': 100, 'm.room.power_levels': 100}, | ||||
|               'events_default': 0, | ||||
|               'invite': 50, | ||||
|               'kick': 50, | ||||
|               'notifications': {'room': 20}, | ||||
|               'redact': 50, | ||||
|               'state_default': 50, | ||||
|               'users': {'@test:fakeServer.notExisting': 100}, | ||||
|               'users_default': 10 | ||||
|             }, | ||||
|             stateKey: ''), | ||||
|       ); | ||||
|       expect(room.ownPowerLevel, 100); | ||||
|       expect(room.getPowerLevelByUserId(matrix.userID), room.ownPowerLevel); | ||||
|       expect(room.getPowerLevelByUserId('@nouser:example.com'), 10); | ||||
|  | @ -283,9 +301,10 @@ void main() { | |||
|       expect(room.canSendEvent('m.room.power_levels'), true); | ||||
|       expect(room.canSendEvent('m.room.member'), true); | ||||
|       expect(room.powerLevels, | ||||
|           room.states['m.room.power_levels'].content['users']); | ||||
|           room.getState('m.room.power_levels').content['users']); | ||||
| 
 | ||||
|       room.states['m.room.power_levels'] = Event( | ||||
|       room.setState( | ||||
|         Event( | ||||
|           senderId: '@test:example.com', | ||||
|           type: 'm.room.power_levels', | ||||
|           roomId: room.id, | ||||
|  | @ -303,7 +322,10 @@ void main() { | |||
|             'users': {}, | ||||
|             'users_default': 0 | ||||
|           }, | ||||
|           stateKey: ''); | ||||
|           stateKey: '', | ||||
|           sortOrder: 1, | ||||
|         ), | ||||
|       ); | ||||
|       expect(room.ownPowerLevel, 0); | ||||
|       expect(room.canBan, false); | ||||
|       expect(room.canInvite, false); | ||||
|  |  | |||
|  | @ -1,71 +0,0 @@ | |||
| /* | ||||
|  *   Famedly Matrix SDK | ||||
|  *   Copyright (C) 2019, 2020 Famedly GmbH | ||||
|  * | ||||
|  *   This program is free software: you can redistribute it and/or modify | ||||
|  *   it under the terms of the GNU Affero General Public License as | ||||
|  *   published by the Free Software Foundation, either version 3 of the | ||||
|  *   License, or (at your option) any later version. | ||||
|  * | ||||
|  *   This program is distributed in the hope that it will be useful, | ||||
|  *   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
|  *   GNU Affero General Public License for more details. | ||||
|  * | ||||
|  *   You should have received a copy of the GNU Affero General Public License | ||||
|  *   along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| 
 | ||||
| import 'package:famedlysdk/famedlysdk.dart'; | ||||
| import 'package:logger/logger.dart'; | ||||
| import 'package:test/test.dart'; | ||||
| import 'package:famedlysdk/src/utils/states_map.dart'; | ||||
| 
 | ||||
| void main() { | ||||
|   /// All Tests related to the ChatTime | ||||
|   group('StateKeys', () { | ||||
|     Logs().level = Level.error; | ||||
|     test('Operator overload', () async { | ||||
|       var states = StatesMap(); | ||||
|       states['m.room.name'] = Event( | ||||
|           eventId: '1', | ||||
|           content: {'name': 'test'}, | ||||
|           type: 'm.room.name', | ||||
|           stateKey: '', | ||||
|           roomId: '!test:test.test', | ||||
|           senderId: '@alice:test.test'); | ||||
| 
 | ||||
|       states['@alice:test.test'] = Event( | ||||
|           eventId: '2', | ||||
|           content: {'membership': 'join'}, | ||||
|           type: 'm.room.name', | ||||
|           stateKey: '@alice:test.test', | ||||
|           roomId: '!test:test.test', | ||||
|           senderId: '@alice:test.test'); | ||||
| 
 | ||||
|       states['m.room.member']['@bob:test.test'] = Event( | ||||
|           eventId: '3', | ||||
|           content: {'membership': 'join'}, | ||||
|           type: 'm.room.name', | ||||
|           stateKey: '@bob:test.test', | ||||
|           roomId: '!test:test.test', | ||||
|           senderId: '@bob:test.test'); | ||||
| 
 | ||||
|       states['com.test.custom'] = Event( | ||||
|           eventId: '4', | ||||
|           content: {'custom': 'stuff'}, | ||||
|           type: 'com.test.custom', | ||||
|           stateKey: 'customStateKey', | ||||
|           roomId: '!test:test.test', | ||||
|           senderId: '@bob:test.test'); | ||||
| 
 | ||||
|       expect(states['m.room.name'].eventId, '1'); | ||||
|       expect(states['@alice:test.test'].eventId, '2'); | ||||
|       expect(states['m.room.member']['@alice:test.test'].eventId, '2'); | ||||
|       expect(states['@bob:test.test'].eventId, '3'); | ||||
|       expect(states['m.room.member']['@bob:test.test'].eventId, '3'); | ||||
|       expect(states['m.room.member'].length, 2); | ||||
|       expect(states['com.test.custom']['customStateKey'].eventId, '4'); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
		Loading…
	
		Reference in New Issue