137 lines
4.6 KiB
Dart
137 lines
4.6 KiB
Dart
import 'dart:async';
|
|
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 peer = await live.Device.create(
|
|
Uri.parse('https://ikar.kusoft.xyz'),
|
|
Platform.environment['IKAR_TEST_NODE'] ?? 'node',
|
|
'+999${DateTime.now().microsecondsSinceEpoch}',
|
|
'IKAR bot test',
|
|
);
|
|
final http = IkarNetwork.client();
|
|
String? botGuid;
|
|
try {
|
|
Future<dynamic> request(String method, String path, [Object? body]) async {
|
|
final r = await http.openUrl(
|
|
method,
|
|
Uri.parse('https://ikar.kusoft.xyz$path'),
|
|
);
|
|
r.headers.set('Authorization', 'Bearer ${peer.transport.token}');
|
|
if (body != null) {
|
|
r.headers.contentType = ContentType.json;
|
|
r.write(jsonEncode(body));
|
|
}
|
|
final response = await r.close();
|
|
final text = await utf8.decodeStream(response);
|
|
live.check(
|
|
response.statusCode >= 200 && response.statusCode < 300,
|
|
'Bot HTTP $method rejected: ${response.statusCode}',
|
|
);
|
|
return text.isEmpty ? null : jsonDecode(text);
|
|
}
|
|
|
|
final creator =
|
|
(await peer.ok(60, {
|
|
'query': 'botfatherbot',
|
|
}))['result'][0]['contact']['id']
|
|
as int;
|
|
final creatorChat = creator ^ peer.id;
|
|
final reply = peer.transport.events
|
|
.firstWhere(
|
|
(e) =>
|
|
e['opcode'] == 128 &&
|
|
e['payload']?['message']?['sender'] == creator,
|
|
)
|
|
.timeout(const Duration(seconds: 20));
|
|
final name = 'ikar_test_${DateTime.now().millisecondsSinceEpoch}bot';
|
|
await peer.ok(64, {
|
|
'chatId': creatorChat,
|
|
'message': {'text': '/создать_бота IKAR smoke | $name | Test'},
|
|
});
|
|
final createdText = (await reply)['payload']['message']['text'] as String;
|
|
final botToken = RegExp(
|
|
r'ikarbot_[A-Za-z0-9_-]+',
|
|
).firstMatch(createdText)?.group(0);
|
|
live.check(botToken != null, 'Creator did not return a bot token');
|
|
final mine = await request('GET', '/api/bots/mine') as List;
|
|
final bot = mine.singleWhere((x) => x['username'] == name);
|
|
botGuid = bot['id'];
|
|
await request('PUT', '/api/bots/$botGuid/web-app', {
|
|
'url': 'https://example.com/ikar-test',
|
|
});
|
|
final contact = (await peer.ok(60, {
|
|
'query': name,
|
|
}))['result'][0]['contact'];
|
|
live.check(
|
|
(contact['options'] as List).contains('HAS_WEBAPP'),
|
|
'Mini-app was not advertised',
|
|
);
|
|
final botId = contact['id'] as int;
|
|
final launch = await peer.ok(160, {'botId': botId, 'startParam': 'test'});
|
|
live.check(
|
|
(launch['url'] as String).contains('ikarWebAppData'),
|
|
'Own launch signature missing',
|
|
);
|
|
final phone = await peer.ok(106, {'botId': botId});
|
|
live.check(
|
|
(phone['hash'] as String).length == 64,
|
|
'Phone share signature missing',
|
|
);
|
|
final botChat = peer.id ^ botId;
|
|
await peer.ok(64, {
|
|
'chatId': botChat,
|
|
'message': {'text': 'IKAR bot request'},
|
|
});
|
|
final updates = await request(
|
|
'GET',
|
|
'/api/bot/$botToken/getUpdates?timeoutSeconds=0',
|
|
);
|
|
final update = (updates['updates'] as List).singleWhere(
|
|
(x) => x['message']?['text'] == 'IKAR bot request',
|
|
);
|
|
final botReply = peer.transport.events
|
|
.firstWhere(
|
|
(e) =>
|
|
e['opcode'] == 128 &&
|
|
e['payload']?['message']?['sender'] == botId,
|
|
)
|
|
.timeout(const Duration(seconds: 20));
|
|
await request('POST', '/api/bot/$botToken/sendMessage', {
|
|
'chatId': update['message']['chatId'],
|
|
'text': 'IKAR bot response',
|
|
});
|
|
live.check(
|
|
(await botReply)['payload']['message']['text'] == 'IKAR bot response',
|
|
'Bot reply not delivered',
|
|
);
|
|
final report = {
|
|
'passed': true,
|
|
'checks': [
|
|
'bot creation through own chat',
|
|
'bot update queue and reply delivery',
|
|
'mini-app configuration and signed launch',
|
|
'separate signed phone share',
|
|
],
|
|
'timestamp': DateTime.now().toUtc().toIso8601String(),
|
|
};
|
|
await File(
|
|
'artifacts/live-bot-smoke.json',
|
|
).writeAsString(const JsonEncoder.withIndent(' ').convert(report));
|
|
stdout.writeln(jsonEncode(report));
|
|
} finally {
|
|
if (botGuid != null) {
|
|
final r = await http.deleteUrl(
|
|
Uri.parse('https://ikar.kusoft.xyz/api/bots/$botGuid'),
|
|
);
|
|
r.headers.set('Authorization', 'Bearer ${peer.transport.token}');
|
|
await (await r.close()).drain<void>();
|
|
}
|
|
http.close(force: true);
|
|
await peer.ok(199, {});
|
|
await peer.close();
|
|
}
|
|
}
|