refactor(chat): dedup

This commit is contained in:
Anatoliy
2026-09-15 23:20:00 +03:00
parent 077cfb3a67
commit 8ec6d5b799
2 changed files with 108 additions and 16 deletions

View File

@@ -1469,11 +1469,13 @@ void main() {
roomId: 'chat-id',
);
chatRoomCubit.addIncomingMessage(incoming);
final shouldPlayIncomingSound = chatRoomCubit.addIncomingMessage(incoming);
final state = chatRoomCubit.state as ChatRoomStateLoaded;
expect(shouldPlayIncomingSound, isTrue);
expect(state.chatMessages.first.id, 99);
expect(state.chatMessages.length, 2);
verify(mockChatRepository.emitNewMessageToChats(incoming)).called(1);
});
test('addIncomingMessage - не добавляет дубликат по id', () async {
@@ -1501,14 +1503,63 @@ void main() {
roomId: 'chat-id',
);
chatRoomCubit.addIncomingMessage(incoming);
final shouldPlayIncomingSound = chatRoomCubit.addIncomingMessage(incoming);
final state = chatRoomCubit.state as ChatRoomStateLoaded;
expect(shouldPlayIncomingSound, isFalse);
expect(state.chatMessages.length, 1);
expect(state.chatMessages.first.data, 'Test message');
verifyNever(mockChatRepository.emitNewMessageToChats(any));
});
test('addIncomingMessage - игнорирует собственные сообщения', () async {
test('addIncomingMessage - не добавляет дубликат по uuid (эхо оптимистичного сообщения)', () async {
const uuid = 'room-uuid';
when(mockChatRepository.getChatRoom(uuid)).thenAnswer((_) async => testChatRoom);
when(mockChatRepository.getChatMessages(uuid, 1)).thenAnswer((_) async => testChatMessages);
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);
when(mockChatRepository.getChosenPlan(id: anyNamed('id'))).thenAnswer((_) async => throw Exception('No plan'));
await chatRoomCubit.initChat(uuid);
await Future.delayed(const Duration(milliseconds: 200));
chatRoomCubit.addIncomingMessage(
ChatMessageModel(
id: 501,
data: 'Echo with client uuid',
mediaData: null,
authorId: 2,
updatedAt: DateTime.now(),
isRead: false,
isCurrentUserAuthor: false,
roomId: 'chat-id',
uuid: 'client-uuid-1',
),
);
final shouldPlayIncomingSound = chatRoomCubit.addIncomingMessage(
ChatMessageModel(
id: 502,
data: 'Same client uuid, server id differs',
mediaData: null,
authorId: 2,
updatedAt: DateTime.now(),
isRead: false,
isCurrentUserAuthor: false,
roomId: 'chat-id',
uuid: 'client-uuid-1',
),
);
final state = chatRoomCubit.state as ChatRoomStateLoaded;
expect(shouldPlayIncomingSound, isFalse);
expect(state.chatMessages.where((message) => message.uuid == 'client-uuid-1').length, 1);
});
test('addIncomingMessage - добавляет собственное сообщение (эхо второго устройства) без звука и без обновления списка', () async {
const uuid = 'room-uuid';
when(mockChatRepository.getChatRoom(uuid)).thenAnswer((_) async => testChatRoom);
when(mockChatRepository.getChatMessages(uuid, 1)).thenAnswer((_) async => testChatMessages);
@@ -1523,7 +1574,7 @@ void main() {
await chatRoomCubit.initChat(uuid);
await Future.delayed(const Duration(milliseconds: 200));
chatRoomCubit.addIncomingMessage(
final shouldPlayIncomingSound = chatRoomCubit.addIncomingMessage(
ChatMessageModel(
id: 77,
data: 'Own echo',
@@ -1531,14 +1582,36 @@ void main() {
authorId: 1,
updatedAt: DateTime.now(),
isRead: true,
isCurrentUserAuthor: true,
isCurrentUserAuthor: false,
roomId: 'chat-id',
),
);
final state = chatRoomCubit.state as ChatRoomStateLoaded;
expect(state.chatMessages.length, 1);
expect(state.chatMessages.any((message) => message.id == 77), isFalse);
expect(shouldPlayIncomingSound, isFalse);
expect(state.chatMessages.length, 2);
expect(state.chatMessages.any((message) => message.id == 77), isTrue);
// Список чатов за собственные сообщения обновляет S3 (new-chat-messages.{senderId}).
verifyNever(mockChatRepository.emitNewMessageToChats(any));
});
test('addIncomingMessage - игнорирует событие, когда state не loaded', () {
final shouldPlayIncomingSound = chatRoomCubit.addIncomingMessage(
ChatMessageModel(
id: 42,
data: 'Arrived before chat is loaded',
mediaData: null,
authorId: 2,
updatedAt: DateTime.now(),
isRead: false,
isCurrentUserAuthor: false,
roomId: 'chat-id',
),
);
expect(shouldPlayIncomingSound, isFalse);
expect(chatRoomCubit.state, isA<ChatRoomStateLoading>());
verifyNever(mockChatRepository.emitNewMessageToChats(any));
});
test('updateChosenPlanState - не затирает сообщения, пришедшие во время запроса', () async {