import 'package:cardash_launcher/core/theme/app_theme.dart'; import 'package:cardash_launcher/data/services/jellyfin_library_service.dart'; import 'package:cardash_launcher/features/home/system_controller.dart'; import 'package:cardash_launcher/features/home/widgets/volume_card.dart'; import 'package:cardash_launcher/features/jellyfin/jellyfin_album_screen.dart'; import 'package:cardash_launcher/features/jellyfin/jellyfin_playback_controller.dart'; import 'package:cardash_launcher/features/settings/jellyfin_controller.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:provider/provider.dart'; import 'jellyfin_fakes.dart'; void main() { testWidgets('shows the album, track list and transport, and changes tracks', ( tester, ) async { await tester.binding.setSurfaceSize(const Size(1280, 800)); addTearDown(() => tester.binding.setSurfaceSize(null)); final jellyfin = await configuredJellyfinController(); final gateway = FakeJellyfinLibraryGateway() ..albumFavorite = true ..tracks = { 'album-1': [ track('t1', albumId: 'album-1', albumName: 'Album 1', index: 1), track('t2', albumId: 'album-1', albumName: 'Album 1', index: 2), track('t3', albumId: 'album-1', albumName: 'Album 1', index: 3), ], }; final library = JellyfinLibraryService( connectionProvider: () => jellyfin.connection, gateway: gateway, ); final platform = FakeJellyfinPlaybackPlatform(); final playback = JellyfinPlaybackController( platform, library, jellyfin, pollInterval: const Duration(hours: 1), ); await playback.playAlbum(album('album-1')); final system = SystemController(FakeSystemPlatform()); await tester.pumpWidget( MultiProvider( providers: [ Provider.value(value: library), ChangeNotifierProvider.value(value: jellyfin), ChangeNotifierProvider.value( value: playback, ), ChangeNotifierProvider.value(value: system), ], child: MaterialApp( theme: AppTheme.light(), home: JellyfinAlbumScreen(album: album('album-1')), ), ), ); await tester.pumpAndSettle(); expect(find.text('Album album-1'), findsOneWidget); expect(find.text('Tracks'), findsOneWidget); expect(find.text('Track t1'), findsWidgets); expect(find.text('Track t2'), findsOneWidget); expect(find.text('Track t3'), findsOneWidget); expect(find.text('Now playing'), findsOneWidget); expect(find.byType(VolumeCard), findsOneWidget); expect(find.bySemanticsLabel('Previous track'), findsOneWidget); expect(find.bySemanticsLabel('Next track'), findsOneWidget); expect(find.bySemanticsLabel('Remove from favorites'), findsOneWidget); expect(tester.takeException(), isNull); await tester.tap(find.bySemanticsLabel('Remove from favorites')); await tester.pumpAndSettle(); expect(gateway.setFavoriteCalls, 1); expect(gateway.lastFavoriteValue, isFalse); expect(find.bySemanticsLabel('Add to favorites'), findsOneWidget); await tester.tap(find.bySemanticsLabel('Next track')); await tester.pumpAndSettle(); expect(platform.commands, contains('next')); expect(playback.currentItem?.trackId, 't2'); expect(find.text('Track t2'), findsWidgets); await tester.tap(find.text('Track t3')); await tester.pumpAndSettle(); expect(platform.commands, contains('seekToIndex:2')); expect(playback.currentItem?.trackId, 't3'); await tester.tap(find.bySemanticsLabel('Previous track')); await tester.pumpAndSettle(); expect(platform.commands, contains('previous')); expect(playback.currentItem?.trackId, 't2'); await tester.pumpWidget(const SizedBox.shrink()); playback.dispose(); jellyfin.dispose(); system.dispose(); }); }