108 lines
3.5 KiB
Dart
108 lines
3.5 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import '../lib/core/transport/ikar_network.dart';
|
|
import 'live_ikar_smoke.dart' as live;
|
|
|
|
Future<void> main() async {
|
|
final peers = <live.Device>[];
|
|
final client = IkarNetwork.client();
|
|
try {
|
|
final stamp = DateTime.now().microsecondsSinceEpoch.toString().substring(6);
|
|
for (var index = 0; index < 3; index++) {
|
|
peers.add(
|
|
await live.Device.create(
|
|
Uri.parse('https://ikar.kusoft.xyz'),
|
|
Platform.environment['IKAR_TEST_NODE'] ?? 'node',
|
|
'+999$stamp$index',
|
|
'Voice menu test $index',
|
|
),
|
|
);
|
|
}
|
|
final sender = peers[0], recipient = peers[1], outsider = peers[2];
|
|
final chatId = sender.id ^ recipient.id;
|
|
final info = (await sender.ok(87, {'count': 1}))['info'][0];
|
|
final uri = Uri.parse(
|
|
info['url'],
|
|
).replace(queryParameters: {'filename': 'ikar-speech-test.wav'});
|
|
final upload = await client.postUrl(uri);
|
|
upload.headers.contentType = ContentType('audio', 'wav');
|
|
upload.add(await File('artifacts/speech-test.wav').readAsBytes());
|
|
final response = await upload.close();
|
|
live.check(response.statusCode == 200, 'Voice upload rejected');
|
|
final token = jsonDecode(await utf8.decodeStream(response))['token'];
|
|
final sent = await sender.ok(64, {
|
|
'chatId': chatId,
|
|
'message': {
|
|
'attaches': [
|
|
{'_type': 'AUDIO', 'token': token, 'name': 'ikar-speech-test.wav'},
|
|
],
|
|
},
|
|
});
|
|
final message = sent['message'];
|
|
final messageId = message['id'];
|
|
final audioId = message['attaches'][0]['audioId'];
|
|
final completed = recipient.transport.events
|
|
.firstWhere(
|
|
(event) =>
|
|
event['opcode'] == 293 &&
|
|
event['payload']?['messageId'] == messageId,
|
|
)
|
|
.timeout(const Duration(seconds: 90));
|
|
final queued = await recipient.ok(202, {
|
|
'chatId': chatId,
|
|
'messageId': messageId,
|
|
'mediaId': audioId,
|
|
});
|
|
live.check(
|
|
queued['transcriptionStatus'] == 0 || queued['transcriptionStatus'] == 1,
|
|
'Voice menu request rejected',
|
|
);
|
|
final push = await completed;
|
|
final text = push['payload']['transcription'] as String;
|
|
live.check(text.contains('привет'), 'Speech recognition failed');
|
|
for (final peer in [sender, recipient]) {
|
|
final cached = await peer.ok(202, {
|
|
'chatId': chatId,
|
|
'messageId': messageId,
|
|
'mediaId': audioId,
|
|
});
|
|
live.check(
|
|
cached['transcriptionStatus'] == 1 && cached['transcription'] == text,
|
|
'Saved transcription missing',
|
|
);
|
|
}
|
|
final denied = await outsider.transport.request(202, {
|
|
'chatId': chatId,
|
|
'messageId': messageId,
|
|
'mediaId': audioId,
|
|
});
|
|
live.check(denied['cmd'] == 3, 'Transcription leaked to a nonmember');
|
|
final report = {
|
|
'passed': true,
|
|
'checks': [
|
|
'voice upload',
|
|
'recipient transcription request',
|
|
'completed recognition push',
|
|
'persisted text for both participants',
|
|
'nonmember denial',
|
|
],
|
|
'recognizedTestText': text,
|
|
'timestamp': DateTime.now().toUtc().toIso8601String(),
|
|
};
|
|
await File(
|
|
'artifacts/voice-transcription-live-verification.json',
|
|
).writeAsString(const JsonEncoder.withIndent(' ').convert(report));
|
|
stdout.writeln(jsonEncode(report));
|
|
} finally {
|
|
for (final peer in peers.reversed) {
|
|
try {
|
|
await peer.ok(199, {});
|
|
} finally {
|
|
await peer.close();
|
|
}
|
|
}
|
|
client.close(force: true);
|
|
}
|
|
}
|