mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-26 03:20:45 +02:00
test: decouple app fixtures from extension identities
This commit is contained in:
@@ -15,7 +15,7 @@ DownloadHistoryItem _historyItem({
|
||||
filePath: filePath,
|
||||
service: 'test',
|
||||
downloadedAt: downloadedAt,
|
||||
spotifyId: 'spotify:track:same',
|
||||
spotifyId: 'source-track-same',
|
||||
isrc: 'SAMEISRC',
|
||||
);
|
||||
}
|
||||
@@ -84,7 +84,7 @@ void main() {
|
||||
totalCount: 2,
|
||||
);
|
||||
|
||||
expect(state.getBySpotifyId('spotify:track:same')?.id, 'newest');
|
||||
expect(state.getBySpotifyId('source-track-same')?.id, 'newest');
|
||||
expect(state.getByIsrc('SAMEISRC')?.id, 'newest');
|
||||
expect(
|
||||
state.findByTrackAndArtist('Same Song', 'Same Artist')?.id,
|
||||
|
||||
@@ -8,43 +8,43 @@ void main() {
|
||||
test('failed challenge attempts do not consume the granted retry', () {
|
||||
final guard = DownloadVerificationRetryGuard();
|
||||
|
||||
guard.recordVerificationResult('item-1', 'tidal-web', granted: false);
|
||||
guard.recordVerificationResult('item-1', 'provider-a', granted: false);
|
||||
|
||||
expect(guard.hasRetriedAfterGrant('item-1', 'tidal-web'), isFalse);
|
||||
expect(guard.hasRetriedAfterGrant('item-1', 'provider-a'), isFalse);
|
||||
});
|
||||
|
||||
test('completed grants allow only one automatic retry per service', () {
|
||||
final guard = DownloadVerificationRetryGuard();
|
||||
|
||||
guard.recordVerificationResult('item-1', ' TIDAL-WEB ', granted: true);
|
||||
guard.recordVerificationResult('item-1', ' PROVIDER-A ', granted: true);
|
||||
|
||||
expect(guard.hasRetriedAfterGrant('item-1', 'tidal-web'), isTrue);
|
||||
expect(guard.hasRetriedAfterGrant('item-1', 'qobuz-web'), isFalse);
|
||||
expect(guard.hasRetriedAfterGrant('item-2', 'tidal-web'), isFalse);
|
||||
expect(guard.hasRetriedAfterGrant('item-1', 'provider-a'), isTrue);
|
||||
expect(guard.hasRetriedAfterGrant('item-1', 'provider-b'), isFalse);
|
||||
expect(guard.hasRetriedAfterGrant('item-2', 'provider-a'), isFalse);
|
||||
});
|
||||
|
||||
test('manual retry clears every service marker for an item', () {
|
||||
final guard = DownloadVerificationRetryGuard()
|
||||
..recordVerificationResult('item-1', 'tidal-web', granted: true)
|
||||
..recordVerificationResult('item-1', 'qobuz-web', granted: true)
|
||||
..recordVerificationResult('item-2', 'tidal-web', granted: true);
|
||||
..recordVerificationResult('item-1', 'provider-a', granted: true)
|
||||
..recordVerificationResult('item-1', 'provider-b', granted: true)
|
||||
..recordVerificationResult('item-2', 'provider-a', granted: true);
|
||||
|
||||
guard.clearItem('item-1');
|
||||
|
||||
expect(guard.hasRetriedAfterGrant('item-1', 'tidal-web'), isFalse);
|
||||
expect(guard.hasRetriedAfterGrant('item-1', 'qobuz-web'), isFalse);
|
||||
expect(guard.hasRetriedAfterGrant('item-2', 'tidal-web'), isTrue);
|
||||
expect(guard.hasRetriedAfterGrant('item-1', 'provider-a'), isFalse);
|
||||
expect(guard.hasRetriedAfterGrant('item-1', 'provider-b'), isFalse);
|
||||
expect(guard.hasRetriedAfterGrant('item-2', 'provider-a'), isTrue);
|
||||
});
|
||||
|
||||
test('queue cleanup retains markers only for remaining items', () {
|
||||
final guard = DownloadVerificationRetryGuard()
|
||||
..recordVerificationResult('removed', 'tidal-web', granted: true)
|
||||
..recordVerificationResult('remaining', 'tidal-web', granted: true);
|
||||
..recordVerificationResult('removed', 'provider-a', granted: true)
|
||||
..recordVerificationResult('remaining', 'provider-a', granted: true);
|
||||
|
||||
guard.retainItems({'remaining'});
|
||||
|
||||
expect(guard.hasRetriedAfterGrant('removed', 'tidal-web'), isFalse);
|
||||
expect(guard.hasRetriedAfterGrant('remaining', 'tidal-web'), isTrue);
|
||||
expect(guard.hasRetriedAfterGrant('removed', 'provider-a'), isFalse);
|
||||
expect(guard.hasRetriedAfterGrant('remaining', 'provider-a'), isTrue);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -58,7 +58,7 @@ void main() {
|
||||
|
||||
final result = coordinator.waitForGrant(
|
||||
itemId: 'item-1',
|
||||
service: 'tidal-web',
|
||||
service: 'provider-a',
|
||||
startFlow: (cancellationSignal) async {
|
||||
flowStarted.complete();
|
||||
await cancellationSignal;
|
||||
@@ -81,7 +81,7 @@ void main() {
|
||||
|
||||
final first = coordinator.waitForGrant(
|
||||
itemId: 'item-1',
|
||||
service: 'tidal-web',
|
||||
service: 'provider-a',
|
||||
startFlow: (cancellationSignal) async {
|
||||
starts++;
|
||||
await cancellationSignal;
|
||||
@@ -93,7 +93,7 @@ void main() {
|
||||
|
||||
final second = coordinator.waitForGrant(
|
||||
itemId: 'item-2',
|
||||
service: 'tidal-web',
|
||||
service: 'provider-a',
|
||||
startFlow: (_) async {
|
||||
starts++;
|
||||
return true;
|
||||
@@ -122,12 +122,12 @@ void main() {
|
||||
|
||||
final first = coordinator.waitForGrant(
|
||||
itemId: 'item-1',
|
||||
service: ' TIDAL-WEB ',
|
||||
service: ' PROVIDER-A ',
|
||||
startFlow: startFlow,
|
||||
);
|
||||
final second = coordinator.waitForGrant(
|
||||
itemId: 'item-2',
|
||||
service: 'tidal-web',
|
||||
service: 'provider-a',
|
||||
startFlow: startFlow,
|
||||
);
|
||||
|
||||
|
||||
@@ -680,7 +680,7 @@ void main() {
|
||||
|
||||
test('round-trips json with service availability', () {
|
||||
final track = Track.fromJson({
|
||||
'id': 'spotify:track:1',
|
||||
'id': 'source-track-1',
|
||||
'name': 'Song',
|
||||
'artistName': 'Artist',
|
||||
'albumName': 'Album',
|
||||
@@ -691,7 +691,7 @@ void main() {
|
||||
expect(track.availability?.tidal, isTrue);
|
||||
expect(track.availability?.qobuz, isFalse);
|
||||
expect(track.availability?.deezerId, '31337');
|
||||
expect(track.toJson()['id'], 'spotify:track:1');
|
||||
expect(track.toJson()['id'], 'source-track-1');
|
||||
expect(track.availability!.toJson()['deezer'], isTrue);
|
||||
});
|
||||
});
|
||||
@@ -710,7 +710,7 @@ void main() {
|
||||
final item = DownloadItem(
|
||||
id: 'download-1',
|
||||
track: sampleTrack(),
|
||||
service: 'tidal',
|
||||
service: 'provider-a',
|
||||
createdAt: createdAt,
|
||||
);
|
||||
|
||||
@@ -745,7 +745,7 @@ void main() {
|
||||
final base = DownloadItem(
|
||||
id: 'download-1',
|
||||
track: sampleTrack(),
|
||||
service: 'qobuz',
|
||||
service: 'provider-b',
|
||||
createdAt: DateTime.utc(2026),
|
||||
filePath: '/music/stale.flac',
|
||||
error: 'raw backend failure',
|
||||
@@ -790,7 +790,7 @@ void main() {
|
||||
'albumName': 'Album',
|
||||
'duration': 1000,
|
||||
},
|
||||
'service': 'deezer',
|
||||
'service': 'provider-a',
|
||||
'status': 'failed',
|
||||
'errorType': 'network',
|
||||
'createdAt': '2026-05-04T10:00:00.000Z',
|
||||
@@ -811,7 +811,7 @@ void main() {
|
||||
final item = DownloadItem(
|
||||
id: 'download-active',
|
||||
track: sampleTrack(),
|
||||
service: 'tidal',
|
||||
service: 'provider-a',
|
||||
createdAt: DateTime.utc(2026),
|
||||
status: DownloadStatus.finalizing,
|
||||
progress: 0.97,
|
||||
@@ -937,7 +937,7 @@ void main() {
|
||||
);
|
||||
|
||||
final updated = settings.copyWith(
|
||||
defaultService: 'tidal',
|
||||
defaultService: 'provider-a',
|
||||
embedReplayGain: true,
|
||||
embeddedCoverMaxDimension: 1000,
|
||||
lyricsProviders: ['apple_music'],
|
||||
@@ -950,7 +950,7 @@ void main() {
|
||||
clearHomeFeedProvider: true,
|
||||
);
|
||||
|
||||
expect(updated.defaultService, 'tidal');
|
||||
expect(updated.defaultService, 'provider-a');
|
||||
expect(updated.embedReplayGain, isTrue);
|
||||
expect(updated.embeddedCoverMaxDimension, 1000);
|
||||
expect(updated.lyricsProviders, ['apple_music']);
|
||||
@@ -969,7 +969,7 @@ void main() {
|
||||
|
||||
test('round-trips json including recently added settings', () {
|
||||
const settings = AppSettings(
|
||||
defaultService: 'qobuz',
|
||||
defaultService: 'provider-b',
|
||||
storageMode: 'saf',
|
||||
downloadTreeUri: 'content://tree/music',
|
||||
downloadFallbackExtensionIds: ['ext.a', 'ext.b'],
|
||||
@@ -996,7 +996,7 @@ void main() {
|
||||
|
||||
final decoded = AppSettings.fromJson(settings.toJson());
|
||||
|
||||
expect(decoded.defaultService, 'qobuz');
|
||||
expect(decoded.defaultService, 'provider-b');
|
||||
expect(decoded.storageMode, 'saf');
|
||||
expect(decoded.downloadTreeUri, 'content://tree/music');
|
||||
expect(decoded.downloadFallbackExtensionIds, ['ext.a', 'ext.b']);
|
||||
@@ -1053,10 +1053,10 @@ void main() {
|
||||
test('serializes all backend field names', () {
|
||||
const payload = DownloadRequestPayload(
|
||||
isrc: 'ISRC123',
|
||||
service: 'tidal',
|
||||
downloadProvider: 'tidal-web',
|
||||
service: 'source-provider',
|
||||
downloadProvider: 'download-provider',
|
||||
providerTrackId: '123456789',
|
||||
spotifyId: 'spotify:track:1',
|
||||
spotifyId: 'source-track-1',
|
||||
trackName: 'Song',
|
||||
artistName: 'Artist',
|
||||
albumName: 'Album',
|
||||
@@ -1092,9 +1092,9 @@ void main() {
|
||||
explicit: true,
|
||||
albumType: 'compilation',
|
||||
upc: '0012345678901',
|
||||
tidalId: 'tidal-1',
|
||||
qobuzId: 'qobuz-1',
|
||||
deezerId: 'deezer-1',
|
||||
tidalId: 'alternate-id-a',
|
||||
qobuzId: 'alternate-id-b',
|
||||
deezerId: 'alternate-id-c',
|
||||
lyricsMode: 'sidecar',
|
||||
useExtensions: true,
|
||||
useFallback: true,
|
||||
@@ -1114,10 +1114,10 @@ void main() {
|
||||
expect(payload.toJson(), {
|
||||
'contract_version': DownloadRequestPayload.nativeWorkerContractVersion,
|
||||
'isrc': 'ISRC123',
|
||||
'service': 'tidal',
|
||||
'download_provider': 'tidal-web',
|
||||
'service': 'source-provider',
|
||||
'download_provider': 'download-provider',
|
||||
'provider_track_id': '123456789',
|
||||
'spotify_id': 'spotify:track:1',
|
||||
'spotify_id': 'source-track-1',
|
||||
'track_name': 'Song',
|
||||
'artist_name': 'Artist',
|
||||
'album_name': 'Album',
|
||||
@@ -1153,9 +1153,9 @@ void main() {
|
||||
'explicit': true,
|
||||
'album_type': 'compilation',
|
||||
'upc': '0012345678901',
|
||||
'tidal_id': 'tidal-1',
|
||||
'qobuz_id': 'qobuz-1',
|
||||
'deezer_id': 'deezer-1',
|
||||
'tidal_id': 'alternate-id-a',
|
||||
'qobuz_id': 'alternate-id-b',
|
||||
'deezer_id': 'alternate-id-c',
|
||||
'lyrics_mode': 'sidecar',
|
||||
'use_extensions': true,
|
||||
'use_fallback': true,
|
||||
@@ -1283,7 +1283,7 @@ void main() {
|
||||
'albumType': 'album',
|
||||
'explicit': true,
|
||||
'upc': '4006381333931',
|
||||
'comment': 'https://listen.tidal.com/album/1',
|
||||
'comment': 'https://media.example/album/1',
|
||||
'format': 'flac',
|
||||
});
|
||||
|
||||
@@ -1302,7 +1302,7 @@ void main() {
|
||||
expect(normalized['album_type'], 'album');
|
||||
expect(normalized['explicit'], isTrue);
|
||||
expect(normalized['upc'], '4006381333931');
|
||||
expect(normalized['comment'], 'https://listen.tidal.com/album/1');
|
||||
expect(normalized['comment'], 'https://media.example/album/1');
|
||||
expect(normalized['audio_codec'], 'flac');
|
||||
});
|
||||
|
||||
|
||||
@@ -31,11 +31,11 @@ void main() {
|
||||
addTearDown(subscription.cancel);
|
||||
|
||||
final first = PlatformBridge.completeExtensionSessionGrant(
|
||||
' qobuz-web ',
|
||||
' provider-a ',
|
||||
'grant-value',
|
||||
);
|
||||
final second = PlatformBridge.completeExtensionSessionGrant(
|
||||
'QOBUZ-WEB',
|
||||
'PROVIDER-A',
|
||||
'grant-value',
|
||||
);
|
||||
|
||||
@@ -48,7 +48,7 @@ void main() {
|
||||
|
||||
expect(callCount, 1);
|
||||
expect(events, hasLength(1));
|
||||
expect(events.single.extensionId, 'qobuz-web');
|
||||
expect(events.single.extensionId, 'provider-a');
|
||||
expect(events.single.success, isTrue);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -45,10 +45,10 @@ void main() {
|
||||
test('prefers a known provider id over guessing from the resource id', () {
|
||||
expect(
|
||||
resolvePreferredMetadataProviderId(
|
||||
'apple-music-ext',
|
||||
'sample-provider',
|
||||
'37i9dQZF1DXcBWIGoYBM5M',
|
||||
),
|
||||
'apple-music-ext',
|
||||
'sample-provider',
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ void main() {
|
||||
artistName: 'Artist',
|
||||
albumName: 'Album',
|
||||
filePath: r'Z:\missing\track.flac',
|
||||
service: 'tidal-web',
|
||||
service: 'provider-a',
|
||||
downloadedAt: DateTime(2026),
|
||||
duration: 250,
|
||||
bitDepth: 16,
|
||||
@@ -45,7 +45,7 @@ void main() {
|
||||
expect(headerMeta, findsOneWidget);
|
||||
expect(find.byType(ExplicitBadge), findsNWidgets(2));
|
||||
expect(find.text('Explicit'), findsNothing);
|
||||
for (final label in const ['16-bit/44.1kHz', '4:10', 'Tidal-web']) {
|
||||
for (final label in const ['16-bit/44.1kHz', '4:10', 'Provider-a']) {
|
||||
final text = tester.widget<Text>(
|
||||
find.descendant(of: headerMeta, matching: find.text(label)),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user