Import IKAR messenger client and server
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:ikar/core/webpush/max_web_protocol.dart';
|
||||
|
||||
Uint8List _hex(String value) {
|
||||
final bytes = Uint8List(value.length ~/ 2);
|
||||
for (var i = 0; i < bytes.length; i++) {
|
||||
bytes[i] = int.parse(value.substring(i * 2, i * 2 + 2), radix: 16);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
const _compressedResponseHex =
|
||||
'0a010000000601000018f00782a6726567696f6ea25a5aa973796e746865746963c3';
|
||||
|
||||
void main() {
|
||||
test('заголовок кадра совпадает с синтетическим вектором', () {
|
||||
final frame = _hex(_compressedResponseHex);
|
||||
expect(frame[0], MaxWebFraming.protocolVersion);
|
||||
final decoded = MaxWebFraming.decode(frame);
|
||||
expect(decoded.cmd, MaxWebCmd.ok);
|
||||
expect(decoded.opcode, 6);
|
||||
expect(decoded.isOk, isTrue);
|
||||
});
|
||||
|
||||
test('распаковка LZ4 и msgpack из синтетического кадра', () {
|
||||
final decoded = MaxWebFraming.decode(_hex(_compressedResponseHex));
|
||||
final payload = decoded.payload as Map<Object?, Object?>;
|
||||
expect(payload['region'], 'ZZ');
|
||||
expect(payload['synthetic'], isTrue);
|
||||
expect(payload.length, 2);
|
||||
});
|
||||
|
||||
test('кодирование кадра сохраняет контракт заголовка', () {
|
||||
final actual = MaxWebFraming.encode(
|
||||
cmd: 0,
|
||||
seq: 2,
|
||||
opcode: 6,
|
||||
payload: <String, Object?>{'synthetic': true},
|
||||
);
|
||||
expect(
|
||||
actual.sublist(0, MaxWebFraming.headerSize),
|
||||
_hex('0a00000200060000000c'),
|
||||
);
|
||||
});
|
||||
|
||||
test('msgpack переживает круговой рейс', () {
|
||||
final source = <String, Object?>{
|
||||
'enabled': true,
|
||||
'count': 40,
|
||||
'offset': -1,
|
||||
'nested': <String, Object?>{
|
||||
'a': null,
|
||||
'b': 3.5,
|
||||
'c': <Object?>[1, 'два', false],
|
||||
},
|
||||
};
|
||||
final restored =
|
||||
MaxMsgpack.decode(MaxMsgpack.encode(source)) as Map<Object?, Object?>;
|
||||
expect(restored['enabled'], true);
|
||||
expect(restored['count'], 40);
|
||||
expect(restored['offset'], -1);
|
||||
final nested = restored['nested'] as Map<Object?, Object?>;
|
||||
expect(nested['a'], isNull);
|
||||
expect(nested['b'], 3.5);
|
||||
expect((nested['c'] as List<Object?>)[1], 'два');
|
||||
});
|
||||
|
||||
test('ext(1) разворачивается во вложенное число', () {
|
||||
final pollingInterval =
|
||||
MaxMsgpack.decode(
|
||||
Uint8List.fromList([
|
||||
0x81,
|
||||
0xA8,
|
||||
0x69,
|
||||
0x6E,
|
||||
0x74,
|
||||
0x65,
|
||||
0x72,
|
||||
0x76,
|
||||
0x61,
|
||||
0x6C,
|
||||
0xC7,
|
||||
0x03,
|
||||
0x01,
|
||||
0xD1,
|
||||
0x13,
|
||||
0x88,
|
||||
]),
|
||||
)
|
||||
as Map<Object?, Object?>;
|
||||
expect(pollingInterval['interval'], 5000);
|
||||
|
||||
final expiresAt = MaxMsgpack.decode(
|
||||
Uint8List.fromList([
|
||||
0xC7,
|
||||
0x09,
|
||||
0x01,
|
||||
0xD3,
|
||||
0x00,
|
||||
0x00,
|
||||
0x01,
|
||||
0xA0,
|
||||
0x25,
|
||||
0x5B,
|
||||
0xE9,
|
||||
0xD2,
|
||||
]),
|
||||
);
|
||||
expect(expiresAt, 1787333175762);
|
||||
});
|
||||
|
||||
test('LZ4 разворачивает перекрывающиеся совпадения', () {
|
||||
final compressed = Uint8List.fromList([
|
||||
0x6E,
|
||||
0x71,
|
||||
0x6C,
|
||||
0x79,
|
||||
0x72,
|
||||
0x61,
|
||||
0x20,
|
||||
0x06,
|
||||
0x00,
|
||||
0x46,
|
||||
0x70,
|
||||
0x75,
|
||||
0x73,
|
||||
0x68,
|
||||
0x05,
|
||||
0x00,
|
||||
0x50,
|
||||
0x20,
|
||||
0x70,
|
||||
0x75,
|
||||
0x73,
|
||||
0x68,
|
||||
]);
|
||||
final result = Lz4Block.decompress(compressed, 256);
|
||||
expect(utf8.decode(result), 'qlyra qlyra qlyra qlyra push push push push');
|
||||
});
|
||||
|
||||
test('отклоняет кадр с несовпадающей длиной', () {
|
||||
expect(
|
||||
() => MaxWebFraming.decode(_hex('0a000002000600000003aa')),
|
||||
throwsFormatException,
|
||||
);
|
||||
});
|
||||
|
||||
test('ограничивает распаковку LZ4', () {
|
||||
expect(
|
||||
() => Lz4Block.decompress(
|
||||
Uint8List.fromList([0x1f, 0x41, 0x01, 0x00, 0x00]),
|
||||
8,
|
||||
),
|
||||
throwsFormatException,
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user