From 3852fdac3dfad833cfae6ce0afa00e5520bfd313 Mon Sep 17 00:00:00 2001 From: npub1ux8n2yfs8qfvgd75s7kyhar2mztac355v6vmrz4juc9l3msw4pgstums9e Date: Tue, 14 Jul 2026 11:58:47 -0700 Subject: [PATCH] test(mobile): harden auth disconnect coverage Cover both clean stream closure and stream errors during authentication, with bounded waits and socket-close assertions. Co-authored-by: npub1ux8n2yfs8qfvgd75s7kyhar2mztac355v6vmrz4juc9l3msw4pgstums9e Signed-off-by: npub1ux8n2yfs8qfvgd75s7kyhar2mztac355v6vmrz4juc9l3msw4pgstums9e --- .../test/shared/relay/relay_socket_test.dart | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/mobile/test/shared/relay/relay_socket_test.dart b/mobile/test/shared/relay/relay_socket_test.dart index e807c9bb1..5cd25cc2f 100644 --- a/mobile/test/shared/relay/relay_socket_test.dart +++ b/mobile/test/shared/relay/relay_socket_test.dart @@ -44,11 +44,37 @@ void main() { expect(socket.state, SocketState.authenticating); await channel.closeStream(); - await connecting; + await connecting.timeout(const Duration(seconds: 1)); expect(disconnections, hasLength(1)); expect(disconnections.single, isA()); expect(socket.state, SocketState.disconnected); + expect(channel.closeCount, 1); + }); + + test('auth-phase stream error reports one disconnection', () async { + final channel = _ReadyWebSocketChannel(); + final disconnections = []; + final socket = RelaySocket( + wsUrl: 'wss://relay.example', + nsec: null, + onMessage: (_) {}, + onConnected: () => fail('socket must not connect'), + onDisconnected: disconnections.add, + channelFactory: (_) => channel, + ); + + final connecting = socket.connect(); + await Future.delayed(Duration.zero); + expect(socket.state, SocketState.authenticating); + + channel.addStreamError(StateError('connection reset')); + await connecting.timeout(const Duration(seconds: 1)); + + expect(disconnections, hasLength(1)); + expect(disconnections.single, isA()); + expect(socket.state, SocketState.disconnected); + expect(channel.closeCount, 1); }); test('hung handshake times out, closes, and reports disconnection', () async { @@ -93,6 +119,8 @@ class _ReadyWebSocketChannel implements WebSocketChannel { Future closeStream() => _controller.close(); + void addStreamError(Object error) => _controller.addError(error); + @override late final WebSocketSink sink = _RecordingWebSocketSink( _controller.sink,