swarm/test/fake_relay_connection.dart

62 lines
1.7 KiB
Dart
Raw Permalink Normal View History

2026-06-07 16:45:43 +03:00
import 'dart:async';
import 'dart:convert';
import 'package:swarm/swarm.dart';
final class FakeRelayConnection implements RelayConnection {
final _controller = StreamController<String>.broadcast();
final sentMessages = <String>[];
final queuedResponses = <String>[];
bool isConnected = false;
bool autoRespond = true;
bool throwOnConnect = false;
// When set, connect() never completes — simulates a handshake that hangs
// (accepted socket, no WebSocket upgrade).
bool hangOnConnect = false;
2026-06-07 16:45:43 +03:00
void Function(String subId)? onReq;
@override
Future<void> connect() async {
if (throwOnConnect) throw Exception('connection failed');
if (hangOnConnect) await Completer<void>().future;
2026-06-07 16:45:43 +03:00
isConnected = true;
}
@override
Future<void> send(String message) async {
sentMessages.add(message);
if (queuedResponses.isNotEmpty) {
final response = queuedResponses.removeAt(0);
Future(() => _controller.add(response));
return;
}
_tryAutoRespond(message);
}
@override
Stream<String> get messages => _controller.stream;
@override
Future<void> close() async => isConnected = false;
void push(String message) => _controller.add(message);
Future<void> dispose() => _controller.close();
void _tryAutoRespond(String message) {
if (!autoRespond) return;
try {
final list = jsonDecode(message) as List;
if (list[0] == 'EVENT') {
final event = list[1] as Map<String, dynamic>;
final id = event['id'] as String;
Future(() => _controller.add(jsonEncode(['OK', id, true, ''])));
} else if (list[0] == 'REQ') {
final subId = list[1] as String;
Future(() => onReq?.call(subId));
}
} catch (_) {
// malformed, ignore
}
}
}