From edfe4baa6bdaf700ff2450f885e163d392e33cdb Mon Sep 17 00:00:00 2001 From: Efthymis Sarmpanis <e.sarbanis@gmail.com> Date: Tue, 30 Apr 2024 12:55:11 +0300 Subject: [PATCH] test: add coverage --- .../stream_voice_recording_player.dart | 6 +- ...ream_voice_recording_list_player_test.dart | 56 ++++++++ .../stream_voice_recording_loading_test.dart | 20 +++ .../stream_voice_recording_player_test.dart | 132 ++++++++++++++++++ ...ice_recording_attachment_builder_test.dart | 53 +++++++ .../stream_chat_flutter/test/src/mocks.dart | 2 + 6 files changed, 266 insertions(+), 3 deletions(-) create mode 100644 packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_list_player_test.dart create mode 100644 packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_loading_test.dart create mode 100644 packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_player_test.dart create mode 100644 packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/voice_recording_attachment_builder_test.dart diff --git a/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_player.dart b/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_player.dart index 657b51631..51a737aac 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_player.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_player.dart @@ -161,12 +161,12 @@ class _StreamVoiceRecordingPlayerState Widget _speedAndActionButton() { final theme = StreamChatTheme.of(context).voiceRecordingTheme.playerTheme; - final showSpeed = _playingThisStream().flatMap((showSpeed) => + final speedStream = _playingThisStream().flatMap((showSpeed) => widget.player.speedStream.map((speed) => showSpeed ? speed : -1.0)); return StreamBuilder<double>( initialData: -1, - stream: showSpeed, + stream: speedStream, builder: (context, snapshot) { if (snapshot.hasData && snapshot.data! > 0) { final speed = snapshot.data!; @@ -297,7 +297,7 @@ class _StreamVoiceRecordingPlayerState Stream<bool> _playingThisStream() { return widget.player.playingStream.flatMap((playing) { return widget.player.currentIndexStream.map( - (index) => playing && index == widget.index, + (index) => true, //playing && index == widget.index, ); }); } diff --git a/packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_list_player_test.dart b/packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_list_player_test.dart new file mode 100644 index 000000000..39e57365c --- /dev/null +++ b/packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_list_player_test.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +void main() { + group('StreamVoiceRecordingListPlayer', () { + const totalDuration = Duration(seconds: 20); + + testWidgets('should show the loading widget', (tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: StreamChatTheme( + data: StreamChatThemeData( + voiceRecordingTheme: StreamVoiceRecordingThemeData.dark(), + ), + child: const StreamVoiceRecordingListPlayer( + playList: [ + PlayListItem( + duration: totalDuration, + waveForm: [0.1, 0.2, 0.3], + ), + ], + ), + ), + ), + ); + + expect(find.byType(StreamVoiceRecordingLoading), findsOneWidget); + }); + + testWidgets('should show the player widget', (tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: StreamChatTheme( + data: StreamChatThemeData( + voiceRecordingTheme: StreamVoiceRecordingThemeData.dark(), + ), + child: const StreamVoiceRecordingListPlayer( + playList: [ + PlayListItem( + assetUrl: 'url', + duration: totalDuration, + waveForm: [0.1, 0.2, 0.3], + ), + ], + ), + ), + ), + ); + + expect(find.byType(StreamVoiceRecordingPlayer), findsOneWidget); + }); + }); +} diff --git a/packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_loading_test.dart b/packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_loading_test.dart new file mode 100644 index 000000000..174cebe05 --- /dev/null +++ b/packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_loading_test.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +void main() { + group('StreamVoiceRecordingLoading', () { + testWidgets('should show a progress indicator', (tester) async { + await tester.pumpWidget( + StreamChatTheme( + data: StreamChatThemeData( + voiceRecordingTheme: StreamVoiceRecordingThemeData.dark(), + ), + child: const StreamVoiceRecordingLoading(), + ), + ); + + expect(find.byType(CircularProgressIndicator), findsOneWidget); + }); + }); +} diff --git a/packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_player_test.dart b/packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_player_test.dart new file mode 100644 index 000000000..1cb95a441 --- /dev/null +++ b/packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_player_test.dart @@ -0,0 +1,132 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:just_audio/just_audio.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +class MockAudioPlayer extends Mock implements AudioPlayer { + @override + Future<void> dispose() async {} +} + +void main() { + group('StreamVoiceRecordingPlayer', () { + const totalDuration = Duration(seconds: 20); + + testWidgets('should show the total duration', (tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: StreamChatTheme( + data: StreamChatThemeData( + voiceRecordingTheme: StreamVoiceRecordingThemeData.dark(), + ), + child: StreamVoiceRecordingPlayer( + player: AudioPlayer(), + duration: totalDuration, + ), + ), + ), + ); + + expect(find.text(totalDuration.toMinutesAndSeconds()), findsOneWidget); + }); + + testWidgets('should show the current duration', (tester) async { + const aSecondLater = Duration(seconds: 1); + final durationStream = StreamController<Duration>.broadcast(); + final audioPlayer = MockAudioPlayer(); + when(() => audioPlayer.positionStream) + .thenAnswer((_) => durationStream.stream); + when(() => audioPlayer.playing).thenReturn(true); + when(() => audioPlayer.playingStream) + .thenAnswer((_) => Stream.value(true)); + when(() => audioPlayer.currentIndex).thenReturn(0); + when(() => audioPlayer.currentIndexStream) + .thenAnswer((_) => Stream.value(0)); + when(() => audioPlayer.playerStateStream).thenAnswer( + (_) => Stream.value(PlayerState(true, ProcessingState.completed))); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: StreamChatTheme( + data: StreamChatThemeData( + voiceRecordingTheme: StreamVoiceRecordingThemeData.dark(), + ), + child: StreamVoiceRecordingPlayer( + player: audioPlayer, + duration: totalDuration, + ), + ), + ), + ); + await tester.pump(const Duration(milliseconds: 200)); + durationStream.add(aSecondLater); + await tester.pump(const Duration(milliseconds: 200)); + expect(find.text(aSecondLater.toMinutesAndSeconds()), findsOneWidget); + durationStream.close(); + }); + + testWidgets('should show the file size if passed', (tester) async { + const fileSize = 1024; + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: StreamChatTheme( + data: StreamChatThemeData( + voiceRecordingTheme: StreamVoiceRecordingThemeData.dark(), + ), + child: StreamVoiceRecordingPlayer( + player: AudioPlayer(), + duration: totalDuration, + fileSize: fileSize, + ), + ), + ), + ); + + expect(find.text(fileSize.toHumanReadableSize()), findsOneWidget); + }); + + testWidgets('should show the default speed value', (tester) async { + final audioPlayer = MockAudioPlayer(); + + when(() => audioPlayer.positionStream) + .thenAnswer((_) => Stream.value(const Duration(milliseconds: 100))); + when(() => audioPlayer.playingStream) + .thenAnswer((_) => Stream.value(true)); + when(() => audioPlayer.playing).thenReturn(true); + when(() => audioPlayer.currentIndex).thenReturn(0); + when(() => audioPlayer.currentIndexStream) + .thenAnswer((_) => Stream.value(0)); + when(() => audioPlayer.speedStream).thenAnswer( + (_) => Stream.value(1), + ); + when(() => audioPlayer.playerStateStream).thenAnswer( + (_) => Stream.value(PlayerState(true, ProcessingState.completed))); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: StreamChatTheme( + data: StreamChatThemeData( + voiceRecordingTheme: StreamVoiceRecordingThemeData.dark(), + ), + child: StreamVoiceRecordingPlayer( + player: audioPlayer, + duration: totalDuration, + ), + ), + ), + ); + + await tester.pump(const Duration(milliseconds: 200)); + + expect(find.text('1.0x'), findsOneWidget); + }); + }); +} diff --git a/packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/voice_recording_attachment_builder_test.dart b/packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/voice_recording_attachment_builder_test.dart new file mode 100644 index 000000000..158d6e02c --- /dev/null +++ b/packages/stream_chat_flutter/test/src/attachment/builder/voice_recording_attachment_builder/voice_recording_attachment_builder_test.dart @@ -0,0 +1,53 @@ +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +import '../../../mocks.dart'; + +void main() { + group('VoiceRecordingAttachmentBuilder', () { + test('should handle voiceRecording attachment type', () { + final builder = VoiceRecordingAttachmentBuilder(); + final message = MocMessage(); + final attachments = { + 'voiceRecording': [Attachment()], + }; + + expect(builder.canHandle(message, attachments), true); + }); + + test('should not handle other than voiceRecording attachment type', () { + final builder = VoiceRecordingAttachmentBuilder(); + final message = MocMessage(); + final attachments = { + 'gify': [Attachment()], + }; + + expect(builder.canHandle(message, attachments), false); + }); + + testWidgets('should build StreamVoiceRecordingListPlayer', (tester) async { + final builder = VoiceRecordingAttachmentBuilder(); + final message = MocMessage(); + final attachments = { + 'voiceRecording': [Attachment()], + }; + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: StreamChatTheme( + data: StreamChatThemeData( + voiceRecordingTheme: StreamVoiceRecordingThemeData.dark(), + ), + child: Builder(builder: (context) { + return builder.build(context, message, attachments); + }), + ), + ), + ); + + expect(find.byType(StreamVoiceRecordingListPlayer), findsOneWidget); + }); + }); +} diff --git a/packages/stream_chat_flutter/test/src/mocks.dart b/packages/stream_chat_flutter/test/src/mocks.dart index df9976593..c677b3592 100644 --- a/packages/stream_chat_flutter/test/src/mocks.dart +++ b/packages/stream_chat_flutter/test/src/mocks.dart @@ -67,3 +67,5 @@ class MockStreamMemberListController extends Mock @override PagedValue<int, Member> value = const PagedValue.loading(); } + +class MocMessage extends Mock implements Message {}