mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-21 15:02:21 +02:00
The grab-bag file mixed model tests with tests that pin literal source text across Dart, Kotlin and Swift. The contracts now live in source_contracts_test.dart with a header explaining that they must be updated, never deleted, when code moves. The remaining groups moved verbatim into domain files.
201 lines
7.5 KiB
Dart
201 lines
7.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:spotiflac_android/models/settings.dart';
|
|
import 'package:spotiflac_android/models/theme_settings.dart';
|
|
import 'package:spotiflac_android/utils/artist_utils.dart';
|
|
|
|
void main() {
|
|
test(
|
|
'retired quality conversion settings do not enable automatic conversion',
|
|
() {
|
|
for (final format in ['mp3_320', 'aac_320', 'opus_256', 'opus_128']) {
|
|
final settings = AppSettings.fromJson({
|
|
'audioQuality': 'HIGH',
|
|
'tidalHighFormat': format,
|
|
});
|
|
expect(settings.audioQuality, 'HIGH');
|
|
expect(settings.autoConvertDownloads, isFalse);
|
|
expect(settings.toJson().containsKey('tidalHighFormat'), isFalse);
|
|
}
|
|
final settings = AppSettings.fromJson({
|
|
'tidalHighFormat': 'mp3_320',
|
|
'autoConvertDownloads': true,
|
|
'autoConvertFormat': 'opus',
|
|
'autoConvertBitrate': '192k',
|
|
});
|
|
expect(settings.autoConvertDownloads, isTrue);
|
|
expect(settings.autoConvertFormat, 'opus');
|
|
expect(settings.autoConvertBitrate, '192k');
|
|
},
|
|
);
|
|
|
|
group('AppSettings', () {
|
|
test('provides stable defaults', () {
|
|
const settings = AppSettings();
|
|
|
|
expect(settings.audioQuality, 'LOSSLESS');
|
|
expect(settings.filenameFormat, '{title} - {artist}');
|
|
expect(settings.artistTagMode, artistTagModeJoined);
|
|
expect(settings.embeddedCoverMaxDimension, 0);
|
|
expect(settings.autoFallback, isTrue);
|
|
expect(settings.lyricsProviders, [
|
|
'apple_music',
|
|
'lrcred',
|
|
'spotiflac_lyrics',
|
|
'lyricsplus',
|
|
'lrclib',
|
|
]);
|
|
expect(settings.playerMode, 'internal');
|
|
expect(settings.lyricsMultiPersonWordByWord, isTrue);
|
|
expect(settings.lyricsAppleElrcWordSync, isTrue);
|
|
expect(settings.deduplicateDownloads, isTrue);
|
|
expect(settings.allowQualityVariants, isFalse);
|
|
expect(settings.nativeDownloadWorkerEnabled, isFalse);
|
|
expect(settings.autoConvertDownloads, isFalse);
|
|
expect(settings.autoConvertFormat, 'mp3');
|
|
expect(settings.autoConvertBitrate, '320k');
|
|
expect(
|
|
settings.libraryQualityLabelMode,
|
|
AppSettings.libraryQualityLabelBitDepthOnly,
|
|
);
|
|
});
|
|
|
|
test('copyWith updates values and can clear nullable provider fields', () {
|
|
const settings = AppSettings(
|
|
downloadFallbackExtensionIds: ['fallback.ext'],
|
|
searchProvider: 'search.ext',
|
|
homeFeedProvider: 'feed.ext',
|
|
);
|
|
|
|
final updated = settings.copyWith(
|
|
defaultService: 'provider-a',
|
|
embedReplayGain: true,
|
|
embeddedCoverMaxDimension: 1000,
|
|
lyricsProviders: ['apple_music'],
|
|
lyricsAppleElrcWordSync: true,
|
|
deduplicateDownloads: false,
|
|
allowQualityVariants: true,
|
|
libraryQualityLabelMode: AppSettings.libraryQualityLabelBitDepthOnly,
|
|
clearDownloadFallbackExtensionIds: true,
|
|
clearSearchProvider: true,
|
|
clearHomeFeedProvider: true,
|
|
);
|
|
|
|
expect(updated.defaultService, 'provider-a');
|
|
expect(updated.embedReplayGain, isTrue);
|
|
expect(updated.embeddedCoverMaxDimension, 1000);
|
|
expect(updated.lyricsProviders, ['apple_music']);
|
|
expect(updated.lyricsAppleElrcWordSync, isTrue);
|
|
expect(updated.deduplicateDownloads, isFalse);
|
|
expect(updated.allowQualityVariants, isTrue);
|
|
expect(
|
|
updated.libraryQualityLabelMode,
|
|
AppSettings.libraryQualityLabelBitDepthOnly,
|
|
);
|
|
expect(updated.downloadFallbackExtensionIds, isNull);
|
|
expect(updated.searchProvider, isNull);
|
|
expect(updated.homeFeedProvider, isNull);
|
|
expect(updated.audioQuality, settings.audioQuality);
|
|
});
|
|
|
|
test('round-trips json including recently added settings', () {
|
|
const settings = AppSettings(
|
|
defaultService: 'provider-b',
|
|
storageMode: 'saf',
|
|
downloadTreeUri: 'content://tree/music',
|
|
downloadFallbackExtensionIds: ['ext.a', 'ext.b'],
|
|
searchProvider: 'search.ext',
|
|
homeFeedProvider: AppSettings.homeFeedProviderOff,
|
|
useAllFilesAccess: true,
|
|
networkCompatibilityMode: true,
|
|
songLinkRegion: 'ID',
|
|
localLibraryEnabled: true,
|
|
localLibraryPath: '/music',
|
|
hasCompletedTutorial: true,
|
|
musixmatchLanguage: 'id',
|
|
lyricsAppleElrcWordSync: true,
|
|
lastSeenVersion: '4.5.0',
|
|
deduplicateDownloads: false,
|
|
allowQualityVariants: true,
|
|
nativeDownloadWorkerEnabled: true,
|
|
autoConvertDownloads: true,
|
|
autoConvertFormat: 'opus',
|
|
autoConvertBitrate: '192k',
|
|
libraryQualityLabelMode: AppSettings.libraryQualityLabelBitDepthOnly,
|
|
embeddedCoverMaxDimension: 1500,
|
|
);
|
|
|
|
final decoded = AppSettings.fromJson(settings.toJson());
|
|
|
|
expect(decoded.defaultService, 'provider-b');
|
|
expect(decoded.storageMode, 'saf');
|
|
expect(decoded.downloadTreeUri, 'content://tree/music');
|
|
expect(decoded.downloadFallbackExtensionIds, ['ext.a', 'ext.b']);
|
|
expect(decoded.searchProvider, 'search.ext');
|
|
expect(decoded.homeFeedProvider, AppSettings.homeFeedProviderOff);
|
|
expect(decoded.useAllFilesAccess, isTrue);
|
|
expect(decoded.networkCompatibilityMode, isTrue);
|
|
expect(decoded.songLinkRegion, 'ID');
|
|
expect(decoded.localLibraryEnabled, isTrue);
|
|
expect(decoded.localLibraryPath, '/music');
|
|
expect(decoded.hasCompletedTutorial, isTrue);
|
|
expect(decoded.musixmatchLanguage, 'id');
|
|
expect(decoded.lyricsAppleElrcWordSync, isTrue);
|
|
expect(decoded.lastSeenVersion, '4.5.0');
|
|
expect(
|
|
decoded.libraryQualityLabelMode,
|
|
AppSettings.libraryQualityLabelBitDepthOnly,
|
|
);
|
|
expect(decoded.deduplicateDownloads, isFalse);
|
|
expect(decoded.allowQualityVariants, isTrue);
|
|
expect(decoded.nativeDownloadWorkerEnabled, isTrue);
|
|
expect(decoded.autoConvertDownloads, isTrue);
|
|
expect(decoded.autoConvertFormat, 'opus');
|
|
expect(decoded.autoConvertBitrate, '192k');
|
|
expect(decoded.embeddedCoverMaxDimension, 1500);
|
|
});
|
|
});
|
|
|
|
group('ThemeSettings', () {
|
|
test('serializes, deserializes, copies, and compares values', () {
|
|
const settings = ThemeSettings(
|
|
themeMode: ThemeMode.dark,
|
|
useDynamicColor: false,
|
|
seedColorValue: 0xff123456,
|
|
useAmoled: true,
|
|
style: AppThemeStyle.mornye,
|
|
mornyeAccent: MornyeAccent.blue,
|
|
useSystemFont: true,
|
|
);
|
|
|
|
final decoded = ThemeSettings.fromJson(settings.toJson());
|
|
final copied = decoded.copyWith(themeMode: ThemeMode.light);
|
|
|
|
expect(decoded, settings);
|
|
expect(decoded.hashCode, settings.hashCode);
|
|
expect(decoded.seedColor, const Color(0xff123456));
|
|
expect(copied.themeMode, ThemeMode.light);
|
|
expect(copied.useAmoled, isTrue);
|
|
expect(decoded.style, AppThemeStyle.mornye);
|
|
expect(decoded.mornyeAccent, MornyeAccent.blue);
|
|
expect(copied.mornyeAccent, MornyeAccent.blue);
|
|
expect(decoded.useSystemFont, isTrue);
|
|
expect(copied.useSystemFont, isTrue);
|
|
expect(ThemeSettings.fromJson({}).useSystemFont, isFalse);
|
|
expect(ThemeSettings.fromJson({}).mornyeAccent, MornyeAccent.red);
|
|
expect(
|
|
ThemeSettings.fromJson({kMornyeAccentKey: 'unknown'}).mornyeAccent,
|
|
MornyeAccent.red,
|
|
);
|
|
expect(
|
|
ThemeSettings.fromJson({'theme_mode': 'invalid'}).themeMode,
|
|
ThemeMode.system,
|
|
);
|
|
expect(
|
|
ThemeSettings.fromJson({'theme_style': 'invalid'}).style,
|
|
AppThemeStyle.material,
|
|
);
|
|
});
|
|
});
|
|
}
|