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? imageTags, List? backdropImageTags, Map 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')); }); }); }