diff --git a/lib/src/room.dart b/lib/src/room.dart index e187cbf0..41efe2b1 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -1299,8 +1299,21 @@ class Room { /// Searches for the event on the server. Returns null if not found. Future getEventById(String eventID) async { - final matrixEvent = await client.requestEvent(id, eventID); - return Event.fromMatrixEvent(matrixEvent, this); + try { + final matrixEvent = await client.requestEvent(id, eventID); + final event = Event.fromMatrixEvent(matrixEvent, this); + if (event.type == EventTypes.Encrypted && client.encryptionEnabled) { + // attempt decryption + return await client.encryption + .decryptRoomEvent(id, event, store: false); + } + return event; + } on MatrixException catch (err) { + if (err.errcode == 'M_NOT_FOUND') { + return null; + } + rethrow; + } } /// Returns the power level of the given user ID. diff --git a/test/fake_matrix_api.dart b/test/fake_matrix_api.dart index c9b36b4f..428c15a8 100644 --- a/test/fake_matrix_api.dart +++ b/test/fake_matrix_api.dart @@ -83,7 +83,11 @@ class FakeMatrixApi extends MockClient { if (api.containsKey(method) && api[method].containsKey(action)) { res = api[method][action](data); if (res is Map && res.containsKey('errcode')) { - statusCode = 405; + if (res['errcode'] == 'M_NOT_FOUND') { + statusCode = 404; + } else { + statusCode = 405; + } } } else if (method == 'PUT' && action.contains('/client/r0/sendToDevice/')) { @@ -1283,6 +1287,41 @@ class FakeMatrixApi extends MockClient { 'origin_server_ts': 1432735824653, 'unsigned': {'age': 1234} }, + '/client/r0/rooms/!1234%3Aexample.com/event/not_found': (var req) => { + 'errcode': 'M_NOT_FOUND', + 'error': 'Event not found', + }, + '/client/r0/rooms/!1234%3Aexample.com/event/unencrypted_event': + (var req) => { + 'content': { + 'body': 'This is an example text message', + 'msgtype': 'm.text', + 'format': 'org.matrix.custom.html', + 'formatted_body': 'This is an example text message' + }, + 'type': 'm.room.message', + 'event_id': '143273582443PhrSn:example.org', + 'room_id': '!localpart:server.abc', + 'sender': '@example:example.org', + 'origin_server_ts': 1432735824653, + 'unsigned': {'age': 1234} + }, + '/client/r0/rooms/!1234%3Aexample.com/event/encrypted_event': (var req) => + { + 'content': { + 'algorithm': 'm.megolm.v1.aes-sha2', + 'ciphertext': 'invalid', + 'device_id': 'SOME_DEVICE', + 'sender_key': 'invalid', + 'session_id': 'not_found' + }, + 'type': 'm.room.encrypted', + 'event_id': '143273582443PhrSn:example.org', + 'room_id': '!localpart:server.abc', + 'sender': '@example:example.org', + 'origin_server_ts': 1432735824653, + 'unsigned': {'age': 1234} + }, '/client/r0/rooms/!localpart%3Aserver.abc/messages?from=1234&dir=b&to=1234&limit=10&filter=%7B%22lazy_load_members%22%3Atrue%7D': (var req) => messagesResponse, '/client/r0/rooms/!localpart%3Aserver.abc/messages?from=&dir=b&limit=10&filter=%7B%22lazy_load_members%22%3Atrue%7D': diff --git a/test/timeline_test.dart b/test/timeline_test.dart index 8176d365..862acbcc 100644 --- a/test/timeline_test.dart +++ b/test/timeline_test.dart @@ -24,7 +24,8 @@ import 'package:famedlysdk/src/room.dart'; import 'package:famedlysdk/src/timeline.dart'; import 'package:famedlysdk/src/utils/event_update.dart'; import 'package:famedlysdk/src/utils/room_update.dart'; -import 'fake_matrix_api.dart'; +import 'package:olm/olm.dart' as olm; +import 'fake_client.dart'; void main() { /// All Tests related to the MxContent @@ -34,21 +35,35 @@ void main() { final testTimeStamp = DateTime.now().millisecondsSinceEpoch; var updateCount = 0; var insertList = []; + var olmEnabled = true; + try { + olm.init(); + olm.Account(); + } catch (e) { + olmEnabled = false; + Logs().w('[LibOlm] Failed to load LibOlm', e); + } + Logs().i('[LibOlm] Enabled: $olmEnabled'); - var client = Client('testclient', - httpClient: FakeMatrixApi(), sendMessageTimeoutSeconds: 5); + Client client; + Room room; + Timeline timeline; + test('create stuff', () async { + client = await getClient(); + client.sendMessageTimeoutSeconds = 5; - var room = Room( - id: roomID, client: client, prev_batch: '1234', roomAccountData: {}); - var timeline = Timeline( - room: room, - events: [], - onUpdate: () { - updateCount++; - }, - onInsert: (int insertID) { - insertList.add(insertID); - }); + room = Room( + id: roomID, client: client, prev_batch: '1234', roomAccountData: {}); + timeline = Timeline( + room: room, + events: [], + onUpdate: () { + updateCount++; + }, + onInsert: (int insertID) { + insertList.add(insertID); + }); + }); test('Create', () async { await client.checkHomeserver('https://fakeserver.notexisting', @@ -221,6 +236,23 @@ void main() { expect(timeline.events[0].status, -1); }); + test('getEventById', () async { + var event = await timeline.getEventById('abc'); + expect(event.content, {'msgtype': 'm.text', 'body': 'Testcase'}); + + event = await timeline.getEventById('not_found'); + expect(event, null); + + event = await timeline.getEventById('unencrypted_event'); + expect(event.body, 'This is an example text message'); + + if (olmEnabled) { + event = await timeline.getEventById('encrypted_event'); + // the event is invalid but should have traces of attempting to decrypt + expect(event.messageType, MessageTypes.BadEncrypted); + } + }); + test('Resend message', () async { timeline.events.clear(); client.onEvent.add(EventUpdate( @@ -565,5 +597,8 @@ void main() { expect(timeline.events[0].status, 2); expect(timeline.events.length, 1); }); + test('logout', () async { + await client.logout(); + }); }); }