288 lines
7.7 KiB
Dart
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'));
|
|
});
|
|
});
|
|
}
|