import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:spotiflac_android/l10n/l10n.dart'; import 'package:spotiflac_android/models/theme_settings.dart'; import 'package:spotiflac_android/providers/theme_provider.dart'; import 'package:spotiflac_android/screens/settings/appearance_settings_page.dart'; import 'package:spotiflac_android/theme/dynamic_color_wrapper.dart'; import 'package:spotiflac_android/theme/mornye_theme.dart'; void main() { Future openSettings( WidgetTester tester, SharedPreferences prefs, ) async { tester.view.physicalSize = const Size(390, 1000); tester.view.devicePixelRatio = 1; addTearDown(tester.view.reset); await tester.pumpWidget( ProviderScope( overrides: [ initialThemeSettingsProvider.overrideWithValue( loadBootstrapThemeSettings(prefs), ), ], child: DynamicColorWrapper( builder: (light, dark, mode) => MaterialApp( theme: light, darkTheme: dark, themeMode: mode, localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, home: const MornyeSettingsTheme(child: AppearanceSettingsPage()), ), ), ), ); await tester.pumpAndSettle(); } for (final mode in [ThemeMode.light, ThemeMode.dark]) { testWidgets('Mornye accent updates live and survives restart ($mode)', ( tester, ) async { SharedPreferences.setMockInitialValues({ kThemeStyleKey: 'mornye', kThemeModeKey: mode.name, kSeedColorKey: 0xff123456, }); final prefs = await SharedPreferences.getInstance(); await openSettings(tester, prefs); final page = find.byType(AppearanceSettingsPage); final initial = Theme.of(tester.element(page)); expect( initial.colorScheme.primary, MornyeTheme.accentColor(MornyeAccent.red, initial.brightness), ); final blue = find.byTooltip('Blue'); await tester.ensureVisible(blue); await tester.tap(blue); await tester.pumpAndSettle(); final theme = Theme.of(tester.element(page)); expect( theme.colorScheme.primary, MornyeTheme.accentColor(MornyeAccent.blue, theme.brightness), ); expect(prefs.getString(kMornyeAccentKey), 'blue'); expect(prefs.getInt(kSeedColorKey), 0xff123456); final overlay = MornyeTheme.fromContext( tester.element(page), brightness: Brightness.dark, ); expect(overlay.extension()!.accent, MornyeAccent.blue); expect( overlay.colorScheme.primary, MornyeTheme.accentColor(MornyeAccent.blue, Brightness.dark), ); await tester.pumpWidget(const SizedBox()); await openSettings(tester, prefs); expect( Theme.of(tester.element(page)).colorScheme.primary, theme.colorScheme.primary, ); await tester.ensureVisible(find.byTooltip('Red (default)')); await tester.tap(find.byTooltip('Red (default)')); await tester.pumpAndSettle(); expect( Theme.of(tester.element(page)).colorScheme.primary, initial.colorScheme.primary, ); expect(tester.takeException(), isNull); }); } for (final style in AppThemeStyle.values) { testWidgets( 'system font persists and restores the default ($style)', (tester) async { SharedPreferences.setMockInitialValues({ kThemeStyleKey: style.name, kMornyeAccentKey: 'blue', kUseDynamicColorKey: false, }); final prefs = await SharedPreferences.getInstance(); await openSettings(tester, prefs); final page = find.byType(AppearanceSettingsPage); final original = Theme.of( tester.element(page), ).textTheme.bodyLarge!.fontFamily; final setting = find.text('Use system font'); await tester.ensureVisible(setting); await tester.pumpAndSettle(); await tester.tap(setting); await tester.pumpAndSettle(); final theme = Theme.of(tester.element(page)); final systemFamily = theme.textTheme.bodyLarge!.fontFamily; expect(systemFamily, isNot('Inter')); expect(systemFamily, isNot('Google Sans Flex')); expect(prefs.getBool(kUseSystemFontKey), isTrue); if (style == AppThemeStyle.mornye) { final overlay = MornyeTheme.fromContext( tester.element(page), brightness: Brightness.dark, ); expect(overlay.extension()!.useSystemFont, isTrue); expect(overlay.extension()!.accent, MornyeAccent.blue); expect(overlay.textTheme.bodyLarge!.fontFamily, systemFamily); } await tester.pumpWidget(const SizedBox()); await openSettings(tester, prefs); expect( Theme.of(tester.element(page)).textTheme.bodyLarge!.fontFamily, systemFamily, ); await tester.ensureVisible(setting); await tester.pumpAndSettle(); await tester.tap(setting); await tester.pumpAndSettle(); expect(prefs.getBool(kUseSystemFontKey), isFalse); expect( Theme.of(tester.element(page)).textTheme.bodyLarge!.fontFamily, original, ); expect(tester.takeException(), isNull); }, variant: const TargetPlatformVariant({ TargetPlatform.android, TargetPlatform.iOS, }), ); } }