forked from eatvio/eatvio_app
fix(chat): ws manager
This commit is contained in:
@@ -252,5 +252,36 @@ void main() {
|
||||
|
||||
expect(manager.client, isNull);
|
||||
});
|
||||
|
||||
test('reconnected - эмитит сигнал после восстановления соединения', () async {
|
||||
final wsService = MockWsService();
|
||||
final manager = WsManager(wsService: wsService, errorReporter: const NoOpErrorReporter());
|
||||
|
||||
final received = <void>[];
|
||||
final subscription = manager.reconnected.listen(received.add);
|
||||
|
||||
manager.handleConnectionEstablished();
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
|
||||
expect(received, hasLength(1));
|
||||
|
||||
await subscription.cancel();
|
||||
});
|
||||
|
||||
test('reconnected - переживает clear (поток не закрывается при логауте)', () async {
|
||||
final wsService = MockWsService();
|
||||
final manager = WsManager(wsService: wsService, errorReporter: const NoOpErrorReporter());
|
||||
|
||||
final received = <void>[];
|
||||
final subscription = manager.reconnected.listen(received.add);
|
||||
|
||||
await manager.clear();
|
||||
manager.handleConnectionEstablished();
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
|
||||
expect(received, hasLength(1));
|
||||
|
||||
await subscription.cancel();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1729,5 +1729,78 @@ void main() {
|
||||
expect(state.chatMessages.any((message) => message.id == 88), isTrue);
|
||||
expect(state.chatMessages.firstWhere((message) => message.id == 1).isRead, isTrue);
|
||||
});
|
||||
|
||||
test('refreshCurrentChat - подтягивает сообщение, добавленное в БД в обход сокета', () async {
|
||||
const uuid = 'room-uuid';
|
||||
final reconnectController = StreamController<void>.broadcast();
|
||||
|
||||
when(mockWsManager.reconnected).thenAnswer((_) => reconnectController.stream);
|
||||
when(mockChatRepository.getChatRoom(uuid)).thenAnswer((_) async => testChatRoom);
|
||||
when(mockChatRepository.getChatMessages(uuid, 1)).thenAnswer((_) async => testChatMessages);
|
||||
when(mockChatRepository.getChosenPlan(id: anyNamed('id'))).thenAnswer((_) async => throw Exception('No plan'));
|
||||
when(mockWsManager.client).thenReturn(null);
|
||||
when(mockWsManager.initPrivateDirectChatChannel(any)).thenAnswer((_) async => Future.value());
|
||||
when(mockWsManager.subscribeDirectChatChannel()).thenReturn(null);
|
||||
when(mockWsManager.directChatStream).thenReturn(null);
|
||||
when(mockWsManager.clientTypingStream).thenReturn(null);
|
||||
|
||||
await chatRoomCubit.initChat(uuid);
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
|
||||
final missedMessage = ChatMessageModel(
|
||||
id: 99,
|
||||
data: 'Missed during outage',
|
||||
mediaData: null,
|
||||
authorId: 2,
|
||||
updatedAt: DateTime.now(),
|
||||
isRead: false,
|
||||
isCurrentUserAuthor: false,
|
||||
roomId: 'chat-id',
|
||||
);
|
||||
|
||||
when(mockChatRepository.getChatMessages(uuid, 1)).thenAnswer(
|
||||
(_) async => ChatMessagesModel(
|
||||
messagesList: [missedMessage, ...testChatMessages.messagesList],
|
||||
meta: const ChatMetaModel(lastPage: 3),
|
||||
),
|
||||
);
|
||||
|
||||
reconnectController.add(null);
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
|
||||
final state = chatRoomCubit.state as ChatRoomStateLoaded;
|
||||
expect(state.chatMessages.any((message) => message.id == 99), isTrue);
|
||||
expect(state.chatMessages.any((message) => message.id == 1), isTrue);
|
||||
expect(chatRoomCubit.lastPage, 3);
|
||||
|
||||
await reconnectController.close();
|
||||
});
|
||||
|
||||
test('refreshCurrentChat - идемпотентен: повторный реконнект не двоит сообщения', () async {
|
||||
const uuid = 'room-uuid';
|
||||
final reconnectController = StreamController<void>.broadcast();
|
||||
|
||||
when(mockWsManager.reconnected).thenAnswer((_) => reconnectController.stream);
|
||||
when(mockChatRepository.getChatRoom(uuid)).thenAnswer((_) async => testChatRoom);
|
||||
when(mockChatRepository.getChatMessages(uuid, 1)).thenAnswer((_) async => testChatMessages);
|
||||
when(mockChatRepository.getChosenPlan(id: anyNamed('id'))).thenAnswer((_) async => throw Exception('No plan'));
|
||||
when(mockWsManager.client).thenReturn(null);
|
||||
when(mockWsManager.initPrivateDirectChatChannel(any)).thenAnswer((_) async => Future.value());
|
||||
when(mockWsManager.subscribeDirectChatChannel()).thenReturn(null);
|
||||
when(mockWsManager.directChatStream).thenReturn(null);
|
||||
when(mockWsManager.clientTypingStream).thenReturn(null);
|
||||
|
||||
await chatRoomCubit.initChat(uuid);
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
|
||||
reconnectController.add(null);
|
||||
reconnectController.add(null);
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
|
||||
final state = chatRoomCubit.state as ChatRoomStateLoaded;
|
||||
expect(state.chatMessages.where((message) => message.id == 1).length, 1);
|
||||
|
||||
await reconnectController.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -578,6 +578,23 @@ void main() {
|
||||
expect(updatedRoom.unreadMessagesCount, 0);
|
||||
expect(updatedState.chatsWithUnreadMessagesCount, 0);
|
||||
});
|
||||
|
||||
test('connectToWebSocket - обновляет список чатов после реконнекта', () async {
|
||||
final reconnectController = StreamController<void>.broadcast();
|
||||
|
||||
when(mockWsManager.reconnected).thenAnswer((_) => reconnectController.stream);
|
||||
when(mockWsManager.newMessagesStream).thenReturn(null);
|
||||
when(mockChatRepository.getChatRooms(query: null)).thenAnswer((_) async => testChatRoomsPagination);
|
||||
|
||||
await chatsCubit.connectToWebSocket();
|
||||
|
||||
reconnectController.add(null);
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
|
||||
verify(mockChatRepository.getChatRooms(query: null)).called(1);
|
||||
|
||||
await reconnectController.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user