Merge branch 'sdk-refactor-new-linter' into 'master'

[SDK] Refactoring with new linter rules

See merge request famedly/famedlysdk!250
This commit is contained in:
Christian Pauly 2020-03-30 09:08:38 +00:00
commit 0266ab9659
42 changed files with 2827 additions and 2847 deletions

View file

@ -35,8 +35,7 @@ class AccountData {
/// Get a State event from a table row or from the event stream. /// Get a State event from a table row or from the event stream.
factory AccountData.fromJson(Map<String, dynamic> jsonPayload) { factory AccountData.fromJson(Map<String, dynamic> jsonPayload) {
final Map<String, dynamic> content = final content = Event.getMapFromPayload(jsonPayload['content']);
Event.getMapFromPayload(jsonPayload['content']);
return AccountData(content: content, typeKey: jsonPayload['type']); return AccountData(content: content, typeKey: jsonPayload['type']);
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -47,7 +47,7 @@ class Event {
/// The user who has sent this event if it is not a global account data event. /// The user who has sent this event if it is not a global account data event.
final String senderId; final String senderId;
User get sender => room.getUserByMXIDSync(senderId ?? "@unknown"); User get sender => room.getUserByMXIDSync(senderId ?? '@unknown');
/// The time this event has received at the server. May be null for events like /// The time this event has received at the server. May be null for events like
/// account data. /// account data.
@ -78,17 +78,17 @@ class Event {
static const int defaultStatus = 2; static const int defaultStatus = 2;
static const Map<String, int> STATUS_TYPE = { static const Map<String, int> STATUS_TYPE = {
"ERROR": -1, 'ERROR': -1,
"SENDING": 0, 'SENDING': 0,
"SENT": 1, 'SENT': 1,
"TIMELINE": 2, 'TIMELINE': 2,
"ROOM_STATE": 3, 'ROOM_STATE': 3,
}; };
/// Optional. The event that redacted this event, if any. Otherwise null. /// Optional. The event that redacted this event, if any. Otherwise null.
Event get redactedBecause => Event get redactedBecause =>
unsigned != null && unsigned.containsKey("redacted_because") unsigned != null && unsigned.containsKey('redacted_because')
? Event.fromJson(unsigned["redacted_because"], room) ? Event.fromJson(unsigned['redacted_because'], room)
: null; : null;
bool get redacted => redactedBecause != null; bool get redacted => redactedBecause != null;
@ -122,12 +122,9 @@ class Event {
/// Get a State event from a table row or from the event stream. /// Get a State event from a table row or from the event stream.
factory Event.fromJson(Map<String, dynamic> jsonPayload, Room room) { factory Event.fromJson(Map<String, dynamic> jsonPayload, Room room) {
final Map<String, dynamic> content = final content = Event.getMapFromPayload(jsonPayload['content']);
Event.getMapFromPayload(jsonPayload['content']); final unsigned = Event.getMapFromPayload(jsonPayload['unsigned']);
final Map<String, dynamic> unsigned = final prevContent = Event.getMapFromPayload(jsonPayload['prev_content']);
Event.getMapFromPayload(jsonPayload['unsigned']);
final Map<String, dynamic> prevContent =
Event.getMapFromPayload(jsonPayload['prev_content']);
return Event( return Event(
status: jsonPayload['status'] ?? defaultStatus, status: jsonPayload['status'] ?? defaultStatus,
stateKey: jsonPayload['state_key'], stateKey: jsonPayload['state_key'],
@ -146,19 +143,19 @@ class Event {
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>(); final data = <String, dynamic>{};
if (this.stateKey != null) data['state_key'] = this.stateKey; if (stateKey != null) data['state_key'] = stateKey;
if (this.prevContent != null && this.prevContent.isNotEmpty) { if (prevContent != null && prevContent.isNotEmpty) {
data['prev_content'] = this.prevContent; data['prev_content'] = prevContent;
} }
data['content'] = this.content; data['content'] = content;
data['type'] = this.typeKey; data['type'] = typeKey;
data['event_id'] = this.eventId; data['event_id'] = eventId;
data['room_id'] = this.roomId; data['room_id'] = roomId;
data['sender'] = this.senderId; data['sender'] = senderId;
data['origin_server_ts'] = this.time.millisecondsSinceEpoch; data['origin_server_ts'] = time.millisecondsSinceEpoch;
if (this.unsigned != null && this.unsigned.isNotEmpty) { if (unsigned != null && unsigned.isNotEmpty) {
data['unsigned'] = this.unsigned; data['unsigned'] = unsigned;
} }
return data; return data;
} }
@ -183,45 +180,45 @@ class Event {
/// Get the real type. /// Get the real type.
EventTypes get type { EventTypes get type {
switch (typeKey) { switch (typeKey) {
case "m.room.avatar": case 'm.room.avatar':
return EventTypes.RoomAvatar; return EventTypes.RoomAvatar;
case "m.room.name": case 'm.room.name':
return EventTypes.RoomName; return EventTypes.RoomName;
case "m.room.topic": case 'm.room.topic':
return EventTypes.RoomTopic; return EventTypes.RoomTopic;
case "m.room.aliases": case 'm.room.aliases':
return EventTypes.RoomAliases; return EventTypes.RoomAliases;
case "m.room.canonical_alias": case 'm.room.canonical_alias':
return EventTypes.RoomCanonicalAlias; return EventTypes.RoomCanonicalAlias;
case "m.room.create": case 'm.room.create':
return EventTypes.RoomCreate; return EventTypes.RoomCreate;
case "m.room.redaction": case 'm.room.redaction':
return EventTypes.Redaction; return EventTypes.Redaction;
case "m.room.join_rules": case 'm.room.join_rules':
return EventTypes.RoomJoinRules; return EventTypes.RoomJoinRules;
case "m.room.member": case 'm.room.member':
return EventTypes.RoomMember; return EventTypes.RoomMember;
case "m.room.power_levels": case 'm.room.power_levels':
return EventTypes.RoomPowerLevels; return EventTypes.RoomPowerLevels;
case "m.room.guest_access": case 'm.room.guest_access':
return EventTypes.GuestAccess; return EventTypes.GuestAccess;
case "m.room.history_visibility": case 'm.room.history_visibility':
return EventTypes.HistoryVisibility; return EventTypes.HistoryVisibility;
case "m.sticker": case 'm.sticker':
return EventTypes.Sticker; return EventTypes.Sticker;
case "m.room.message": case 'm.room.message':
return EventTypes.Message; return EventTypes.Message;
case "m.room.encrypted": case 'm.room.encrypted':
return EventTypes.Encrypted; return EventTypes.Encrypted;
case "m.room.encryption": case 'm.room.encryption':
return EventTypes.Encryption; return EventTypes.Encryption;
case "m.call.invite": case 'm.call.invite':
return EventTypes.CallInvite; return EventTypes.CallInvite;
case "m.call.answer": case 'm.call.answer':
return EventTypes.CallAnswer; return EventTypes.CallAnswer;
case "m.call.candidates": case 'm.call.candidates':
return EventTypes.CallCandidates; return EventTypes.CallCandidates;
case "m.call.hangup": case 'm.call.hangup':
return EventTypes.CallHangup; return EventTypes.CallHangup;
} }
return EventTypes.Unknown; return EventTypes.Unknown;
@ -229,29 +226,29 @@ class Event {
/// ///
MessageTypes get messageType { MessageTypes get messageType {
switch (content["msgtype"] ?? "m.text") { switch (content['msgtype'] ?? 'm.text') {
case "m.text": case 'm.text':
if (content.containsKey("m.relates_to")) { if (content.containsKey('m.relates_to')) {
return MessageTypes.Reply; return MessageTypes.Reply;
} }
return MessageTypes.Text; return MessageTypes.Text;
case "m.notice": case 'm.notice':
return MessageTypes.Notice; return MessageTypes.Notice;
case "m.emote": case 'm.emote':
return MessageTypes.Emote; return MessageTypes.Emote;
case "m.image": case 'm.image':
return MessageTypes.Image; return MessageTypes.Image;
case "m.video": case 'm.video':
return MessageTypes.Video; return MessageTypes.Video;
case "m.audio": case 'm.audio':
return MessageTypes.Audio; return MessageTypes.Audio;
case "m.file": case 'm.file':
return MessageTypes.File; return MessageTypes.File;
case "m.sticker": case 'm.sticker':
return MessageTypes.Sticker; return MessageTypes.Sticker;
case "m.location": case 'm.location':
return MessageTypes.Location; return MessageTypes.Location;
case "m.bad.encrypted": case 'm.bad.encrypted':
return MessageTypes.BadEncrypted; return MessageTypes.BadEncrypted;
default: default:
if (type == EventTypes.Message) { if (type == EventTypes.Message) {
@ -263,40 +260,40 @@ class Event {
void setRedactionEvent(Event redactedBecause) { void setRedactionEvent(Event redactedBecause) {
unsigned = { unsigned = {
"redacted_because": redactedBecause.toJson(), 'redacted_because': redactedBecause.toJson(),
}; };
prevContent = null; prevContent = null;
List<String> contentKeyWhiteList = []; var contentKeyWhiteList = <String>[];
switch (type) { switch (type) {
case EventTypes.RoomMember: case EventTypes.RoomMember:
contentKeyWhiteList.add("membership"); contentKeyWhiteList.add('membership');
break; break;
case EventTypes.RoomCreate: case EventTypes.RoomCreate:
contentKeyWhiteList.add("creator"); contentKeyWhiteList.add('creator');
break; break;
case EventTypes.RoomJoinRules: case EventTypes.RoomJoinRules:
contentKeyWhiteList.add("join_rule"); contentKeyWhiteList.add('join_rule');
break; break;
case EventTypes.RoomPowerLevels: case EventTypes.RoomPowerLevels:
contentKeyWhiteList.add("ban"); contentKeyWhiteList.add('ban');
contentKeyWhiteList.add("events"); contentKeyWhiteList.add('events');
contentKeyWhiteList.add("events_default"); contentKeyWhiteList.add('events_default');
contentKeyWhiteList.add("kick"); contentKeyWhiteList.add('kick');
contentKeyWhiteList.add("redact"); contentKeyWhiteList.add('redact');
contentKeyWhiteList.add("state_default"); contentKeyWhiteList.add('state_default');
contentKeyWhiteList.add("users"); contentKeyWhiteList.add('users');
contentKeyWhiteList.add("users_default"); contentKeyWhiteList.add('users_default');
break; break;
case EventTypes.RoomAliases: case EventTypes.RoomAliases:
contentKeyWhiteList.add("aliases"); contentKeyWhiteList.add('aliases');
break; break;
case EventTypes.HistoryVisibility: case EventTypes.HistoryVisibility:
contentKeyWhiteList.add("history_visibility"); contentKeyWhiteList.add('history_visibility');
break; break;
default: default:
break; break;
} }
List<String> toRemoveList = []; var toRemoveList = <String>[];
for (var entry in content.entries) { for (var entry in content.entries) {
if (!contentKeyWhiteList.contains(entry.key)) { if (!contentKeyWhiteList.contains(entry.key)) {
toRemoveList.add(entry.key); toRemoveList.add(entry.key);
@ -306,30 +303,30 @@ class Event {
} }
/// Returns the body of this event if it has a body. /// Returns the body of this event if it has a body.
String get text => content["body"] ?? ""; String get text => content['body'] ?? '';
/// Returns the formatted boy of this event if it has a formatted body. /// Returns the formatted boy of this event if it has a formatted body.
String get formattedText => content["formatted_body"] ?? ""; String get formattedText => content['formatted_body'] ?? '';
@Deprecated("Use [body] instead.") @Deprecated('Use [body] instead.')
String getBody() => body; String getBody() => body;
/// Use this to get the body. /// Use this to get the body.
String get body { String get body {
if (redacted) return "Redacted"; if (redacted) return 'Redacted';
if (text != "") return text; if (text != '') return text;
if (formattedText != "") return formattedText; if (formattedText != '') return formattedText;
return "$type"; return '$type';
} }
/// Returns a list of [Receipt] instances for this event. /// Returns a list of [Receipt] instances for this event.
List<Receipt> get receipts { List<Receipt> get receipts {
if (!(room.roomAccountData.containsKey("m.receipt"))) return []; if (!(room.roomAccountData.containsKey('m.receipt'))) return [];
List<Receipt> receiptsList = []; var receiptsList = <Receipt>[];
for (var entry in room.roomAccountData["m.receipt"].content.entries) { for (var entry in room.roomAccountData['m.receipt'].content.entries) {
if (entry.value["event_id"] == eventId) { if (entry.value['event_id'] == eventId) {
receiptsList.add(Receipt(room.getUserByMXIDSync(entry.key), receiptsList.add(Receipt(room.getUserByMXIDSync(entry.key),
DateTime.fromMillisecondsSinceEpoch(entry.value["ts"]))); DateTime.fromMillisecondsSinceEpoch(entry.value['ts'])));
} }
} }
return receiptsList; return receiptsList;
@ -345,12 +342,12 @@ class Event {
room.client.onEvent.add(EventUpdate( room.client.onEvent.add(EventUpdate(
roomID: room.id, roomID: room.id,
type: "timeline", type: 'timeline',
eventType: typeKey, eventType: typeKey,
content: { content: {
"event_id": eventId, 'event_id': eventId,
"status": -2, 'status': -2,
"content": {"body": "Removed..."} 'content': {'body': 'Removed...'}
})); }));
return true; return true;
} }
@ -361,7 +358,7 @@ class Event {
Future<String> sendAgain({String txid}) async { Future<String> sendAgain({String txid}) async {
if (status != -1) return null; if (status != -1) return null;
await remove(); await remove();
final String eventID = await room.sendTextEvent(text, txid: txid); final eventID = await room.sendTextEvent(text, txid: txid);
return eventID; return eventID;
} }
@ -397,34 +394,34 @@ class Event {
/// in the room. If the event is not encrypted or the decryption failed because /// in the room. If the event is not encrypted or the decryption failed because
/// of a different error, this throws an exception. /// of a different error, this throws an exception.
Future<void> requestKey() async { Future<void> requestKey() async {
if (this.type != EventTypes.Encrypted || if (type != EventTypes.Encrypted ||
this.messageType != MessageTypes.BadEncrypted || messageType != MessageTypes.BadEncrypted ||
this.content["body"] != DecryptError.UNKNOWN_SESSION) { content['body'] != DecryptError.UNKNOWN_SESSION) {
throw ("Session key not unknown"); throw ('Session key not unknown');
} }
final List<User> users = await room.requestParticipants(); final users = await room.requestParticipants();
await room.client.sendToDevice( await room.client.sendToDevice(
[], [],
"m.room_key_request", 'm.room_key_request',
{ {
"action": "request_cancellation", 'action': 'request_cancellation',
"request_id": base64.encode(utf8.encode(content["session_id"])), 'request_id': base64.encode(utf8.encode(content['session_id'])),
"requesting_device_id": room.client.deviceID, 'requesting_device_id': room.client.deviceID,
}, },
toUsers: users); toUsers: users);
await room.client.sendToDevice( await room.client.sendToDevice(
[], [],
"m.room_key_request", 'm.room_key_request',
{ {
"action": "request", 'action': 'request',
"body": { 'body': {
"algorithm": "m.megolm.v1.aes-sha2", 'algorithm': 'm.megolm.v1.aes-sha2',
"room_id": roomId, 'room_id': roomId,
"sender_key": content["sender_key"], 'sender_key': content['sender_key'],
"session_id": content["session_id"], 'session_id': content['session_id'],
}, },
"request_id": base64.encode(utf8.encode(content["session_id"])), 'request_id': base64.encode(utf8.encode(content['session_id'])),
"requesting_device_id": room.client.deviceID, 'requesting_device_id': room.client.deviceID,
}, },
encrypted: false, encrypted: false,
toUsers: users); toUsers: users);
@ -435,27 +432,27 @@ class Event {
/// event and returns it as a [MatrixFile]. If this event doesn't /// event and returns it as a [MatrixFile]. If this event doesn't
/// contain an attachment, this throws an error. /// contain an attachment, this throws an error.
Future<MatrixFile> downloadAndDecryptAttachment() async { Future<MatrixFile> downloadAndDecryptAttachment() async {
if (![EventTypes.Message, EventTypes.Sticker].contains(this.type)) { if (![EventTypes.Message, EventTypes.Sticker].contains(type)) {
throw ("This event has the type '$typeKey' and so it can't contain an attachment."); throw ("This event has the type '$typeKey' and so it can't contain an attachment.");
} }
if (!content.containsKey("url") && !content.containsKey("file")) { if (!content.containsKey('url') && !content.containsKey('file')) {
throw ("This event hasn't any attachment."); throw ("This event hasn't any attachment.");
} }
final bool isEncrypted = !content.containsKey("url"); final isEncrypted = !content.containsKey('url');
if (isEncrypted && !room.client.encryptionEnabled) { if (isEncrypted && !room.client.encryptionEnabled) {
throw ("Encryption is not enabled in your Client."); throw ('Encryption is not enabled in your Client.');
} }
MxContent mxContent = var mxContent =
MxContent(isEncrypted ? content["file"]["url"] : content["url"]); MxContent(isEncrypted ? content['file']['url'] : content['url']);
Uint8List uint8list; Uint8List uint8list;
// Is this file storeable? // Is this file storeable?
final bool storeable = room.client.storeAPI.extended && final storeable = room.client.storeAPI.extended &&
content["info"] is Map<String, dynamic> && content['info'] is Map<String, dynamic> &&
content["info"]["size"] is int && content['info']['size'] is int &&
content["info"]["size"] <= ExtendedStoreAPI.MAX_FILE_SIZE; content['info']['size'] <= ExtendedStoreAPI.MAX_FILE_SIZE;
if (storeable) { if (storeable) {
uint8list = await room.client.store.getFile(mxContent.mxc); uint8list = await room.client.store.getFile(mxContent.mxc);
@ -470,18 +467,18 @@ class Event {
// Decrypt the file // Decrypt the file
if (isEncrypted) { if (isEncrypted) {
if (!content.containsKey("file") || if (!content.containsKey('file') ||
!content["file"]["key"]["key_ops"].contains("decrypt")) { !content['file']['key']['key_ops'].contains('decrypt')) {
throw ("Missing 'decrypt' in 'key_ops'."); throw ("Missing 'decrypt' in 'key_ops'.");
} }
final EncryptedFile encryptedFile = EncryptedFile(); final encryptedFile = EncryptedFile();
encryptedFile.data = uint8list; encryptedFile.data = uint8list;
encryptedFile.iv = content["file"]["iv"]; encryptedFile.iv = content['file']['iv'];
encryptedFile.k = content["file"]["key"]["k"]; encryptedFile.k = content['file']['key']['k'];
encryptedFile.sha256 = content["file"]["hashes"]["sha256"]; encryptedFile.sha256 = content['file']['hashes']['sha256'];
uint8list = await decryptFile(encryptedFile); uint8list = await decryptFile(encryptedFile);
} }
return MatrixFile(bytes: uint8list, path: "/$body"); return MatrixFile(bytes: uint8list, path: '/$body');
} }
} }

View file

@ -44,7 +44,7 @@ class Presence {
Presence.fromJson(Map<String, dynamic> json) Presence.fromJson(Map<String, dynamic> json)
: sender = json['sender'], : sender = json['sender'],
displayname = json['content']['displayname'], displayname = json['content']['displayname'],
avatarUrl = MxContent(json['content']['avatar_url'] ?? ""), avatarUrl = MxContent(json['content']['avatar_url'] ?? ''),
currentlyActive = json['content']['currently_active'], currentlyActive = json['content']['currently_active'],
lastActiveAgo = json['content']['last_active_ago'], lastActiveAgo = json['content']['last_active_ago'],
time = DateTime.fromMillisecondsSinceEpoch( time = DateTime.fromMillisecondsSinceEpoch(

File diff suppressed because it is too large Load diff

View file

@ -39,8 +39,7 @@ class RoomAccountData extends AccountData {
/// Get a State event from a table row or from the event stream. /// Get a State event from a table row or from the event stream.
factory RoomAccountData.fromJson( factory RoomAccountData.fromJson(
Map<String, dynamic> jsonPayload, Room room) { Map<String, dynamic> jsonPayload, Room room) {
final Map<String, dynamic> content = final content = Event.getMapFromPayload(jsonPayload['content']);
Event.getMapFromPayload(jsonPayload['content']);
return RoomAccountData( return RoomAccountData(
content: content, content: content,
typeKey: jsonPayload['type'], typeKey: jsonPayload['type'],

View file

@ -66,13 +66,14 @@ abstract class ExtendedStoreAPI extends StoreAPI {
/// Whether this is a simple store which only stores the client credentials and /// Whether this is a simple store which only stores the client credentials and
/// end to end encryption stuff or the whole sync payloads. /// end to end encryption stuff or the whole sync payloads.
@override
final bool extended = true; final bool extended = true;
/// The current trans /// The current trans
Future<void> setRoomPrevBatch(String roomId, String prevBatch); Future<void> setRoomPrevBatch(String roomId, String prevBatch);
/// Performs these query or queries inside of an transaction. /// Performs these query or queries inside of an transaction.
Future<void> transaction(void queries()); Future<void> transaction(void Function() queries);
/// Will be automatically called on every synchronisation. Must be called inside of /// Will be automatically called on every synchronisation. Must be called inside of
// /// [transaction]. // /// [transaction].

View file

@ -43,11 +43,11 @@ class EventUpdate {
EventUpdate({this.eventType, this.roomID, this.type, this.content}); EventUpdate({this.eventType, this.roomID, this.type, this.content});
EventUpdate decrypt(Room room) { EventUpdate decrypt(Room room) {
if (eventType != "m.room.encrypted") { if (eventType != 'm.room.encrypted') {
return this; return this;
} }
try { try {
Event decrpytedEvent = var decrpytedEvent =
room.decryptGroupMessage(Event.fromJson(content, room)); room.decryptGroupMessage(Event.fromJson(content, room));
return EventUpdate( return EventUpdate(
eventType: eventType, eventType: eventType,
@ -56,7 +56,7 @@ class EventUpdate {
content: decrpytedEvent.toJson(), content: decrpytedEvent.toJson(),
); );
} catch (e) { } catch (e) {
print("[LibOlm] Could not decrypt megolm event: " + e.toString()); print('[LibOlm] Could not decrypt megolm event: ' + e.toString());
return this; return this;
} }
} }

View file

@ -25,7 +25,6 @@ import 'dart:async';
import 'event.dart'; import 'event.dart';
import 'room.dart'; import 'room.dart';
import 'user.dart';
import 'sync/event_update.dart'; import 'sync/event_update.dart';
typedef onTimelineUpdateCallback = void Function(); typedef onTimelineUpdateCallback = void Function();
@ -45,17 +44,17 @@ class Timeline {
StreamSubscription<String> sessionIdReceivedSub; StreamSubscription<String> sessionIdReceivedSub;
bool _requestingHistoryLock = false; bool _requestingHistoryLock = false;
Map<String, Event> _eventCache = {}; final Map<String, Event> _eventCache = {};
/// Searches for the event in this timeline. If not /// Searches for the event in this timeline. If not
/// found, requests from the server. Requested events /// found, requests from the server. Requested events
/// are cached. /// are cached.
Future<Event> getEventById(String id) async { Future<Event> getEventById(String id) async {
for (int i = 0; i < events.length; i++) { for (var i = 0; i < events.length; i++) {
if (events[i].eventId == id) return events[i]; if (events[i].eventId == id) return events[i];
} }
if (_eventCache.containsKey(id)) return _eventCache[id]; if (_eventCache.containsKey(id)) return _eventCache[id];
final Event requestedEvent = await room.getEventById(id); final requestedEvent = await room.getEventById(id);
if (requestedEvent == null) return null; if (requestedEvent == null) return null;
_eventCache[id] = requestedEvent; _eventCache[id] = requestedEvent;
return _eventCache[id]; return _eventCache[id];
@ -89,12 +88,12 @@ class Timeline {
} }
void _sessionKeyReceived(String sessionId) { void _sessionKeyReceived(String sessionId) {
bool decryptAtLeastOneEvent = false; var decryptAtLeastOneEvent = false;
for (int i = 0; i < events.length; i++) { for (var i = 0; i < events.length; i++) {
if (events[i].type == EventTypes.Encrypted && if (events[i].type == EventTypes.Encrypted &&
events[i].messageType == MessageTypes.BadEncrypted && events[i].messageType == MessageTypes.BadEncrypted &&
events[i].content["body"] == DecryptError.UNKNOWN_SESSION && events[i].content['body'] == DecryptError.UNKNOWN_SESSION &&
events[i].content["session_id"] == sessionId) { events[i].content['session_id'] == sessionId) {
events[i] = events[i].decrypted; events[i] = events[i].decrypted;
if (events[i].type != EventTypes.Encrypted) { if (events[i].type != EventTypes.Encrypted) {
decryptAtLeastOneEvent = true; decryptAtLeastOneEvent = true;
@ -117,26 +116,25 @@ class Timeline {
try { try {
if (eventUpdate.roomID != room.id) return; if (eventUpdate.roomID != room.id) return;
if (eventUpdate.type == "timeline" || eventUpdate.type == "history") { if (eventUpdate.type == 'timeline' || eventUpdate.type == 'history') {
// Redaction events are handled as modification for existing events. // Redaction events are handled as modification for existing events.
if (eventUpdate.eventType == "m.room.redaction") { if (eventUpdate.eventType == 'm.room.redaction') {
final int eventId = final eventId = _findEvent(event_id: eventUpdate.content['redacts']);
_findEvent(event_id: eventUpdate.content["redacts"]);
if (eventId != null) { if (eventId != null) {
events[eventId] events[eventId]
.setRedactionEvent(Event.fromJson(eventUpdate.content, room)); .setRedactionEvent(Event.fromJson(eventUpdate.content, room));
} }
} else if (eventUpdate.content["status"] == -2) { } else if (eventUpdate.content['status'] == -2) {
int i = _findEvent(event_id: eventUpdate.content["event_id"]); var i = _findEvent(event_id: eventUpdate.content['event_id']);
if (i < events.length) events.removeAt(i); if (i < events.length) events.removeAt(i);
} }
// Is this event already in the timeline? // Is this event already in the timeline?
else if (eventUpdate.content.containsKey("unsigned") && else if (eventUpdate.content.containsKey('unsigned') &&
eventUpdate.content["unsigned"]["transaction_id"] is String) { eventUpdate.content['unsigned']['transaction_id'] is String) {
int i = _findEvent( var i = _findEvent(
event_id: eventUpdate.content["event_id"], event_id: eventUpdate.content['event_id'],
unsigned_txid: eventUpdate.content.containsKey("unsigned") unsigned_txid: eventUpdate.content.containsKey('unsigned')
? eventUpdate.content["unsigned"]["transaction_id"] ? eventUpdate.content['unsigned']['transaction_id']
: null); : null);
if (i < events.length) { if (i < events.length) {
@ -144,18 +142,18 @@ class Timeline {
} }
} else { } else {
Event newEvent; Event newEvent;
User senderUser = await room.client.store var senderUser = await room.client.store
?.getUser(matrixID: eventUpdate.content["sender"], room: room); ?.getUser(matrixID: eventUpdate.content['sender'], room: room);
if (senderUser != null) { if (senderUser != null) {
eventUpdate.content["displayname"] = senderUser.displayName; eventUpdate.content['displayname'] = senderUser.displayName;
eventUpdate.content["avatar_url"] = senderUser.avatarUrl.mxc; eventUpdate.content['avatar_url'] = senderUser.avatarUrl.mxc;
} }
newEvent = Event.fromJson(eventUpdate.content, room); newEvent = Event.fromJson(eventUpdate.content, room);
if (eventUpdate.type == "history" && if (eventUpdate.type == 'history' &&
events.indexWhere( events.indexWhere(
(e) => e.eventId == eventUpdate.content["event_id"]) != (e) => e.eventId == eventUpdate.content['event_id']) !=
-1) return; -1) return;
events.insert(0, newEvent); events.insert(0, newEvent);
@ -165,14 +163,14 @@ class Timeline {
sortAndUpdate(); sortAndUpdate();
} catch (e) { } catch (e) {
if (room.client.debug) { if (room.client.debug) {
print("[WARNING] (_handleEventUpdate) ${e.toString()}"); print('[WARNING] (_handleEventUpdate) ${e.toString()}');
} }
} }
} }
bool sortLock = false; bool sortLock = false;
sort() { void sort() {
if (sortLock || events.length < 2) return; if (sortLock || events.length < 2) return;
sortLock = true; sortLock = true;
events?.sort((a, b) => events?.sort((a, b) =>
@ -180,7 +178,7 @@ class Timeline {
sortLock = false; sortLock = false;
} }
sortAndUpdate() { void sortAndUpdate() async {
sort(); sort();
if (onUpdate != null) onUpdate(); if (onUpdate != null) onUpdate();
} }

View file

@ -37,14 +37,14 @@ class User extends Event {
String avatarUrl, String avatarUrl,
Room room, Room room,
}) { }) {
Map<String, String> content = {}; var content = <String, String>{};
if (membership != null) content["membership"] = membership; if (membership != null) content['membership'] = membership;
if (displayName != null) content["displayname"] = displayName; if (displayName != null) content['displayname'] = displayName;
if (avatarUrl != null) content["avatar_url"] = avatarUrl; if (avatarUrl != null) content['avatar_url'] = avatarUrl;
return User.fromState( return User.fromState(
stateKey: id, stateKey: id,
content: content, content: content,
typeKey: "m.room.member", typeKey: 'm.room.member',
roomId: room?.id, roomId: room?.id,
room: room, room: room,
time: DateTime.now(), time: DateTime.now(),
@ -78,7 +78,7 @@ class User extends Event {
String get id => stateKey; String get id => stateKey;
/// The displayname of the user if the user has set one. /// The displayname of the user if the user has set one.
String get displayName => content != null ? content["displayname"] : null; String get displayName => content != null ? content['displayname'] : null;
/// Returns the power level of this user. /// Returns the power level of this user.
int get powerLevel => room?.getPowerLevelByUserId(id); int get powerLevel => room?.getPowerLevelByUserId(id);
@ -89,21 +89,21 @@ class User extends Event {
/// leave /// leave
/// ban /// ban
Membership get membership => Membership.values.firstWhere((e) { Membership get membership => Membership.values.firstWhere((e) {
if (content["membership"] != null) { if (content['membership'] != null) {
return e.toString() == 'Membership.' + content['membership']; return e.toString() == 'Membership.' + content['membership'];
} }
return false; return false;
}, orElse: () => Membership.join); }, orElse: () => Membership.join);
/// The avatar if the user has one. /// The avatar if the user has one.
MxContent get avatarUrl => content != null && content["avatar_url"] is String MxContent get avatarUrl => content != null && content['avatar_url'] is String
? MxContent(content["avatar_url"]) ? MxContent(content['avatar_url'])
: MxContent(""); : MxContent('');
/// Returns the displayname or the local part of the Matrix ID if the user /// Returns the displayname or the local part of the Matrix ID if the user
/// has no displayname. /// has no displayname.
String calcDisplayname() => (displayName == null || displayName.isEmpty) String calcDisplayname() => (displayName == null || displayName.isEmpty)
? (stateKey != null ? stateKey.localpart : "Unknown User") ? (stateKey != null ? stateKey.localpart : 'Unknown User')
: displayName; : displayName;
/// Call the Matrix API to kick this user from this room. /// Call the Matrix API to kick this user from this room.
@ -122,20 +122,20 @@ class User extends Event {
/// Returns null on error. /// Returns null on error.
Future<String> startDirectChat() async { Future<String> startDirectChat() async {
// Try to find an existing direct chat // Try to find an existing direct chat
String roomID = await room.client?.getDirectChatFromUserId(id); var roomID = await room.client?.getDirectChatFromUserId(id);
if (roomID != null) return roomID; if (roomID != null) return roomID;
// Start a new direct chat // Start a new direct chat
final dynamic resp = await room.client.jsonRequest( final dynamic resp = await room.client.jsonRequest(
type: HTTPType.POST, type: HTTPType.POST,
action: "/client/r0/createRoom", action: '/client/r0/createRoom',
data: { data: {
"invite": [id], 'invite': [id],
"is_direct": true, 'is_direct': true,
"preset": "trusted_private_chat" 'preset': 'trusted_private_chat'
}); });
final String newRoomID = resp["room_id"]; final String newRoomID = resp['room_id'];
if (newRoomID == null) return newRoomID; if (newRoomID == null) return newRoomID;

View file

@ -1,7 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import '../client.dart'; import '../client.dart';
import '../room.dart';
class DeviceKeysList { class DeviceKeysList {
String userId; String userId;
@ -19,18 +18,20 @@ class DeviceKeysList {
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>(); var map = <String, dynamic>{};
data['user_id'] = this.userId; final data = map;
data['outdated'] = this.outdated ?? true; data['user_id'] = userId;
data['outdated'] = outdated ?? true;
Map<String, dynamic> rawDeviceKeys = {}; var rawDeviceKeys = <String, dynamic>{};
for (final deviceKeyEntry in this.deviceKeys.entries) { for (final deviceKeyEntry in deviceKeys.entries) {
rawDeviceKeys[deviceKeyEntry.key] = deviceKeyEntry.value.toJson(); rawDeviceKeys[deviceKeyEntry.key] = deviceKeyEntry.value.toJson();
} }
data['device_keys'] = rawDeviceKeys; data['device_keys'] = rawDeviceKeys;
return data; return data;
} }
@override
String toString() => json.encode(toJson()); String toString() => json.encode(toJson());
DeviceKeysList(this.userId); DeviceKeysList(this.userId);
@ -46,8 +47,8 @@ class DeviceKeys {
bool verified; bool verified;
bool blocked; bool blocked;
String get curve25519Key => keys["curve25519:$deviceId"]; String get curve25519Key => keys['curve25519:$deviceId'];
String get ed25519Key => keys["ed25519:$deviceId"]; String get ed25519Key => keys['ed25519:$deviceId'];
Future<void> setVerified(bool newVerified, Client client) { Future<void> setVerified(bool newVerified, Client client) {
verified = newVerified; verified = newVerified;
@ -56,7 +57,7 @@ class DeviceKeys {
Future<void> setBlocked(bool newBlocked, Client client) { Future<void> setBlocked(bool newBlocked, Client client) {
blocked = newBlocked; blocked = newBlocked;
for (Room room in client.rooms) { for (var room in client.rooms) {
if (!room.encrypted) continue; if (!room.encrypted) continue;
if (room.getParticipants().indexWhere((u) => u.id == userId) != -1) { if (room.getParticipants().indexWhere((u) => u.id == userId) != -1) {
room.clearOutboundGroupSession(); room.clearOutboundGroupSession();
@ -92,21 +93,21 @@ class DeviceKeys {
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>(); final data = <String, dynamic>{};
data['user_id'] = this.userId; data['user_id'] = userId;
data['device_id'] = this.deviceId; data['device_id'] = deviceId;
data['algorithms'] = this.algorithms; data['algorithms'] = algorithms;
if (this.keys != null) { if (keys != null) {
data['keys'] = this.keys; data['keys'] = keys;
} }
if (this.signatures != null) { if (signatures != null) {
data['signatures'] = this.signatures; data['signatures'] = signatures;
} }
if (this.unsigned != null) { if (unsigned != null) {
data['unsigned'] = this.unsigned; data['unsigned'] = unsigned;
} }
data['verified'] = this.verified; data['verified'] = verified;
data['blocked'] = this.blocked; data['blocked'] = blocked;
return data; return data;
} }
} }

View file

@ -48,34 +48,34 @@ class MatrixException implements Exception {
/// The unique identifier for this error. /// The unique identifier for this error.
String get errcode => String get errcode =>
raw["errcode"] ?? raw['errcode'] ??
(requireAdditionalAuthentication ? "M_FORBIDDEN" : "M_UNKNOWN"); (requireAdditionalAuthentication ? 'M_FORBIDDEN' : 'M_UNKNOWN');
/// A human readable error description. /// A human readable error description.
String get errorMessage => String get errorMessage =>
raw["error"] ?? raw['error'] ??
(requireAdditionalAuthentication (requireAdditionalAuthentication
? "Require additional authentication" ? 'Require additional authentication'
: "Unknown error"); : 'Unknown error');
/// The frozen request which triggered this Error /// The frozen request which triggered this Error
http.Response response; http.Response response;
MatrixException(this.response) : this.raw = json.decode(response.body); MatrixException(this.response) : raw = json.decode(response.body);
@override @override
String toString() => "$errcode: $errorMessage"; String toString() => '$errcode: $errorMessage';
/// Returns the [ResponseError]. Is ResponseError.NONE if there wasn't an error. /// Returns the [ResponseError]. Is ResponseError.NONE if there wasn't an error.
MatrixError get error => MatrixError.values.firstWhere( MatrixError get error => MatrixError.values.firstWhere(
(e) => e.toString() == 'MatrixError.${(raw["errcode"] ?? "")}', (e) => e.toString() == 'MatrixError.${(raw["errcode"] ?? "")}',
orElse: () => MatrixError.M_UNKNOWN); orElse: () => MatrixError.M_UNKNOWN);
int get retryAfterMs => raw["retry_after_ms"]; int get retryAfterMs => raw['retry_after_ms'];
/// This is a session identifier that the client must pass back to the homeserver, if one is provided, /// This is a session identifier that the client must pass back to the homeserver, if one is provided,
/// in subsequent attempts to authenticate in the same API call. /// in subsequent attempts to authenticate in the same API call.
String get session => raw["session"]; String get session => raw['session'];
/// Returns true if the server requires additional authentication. /// Returns true if the server requires additional authentication.
bool get requireAdditionalAuthentication => response.statusCode == 401; bool get requireAdditionalAuthentication => response.statusCode == 401;
@ -84,11 +84,11 @@ class MatrixException implements Exception {
/// to authenticate itself. Each flow comprises a series of stages. If this request /// to authenticate itself. Each flow comprises a series of stages. If this request
/// doesn't need additional authentication, then this is null. /// doesn't need additional authentication, then this is null.
List<AuthenticationFlow> get authenticationFlows { List<AuthenticationFlow> get authenticationFlows {
if (!raw.containsKey("flows") || !(raw["flows"] is List)) return null; if (!raw.containsKey('flows') || !(raw['flows'] is List)) return null;
List<AuthenticationFlow> flows = []; var flows = <AuthenticationFlow>[];
for (Map<String, dynamic> flow in raw["flows"]) { for (Map<String, dynamic> flow in raw['flows']) {
if (flow["stages"] is List) { if (flow['stages'] is List) {
flows.add(AuthenticationFlow(List<String>.from(flow["stages"]))); flows.add(AuthenticationFlow(List<String>.from(flow['stages'])));
} }
} }
return flows; return flows;
@ -97,10 +97,11 @@ class MatrixException implements Exception {
/// This section contains any information that the client will need to know in order to use a given type /// This section contains any information that the client will need to know in order to use a given type
/// of authentication. For each authentication type presented, that type may be present as a key in this /// of authentication. For each authentication type presented, that type may be present as a key in this
/// dictionary. For example, the public part of an OAuth client ID could be given here. /// dictionary. For example, the public part of an OAuth client ID could be given here.
Map<String, dynamic> get authenticationParams => raw["params"]; Map<String, dynamic> get authenticationParams => raw['params'];
/// Returns the list of already completed authentication flows from previous requests. /// Returns the list of already completed authentication flows from previous requests.
List<String> get completedAuthenticationFlows => List<String>.from(raw["completed"] ?? []); List<String> get completedAuthenticationFlows =>
List<String>.from(raw['completed'] ?? []);
} }
/// For each endpoint, a server offers one or more 'flows' that the client can use /// For each endpoint, a server offers one or more 'flows' that the client can use

View file

@ -11,11 +11,12 @@ class MatrixFile {
/// Encrypts this file, changes the [bytes] and returns the /// Encrypts this file, changes the [bytes] and returns the
/// encryption information as an [EncryptedFile]. /// encryption information as an [EncryptedFile].
Future<EncryptedFile> encrypt() async { Future<EncryptedFile> encrypt() async {
final EncryptedFile encryptedFile = await encryptFile(bytes); var encryptFile2 = encryptFile(bytes);
this.bytes = encryptedFile.data; final encryptedFile = await encryptFile2;
bytes = encryptedFile.data;
return encryptedFile; return encryptedFile;
} }
MatrixFile({this.bytes, String path}) : this.path = path.toLowerCase(); MatrixFile({this.bytes, String path}) : path = path.toLowerCase();
int get size => bytes.length; int get size => bytes.length;
} }

View file

@ -1,27 +1,27 @@
extension MatrixIdExtension on String { extension MatrixIdExtension on String {
static const Set<String> VALID_SIGILS = {"@", "!", "#", "\$", "+"}; static const Set<String> VALID_SIGILS = {'@', '!', '#', '\$', '+'};
static const int MAX_LENGTH = 255; static const int MAX_LENGTH = 255;
bool get isValidMatrixId { bool get isValidMatrixId {
if (this?.isEmpty ?? true) return false; if (isEmpty ?? true) return false;
if (this.length > MAX_LENGTH) return false; if (length > MAX_LENGTH) return false;
if (!VALID_SIGILS.contains(this.substring(0, 1))) { if (!VALID_SIGILS.contains(substring(0, 1))) {
return false; return false;
} }
final List<String> parts = this.substring(1).split(":"); final parts = substring(1).split(':');
if (parts.length != 2 || parts[0].isEmpty || parts[1].isEmpty) { if (parts.length != 2 || parts[0].isEmpty || parts[1].isEmpty) {
return false; return false;
} }
return true; return true;
} }
String get sigil => isValidMatrixId ? this.substring(0, 1) : null; String get sigil => isValidMatrixId ? substring(0, 1) : null;
String get localpart => String get localpart =>
isValidMatrixId ? this.substring(1).split(":").first : null; isValidMatrixId ? substring(1).split(':').first : null;
String get domain => isValidMatrixId ? this.substring(1).split(":")[1] : null; String get domain => isValidMatrixId ? substring(1).split(':')[1] : null;
bool equals(String other) => this?.toLowerCase() == other?.toLowerCase(); bool equals(String other) => toLowerCase() == other?.toLowerCase();
} }

View file

@ -29,7 +29,7 @@ class MxContent {
final String _mxc; final String _mxc;
/// Insert a mxc:// uri here. /// Insert a mxc:// uri here.
MxContent(String mxcUrl) : this._mxc = mxcUrl ?? ""; MxContent(String mxcUrl) : _mxc = mxcUrl ?? '';
/// Returns the mxc uri. /// Returns the mxc uri.
String get mxc => _mxc; String get mxc => _mxc;
@ -37,20 +37,20 @@ class MxContent {
/// Returns a download Link to this content. /// Returns a download Link to this content.
String getDownloadLink(Client matrix) => matrix.homeserver != null String getDownloadLink(Client matrix) => matrix.homeserver != null
? "${matrix.homeserver}/_matrix/media/r0/download/${_mxc.replaceFirst("mxc://", "")}" ? "${matrix.homeserver}/_matrix/media/r0/download/${_mxc.replaceFirst("mxc://", "")}"
: ""; : '';
/// Returns a scaled thumbnail link to this content with the given [width] and /// Returns a scaled thumbnail link to this content with the given [width] and
/// [height]. [method] can be [ThumbnailMethod.crop] or /// [height]. [method] can be [ThumbnailMethod.crop] or
/// [ThumbnailMethod.scale] and defaults to [ThumbnailMethod.scale]. /// [ThumbnailMethod.scale] and defaults to [ThumbnailMethod.scale].
String getThumbnail(Client matrix, String getThumbnail(Client matrix,
{num width, num height, ThumbnailMethod method}) { {num width, num height, ThumbnailMethod method}) {
String methodStr = "crop"; var methodStr = 'crop';
if (method == ThumbnailMethod.scale) methodStr = "scale"; if (method == ThumbnailMethod.scale) methodStr = 'scale';
width = width.round(); width = width.round();
height = height.round(); height = height.round();
return matrix.homeserver != null return matrix.homeserver != null
? "${matrix.homeserver}/_matrix/media/r0/thumbnail/${_mxc.replaceFirst("mxc://", "")}?width=$width&height=$height&method=$methodStr" ? "${matrix.homeserver}/_matrix/media/r0/thumbnail/${_mxc.replaceFirst("mxc://", "")}?width=$width&height=$height&method=$methodStr"
: ""; : '';
} }
} }

View file

@ -18,11 +18,12 @@ class OpenIdCredentials {
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>(); var map = <String, dynamic>{};
data['access_token'] = this.accessToken; final data = map;
data['token_type'] = this.tokenType; data['access_token'] = accessToken;
data['matrix_server_name'] = this.matrixServerName; data['token_type'] = tokenType;
data['expires_in'] = this.expiresIn; data['matrix_server_name'] = matrixServerName;
data['expires_in'] = expiresIn;
return data; return data;
} }
} }

View file

@ -16,7 +16,7 @@ class Profile {
displayname = json['displayname'], displayname = json['displayname'],
content = json; content = json;
@override
bool operator ==(dynamic other) => bool operator ==(dynamic other) =>
this.avatarUrl.mxc == other.avatarUrl.mxc && avatarUrl.mxc == other.avatarUrl.mxc && displayname == other.displayname;
this.displayname == other.displayname;
} }

View file

@ -21,7 +21,7 @@ class PublicRoomsResponse {
client = client, client = client,
totalRoomCountEstimate = json['total_room_count_estimate'] { totalRoomCountEstimate = json['total_room_count_estimate'] {
if (json['chunk'] != null) { if (json['chunk'] != null) {
publicRooms = List<PublicRoomEntry>(); publicRooms = <PublicRoomEntry>[];
json['chunk'].forEach((v) { json['chunk'].forEach((v) {
publicRooms.add(PublicRoomEntry.fromJson(v, client)); publicRooms.add(PublicRoomEntry.fromJson(v, client));
}); });

View file

@ -3,7 +3,7 @@ class PushRules {
final GlobalPushRules global; final GlobalPushRules global;
PushRules.fromJson(Map<String, dynamic> json) PushRules.fromJson(Map<String, dynamic> json)
: this.global = GlobalPushRules.fromJson(json["global"]); : global = GlobalPushRules.fromJson(json['global']);
} }
/// The global ruleset. /// The global ruleset.
@ -15,20 +15,20 @@ class GlobalPushRules {
final List<PushRule> underride; final List<PushRule> underride;
GlobalPushRules.fromJson(Map<String, dynamic> json) GlobalPushRules.fromJson(Map<String, dynamic> json)
: this.content = json.containsKey("content") : content = json.containsKey('content')
? PushRule.fromJsonList(json["content"]) ? PushRule.fromJsonList(json['content'])
: null, : null,
this.override = json.containsKey("override") override = json.containsKey('override')
? PushRule.fromJsonList(json["content"]) ? PushRule.fromJsonList(json['content'])
: null, : null,
this.room = json.containsKey("room") room = json.containsKey('room')
? PushRule.fromJsonList(json["room"]) ? PushRule.fromJsonList(json['room'])
: null, : null,
this.sender = json.containsKey("sender") sender = json.containsKey('sender')
? PushRule.fromJsonList(json["sender"]) ? PushRule.fromJsonList(json['sender'])
: null, : null,
this.underride = json.containsKey("underride") underride = json.containsKey('underride')
? PushRule.fromJsonList(json["underride"]) ? PushRule.fromJsonList(json['underride'])
: null; : null;
} }
@ -42,7 +42,7 @@ class PushRule {
final String pattern; final String pattern;
static List<PushRule> fromJsonList(List<dynamic> list) { static List<PushRule> fromJsonList(List<dynamic> list) {
List<PushRule> objList = []; var objList = <PushRule>[];
list.forEach((json) { list.forEach((json) {
objList.add(PushRule.fromJson(json)); objList.add(PushRule.fromJson(json));
}); });
@ -50,14 +50,14 @@ class PushRule {
} }
PushRule.fromJson(Map<String, dynamic> json) PushRule.fromJson(Map<String, dynamic> json)
: this.actions = json["actions"], : actions = json['actions'],
this.isDefault = json["default"], isDefault = json['default'],
this.enabled = json["enabled"], enabled = json['enabled'],
this.ruleId = json["rule_id"], ruleId = json['rule_id'],
this.conditions = json.containsKey("conditions") conditions = json.containsKey('conditions')
? PushRuleConditions.fromJsonList(json["conditions"]) ? PushRuleConditions.fromJsonList(json['conditions'])
: null, : null,
this.pattern = json["pattern"]; pattern = json['pattern'];
} }
/// Conditions when this pushrule should be active. /// Conditions when this pushrule should be active.
@ -68,7 +68,7 @@ class PushRuleConditions {
final String is_; final String is_;
static List<PushRuleConditions> fromJsonList(List<dynamic> list) { static List<PushRuleConditions> fromJsonList(List<dynamic> list) {
List<PushRuleConditions> objList = []; var objList = <PushRuleConditions>[];
list.forEach((json) { list.forEach((json) {
objList.add(PushRuleConditions.fromJson(json)); objList.add(PushRuleConditions.fromJson(json));
}); });
@ -76,8 +76,8 @@ class PushRuleConditions {
} }
PushRuleConditions.fromJson(Map<String, dynamic> json) PushRuleConditions.fromJson(Map<String, dynamic> json)
: this.kind = json["kind"], : kind = json['kind'],
this.key = json["key"], key = json['key'],
this.pattern = json["pattern"], pattern = json['pattern'],
this.is_ = json["is"]; is_ = json['is'];
} }

View file

@ -1,35 +1,33 @@
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/utils/session_key.dart';
class RoomKeyRequest extends ToDeviceEvent { class RoomKeyRequest extends ToDeviceEvent {
Client client; Client client;
RoomKeyRequest.fromToDeviceEvent(ToDeviceEvent toDeviceEvent, Client client) { RoomKeyRequest.fromToDeviceEvent(ToDeviceEvent toDeviceEvent, Client client) {
this.client = client; this.client = client;
this.sender = toDeviceEvent.sender; sender = toDeviceEvent.sender;
this.content = toDeviceEvent.content; content = toDeviceEvent.content;
this.type = toDeviceEvent.type; type = toDeviceEvent.type;
} }
Room get room => client.getRoomById(this.content["body"]["room_id"]); Room get room => client.getRoomById(content['body']['room_id']);
DeviceKeys get requestingDevice => DeviceKeys get requestingDevice =>
client.userDeviceKeys[sender].deviceKeys[content["requesting_device_id"]]; client.userDeviceKeys[sender].deviceKeys[content['requesting_device_id']];
Future<void> forwardKey() async { Future<void> forwardKey() async {
Room room = this.room; var room = this.room;
final SessionKey session = final session = room.sessionKeys[content['body']['session_id']];
room.sessionKeys[this.content["body"]["session_id"]]; var forwardedKeys = <dynamic>[client.identityKey];
List<dynamic> forwardedKeys = [client.identityKey];
for (final key in session.forwardingCurve25519KeyChain) { for (final key in session.forwardingCurve25519KeyChain) {
forwardedKeys.add(key); forwardedKeys.add(key);
} }
await requestingDevice.setVerified(true, client); await requestingDevice.setVerified(true, client);
Map<String, dynamic> message = session.content; var message = session.content;
message["forwarding_curve25519_key_chain"] = forwardedKeys; message['forwarding_curve25519_key_chain'] = forwardedKeys;
message["session_key"] = session.inboundGroupSession.export_session(0); message['session_key'] = session.inboundGroupSession.export_session(0);
await client.sendToDevice( await client.sendToDevice(
[requestingDevice], [requestingDevice],
"m.forwarded_room_key", 'm.forwarded_room_key',
message, message,
); );
} }

View file

@ -8,35 +8,36 @@ class SessionKey {
InboundGroupSession inboundGroupSession; InboundGroupSession inboundGroupSession;
final String key; final String key;
List<dynamic> get forwardingCurve25519KeyChain => List<dynamic> get forwardingCurve25519KeyChain =>
content["forwarding_curve25519_key_chain"] ?? []; content['forwarding_curve25519_key_chain'] ?? [];
String get senderClaimedEd25519Key => String get senderClaimedEd25519Key =>
content["sender_claimed_ed25519_key"] ?? ""; content['sender_claimed_ed25519_key'] ?? '';
SessionKey({this.content, this.inboundGroupSession, this.key, this.indexes}); SessionKey({this.content, this.inboundGroupSession, this.key, this.indexes});
SessionKey.fromJson(Map<String, dynamic> json, String key) : this.key = key { SessionKey.fromJson(Map<String, dynamic> json, String key) : key = key {
content = json['content'] != null content = json['content'] != null
? Map<String, dynamic>.from(json['content']) ? Map<String, dynamic>.from(json['content'])
: null; : null;
indexes = json['indexes'] != null indexes = json['indexes'] != null
? Map<String, int>.from(json['indexes']) ? Map<String, int>.from(json['indexes'])
: Map<String, int>(); : <String, int>{};
InboundGroupSession newInboundGroupSession = InboundGroupSession(); var newInboundGroupSession = InboundGroupSession();
newInboundGroupSession.unpickle(key, json['inboundGroupSession']); newInboundGroupSession.unpickle(key, json['inboundGroupSession']);
inboundGroupSession = newInboundGroupSession; inboundGroupSession = newInboundGroupSession;
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>(); final data = <String, dynamic>{};
if (this.content != null) { if (content != null) {
data['content'] = this.content; data['content'] = content;
} }
if (this.indexes != null) { if (indexes != null) {
data['indexes'] = this.indexes; data['indexes'] = indexes;
} }
data['inboundGroupSession'] = this.inboundGroupSession.pickle(this.key); data['inboundGroupSession'] = inboundGroupSession.pickle(key);
return data; return data;
} }
String toString() => json.encode(this.toJson()); @override
String toString() => json.encode(toJson());
} }

View file

@ -10,13 +10,13 @@ class StatesMap {
dynamic operator [](String key) { dynamic operator [](String key) {
//print("[Warning] This method will be depracated in the future!"); //print("[Warning] This method will be depracated in the future!");
if (key == null) return null; if (key == null) return null;
if (key.startsWith("@") && key.contains(":")) { if (key.startsWith('@') && key.contains(':')) {
if (!states.containsKey("m.room.member")) states["m.room.member"] = {}; if (!states.containsKey('m.room.member')) states['m.room.member'] = {};
return states["m.room.member"][key]; return states['m.room.member'][key];
} }
if (!states.containsKey(key)) states[key] = {}; if (!states.containsKey(key)) states[key] = {};
if (states[key][""] is Event) { if (states[key][''] is Event) {
return states[key][""]; return states[key][''];
} else if (states[key].isEmpty) { } else if (states[key].isEmpty) {
return null; return null;
} else { } else {
@ -26,12 +26,12 @@ class StatesMap {
void operator []=(String key, Event val) { void operator []=(String key, Event val) {
//print("[Warning] This method will be depracated in the future!"); //print("[Warning] This method will be depracated in the future!");
if (key.startsWith("@") && key.contains(":")) { if (key.startsWith('@') && key.contains(':')) {
if (!states.containsKey("m.room.member")) states["m.room.member"] = {}; if (!states.containsKey('m.room.member')) states['m.room.member'] = {};
states["m.room.member"][key] = val; states['m.room.member'][key] = val;
} }
if (!states.containsKey(key)) states[key] = {}; if (!states.containsKey(key)) states[key] = {};
states[key][val.stateKey ?? ""] = val; states[key][val.stateKey ?? ''] = val;
} }
bool containsKey(String key) => states.containsKey(key); bool containsKey(String key) => states.containsKey(key);

View file

@ -14,11 +14,12 @@ class ToDeviceEvent {
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>(); var map = <String, dynamic>{};
data['sender'] = this.sender; final data = map;
data['type'] = this.type; data['sender'] = sender;
if (this.content != null) { data['type'] = type;
data['content'] = this.content; if (content != null) {
data['content'] = content;
} }
return data; return data;
} }

View file

@ -20,8 +20,8 @@ class UserDevice {
Future<void> updateMetaData(String newName) async { Future<void> updateMetaData(String newName) async {
await _client.jsonRequest( await _client.jsonRequest(
type: HTTPType.PUT, type: HTTPType.PUT,
action: "/client/r0/devices/$deviceId", action: '/client/r0/devices/$deviceId',
data: {"display_name": newName}, data: {'display_name': newName},
); );
return; return;
} }
@ -30,8 +30,8 @@ class UserDevice {
Future<void> deleteDevice(Map<String, dynamic> auth) async { Future<void> deleteDevice(Map<String, dynamic> auth) async {
await _client.jsonRequest( await _client.jsonRequest(
type: HTTPType.DELETE, type: HTTPType.DELETE,
action: "/client/r0/devices/$deviceId", action: '/client/r0/devices/$deviceId',
data: auth != null ? {"auth": auth} : null, data: auth != null ? {'auth': auth} : null,
); );
return; return;
} }

View file

@ -196,7 +196,7 @@ packages:
name: http name: http
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.0+2" version: "0.12.0+4"
http_multi_server: http_multi_server:
dependency: transitive dependency: transitive
description: description:
@ -333,7 +333,7 @@ packages:
name: pedantic name: pedantic
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0+1" version: "1.9.0"
pointycastle: pointycastle:
dependency: transitive dependency: transitive
description: description:

View file

@ -25,4 +25,4 @@ dependencies:
dev_dependencies: dev_dependencies:
test: ^1.0.0 test: ^1.0.0
build_runner: ^1.5.2 build_runner: ^1.5.2
pedantic: ^1.5.0 # DO NOT UPDATE AS THIS WOULD CAUSE FLUTTER TO FAIL pedantic: ^1.9.0 # DO NOT UPDATE AS THIS WOULD CAUSE FLUTTER TO FAIL

View file

@ -26,26 +26,26 @@ import 'package:test/test.dart';
void main() { void main() {
/// All Tests related to the ChatTime /// All Tests related to the ChatTime
group("Canonical Json", () { group('Canonical Json', () {
Map<String, Map<String, dynamic>> textMap = { var textMap = <String, Map<String, dynamic>>{
'{}': {}, '{}': {},
'{"one":1,"two":"Two"}': {"one": 1, "two": "Two"}, '{"one":1,"two":"Two"}': {'one': 1, 'two': 'Two'},
'{"a":"1","b":"2"}': {"b": "2", "a": "1"}, '{"a":"1","b":"2"}': {'b': '2', 'a': '1'},
'{"auth":{"mxid":"@john.doe:example.com","profile":{"display_name":"John Doe","three_pids":[{"address":"john.doe@example.org","medium":"email"},{"address":"123456789","medium":"msisdn"}]},"success":true}}': '{"auth":{"mxid":"@john.doe:example.com","profile":{"display_name":"John Doe","three_pids":[{"address":"john.doe@example.org","medium":"email"},{"address":"123456789","medium":"msisdn"}]},"success":true}}':
{ {
"auth": { 'auth': {
"success": true, 'success': true,
"mxid": "@john.doe:example.com", 'mxid': '@john.doe:example.com',
"profile": { 'profile': {
"display_name": "John Doe", 'display_name': 'John Doe',
"three_pids": [ 'three_pids': [
{"medium": "email", "address": "john.doe@example.org"}, {'medium': 'email', 'address': 'john.doe@example.org'},
{"medium": "msisdn", "address": "123456789"} {'medium': 'msisdn', 'address': '123456789'}
] ]
} }
} }
}, },
'{"a":null}': {"a": null}, '{"a":null}': {'a': null},
}; };
for (final entry in textMap.entries) { for (final entry in textMap.entries) {
test(entry.key, () async { test(entry.key, () async {

View file

@ -29,15 +29,12 @@ import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/account_data.dart'; import 'package:famedlysdk/src/account_data.dart';
import 'package:famedlysdk/src/client.dart'; import 'package:famedlysdk/src/client.dart';
import 'package:famedlysdk/src/presence.dart'; import 'package:famedlysdk/src/presence.dart';
import 'package:famedlysdk/src/room.dart';
import 'package:famedlysdk/src/user.dart'; import 'package:famedlysdk/src/user.dart';
import 'package:famedlysdk/src/sync/event_update.dart'; import 'package:famedlysdk/src/sync/event_update.dart';
import 'package:famedlysdk/src/sync/room_update.dart'; import 'package:famedlysdk/src/sync/room_update.dart';
import 'package:famedlysdk/src/sync/user_update.dart'; import 'package:famedlysdk/src/sync/user_update.dart';
import 'package:famedlysdk/src/utils/matrix_exception.dart'; import 'package:famedlysdk/src/utils/matrix_exception.dart';
import 'package:famedlysdk/src/utils/matrix_file.dart'; import 'package:famedlysdk/src/utils/matrix_file.dart';
import 'package:famedlysdk/src/utils/profile.dart';
import 'package:famedlysdk/src/utils/user_device.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
import 'package:test/test.dart'; import 'package:test/test.dart';
@ -52,35 +49,35 @@ void main() {
Future<List<UserUpdate>> userUpdateListFuture; Future<List<UserUpdate>> userUpdateListFuture;
Future<List<ToDeviceEvent>> toDeviceUpdateListFuture; Future<List<ToDeviceEvent>> toDeviceUpdateListFuture;
const String pickledOlmAccount = const pickledOlmAccount =
"N2v1MkIFGcl0mQpo2OCwSopxPQJ0wnl7oe7PKiT4141AijfdTIhRu+ceXzXKy3Kr00nLqXtRv7kid6hU4a+V0rfJWLL0Y51+3Rp/ORDVnQy+SSeo6Fn4FHcXrxifJEJ0djla5u98fBcJ8BSkhIDmtXRPi5/oJAvpiYn+8zMjFHobOeZUAxYR0VfQ9JzSYBsSovoQ7uFkNks1M4EDUvHtuweStA+EKZvvHZO0SnwRp0Hw7sv8UMYvXw"; 'N2v1MkIFGcl0mQpo2OCwSopxPQJ0wnl7oe7PKiT4141AijfdTIhRu+ceXzXKy3Kr00nLqXtRv7kid6hU4a+V0rfJWLL0Y51+3Rp/ORDVnQy+SSeo6Fn4FHcXrxifJEJ0djla5u98fBcJ8BSkhIDmtXRPi5/oJAvpiYn+8zMjFHobOeZUAxYR0VfQ9JzSYBsSovoQ7uFkNks1M4EDUvHtuweStA+EKZvvHZO0SnwRp0Hw7sv8UMYvXw';
const String identityKey = "7rvl3jORJkBiK4XX1e5TnGnqz068XfYJ0W++Ml63rgk"; const identityKey = '7rvl3jORJkBiK4XX1e5TnGnqz068XfYJ0W++Ml63rgk';
const String fingerprintKey = "gjL//fyaFHADt9KBADGag8g7F8Up78B/K1zXeiEPLJo"; const fingerprintKey = 'gjL//fyaFHADt9KBADGag8g7F8Up78B/K1zXeiEPLJo';
/// All Tests related to the Login /// All Tests related to the Login
group("FluffyMatrix", () { group('FluffyMatrix', () {
/// Check if all Elements get created /// Check if all Elements get created
matrix = Client("testclient", debug: true); matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi(); matrix.httpClient = FakeMatrixApi();
roomUpdateListFuture = matrix.onRoomUpdate.stream.toList(); roomUpdateListFuture = matrix.onRoomUpdate.stream.toList();
eventUpdateListFuture = matrix.onEvent.stream.toList(); eventUpdateListFuture = matrix.onEvent.stream.toList();
userUpdateListFuture = matrix.onUserEvent.stream.toList(); userUpdateListFuture = matrix.onUserEvent.stream.toList();
toDeviceUpdateListFuture = matrix.onToDeviceEvent.stream.toList(); toDeviceUpdateListFuture = matrix.onToDeviceEvent.stream.toList();
bool olmEnabled = true; var olmEnabled = true;
try { try {
olm.init(); olm.init();
olm.Account(); olm.Account();
} catch (_) { } catch (_) {
olmEnabled = false; olmEnabled = false;
print("[LibOlm] Failed to load LibOlm: " + _.toString()); print('[LibOlm] Failed to load LibOlm: ' + _.toString());
} }
print("[LibOlm] Enabled: $olmEnabled"); print('[LibOlm] Enabled: $olmEnabled');
test('Login', () async { test('Login', () async {
int presenceCounter = 0; var presenceCounter = 0;
int accountDataCounter = 0; var accountDataCounter = 0;
matrix.onPresence.stream.listen((Presence data) { matrix.onPresence.stream.listen((Presence data) {
presenceCounter++; presenceCounter++;
}); });
@ -92,46 +89,45 @@ void main() {
expect(matrix.matrixVersions, null); expect(matrix.matrixVersions, null);
try { try {
await matrix.checkServer("https://fakeserver.wrongaddress"); await matrix.checkServer('https://fakeserver.wrongaddress');
} on FormatException catch (exception) { } on FormatException catch (exception) {
expect(exception != null, true); expect(exception != null, true);
} }
await matrix.checkServer("https://fakeserver.notexisting"); await matrix.checkServer('https://fakeserver.notexisting');
expect(matrix.homeserver, "https://fakeserver.notexisting"); expect(matrix.homeserver, 'https://fakeserver.notexisting');
expect(matrix.matrixVersions, expect(matrix.matrixVersions,
["r0.0.1", "r0.1.0", "r0.2.0", "r0.3.0", "r0.4.0", "r0.5.0"]); ['r0.0.1', 'r0.1.0', 'r0.2.0', 'r0.3.0', 'r0.4.0', 'r0.5.0']);
final Map<String, dynamic> resp = await matrix final resp = await matrix
.jsonRequest(type: HTTPType.POST, action: "/client/r0/login", data: { .jsonRequest(type: HTTPType.POST, action: '/client/r0/login', data: {
"type": "m.login.password", 'type': 'm.login.password',
"user": "test", 'user': 'test',
"password": "1234", 'password': '1234',
"initial_device_display_name": "Fluffy Matrix Client" 'initial_device_display_name': 'Fluffy Matrix Client'
}); });
final bool available = await matrix.usernameAvailable("testuser"); final available = await matrix.usernameAvailable('testuser');
expect(available, true); expect(available, true);
Map registerResponse = await matrix.register(username: "testuser"); Map registerResponse = await matrix.register(username: 'testuser');
expect(registerResponse["user_id"], "@testuser:example.com"); expect(registerResponse['user_id'], '@testuser:example.com');
registerResponse = registerResponse =
await matrix.register(username: "testuser", kind: "user"); await matrix.register(username: 'testuser', kind: 'user');
expect(registerResponse["user_id"], "@testuser:example.com"); expect(registerResponse['user_id'], '@testuser:example.com');
registerResponse = registerResponse =
await matrix.register(username: "testuser", kind: "guest"); await matrix.register(username: 'testuser', kind: 'guest');
expect(registerResponse["user_id"], "@testuser:example.com"); expect(registerResponse['user_id'], '@testuser:example.com');
Future<LoginState> loginStateFuture = var loginStateFuture = matrix.onLoginStateChanged.stream.first;
matrix.onLoginStateChanged.stream.first; var firstSyncFuture = matrix.onFirstSync.stream.first;
Future<bool> firstSyncFuture = matrix.onFirstSync.stream.first; var syncFuture = matrix.onSync.stream.first;
Future<dynamic> syncFuture = matrix.onSync.stream.first;
matrix.connect( matrix.connect(
newToken: resp["access_token"], newToken: resp['access_token'],
newUserID: resp["user_id"], newUserID: resp['user_id'],
newHomeserver: matrix.homeserver, newHomeserver: matrix.homeserver,
newDeviceName: "Text Matrix Client", newDeviceName: 'Text Matrix Client',
newDeviceID: resp["device_id"], newDeviceID: resp['device_id'],
newMatrixVersions: matrix.matrixVersions, newMatrixVersions: matrix.matrixVersions,
newLazyLoadMembers: matrix.lazyLoadMembers, newLazyLoadMembers: matrix.lazyLoadMembers,
newOlmAccount: pickledOlmAccount, newOlmAccount: pickledOlmAccount,
@ -139,13 +135,13 @@ void main() {
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
expect(matrix.accessToken == resp["access_token"], true); expect(matrix.accessToken == resp['access_token'], true);
expect(matrix.deviceName == "Text Matrix Client", true); expect(matrix.deviceName == 'Text Matrix Client', true);
expect(matrix.deviceID == resp["device_id"], true); expect(matrix.deviceID == resp['device_id'], true);
expect(matrix.userID == resp["user_id"], true); expect(matrix.userID == resp['user_id'], true);
LoginState loginState = await loginStateFuture; var loginState = await loginStateFuture;
bool firstSync = await firstSyncFuture; var firstSync = await firstSyncFuture;
dynamic sync = await syncFuture; dynamic sync = await syncFuture;
expect(loginState, LoginState.logged); expect(loginState, LoginState.logged);
@ -156,91 +152,91 @@ void main() {
expect(matrix.identityKey, identityKey); expect(matrix.identityKey, identityKey);
expect(matrix.fingerprintKey, fingerprintKey); expect(matrix.fingerprintKey, fingerprintKey);
} }
expect(sync["next_batch"] == matrix.prevBatch, true); expect(sync['next_batch'] == matrix.prevBatch, true);
expect(matrix.accountData.length, 3); expect(matrix.accountData.length, 3);
expect(matrix.getDirectChatFromUserId("@bob:example.com"), expect(matrix.getDirectChatFromUserId('@bob:example.com'),
"!726s6s6q:example.com"); '!726s6s6q:example.com');
expect(matrix.rooms[1].directChatMatrixID, "@bob:example.com"); expect(matrix.rooms[1].directChatMatrixID, '@bob:example.com');
expect(matrix.directChats, matrix.accountData["m.direct"].content); expect(matrix.directChats, matrix.accountData['m.direct'].content);
expect(matrix.presences.length, 1); expect(matrix.presences.length, 1);
expect(matrix.rooms[1].ephemerals.length, 2); expect(matrix.rooms[1].ephemerals.length, 2);
expect(matrix.rooms[1].sessionKeys.length, 1); expect(matrix.rooms[1].sessionKeys.length, 1);
expect( expect(
matrix matrix
.rooms[1] .rooms[1]
.sessionKeys["ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU"] .sessionKeys['ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU']
.content["session_key"], .content['session_key'],
"AgAAAAAQcQ6XrFJk6Prm8FikZDqfry/NbDz8Xw7T6e+/9Yf/q3YHIPEQlzv7IZMNcYb51ifkRzFejVvtphS7wwG2FaXIp4XS2obla14iKISR0X74ugB2vyb1AydIHE/zbBQ1ic5s3kgjMFlWpu/S3FQCnCrv+DPFGEt3ERGWxIl3Bl5X53IjPyVkz65oljz2TZESwz0GH/QFvyOOm8ci0q/gceaF3S7Dmafg3dwTKYwcA5xkcc+BLyrLRzB6Hn+oMAqSNSscnm4mTeT5zYibIhrzqyUTMWr32spFtI9dNR/RFSzfCw"); 'AgAAAAAQcQ6XrFJk6Prm8FikZDqfry/NbDz8Xw7T6e+/9Yf/q3YHIPEQlzv7IZMNcYb51ifkRzFejVvtphS7wwG2FaXIp4XS2obla14iKISR0X74ugB2vyb1AydIHE/zbBQ1ic5s3kgjMFlWpu/S3FQCnCrv+DPFGEt3ERGWxIl3Bl5X53IjPyVkz65oljz2TZESwz0GH/QFvyOOm8ci0q/gceaF3S7Dmafg3dwTKYwcA5xkcc+BLyrLRzB6Hn+oMAqSNSscnm4mTeT5zYibIhrzqyUTMWr32spFtI9dNR/RFSzfCw');
if (olmEnabled) { if (olmEnabled) {
expect( expect(
matrix matrix
.rooms[1] .rooms[1]
.sessionKeys["ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU"] .sessionKeys['ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU']
.inboundGroupSession != .inboundGroupSession !=
null, null,
true); true);
} }
expect(matrix.rooms[1].typingUsers.length, 1); expect(matrix.rooms[1].typingUsers.length, 1);
expect(matrix.rooms[1].typingUsers[0].id, "@alice:example.com"); expect(matrix.rooms[1].typingUsers[0].id, '@alice:example.com');
expect(matrix.rooms[1].roomAccountData.length, 3); expect(matrix.rooms[1].roomAccountData.length, 3);
expect(matrix.rooms[1].encrypted, true); expect(matrix.rooms[1].encrypted, true);
expect(matrix.rooms[1].encryptionAlgorithm, expect(matrix.rooms[1].encryptionAlgorithm,
Client.supportedGroupEncryptionAlgorithms.first); Client.supportedGroupEncryptionAlgorithms.first);
expect( expect(
matrix.rooms[1].roomAccountData["m.receipt"] matrix.rooms[1].roomAccountData['m.receipt']
.content["@alice:example.com"]["ts"], .content['@alice:example.com']['ts'],
1436451550453); 1436451550453);
expect( expect(
matrix.rooms[1].roomAccountData["m.receipt"] matrix.rooms[1].roomAccountData['m.receipt']
.content["@alice:example.com"]["event_id"], .content['@alice:example.com']['event_id'],
"7365636s6r6432:example.com"); '7365636s6r6432:example.com');
expect(matrix.rooms.length, 2); expect(matrix.rooms.length, 2);
expect(matrix.rooms[1].canonicalAlias, expect(matrix.rooms[1].canonicalAlias,
"#famedlyContactDiscovery:${matrix.userID.split(":")[1]}"); "#famedlyContactDiscovery:${matrix.userID.split(":")[1]}");
final List<User> contacts = await matrix.loadFamedlyContacts(); final contacts = await matrix.loadFamedlyContacts();
expect(contacts.length, 1); expect(contacts.length, 1);
expect(contacts[0].senderId, "@alice:example.com"); expect(contacts[0].senderId, '@alice:example.com');
expect( expect(
matrix.presences["@alice:example.com"].presence, PresenceType.online); matrix.presences['@alice:example.com'].presence, PresenceType.online);
expect(presenceCounter, 1); expect(presenceCounter, 1);
expect(accountDataCounter, 3); expect(accountDataCounter, 3);
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
expect(matrix.userDeviceKeys.length, 2); expect(matrix.userDeviceKeys.length, 2);
expect(matrix.userDeviceKeys["@alice:example.com"].outdated, false); expect(matrix.userDeviceKeys['@alice:example.com'].outdated, false);
expect(matrix.userDeviceKeys["@alice:example.com"].deviceKeys.length, 1); expect(matrix.userDeviceKeys['@alice:example.com'].deviceKeys.length, 1);
expect( expect(
matrix.userDeviceKeys["@alice:example.com"].deviceKeys["JLAFKJWSCS"] matrix.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
.verified, .verified,
false); false);
matrix.handleSync({ matrix.handleSync({
"device_lists": { 'device_lists': {
"changed": [ 'changed': [
"@alice:example.com", '@alice:example.com',
], ],
"left": [ 'left': [
"@bob:example.com", '@bob:example.com',
], ],
} }
}); });
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
expect(matrix.userDeviceKeys.length, 2); expect(matrix.userDeviceKeys.length, 2);
expect(matrix.userDeviceKeys["@alice:example.com"].outdated, true); expect(matrix.userDeviceKeys['@alice:example.com'].outdated, true);
matrix.handleSync({ matrix.handleSync({
"rooms": { 'rooms': {
"join": { 'join': {
"!726s6s6q:example.com": { '!726s6s6q:example.com': {
"state": { 'state': {
"events": [ 'events': [
{ {
"sender": "@alice:example.com", 'sender': '@alice:example.com',
"type": "m.room.canonical_alias", 'type': 'm.room.canonical_alias',
"content": {"alias": ""}, 'content': {'alias': ''},
"state_key": "", 'state_key': '',
"origin_server_ts": 1417731086799, 'origin_server_ts': 1417731086799,
"event_id": "66697273743033:example.com" 'event_id': '66697273743033:example.com'
} }
] ]
} }
@ -254,17 +250,17 @@ void main() {
matrix.getRoomByAlias( matrix.getRoomByAlias(
"#famedlyContactDiscovery:${matrix.userID.split(":")[1]}"), "#famedlyContactDiscovery:${matrix.userID.split(":")[1]}"),
null); null);
final List<User> altContacts = await matrix.loadFamedlyContacts(); final altContacts = await matrix.loadFamedlyContacts();
altContacts.forEach((u) => print(u.id)); altContacts.forEach((u) => print(u.id));
expect(altContacts.length, 2); expect(altContacts.length, 2);
expect(altContacts[0].senderId, "@alice:example.com"); expect(altContacts[0].senderId, '@alice:example.com');
}); });
test('Try to get ErrorResponse', () async { test('Try to get ErrorResponse', () async {
MatrixException expectedException; MatrixException expectedException;
try { try {
await matrix.jsonRequest( await matrix.jsonRequest(
type: HTTPType.PUT, action: "/non/existing/path"); type: HTTPType.PUT, action: '/non/existing/path');
} on MatrixException catch (exception) { } on MatrixException catch (exception) {
expectedException = exception; expectedException = exception;
} }
@ -273,10 +269,9 @@ void main() {
test('Logout', () async { test('Logout', () async {
await matrix.jsonRequest( await matrix.jsonRequest(
type: HTTPType.POST, action: "/client/r0/logout"); type: HTTPType.POST, action: '/client/r0/logout');
Future<LoginState> loginStateFuture = var loginStateFuture = matrix.onLoginStateChanged.stream.first;
matrix.onLoginStateChanged.stream.first;
matrix.clear(); matrix.clear();
@ -289,27 +284,27 @@ void main() {
expect(matrix.lazyLoadMembers == null, true); expect(matrix.lazyLoadMembers == null, true);
expect(matrix.prevBatch == null, true); expect(matrix.prevBatch == null, true);
LoginState loginState = await loginStateFuture; var loginState = await loginStateFuture;
expect(loginState, LoginState.loggedOut); expect(loginState, LoginState.loggedOut);
}); });
test('Room Update Test', () async { test('Room Update Test', () async {
await matrix.onRoomUpdate.close(); await matrix.onRoomUpdate.close();
List<RoomUpdate> roomUpdateList = await roomUpdateListFuture; var roomUpdateList = await roomUpdateListFuture;
expect(roomUpdateList.length, 3); expect(roomUpdateList.length, 3);
expect(roomUpdateList[0].id == "!726s6s6q:example.com", true); expect(roomUpdateList[0].id == '!726s6s6q:example.com', true);
expect(roomUpdateList[0].membership == Membership.join, true); expect(roomUpdateList[0].membership == Membership.join, true);
expect(roomUpdateList[0].prev_batch == "t34-23535_0_0", true); expect(roomUpdateList[0].prev_batch == 't34-23535_0_0', true);
expect(roomUpdateList[0].limitedTimeline == true, true); expect(roomUpdateList[0].limitedTimeline == true, true);
expect(roomUpdateList[0].notification_count == 2, true); expect(roomUpdateList[0].notification_count == 2, true);
expect(roomUpdateList[0].highlight_count == 2, true); expect(roomUpdateList[0].highlight_count == 2, true);
expect(roomUpdateList[1].id == "!696r7674:example.com", true); expect(roomUpdateList[1].id == '!696r7674:example.com', true);
expect(roomUpdateList[1].membership == Membership.invite, true); expect(roomUpdateList[1].membership == Membership.invite, true);
expect(roomUpdateList[1].prev_batch == "", true); expect(roomUpdateList[1].prev_batch == '', true);
expect(roomUpdateList[1].limitedTimeline == false, true); expect(roomUpdateList[1].limitedTimeline == false, true);
expect(roomUpdateList[1].notification_count == 0, true); expect(roomUpdateList[1].notification_count == 0, true);
expect(roomUpdateList[1].highlight_count == 0, true); expect(roomUpdateList[1].highlight_count == 0, true);
@ -318,194 +313,193 @@ void main() {
test('Event Update Test', () async { test('Event Update Test', () async {
await matrix.onEvent.close(); await matrix.onEvent.close();
List<EventUpdate> eventUpdateList = await eventUpdateListFuture; var eventUpdateList = await eventUpdateListFuture;
expect(eventUpdateList.length, 13); expect(eventUpdateList.length, 13);
expect(eventUpdateList[0].eventType, "m.room.member"); expect(eventUpdateList[0].eventType, 'm.room.member');
expect(eventUpdateList[0].roomID, "!726s6s6q:example.com"); expect(eventUpdateList[0].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[0].type, "state"); expect(eventUpdateList[0].type, 'state');
expect(eventUpdateList[1].eventType, "m.room.canonical_alias"); expect(eventUpdateList[1].eventType, 'm.room.canonical_alias');
expect(eventUpdateList[1].roomID, "!726s6s6q:example.com"); expect(eventUpdateList[1].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[1].type, "state"); expect(eventUpdateList[1].type, 'state');
expect(eventUpdateList[2].eventType, "m.room.encryption"); expect(eventUpdateList[2].eventType, 'm.room.encryption');
expect(eventUpdateList[2].roomID, "!726s6s6q:example.com"); expect(eventUpdateList[2].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[2].type, "state"); expect(eventUpdateList[2].type, 'state');
expect(eventUpdateList[3].eventType, "m.room.member"); expect(eventUpdateList[3].eventType, 'm.room.member');
expect(eventUpdateList[3].roomID, "!726s6s6q:example.com"); expect(eventUpdateList[3].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[3].type, "timeline"); expect(eventUpdateList[3].type, 'timeline');
expect(eventUpdateList[4].eventType, "m.room.message"); expect(eventUpdateList[4].eventType, 'm.room.message');
expect(eventUpdateList[4].roomID, "!726s6s6q:example.com"); expect(eventUpdateList[4].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[4].type, "timeline"); expect(eventUpdateList[4].type, 'timeline');
expect(eventUpdateList[5].eventType, "m.typing"); expect(eventUpdateList[5].eventType, 'm.typing');
expect(eventUpdateList[5].roomID, "!726s6s6q:example.com"); expect(eventUpdateList[5].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[5].type, "ephemeral"); expect(eventUpdateList[5].type, 'ephemeral');
expect(eventUpdateList[6].eventType, "m.receipt"); expect(eventUpdateList[6].eventType, 'm.receipt');
expect(eventUpdateList[6].roomID, "!726s6s6q:example.com"); expect(eventUpdateList[6].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[6].type, "ephemeral"); expect(eventUpdateList[6].type, 'ephemeral');
expect(eventUpdateList[7].eventType, "m.receipt"); expect(eventUpdateList[7].eventType, 'm.receipt');
expect(eventUpdateList[7].roomID, "!726s6s6q:example.com"); expect(eventUpdateList[7].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[7].type, "account_data"); expect(eventUpdateList[7].type, 'account_data');
expect(eventUpdateList[8].eventType, "m.tag"); expect(eventUpdateList[8].eventType, 'm.tag');
expect(eventUpdateList[8].roomID, "!726s6s6q:example.com"); expect(eventUpdateList[8].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[8].type, "account_data"); expect(eventUpdateList[8].type, 'account_data');
expect(eventUpdateList[9].eventType, "org.example.custom.room.config"); expect(eventUpdateList[9].eventType, 'org.example.custom.room.config');
expect(eventUpdateList[9].roomID, "!726s6s6q:example.com"); expect(eventUpdateList[9].roomID, '!726s6s6q:example.com');
expect(eventUpdateList[9].type, "account_data"); expect(eventUpdateList[9].type, 'account_data');
expect(eventUpdateList[10].eventType, "m.room.name"); expect(eventUpdateList[10].eventType, 'm.room.name');
expect(eventUpdateList[10].roomID, "!696r7674:example.com"); expect(eventUpdateList[10].roomID, '!696r7674:example.com');
expect(eventUpdateList[10].type, "invite_state"); expect(eventUpdateList[10].type, 'invite_state');
expect(eventUpdateList[11].eventType, "m.room.member"); expect(eventUpdateList[11].eventType, 'm.room.member');
expect(eventUpdateList[11].roomID, "!696r7674:example.com"); expect(eventUpdateList[11].roomID, '!696r7674:example.com');
expect(eventUpdateList[11].type, "invite_state"); expect(eventUpdateList[11].type, 'invite_state');
}); });
test('User Update Test', () async { test('User Update Test', () async {
await matrix.onUserEvent.close(); await matrix.onUserEvent.close();
List<UserUpdate> eventUpdateList = await userUpdateListFuture; var eventUpdateList = await userUpdateListFuture;
expect(eventUpdateList.length, 4); expect(eventUpdateList.length, 4);
expect(eventUpdateList[0].eventType, "m.presence"); expect(eventUpdateList[0].eventType, 'm.presence');
expect(eventUpdateList[0].type, "presence"); expect(eventUpdateList[0].type, 'presence');
expect(eventUpdateList[1].eventType, "m.push_rules"); expect(eventUpdateList[1].eventType, 'm.push_rules');
expect(eventUpdateList[1].type, "account_data"); expect(eventUpdateList[1].type, 'account_data');
expect(eventUpdateList[2].eventType, "org.example.custom.config"); expect(eventUpdateList[2].eventType, 'org.example.custom.config');
expect(eventUpdateList[2].type, "account_data"); expect(eventUpdateList[2].type, 'account_data');
}); });
test('To Device Update Test', () async { test('To Device Update Test', () async {
await matrix.onToDeviceEvent.close(); await matrix.onToDeviceEvent.close();
List<ToDeviceEvent> eventUpdateList = await toDeviceUpdateListFuture; var eventUpdateList = await toDeviceUpdateListFuture;
expect(eventUpdateList.length, 2); expect(eventUpdateList.length, 2);
expect(eventUpdateList[0].type, "m.new_device"); expect(eventUpdateList[0].type, 'm.new_device');
expect(eventUpdateList[1].type, "m.room_key"); expect(eventUpdateList[1].type, 'm.room_key');
}); });
test('Login', () async { test('Login', () async {
matrix = Client("testclient", debug: true); matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi(); matrix.httpClient = FakeMatrixApi();
roomUpdateListFuture = matrix.onRoomUpdate.stream.toList(); roomUpdateListFuture = matrix.onRoomUpdate.stream.toList();
eventUpdateListFuture = matrix.onEvent.stream.toList(); eventUpdateListFuture = matrix.onEvent.stream.toList();
userUpdateListFuture = matrix.onUserEvent.stream.toList(); userUpdateListFuture = matrix.onUserEvent.stream.toList();
final bool checkResp = final checkResp =
await matrix.checkServer("https://fakeServer.notExisting"); await matrix.checkServer('https://fakeServer.notExisting');
final bool loginResp = await matrix.login("test", "1234"); final loginResp = await matrix.login('test', '1234');
expect(checkResp, true); expect(checkResp, true);
expect(loginResp, true); expect(loginResp, true);
}); });
test('createRoom', () async { test('createRoom', () async {
final OpenIdCredentials openId = await matrix.requestOpenIdCredentials(); final openId = await matrix.requestOpenIdCredentials();
expect(openId.accessToken, "SomeT0kenHere"); expect(openId.accessToken, 'SomeT0kenHere');
expect(openId.tokenType, "Bearer"); expect(openId.tokenType, 'Bearer');
expect(openId.matrixServerName, "example.com"); expect(openId.matrixServerName, 'example.com');
expect(openId.expiresIn, 3600); expect(openId.expiresIn, 3600);
}); });
test('createRoom', () async { test('createRoom', () async {
final List<User> users = [ final users = [
User("@alice:fakeServer.notExisting"), User('@alice:fakeServer.notExisting'),
User("@bob:fakeServer.notExisting") User('@bob:fakeServer.notExisting')
]; ];
final String newID = await matrix.createRoom(invite: users); final newID = await matrix.createRoom(invite: users);
expect(newID, "!1234:fakeServer.notExisting"); expect(newID, '!1234:fakeServer.notExisting');
}); });
test('setAvatar', () async { test('setAvatar', () async {
final MatrixFile testFile = final testFile =
MatrixFile(bytes: Uint8List(0), path: "fake/path/file.jpeg"); MatrixFile(bytes: Uint8List(0), path: 'fake/path/file.jpeg');
await matrix.setAvatar(testFile); await matrix.setAvatar(testFile);
}); });
test('setPushers', () async { test('setPushers', () async {
await matrix.setPushers("abcdefg", "http", "com.famedly.famedlysdk", await matrix.setPushers('abcdefg', 'http', 'com.famedly.famedlysdk',
"famedlySDK", "GitLabCi", "en", "https://examplepushserver.com", 'famedlySDK', 'GitLabCi', 'en', 'https://examplepushserver.com',
format: "event_id_only"); format: 'event_id_only');
}); });
test('joinRoomById', () async { test('joinRoomById', () async {
final String roomID = "1234"; final roomID = '1234';
final Map<String, dynamic> resp = await matrix.joinRoomById(roomID); final Map<String, dynamic> resp = await matrix.joinRoomById(roomID);
expect(resp["room_id"], roomID); expect(resp['room_id'], roomID);
}); });
test('requestUserDevices', () async { test('requestUserDevices', () async {
final List<UserDevice> userDevices = await matrix.requestUserDevices(); final userDevices = await matrix.requestUserDevices();
expect(userDevices.length, 1); expect(userDevices.length, 1);
expect(userDevices.first.deviceId, "QBUAZIFURK"); expect(userDevices.first.deviceId, 'QBUAZIFURK');
expect(userDevices.first.displayName, "android"); expect(userDevices.first.displayName, 'android');
expect(userDevices.first.lastSeenIp, "1.2.3.4"); expect(userDevices.first.lastSeenIp, '1.2.3.4');
expect( expect(
userDevices.first.lastSeenTs.millisecondsSinceEpoch, 1474491775024); userDevices.first.lastSeenTs.millisecondsSinceEpoch, 1474491775024);
}); });
test('get archive', () async { test('get archive', () async {
List<Room> archive = await matrix.archive; var archive = await matrix.archive;
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
expect(archive.length, 2); expect(archive.length, 2);
expect(archive[0].id, "!5345234234:example.com"); expect(archive[0].id, '!5345234234:example.com');
expect(archive[0].membership, Membership.leave); expect(archive[0].membership, Membership.leave);
expect(archive[0].name, "The room name"); expect(archive[0].name, 'The room name');
expect(archive[0].lastMessage, "This is an example text message"); expect(archive[0].lastMessage, 'This is an example text message');
expect(archive[0].roomAccountData.length, 1); expect(archive[0].roomAccountData.length, 1);
expect(archive[1].id, "!5345234235:example.com"); expect(archive[1].id, '!5345234235:example.com');
expect(archive[1].membership, Membership.leave); expect(archive[1].membership, Membership.leave);
expect(archive[1].name, "The room name 2"); expect(archive[1].name, 'The room name 2');
}); });
test('getProfileFromUserId', () async { test('getProfileFromUserId', () async {
final Profile profile = final profile = await matrix.getProfileFromUserId('@getme:example.com');
await matrix.getProfileFromUserId("@getme:example.com"); expect(profile.avatarUrl.mxc, 'mxc://test');
expect(profile.avatarUrl.mxc, "mxc://test"); expect(profile.displayname, 'You got me');
expect(profile.displayname, "You got me"); expect(profile.content['avatar_url'], profile.avatarUrl.mxc);
expect(profile.content["avatar_url"], profile.avatarUrl.mxc); expect(profile.content['displayname'], profile.displayname);
expect(profile.content["displayname"], profile.displayname);
}); });
test('signJson', () { test('signJson', () {
if (matrix.encryptionEnabled) { if (matrix.encryptionEnabled) {
expect(matrix.fingerprintKey.isNotEmpty, true); expect(matrix.fingerprintKey.isNotEmpty, true);
expect(matrix.identityKey.isNotEmpty, true); expect(matrix.identityKey.isNotEmpty, true);
Map<String, dynamic> payload = { var payload = <String, dynamic>{
"unsigned": { 'unsigned': {
"foo": "bar", 'foo': 'bar',
}, },
"auth": { 'auth': {
"success": true, 'success': true,
"mxid": "@john.doe:example.com", 'mxid': '@john.doe:example.com',
"profile": { 'profile': {
"display_name": "John Doe", 'display_name': 'John Doe',
"three_pids": [ 'three_pids': [
{"medium": "email", "address": "john.doe@example.org"}, {'medium': 'email', 'address': 'john.doe@example.org'},
{"medium": "msisdn", "address": "123456789"} {'medium': 'msisdn', 'address': '123456789'}
] ]
} }
} }
}; };
Map<String, dynamic> payloadWithoutUnsigned = Map.from(payload); var payloadWithoutUnsigned = Map<String, dynamic>.from(payload);
payloadWithoutUnsigned.remove("unsigned"); payloadWithoutUnsigned.remove('unsigned');
expect( expect(
matrix.checkJsonSignature( matrix.checkJsonSignature(
@ -517,8 +511,8 @@ void main() {
false); false);
payload = matrix.signJson(payload); payload = matrix.signJson(payload);
payloadWithoutUnsigned = matrix.signJson(payloadWithoutUnsigned); payloadWithoutUnsigned = matrix.signJson(payloadWithoutUnsigned);
expect(payload["signatures"], payloadWithoutUnsigned["signatures"]); expect(payload['signatures'], payloadWithoutUnsigned['signatures']);
print(payload["signatures"]); print(payload['signatures']);
expect( expect(
matrix.checkJsonSignature( matrix.checkJsonSignature(
matrix.fingerprintKey, payload, matrix.userID, matrix.deviceID), matrix.fingerprintKey, payload, matrix.userID, matrix.deviceID),
@ -531,9 +525,9 @@ void main() {
}); });
test('Track oneTimeKeys', () async { test('Track oneTimeKeys', () async {
if (matrix.encryptionEnabled) { if (matrix.encryptionEnabled) {
DateTime last = matrix.lastTimeKeysUploaded ?? DateTime.now(); var last = matrix.lastTimeKeysUploaded ?? DateTime.now();
matrix.handleSync({ matrix.handleSync({
"device_one_time_keys_count": {"signed_curve25519": 49} 'device_one_time_keys_count': {'signed_curve25519': 49}
}); });
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
expect( expect(
@ -548,12 +542,12 @@ void main() {
await matrix.rooms[1].createOutboundGroupSession(); await matrix.rooms[1].createOutboundGroupSession();
expect(matrix.rooms[1].outboundGroupSession != null, true); expect(matrix.rooms[1].outboundGroupSession != null, true);
matrix.handleSync({ matrix.handleSync({
"device_lists": { 'device_lists': {
"changed": [ 'changed': [
"@alice:example.com", '@alice:example.com',
], ],
"left": [ 'left': [
"@bob:example.com", '@bob:example.com',
], ],
} }
}); });
@ -568,19 +562,19 @@ void main() {
await matrix.rooms[1].createOutboundGroupSession(); await matrix.rooms[1].createOutboundGroupSession();
expect(matrix.rooms[1].outboundGroupSession != null, true); expect(matrix.rooms[1].outboundGroupSession != null, true);
matrix.handleSync({ matrix.handleSync({
"rooms": { 'rooms': {
"join": { 'join': {
"!726s6s6q:example.com": { '!726s6s6q:example.com': {
"state": { 'state': {
"events": [ 'events': [
{ {
"content": {"membership": "leave"}, 'content': {'membership': 'leave'},
"event_id": "143273582443PhrSn:example.org", 'event_id': '143273582443PhrSn:example.org',
"origin_server_ts": 1432735824653, 'origin_server_ts': 1432735824653,
"room_id": "!726s6s6q:example.com", 'room_id': '!726s6s6q:example.com',
"sender": "@alice:example.com", 'sender': '@alice:example.com',
"state_key": "@alice:example.com", 'state_key': '@alice:example.com',
"type": "m.room.member" 'type': 'm.room.member'
} }
] ]
} }
@ -592,18 +586,18 @@ void main() {
expect(matrix.rooms[1].outboundGroupSession != null, true); expect(matrix.rooms[1].outboundGroupSession != null, true);
} }
}); });
DeviceKeys deviceKeys = DeviceKeys.fromJson({ var deviceKeys = DeviceKeys.fromJson({
"user_id": "@alice:example.com", 'user_id': '@alice:example.com',
"device_id": "JLAFKJWSCS", 'device_id': 'JLAFKJWSCS',
"algorithms": ["m.olm.v1.curve25519-aes-sha2", "m.megolm.v1.aes-sha2"], 'algorithms': ['m.olm.v1.curve25519-aes-sha2', 'm.megolm.v1.aes-sha2'],
"keys": { 'keys': {
"curve25519:JLAFKJWSCS": "3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI", 'curve25519:JLAFKJWSCS': '3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI',
"ed25519:JLAFKJWSCS": "lEuiRJBit0IG6nUf5pUzWTUEsRVVe/HJkoKuEww9ULI" 'ed25519:JLAFKJWSCS': 'lEuiRJBit0IG6nUf5pUzWTUEsRVVe/HJkoKuEww9ULI'
}, },
"signatures": { 'signatures': {
"@alice:example.com": { '@alice:example.com': {
"ed25519:JLAFKJWSCS": 'ed25519:JLAFKJWSCS':
"dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA" 'dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA'
} }
} }
}); });
@ -614,52 +608,51 @@ void main() {
.startOutgoingOlmSessions([deviceKeys], checkSignature: false); .startOutgoingOlmSessions([deviceKeys], checkSignature: false);
expect(matrix.olmSessions.length, 1); expect(matrix.olmSessions.length, 1);
expect(matrix.olmSessions.entries.first.key, expect(matrix.olmSessions.entries.first.key,
"3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI"); '3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI');
} }
}); });
test('sendToDevice', () async { test('sendToDevice', () async {
await matrix.sendToDevice( await matrix.sendToDevice(
[deviceKeys], [deviceKeys],
"m.message", 'm.message',
{ {
"msgtype": "m.text", 'msgtype': 'm.text',
"body": "Hello world", 'body': 'Hello world',
}); });
}); });
test('Logout when token is unknown', () async { test('Logout when token is unknown', () async {
Future<LoginState> loginStateFuture = var loginStateFuture = matrix.onLoginStateChanged.stream.first;
matrix.onLoginStateChanged.stream.first;
try { try {
await matrix.jsonRequest( await matrix.jsonRequest(
type: HTTPType.DELETE, action: "/unknown/token"); type: HTTPType.DELETE, action: '/unknown/token');
} on MatrixException catch (exception) { } on MatrixException catch (exception) {
expect(exception.error, MatrixError.M_UNKNOWN_TOKEN); expect(exception.error, MatrixError.M_UNKNOWN_TOKEN);
} }
LoginState state = await loginStateFuture; var state = await loginStateFuture;
expect(state, LoginState.loggedOut); expect(state, LoginState.loggedOut);
expect(matrix.isLogged(), false); expect(matrix.isLogged(), false);
}); });
test('Test the fake store api', () async { test('Test the fake store api', () async {
Client client1 = Client("testclient", debug: true); var client1 = Client('testclient', debug: true);
client1.httpClient = FakeMatrixApi(); client1.httpClient = FakeMatrixApi();
FakeStore fakeStore = FakeStore(client1, {}); var fakeStore = FakeStore(client1, {});
client1.storeAPI = fakeStore; client1.storeAPI = fakeStore;
client1.connect( client1.connect(
newToken: "abc123", newToken: 'abc123',
newUserID: "@test:fakeServer.notExisting", newUserID: '@test:fakeServer.notExisting',
newHomeserver: "https://fakeServer.notExisting", newHomeserver: 'https://fakeServer.notExisting',
newDeviceName: "Text Matrix Client", newDeviceName: 'Text Matrix Client',
newDeviceID: "GHTYAJCE", newDeviceID: 'GHTYAJCE',
newMatrixVersions: [ newMatrixVersions: [
"r0.0.1", 'r0.0.1',
"r0.1.0", 'r0.1.0',
"r0.2.0", 'r0.2.0',
"r0.3.0", 'r0.3.0',
"r0.4.0", 'r0.4.0',
"r0.5.0" 'r0.5.0'
], ],
newLazyLoadMembers: true, newLazyLoadMembers: true,
newOlmAccount: pickledOlmAccount, newOlmAccount: pickledOlmAccount,
@ -677,7 +670,7 @@ void main() {
expect(client1.isLogged(), true); expect(client1.isLogged(), true);
expect(client1.rooms.length, 2); expect(client1.rooms.length, 2);
Client client2 = Client("testclient", debug: true); var client2 = Client('testclient', debug: true);
client2.httpClient = FakeMatrixApi(); client2.httpClient = FakeMatrixApi();
client2.storeAPI = FakeStore(client2, fakeStore.storeMap); client2.storeAPI = FakeStore(client2, fakeStore.storeMap);

View file

@ -28,38 +28,38 @@ import 'package:test/test.dart';
void main() { void main() {
/// All Tests related to device keys /// All Tests related to device keys
group("Device keys", () { group('Device keys', () {
test("fromJson", () async { test('fromJson', () async {
Map<String, dynamic> rawJson = { var rawJson = <String, dynamic>{
"user_id": "@alice:example.com", 'user_id': '@alice:example.com',
"device_id": "JLAFKJWSCS", 'device_id': 'JLAFKJWSCS',
"algorithms": ["m.olm.v1.curve25519-aes-sha2", "m.megolm.v1.aes-sha2"], 'algorithms': ['m.olm.v1.curve25519-aes-sha2', 'm.megolm.v1.aes-sha2'],
"keys": { 'keys': {
"curve25519:JLAFKJWSCS": 'curve25519:JLAFKJWSCS':
"3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI", '3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI',
"ed25519:JLAFKJWSCS": "lEuiRJBit0IG6nUf5pUzWTUEsRVVe/HJkoKuEww9ULI" 'ed25519:JLAFKJWSCS': 'lEuiRJBit0IG6nUf5pUzWTUEsRVVe/HJkoKuEww9ULI'
}, },
"signatures": { 'signatures': {
"@alice:example.com": { '@alice:example.com': {
"ed25519:JLAFKJWSCS": 'ed25519:JLAFKJWSCS':
"dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA" 'dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA'
} }
}, },
"unsigned": {"device_display_name": "Alice's mobile phone"}, 'unsigned': {'device_display_name': "Alice's mobile phone"},
"verified": false, 'verified': false,
"blocked": true, 'blocked': true,
}; };
Map<String, dynamic> rawListJson = { var rawListJson = <String, dynamic>{
"user_id": "@alice:example.com", 'user_id': '@alice:example.com',
"outdated": true, 'outdated': true,
"device_keys": {"JLAFKJWSCS": rawJson}, 'device_keys': {'JLAFKJWSCS': rawJson},
}; };
Map<String, DeviceKeysList> userDeviceKeys = { var userDeviceKeys = <String, DeviceKeysList>{
"@alice:example.com": DeviceKeysList.fromJson(rawListJson), '@alice:example.com': DeviceKeysList.fromJson(rawListJson),
}; };
Map<String, dynamic> userDeviceKeyRaw = { var userDeviceKeyRaw = <String, dynamic>{
"@alice:example.com": rawListJson, '@alice:example.com': rawListJson,
}; };
expect(json.encode(DeviceKeys.fromJson(rawJson).toJson()), expect(json.encode(DeviceKeys.fromJson(rawJson).toJson()),
@ -67,7 +67,7 @@ void main() {
expect(json.encode(DeviceKeysList.fromJson(rawListJson).toJson()), expect(json.encode(DeviceKeysList.fromJson(rawListJson).toJson()),
json.encode(rawListJson)); json.encode(rawListJson));
Map<String, DeviceKeysList> mapFromRaw = {}; var mapFromRaw = <String, DeviceKeysList>{};
for (final rawListEntry in userDeviceKeyRaw.entries) { for (final rawListEntry in userDeviceKeyRaw.entries) {
mapFromRaw[rawListEntry.key] = mapFromRaw[rawListEntry.key] =
DeviceKeysList.fromJson(rawListEntry.value); DeviceKeysList.fromJson(rawListEntry.value);

View file

@ -31,34 +31,34 @@ import 'fake_matrix_api.dart';
void main() { void main() {
/// All Tests related to the Event /// All Tests related to the Event
group("Event", () { group('Event', () {
final int timestamp = DateTime.now().millisecondsSinceEpoch; final timestamp = DateTime.now().millisecondsSinceEpoch;
final String id = "!4fsdfjisjf:server.abc"; final id = '!4fsdfjisjf:server.abc';
final String senderID = "@alice:server.abc"; final senderID = '@alice:server.abc';
final String type = "m.room.message"; final type = 'm.room.message';
final String msgtype = "m.text"; final msgtype = 'm.text';
final String body = "Hello World"; final body = 'Hello World';
final String formatted_body = "<b>Hello</b> World"; final formatted_body = '<b>Hello</b> World';
final String contentJson = final contentJson =
'{"msgtype":"$msgtype","body":"$body","formatted_body":"$formatted_body","m.relates_to":{"m.in_reply_to":{"event_id":"\$1234:example.com"}}}'; '{"msgtype":"$msgtype","body":"$body","formatted_body":"$formatted_body","m.relates_to":{"m.in_reply_to":{"event_id":"\$1234:example.com"}}}';
Map<String, dynamic> jsonObj = { var jsonObj = <String, dynamic>{
"event_id": id, 'event_id': id,
"sender": senderID, 'sender': senderID,
"origin_server_ts": timestamp, 'origin_server_ts': timestamp,
"type": type, 'type': type,
"room_id": "1234", 'room_id': '1234',
"status": 2, 'status': 2,
"content": contentJson, 'content': contentJson,
}; };
test("Create from json", () async { test('Create from json', () async {
Event event = Event.fromJson(jsonObj, null); var event = Event.fromJson(jsonObj, null);
jsonObj.remove("status"); jsonObj.remove('status');
jsonObj["content"] = json.decode(contentJson); jsonObj['content'] = json.decode(contentJson);
expect(event.toJson(), jsonObj); expect(event.toJson(), jsonObj);
jsonObj["content"] = contentJson; jsonObj['content'] = contentJson;
expect(event.eventId, id); expect(event.eventId, id);
expect(event.senderId, senderID); expect(event.senderId, senderID);
@ -68,181 +68,180 @@ void main() {
expect(event.body, body); expect(event.body, body);
expect(event.type, EventTypes.Message); expect(event.type, EventTypes.Message);
expect(event.isReply, true); expect(event.isReply, true);
jsonObj["state_key"] = ""; jsonObj['state_key'] = '';
Event state = Event.fromJson(jsonObj, null); var state = Event.fromJson(jsonObj, null);
expect(state.eventId, id); expect(state.eventId, id);
expect(state.stateKey, ""); expect(state.stateKey, '');
expect(state.status, 2); expect(state.status, 2);
}); });
test("Test all EventTypes", () async { test('Test all EventTypes', () async {
Event event; Event event;
jsonObj["type"] = "m.room.avatar"; jsonObj['type'] = 'm.room.avatar';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.type, EventTypes.RoomAvatar); expect(event.type, EventTypes.RoomAvatar);
jsonObj["type"] = "m.room.name"; jsonObj['type'] = 'm.room.name';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.type, EventTypes.RoomName); expect(event.type, EventTypes.RoomName);
jsonObj["type"] = "m.room.topic"; jsonObj['type'] = 'm.room.topic';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.type, EventTypes.RoomTopic); expect(event.type, EventTypes.RoomTopic);
jsonObj["type"] = "m.room.aliases"; jsonObj['type'] = 'm.room.aliases';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.type, EventTypes.RoomAliases); expect(event.type, EventTypes.RoomAliases);
jsonObj["type"] = "m.room.canonical_alias"; jsonObj['type'] = 'm.room.canonical_alias';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.type, EventTypes.RoomCanonicalAlias); expect(event.type, EventTypes.RoomCanonicalAlias);
jsonObj["type"] = "m.room.create"; jsonObj['type'] = 'm.room.create';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.type, EventTypes.RoomCreate); expect(event.type, EventTypes.RoomCreate);
jsonObj["type"] = "m.room.join_rules"; jsonObj['type'] = 'm.room.join_rules';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.type, EventTypes.RoomJoinRules); expect(event.type, EventTypes.RoomJoinRules);
jsonObj["type"] = "m.room.member"; jsonObj['type'] = 'm.room.member';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.type, EventTypes.RoomMember); expect(event.type, EventTypes.RoomMember);
jsonObj["type"] = "m.room.power_levels"; jsonObj['type'] = 'm.room.power_levels';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.type, EventTypes.RoomPowerLevels); expect(event.type, EventTypes.RoomPowerLevels);
jsonObj["type"] = "m.room.guest_access"; jsonObj['type'] = 'm.room.guest_access';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.type, EventTypes.GuestAccess); expect(event.type, EventTypes.GuestAccess);
jsonObj["type"] = "m.room.history_visibility"; jsonObj['type'] = 'm.room.history_visibility';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.type, EventTypes.HistoryVisibility); expect(event.type, EventTypes.HistoryVisibility);
jsonObj["type"] = "m.room.message"; jsonObj['type'] = 'm.room.message';
jsonObj["content"] = json.decode(jsonObj["content"]); jsonObj['content'] = json.decode(jsonObj['content']);
jsonObj["content"]["msgtype"] = "m.notice"; jsonObj['content']['msgtype'] = 'm.notice';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.messageType, MessageTypes.Notice); expect(event.messageType, MessageTypes.Notice);
jsonObj["content"]["msgtype"] = "m.emote"; jsonObj['content']['msgtype'] = 'm.emote';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.messageType, MessageTypes.Emote); expect(event.messageType, MessageTypes.Emote);
jsonObj["content"]["msgtype"] = "m.image"; jsonObj['content']['msgtype'] = 'm.image';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.messageType, MessageTypes.Image); expect(event.messageType, MessageTypes.Image);
jsonObj["content"]["msgtype"] = "m.video"; jsonObj['content']['msgtype'] = 'm.video';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.messageType, MessageTypes.Video); expect(event.messageType, MessageTypes.Video);
jsonObj["content"]["msgtype"] = "m.audio"; jsonObj['content']['msgtype'] = 'm.audio';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.messageType, MessageTypes.Audio); expect(event.messageType, MessageTypes.Audio);
jsonObj["content"]["msgtype"] = "m.file"; jsonObj['content']['msgtype'] = 'm.file';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.messageType, MessageTypes.File); expect(event.messageType, MessageTypes.File);
jsonObj["content"]["msgtype"] = "m.location"; jsonObj['content']['msgtype'] = 'm.location';
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.messageType, MessageTypes.Location); expect(event.messageType, MessageTypes.Location);
jsonObj["type"] = "m.room.message"; jsonObj['type'] = 'm.room.message';
jsonObj["content"]["msgtype"] = "m.text"; jsonObj['content']['msgtype'] = 'm.text';
jsonObj["content"]["m.relates_to"] = {}; jsonObj['content']['m.relates_to'] = {};
jsonObj["content"]["m.relates_to"]["m.in_reply_to"] = { jsonObj['content']['m.relates_to']['m.in_reply_to'] = {
"event_id": "1234", 'event_id': '1234',
}; };
event = Event.fromJson(jsonObj, null); event = Event.fromJson(jsonObj, null);
expect(event.messageType, MessageTypes.Reply); expect(event.messageType, MessageTypes.Reply);
}); });
test("redact", () async { test('redact', () async {
final Room room = final room = Room(id: '1234', client: Client('testclient', debug: true));
Room(id: "1234", client: Client("testclient", debug: true)); final redactionEventJson = {
final Map<String, dynamic> redactionEventJson = { 'content': {'reason': 'Spamming'},
"content": {"reason": "Spamming"}, 'event_id': '143273582443PhrSn:example.org',
"event_id": "143273582443PhrSn:example.org", 'origin_server_ts': 1432735824653,
"origin_server_ts": 1432735824653, 'redacts': id,
"redacts": id, 'room_id': '1234',
"room_id": "1234", 'sender': '@example:example.org',
"sender": "@example:example.org", 'type': 'm.room.redaction',
"type": "m.room.redaction", 'unsigned': {'age': 1234}
"unsigned": {"age": 1234}
}; };
Event redactedBecause = Event.fromJson(redactionEventJson, room); var redactedBecause = Event.fromJson(redactionEventJson, room);
Event event = Event.fromJson(jsonObj, room); var event = Event.fromJson(jsonObj, room);
event.setRedactionEvent(redactedBecause); event.setRedactionEvent(redactedBecause);
expect(event.redacted, true); expect(event.redacted, true);
expect(event.redactedBecause.toJson(), redactedBecause.toJson()); expect(event.redactedBecause.toJson(), redactedBecause.toJson());
expect(event.content.isEmpty, true); expect(event.content.isEmpty, true);
redactionEventJson.remove("redacts"); redactionEventJson.remove('redacts');
expect(event.unsigned["redacted_because"], redactionEventJson); expect(event.unsigned['redacted_because'], redactionEventJson);
}); });
test("remove", () async { test('remove', () async {
Event event = Event.fromJson( var event = Event.fromJson(
jsonObj, Room(id: "1234", client: Client("testclient", debug: true))); jsonObj, Room(id: '1234', client: Client('testclient', debug: true)));
final bool removed1 = await event.remove(); final removed1 = await event.remove();
event.status = 0; event.status = 0;
final bool removed2 = await event.remove(); final removed2 = await event.remove();
expect(removed1, false); expect(removed1, false);
expect(removed2, true); expect(removed2, true);
}); });
test("sendAgain", () async { test('sendAgain', () async {
Client matrix = Client("testclient", debug: true); var matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi(); matrix.httpClient = FakeMatrixApi();
await matrix.checkServer("https://fakeServer.notExisting"); await matrix.checkServer('https://fakeServer.notExisting');
await matrix.login("test", "1234"); await matrix.login('test', '1234');
Event event = Event.fromJson( var event = Event.fromJson(
jsonObj, Room(id: "!1234:example.com", client: matrix)); jsonObj, Room(id: '!1234:example.com', client: matrix));
final String resp1 = await event.sendAgain(); final resp1 = await event.sendAgain();
event.status = -1; event.status = -1;
final String resp2 = await event.sendAgain(txid: "1234"); final resp2 = await event.sendAgain(txid: '1234');
expect(resp1, null); expect(resp1, null);
expect(resp2, "42"); expect(resp2, '42');
}); });
test("requestKey", () async { test('requestKey', () async {
Client matrix = Client("testclient", debug: true); var matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi(); matrix.httpClient = FakeMatrixApi();
await matrix.checkServer("https://fakeServer.notExisting"); await matrix.checkServer('https://fakeServer.notExisting');
await matrix.login("test", "1234"); await matrix.login('test', '1234');
Event event = Event.fromJson( var event = Event.fromJson(
jsonObj, Room(id: "!1234:example.com", client: matrix)); jsonObj, Room(id: '!1234:example.com', client: matrix));
String exception; String exception;
try { try {
await event.requestKey(); await event.requestKey();
} catch (e) { } catch (e) {
exception = e; exception = e;
} }
expect(exception, "Session key not unknown"); expect(exception, 'Session key not unknown');
event = Event.fromJson({ event = Event.fromJson({
"event_id": id, 'event_id': id,
"sender": senderID, 'sender': senderID,
"origin_server_ts": timestamp, 'origin_server_ts': timestamp,
"type": "m.room.encrypted", 'type': 'm.room.encrypted',
"room_id": "1234", 'room_id': '1234',
"status": 2, 'status': 2,
"content": json.encode({ 'content': json.encode({
"msgtype": "m.bad.encrypted", 'msgtype': 'm.bad.encrypted',
"body": DecryptError.UNKNOWN_SESSION, 'body': DecryptError.UNKNOWN_SESSION,
"algorithm": "m.megolm.v1.aes-sha2", 'algorithm': 'm.megolm.v1.aes-sha2',
"ciphertext": "AwgAEnACgAkLmt6qF84IK++J7UDH2Za1YVchHyprqTqsg...", 'ciphertext': 'AwgAEnACgAkLmt6qF84IK++J7UDH2Za1YVchHyprqTqsg...',
"device_id": "RJYKSTBOIE", 'device_id': 'RJYKSTBOIE',
"sender_key": "IlRMeOPX2e0MurIyfWEucYBRVOEEUMrOHqn/8mLqMjA", 'sender_key': 'IlRMeOPX2e0MurIyfWEucYBRVOEEUMrOHqn/8mLqMjA',
"session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ" 'session_id': 'X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ'
}), }),
}, Room(id: "!1234:example.com", client: matrix)); }, Room(id: '!1234:example.com', client: matrix));
await event.requestKey(); await event.requestKey();
}); });

File diff suppressed because it is too large Load diff

View file

@ -5,83 +5,91 @@ import 'package:famedlysdk/famedlysdk.dart';
class FakeStore implements StoreAPI { class FakeStore implements StoreAPI {
/// Whether this is a simple store which only stores the client credentials and /// Whether this is a simple store which only stores the client credentials and
/// end to end encryption stuff or the whole sync payloads. /// end to end encryption stuff or the whole sync payloads.
@override
final bool extended = false; final bool extended = false;
Map<String, dynamic> storeMap = {}; Map<String, dynamic> storeMap = {};
/// Link back to the client. /// Link back to the client.
@override
Client client; Client client;
FakeStore(this.client, this.storeMap) { FakeStore(this.client, this.storeMap) {
_init(); _init();
} }
_init() async { Future<void> _init() async {
final credentialsStr = await getItem(client.clientName); final credentialsStr = await getItem(client.clientName);
if (credentialsStr == null || credentialsStr.isEmpty) { if (credentialsStr == null || credentialsStr.isEmpty) {
client.onLoginStateChanged.add(LoginState.loggedOut); client.onLoginStateChanged.add(LoginState.loggedOut);
return; return;
} }
print("[Matrix] Restoring account credentials"); print('[Matrix] Restoring account credentials');
final Map<String, dynamic> credentials = json.decode(credentialsStr); final Map<String, dynamic> credentials = json.decode(credentialsStr);
client.connect( client.connect(
newDeviceID: credentials["deviceID"], newDeviceID: credentials['deviceID'],
newDeviceName: credentials["deviceName"], newDeviceName: credentials['deviceName'],
newHomeserver: credentials["homeserver"], newHomeserver: credentials['homeserver'],
newLazyLoadMembers: credentials["lazyLoadMembers"], newLazyLoadMembers: credentials['lazyLoadMembers'],
newMatrixVersions: List<String>.from(credentials["matrixVersions"]), newMatrixVersions: List<String>.from(credentials['matrixVersions']),
newToken: credentials["token"], newToken: credentials['token'],
newUserID: credentials["userID"], newUserID: credentials['userID'],
newPrevBatch: credentials["prev_batch"], newPrevBatch: credentials['prev_batch'],
newOlmAccount: credentials["olmAccount"], newOlmAccount: credentials['olmAccount'],
); );
} }
/// Will be automatically called when the client is logged in successfully. /// Will be automatically called when the client is logged in successfully.
@override
Future<void> storeClient() async { Future<void> storeClient() async {
final Map<String, dynamic> credentials = { final credentials = {
"deviceID": client.deviceID, 'deviceID': client.deviceID,
"deviceName": client.deviceName, 'deviceName': client.deviceName,
"homeserver": client.homeserver, 'homeserver': client.homeserver,
"lazyLoadMembers": client.lazyLoadMembers, 'lazyLoadMembers': client.lazyLoadMembers,
"matrixVersions": client.matrixVersions, 'matrixVersions': client.matrixVersions,
"token": client.accessToken, 'token': client.accessToken,
"userID": client.userID, 'userID': client.userID,
"olmAccount": client.pickledOlmAccount, 'olmAccount': client.pickledOlmAccount,
}; };
await setItem(client.clientName, json.encode(credentials)); await setItem(client.clientName, json.encode(credentials));
return; return;
} }
/// Clears all tables from the database. /// Clears all tables from the database.
@override
Future<void> clear() async { Future<void> clear() async {
storeMap = {}; storeMap = {};
return; return;
} }
@override
Future<dynamic> getItem(String key) async { Future<dynamic> getItem(String key) async {
return storeMap[key]; return storeMap[key];
} }
@override
Future<void> setItem(String key, String value) async { Future<void> setItem(String key, String value) async {
storeMap[key] = value; storeMap[key] = value;
return; return;
} }
String get _UserDeviceKeysKey => "${client.clientName}.user_device_keys"; String get _UserDeviceKeysKey => '${client.clientName}.user_device_keys';
@override
Future<Map<String, DeviceKeysList>> getUserDeviceKeys() async { Future<Map<String, DeviceKeysList>> getUserDeviceKeys() async {
final deviceKeysListString = await getItem(_UserDeviceKeysKey); final deviceKeysListString = await getItem(_UserDeviceKeysKey);
if (deviceKeysListString == null) return {}; if (deviceKeysListString == null) return {};
Map<String, dynamic> rawUserDeviceKeys = json.decode(deviceKeysListString); Map<String, dynamic> rawUserDeviceKeys = json.decode(deviceKeysListString);
Map<String, DeviceKeysList> userDeviceKeys = {}; var userDeviceKeys = <String, DeviceKeysList>{};
for (final entry in rawUserDeviceKeys.entries) { for (final entry in rawUserDeviceKeys.entries) {
userDeviceKeys[entry.key] = DeviceKeysList.fromJson(entry.value); userDeviceKeys[entry.key] = DeviceKeysList.fromJson(entry.value);
} }
return userDeviceKeys; return userDeviceKeys;
} }
@override
Future<void> storeUserDeviceKeys( Future<void> storeUserDeviceKeys(
Map<String, DeviceKeysList> userDeviceKeys) async { Map<String, DeviceKeysList> userDeviceKeys) async {
await setItem(_UserDeviceKeysKey, json.encode(userDeviceKeys)); await setItem(_UserDeviceKeysKey, json.encode(userDeviceKeys));

View file

@ -26,25 +26,25 @@ import 'package:famedlysdk/src/utils/matrix_id_string_extension.dart';
void main() { void main() {
/// All Tests related to the ChatTime /// All Tests related to the ChatTime
group("Matrix ID String Extension", () { group('Matrix ID String Extension', () {
test("Matrix ID String Extension", () async { test('Matrix ID String Extension', () async {
final String mxId = "@test:example.com"; final mxId = '@test:example.com';
expect(mxId.isValidMatrixId, true); expect(mxId.isValidMatrixId, true);
expect("#test:example.com".isValidMatrixId, true); expect('#test:example.com'.isValidMatrixId, true);
expect("!test:example.com".isValidMatrixId, true); expect('!test:example.com'.isValidMatrixId, true);
expect("+test:example.com".isValidMatrixId, true); expect('+test:example.com'.isValidMatrixId, true);
expect("\$test:example.com".isValidMatrixId, true); expect('\$test:example.com'.isValidMatrixId, true);
expect("test:example.com".isValidMatrixId, false); expect('test:example.com'.isValidMatrixId, false);
expect("@testexample.com".isValidMatrixId, false); expect('@testexample.com'.isValidMatrixId, false);
expect("@:example.com".isValidMatrixId, false); expect('@:example.com'.isValidMatrixId, false);
expect("@test:".isValidMatrixId, false); expect('@test:'.isValidMatrixId, false);
expect(mxId.sigil, "@"); expect(mxId.sigil, '@');
expect("#test:example.com".sigil, "#"); expect('#test:example.com'.sigil, '#');
expect("!test:example.com".sigil, "!"); expect('!test:example.com'.sigil, '!');
expect("+test:example.com".sigil, "+"); expect('+test:example.com'.sigil, '+');
expect("\$test:example.com".sigil, "\$"); expect('\$test:example.com'.sigil, '\$');
expect(mxId.localpart, "test"); expect(mxId.localpart, 'test');
expect(mxId.domain, "example.com"); expect(mxId.domain, 'example.com');
}); });
}); });
} }

View file

@ -29,30 +29,30 @@ import 'fake_matrix_api.dart';
void main() { void main() {
/// All Tests related to the MxContent /// All Tests related to the MxContent
group("MxContent", () { group('MxContent', () {
test("Formatting", () async { test('Formatting', () async {
Client client = Client("testclient"); var client = Client('testclient');
client.httpClient = FakeMatrixApi(); client.httpClient = FakeMatrixApi();
await client.checkServer("https://fakeserver.notexisting"); await client.checkServer('https://fakeserver.notexisting');
final String mxc = "mxc://exampleserver.abc/abcdefghijklmn"; final mxc = 'mxc://exampleserver.abc/abcdefghijklmn';
final MxContent content = MxContent(mxc); final content = MxContent(mxc);
expect(content.getDownloadLink(client), expect(content.getDownloadLink(client),
"${client.homeserver}/_matrix/media/r0/download/exampleserver.abc/abcdefghijklmn"); '${client.homeserver}/_matrix/media/r0/download/exampleserver.abc/abcdefghijklmn');
expect(content.getThumbnail(client, width: 50, height: 50), expect(content.getThumbnail(client, width: 50, height: 50),
"${client.homeserver}/_matrix/media/r0/thumbnail/exampleserver.abc/abcdefghijklmn?width=50&height=50&method=crop"); '${client.homeserver}/_matrix/media/r0/thumbnail/exampleserver.abc/abcdefghijklmn?width=50&height=50&method=crop');
expect( expect(
content.getThumbnail(client, content.getThumbnail(client,
width: 50, height: 50, method: ThumbnailMethod.scale), width: 50, height: 50, method: ThumbnailMethod.scale),
"${client.homeserver}/_matrix/media/r0/thumbnail/exampleserver.abc/abcdefghijklmn?width=50&height=50&method=scale"); '${client.homeserver}/_matrix/media/r0/thumbnail/exampleserver.abc/abcdefghijklmn?width=50&height=50&method=scale');
}); });
test("Not crashing if null", () async { test('Not crashing if null', () async {
Client client = Client("testclient"); var client = Client('testclient');
client.httpClient = FakeMatrixApi(); client.httpClient = FakeMatrixApi();
await client.checkServer("https://fakeserver.notexisting"); await client.checkServer('https://fakeserver.notexisting');
final MxContent content = MxContent(null); final content = MxContent(null);
expect(content.getDownloadLink(client), expect(content.getDownloadLink(client),
"${client.homeserver}/_matrix/media/r0/download/"); '${client.homeserver}/_matrix/media/r0/download/');
}); });
}); });
} }

View file

@ -26,26 +26,26 @@ import 'package:test/test.dart';
void main() { void main() {
/// All Tests related to the ChatTime /// All Tests related to the ChatTime
group("Presence", () { group('Presence', () {
test("fromJson", () async { test('fromJson', () async {
Map<String, dynamic> rawPresence = { var rawPresence = <String, dynamic>{
"content": { 'content': {
"avatar_url": "mxc://localhost:wefuiwegh8742w", 'avatar_url': 'mxc://localhost:wefuiwegh8742w',
"currently_active": false, 'currently_active': false,
"last_active_ago": 2478593, 'last_active_ago': 2478593,
"presence": "online", 'presence': 'online',
"status_msg": "Making cupcakes" 'status_msg': 'Making cupcakes'
}, },
"sender": "@example:localhost", 'sender': '@example:localhost',
"type": "m.presence" 'type': 'm.presence'
}; };
Presence presence = Presence.fromJson(rawPresence); var presence = Presence.fromJson(rawPresence);
expect(presence.sender, "@example:localhost"); expect(presence.sender, '@example:localhost');
expect(presence.avatarUrl.mxc, "mxc://localhost:wefuiwegh8742w"); expect(presence.avatarUrl.mxc, 'mxc://localhost:wefuiwegh8742w');
expect(presence.currentlyActive, false); expect(presence.currentlyActive, false);
expect(presence.lastActiveAgo, 2478593); expect(presence.lastActiveAgo, 2478593);
expect(presence.presence, PresenceType.online); expect(presence.presence, PresenceType.online);
expect(presence.statusMsg, "Making cupcakes"); expect(presence.statusMsg, 'Making cupcakes');
}); });
}); });
} }

View file

@ -26,154 +26,154 @@ import 'package:test/test.dart';
void main() { void main() {
/// All Tests related to the MxContent /// All Tests related to the MxContent
group("PushRules", () { group('PushRules', () {
test("Create", () async { test('Create', () async {
final Map<String, dynamic> json = { final json = {
"global": { 'global': {
"content": [ 'content': [
{ {
"actions": [ 'actions': [
"notify", 'notify',
{"set_tweak": "sound", "value": "default"}, {'set_tweak': 'sound', 'value': 'default'},
{"set_tweak": "highlight"} {'set_tweak': 'highlight'}
], ],
"default": true, 'default': true,
"enabled": true, 'enabled': true,
"pattern": "alice", 'pattern': 'alice',
"rule_id": ".m.rule.contains_user_name" 'rule_id': '.m.rule.contains_user_name'
} }
], ],
"override": [ 'override': [
{ {
"actions": ["dont_notify"], 'actions': ['dont_notify'],
"conditions": [], 'conditions': [],
"default": true, 'default': true,
"enabled": false, 'enabled': false,
"rule_id": ".m.rule.master" 'rule_id': '.m.rule.master'
}, },
{ {
"actions": ["dont_notify"], 'actions': ['dont_notify'],
"conditions": [ 'conditions': [
{ {
"key": "content.msgtype", 'key': 'content.msgtype',
"kind": "event_match", 'kind': 'event_match',
"pattern": "m.notice" 'pattern': 'm.notice'
} }
], ],
"default": true, 'default': true,
"enabled": true, 'enabled': true,
"rule_id": ".m.rule.suppress_notices" 'rule_id': '.m.rule.suppress_notices'
} }
], ],
"room": [], 'room': [],
"sender": [], 'sender': [],
"underride": [ 'underride': [
{ {
"actions": [ 'actions': [
"notify", 'notify',
{"set_tweak": "sound", "value": "ring"}, {'set_tweak': 'sound', 'value': 'ring'},
{"set_tweak": "highlight", "value": false} {'set_tweak': 'highlight', 'value': false}
], ],
"conditions": [ 'conditions': [
{ {
"key": "type", 'key': 'type',
"kind": "event_match", 'kind': 'event_match',
"pattern": "m.call.invite" 'pattern': 'm.call.invite'
} }
], ],
"default": true, 'default': true,
"enabled": true, 'enabled': true,
"rule_id": ".m.rule.call" 'rule_id': '.m.rule.call'
}, },
{ {
"actions": [ 'actions': [
"notify", 'notify',
{"set_tweak": "sound", "value": "default"}, {'set_tweak': 'sound', 'value': 'default'},
{"set_tweak": "highlight"} {'set_tweak': 'highlight'}
], ],
"conditions": [ 'conditions': [
{"kind": "contains_display_name"} {'kind': 'contains_display_name'}
], ],
"default": true, 'default': true,
"enabled": true, 'enabled': true,
"rule_id": ".m.rule.contains_display_name" 'rule_id': '.m.rule.contains_display_name'
}, },
{ {
"actions": [ 'actions': [
"notify", 'notify',
{"set_tweak": "sound", "value": "default"}, {'set_tweak': 'sound', 'value': 'default'},
{"set_tweak": "highlight", "value": false} {'set_tweak': 'highlight', 'value': false}
], ],
"conditions": [ 'conditions': [
{"kind": "room_member_count", "is": "2"}, {'kind': 'room_member_count', 'is': '2'},
{ {
"kind": "event_match", 'kind': 'event_match',
"key": "type", 'key': 'type',
"pattern": "m.room.message" 'pattern': 'm.room.message'
} }
], ],
"default": true, 'default': true,
"enabled": true, 'enabled': true,
"rule_id": ".m.rule.room_one_to_one" 'rule_id': '.m.rule.room_one_to_one'
}, },
{ {
"actions": [ 'actions': [
"notify", 'notify',
{"set_tweak": "sound", "value": "default"}, {'set_tweak': 'sound', 'value': 'default'},
{"set_tweak": "highlight", "value": false} {'set_tweak': 'highlight', 'value': false}
], ],
"conditions": [ 'conditions': [
{ {
"key": "type", 'key': 'type',
"kind": "event_match", 'kind': 'event_match',
"pattern": "m.room.member" 'pattern': 'm.room.member'
}, },
{ {
"key": "content.membership", 'key': 'content.membership',
"kind": "event_match", 'kind': 'event_match',
"pattern": "invite" 'pattern': 'invite'
}, },
{ {
"key": "state_key", 'key': 'state_key',
"kind": "event_match", 'kind': 'event_match',
"pattern": "@alice:example.com" 'pattern': '@alice:example.com'
} }
], ],
"default": true, 'default': true,
"enabled": true, 'enabled': true,
"rule_id": ".m.rule.invite_for_me" 'rule_id': '.m.rule.invite_for_me'
}, },
{ {
"actions": [ 'actions': [
"notify", 'notify',
{"set_tweak": "highlight", "value": false} {'set_tweak': 'highlight', 'value': false}
], ],
"conditions": [ 'conditions': [
{ {
"key": "type", 'key': 'type',
"kind": "event_match", 'kind': 'event_match',
"pattern": "m.room.member" 'pattern': 'm.room.member'
} }
], ],
"default": true, 'default': true,
"enabled": true, 'enabled': true,
"rule_id": ".m.rule.member_event" 'rule_id': '.m.rule.member_event'
}, },
{ {
"actions": [ 'actions': [
"notify", 'notify',
{"set_tweak": "highlight", "value": false} {'set_tweak': 'highlight', 'value': false}
], ],
"conditions": [ 'conditions': [
{ {
"key": "type", 'key': 'type',
"kind": "event_match", 'kind': 'event_match',
"pattern": "m.room.message" 'pattern': 'm.room.message'
} }
], ],
"default": true, 'default': true,
"enabled": true, 'enabled': true,
"rule_id": ".m.rule.message" 'rule_id': '.m.rule.message'
} }
] ]
} }

View file

@ -29,39 +29,39 @@ import 'fake_store.dart';
void main() { void main() {
/// All Tests related to device keys /// All Tests related to device keys
group("Room Key Request", () { group('Room Key Request', () {
test("fromJson", () async { test('fromJson', () async {
Map<String, dynamic> rawJson = { var rawJson = <String, dynamic>{
"content": { 'content': {
"action": "request", 'action': 'request',
"body": { 'body': {
"algorithm": "m.megolm.v1.aes-sha2", 'algorithm': 'm.megolm.v1.aes-sha2',
"room_id": "!726s6s6q:example.com", 'room_id': '!726s6s6q:example.com',
"sender_key": "RF3s+E7RkTQTGF2d8Deol0FkQvgII2aJDf3/Jp5mxVU", 'sender_key': 'RF3s+E7RkTQTGF2d8Deol0FkQvgII2aJDf3/Jp5mxVU',
"session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ" 'session_id': 'X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ'
}, },
"request_id": "1495474790150.19", 'request_id': '1495474790150.19',
"requesting_device_id": "JLAFKJWSCS" 'requesting_device_id': 'JLAFKJWSCS'
}, },
"type": "m.room_key_request", 'type': 'm.room_key_request',
"sender": "@alice:example.com" 'sender': '@alice:example.com'
}; };
ToDeviceEvent toDeviceEvent = ToDeviceEvent.fromJson(rawJson); var toDeviceEvent = ToDeviceEvent.fromJson(rawJson);
expect(toDeviceEvent.content, rawJson["content"]); expect(toDeviceEvent.content, rawJson['content']);
expect(toDeviceEvent.sender, rawJson["sender"]); expect(toDeviceEvent.sender, rawJson['sender']);
expect(toDeviceEvent.type, rawJson["type"]); expect(toDeviceEvent.type, rawJson['type']);
Client matrix = Client("testclient", debug: true); var matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi(); matrix.httpClient = FakeMatrixApi();
matrix.storeAPI = FakeStore(matrix, {}); matrix.storeAPI = FakeStore(matrix, {});
await matrix.checkServer("https://fakeServer.notExisting"); await matrix.checkServer('https://fakeServer.notExisting');
await matrix.login("test", "1234"); await matrix.login('test', '1234');
Room room = matrix.getRoomById("!726s6s6q:example.com"); var room = matrix.getRoomById('!726s6s6q:example.com');
if (matrix.encryptionEnabled) { if (matrix.encryptionEnabled) {
await room.createOutboundGroupSession(); await room.createOutboundGroupSession();
rawJson["content"]["body"]["session_id"] = room.sessionKeys.keys.first; rawJson['content']['body']['session_id'] = room.sessionKeys.keys.first;
RoomKeyRequest roomKeyRequest = RoomKeyRequest.fromToDeviceEvent( var roomKeyRequest = RoomKeyRequest.fromToDeviceEvent(
ToDeviceEvent.fromJson(rawJson), matrix); ToDeviceEvent.fromJson(rawJson), matrix);
await roomKeyRequest.forwardKey(); await roomKeyRequest.forwardKey();
} }

View file

@ -24,7 +24,6 @@
import 'package:famedlysdk/src/client.dart'; import 'package:famedlysdk/src/client.dart';
import 'package:famedlysdk/src/event.dart'; import 'package:famedlysdk/src/event.dart';
import 'package:famedlysdk/src/room.dart'; import 'package:famedlysdk/src/room.dart';
import 'package:famedlysdk/src/timeline.dart';
import 'package:famedlysdk/src/user.dart'; import 'package:famedlysdk/src/user.dart';
import 'package:famedlysdk/src/utils/matrix_file.dart'; import 'package:famedlysdk/src/utils/matrix_file.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
@ -38,61 +37,61 @@ void main() {
Room room; Room room;
/// All Tests related to the Event /// All Tests related to the Event
group("Room", () { group('Room', () {
test('Login', () async { test('Login', () async {
matrix = Client("testclient", debug: true); matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi(); matrix.httpClient = FakeMatrixApi();
final bool checkResp = final checkResp =
await matrix.checkServer("https://fakeServer.notExisting"); await matrix.checkServer('https://fakeServer.notExisting');
final bool loginResp = await matrix.login("test", "1234"); final loginResp = await matrix.login('test', '1234');
expect(checkResp, true); expect(checkResp, true);
expect(loginResp, true); expect(loginResp, true);
}); });
test("Create from json", () async { test('Create from json', () async {
final String id = "!localpart:server.abc"; final id = '!localpart:server.abc';
final Membership membership = Membership.join; final membership = Membership.join;
final int notificationCount = 2; final notificationCount = 2;
final int highlightCount = 1; final highlightCount = 1;
final List<String> heroes = [ final heroes = [
"@alice:matrix.org", '@alice:matrix.org',
"@bob:example.com", '@bob:example.com',
"@charley:example.org" '@charley:example.org'
]; ];
Map<String, dynamic> jsonObj = { var jsonObj = <String, dynamic>{
"room_id": id, 'room_id': id,
"membership": membership.toString().split('.').last, 'membership': membership.toString().split('.').last,
"avatar_url": "", 'avatar_url': '',
"notification_count": notificationCount, 'notification_count': notificationCount,
"highlight_count": highlightCount, 'highlight_count': highlightCount,
"prev_batch": "", 'prev_batch': '',
"joined_member_count": notificationCount, 'joined_member_count': notificationCount,
"invited_member_count": notificationCount, 'invited_member_count': notificationCount,
"heroes": heroes.join(","), 'heroes': heroes.join(','),
}; };
Function states = () async => [ Function states = () async => [
{ {
"content": {"join_rule": "public"}, 'content': {'join_rule': 'public'},
"event_id": "143273582443PhrSn:example.org", 'event_id': '143273582443PhrSn:example.org',
"origin_server_ts": 1432735824653, 'origin_server_ts': 1432735824653,
"room_id": id, 'room_id': id,
"sender": "@example:example.org", 'sender': '@example:example.org',
"state_key": "", 'state_key': '',
"type": "m.room.join_rules", 'type': 'm.room.join_rules',
"unsigned": {"age": 1234} 'unsigned': {'age': 1234}
} }
]; ];
Function roomAccountData = () async => [ Function roomAccountData = () async => [
{ {
"content": {"foo": "bar"}, 'content': {'foo': 'bar'},
"room_id": id, 'room_id': id,
"type": "com.test.foo" 'type': 'com.test.foo'
} }
]; ];
@ -110,131 +109,131 @@ void main() {
expect(room.mJoinedMemberCount, notificationCount); expect(room.mJoinedMemberCount, notificationCount);
expect(room.mInvitedMemberCount, notificationCount); expect(room.mInvitedMemberCount, notificationCount);
expect(room.mHeroes, heroes); expect(room.mHeroes, heroes);
expect(room.displayname, "alice, bob, charley"); expect(room.displayname, 'alice, bob, charley');
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.states['m.room.canonical_alias'] = Event(
senderId: "@test:example.com", senderId: '@test:example.com',
typeKey: "m.room.canonical_alias", typeKey: '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.states['m.room.name'] = Event(
senderId: "@test:example.com", senderId: '@test:example.com',
typeKey: "m.room.name", typeKey: '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.states['m.room.topic'] = Event(
senderId: "@test:example.com", senderId: '@test:example.com',
typeKey: "m.room.topic", typeKey: '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.mxc, ""); expect(room.avatar.mxc, '');
room.states["m.room.avatar"] = Event( room.states['m.room.avatar'] = Event(
senderId: "@test:example.com", senderId: '@test:example.com',
typeKey: "m.room.avatar", typeKey: '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.mxc, "mxc://testurl"); expect(room.avatar.mxc, 'mxc://testurl');
room.states["m.room.message"] = Event( room.states['m.room.message'] = Event(
senderId: "@test:example.com", senderId: '@test:example.com',
typeKey: "m.room.message", typeKey: 'm.room.message',
roomId: room.id, roomId: room.id,
room: room, room: room,
eventId: "12345", eventId: '12345',
time: DateTime.now(), time: 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.lastMessage, "test"); expect(room.lastMessage, 'test');
expect(room.timeCreated, room.lastEvent.time); expect(room.timeCreated, room.lastEvent.time);
}); });
test("sendReadReceipt", () async { test('sendReadReceipt', () async {
await room.sendReadReceipt("§1234:fakeServer.notExisting"); await room.sendReadReceipt('§1234:fakeServer.notExisting');
}); });
test("requestParticipants", () async { test('requestParticipants', () async {
final List<User> participants = await room.requestParticipants(); final participants = await room.requestParticipants();
expect(participants.length, 1); expect(participants.length, 1);
User user = participants[0]; var user = participants[0];
expect(user.id, "@alice:example.org"); expect(user.id, '@alice:example.org');
expect(user.displayName, "Alice Margatroid"); expect(user.displayName, 'Alice Margatroid');
expect(user.membership, Membership.join); expect(user.membership, Membership.join);
expect(user.avatarUrl.mxc, "mxc://example.org/SEsfnsuifSDFSSEF"); expect(user.avatarUrl.mxc, 'mxc://example.org/SEsfnsuifSDFSSEF');
expect(user.room.id, "!localpart:server.abc"); expect(user.room.id, '!localpart:server.abc');
}); });
test("getEventByID", () async { test('getEventByID', () async {
final Event event = await room.getEventById("1234"); final event = await room.getEventById('1234');
expect(event.eventId, "143273582443PhrSn:example.org"); expect(event.eventId, '143273582443PhrSn:example.org');
}); });
test("setName", () async { test('setName', () async {
final String eventId = await room.setName("Testname"); final eventId = await room.setName('Testname');
expect(eventId, "42"); expect(eventId, '42');
}); });
test("setDescription", () async { test('setDescription', () async {
final String eventId = await room.setDescription("Testname"); final eventId = await room.setDescription('Testname');
expect(eventId, "42"); expect(eventId, '42');
}); });
test("kick", () async { test('kick', () async {
await room.kick("Testname"); await room.kick('Testname');
}); });
test("ban", () async { test('ban', () async {
await room.ban("Testname"); await room.ban('Testname');
}); });
test("unban", () async { test('unban', () async {
await room.unban("Testname"); await room.unban('Testname');
}); });
test("PowerLevels", () async { test('PowerLevels', () async {
room.states["m.room.power_levels"] = Event( room.states['m.room.power_levels'] = Event(
senderId: "@test:example.com", senderId: '@test:example.com',
typeKey: "m.room.power_levels", typeKey: 'm.room.power_levels',
roomId: room.id, roomId: room.id,
room: room, room: room,
eventId: "123", eventId: '123',
content: { content: {
"ban": 50, 'ban': 50,
"events": {"m.room.name": 100, "m.room.power_levels": 100}, 'events': {'m.room.name': 100, 'm.room.power_levels': 100},
"events_default": 0, 'events_default': 0,
"invite": 50, 'invite': 50,
"kick": 50, 'kick': 50,
"notifications": {"room": 20}, 'notifications': {'room': 20},
"redact": 50, 'redact': 50,
"state_default": 50, 'state_default': 50,
"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);
expect(room.ownPowerLevel, 100); expect(room.ownPowerLevel, 100);
expect(room.canBan, true); expect(room.canBan, true);
expect(room.canInvite, true); expect(room.canInvite, true);
@ -243,31 +242,31 @@ void main() {
expect(room.canSendDefaultMessages, true); expect(room.canSendDefaultMessages, true);
expect(room.canSendDefaultStates, true); expect(room.canSendDefaultStates, true);
expect(room.canChangePowerLevel, true); expect(room.canChangePowerLevel, true);
expect(room.canSendEvent("m.room.name"), true); expect(room.canSendEvent('m.room.name'), true);
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.states['m.room.power_levels'].content['users']);
room.states["m.room.power_levels"] = Event( room.states['m.room.power_levels'] = Event(
senderId: "@test:example.com", senderId: '@test:example.com',
typeKey: "m.room.power_levels", typeKey: 'm.room.power_levels',
roomId: room.id, roomId: room.id,
room: room, room: room,
eventId: "123abc", eventId: '123abc',
content: { content: {
"ban": 50, 'ban': 50,
"events": {"m.room.name": 0, "m.room.power_levels": 100}, 'events': {'m.room.name': 0, 'm.room.power_levels': 100},
"events_default": 0, 'events_default': 0,
"invite": 50, 'invite': 50,
"kick": 50, 'kick': 50,
"notifications": {"room": 20}, 'notifications': {'room': 20},
"redact": 50, 'redact': 50,
"state_default": 50, 'state_default': 50,
"users": {}, 'users': {},
"users_default": 0 'users_default': 0
}, },
stateKey: ""); stateKey: '');
expect(room.ownPowerLevel, 0); expect(room.ownPowerLevel, 0);
expect(room.canBan, false); expect(room.canBan, false);
expect(room.canInvite, false); expect(room.canInvite, false);
@ -276,70 +275,69 @@ void main() {
expect(room.canSendDefaultMessages, true); expect(room.canSendDefaultMessages, true);
expect(room.canSendDefaultStates, false); expect(room.canSendDefaultStates, false);
expect(room.canChangePowerLevel, false); expect(room.canChangePowerLevel, false);
expect(room.canSendEvent("m.room.name"), true); expect(room.canSendEvent('m.room.name'), true);
expect(room.canSendEvent("m.room.power_levels"), false); expect(room.canSendEvent('m.room.power_levels'), false);
expect(room.canSendEvent("m.room.member"), false); expect(room.canSendEvent('m.room.member'), false);
expect(room.canSendEvent("m.room.message"), true); expect(room.canSendEvent('m.room.message'), true);
final String resp = final resp = await room.setPower('@test:fakeServer.notExisting', 90);
await room.setPower("@test:fakeServer.notExisting", 90); expect(resp, '42');
expect(resp, "42");
}); });
test("invite", () async { test('invite', () async {
await room.invite("Testname"); await room.invite('Testname');
}); });
test("getParticipants", () async { test('getParticipants', () async {
room.setState(Event( room.setState(Event(
senderId: "@alice:test.abc", senderId: '@alice:test.abc',
typeKey: "m.room.member", typeKey: 'm.room.member',
roomId: room.id, roomId: room.id,
room: room, room: room,
eventId: "12345", eventId: '12345',
time: DateTime.now(), time: DateTime.now(),
content: {"displayname": "alice"}, content: {'displayname': 'alice'},
stateKey: "@alice:test.abc")); stateKey: '@alice:test.abc'));
final List<User> userList = room.getParticipants(); final userList = room.getParticipants();
expect(userList.length, 5); expect(userList.length, 5);
expect(userList[3].displayName, "Alice Margatroid"); expect(userList[3].displayName, 'Alice Margatroid');
}); });
test("addToDirectChat", () async { test('addToDirectChat', () async {
await room.addToDirectChat("Testname"); await room.addToDirectChat('Testname');
}); });
test("getTimeline", () async { test('getTimeline', () async {
final Timeline timeline = await room.getTimeline(); final timeline = await room.getTimeline();
expect(timeline.events, []); expect(timeline.events, []);
}); });
test("getUserByMXID", () async { test('getUserByMXID', () async {
User user; User user;
try { try {
user = await room.getUserByMXID("@getme:example.com"); user = await room.getUserByMXID('@getme:example.com');
} catch (_) {} } catch (_) {}
expect(user.stateKey, "@getme:example.com"); expect(user.stateKey, '@getme:example.com');
expect(user.calcDisplayname(), "You got me"); expect(user.calcDisplayname(), 'You got me');
}); });
test('setAvatar', () async { test('setAvatar', () async {
final MatrixFile testFile = final testFile =
MatrixFile(bytes: Uint8List(0), path: "fake/path/file.jpeg"); MatrixFile(bytes: Uint8List(0), path: 'fake/path/file.jpeg');
final dynamic resp = await room.setAvatar(testFile); final dynamic resp = await room.setAvatar(testFile);
expect(resp, "YUwRidLecu:example.com"); expect(resp, 'YUwRidLecu:example.com');
}); });
test('sendEvent', () async { test('sendEvent', () async {
final dynamic resp = await room.sendEvent( final dynamic resp = await room.sendEvent(
{"msgtype": "m.text", "body": "hello world"}, {'msgtype': 'm.text', 'body': 'hello world'},
txid: "testtxid"); txid: 'testtxid');
expect(resp, "42"); expect(resp, '42');
}); });
test('sendEvent', () async { test('sendEvent', () async {
final dynamic resp = final dynamic resp =
await room.sendTextEvent("Hello world", txid: "testtxid"); await room.sendTextEvent('Hello world', txid: 'testtxid');
expect(resp, "42"); expect(resp, '42');
}); });
// Not working because there is no real file to test it... // Not working because there is no real file to test it...
@ -351,38 +349,38 @@ void main() {
});*/ });*/
test('sendFileEvent', () async { test('sendFileEvent', () async {
final MatrixFile testFile = final testFile =
MatrixFile(bytes: Uint8List(0), path: "fake/path/file.jpeg"); MatrixFile(bytes: Uint8List(0), path: 'fake/path/file.jpeg');
final dynamic resp = await room.sendFileEvent(testFile, final dynamic resp = await room.sendFileEvent(testFile,
msgType: "m.file", txid: "testtxid"); msgType: 'm.file', txid: 'testtxid');
expect(resp, "mxc://example.com/AQwafuaFswefuhsfAFAgsw"); expect(resp, 'mxc://example.com/AQwafuaFswefuhsfAFAgsw');
}); });
test('pushRuleState', () async { test('pushRuleState', () async {
expect(room.pushRuleState, PushRuleState.mentions_only); expect(room.pushRuleState, PushRuleState.mentions_only);
matrix.accountData["m.push_rules"].content["global"]["override"] matrix.accountData['m.push_rules'].content['global']['override']
.add(matrix.accountData["m.push_rules"].content["global"]["room"][0]); .add(matrix.accountData['m.push_rules'].content['global']['room'][0]);
expect(room.pushRuleState, PushRuleState.dont_notify); expect(room.pushRuleState, PushRuleState.dont_notify);
}); });
test('Enable encryption', () async { test('Enable encryption', () async {
room.setState( room.setState(
Event( Event(
senderId: "@alice:test.abc", senderId: '@alice:test.abc',
typeKey: "m.room.encryption", typeKey: 'm.room.encryption',
roomId: room.id, roomId: room.id,
room: room, room: room,
eventId: "12345", eventId: '12345',
time: DateTime.now(), time: DateTime.now(),
content: { content: {
"algorithm": "m.megolm.v1.aes-sha2", 'algorithm': 'm.megolm.v1.aes-sha2',
"rotation_period_ms": 604800000, 'rotation_period_ms': 604800000,
"rotation_period_msgs": 100 'rotation_period_msgs': 100
}, },
stateKey: ""), stateKey: ''),
); );
expect(room.encrypted, true); expect(room.encrypted, true);
expect(room.encryptionAlgorithm, "m.megolm.v1.aes-sha2"); expect(room.encryptionAlgorithm, 'm.megolm.v1.aes-sha2');
expect(room.outboundGroupSession, null); expect(room.outboundGroupSession, null);
}); });
@ -396,7 +394,7 @@ void main() {
true); true);
expect( expect(
room.sessionKeys[room.outboundGroupSession.session_id()] room.sessionKeys[room.outboundGroupSession.session_id()]
.content["session_key"], .content['session_key'],
room.outboundGroupSession.session_key()); room.outboundGroupSession.session_key());
expect( expect(
room.sessionKeys[room.outboundGroupSession.session_id()].indexes room.sessionKeys[room.outboundGroupSession.session_id()].indexes
@ -412,30 +410,29 @@ void main() {
test('encryptGroupMessagePayload and decryptGroupMessage', () async { test('encryptGroupMessagePayload and decryptGroupMessage', () async {
if (!room.client.encryptionEnabled) return; if (!room.client.encryptionEnabled) return;
final Map<String, dynamic> payload = { final payload = {
"msgtype": "m.text", 'msgtype': 'm.text',
"body": "Hello world", 'body': 'Hello world',
}; };
final Map<String, dynamic> encryptedPayload = final encryptedPayload = await room.encryptGroupMessagePayload(payload);
await room.encryptGroupMessagePayload(payload); expect(encryptedPayload['algorithm'], 'm.megolm.v1.aes-sha2');
expect(encryptedPayload["algorithm"], "m.megolm.v1.aes-sha2"); expect(encryptedPayload['ciphertext'].isNotEmpty, true);
expect(encryptedPayload["ciphertext"].isNotEmpty, true); expect(encryptedPayload['device_id'], room.client.deviceID);
expect(encryptedPayload["device_id"], room.client.deviceID); expect(encryptedPayload['sender_key'], room.client.identityKey);
expect(encryptedPayload["sender_key"], room.client.identityKey); expect(encryptedPayload['session_id'],
expect(encryptedPayload["session_id"],
room.outboundGroupSession.session_id()); room.outboundGroupSession.session_id());
Event encryptedEvent = Event( var encryptedEvent = Event(
content: encryptedPayload, content: encryptedPayload,
typeKey: "m.room.encrypted", typeKey: 'm.room.encrypted',
senderId: room.client.userID, senderId: room.client.userID,
eventId: "1234", eventId: '1234',
roomId: room.id, roomId: room.id,
room: room, room: room,
time: DateTime.now(), time: DateTime.now(),
); );
Event decryptedEvent = room.decryptGroupMessage(encryptedEvent); var decryptedEvent = room.decryptGroupMessage(encryptedEvent);
expect(decryptedEvent.typeKey, "m.room.message"); expect(decryptedEvent.typeKey, 'm.room.message');
expect(decryptedEvent.content, payload); expect(decryptedEvent.content, payload);
}); });
}); });

View file

@ -27,48 +27,48 @@ import 'package:famedlysdk/src/utils/states_map.dart';
void main() { void main() {
/// All Tests related to the ChatTime /// All Tests related to the ChatTime
group("StateKeys", () { group('StateKeys', () {
test("Operator overload", () async { test('Operator overload', () async {
StatesMap states = StatesMap(); var states = StatesMap();
states["m.room.name"] = Event( states['m.room.name'] = Event(
eventId: "1", eventId: '1',
content: {"name": "test"}, content: {'name': 'test'},
typeKey: "m.room.name", typeKey: 'm.room.name',
stateKey: "", stateKey: '',
roomId: "!test:test.test", roomId: '!test:test.test',
senderId: "@alice:test.test"); senderId: '@alice:test.test');
states["@alice:test.test"] = Event( states['@alice:test.test'] = Event(
eventId: "2", eventId: '2',
content: {"membership": "join"}, content: {'membership': 'join'},
typeKey: "m.room.name", typeKey: 'm.room.name',
stateKey: "@alice:test.test", stateKey: '@alice:test.test',
roomId: "!test:test.test", roomId: '!test:test.test',
senderId: "@alice:test.test"); senderId: '@alice:test.test');
states["m.room.member"]["@bob:test.test"] = Event( states['m.room.member']['@bob:test.test'] = Event(
eventId: "3", eventId: '3',
content: {"membership": "join"}, content: {'membership': 'join'},
typeKey: "m.room.name", typeKey: 'm.room.name',
stateKey: "@bob:test.test", stateKey: '@bob:test.test',
roomId: "!test:test.test", roomId: '!test:test.test',
senderId: "@bob:test.test"); senderId: '@bob:test.test');
states["com.test.custom"] = Event( states['com.test.custom'] = Event(
eventId: "4", eventId: '4',
content: {"custom": "stuff"}, content: {'custom': 'stuff'},
typeKey: "com.test.custom", typeKey: 'com.test.custom',
stateKey: "customStateKey", stateKey: 'customStateKey',
roomId: "!test:test.test", roomId: '!test:test.test',
senderId: "@bob:test.test"); senderId: '@bob:test.test');
expect(states["m.room.name"].eventId, "1"); expect(states['m.room.name'].eventId, '1');
expect(states["@alice:test.test"].eventId, "2"); expect(states['@alice:test.test'].eventId, '2');
expect(states["m.room.member"]["@alice:test.test"].eventId, "2"); expect(states['m.room.member']['@alice:test.test'].eventId, '2');
expect(states["@bob:test.test"].eventId, "3"); expect(states['@bob:test.test'].eventId, '3');
expect(states["m.room.member"]["@bob:test.test"].eventId, "3"); expect(states['m.room.member']['@bob:test.test'].eventId, '3');
expect(states["m.room.member"].length, 2); expect(states['m.room.member'].length, 2);
expect(states["com.test.custom"]["customStateKey"].eventId, "4"); expect(states['com.test.custom']['customStateKey'].eventId, '4');
}); });
}); });
} }

View file

@ -31,18 +31,18 @@ import 'fake_matrix_api.dart';
void main() { void main() {
/// All Tests related to the MxContent /// All Tests related to the MxContent
group("Timeline", () { group('Timeline', () {
final String roomID = "!1234:example.com"; final roomID = '!1234:example.com';
final testTimeStamp = DateTime.now().millisecondsSinceEpoch; final testTimeStamp = DateTime.now().millisecondsSinceEpoch;
int updateCount = 0; var updateCount = 0;
List<int> insertList = []; var insertList = <int>[];
Client client = Client("testclient", debug: true); var client = Client('testclient', debug: true);
client.httpClient = FakeMatrixApi(); client.httpClient = FakeMatrixApi();
Room room = Room( var room = Room(
id: roomID, client: client, prev_batch: "1234", roomAccountData: {}); id: roomID, client: client, prev_batch: '1234', roomAccountData: {});
Timeline timeline = Timeline( var timeline = Timeline(
room: room, room: room,
events: [], events: [],
onUpdate: () { onUpdate: () {
@ -52,32 +52,32 @@ void main() {
insertList.add(insertID); insertList.add(insertID);
}); });
test("Create", () async { test('Create', () async {
await client.checkServer("https://fakeServer.notExisting"); await client.checkServer('https://fakeServer.notExisting');
client.onEvent.add(EventUpdate( client.onEvent.add(EventUpdate(
type: "timeline", type: 'timeline',
roomID: roomID, roomID: roomID,
eventType: "m.room.message", eventType: 'm.room.message',
content: { content: {
"type": "m.room.message", 'type': 'm.room.message',
"content": {"msgtype": "m.text", "body": "Testcase"}, 'content': {'msgtype': 'm.text', 'body': 'Testcase'},
"sender": "@alice:example.com", 'sender': '@alice:example.com',
"status": 2, 'status': 2,
"event_id": "1", 'event_id': '1',
"origin_server_ts": testTimeStamp 'origin_server_ts': testTimeStamp
})); }));
client.onEvent.add(EventUpdate( client.onEvent.add(EventUpdate(
type: "timeline", type: 'timeline',
roomID: roomID, roomID: roomID,
eventType: "m.room.message", eventType: 'm.room.message',
content: { content: {
"type": "m.room.message", 'type': 'm.room.message',
"content": {"msgtype": "m.text", "body": "Testcase"}, 'content': {'msgtype': 'm.text', 'body': 'Testcase'},
"sender": "@alice:example.com", 'sender': '@alice:example.com',
"status": 2, 'status': 2,
"event_id": "2", 'event_id': '2',
"origin_server_ts": testTimeStamp - 1000 'origin_server_ts': testTimeStamp - 1000
})); }));
expect(timeline.sub != null, true); expect(timeline.sub != null, true);
@ -88,43 +88,43 @@ void main() {
expect(insertList, [0, 0]); expect(insertList, [0, 0]);
expect(insertList.length, timeline.events.length); expect(insertList.length, timeline.events.length);
expect(timeline.events.length, 2); expect(timeline.events.length, 2);
expect(timeline.events[0].eventId, "1"); expect(timeline.events[0].eventId, '1');
expect(timeline.events[0].sender.id, "@alice:example.com"); expect(timeline.events[0].sender.id, '@alice:example.com');
expect(timeline.events[0].time.millisecondsSinceEpoch, testTimeStamp); expect(timeline.events[0].time.millisecondsSinceEpoch, testTimeStamp);
expect(timeline.events[0].body, "Testcase"); expect(timeline.events[0].body, 'Testcase');
expect( expect(
timeline.events[0].time.millisecondsSinceEpoch > timeline.events[0].time.millisecondsSinceEpoch >
timeline.events[1].time.millisecondsSinceEpoch, timeline.events[1].time.millisecondsSinceEpoch,
true); true);
expect(timeline.events[0].receipts, []); expect(timeline.events[0].receipts, []);
room.roomAccountData["m.receipt"] = RoomAccountData.fromJson({ room.roomAccountData['m.receipt'] = RoomAccountData.fromJson({
"type": "m.receipt", 'type': 'm.receipt',
"content": { 'content': {
"@alice:example.com": { '@alice:example.com': {
"event_id": "1", 'event_id': '1',
"ts": 1436451550453, 'ts': 1436451550453,
} }
}, },
"room_id": roomID, 'room_id': roomID,
}, room); }, room);
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
expect(timeline.events[0].receipts.length, 1); expect(timeline.events[0].receipts.length, 1);
expect(timeline.events[0].receipts[0].user.id, "@alice:example.com"); expect(timeline.events[0].receipts[0].user.id, '@alice:example.com');
client.onEvent.add(EventUpdate( client.onEvent.add(EventUpdate(
type: "timeline", type: 'timeline',
roomID: roomID, roomID: roomID,
eventType: "m.room.redaction", eventType: 'm.room.redaction',
content: { content: {
"type": "m.room.redaction", 'type': 'm.room.redaction',
"content": {"reason": "spamming"}, 'content': {'reason': 'spamming'},
"sender": "@alice:example.com", 'sender': '@alice:example.com',
"redacts": "2", 'redacts': '2',
"event_id": "3", 'event_id': '3',
"origin_server_ts": testTimeStamp + 1000 'origin_server_ts': testTimeStamp + 1000
})); }));
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
@ -136,29 +136,29 @@ void main() {
expect(timeline.events[1].redacted, true); expect(timeline.events[1].redacted, true);
}); });
test("Send message", () async { test('Send message', () async {
await room.sendTextEvent("test", txid: "1234"); await room.sendTextEvent('test', txid: '1234');
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
expect(updateCount, 5); expect(updateCount, 5);
expect(insertList, [0, 0, 0]); expect(insertList, [0, 0, 0]);
expect(insertList.length, timeline.events.length); expect(insertList.length, timeline.events.length);
expect(timeline.events[0].eventId, "42"); expect(timeline.events[0].eventId, '42');
expect(timeline.events[0].status, 1); expect(timeline.events[0].status, 1);
client.onEvent.add(EventUpdate( client.onEvent.add(EventUpdate(
type: "timeline", type: 'timeline',
roomID: roomID, roomID: roomID,
eventType: "m.room.message", eventType: 'm.room.message',
content: { content: {
"type": "m.room.message", 'type': 'm.room.message',
"content": {"msgtype": "m.text", "body": "test"}, 'content': {'msgtype': 'm.text', 'body': 'test'},
"sender": "@alice:example.com", 'sender': '@alice:example.com',
"status": 2, 'status': 2,
"event_id": "42", 'event_id': '42',
"unsigned": {"transaction_id": "1234"}, 'unsigned': {'transaction_id': '1234'},
"origin_server_ts": DateTime.now().millisecondsSinceEpoch 'origin_server_ts': DateTime.now().millisecondsSinceEpoch
})); }));
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
@ -166,29 +166,29 @@ void main() {
expect(updateCount, 6); expect(updateCount, 6);
expect(insertList, [0, 0, 0]); expect(insertList, [0, 0, 0]);
expect(insertList.length, timeline.events.length); expect(insertList.length, timeline.events.length);
expect(timeline.events[0].eventId, "42"); expect(timeline.events[0].eventId, '42');
expect(timeline.events[0].status, 2); expect(timeline.events[0].status, 2);
}); });
test("Send message with error", () async { test('Send message with error', () async {
client.onEvent.add(EventUpdate( client.onEvent.add(EventUpdate(
type: "timeline", type: 'timeline',
roomID: roomID, roomID: roomID,
eventType: "m.room.message", eventType: 'm.room.message',
content: { content: {
"type": "m.room.message", 'type': 'm.room.message',
"content": {"msgtype": "m.text", "body": "Testcase"}, 'content': {'msgtype': 'm.text', 'body': 'Testcase'},
"sender": "@alice:example.com", 'sender': '@alice:example.com',
"status": 0, 'status': 0,
"event_id": "abc", 'event_id': 'abc',
"origin_server_ts": testTimeStamp 'origin_server_ts': testTimeStamp
})); }));
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
await room.sendTextEvent("test", txid: "errortxid"); await room.sendTextEvent('test', txid: 'errortxid');
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
await room.sendTextEvent("test", txid: "errortxid2"); await room.sendTextEvent('test', txid: 'errortxid2');
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
await room.sendTextEvent("test", txid: "errortxid3"); await room.sendTextEvent('test', txid: 'errortxid3');
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
expect(updateCount, 13); expect(updateCount, 13);
@ -199,7 +199,7 @@ void main() {
expect(timeline.events[2].status, -1); expect(timeline.events[2].status, -1);
}); });
test("Remove message", () async { test('Remove message', () async {
await timeline.events[0].remove(); await timeline.events[0].remove();
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
@ -211,8 +211,8 @@ void main() {
expect(timeline.events[0].status, -1); expect(timeline.events[0].status, -1);
}); });
test("Resend message", () async { test('Resend message', () async {
await timeline.events[0].sendAgain(txid: "1234"); await timeline.events[0].sendAgain(txid: '1234');
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
@ -223,17 +223,17 @@ void main() {
expect(timeline.events[0].status, 1); expect(timeline.events[0].status, 1);
}); });
test("Request history", () async { test('Request history', () async {
await room.requestHistory(); await room.requestHistory();
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
expect(updateCount, 20); expect(updateCount, 20);
expect(timeline.events.length, 9); expect(timeline.events.length, 9);
expect(timeline.events[6].eventId, "1143273582443PhrSn:example.org"); expect(timeline.events[6].eventId, '1143273582443PhrSn:example.org');
expect(timeline.events[7].eventId, "2143273582443PhrSn:example.org"); expect(timeline.events[7].eventId, '2143273582443PhrSn:example.org');
expect(timeline.events[8].eventId, "3143273582443PhrSn:example.org"); expect(timeline.events[8].eventId, '3143273582443PhrSn:example.org');
expect(room.prev_batch, "t47409-4357353_219380_26003_2265"); expect(room.prev_batch, 't47409-4357353_219380_26003_2265');
}); });
}); });
} }

View file

@ -27,29 +27,29 @@ import 'package:test/test.dart';
void main() { void main() {
/// All Tests related to the Event /// All Tests related to the Event
group("User", () { group('User', () {
test("Create from json", () async { test('Create from json', () async {
final String id = "@alice:server.abc"; final id = '@alice:server.abc';
final Membership membership = Membership.join; final membership = Membership.join;
final String displayName = "Alice"; final displayName = 'Alice';
final String avatarUrl = ""; final avatarUrl = '';
final Map<String, dynamic> jsonObj = { final jsonObj = {
"content": { 'content': {
"membership": "join", 'membership': 'join',
"avatar_url": avatarUrl, 'avatar_url': avatarUrl,
"displayname": displayName 'displayname': displayName
}, },
"type": "m.room.member", 'type': 'm.room.member',
"event_id": "143273582443PhrSn:example.org", 'event_id': '143273582443PhrSn:example.org',
"room_id": "!636q39766251:example.com", 'room_id': '!636q39766251:example.com',
"sender": id, 'sender': id,
"origin_server_ts": 1432735824653, 'origin_server_ts': 1432735824653,
"unsigned": {"age": 1234}, 'unsigned': {'age': 1234},
"state_key": id 'state_key': id
}; };
User user = Event.fromJson(jsonObj, null).asUser; var user = Event.fromJson(jsonObj, null).asUser;
expect(user.id, id); expect(user.id, id);
expect(user.membership, membership); expect(user.membership, membership);
@ -58,13 +58,13 @@ void main() {
expect(user.calcDisplayname(), displayName); expect(user.calcDisplayname(), displayName);
}); });
test("calcDisplayname", () async { test('calcDisplayname', () async {
final User user1 = User("@alice:example.com"); final user1 = User('@alice:example.com');
final User user2 = User("@SuperAlice:example.com"); final user2 = User('@SuperAlice:example.com');
final User user3 = User("@alice:example.com"); final user3 = User('@alice:example.com');
expect(user1.calcDisplayname(), "alice"); expect(user1.calcDisplayname(), 'alice');
expect(user2.calcDisplayname(), "SuperAlice"); expect(user2.calcDisplayname(), 'SuperAlice');
expect(user3.calcDisplayname(), "alice"); expect(user3.calcDisplayname(), 'alice');
}); });
}); });
} }

View file

@ -3,36 +3,36 @@ import '../test/fake_store.dart';
void main() => test(); void main() => test();
const String homeserver = "https://matrix.test.famedly.de"; const String homeserver = 'https://matrix.test.famedly.de';
const String testUserA = "@tick:test.famedly.de"; const String testUserA = '@tick:test.famedly.de';
const String testPasswordA = "test"; const String testPasswordA = 'test';
const String testUserB = "@trick:test.famedly.de"; const String testUserB = '@trick:test.famedly.de';
const String testPasswordB = "test"; const String testPasswordB = 'test';
const String testMessage = "Hello world"; const String testMessage = 'Hello world';
const String testMessage2 = "Hello moon"; const String testMessage2 = 'Hello moon';
const String testMessage3 = "Hello sun"; const String testMessage3 = 'Hello sun';
const String testMessage4 = "Hello star"; const String testMessage4 = 'Hello star';
const String testMessage5 = "Hello earth"; const String testMessage5 = 'Hello earth';
const String testMessage6 = "Hello mars"; const String testMessage6 = 'Hello mars';
void test() async { void test() async {
print("++++ Login $testUserA ++++"); print('++++ Login $testUserA ++++');
Client testClientA = Client("TestClient", debug: false); var testClientA = Client('TestClient', debug: false);
testClientA.storeAPI = FakeStore(testClientA, Map<String, dynamic>()); testClientA.storeAPI = FakeStore(testClientA, <String, dynamic>{});
await testClientA.checkServer(homeserver); await testClientA.checkServer(homeserver);
await testClientA.login(testUserA, testPasswordA); await testClientA.login(testUserA, testPasswordA);
assert(testClientA.encryptionEnabled); assert(testClientA.encryptionEnabled);
print("++++ Login $testUserB ++++"); print('++++ Login $testUserB ++++');
Client testClientB = Client("TestClient", debug: false); var testClientB = Client('TestClient', debug: false);
testClientB.storeAPI = FakeStore(testClientB, Map<String, dynamic>()); testClientB.storeAPI = FakeStore(testClientB, <String, dynamic>{});
await testClientB.checkServer(homeserver); await testClientB.checkServer(homeserver);
await testClientB.login(testUserB, testPasswordA); await testClientB.login(testUserB, testPasswordA);
assert(testClientB.encryptionEnabled); assert(testClientB.encryptionEnabled);
print("++++ ($testUserA) Leave all rooms ++++"); print('++++ ($testUserA) Leave all rooms ++++');
while (testClientA.rooms.isNotEmpty) { while (testClientA.rooms.isNotEmpty) {
Room room = testClientA.rooms.first; var room = testClientA.rooms.first;
if (room.canonicalAlias?.isNotEmpty ?? false) { if (room.canonicalAlias?.isNotEmpty ?? false) {
break; break;
} }
@ -44,10 +44,10 @@ void test() async {
} }
} }
print("++++ ($testUserB) Leave all rooms ++++"); print('++++ ($testUserB) Leave all rooms ++++');
for (int i = 0; i < 3; i++) { for (var i = 0; i < 3; i++) {
if (testClientB.rooms.isNotEmpty) { if (testClientB.rooms.isNotEmpty) {
Room room = testClientB.rooms.first; var room = testClientB.rooms.first;
try { try {
await room.leave(); await room.leave();
await room.forget(); await room.forget();
@ -57,7 +57,7 @@ void test() async {
} }
} }
print("++++ Check if own olm device is verified by default ++++"); print('++++ Check if own olm device is verified by default ++++');
assert(testClientA.userDeviceKeys.containsKey(testUserA)); assert(testClientA.userDeviceKeys.containsKey(testUserA));
assert(testClientA.userDeviceKeys[testUserA].deviceKeys assert(testClientA.userDeviceKeys[testUserA].deviceKeys
.containsKey(testClientA.deviceID)); .containsKey(testClientA.deviceID));
@ -73,27 +73,27 @@ void test() async {
assert(!testClientB assert(!testClientB
.userDeviceKeys[testUserB].deviceKeys[testClientB.deviceID].blocked); .userDeviceKeys[testUserB].deviceKeys[testClientB.deviceID].blocked);
print("++++ ($testUserA) Create room and invite $testUserB ++++"); print('++++ ($testUserA) Create room and invite $testUserB ++++');
await testClientA.createRoom(invite: [User(testUserB)]); await testClientA.createRoom(invite: [User(testUserB)]);
await Future.delayed(Duration(seconds: 1)); await Future.delayed(Duration(seconds: 1));
Room room = testClientA.rooms.first; var room = testClientA.rooms.first;
assert(room != null); assert(room != null);
final String roomId = room.id; final roomId = room.id;
print("++++ ($testUserB) Join room ++++"); print('++++ ($testUserB) Join room ++++');
Room inviteRoom = testClientB.getRoomById(roomId); var inviteRoom = testClientB.getRoomById(roomId);
await inviteRoom.join(); await inviteRoom.join();
await Future.delayed(Duration(seconds: 1)); await Future.delayed(Duration(seconds: 1));
assert(inviteRoom.membership == Membership.join); assert(inviteRoom.membership == Membership.join);
print("++++ ($testUserA) Enable encryption ++++"); print('++++ ($testUserA) Enable encryption ++++');
assert(room.encrypted == false); assert(room.encrypted == false);
await room.enableEncryption(); await room.enableEncryption();
await Future.delayed(Duration(seconds: 5)); await Future.delayed(Duration(seconds: 5));
assert(room.encrypted == true); assert(room.encrypted == true);
assert(room.outboundGroupSession == null); assert(room.outboundGroupSession == null);
print("++++ ($testUserA) Check known olm devices ++++"); print('++++ ($testUserA) Check known olm devices ++++');
assert(testClientA.userDeviceKeys.containsKey(testUserB)); assert(testClientA.userDeviceKeys.containsKey(testUserB));
assert(testClientA.userDeviceKeys[testUserB].deviceKeys assert(testClientA.userDeviceKeys[testUserB].deviceKeys
.containsKey(testClientB.deviceID)); .containsKey(testClientB.deviceID));
@ -111,7 +111,7 @@ void test() async {
await testClientA.userDeviceKeys[testUserB].deviceKeys[testClientB.deviceID] await testClientA.userDeviceKeys[testUserB].deviceKeys[testClientB.deviceID]
.setVerified(true, testClientA); .setVerified(true, testClientA);
print("++++ Check if own olm device is verified by default ++++"); print('++++ Check if own olm device is verified by default ++++');
assert(testClientA.userDeviceKeys.containsKey(testUserA)); assert(testClientA.userDeviceKeys.containsKey(testUserA));
assert(testClientA.userDeviceKeys[testUserA].deviceKeys assert(testClientA.userDeviceKeys[testUserA].deviceKeys
.containsKey(testClientA.deviceID)); .containsKey(testClientA.deviceID));
@ -127,7 +127,7 @@ void test() async {
await room.sendTextEvent(testMessage); await room.sendTextEvent(testMessage);
await Future.delayed(Duration(seconds: 5)); await Future.delayed(Duration(seconds: 5));
assert(room.outboundGroupSession != null); assert(room.outboundGroupSession != null);
String currentSessionIdA = room.outboundGroupSession.session_id(); var currentSessionIdA = room.outboundGroupSession.session_id();
assert(room.sessionKeys.containsKey(room.outboundGroupSession.session_id())); assert(room.sessionKeys.containsKey(room.outboundGroupSession.session_id()));
assert(testClientA.olmSessions[testClientB.identityKey].length == 1); assert(testClientA.olmSessions[testClientB.identityKey].length == 1);
assert(testClientB.olmSessions[testClientA.identityKey].length == 1); assert(testClientB.olmSessions[testClientA.identityKey].length == 1);
@ -172,9 +172,9 @@ void test() async {
print( print(
"++++ ($testUserA) Received decrypted message: '${room.lastMessage}' ++++"); "++++ ($testUserA) Received decrypted message: '${room.lastMessage}' ++++");
print("++++ Login $testUserB in another client ++++"); print('++++ Login $testUserB in another client ++++');
Client testClientC = Client("TestClient", debug: false); var testClientC = Client('TestClient', debug: false);
testClientC.storeAPI = FakeStore(testClientC, Map<String, dynamic>()); testClientC.storeAPI = FakeStore(testClientC, <String, dynamic>{});
await testClientC.checkServer(homeserver); await testClientC.checkServer(homeserver);
await testClientC.login(testUserB, testPasswordA); await testClientC.login(testUserB, testPasswordA);
await Future.delayed(Duration(seconds: 3)); await Future.delayed(Duration(seconds: 3));
@ -200,7 +200,7 @@ void test() async {
print( print(
"++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++"); "++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");
print("++++ Logout $testUserB another client ++++"); print('++++ Logout $testUserB another client ++++');
await testClientC.logout(); await testClientC.logout();
testClientC = null; testClientC = null;
await Future.delayed(Duration(seconds: 5)); await Future.delayed(Duration(seconds: 5));
@ -223,20 +223,20 @@ void test() async {
print( print(
"++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++"); "++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");
print("++++ ($testUserA) Restore user ++++"); print('++++ ($testUserA) Restore user ++++');
FakeStore clientAStore = testClientA.storeAPI; FakeStore clientAStore = testClientA.storeAPI;
testClientA = null; testClientA = null;
testClientA = Client("TestClient", debug: false); testClientA = Client('TestClient', debug: false);
testClientA.storeAPI = FakeStore(testClientA, clientAStore.storeMap); testClientA.storeAPI = FakeStore(testClientA, clientAStore.storeMap);
await Future.delayed(Duration(seconds: 3)); await Future.delayed(Duration(seconds: 3));
Room restoredRoom = testClientA.rooms.first; var restoredRoom = testClientA.rooms.first;
assert(room != null); assert(room != null);
assert(restoredRoom.id == room.id); assert(restoredRoom.id == room.id);
assert(restoredRoom.outboundGroupSession.session_id() == assert(restoredRoom.outboundGroupSession.session_id() ==
room.outboundGroupSession.session_id()); room.outboundGroupSession.session_id());
assert(restoredRoom.sessionKeys.length == 4); assert(restoredRoom.sessionKeys.length == 4);
assert(restoredRoom.sessionKeys.length == room.sessionKeys.length); assert(restoredRoom.sessionKeys.length == room.sessionKeys.length);
for (int i = 0; i < restoredRoom.sessionKeys.length; i++) { for (var i = 0; i < restoredRoom.sessionKeys.length; i++) {
assert(restoredRoom.sessionKeys.keys.toList()[i] == assert(restoredRoom.sessionKeys.keys.toList()[i] ==
room.sessionKeys.keys.toList()[i]); room.sessionKeys.keys.toList()[i]);
} }
@ -261,16 +261,16 @@ void test() async {
print( print(
"++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++"); "++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");
print("++++ Logout $testUserA and $testUserB ++++"); print('++++ Logout $testUserA and $testUserB ++++');
await room.leave(); await room.leave();
await room.forget(); await room.forget();
await inviteRoom.leave(); await inviteRoom.leave();
await inviteRoom.forget(); await inviteRoom.forget();
await Future.delayed(Duration(seconds: 1)); await Future.delayed(Duration(seconds: 1));
await testClientA.jsonRequest( await testClientA.jsonRequest(
type: HTTPType.POST, action: "/client/r0/logout/all"); type: HTTPType.POST, action: '/client/r0/logout/all');
await testClientB.jsonRequest( await testClientB.jsonRequest(
type: HTTPType.POST, action: "/client/r0/logout/all"); type: HTTPType.POST, action: '/client/r0/logout/all');
testClientA = null; testClientA = null;
testClientB = null; testClientB = null;
return; return;