From 384e5962d6ec7fc132cf1ddbd38e8cf3f4df40ec Mon Sep 17 00:00:00 2001 From: Sorunome Date: Fri, 22 May 2020 11:15:48 +0000 Subject: [PATCH 1/4] properly persist decryption of events --- lib/src/event.dart | 19 +++++++++++++++++++ lib/src/room.dart | 18 +++--------------- lib/src/timeline.dart | 25 ++++++++++++++++--------- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/lib/src/event.dart b/lib/src/event.dart index e3699d7..cbd96f0 100644 --- a/lib/src/event.dart +++ b/lib/src/event.dart @@ -425,6 +425,25 @@ class Event { /// if it fails and does nothing if the event was not encrypted. Event get decrypted => room.decryptGroupMessage(this); + /// Trys to decrypt this event and persists it in the database afterwards + Future decryptAndStore([String updateType = 'timeline']) async { + final newEvent = decrypted; + if (newEvent.type == EventTypes.Encrypted || room.client.database == null) { + return newEvent; // decryption failed or we don't have a database + } + await room.client.database.storeEventUpdate( + room.client.id, + EventUpdate( + eventType: newEvent.typeKey, + content: newEvent.toJson(), + roomID: newEvent.roomId, + type: updateType, + sortOrder: newEvent.sortOrder, + ), + ); + return newEvent; + } + /// If this event is encrypted and the decryption was not successful because /// the session is unknown, this requests the session key from other devices /// in the room. If the event is not encrypted or the decryption failed because diff --git a/lib/src/room.dart b/lib/src/room.dart index 4d199ea..1823d3e 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -271,9 +271,9 @@ class Room { onSessionKeyReceived.add(sessionId); } - void _tryAgainDecryptLastMessage() { + Future _tryAgainDecryptLastMessage() async { if (getState('m.room.encrypted') != null) { - final decrypted = getState('m.room.encrypted').decrypted; + final decrypted = await getState('m.room.encrypted').decryptAndStore(); if (decrypted.type != EventTypes.Encrypted) { setState(decrypted); } @@ -1207,19 +1207,7 @@ class Room { if (events[i].type == EventTypes.Encrypted && events[i].content['body'] == DecryptError.UNKNOWN_SESSION) { await events[i].loadSession(); - events[i] = events[i].decrypted; - if (events[i].type != EventTypes.Encrypted) { - await client.database.storeEventUpdate( - client.id, - EventUpdate( - eventType: events[i].typeKey, - content: events[i].toJson(), - roomID: events[i].roomId, - type: 'timeline', - sortOrder: events[i].sortOrder, - ), - ); - } + events[i] = await events[i].decryptAndStore(); } } }); diff --git a/lib/src/timeline.dart b/lib/src/timeline.dart index 9ff2a87..aabf279 100644 --- a/lib/src/timeline.dart +++ b/lib/src/timeline.dart @@ -97,18 +97,25 @@ class Timeline { sessionIdReceivedSub?.cancel(); } - void _sessionKeyReceived(String sessionId) { + void _sessionKeyReceived(String sessionId) async { var decryptAtLeastOneEvent = false; - for (var i = 0; i < events.length; i++) { - if (events[i].type == EventTypes.Encrypted && - events[i].messageType == MessageTypes.BadEncrypted && - events[i].content['body'] == DecryptError.UNKNOWN_SESSION && - events[i].content['session_id'] == sessionId) { - events[i] = events[i].decrypted; - if (events[i].type != EventTypes.Encrypted) { - decryptAtLeastOneEvent = true; + final decryptFn = () async { + for (var i = 0; i < events.length; i++) { + if (events[i].type == EventTypes.Encrypted && + events[i].messageType == MessageTypes.BadEncrypted && + events[i].content['body'] == DecryptError.UNKNOWN_SESSION && + events[i].content['session_id'] == sessionId) { + events[i] = await events[i].decryptAndStore(); + if (events[i].type != EventTypes.Encrypted) { + decryptAtLeastOneEvent = true; + } } } + }; + if (room.client.database != null) { + await room.client.database.transaction(decryptFn); + } else { + await decryptFn(); } if (decryptAtLeastOneEvent) onUpdate(); } From c01f75bafa29139a76b1b1601a4a244280d60e5b Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Fri, 22 May 2020 15:51:45 +0200 Subject: [PATCH 2/4] Add olm error stream --- lib/src/client.dart | 19 +++++++++++++++---- lib/src/utils/to_device_event.dart | 14 ++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/lib/src/client.dart b/lib/src/client.dart index d8a0b7f..a0751a3 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -639,6 +639,10 @@ class Client { final StreamController onError = StreamController.broadcast(); + /// Synchronization erros are coming here. + final StreamController onOlmError = + StreamController.broadcast(); + /// This is called once, when the first sync has received. final StreamController onFirstSync = StreamController.broadcast(); @@ -1134,11 +1138,18 @@ class Client { if (toDeviceEvent.type == 'm.room.encrypted') { try { toDeviceEvent = decryptToDeviceEvent(toDeviceEvent); - } catch (e) { + } catch (e, s) { print( - '[LibOlm] Could not decrypt to device event from ${toDeviceEvent.sender}: ' + - e.toString()); - print(toDeviceEvent.sender); + '[LibOlm] Could not decrypt to device event from ${toDeviceEvent.sender} with content: ${toDeviceEvent.content}'); + print(e); + print(s); + onOlmError.add( + ToDeviceEventDecryptionError( + exception: e, + stackTrace: s, + toDeviceEvent: toDeviceEvent, + ), + ); toDeviceEvent = ToDeviceEvent.fromJson(events[i]); } } diff --git a/lib/src/utils/to_device_event.dart b/lib/src/utils/to_device_event.dart index 11d0fa2..3b7f59d 100644 --- a/lib/src/utils/to_device_event.dart +++ b/lib/src/utils/to_device_event.dart @@ -24,3 +24,17 @@ class ToDeviceEvent { return data; } } + +class ToDeviceEventDecryptionError extends ToDeviceEvent { + Exception exception; + StackTrace stackTrace; + ToDeviceEventDecryptionError({ + ToDeviceEvent toDeviceEvent, + this.exception, + this.stackTrace, + }) : super( + sender: toDeviceEvent.sender, + content: toDeviceEvent.content, + type: toDeviceEvent.type, + ); +} From f7b29f3703642b4d0a5c7af062d2843815487e37 Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Mon, 25 May 2020 07:31:17 +0000 Subject: [PATCH 3/4] Ignore key requests from unknown devices --- lib/src/client.dart | 2 +- lib/src/utils/room_key_request.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/client.dart b/lib/src/client.dart index a0751a3..6282788 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -1574,7 +1574,7 @@ class Client { deviceKeys.verified && !deviceKeys.blocked) { await roomKeyRequest.forwardKey(); - } else { + } else if (roomKeyRequest.requestingDevice != null) { onRoomKeyRequest.add(roomKeyRequest); } } diff --git a/lib/src/utils/room_key_request.dart b/lib/src/utils/room_key_request.dart index 8f3d1bd..778e93e 100644 --- a/lib/src/utils/room_key_request.dart +++ b/lib/src/utils/room_key_request.dart @@ -22,7 +22,7 @@ class RoomKeyRequest extends ToDeviceEvent { for (final key in session.forwardingCurve25519KeyChain) { forwardedKeys.add(key); } - await requestingDevice?.setVerified(true, client); + await requestingDevice.setVerified(true, client); var message = session.content; message['forwarding_curve25519_key_chain'] = forwardedKeys; From cbf5069e32ccd93d3594a7990129d316e56163da Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Mon, 25 May 2020 09:34:43 +0000 Subject: [PATCH 4/4] Add more tests --- lib/src/utils/matrix_localizations.dart | 7 +- lib/src/utils/open_id_credentials.dart | 6 - lib/src/utils/public_rooms_response.dart | 20 -- lib/src/utils/pusher.dart | 16 +- lib/src/utils/well_known_informations.dart | 4 - test/client_test.dart | 6 + test/matrix_default_localizations.dart | 213 +++++++++++++++++++++ test/matrix_exception_test.dart | 71 +++++++ test/matrix_file_test.dart | 52 +++++ test/matrix_id_string_extension_test.dart | 2 + test/matrix_localizations_test.dart | 65 +++++++ test/public_rooms_response_test.dart | 59 ++++++ test/pusher_test.dart | 45 +++++ test/well_known_informations_test.dart | 40 ++++ 14 files changed, 558 insertions(+), 48 deletions(-) create mode 100644 test/matrix_default_localizations.dart create mode 100644 test/matrix_exception_test.dart create mode 100644 test/matrix_file_test.dart create mode 100644 test/matrix_localizations_test.dart create mode 100644 test/public_rooms_response_test.dart create mode 100644 test/pusher_test.dart create mode 100644 test/well_known_informations_test.dart diff --git a/lib/src/utils/matrix_localizations.dart b/lib/src/utils/matrix_localizations.dart index 1b8fefd..ad70da9 100644 --- a/lib/src/utils/matrix_localizations.dart +++ b/lib/src/utils/matrix_localizations.dart @@ -1,6 +1,7 @@ import '../room.dart'; abstract class MatrixLocalizations { + const MatrixLocalizations(); String get emptyChat; String get invitedUsersOnly; @@ -121,9 +122,8 @@ extension HistoryVisibilityDisplayString on HistoryVisibility { return i18n.visibleForAllParticipants; case HistoryVisibility.world_readable: return i18n.visibleForEveryone; - default: - return toString().replaceAll('HistoryVisibility.', ''); } + return null; } } @@ -134,9 +134,8 @@ extension GuestAccessDisplayString on GuestAccess { return i18n.guestsCanJoin; case GuestAccess.forbidden: return i18n.guestsAreForbidden; - default: - return toString().replaceAll('GuestAccess.', ''); } + return null; } } diff --git a/lib/src/utils/open_id_credentials.dart b/lib/src/utils/open_id_credentials.dart index a2c79b6..4a0852e 100644 --- a/lib/src/utils/open_id_credentials.dart +++ b/lib/src/utils/open_id_credentials.dart @@ -4,12 +4,6 @@ class OpenIdCredentials { String matrixServerName; num expiresIn; - OpenIdCredentials( - {this.accessToken, - this.tokenType, - this.matrixServerName, - this.expiresIn}); - OpenIdCredentials.fromJson(Map json) { accessToken = json['access_token']; tokenType = json['token_type']; diff --git a/lib/src/utils/public_rooms_response.dart b/lib/src/utils/public_rooms_response.dart index 738ca59..3f833be 100644 --- a/lib/src/utils/public_rooms_response.dart +++ b/lib/src/utils/public_rooms_response.dart @@ -7,14 +7,6 @@ class PublicRoomsResponse { final int totalRoomCountEstimate; Client client; - PublicRoomsResponse({ - this.publicRooms, - this.nextBatch, - this.prevBatch, - this.totalRoomCountEstimate, - this.client, - }); - PublicRoomsResponse.fromJson(Map json, Client client) : nextBatch = json['next_batch'], prevBatch = json['prev_batch'], @@ -42,18 +34,6 @@ class PublicRoomEntry { Future join() => client.joinRoomById(roomId); - PublicRoomEntry({ - this.aliases, - this.avatarUrl, - this.guestCanJoin, - this.name, - this.numJoinedMembers, - this.roomId, - this.topic, - this.worldReadable, - this.client, - }); - PublicRoomEntry.fromJson(Map json, Client client) : aliases = json.containsKey('aliases') ? json['aliases'].cast() : [], diff --git a/lib/src/utils/pusher.dart b/lib/src/utils/pusher.dart index 810afd8..d4bd5da 100644 --- a/lib/src/utils/pusher.dart +++ b/lib/src/utils/pusher.dart @@ -8,16 +8,6 @@ class Pusher { String lang; PusherData data; - Pusher( - {this.pushkey, - this.kind, - this.appId, - this.appDisplayName, - this.deviceDisplayName, - this.profileTag, - this.lang, - this.data}); - Pusher.fromJson(Map json) { pushkey = json['pushkey']; kind = json['kind']; @@ -49,8 +39,6 @@ class PusherData { String url; String format; - PusherData({this.url, this.format}); - PusherData.fromJson(Map json) { url = json['url']; format = json['format']; @@ -58,8 +46,8 @@ class PusherData { Map toJson() { final data = {}; - data['url'] = url; - data['format'] = format; + if (url != null) data['url'] = url; + if (format != null) data['format'] = format; return data; } } diff --git a/lib/src/utils/well_known_informations.dart b/lib/src/utils/well_known_informations.dart index 46ab78e..359dbd0 100644 --- a/lib/src/utils/well_known_informations.dart +++ b/lib/src/utils/well_known_informations.dart @@ -3,8 +3,6 @@ class WellKnownInformations { MHomeserver mIdentityServer; Map content; - WellKnownInformations({this.mHomeserver, this.mIdentityServer}); - WellKnownInformations.fromJson(Map json) { content = json; mHomeserver = json['m.homeserver'] != null @@ -19,8 +17,6 @@ class WellKnownInformations { class MHomeserver { String baseUrl; - MHomeserver({this.baseUrl}); - MHomeserver.fromJson(Map json) { baseUrl = json['base_url']; } diff --git a/test/client_test.dart b/test/client_test.dart index 2d5b66e..fc3b939 100644 --- a/test/client_test.dart +++ b/test/client_test.dart @@ -411,6 +411,12 @@ void main() { expect(openId.tokenType, 'Bearer'); expect(openId.matrixServerName, 'example.com'); expect(openId.expiresIn, 3600); + expect(openId.toJson(), { + 'access_token': 'SomeT0kenHere', + 'token_type': 'Bearer', + 'matrix_server_name': 'example.com', + 'expires_in': 3600 + }); }); test('createRoom', () async { diff --git a/test/matrix_default_localizations.dart b/test/matrix_default_localizations.dart new file mode 100644 index 0000000..7ec3d6d --- /dev/null +++ b/test/matrix_default_localizations.dart @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2019 Zender & Kurtz GbR. + * + * Authors: + * Christian Pauly + * Marcel Radzio + * + * This file is part of famedlysdk. + * + * famedlysdk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * famedlysdk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with famedlysdk. If not, see . + */ +import 'package:famedlysdk/famedlysdk.dart'; + +class MatrixDefaultLocalizations extends MatrixLocalizations { + const MatrixDefaultLocalizations(); + @override + String acceptedTheInvitation(String targetName) => + '$targetName accepted the invitation'; + + @override + String activatedEndToEndEncryption(String senderName) => + '$senderName activated end to end encryption'; + + @override + String get anyoneCanJoin => 'Anyone can join'; + + @override + String bannedUser(String senderName, String targetName) => + '$senderName banned $targetName'; + + @override + String changedTheChatAvatar(String senderName) => + '$senderName changed the chat avatar'; + + @override + String changedTheChatDescriptionTo(String senderName, String content) => + '$senderName changed the chat description to $content'; + + @override + String changedTheChatNameTo(String senderName, String content) => + '$senderName changed the chat name to $content'; + + @override + String changedTheChatPermissions(String senderName) => + '$senderName changed the chat permissions'; + + @override + String changedTheDisplaynameTo(String targetName, String newDisplayname) => + '$targetName changed the displayname to $newDisplayname'; + + @override + String changedTheGuestAccessRules(String senderName) => + '$senderName changed the guest access rules'; + + @override + String changedTheGuestAccessRulesTo( + String senderName, String localizedString) => + '$senderName changed the guest access rules to $localizedString'; + + @override + String changedTheHistoryVisibility(String senderName) => + '$senderName changed the history visibility'; + + @override + String changedTheHistoryVisibilityTo( + String senderName, String localizedString) => + '$senderName changed the history visibility to $localizedString'; + + @override + String changedTheJoinRules(String senderName) => + '$senderName changed the join rules'; + + @override + String changedTheJoinRulesTo(String senderName, String localizedString) => + '$senderName changed the join rules to $localizedString'; + + @override + String changedTheProfileAvatar(String targetName) => + '$targetName changed the profile avatar'; + + @override + String changedTheRoomAliases(String senderName) => + '$senderName changed the room aliases'; + + @override + String changedTheRoomInvitationLink(String senderName) => + '$senderName changed the room invitation link'; + + @override + String get channelCorruptedDecryptError => + 'The secure channel has been corrupted'; + + @override + String couldNotDecryptMessage(String errorText) => + 'Could not decrypt message: $errorText'; + + @override + String createdTheChat(String senderName) => '$senderName created the chat'; + + @override + String get emptyChat => 'Empty chat'; + + @override + String get encryptionNotEnabled => 'Encryption not enabled'; + + @override + String get fromJoining => 'From joining'; + + @override + String get fromTheInvitation => 'From the invitation'; + + @override + String groupWith(String displayname) => 'Group with $displayname'; + + @override + String get guestsAreForbidden => 'Guests are forbidden'; + + @override + String get guestsCanJoin => 'Guests can join'; + + @override + String hasWithdrawnTheInvitationFor(String senderName, String targetName) => + '$senderName has withdrawn the invitation for $targetName'; + + @override + String invitedUser(String senderName, String targetName) => + '$senderName has invited $targetName'; + + @override + String get invitedUsersOnly => 'Invited users only'; + + @override + String joinedTheChat(String targetName) => '$targetName joined the chat'; + + @override + String kicked(String senderName, String targetName) => + '$senderName kicked $targetName'; + + @override + String kickedAndBanned(String senderName, String targetName) => + '$senderName banned $targetName'; + + @override + String get needPantalaimonWarning => 'Need pantalaimon'; + + @override + String get noPermission => 'No permission'; + + @override + String redactedAnEvent(String senderName) => '$senderName redacted an event'; + + @override + String rejectedTheInvitation(String targetName) => + '$targetName rejected the invitation'; + + @override + String removedBy(String calcDisplayname) => 'Removed by $calcDisplayname'; + + @override + String get roomHasBeenUpgraded => 'Room has been upgraded'; + + @override + String sentAFile(String senderName) => '$senderName sent a file'; + + @override + String sentAPicture(String senderName) => '$senderName sent a picture'; + + @override + String sentASticker(String senderName) => '$senderName sent a sticker'; + + @override + String sentAVideo(String senderName) => '$senderName sent a video'; + + @override + String sentAnAudio(String senderName) => '$senderName sent an audio'; + + @override + String sharedTheLocation(String senderName) => + '$senderName shared the location'; + + @override + String unbannedUser(String senderName, String targetName) => + '$senderName unbanned $targetName'; + + @override + String get unknownEncryptionAlgorithm => 'Unknown encryption algorithm'; + + @override + String unknownEvent(String typeKey) => 'Unknown event $typeKey'; + + @override + String userLeftTheChat(String targetName) => '$targetName left the chat'; + + @override + String get visibleForAllParticipants => 'Visible for all participants'; + + @override + String get visibleForEveryone => 'Visible for everyone'; + + @override + String get you => 'You'; +} diff --git a/test/matrix_exception_test.dart b/test/matrix_exception_test.dart new file mode 100644 index 0000000..77ec04c --- /dev/null +++ b/test/matrix_exception_test.dart @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2019 Zender & Kurtz GbR. + * + * Authors: + * Christian Pauly + * Marcel Radzio + * + * This file is part of famedlysdk. + * + * famedlysdk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * famedlysdk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with famedlysdk. If not, see . + */ +import 'package:famedlysdk/famedlysdk.dart'; +import 'package:http/http.dart'; +import 'package:test/test.dart'; + +void main() { + /// All Tests related to device keys + group('Matrix Exception', () { + test('Matrix Exception', () async { + final matrixException = MatrixException( + Response( + '{"flows":[{"stages":["example.type.foo"]}],"params":{"example.type.baz":{"example_key":"foobar"}},"session":"xxxxxxyz","completed":["example.type.foo"]}', + 401, + ), + ); + expect(matrixException.errcode, 'M_FORBIDDEN'); + final flows = matrixException.authenticationFlows; + expect(flows.length, 1); + expect(flows.first.stages.length, 1); + expect(flows.first.stages.first, 'example.type.foo'); + expect( + matrixException.authenticationParams['example.type.baz'], + {'example_key': 'foobar'}, + ); + expect(matrixException.completedAuthenticationFlows.length, 1); + expect(matrixException.completedAuthenticationFlows.first, + 'example.type.foo'); + expect(matrixException.session, 'xxxxxxyz'); + }); + test('Unknown Exception', () async { + final matrixException = MatrixException( + Response( + '{"errcode":"M_HAHA","error":"HAHA","retry_after_ms":500}', + 401, + ), + ); + expect(matrixException.error, MatrixError.M_UNKNOWN); + expect(matrixException.retryAfterMs, 500); + }); + test('Missing Exception', () async { + final matrixException = MatrixException( + Response( + '{"error":"HAHA"}', + 401, + ), + ); + expect(matrixException.error, MatrixError.M_UNKNOWN); + }); + }); +} diff --git a/test/matrix_file_test.dart b/test/matrix_file_test.dart new file mode 100644 index 0000000..498c230 --- /dev/null +++ b/test/matrix_file_test.dart @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019 Zender & Kurtz GbR. + * + * Authors: + * Christian Pauly + * Marcel Radzio + * + * This file is part of famedlysdk. + * + * famedlysdk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * famedlysdk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with famedlysdk. If not, see . + */ + +import 'dart:typed_data'; + +import 'package:famedlysdk/famedlysdk.dart'; +import 'package:test/test.dart'; +import 'package:olm/olm.dart' as olm; + +void main() { + /// All Tests related to device keys + group('Matrix File', () { + test('Decrypt', () async { + final text = 'hello world'; + final file = MatrixFile( + path: '/path/to/file.txt', + bytes: Uint8List.fromList(text.codeUnits), + ); + var olmEnabled = true; + try { + await olm.init(); + olm.Account(); + } catch (_) { + olmEnabled = false; + } + if (olmEnabled) { + final encryptedFile = await file.encrypt(); + expect(encryptedFile != null, true); + } + }); + }); +} diff --git a/test/matrix_id_string_extension_test.dart b/test/matrix_id_string_extension_test.dart index 4b0b425..f5ae04c 100644 --- a/test/matrix_id_string_extension_test.dart +++ b/test/matrix_id_string_extension_test.dart @@ -45,6 +45,8 @@ void main() { expect('\$test:example.com'.sigil, '\$'); expect(mxId.localpart, 'test'); expect(mxId.domain, 'example.com'); + expect(mxId.equals('@Test:example.com'), true); + expect(mxId.equals('@test:example.org'), false); }); }); } diff --git a/test/matrix_localizations_test.dart b/test/matrix_localizations_test.dart new file mode 100644 index 0000000..044073b --- /dev/null +++ b/test/matrix_localizations_test.dart @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019 Zender & Kurtz GbR. + * + * Authors: + * Christian Pauly + * Marcel Radzio + * + * This file is part of famedlysdk. + * + * famedlysdk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * famedlysdk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with famedlysdk. If not, see . + */ +import 'package:famedlysdk/famedlysdk.dart'; +import 'package:test/test.dart'; + +import 'matrix_default_localizations.dart'; + +void main() { + /// All Tests related to device keys + group('Matrix Localizations', () { + test('Matrix Localizations', () { + expect( + HistoryVisibility.invited + .getLocalizedString(MatrixDefaultLocalizations()), + 'From the invitation'); + expect( + HistoryVisibility.joined + .getLocalizedString(MatrixDefaultLocalizations()), + 'From joining'); + expect( + HistoryVisibility.shared + .getLocalizedString(MatrixDefaultLocalizations()), + 'Visible for all participants'); + expect( + HistoryVisibility.world_readable + .getLocalizedString(MatrixDefaultLocalizations()), + 'Visible for everyone'); + expect( + GuestAccess.can_join.getLocalizedString(MatrixDefaultLocalizations()), + 'Guests can join'); + expect( + GuestAccess.forbidden + .getLocalizedString(MatrixDefaultLocalizations()), + 'Guests are forbidden'); + expect(JoinRules.invite.getLocalizedString(MatrixDefaultLocalizations()), + 'Invited users only'); + expect(JoinRules.public.getLocalizedString(MatrixDefaultLocalizations()), + 'Anyone can join'); + expect(JoinRules.private.getLocalizedString(MatrixDefaultLocalizations()), + 'private'); + expect(JoinRules.knock.getLocalizedString(MatrixDefaultLocalizations()), + 'knock'); + }); + }); +} diff --git a/test/public_rooms_response_test.dart b/test/public_rooms_response_test.dart new file mode 100644 index 0000000..b76a7d4 --- /dev/null +++ b/test/public_rooms_response_test.dart @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 Zender & Kurtz GbR. + * + * Authors: + * Christian Pauly + * Marcel Radzio + * + * This file is part of famedlysdk. + * + * famedlysdk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * famedlysdk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with famedlysdk. If not, see . + */ +import 'package:famedlysdk/famedlysdk.dart'; +import 'package:test/test.dart'; + +import 'fake_matrix_api.dart'; + +void main() { + /// All Tests related to device keys + group('Public Rooms Response', () { + Client client; + test('Public Rooms Response', () async { + client = Client('testclient', debug: true); + client.httpClient = FakeMatrixApi(); + + await client.checkServer('https://fakeServer.notExisting'); + final responseMap = { + 'chunk': [ + { + 'aliases': ['#murrays:cheese.bar'], + 'avatar_url': 'mxc://bleeker.street/CHEDDARandBRIE', + 'guest_can_join': false, + 'name': 'CHEESE', + 'num_joined_members': 37, + 'room_id': '1234', + 'topic': 'Tasty tasty cheese', + 'world_readable': true + } + ], + 'next_batch': 'p190q', + 'prev_batch': 'p1902', + 'total_room_count_estimate': 115 + }; + final publicRoomsResponse = + PublicRoomsResponse.fromJson(responseMap, client); + await publicRoomsResponse.publicRooms.first.join(); + }); + }); +} diff --git a/test/pusher_test.dart b/test/pusher_test.dart new file mode 100644 index 0000000..fe2dfa2 --- /dev/null +++ b/test/pusher_test.dart @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019 Zender & Kurtz GbR. + * + * Authors: + * Christian Pauly + * Marcel Radzio + * + * This file is part of famedlysdk. + * + * famedlysdk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * famedlysdk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with famedlysdk. If not, see . + */ +import 'package:famedlysdk/src/utils/pusher.dart'; +import 'package:test/test.dart'; + +void main() { + /// All Tests related to device keys + group('Pusher', () { + test('Pusher', () { + final rawPusher = { + 'pushkey': 'Xp/MzCt8/9DcSNE9cuiaoT5Ac55job3TdLSSmtmYl4A=', + 'kind': 'http', + 'app_id': 'face.mcapp.appy.prod', + 'app_display_name': 'Appy McAppface', + 'device_display_name': "Alice's Phone", + 'profile_tag': 'xyz', + 'lang': 'en-US', + 'data': {'url': 'https://example.com/_matrix/push/v1/notify'} + }; + + final pusher = Pusher.fromJson(rawPusher); + expect(pusher.toJson(), rawPusher); + }); + }); +} diff --git a/test/well_known_informations_test.dart b/test/well_known_informations_test.dart new file mode 100644 index 0000000..7417d10 --- /dev/null +++ b/test/well_known_informations_test.dart @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019 Zender & Kurtz GbR. + * + * Authors: + * Christian Pauly + * Marcel Radzio + * + * This file is part of famedlysdk. + * + * famedlysdk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * famedlysdk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with famedlysdk. If not, see . + */ +import 'package:famedlysdk/famedlysdk.dart'; +import 'package:test/test.dart'; + +void main() { + /// All Tests related to device keys + group('WellKnownInformations', () { + test('WellKnownInformations', () { + final json = { + 'm.homeserver': {'base_url': 'https://matrix.example.com'}, + 'm.identity_server': {'base_url': 'https://identity.example.com'}, + 'org.example.custom.property': { + 'app_url': 'https://custom.app.example.org' + } + }; + WellKnownInformations.fromJson(json); + }); + }); +}