added tests and some fixes

This commit is contained in:
otsmr 2025-10-18 17:20:34 +02:00
parent 5cd4d25d88
commit 90e6aa6598
6 changed files with 137 additions and 25 deletions

View file

@ -35,7 +35,7 @@ import 'package:twonly/src/views/components/animate_icon.dart';
final lockHandleServerMessage = Mutex();
Future<void> handleServerMessage(server.ServerToClient msg) async {
return lockHandleServerMessage.protect(() async {
// return lockHandleServerMessage.protect(() async {
client.Response? response;
try {
@ -58,7 +58,7 @@ Future<void> handleServerMessage(server.ServerToClient msg) async {
..response = response;
await apiService.sendResponse(ClientToServer()..v0 = v0);
});
// });
}
DateTime lastSignalDecryptMessage =
@ -128,6 +128,8 @@ Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
.getRetransmissionFromHash(fromUserId, hash);
if (message != null) {
unawaited(sendRetransmitMessage(message.retransmissionId));
} else {
Log.error('Could not find message to retransmit!');
}
}

View file

@ -63,7 +63,8 @@ Future<List<PreKeyRecord>> signalGetPreKeys() async {
final start = user.currentPreKeyIndexStart;
await updateUserdata((user) {
user.currentPreKeyIndexStart += 200;
user.currentPreKeyIndexStart =
(user.currentPreKeyIndexStart + 200) % maxValue;
return user;
});
final preKeys = generatePreKeys(start, 200);

View file

@ -133,7 +133,8 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
DateTime? lastDate;
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 messageIdToMessage = <int, Message>{};
@ -150,8 +151,10 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
for (final msg in newMessages) {
if (msg.kind == MessageKind.textMessage &&
msg.messageOtherId != null &&
msg.openedAt == null) {
openedMessageOtherIds.add(msg.messageOtherId!);
msg.openedAt == null &&
(openedTextMessageOtherIds == null ||
openedTextMessageOtherIds < msg.messageOtherId!)) {
openedTextMessageOtherIds = msg.messageOtherId;
}
Message? responseTo;
@ -207,10 +210,10 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
}
}
if (openedMessageOtherIds.isNotEmpty) {
if (openedTextMessageOtherIds != null) {
await notifyContactAboutOpeningMessage(
widget.contact.userId,
openedMessageOtherIds,
[openedTextMessageOtherIds],
);
}

View 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,
);
}
}
},
),
],
),
);
}
}

View file

@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:twonly/globals.dart';
import 'package:twonly/src/services/flame.service.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';
class DeveloperSettingsView extends StatefulWidget {
@ -76,6 +77,20 @@ class _DeveloperSettingsViewState extends State<DeveloperSettingsView> {
await syncFlameCounters();
},
),
if (kDebugMode)
ListTile(
title: const Text('Automated Testing'),
onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const AutomatedTestingView();
},
),
);
},
),
],
),
);

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