Files
plezy/test/screens/music/queue_sheet_test.dart
T
edde746 7d6a747aa7 feat(music): now-playing, mini-player, queue and lyrics UI
Persistent mini-player over the profile navigator (route-aware
suppression, bottom-bar inset), slide-up now-playing screen with
mobile/desktop/TV layouts (blurred-art background, pause shape morphs,
dpad seek chain), queue sheet with reorder/remove/jump, synced lyrics
view, TV rail now-playing item, sleep timer, and audio playlist
playback. Adds download affordances on music surfaces.
2026-07-05 21:50:11 +02:00

128 lines
4.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:plezy/i18n/strings.g.dart';
import 'package:plezy/media/media_backend.dart';
import 'package:plezy/media/media_item.dart';
import 'package:plezy/media/media_kind.dart';
import 'package:plezy/providers/multi_server_provider.dart';
import 'package:plezy/screens/music/queue_sheet.dart';
import 'package:plezy/services/data_aggregation_service.dart';
import 'package:plezy/services/multi_server_manager.dart';
import 'package:plezy/services/music/music_playback_service.dart';
import 'package:plezy/services/settings_service.dart';
import 'package:plezy/theme/mono_theme.dart';
import 'package:plezy/widgets/music/track_row.dart';
import 'package:provider/provider.dart';
import '../../test_helpers/prefs.dart';
MediaItem _track(String id, String title) => MediaItem(
id: id,
backend: MediaBackend.plex,
kind: MediaKind.track,
title: title,
parentId: 'album_1',
parentTitle: 'First Light',
grandparentId: 'artist_1',
grandparentTitle: 'Test Artist',
durationMs: 180000,
serverId: 'server_1',
serverName: 'Server',
);
/// Fixed-state fake queue: three tracks, playing the first.
class _FakeQueueService extends StubMusicPlaybackService {
final List<MediaItem> tracks;
final List<int> jumps = [];
_FakeQueueService(this.tracks);
@override
bool get isAvailable => true;
@override
MediaItem? get currentTrack => tracks.first;
@override
MusicPlaybackStatus get status => MusicPlaybackStatus.playing;
@override
List<MediaItem> get queue => tracks;
@override
int get currentIndex => 0;
@override
Future<void> jumpTo(int index) async {
jumps.add(index);
}
}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
setUp(() async {
resetSharedPreferencesForTest();
SettingsService.resetForTesting();
LocaleSettings.setLocaleSync(AppLocale.en);
await SettingsService.getInstance();
});
Widget wrap(MusicPlaybackService service) {
final manager = MultiServerManager();
final multiServerProvider = MultiServerProvider(manager, DataAggregationService(manager));
addTearDown(multiServerProvider.dispose);
return TranslationProvider(
child: MultiProvider(
providers: [
ChangeNotifierProvider<MultiServerProvider>.value(value: multiServerProvider),
ChangeNotifierProvider<MusicPlaybackService>.value(value: service),
],
child: MaterialApp(
theme: monoTheme(dark: true),
home: const Scaffold(body: SizedBox(width: 500, height: 700, child: QueueSheet())),
),
),
);
}
testWidgets('renders header, pinned current track, and upcoming rows', (tester) async {
final service = _FakeQueueService([_track('t1', 'Alpha'), _track('t2', 'Beta'), _track('t3', 'Gamma')]);
await tester.pumpWidget(wrap(service));
// pumpAndSettle would never settle: the current-track equalizer animates
// forever while the fake reports "playing".
await tester.pump();
await tester.pump(const Duration(milliseconds: 300));
// Header: title + total track count.
expect(find.text(t.music.queue), findsOneWidget);
expect(find.text(t.music.trackCount(n: 3)), findsOneWidget);
// Pinned current row (not a TrackRow) + "Up next" label.
expect(find.text('Alpha'), findsOneWidget);
expect(find.text(t.music.upNext), findsOneWidget);
// Upcoming tracks render as TrackRows.
expect(find.byType(TrackRow), findsNWidgets(2));
expect(find.text('Beta'), findsOneWidget);
expect(find.text('Gamma'), findsOneWidget);
});
testWidgets('tapping an upcoming row jumps to its queue index', (tester) async {
final service = _FakeQueueService([_track('t1', 'Alpha'), _track('t2', 'Beta'), _track('t3', 'Gamma')]);
await tester.pumpWidget(wrap(service));
// pumpAndSettle would never settle: the current-track equalizer animates
// forever while the fake reports "playing".
await tester.pump();
await tester.pump(const Duration(milliseconds: 300));
await tester.tap(find.text('Gamma'));
await tester.pump();
expect(service.jumps, [2]);
});
}