refactor: Room states

This commit is contained in:
Christian Pauly 2021-03-02 09:05:46 +01:00 committed by Krille Fear
parent 3f2ced692f
commit 1f8285c3e7
7 changed files with 185 additions and 283 deletions

View File

@ -27,7 +27,6 @@ export 'src/utils/matrix_id_string_extension.dart';
export 'src/utils/uri_extension.dart'; export 'src/utils/uri_extension.dart';
export 'src/utils/matrix_localizations.dart'; export 'src/utils/matrix_localizations.dart';
export 'src/utils/receipt.dart'; export 'src/utils/receipt.dart';
export 'src/utils/states_map.dart';
export 'src/utils/sync_update_extension.dart'; export 'src/utils/sync_update_extension.dart';
export 'src/utils/to_device_event.dart'; export 'src/utils/to_device_event.dart';
export 'src/utils/uia_request.dart'; export 'src/utils/uia_request.dart';

View File

@ -271,8 +271,12 @@ class Client extends MatrixApi {
} }
for (var i = 0; i < rooms.length; i++) { for (var i = 0; i < rooms.length; i++) {
if (rooms[i].membership == Membership.invite && if (rooms[i].membership == Membership.invite &&
rooms[i].states[userID]?.senderId == userId && rooms[i].getState(EventTypes.RoomMember, userID)?.senderId ==
rooms[i].states[userID].content['is_direct'] == true) { userId &&
rooms[i]
.getState(EventTypes.RoomMember, userID)
.content['is_direct'] ==
true) {
return rooms[i].id; return rooms[i].id;
} }
} }
@ -1412,7 +1416,7 @@ sort order of ${prevState.sortOrder}. This should never happen...''');
} }
if (stateEvent.type == EventTypes.Redaction) { if (stateEvent.type == EventTypes.Redaction) {
final String redacts = eventUpdate.content['redacts']; final String redacts = eventUpdate.content['redacts'];
room.states.states.forEach( room.states.forEach(
(String key, Map<String, Event> states) => states.forEach( (String key, Map<String, Event> states) => states.forEach(
(String key, Event state) { (String key, Event state) {
if (state.eventId == redacts) { if (state.eventId == redacts) {

View File

@ -33,7 +33,6 @@ import 'utils/markdown.dart';
import 'utils/marked_unread.dart'; import 'utils/marked_unread.dart';
import 'utils/matrix_file.dart'; import 'utils/matrix_file.dart';
import 'utils/matrix_localizations.dart'; import 'utils/matrix_localizations.dart';
import 'utils/states_map.dart';
enum PushRuleState { notify, mentions_only, dont_notify } enum PushRuleState { notify, mentions_only, dont_notify }
enum JoinRules { public, knock, invite, private } enum JoinRules { public, knock, invite, private }
@ -70,7 +69,10 @@ class Room {
/// The number of users with membership of invite. /// The number of users with membership of invite.
int mInvitedMemberCount; 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. /// Key-Value store for ephemerals.
Map<String, BasicRoomEvent> ephemerals = {}; Map<String, BasicRoomEvent> ephemerals = {};
@ -128,7 +130,7 @@ class Room {
/// Returns the [Event] for the given [typeKey] and optional [stateKey]. /// Returns the [Event] for the given [typeKey] and optional [stateKey].
/// If no [stateKey] is provided, it defaults to an empty string. /// If no [stateKey] is provided, it defaults to an empty string.
Event getState(String typeKey, [String stateKey = '']) => 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 /// Adds the [state] to this room and overwrites a state with the same
/// typeKey/stateKey key pair if there is one. /// typeKey/stateKey key pair if there is one.
@ -152,10 +154,10 @@ class Room {
if (oldStateEvent != null && oldStateEvent.sortOrder >= state.sortOrder) { if (oldStateEvent != null && oldStateEvent.sortOrder >= state.sortOrder) {
return; return;
} }
if (!states.states.containsKey(state.type)) { if (!states.containsKey(state.type)) {
states.states[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. /// ID of the fully read marker event.
@ -173,16 +175,17 @@ class Room {
StreamController.broadcast(); StreamController.broadcast();
/// The name of the room if set by a participant. /// The name of the room if set by a participant.
String get name => states[EventTypes.RoomName] != null && String get name => getState(EventTypes.RoomName) != null &&
states[EventTypes.RoomName].content['name'] is String getState(EventTypes.RoomName).content['name'] is String
? states[EventTypes.RoomName].content['name'] ? getState(EventTypes.RoomName).content['name']
: ''; : '';
/// The pinned events for this room. If there are none this returns an empty /// The pinned events for this room. If there are none this returns an empty
/// list. /// list.
List<String> get pinnedEventIds => states[EventTypes.RoomPinnedEvents] != null List<String> get pinnedEventIds => getState(EventTypes.RoomPinnedEvents) !=
? (states[EventTypes.RoomPinnedEvents].content['pinned'] is List<String> null
? states[EventTypes.RoomPinnedEvents].content['pinned'] ? (getState(EventTypes.RoomPinnedEvents).content['pinned'] is List<String>
? getState(EventTypes.RoomPinnedEvents).content['pinned']
: <String>[]) : <String>[])
: <String>[]; : <String>[];
@ -205,19 +208,21 @@ class Room {
} }
/// The topic of the room if set by a participant. /// The topic of the room if set by a participant.
String get topic => states[EventTypes.RoomTopic] != null && String get topic => getState(EventTypes.RoomTopic) != null &&
states[EventTypes.RoomTopic].content['topic'] is String getState(EventTypes.RoomTopic).content['topic'] is String
? states[EventTypes.RoomTopic].content['topic'] ? getState(EventTypes.RoomTopic).content['topic']
: ''; : '';
/// The avatar of the room if set by a participant. /// The avatar of the room if set by a participant.
Uri get avatar { Uri get avatar {
if (states[EventTypes.RoomAvatar] != null && if (getState(EventTypes.RoomAvatar) != null &&
states[EventTypes.RoomAvatar].content['url'] is String) { getState(EventTypes.RoomAvatar).content['url'] is String) {
return Uri.tryParse(states[EventTypes.RoomAvatar].content['url']); return Uri.tryParse(getState(EventTypes.RoomAvatar).content['url']);
} }
if (mHeroes != null && mHeroes.length == 1 && states[mHeroes[0]] != null) { if (mHeroes != null &&
return states[mHeroes[0]].asUser.avatarUrl; mHeroes.length == 1 &&
getState(EventTypes.RoomMember, mHeroes.first) != null) {
return getState(EventTypes.RoomMember, mHeroes.first).asUser.avatarUrl;
} }
if (membership == Membership.invite && if (membership == Membership.invite &&
getState(EventTypes.RoomMember, client.userID) != null) { getState(EventTypes.RoomMember, client.userID) != null) {
@ -227,9 +232,10 @@ class Room {
} }
/// The address in the format: #roomname:homeserver.org. /// The address in the format: #roomname:homeserver.org.
String get canonicalAlias => states[EventTypes.RoomCanonicalAlias] != null && String get canonicalAlias =>
states[EventTypes.RoomCanonicalAlias].content['alias'] is String getState(EventTypes.RoomCanonicalAlias) != null &&
? states[EventTypes.RoomCanonicalAlias].content['alias'] 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. /// If this room is a direct chat, this is the matrix ID of the user.
@ -289,7 +295,7 @@ class Room {
if (lastEvent == null) { if (lastEvent == null) {
states.forEach((final String key, final entry) { states.forEach((final String key, final entry) {
if (!entry.containsKey('')) return; if (!entry.containsKey('')) return;
final Event state = entry['']; final state = entry[''];
if (state.originServerTs != null && if (state.originServerTs != null &&
state.originServerTs.millisecondsSinceEpoch > state.originServerTs.millisecondsSinceEpoch >
lastTime.millisecondsSinceEpoch) { lastTime.millisecondsSinceEpoch) {
@ -358,7 +364,7 @@ class Room {
} else { } else {
if (states[EventTypes.RoomMember] is Map<String, dynamic>) { if (states[EventTypes.RoomMember] is Map<String, dynamic>) {
for (var entry in states[EventTypes.RoomMember].entries) { for (var entry in states[EventTypes.RoomMember].entries) {
Event state = entry.value; final state = entry.value;
if (state.type == EventTypes.RoomMember && if (state.type == EventTypes.RoomMember &&
state.stateKey != client?.userID) heroes.add(state.stateKey); state.stateKey != client?.userID) heroes.add(state.stateKey);
} }
@ -565,7 +571,7 @@ class Room {
} }
} }
// finally add all the room emotes // finally add all the room emotes
final allRoomEmotes = states.states['im.ponies.room_emotes']; final allRoomEmotes = states['im.ponies.room_emotes'];
if (allRoomEmotes != null) { if (allRoomEmotes != null) {
for (final entry in allRoomEmotes.entries) { for (final entry in allRoomEmotes.entries) {
final stateKey = entry.key; final stateKey = entry.key;
@ -923,9 +929,9 @@ class Room {
/// Returns the event ID of the new state event. If there is no known /// 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. /// power level event, there might something broken and this returns null.
Future<String> setPower(String userID, int power) async { 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>{} final powerMap = <String, dynamic>{}
..addAll(states[EventTypes.RoomPowerLevels].content); ..addAll(getState(EventTypes.RoomPowerLevels).content);
if (powerMap['users'] == null) powerMap['users'] = {}; if (powerMap['users'] == null) powerMap['users'] = {};
powerMap['users'][userID] = power; powerMap['users'][userID] = power;
@ -1171,7 +1177,7 @@ class Room {
var userList = <User>[]; var userList = <User>[];
if (states[EventTypes.RoomMember] is Map<String, dynamic>) { if (states[EventTypes.RoomMember] is Map<String, dynamic>) {
for (var entry in states[EventTypes.RoomMember].entries) { 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); if (state.type == EventTypes.RoomMember) userList.add(state.asUser);
} }
} }
@ -1218,7 +1224,9 @@ class Room {
/// the homeserver and waits for a response. /// the homeserver and waits for a response.
@Deprecated('Use [requestUser] instead') @Deprecated('Use [requestUser] instead')
Future<User> getUserByMXID(String mxID) async { 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); return requestUser(mxID);
} }
@ -1351,7 +1359,7 @@ class Room {
/// Returns the power level of the given user ID. /// Returns the power level of the given user ID.
int getPowerLevelByUserId(String userId) { int getPowerLevelByUserId(String userId) {
var powerLevel = 0; var powerLevel = 0;
Event powerLevelState = states[EventTypes.RoomPowerLevels]; final powerLevelState = getState(EventTypes.RoomPowerLevels);
if (powerLevelState == null) return powerLevel; if (powerLevelState == null) return powerLevel;
if (powerLevelState.content['users_default'] is int) { if (powerLevelState.content['users_default'] is int) {
powerLevel = powerLevelState.content['users_default']; 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. /// Returns the power levels from all users for this room or null if not given.
Map<String, int> get powerLevels { Map<String, int> get powerLevels {
Event powerLevelState = states[EventTypes.RoomPowerLevels]; final powerLevelState = getState(EventTypes.RoomPowerLevels);
if (powerLevelState.content['users'] is Map<String, int>) { if (powerLevelState.content['users'] is Map<String, int>) {
return powerLevelState.content['users']; return powerLevelState.content['users'];
} }
@ -1653,7 +1661,7 @@ class Room {
/// Returns all aliases for this room. /// Returns all aliases for this room.
List<String> get aliases { List<String> get aliases {
var aliases = <String>[]; 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) { if (aliasEvent.content['aliases'] is List) {
aliases.addAll(aliasEvent.content['aliases']); aliases.addAll(aliasEvent.content['aliases']);
} }

View File

@ -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);
}

View File

@ -339,7 +339,8 @@ void main() {
final room = Room(id: roomId, client: client); final room = Room(id: roomId, client: client);
client.rooms.add(room); client.rooms.add(room);
// we build up an encrypted message so that we can test if it successfully decrypted afterwards // we build up an encrypted message so that we can test if it successfully decrypted afterwards
room.states['m.room.encrypted'] = Event( room.setState(
Event(
senderId: '@test:example.com', senderId: '@test:example.com',
type: 'm.room.encrypted', type: 'm.room.encrypted',
roomId: room.id, roomId: room.id,
@ -358,6 +359,7 @@ void main() {
}, },
stateKey: '', stateKey: '',
sortOrder: 42.0, sortOrder: 42.0,
),
); );
expect(room.lastEvent.type, 'm.room.encrypted'); expect(room.lastEvent.type, 'm.room.encrypted');
// set a payload... // set a payload...

View File

@ -112,51 +112,60 @@ void main() {
expect(room.getState('m.room.join_rules').content['join_rule'], 'public'); expect(room.getState('m.room.join_rules').content['join_rule'], 'public');
expect(room.roomAccountData['com.test.foo'].content['foo'], 'bar'); expect(room.roomAccountData['com.test.foo'].content['foo'], 'bar');
room.states['m.room.canonical_alias'] = Event( room.setState(
Event(
senderId: '@test:example.com', senderId: '@test:example.com',
type: 'm.room.canonical_alias', type: 'm.room.canonical_alias',
roomId: room.id, roomId: room.id,
room: room, room: room,
eventId: '123', eventId: '123',
content: {'alias': '#testalias:example.com'}, content: {'alias': '#testalias:example.com'},
stateKey: ''); stateKey: ''),
);
expect(room.displayname, 'testalias'); expect(room.displayname, 'testalias');
expect(room.canonicalAlias, '#testalias:example.com'); expect(room.canonicalAlias, '#testalias:example.com');
room.states['m.room.name'] = Event( room.setState(
Event(
senderId: '@test:example.com', senderId: '@test:example.com',
type: 'm.room.name', type: 'm.room.name',
roomId: room.id, roomId: room.id,
room: room, room: room,
eventId: '123', eventId: '123',
content: {'name': 'testname'}, content: {'name': 'testname'},
stateKey: ''); stateKey: ''),
);
expect(room.displayname, 'testname'); expect(room.displayname, 'testname');
expect(room.topic, ''); expect(room.topic, '');
room.states['m.room.topic'] = Event( room.setState(
Event(
senderId: '@test:example.com', senderId: '@test:example.com',
type: 'm.room.topic', type: 'm.room.topic',
roomId: room.id, roomId: room.id,
room: room, room: room,
eventId: '123', eventId: '123',
content: {'topic': 'testtopic'}, content: {'topic': 'testtopic'},
stateKey: ''); stateKey: ''),
);
expect(room.topic, 'testtopic'); expect(room.topic, 'testtopic');
expect(room.avatar, null); expect(room.avatar, null);
room.states['m.room.avatar'] = Event( room.setState(
Event(
senderId: '@test:example.com', senderId: '@test:example.com',
type: 'm.room.avatar', type: 'm.room.avatar',
roomId: room.id, roomId: room.id,
room: room, room: room,
eventId: '123', eventId: '123',
content: {'url': 'mxc://testurl'}, content: {'url': 'mxc://testurl'},
stateKey: ''); stateKey: ''),
);
expect(room.avatar.toString(), 'mxc://testurl'); expect(room.avatar.toString(), 'mxc://testurl');
expect(room.pinnedEventIds, <String>[]); expect(room.pinnedEventIds, <String>[]);
room.states['m.room.pinned_events'] = Event( room.setState(
Event(
senderId: '@test:example.com', senderId: '@test:example.com',
type: 'm.room.pinned_events', type: 'm.room.pinned_events',
roomId: room.id, roomId: room.id,
@ -165,9 +174,11 @@ void main() {
content: { content: {
'pinned': ['1234'] 'pinned': ['1234']
}, },
stateKey: ''); stateKey: ''),
);
expect(room.pinnedEventIds.first, '1234'); expect(room.pinnedEventIds.first, '1234');
room.states['m.room.message'] = Event( room.setState(
Event(
senderId: '@test:example.com', senderId: '@test:example.com',
type: 'm.room.message', type: 'm.room.message',
roomId: room.id, roomId: room.id,
@ -175,14 +186,16 @@ void main() {
eventId: '12345', eventId: '12345',
originServerTs: DateTime.now(), originServerTs: DateTime.now(),
content: {'msgtype': 'm.text', 'body': 'test'}, content: {'msgtype': 'm.text', 'body': 'test'},
stateKey: ''); stateKey: ''),
);
expect(room.lastEvent.eventId, '12345'); expect(room.lastEvent.eventId, '12345');
expect(room.lastEvent.body, 'test'); expect(room.lastEvent.body, 'test');
expect(room.timeCreated, room.lastEvent.originServerTs); expect(room.timeCreated, room.lastEvent.originServerTs);
}); });
test('multiple last event with same sort order', () { test('multiple last event with same sort order', () {
room.states['m.room.encrypted'] = Event( room.setState(
Event(
senderId: '@test:example.com', senderId: '@test:example.com',
type: 'm.room.encrypted', type: 'm.room.encrypted',
roomId: room.id, roomId: room.id,
@ -191,9 +204,11 @@ void main() {
originServerTs: DateTime.now(), originServerTs: DateTime.now(),
content: {'msgtype': 'm.text', 'body': 'test'}, content: {'msgtype': 'm.text', 'body': 'test'},
stateKey: '', stateKey: '',
sortOrder: 42.0); sortOrder: 42.0),
);
expect(room.lastEvent.type, 'm.room.encrypted'); expect(room.lastEvent.type, 'm.room.encrypted');
room.states['m.room.messge'] = Event( room.setState(
Event(
senderId: '@test:example.com', senderId: '@test:example.com',
type: 'm.room.messge', type: 'm.room.messge',
roomId: room.id, roomId: room.id,
@ -202,7 +217,8 @@ void main() {
originServerTs: DateTime.now(), originServerTs: DateTime.now(),
content: {'msgtype': 'm.text', 'body': 'test'}, content: {'msgtype': 'm.text', 'body': 'test'},
stateKey: '', stateKey: '',
sortOrder: 42.0); sortOrder: 42.0),
);
expect(room.lastEvent.type, 'm.room.encrypted'); expect(room.lastEvent.type, 'm.room.encrypted');
}); });
@ -249,7 +265,8 @@ void main() {
}); });
test('PowerLevels', () async { test('PowerLevels', () async {
room.states['m.room.power_levels'] = Event( room.setState(
Event(
senderId: '@test:example.com', senderId: '@test:example.com',
type: 'm.room.power_levels', type: 'm.room.power_levels',
roomId: room.id, roomId: room.id,
@ -267,7 +284,8 @@ void main() {
'users': {'@test:fakeServer.notExisting': 100}, 'users': {'@test:fakeServer.notExisting': 100},
'users_default': 10 'users_default': 10
}, },
stateKey: ''); stateKey: ''),
);
expect(room.ownPowerLevel, 100); expect(room.ownPowerLevel, 100);
expect(room.getPowerLevelByUserId(matrix.userID), room.ownPowerLevel); expect(room.getPowerLevelByUserId(matrix.userID), room.ownPowerLevel);
expect(room.getPowerLevelByUserId('@nouser:example.com'), 10); 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.power_levels'), true);
expect(room.canSendEvent('m.room.member'), true); expect(room.canSendEvent('m.room.member'), true);
expect(room.powerLevels, 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', senderId: '@test:example.com',
type: 'm.room.power_levels', type: 'm.room.power_levels',
roomId: room.id, roomId: room.id,
@ -303,7 +322,10 @@ void main() {
'users': {}, 'users': {},
'users_default': 0 'users_default': 0
}, },
stateKey: ''); stateKey: '',
sortOrder: 1,
),
);
expect(room.ownPowerLevel, 0); expect(room.ownPowerLevel, 0);
expect(room.canBan, false); expect(room.canBan, false);
expect(room.canInvite, false); expect(room.canInvite, false);

View File

@ -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');
});
});
}