Files
sm-emby-share/test/shared/mappers/media_image_url_landscape_card_test.dart
2026-07-14 11:11:36 +08:00

288 lines
7.7 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:smplayer/core/contracts/library.dart';
import 'package:smplayer/shared/mappers/media_image_url.dart';
const _baseUrl = 'https://emby.example.com';
const _token = 'test-token';
EmbyRawItem _makeItem({
String id = 'item-1',
String? type,
String? primaryImageTag,
Map<String, String>? imageTags,
List<String>? backdropImageTags,
Map<String, dynamic> extra = const {},
}) {
return EmbyRawItem(
Id: id,
Name: 'Test',
Type: type,
PrimaryImageTag: primaryImageTag,
ImageTags: imageTags,
BackdropImageTags: backdropImageTags,
extra: extra,
);
}
void main() {
group('EmbyImageUrl.landscapeCard fallback chain', () {
test('returns Primary when PrimaryImageTag is present', () {
final item = _makeItem(primaryImageTag: 'primary-tag-1');
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, isNotNull);
expect(url, contains('/Images/Primary'));
expect(url, contains('tag=primary-tag-1'));
});
test('returns Primary from ImageTags map when PrimaryImageTag is null', () {
final item = _makeItem(imageTags: {'Primary': 'map-primary-tag'});
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, isNotNull);
expect(url, contains('/Images/Primary'));
expect(url, contains('tag=map-primary-tag'));
});
test('falls back to Thumb when Primary is missing', () {
final item = _makeItem(imageTags: {'Thumb': 'thumb-tag-1'});
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, isNotNull);
expect(url, contains('/Images/Thumb'));
expect(url, contains('tag=thumb-tag-1'));
});
test('falls back to Backdrop when Primary and Thumb are missing', () {
final item = _makeItem(backdropImageTags: ['backdrop-tag-1']);
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, isNotNull);
expect(url, contains('/Images/Backdrop'));
expect(url, contains('tag=backdrop-tag-1'));
});
test('falls back to parent Thumb from extra JSON', () {
final item = _makeItem(
extra: {
'ParentThumbItemId': 'parent-1',
'ParentThumbImageTag': 'parent-thumb-tag',
},
);
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, isNotNull);
expect(url, contains('/Items/parent-1/Images/Thumb'));
expect(url, contains('tag=parent-thumb-tag'));
});
test('falls back to parent Backdrop from extra JSON', () {
final item = _makeItem(
extra: {
'ParentBackdropItemId': 'parent-2',
'ParentBackdropImageTags': ['parent-backdrop-tag'],
},
);
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, isNotNull);
expect(url, contains('/Items/parent-2/Images/Backdrop'));
expect(url, contains('tag=parent-backdrop-tag'));
});
test('falls back to series Primary from extra JSON as last resort', () {
final item = _makeItem(
extra: {
'SeriesId': 'series-1',
'SeriesPrimaryImageTag': 'series-primary-tag',
},
);
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, isNotNull);
expect(url, contains('/Items/series-1/Images/Primary'));
expect(url, contains('tag=series-primary-tag'));
});
test('returns null when all image sources are absent', () {
final item = _makeItem();
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, isNull);
});
test('respects priority: Primary beats Thumb beats Backdrop', () {
final item = _makeItem(
primaryImageTag: 'primary-tag',
imageTags: {'Primary': 'primary-tag', 'Thumb': 'thumb-tag'},
backdropImageTags: ['backdrop-tag'],
);
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, contains('/Images/Primary'));
expect(url, contains('tag=primary-tag'));
});
test('parent Thumb takes priority over parent Backdrop', () {
final item = _makeItem(
extra: {
'ParentThumbItemId': 'parent-1',
'ParentThumbImageTag': 'parent-thumb-tag',
'ParentBackdropItemId': 'parent-2',
'ParentBackdropImageTags': ['parent-backdrop-tag'],
'SeriesId': 'series-1',
'SeriesPrimaryImageTag': 'series-primary-tag',
},
);
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, contains('/Items/parent-1/Images/Thumb'));
});
test('forwards maxWidth and quality parameters', () {
final item = _makeItem(primaryImageTag: 'tag');
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
maxWidth: 500,
quality: 80,
);
expect(url, contains('maxWidth=500'));
expect(url, contains('quality=80'));
});
});
group('EmbyImageUrl.landscapeCard movie-specific ordering', () {
test('movie prefers Backdrop over Primary', () {
final item = _makeItem(
type: 'Movie',
primaryImageTag: 'poster-tag',
backdropImageTags: ['backdrop-tag'],
);
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, contains('/Images/Backdrop'));
expect(url, contains('tag=backdrop-tag'));
});
test('movie falls back to Thumb when Backdrop is missing', () {
final item = _makeItem(
type: 'Movie',
primaryImageTag: 'poster-tag',
imageTags: {'Primary': 'poster-tag', 'Thumb': 'thumb-tag'},
);
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, contains('/Images/Thumb'));
expect(url, contains('tag=thumb-tag'));
});
test('movie falls back to Primary (poster) as last resort', () {
final item = _makeItem(type: 'Movie', primaryImageTag: 'poster-tag');
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, contains('/Images/Primary'));
expect(url, contains('tag=poster-tag'));
});
test('movie returns tagless Primary URL when all tag sources absent', () {
final item = _makeItem(type: 'Movie');
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, isNotNull);
expect(url, contains('/Items/item-1/Images/Primary'));
expect(url, isNot(contains('tag=')));
});
test('episode still prefers Primary over Backdrop', () {
final item = _makeItem(
type: 'Episode',
primaryImageTag: 'screenshot-tag',
backdropImageTags: ['backdrop-tag'],
);
final url = EmbyImageUrl.landscapeCard(
baseUrl: _baseUrl,
token: _token,
item: item,
);
expect(url, contains('/Images/Primary'));
expect(url, contains('tag=screenshot-tag'));
});
});
}