mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 09:28:41 +00:00
added tests and some fixes
This commit is contained in:
parent
5cd4d25d88
commit
90e6aa6598
6 changed files with 137 additions and 25 deletions
|
|
@ -35,30 +35,30 @@ import 'package:twonly/src/views/components/animate_icon.dart';
|
||||||
final lockHandleServerMessage = Mutex();
|
final lockHandleServerMessage = Mutex();
|
||||||
|
|
||||||
Future<void> handleServerMessage(server.ServerToClient msg) async {
|
Future<void> handleServerMessage(server.ServerToClient msg) async {
|
||||||
return lockHandleServerMessage.protect(() async {
|
// return lockHandleServerMessage.protect(() async {
|
||||||
client.Response? response;
|
client.Response? response;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (msg.v0.hasRequestNewPreKeys()) {
|
if (msg.v0.hasRequestNewPreKeys()) {
|
||||||
response = await handleRequestNewPreKey();
|
response = await handleRequestNewPreKey();
|
||||||
} else if (msg.v0.hasNewMessage()) {
|
} else if (msg.v0.hasNewMessage()) {
|
||||||
final body = Uint8List.fromList(msg.v0.newMessage.body);
|
final body = Uint8List.fromList(msg.v0.newMessage.body);
|
||||||
final fromUserId = msg.v0.newMessage.fromUserId.toInt();
|
final fromUserId = msg.v0.newMessage.fromUserId.toInt();
|
||||||
response = await handleNewMessage(fromUserId, body);
|
response = await handleNewMessage(fromUserId, body);
|
||||||
} else {
|
} else {
|
||||||
Log.error('Got a unknown message from the server: $msg');
|
Log.error('Got a unknown message from the server: $msg');
|
||||||
response = client.Response()..error = ErrorCode.InternalError;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
response = client.Response()..error = ErrorCode.InternalError;
|
response = client.Response()..error = ErrorCode.InternalError;
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
response = client.Response()..error = ErrorCode.InternalError;
|
||||||
|
}
|
||||||
|
|
||||||
final v0 = client.V0()
|
final v0 = client.V0()
|
||||||
..seq = msg.v0.seq
|
..seq = msg.v0.seq
|
||||||
..response = response;
|
..response = response;
|
||||||
|
|
||||||
await apiService.sendResponse(ClientToServer()..v0 = v0);
|
await apiService.sendResponse(ClientToServer()..v0 = v0);
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
DateTime lastSignalDecryptMessage =
|
DateTime lastSignalDecryptMessage =
|
||||||
|
|
@ -128,6 +128,8 @@ Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
|
||||||
.getRetransmissionFromHash(fromUserId, hash);
|
.getRetransmissionFromHash(fromUserId, hash);
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
unawaited(sendRetransmitMessage(message.retransmissionId));
|
unawaited(sendRetransmitMessage(message.retransmissionId));
|
||||||
|
} else {
|
||||||
|
Log.error('Could not find message to retransmit!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,8 @@ Future<List<PreKeyRecord>> signalGetPreKeys() async {
|
||||||
|
|
||||||
final start = user.currentPreKeyIndexStart;
|
final start = user.currentPreKeyIndexStart;
|
||||||
await updateUserdata((user) {
|
await updateUserdata((user) {
|
||||||
user.currentPreKeyIndexStart += 200;
|
user.currentPreKeyIndexStart =
|
||||||
|
(user.currentPreKeyIndexStart + 200) % maxValue;
|
||||||
return user;
|
return user;
|
||||||
});
|
});
|
||||||
final preKeys = generatePreKeys(start, 200);
|
final preKeys = generatePreKeys(start, 200);
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,8 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
||||||
DateTime? lastDate;
|
DateTime? lastDate;
|
||||||
final tmpEmojiReactionsToMessageId = <int, List<Message>>{};
|
final tmpEmojiReactionsToMessageId = <int, List<Message>>{};
|
||||||
|
|
||||||
final openedMessageOtherIds = <int>[];
|
// only send openedMessage to one text message, as receiver will then set all as read...
|
||||||
|
int? openedTextMessageOtherIds;
|
||||||
|
|
||||||
final messageOtherMessageIdToMyMessageId = <int, int>{};
|
final messageOtherMessageIdToMyMessageId = <int, int>{};
|
||||||
final messageIdToMessage = <int, Message>{};
|
final messageIdToMessage = <int, Message>{};
|
||||||
|
|
@ -150,8 +151,10 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
||||||
for (final msg in newMessages) {
|
for (final msg in newMessages) {
|
||||||
if (msg.kind == MessageKind.textMessage &&
|
if (msg.kind == MessageKind.textMessage &&
|
||||||
msg.messageOtherId != null &&
|
msg.messageOtherId != null &&
|
||||||
msg.openedAt == null) {
|
msg.openedAt == null &&
|
||||||
openedMessageOtherIds.add(msg.messageOtherId!);
|
(openedTextMessageOtherIds == null ||
|
||||||
|
openedTextMessageOtherIds < msg.messageOtherId!)) {
|
||||||
|
openedTextMessageOtherIds = msg.messageOtherId;
|
||||||
}
|
}
|
||||||
|
|
||||||
Message? responseTo;
|
Message? responseTo;
|
||||||
|
|
@ -207,10 +210,10 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openedMessageOtherIds.isNotEmpty) {
|
if (openedTextMessageOtherIds != null) {
|
||||||
await notifyContactAboutOpeningMessage(
|
await notifyContactAboutOpeningMessage(
|
||||||
widget.contact.userId,
|
widget.contact.userId,
|
||||||
openedMessageOtherIds,
|
[openedTextMessageOtherIds],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
66
lib/src/views/settings/developer/automated_testing.view.dart
Normal file
66
lib/src/views/settings/developer/automated_testing.view.dart
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:twonly/globals.dart';
|
||||||
|
import 'package:twonly/src/model/json/message.dart';
|
||||||
|
import 'package:twonly/src/services/api/messages.dart';
|
||||||
|
|
||||||
|
class AutomatedTestingView extends StatefulWidget {
|
||||||
|
const AutomatedTestingView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AutomatedTestingView> createState() => _AutomatedTestingViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AutomatedTestingViewState extends State<AutomatedTestingView> {
|
||||||
|
String lotsOfMessagesStatus = '';
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
unawaited(initAsync());
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> initAsync() async {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Automated Testing'),
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
children: [
|
||||||
|
if (kDebugMode)
|
||||||
|
ListTile(
|
||||||
|
title: const Text('Sending a lot of messages.'),
|
||||||
|
subtitle: Text(lotsOfMessagesStatus),
|
||||||
|
onTap: () async {
|
||||||
|
await twonlyDB.messageRetransmissionDao
|
||||||
|
.clearRetransmissionTable();
|
||||||
|
|
||||||
|
final contacts =
|
||||||
|
await twonlyDB.contactsDao.getAllNotBlockedContacts();
|
||||||
|
|
||||||
|
for (final contact in contacts) {
|
||||||
|
for (var i = 0; i < 200; i++) {
|
||||||
|
setState(() {
|
||||||
|
lotsOfMessagesStatus =
|
||||||
|
'At message $i to ${contact.username}.';
|
||||||
|
});
|
||||||
|
await sendTextMessage(
|
||||||
|
contact.userId,
|
||||||
|
TextMessageContent(
|
||||||
|
text: 'TestMessage $i',
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/services/flame.service.dart';
|
import 'package:twonly/src/services/flame.service.dart';
|
||||||
import 'package:twonly/src/utils/storage.dart';
|
import 'package:twonly/src/utils/storage.dart';
|
||||||
|
import 'package:twonly/src/views/settings/developer/automated_testing.view.dart';
|
||||||
import 'package:twonly/src/views/settings/developer/retransmission_data.view.dart';
|
import 'package:twonly/src/views/settings/developer/retransmission_data.view.dart';
|
||||||
|
|
||||||
class DeveloperSettingsView extends StatefulWidget {
|
class DeveloperSettingsView extends StatefulWidget {
|
||||||
|
|
@ -76,6 +77,20 @@ class _DeveloperSettingsViewState extends State<DeveloperSettingsView> {
|
||||||
await syncFlameCounters();
|
await syncFlameCounters();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
if (kDebugMode)
|
||||||
|
ListTile(
|
||||||
|
title: const Text('Automated Testing'),
|
||||||
|
onTap: () async {
|
||||||
|
await Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) {
|
||||||
|
return const AutomatedTestingView();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
25
test/signal/key_generation.dart
Normal file
25
test/signal/key_generation.dart
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('testing api', () {
|
||||||
|
test('testing api connection', () async {
|
||||||
|
const offset = 100;
|
||||||
|
const count = 400;
|
||||||
|
|
||||||
|
var prekeys = generatePreKeys(offset, count);
|
||||||
|
expect(count, prekeys.length);
|
||||||
|
|
||||||
|
for (var i = 0; i < prekeys.length; i++) {
|
||||||
|
expect(prekeys[i].id, offset + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
prekeys += generatePreKeys(offset + count, count);
|
||||||
|
expect(count * 2, prekeys.length);
|
||||||
|
|
||||||
|
for (var i = 0; i < (count * 2); i++) {
|
||||||
|
expect(prekeys[i].id, offset + i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue