fix(music): keep collection and playlist artwork square
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
import 'package:drift/native.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:plezy/database/app_database.dart';
|
||||
import 'package:plezy/i18n/strings.g.dart';
|
||||
import 'package:plezy/media/ids.dart';
|
||||
import 'package:plezy/media/library_query.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/media/media_server_client.dart';
|
||||
import 'package:plezy/media/server_capabilities.dart';
|
||||
import 'package:plezy/providers/download_provider.dart';
|
||||
import 'package:plezy/providers/multi_server_provider.dart';
|
||||
import 'package:plezy/screens/collection_detail_screen.dart';
|
||||
import 'package:plezy/services/data_aggregation_service.dart';
|
||||
import 'package:plezy/services/download_manager_service.dart';
|
||||
import 'package:plezy/services/download_storage_service.dart';
|
||||
import 'package:plezy/services/jellyfin_api_cache.dart';
|
||||
import 'package:plezy/services/multi_server_manager.dart';
|
||||
import 'package:plezy/services/plex_api_cache.dart';
|
||||
import 'package:plezy/services/settings_service.dart';
|
||||
import 'package:plezy/theme/mono_theme.dart';
|
||||
import 'package:plezy/utils/media_server_http_client.dart';
|
||||
import 'package:plezy/widgets/focusable_media_card.dart';
|
||||
import 'package:plezy/widgets/media_card_sliver_layout.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../test_helpers/media_items.dart';
|
||||
import '../test_helpers/paged_fakes.dart';
|
||||
import '../test_helpers/prefs.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
setUp(() {
|
||||
resetSharedPreferencesForTest();
|
||||
SettingsService.resetForTesting();
|
||||
LocaleSettings.setLocaleSync(AppLocale.en);
|
||||
});
|
||||
|
||||
testWidgets('music collection contents use square grid geometry and cards', (tester) async {
|
||||
final album = testMediaItem(
|
||||
id: 'album_1',
|
||||
backend: MediaBackend.plex,
|
||||
kind: MediaKind.album,
|
||||
title: 'Album 1',
|
||||
serverId: 'server_1',
|
||||
serverName: 'Server',
|
||||
);
|
||||
final harness = await _createHarness([album]);
|
||||
|
||||
await tester.pumpWidget(
|
||||
harness.wrap(SizedBox(width: 1280, height: 720, child: CollectionDetailScreen(collection: _collection))),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final layout = tester.widget<MediaCardSliverLayout>(find.byType(MediaCardSliverLayout));
|
||||
expect(layout.shape, CardShape.square);
|
||||
expect(layout.fullBleedImage, isFalse);
|
||||
expect(tester.widget<FocusableMediaCard>(find.byType(FocusableMediaCard)).cardShapeOverride, CardShape.square);
|
||||
});
|
||||
}
|
||||
|
||||
final _collection = MediaItem(
|
||||
id: 'collection_1',
|
||||
backend: MediaBackend.plex,
|
||||
kind: MediaKind.collection,
|
||||
title: 'Music Collection',
|
||||
libraryId: 'music',
|
||||
serverId: 'server_1',
|
||||
serverName: 'Server',
|
||||
);
|
||||
|
||||
Future<_CollectionHarness> _createHarness(List<MediaItem> items) async {
|
||||
await SettingsService.getInstance();
|
||||
|
||||
final database = AppDatabase.forTesting(NativeDatabase.memory());
|
||||
PlexApiCache.initialize(database);
|
||||
JellyfinApiCache.initialize(database);
|
||||
|
||||
final downloadManager = DownloadManagerService(
|
||||
database: database,
|
||||
storageService: DownloadStorageService.instance,
|
||||
clientResolver: (serverId, {clientScopeId}) => null,
|
||||
);
|
||||
downloadManager.recoveryFuture = Future<void>.value();
|
||||
final downloadProvider = DownloadProvider.forTesting(downloadManager: downloadManager, database: database);
|
||||
await downloadProvider.ensureInitialized();
|
||||
|
||||
final client = _CollectionClient(items);
|
||||
final manager = MultiServerManager()..debugRegisterClientForTesting(client);
|
||||
final multiServerProvider = MultiServerProvider(manager, DataAggregationService(manager));
|
||||
|
||||
addTearDown(() async {
|
||||
downloadProvider.dispose();
|
||||
downloadManager.dispose();
|
||||
multiServerProvider.dispose();
|
||||
await database.close();
|
||||
});
|
||||
|
||||
return _CollectionHarness(multiServerProvider: multiServerProvider, downloadProvider: downloadProvider);
|
||||
}
|
||||
|
||||
class _CollectionHarness {
|
||||
final MultiServerProvider multiServerProvider;
|
||||
final DownloadProvider downloadProvider;
|
||||
|
||||
const _CollectionHarness({required this.multiServerProvider, required this.downloadProvider});
|
||||
|
||||
Widget wrap(Widget child) {
|
||||
return TranslationProvider(
|
||||
child: MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider<MultiServerProvider>.value(value: multiServerProvider),
|
||||
ChangeNotifierProvider<DownloadProvider>.value(value: downloadProvider),
|
||||
],
|
||||
child: MaterialApp(theme: monoTheme(dark: true), home: child),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _CollectionClient implements MediaServerClient {
|
||||
final List<MediaItem> items;
|
||||
|
||||
const _CollectionClient(this.items);
|
||||
|
||||
@override
|
||||
ServerId get serverId => ServerId('server_1');
|
||||
|
||||
@override
|
||||
String? get serverName => 'Server';
|
||||
|
||||
@override
|
||||
MediaBackend get backend => MediaBackend.plex;
|
||||
|
||||
@override
|
||||
ServerCapabilities get capabilities => ServerCapabilities.plex;
|
||||
|
||||
@override
|
||||
Future<LibraryPage<MediaItem>> fetchCollectionPage(
|
||||
String collectionId, {
|
||||
int? start,
|
||||
int? size,
|
||||
AbortController? abort,
|
||||
String? libraryId,
|
||||
String? libraryTitle,
|
||||
}) async {
|
||||
return fakeLibraryPage(items, start: start, size: size);
|
||||
}
|
||||
|
||||
@override
|
||||
void close() {}
|
||||
|
||||
@override
|
||||
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:drift/native.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/testing.dart';
|
||||
import 'package:plezy/database/app_database.dart';
|
||||
import 'package:plezy/focus/input_mode_tracker.dart';
|
||||
import 'package:plezy/media/ids.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/media/media_library.dart';
|
||||
import 'package:plezy/models/plex/plex_config.dart';
|
||||
import 'package:plezy/navigation/main_screen_scope.dart';
|
||||
import 'package:plezy/providers/multi_server_provider.dart';
|
||||
import 'package:plezy/screens/libraries/tabs/library_collections_tab.dart';
|
||||
import 'package:plezy/services/data_aggregation_service.dart';
|
||||
import 'package:plezy/services/multi_server_manager.dart';
|
||||
import 'package:plezy/services/plex_api_cache.dart';
|
||||
import 'package:plezy/services/plex_client.dart';
|
||||
import 'package:plezy/services/settings_service.dart';
|
||||
import 'package:plezy/theme/mono_theme.dart';
|
||||
import 'package:plezy/widgets/card_inflation_budget.dart';
|
||||
import 'package:plezy/widgets/focusable_media_card.dart';
|
||||
import 'package:plezy/widgets/media_card_sliver_layout.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../test_helpers/prefs.dart';
|
||||
|
||||
final _serverId = ServerId('collection-server');
|
||||
final _musicLibrary = MediaLibrary(
|
||||
id: 'music',
|
||||
backend: MediaBackend.plex,
|
||||
title: 'Music',
|
||||
kind: MediaKind.artist,
|
||||
serverId: _serverId,
|
||||
);
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
setUp(() async {
|
||||
resetSharedPreferencesForTest();
|
||||
SettingsService.resetForTesting();
|
||||
CardInflationBudget.reset();
|
||||
await SettingsService.getInstance();
|
||||
});
|
||||
|
||||
testWidgets('music library collections use square grid geometry and square cards', (tester) async {
|
||||
final harness = _CollectionHarness();
|
||||
addTearDown(harness.dispose);
|
||||
|
||||
tester.view.devicePixelRatio = 1;
|
||||
tester.view.physicalSize = const Size(800, 600);
|
||||
addTearDown(() {
|
||||
tester.view.resetDevicePixelRatio();
|
||||
tester.view.resetPhysicalSize();
|
||||
});
|
||||
|
||||
await tester.pumpWidget(
|
||||
ChangeNotifierProvider<MultiServerProvider>.value(
|
||||
value: harness.provider,
|
||||
child: InputModeTracker(
|
||||
child: MaterialApp(
|
||||
theme: monoTheme(dark: true),
|
||||
home: MainScreenFocusScope(
|
||||
focusSidebar: () {},
|
||||
focusContent: () {},
|
||||
isSidebarFocused: false,
|
||||
sideNavigationWidth: 0,
|
||||
child: Scaffold(
|
||||
body: NestedScrollView(
|
||||
headerSliverBuilder: (context, _) => [
|
||||
SliverOverlapAbsorber(
|
||||
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
|
||||
sliver: const SliverToBoxAdapter(child: SizedBox(height: 1)),
|
||||
),
|
||||
],
|
||||
body: LibraryCollectionsTab(library: _musicLibrary, suppressAutoFocus: true, onBack: () {}),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final layout = tester.widget<MediaCardSliverLayout>(find.byType(MediaCardSliverLayout));
|
||||
expect(layout.shape, CardShape.square);
|
||||
expect(layout.fullBleedImage, isFalse);
|
||||
expect(tester.widget<FocusableMediaCard>(find.byType(FocusableMediaCard)).cardShapeOverride, CardShape.square);
|
||||
});
|
||||
}
|
||||
|
||||
class _CollectionHarness {
|
||||
late final AppDatabase database;
|
||||
late final MultiServerManager manager;
|
||||
late final MultiServerProvider provider;
|
||||
|
||||
_CollectionHarness() {
|
||||
database = AppDatabase.forTesting(NativeDatabase.memory());
|
||||
PlexApiCache.initialize(database);
|
||||
final client = PlexClient.forTesting(
|
||||
config: PlexConfig(
|
||||
baseUrl: 'https://plex.example.com',
|
||||
token: 'token',
|
||||
clientIdentifier: 'client-id',
|
||||
product: 'Plezy',
|
||||
version: 'test',
|
||||
),
|
||||
serverId: _serverId,
|
||||
httpClient: MockClient((request) async {
|
||||
if (request.url.path != '/library/sections/music/collections') {
|
||||
return http.Response('not found', 404);
|
||||
}
|
||||
return http.Response(
|
||||
jsonEncode({
|
||||
'MediaContainer': {
|
||||
'size': 1,
|
||||
'totalSize': 1,
|
||||
'Metadata': [
|
||||
{'ratingKey': 'collection-1', 'type': 'collection', 'title': 'Music Collection', 'childCount': 4},
|
||||
],
|
||||
},
|
||||
}),
|
||||
200,
|
||||
headers: {'content-type': 'application/json'},
|
||||
);
|
||||
}),
|
||||
);
|
||||
manager = MultiServerManager()..debugRegisterClientForTesting(client);
|
||||
provider = MultiServerProvider(manager, DataAggregationService(manager));
|
||||
}
|
||||
|
||||
Future<void> dispose() async {
|
||||
provider.dispose();
|
||||
manager.dispose();
|
||||
await database.close();
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import 'package:plezy/database/app_database.dart';
|
||||
import 'package:plezy/focus/input_mode_tracker.dart';
|
||||
import 'package:plezy/media/ids.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/media/media_library.dart';
|
||||
import 'package:plezy/media/media_playlist.dart';
|
||||
@@ -25,6 +26,7 @@ import 'package:plezy/services/settings_service.dart';
|
||||
import 'package:plezy/theme/mono_theme.dart';
|
||||
import 'package:plezy/widgets/card_inflation_budget.dart';
|
||||
import 'package:plezy/widgets/focusable_media_card.dart';
|
||||
import 'package:plezy/widgets/media_card_sliver_layout.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../test_helpers/prefs.dart';
|
||||
@@ -37,6 +39,13 @@ final _library = MediaLibrary(
|
||||
kind: MediaKind.movie,
|
||||
serverId: _serverId,
|
||||
);
|
||||
final _musicLibrary = MediaLibrary(
|
||||
id: 'music',
|
||||
backend: MediaBackend.plex,
|
||||
title: 'Music',
|
||||
kind: MediaKind.artist,
|
||||
serverId: _serverId,
|
||||
);
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
@@ -55,7 +64,13 @@ void main() {
|
||||
var backCalls = 0;
|
||||
var sidebarCalls = 0;
|
||||
|
||||
await _pumpTab(tester, harness: harness, onBack: () => backCalls++, onSidebar: () => sidebarCalls++);
|
||||
await _pumpTab(
|
||||
tester,
|
||||
harness: harness,
|
||||
library: _library,
|
||||
onBack: () => backCalls++,
|
||||
onSidebar: () => sidebarCalls++,
|
||||
);
|
||||
|
||||
expect(find.byType(SliverGrid), findsOneWidget);
|
||||
final cards = tester.widgetList<FocusableMediaCard>(find.byType(FocusableMediaCard)).toList();
|
||||
@@ -108,7 +123,13 @@ void main() {
|
||||
var backCalls = 0;
|
||||
var sidebarCalls = 0;
|
||||
|
||||
await _pumpTab(tester, harness: harness, onBack: () => backCalls++, onSidebar: () => sidebarCalls++);
|
||||
await _pumpTab(
|
||||
tester,
|
||||
harness: harness,
|
||||
library: _library,
|
||||
onBack: () => backCalls++,
|
||||
onSidebar: () => sidebarCalls++,
|
||||
);
|
||||
|
||||
expect(find.byType(SliverList), findsOneWidget);
|
||||
final cards = tester.widgetList<FocusableMediaCard>(find.byType(FocusableMediaCard)).toList();
|
||||
@@ -128,6 +149,24 @@ void main() {
|
||||
expect(backCalls, 1);
|
||||
expect(sidebarCalls, 1);
|
||||
});
|
||||
|
||||
testWidgets('music library playlists use square grid geometry and square cards', (tester) async {
|
||||
final harness = _PlaylistHarness(playlistType: 'audio');
|
||||
addTearDown(harness.dispose);
|
||||
addTearDown(harness.rebuild.dispose);
|
||||
|
||||
await _pumpTab(tester, harness: harness, library: _musicLibrary, onBack: () {}, onSidebar: () {});
|
||||
|
||||
final layout = tester.widget<MediaCardSliverLayout>(find.byType(MediaCardSliverLayout));
|
||||
expect(layout.shape, CardShape.square);
|
||||
expect(layout.fullBleedImage, isFalse);
|
||||
expect(
|
||||
tester
|
||||
.widgetList<FocusableMediaCard>(find.byType(FocusableMediaCard))
|
||||
.every((card) => card.cardShapeOverride == CardShape.square),
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
FocusableMediaCard _cardFor(List<FocusableMediaCard> cards, int index) {
|
||||
@@ -137,6 +176,7 @@ FocusableMediaCard _cardFor(List<FocusableMediaCard> cards, int index) {
|
||||
Future<void> _pumpTab(
|
||||
WidgetTester tester, {
|
||||
required _PlaylistHarness harness,
|
||||
required MediaLibrary library,
|
||||
required VoidCallback onBack,
|
||||
required VoidCallback onSidebar,
|
||||
}) async {
|
||||
@@ -169,7 +209,7 @@ Future<void> _pumpTab(
|
||||
body: ValueListenableBuilder<int>(
|
||||
valueListenable: harness.rebuild,
|
||||
builder: (context, _, _) =>
|
||||
LibraryPlaylistsTab(library: _library, suppressAutoFocus: true, onBack: onBack),
|
||||
LibraryPlaylistsTab(library: library, suppressAutoFocus: true, onBack: onBack),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -184,6 +224,7 @@ Future<void> _pumpTab(
|
||||
class _PlaylistHarness {
|
||||
static const totalPlaylists = 400;
|
||||
|
||||
final String playlistType;
|
||||
final requestStarts = <int>[];
|
||||
final rebuild = ValueNotifier(0);
|
||||
late final PlexClient client;
|
||||
@@ -191,7 +232,7 @@ class _PlaylistHarness {
|
||||
late final MultiServerManager manager;
|
||||
late final MultiServerProvider provider;
|
||||
|
||||
_PlaylistHarness() {
|
||||
_PlaylistHarness({this.playlistType = 'video'}) {
|
||||
database = AppDatabase.forTesting(NativeDatabase.memory());
|
||||
PlexApiCache.initialize(database);
|
||||
client = PlexClient.forTesting(
|
||||
@@ -214,7 +255,7 @@ class _PlaylistHarness {
|
||||
return {
|
||||
'ratingKey': 'playlist-$index',
|
||||
'type': 'playlist',
|
||||
'playlistType': 'video',
|
||||
'playlistType': playlistType,
|
||||
'title': 'Playlist $index',
|
||||
'smart': false,
|
||||
};
|
||||
|
||||
@@ -30,7 +30,11 @@ import 'package:plezy/utils/media_navigation_helper.dart';
|
||||
import 'package:plezy/utils/media_server_http_client.dart';
|
||||
import 'package:plezy/utils/platform_detector.dart';
|
||||
import 'package:plezy/widgets/media_card.dart';
|
||||
import 'package:plezy/widgets/focusable_media_card.dart';
|
||||
import 'package:plezy/widgets/media_card_sliver_layout.dart';
|
||||
import 'package:plezy/widgets/optimized_media_image.dart';
|
||||
import 'package:plezy/widgets/overlay_sheet.dart';
|
||||
import 'package:plezy/utils/media_image_helper.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../test_helpers/media_items.dart';
|
||||
@@ -88,6 +92,59 @@ void main() {
|
||||
expect(find.text(t.common.retry), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('editable audio playlist rows render square track artwork', (tester) async {
|
||||
final harness = await _createHarness([
|
||||
testMediaItem(
|
||||
id: 'track_1',
|
||||
backend: MediaBackend.plex,
|
||||
kind: MediaKind.track,
|
||||
title: 'Track 1',
|
||||
serverId: 'server_1',
|
||||
serverName: 'Server',
|
||||
),
|
||||
]);
|
||||
|
||||
await tester.pumpWidget(
|
||||
harness.wrap(const SizedBox(width: 1280, height: 720, child: PlaylistDetailScreen(playlist: _audioPlaylist))),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final card = find.byType(PlaylistItemCard);
|
||||
final artwork = find.descendant(of: card, matching: find.byType(ClipRRect));
|
||||
expect(tester.getSize(artwork), const Size.square(60));
|
||||
expect(
|
||||
tester
|
||||
.widget<OptimizedMediaImage>(find.descendant(of: card, matching: find.byType(OptimizedMediaImage)))
|
||||
.imageType,
|
||||
ImageType.square,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('read-only audio playlists use square grid geometry and cards', (tester) async {
|
||||
final harness = await _createHarness([
|
||||
testMediaItem(
|
||||
id: 'track_1',
|
||||
backend: MediaBackend.plex,
|
||||
kind: MediaKind.track,
|
||||
title: 'Track 1',
|
||||
serverId: 'server_1',
|
||||
serverName: 'Server',
|
||||
),
|
||||
]);
|
||||
|
||||
await tester.pumpWidget(
|
||||
harness.wrap(
|
||||
const SizedBox(width: 1280, height: 720, child: PlaylistDetailScreen(playlist: _smartAudioPlaylist)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final layout = tester.widget<MediaCardSliverLayout>(find.byType(MediaCardSliverLayout));
|
||||
expect(layout.shape, CardShape.square);
|
||||
expect(layout.fullBleedImage, isFalse);
|
||||
expect(tester.widget<FocusableMediaCard>(find.byType(FocusableMediaCard)).cardShapeOverride, CardShape.square);
|
||||
});
|
||||
|
||||
testWidgets('keeps partial playlist pages and retries from the failed offset', (tester) async {
|
||||
final items = _mediaItems(playlistItemsPageSize * 2 + 5);
|
||||
final harness = await _createHarness(items, failOnceAt: playlistItemsPageSize);
|
||||
@@ -404,6 +461,25 @@ const _playlist = MediaPlaylist(
|
||||
serverName: 'Server',
|
||||
);
|
||||
|
||||
const _audioPlaylist = MediaPlaylist(
|
||||
id: 'audio_playlist_1',
|
||||
backend: MediaBackend.plex,
|
||||
title: 'Audio Playlist',
|
||||
playlistType: 'audio',
|
||||
serverId: 'server_1',
|
||||
serverName: 'Server',
|
||||
);
|
||||
|
||||
const _smartAudioPlaylist = MediaPlaylist(
|
||||
id: 'smart_audio_playlist_1',
|
||||
backend: MediaBackend.plex,
|
||||
title: 'Smart Audio Playlist',
|
||||
playlistType: 'audio',
|
||||
smart: true,
|
||||
serverId: 'server_1',
|
||||
serverName: 'Server',
|
||||
);
|
||||
|
||||
List<MediaItem> _mediaItems(int count) {
|
||||
return List.generate(
|
||||
count,
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter_test/flutter_test.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/media/media_playlist.dart';
|
||||
import 'package:plezy/services/settings_service.dart';
|
||||
import 'package:plezy/theme/mono_theme.dart';
|
||||
import 'package:plezy/utils/layout_constants.dart';
|
||||
@@ -139,6 +140,49 @@ void main() {
|
||||
expect(tester.getSize(imageBox), Size(base, base));
|
||||
});
|
||||
|
||||
testWidgets('music collection override renders square artwork and requests a square transcode', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
_TestApp(
|
||||
child: MediaCard(
|
||||
item: _item(MediaKind.collection),
|
||||
width: 200,
|
||||
height: 194,
|
||||
forceGridMode: true,
|
||||
isOffline: true,
|
||||
cardShapeOverride: CardShape.square,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final imageBox = find.descendant(of: find.byType(MediaCard), matching: find.byType(ClipRRect)).first;
|
||||
expect(tester.getSize(imageBox), const Size(194, 194));
|
||||
expect(tester.widget<OptimizedMediaImage>(find.byType(OptimizedMediaImage)).imageType, ImageType.square);
|
||||
});
|
||||
|
||||
testWidgets('music playlist override uses square artwork in list mode', (tester) async {
|
||||
const playlist = MediaPlaylist(
|
||||
id: 'playlist_1',
|
||||
backend: MediaBackend.plex,
|
||||
title: 'Music playlist',
|
||||
playlistType: 'audio',
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const _TestApp(
|
||||
child: SizedBox(
|
||||
width: 420,
|
||||
height: 160,
|
||||
child: MediaCard(item: playlist, forceListMode: true, isOffline: true, cardShapeOverride: CardShape.square),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final base = MediaCardListLayout.basePosterWidth(LibraryDensity.defaultValue);
|
||||
final imageBox = find.descendant(of: find.byType(MediaCard), matching: find.byType(ClipRRect)).first;
|
||||
expect(tester.getSize(imageBox), Size(base, base));
|
||||
expect(tester.widget<OptimizedMediaImage>(find.byType(OptimizedMediaImage)).imageType, ImageType.square);
|
||||
});
|
||||
|
||||
testWidgets('track artwork failure falls back to album artwork', (tester) async {
|
||||
const trackArtwork = 'https://media.example/track.jpg';
|
||||
const albumArtwork = 'https://media.example/album.jpg';
|
||||
|
||||
Reference in New Issue
Block a user