fix(ui): fix stopTyping unhandled exceptions when network is off or spotty. (#1296)
* feat(llc, ui): Introduce `keyStrokeHandler` to properly handle keyStrokes. Signed-off-by: xsahil03x <[email protected]> * chore(ui): update CHANGELOG.md Signed-off-by: xsahil03x <[email protected]> * test(llc): add key_stroke_handler_test.dart Signed-off-by: xsahil03x <[email protected]>
This commit is contained in:
@@ -2658,16 +2658,22 @@ void main() {
|
||||
});
|
||||
|
||||
test(
|
||||
'''should send `typingStart` event if there is not already a typingEvent or the difference between the two is >= 2 seconds''',
|
||||
'''should send `typingStart` event if there is not already a typingEvent or the difference between the two is > 3 seconds''',
|
||||
() async {
|
||||
final typingEvent = Event(type: EventType.typingStart);
|
||||
final startTypingEvent = Event(type: EventType.typingStart);
|
||||
final stopTypingEvent = Event(type: EventType.typingStop);
|
||||
|
||||
when(() => channel.config?.typingEvents).thenReturn(true);
|
||||
|
||||
when(() => client.sendEvent(
|
||||
channelId,
|
||||
channelType,
|
||||
any(that: isSameEventAs(typingEvent)),
|
||||
any(that: isSameEventAs(startTypingEvent)),
|
||||
)).thenAnswer((_) async => EmptyResponse());
|
||||
when(() => client.sendEvent(
|
||||
channelId,
|
||||
channelType,
|
||||
any(that: isSameEventAs(stopTypingEvent)),
|
||||
)).thenAnswer((_) async => EmptyResponse());
|
||||
|
||||
await channel.keyStroke();
|
||||
@@ -2675,7 +2681,12 @@ void main() {
|
||||
verify(() => client.sendEvent(
|
||||
channelId,
|
||||
channelType,
|
||||
any(that: isSameEventAs(typingEvent)),
|
||||
any(that: isSameEventAs(startTypingEvent)),
|
||||
)).called(1);
|
||||
verify(() => client.sendEvent(
|
||||
channelId,
|
||||
channelType,
|
||||
any(that: isSameEventAs(stopTypingEvent)),
|
||||
)).called(1);
|
||||
},
|
||||
);
|
||||
@@ -2688,7 +2699,7 @@ void main() {
|
||||
|
||||
final typingStopEvent = Event(type: EventType.typingStop);
|
||||
|
||||
await channel.keyStroke();
|
||||
await channel.stopTyping();
|
||||
|
||||
verifyNever(() => client.sendEvent(
|
||||
channelId,
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
mixin OnKeyStrokeEvent {
|
||||
Future<void> call([String? parentId]);
|
||||
}
|
||||
|
||||
class OnStartTyping extends Mock implements OnKeyStrokeEvent {}
|
||||
|
||||
class OnStopTyping extends Mock implements OnKeyStrokeEvent {}
|
||||
|
||||
void main() {
|
||||
final onStartTyping = OnStartTyping();
|
||||
final onStopTyping = OnStopTyping();
|
||||
late KeyStrokeHandler keyStrokeHandler;
|
||||
|
||||
const startTypingEventTimeout = 1;
|
||||
const startTypingResendInterval = 2;
|
||||
|
||||
setUp(() {
|
||||
when(() => onStartTyping(any())).thenAnswer((_) => Future.value());
|
||||
when(() => onStopTyping(any())).thenAnswer((_) => Future.value());
|
||||
|
||||
keyStrokeHandler = KeyStrokeHandler(
|
||||
onStartTyping: onStartTyping,
|
||||
onStopTyping: onStopTyping,
|
||||
startTypingEventTimeout: startTypingEventTimeout,
|
||||
startTypingResendInterval: startTypingResendInterval,
|
||||
);
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
keyStrokeHandler.cancel();
|
||||
clearInteractions(onStartTyping);
|
||||
clearInteractions(onStopTyping);
|
||||
});
|
||||
|
||||
group('call', () {
|
||||
test('should work fine', () {
|
||||
expect(keyStrokeHandler.call(), completes);
|
||||
});
|
||||
|
||||
test('should call onStartTyping', () async {
|
||||
keyStrokeHandler.call();
|
||||
verify(() => onStartTyping(any())).called(1);
|
||||
});
|
||||
|
||||
test('should call onStopTyping', () async {
|
||||
keyStrokeHandler
|
||||
..call()
|
||||
..cancel();
|
||||
verify(() => onStopTyping(any())).called(1);
|
||||
});
|
||||
|
||||
test('should call onStartTyping after startTypingResendInterval', () async {
|
||||
final watch = Stopwatch()..start();
|
||||
while (watch.elapsed.inSeconds <= startTypingResendInterval) {
|
||||
keyStrokeHandler.call();
|
||||
}
|
||||
watch.stop();
|
||||
verify(() => onStartTyping(any())).called(2);
|
||||
});
|
||||
|
||||
test('should call onStopTyping after startTypingEventTimeout', () async {
|
||||
keyStrokeHandler.call();
|
||||
await Future.delayed(const Duration(seconds: startTypingEventTimeout));
|
||||
verify(() => onStopTyping(any())).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user