jellyfin_album_screen_test.dart 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import 'package:cardash_launcher/core/theme/app_theme.dart';
  2. import 'package:cardash_launcher/data/services/jellyfin_library_service.dart';
  3. import 'package:cardash_launcher/features/home/system_controller.dart';
  4. import 'package:cardash_launcher/features/jellyfin/jellyfin_album_screen.dart';
  5. import 'package:cardash_launcher/features/jellyfin/jellyfin_playback_controller.dart';
  6. import 'package:cardash_launcher/features/settings/jellyfin_controller.dart';
  7. import 'package:flutter/material.dart';
  8. import 'package:flutter_test/flutter_test.dart';
  9. import 'package:provider/provider.dart';
  10. import 'jellyfin_fakes.dart';
  11. void main() {
  12. testWidgets('shows the album, track list and transport, and changes tracks', (
  13. tester,
  14. ) async {
  15. await tester.binding.setSurfaceSize(const Size(1280, 800));
  16. addTearDown(() => tester.binding.setSurfaceSize(null));
  17. final jellyfin = await configuredJellyfinController();
  18. final gateway = FakeJellyfinLibraryGateway()
  19. ..albumFavorite = true
  20. ..tracks = {
  21. 'album-1': [
  22. track('t1', albumId: 'album-1', albumName: 'Album 1', index: 1),
  23. track('t2', albumId: 'album-1', albumName: 'Album 1', index: 2),
  24. track('t3', albumId: 'album-1', albumName: 'Album 1', index: 3),
  25. ],
  26. };
  27. final library = JellyfinLibraryService(
  28. connectionProvider: () => jellyfin.connection,
  29. gateway: gateway,
  30. );
  31. final platform = FakeJellyfinPlaybackPlatform();
  32. final playback = JellyfinPlaybackController(
  33. platform,
  34. library,
  35. jellyfin,
  36. pollInterval: const Duration(hours: 1),
  37. );
  38. final albumOne = album('album-1', year: 2025);
  39. await playback.playAlbum(albumOne);
  40. final system = SystemController(FakeSystemPlatform());
  41. await tester.pumpWidget(
  42. MultiProvider(
  43. providers: [
  44. Provider<JellyfinLibraryService>.value(value: library),
  45. ChangeNotifierProvider<JellyfinController>.value(value: jellyfin),
  46. ChangeNotifierProvider<JellyfinPlaybackController>.value(
  47. value: playback,
  48. ),
  49. ChangeNotifierProvider<SystemController>.value(value: system),
  50. ],
  51. child: MaterialApp(
  52. theme: AppTheme.light(),
  53. home: JellyfinAlbumScreen(album: albumOne),
  54. ),
  55. ),
  56. );
  57. await tester.pumpAndSettle();
  58. expect(find.text('Album album-1 (2025)'), findsOneWidget);
  59. expect(find.text('Tracks'), findsOneWidget);
  60. expect(find.text('Track t1'), findsWidgets);
  61. expect(find.text('Track t2'), findsOneWidget);
  62. expect(find.text('Track t3'), findsOneWidget);
  63. expect(find.text('Now playing'), findsOneWidget);
  64. expect(find.byType(Slider), findsOneWidget);
  65. expect(find.bySemanticsLabel('Previous track'), findsOneWidget);
  66. expect(find.bySemanticsLabel('Pause music'), findsOneWidget);
  67. expect(find.bySemanticsLabel('Next track'), findsOneWidget);
  68. expect(find.bySemanticsLabel('Volume down'), findsOneWidget);
  69. expect(find.bySemanticsLabel('Volume up'), findsOneWidget);
  70. expect(find.bySemanticsLabel('Remove from favorites'), findsOneWidget);
  71. final coverRect = tester.getRect(
  72. find.byKey(const ValueKey('jellyfin-album-cover')),
  73. );
  74. final cardRect = tester.getRect(
  75. find.byKey(const ValueKey('jellyfin-album-progress-card')),
  76. );
  77. expect(cardRect.bottom, moreOrLessEquals(coverRect.bottom, epsilon: 0.5));
  78. final trackListRect = tester.getRect(
  79. find.byKey(const ValueKey('jellyfin-album-track-list')),
  80. );
  81. expect(trackListRect.top, greaterThan(coverRect.bottom));
  82. expect(tester.takeException(), isNull);
  83. await tester.drag(find.byType(Slider), const Offset(120, 0));
  84. await tester.pumpAndSettle();
  85. expect(
  86. platform.commands.any((command) => command.startsWith('seek:')),
  87. isTrue,
  88. );
  89. await tester.tap(find.bySemanticsLabel('Remove from favorites'));
  90. await tester.pumpAndSettle();
  91. expect(gateway.setFavoriteCalls, 1);
  92. expect(gateway.lastFavoriteValue, isFalse);
  93. expect(find.bySemanticsLabel('Add to favorites'), findsOneWidget);
  94. await tester.tap(find.bySemanticsLabel('Next track'));
  95. await tester.pumpAndSettle();
  96. expect(platform.commands, contains('next'));
  97. expect(playback.currentItem?.trackId, 't2');
  98. expect(find.text('Track t2'), findsWidgets);
  99. await tester.tap(find.text('Track t3'));
  100. await tester.pumpAndSettle();
  101. expect(platform.commands, contains('seekToIndex:2'));
  102. expect(playback.currentItem?.trackId, 't3');
  103. await tester.tap(find.bySemanticsLabel('Previous track'));
  104. await tester.pumpAndSettle();
  105. expect(platform.commands, contains('previous'));
  106. expect(playback.currentItem?.trackId, 't2');
  107. await tester.binding.setSurfaceSize(const Size(1024, 600));
  108. await tester.pumpAndSettle();
  109. final narrowCover = tester.getRect(
  110. find.byKey(const ValueKey('jellyfin-album-cover')),
  111. );
  112. final narrowCard = tester.getRect(
  113. find.byKey(const ValueKey('jellyfin-album-progress-card')),
  114. );
  115. expect(
  116. narrowCard.bottom,
  117. moreOrLessEquals(narrowCover.bottom, epsilon: 0.5),
  118. );
  119. expect(tester.takeException(), isNull);
  120. await tester.pumpWidget(const SizedBox.shrink());
  121. playback.dispose();
  122. jellyfin.dispose();
  123. system.dispose();
  124. });
  125. }