Files
IKAR/tool/verify_messaging_fix.dart
T

141 lines
4.3 KiB
Dart

import 'dart:convert';
import 'dart:io';
import 'live_ikar_smoke.dart' as live;
Future<void> main(List<String> args) async {
final label = args.isEmpty ? 'before' : args.first;
final devices = <live.Device>[];
final report = <String, dynamic>{
'timestamp': DateTime.now().toUtc().toIso8601String(),
'checks': <String, dynamic>{},
};
final checks = report['checks'] as Map<String, dynamic>;
try {
final stamp = DateTime.now().microsecondsSinceEpoch.toString();
for (var i = 0; i < 2; i++) {
devices.add(
await live.Device.create(
Uri.parse('https://ikar.kusoft.xyz'),
Platform.environment['IKAR_TEST_NODE'] ?? 'node',
'+999$stamp$i',
'IKAR messaging regression',
),
);
}
final a = devices[0], b = devices[1];
Future<Map<String, dynamic>> run(
String name,
int opcode,
Map payload,
) async {
final response = await a.transport.request(opcode, payload);
checks[name] = {
'passed': response['cmd'] == 1,
if (response['cmd'] != 1) 'error': response['payload'],
};
return Map<String, dynamic>.from(response['payload'] as Map);
}
await run('savedHistoryBeforeFirstMessage', 49, {'chatId': 0, 'count': 40});
final saved = await run('savedText', 64, {
'chatId': 0,
'message': {
'text': 'IKAR saved regression',
'cid': DateTime.now().microsecondsSinceEpoch,
},
});
final history = await run('savedHistoryAfterMessage', 49, {
'chatId': 0,
'count': 40,
});
checks['savedMessagePersisted'] = {
'passed':
saved['message'] != null &&
(history['messages'] as List? ?? []).any(
(m) => m['id'] == saved['message']['id'],
),
};
final sticker = await run('savedSticker', 64, {
'chatId': 0,
'message': {
'attaches': [
{'_type': 'STICKER', 'stickerId': 1},
],
},
});
checks['savedStickerPersisted'] = {'passed': sticker['message'] is Map};
await run('savedTyping', 59, {'chatId': 0, 'type': 'TEXT'});
await run('contactAdd', 34, {
'contactId': b.id,
'action': 'ADD',
'firstName': 'Regression contact',
});
await run('contactUpdate', 34, {
'contactId': b.id,
'action': 'UPDATE',
'firstName': 'Renamed contact',
});
await run('contactRemove', 34, {'contactId': b.id, 'action': 'REMOVE'});
final chatId = a.id ^ b.id;
await run('directSubscribeBeforeFirstMessage', 75, {
'chatId': chatId,
'subscribe': true,
});
final received = b.transport.events
.firstWhere(
(e) => e['opcode'] == 128 && e['payload']?['chatId'] == chatId,
)
.timeout(const Duration(seconds: 15));
final message = await run('firstDirectMessage', 64, {
'chatId': chatId,
'message': {
'text': 'IKAR direct regression',
'cid': DateTime.now().microsecondsSinceEpoch,
},
});
await received;
final directHistory = await b.ok(49, {'chatId': chatId, 'count': 40});
checks['directDeliveryAndHistory'] = {
'passed': (directHistory['messages'] as List).any(
(m) => m['id'] == message['message']['id'],
),
};
await run('directUnsubscribe', 75, {'chatId': chatId, 'subscribe': false});
final afterUnsubscribe = await run('directHistoryAfterUnsubscribe', 49, {
'chatId': chatId,
'count': 40,
});
checks['unsubscribeRetainsMembership'] = {
'passed': (afterUnsubscribe['messages'] as List? ?? []).any(
(m) => m['id'] == message['message']['id'],
),
};
final otherSaved = await b.transport.request(49, {
'chatId': 0,
'count': 40,
});
checks['savedIsolation'] = {
'passed':
otherSaved['cmd'] == 1 &&
(otherSaved['payload']['messages'] as List).every(
(m) => m['text'] != 'IKAR saved regression',
),
};
report['passed'] = checks.values.every(
(value) => (value as Map)['passed'] == true,
);
} finally {
for (final device in devices) {
try {
await device.ok(199, {});
} finally {
await device.close();
}
}
await File(
'artifacts/messaging-fix-$label.json',
).writeAsString(const JsonEncoder.withIndent(' ').convert(report));
stdout.writeln(jsonEncode(report));
}
}