Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions lib/features/event_sockets/bloc/event_sockets_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import 'package:socket_probe/features/event_sockets/bloc/event_sockets_state.dar
import 'package:socket_probe/features/event_sockets/data/repository/event_sockets_repo_impl.dart';

class EventSocketsBloc extends Bloc<EventSocketsEvent, EventSocketsState> {
late EventSocketsRepoImpl _repository;
EventSocketsRepoImpl _repository = EventSocketsRepoImpl("wss://echo.websocket.events", {
"auth": {"token": "userToken"},
"transports": ["websocket"],
"autoConnect": true,
});

StreamSubscription? _messageSubscription;
final List<dynamic> _messages = [];
Expand Down Expand Up @@ -36,9 +40,9 @@ class EventSocketsBloc extends Bloc<EventSocketsEvent, EventSocketsState> {
}

_handleConnect(ConnectRequested event, Emitter<EventSocketsState> emit) {
_repository = EventSocketsRepoImpl(event.socketUrl, event.sockedConfigurations);
try {
emit(EventSocketsConnecting());
_repository = EventSocketsRepoImpl(event.socketUrl, event.sockedConfigurations);

_repository.connectToSocket();

Expand Down Expand Up @@ -84,9 +88,13 @@ class EventSocketsBloc extends Bloc<EventSocketsEvent, EventSocketsState> {
}

Future<void> _onMessageReceived(MessageReceived event, Emitter<EventSocketsState> emit) async {
// Log the incoming message.
_messages.add("Received: ${event.message}");
emit(EventSocketsConnected(messages: List.from(_messages)));
try {
// Log the incoming message.
_messages.add("Received: ${event.message}");
emit(EventSocketsConnected(messages: List.from(_messages)));
} catch (e) {
emit(EventSocketsError(error: e.toString()));
}
}

Future<void> _onConnectionErrorOccurred(ConnectionErrorOccurred event, Emitter<EventSocketsState> emit) async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class EventSocketsRepoImpl {
final String socketUrl;
final dynamic socketOpts;

late sio.Socket socket;
sio.Socket? socket;

// A broadcast controller lets multiple listeners receive the stream of messages.
final StreamController<dynamic> _messageController = StreamController<dynamic>.broadcast();
Expand All @@ -21,23 +21,23 @@ class EventSocketsRepoImpl {
// Connect to the Socket.IO server
socket = sio.io(url, socketOpts);

socket.on('connect', (message) {
socket?.on('connect', (message) {
// socket.subEvents();
_messageController.add(message);
log('Connected to server');
});

socket.onAny((event, data) {
socket?.onAny((event, data) {
_messageController.add(data);
log("event name: $event, event data: $data");
});

socket.onError((data) {
socket?.onError((data) {
_messageController.addError(data);
log("connection error: $data");
});

socket.onConnectError((data) {
socket?.onConnectError((data) {
_messageController.addError(data);
log("connection error: $data");
});
Expand All @@ -49,16 +49,18 @@ class EventSocketsRepoImpl {
Stream<dynamic> get messages => _messageController.stream;

void sendEventMessage(String event, [dynamic data]) {
if (socket.connected) {
socket.emit(event, data);
if (socket == null) return;
if (socket?.connected ?? false) {
socket?.emit(event, data);
} else {
throw Exception("WebSocket connection is not established. Call connect() first.");
}
}

void disconnect() {
if (socket.connected) {
socket.disconnect();
if (socket == null) return;
if (socket?.connected ?? false) {
socket?.disconnect();
log('disconnected from server');
}
}
Expand Down
26 changes: 17 additions & 9 deletions lib/features/wsprotocol/bloc/wsprotocol_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class WsprotocolBloc extends Bloc<WsprotocolEvent, WsprotocolState> {
TextEditingController wssTextController = TextEditingController();
TextEditingController randomStringController = TextEditingController();

late WsprotocolRepoImpl repository;
WsprotocolRepoImpl repository = WsprotocolRepoImpl('wss://echo.websocket.events');
StreamSubscription? _messageSubscription;
final List<dynamic> _messages = [];

Expand All @@ -32,7 +32,7 @@ class WsprotocolBloc extends Bloc<WsprotocolEvent, WsprotocolState> {
Future<void> _onConnectRequested(ConnectRequested event, Emitter<WsprotocolState> emit) async {
emit(WsprotocolConnecting());
try {
repository = WsprotocolRepoImpl(wssTextController.text);
repository = WsprotocolRepoImpl(event.socketUrl);
repository.connect();
// Listen for messages from the repository.
_messageSubscription = repository.messages.listen(
Expand All @@ -55,10 +55,14 @@ class WsprotocolBloc extends Bloc<WsprotocolEvent, WsprotocolState> {
}

Future<void> _onDisconnectRequested(DisconnectRequested event, Emitter<WsprotocolState> emit) async {
repository.disconnect();
_messages.clear();
await _messageSubscription?.cancel();
emit(WsprotocolDisconnected());
try {
repository.disconnect();
_messages.clear();
await _messageSubscription?.cancel();
emit(WsprotocolDisconnected());
} catch (e) {
emit(WsprotocolError(e.toString()));
}
}

Future<void> _onSendMessageRequested(SendMessageRequested event, Emitter<WsprotocolState> emit) async {
Expand All @@ -83,9 +87,13 @@ class WsprotocolBloc extends Bloc<WsprotocolEvent, WsprotocolState> {
}

Future<void> _onMessageReceived(MessageReceived event, Emitter<WsprotocolState> emit) async {
// Log the incoming message.
_messages.add("Received: ${event.message}");
emit(WsprotocolConnected(messages: List.from(_messages)));
try {
// Log the incoming message.
_messages.add("Received: ${event.message}");
emit(WsprotocolConnected(messages: List.from(_messages)));
} catch (e) {
emit(WsprotocolError(e.toString()));
}
}

Future<void> _onConnectionErrorOccurred(ConnectionErrorOccurred event, Emitter<WsprotocolState> emit) async {
Expand Down
8 changes: 7 additions & 1 deletion lib/features/wsprotocol/bloc/wsprotocol_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ abstract class WsprotocolEvent extends Equatable {
}

/// Event to initiate a connection.
class ConnectRequested extends WsprotocolEvent {}
class ConnectRequested extends WsprotocolEvent {
final String socketUrl;
const ConnectRequested({required this.socketUrl});

@override
List<Object?> get props => [socketUrl];
}

/// Event to close the connection.
class DisconnectRequested extends WsprotocolEvent {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ class _WsprotocolViewState extends State<WsprotocolView> {
protocolBloc.add(DisconnectRequested());
return;
}
protocolBloc.add(ConnectRequested());
protocolBloc.add(ConnectRequested(
socketUrl: protocolBloc.wssTextController.text
));
},
content: isLoading
? SizedBox(height: 20, width: 20, child: CircularProgressIndicator(color: Colors.white))
Expand Down
154 changes: 60 additions & 94 deletions test/event_sockets/bloc/event_sockets_bloc_test.dart
Original file line number Diff line number Diff line change
@@ -1,103 +1,69 @@
// import 'dart:async';
import 'package:bloc_test/bloc_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:socket_probe/features/event_sockets/bloc/event_sockets_bloc.dart';
import 'package:socket_probe/features/event_sockets/bloc/event_sockets_event.dart';
import 'package:socket_probe/features/event_sockets/bloc/event_sockets_state.dart';

// import 'package:flutter_test/flutter_test.dart';
// import 'package:bloc_test/bloc_test.dart';
// import 'package:mocktail/mocktail.dart';
// import 'package:socket_probe/features/event_sockets/bloc/event_sockets_bloc.dart';
// import 'package:socket_probe/features/event_sockets/bloc/event_sockets_event.dart';
// import 'package:socket_probe/features/event_sockets/bloc/event_sockets_state.dart';
// import 'package:socket_probe/features/event_sockets/data/repository/event_sockets_repo_impl.dart';
void main() {
group(EventSocketsBloc, () {
late EventSocketsBloc eventSocketsBloc;

// // Mock repository class
// class MockEventSocketsRepo extends Mock implements EventSocketsRepoImpl {}
setUp(() {
eventSocketsBloc = EventSocketsBloc();
});

// void main() {
// late EventSocketsBloc eventSocketsBloc;
// late MockEventSocketsRepo mockRepository;
// late StreamController<dynamic> messageController;
blocTest(
'This test the websocket connection when ConnectedRequest is added',
build: () => eventSocketsBloc,
act: (bloc) => bloc.add(
ConnectRequested(socketUrl: 'wss://echo.websocket.events', sockedConfigurations: {
"auth": {"token": "userToken"},
"transports": ["websocket"],
"autoConnect": true,
}),
),
expect: () => [
isA<EventSocketsConnecting>(),
isA<EventSocketsConnected>(),
],
);

// setUp(() {
// mockRepository = MockEventSocketsRepo();
// messageController = StreamController<dynamic>.broadcast();
blocTest(
'This test the websocket connection when DisconnectRequested is added',
build: () => eventSocketsBloc,
act: (bloc) => bloc.add(DisconnectRequested()),
expect: () => [isA<EventSocketsDisconnected>()],
);

// when(() => mockRepository.messages).thenAnswer((_) => messageController.stream);
// when(() => mockRepository.connectToSocket()).thenAnswer((_) {
// messageController.add('Connected'); // Simulating successful connection
// });
// when(() => mockRepository.disconnect()).thenReturn(null);
// when(() => mockRepository.sendEventMessage(any(), any())).thenReturn(null);
blocTest(
'This test the websocket connection when SendMessageRequested is added',
build: () => eventSocketsBloc,
act: (bloc) => bloc.add(
SendMessageRequested(message: "Send Message Requested", event: "message.event"),
),
expect: () => [isA<EventSocketsConnected>()],
);

// eventSocketsBloc = EventSocketsBloc();
// // eventSocketsBloc._repository = mockRepository;
// });
blocTest(
'This test the websocket connection when MessageReceived is added',
build: () => eventSocketsBloc,
act: (bloc) => bloc.add(
MessageReceived(message: "Message Received"),
),
expect: () => [isA<EventSocketsConnected>()],
);

// tearDown(() {
// eventSocketsBloc.close();
// messageController.close();
// });
blocTest(
'This test the websocket connection when ConnectionErrorOccurred is added',
build: () => eventSocketsBloc,
act: (bloc) => bloc.add(
ConnectionErrorOccurred(message: "Connection Error Occurred"),
),
expect: () => [isA<EventSocketsError>()],
);

// test('initial state should be EventSocketsInitial', () {
// expect(eventSocketsBloc.state, equals(EventSocketsInitial()));
// });
tearDown(() => eventSocketsBloc.close());

// blocTest<EventSocketsBloc, EventSocketsState>(
// 'emits [EventSocketsConnecting, EventSocketsConnected] when ConnectRequested is added',
// build: () => eventSocketsBloc,
// act: (bloc) => bloc.add(ConnectRequested(socketUrl: 'ws://test-url', sockedConfigurations: {})),
// expect: () => [
// EventSocketsConnecting(),
// EventSocketsConnected(messages: []),
// ],
// verify: (_) {
// verify(() => mockRepository.connectToSocket()).called(1);
// },
// );

// blocTest<EventSocketsBloc, EventSocketsState>(
// 'emits [EventSocketsDisconnected] when DisconnectRequested is added',
// build: () => eventSocketsBloc,
// act: (bloc) => bloc.add(DisconnectRequested()),
// expect: () => [
// EventSocketsDisconnected(),
// ],
// verify: (_) {
// verify(() => mockRepository.disconnect()).called(1);
// },
// );

// blocTest<EventSocketsBloc, EventSocketsState>(
// 'emits [EventSocketsConnected] when a message is received',
// build: () => eventSocketsBloc,
// act: (bloc) {
// messageController.add('New Event Message');
// bloc.add(MessageReceived(message: 'New Event Message'));
// },
// expect: () => [
// EventSocketsConnected(messages: ['Received: New Event Message']),
// ],
// );

// blocTest<EventSocketsBloc, EventSocketsState>(
// 'emits [EventSocketsConnected] when SendMessageRequested is added',
// build: () => eventSocketsBloc,
// act: (bloc) => bloc.add(SendMessageRequested(event: 'testEvent', message: 'testMessage')),
// expect: () => [
// EventSocketsConnected(messages: ['Sent: testMessage']),
// ],
// verify: (_) {
// verify(() => mockRepository.sendEventMessage('testEvent', 'testMessage')).called(1);
// },
// );

// blocTest<EventSocketsBloc, EventSocketsState>(
// 'emits [EventSocketsError] when a connection error occurs',
// build: () => eventSocketsBloc,
// act: (bloc) {
// messageController.addError('Socket connection failed');
// bloc.add(ConnectionErrorOccurred(message: 'Socket connection failed'));
// },
// expect: () => [
// EventSocketsError(error: 'Socket connection failed'),
// ],
// );
// }
// end of test
});
}
Loading