From f79c74d14323ae9102004838be6c730bfc8ea7d2 Mon Sep 17 00:00:00 2001 From: Efthymis Sarmpanis Date: Tue, 20 Feb 2024 16:42:56 +0200 Subject: [PATCH] fix(ui): be lenient when calling nullable onThreadTap method --- packages/stream_chat_flutter/CHANGELOG.md | 2 + .../lib/src/message_widget/bottom_row.dart | 2 +- .../message_list_view/bottom_row_test.dart | 71 +++++++++++++++++++ .../stream_chat_flutter/test/src/mocks.dart | 4 ++ 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 packages/stream_chat_flutter/test/src/message_list_view/bottom_row_test.dart diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index ae12bed26..7a08b70df 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -7,6 +7,8 @@ 🐞 Fixed - Removed double focus on `StreamMessageInput` when `focusNode` is provided for web and desktop. +- Optionally call `onThreadTap` in `BottomRow` to avoid `Null check operator used on a null value` + ## 7.0.1 diff --git a/packages/stream_chat_flutter/lib/src/message_widget/bottom_row.dart b/packages/stream_chat_flutter/lib/src/message_widget/bottom_row.dart index d7eb2f6c9..3624430fc 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/bottom_row.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/bottom_row.dart @@ -169,7 +169,7 @@ class BottomRow extends StatelessWidget { final channel = StreamChannel.of(context); message = await channel.getMessage(message.parentId!); } - return onThreadTap!(message); + return onThreadTap?.call(message); } catch (e, stk) { debugPrint('Error while fetching message: $e, $stk'); } diff --git a/packages/stream_chat_flutter/test/src/message_list_view/bottom_row_test.dart b/packages/stream_chat_flutter/test/src/message_list_view/bottom_row_test.dart new file mode 100644 index 000000000..f2c9dcc56 --- /dev/null +++ b/packages/stream_chat_flutter/test/src/message_list_view/bottom_row_test.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:stream_chat_flutter/src/message_widget/bottom_row.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +import '../mocks.dart'; + +void main() { + late Channel channel; + late ChannelClientState channelClientState; + + setUp(() { + channel = MockChannel(); + when(() => channel.on(any(), any(), any(), any())) + .thenAnswer((_) => const Stream.empty()); + channelClientState = MockChannelState(); + when(() => channel.state).thenReturn(channelClientState); + when(() => channelClientState.messages).thenReturn([ + Message( + id: 'parentId', + ) + ]); + }); + + setUpAll(() { + registerFallbackValue(Message()); + }); + + testWidgets('BottomRow', (tester) async { + final theme = StreamChatThemeData.light(); + final onThreadTap = MockVoidSingleParamCallback(); + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: StreamChannel( + channel: channel, + child: BottomRow( + message: Message( + parentId: 'parentId', + ), + isDeleted: false, + showThreadReplyIndicator: false, + showUsername: false, + showInChannel: true, + showTimeStamp: false, + reverse: false, + showSendingIndicator: false, + hasUrlAttachments: false, + isGiphy: false, + isOnlyEmoji: false, + messageTheme: theme.otherMessageTheme, + streamChatTheme: theme, + hasNonUrlAttachments: false, + streamChat: StreamChatState(), + onThreadTap: onThreadTap, + ), + ), + ), + ), + ), + ); + + await tester.tap(find.byType(GestureDetector)); + await tester.pumpAndSettle(); + + verify(() => onThreadTap.call(any())); + }); +} diff --git a/packages/stream_chat_flutter/test/src/mocks.dart b/packages/stream_chat_flutter/test/src/mocks.dart index 1f7ddbd92..df9976593 100644 --- a/packages/stream_chat_flutter/test/src/mocks.dart +++ b/packages/stream_chat_flutter/test/src/mocks.dart @@ -46,6 +46,10 @@ class MockVoidCallback extends Mock { void call(); } +class MockVoidSingleParamCallback extends Mock { + void call(T param); +} + class MockAttachmentHandler extends Mock implements StreamAttachmentHandler {} class MockMember extends Mock implements Member {}