Files
minstrel/flutter_client/test/theme/theme_mode_provider_test.dart
T
bvandeusen 6dc488652e feat(flutter/theme): themeModeProvider with secure-storage persistence
AsyncNotifier wrapping flutter_secure_storage's "theme_mode" key.
Returns AppThemeMode.system as the default. set(mode) writes the
value + updates state.

Used by MinstrelApp (next commit) to drive MaterialApp.themeMode and
by the Settings appearance section to persist the operator's pick.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 15:47:00 -04:00

77 lines
2.7 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:minstrel/auth/auth_provider.dart';
import 'package:minstrel/theme/theme_mode_provider.dart';
class _MockStorage extends Mock implements FlutterSecureStorage {}
void main() {
late _MockStorage storage;
setUpAll(() {
registerFallbackValue('');
});
setUp(() {
storage = _MockStorage();
when(() => storage.write(key: any(named: 'key'), value: any(named: 'value')))
.thenAnswer((_) async {});
});
test('defaults to system when nothing stored', () async {
when(() => storage.read(key: 'theme_mode')).thenAnswer((_) async => null);
final container = ProviderContainer(overrides: [
secureStorageProvider.overrideWithValue(storage),
]);
addTearDown(container.dispose);
final mode = await container.read(themeModeProvider.future);
expect(mode, AppThemeMode.system);
});
test('reads stored "dark" → AppThemeMode.dark', () async {
when(() => storage.read(key: 'theme_mode')).thenAnswer((_) async => 'dark');
final container = ProviderContainer(overrides: [
secureStorageProvider.overrideWithValue(storage),
]);
addTearDown(container.dispose);
final mode = await container.read(themeModeProvider.future);
expect(mode, AppThemeMode.dark);
});
test('reads stored "light" → AppThemeMode.light', () async {
when(() => storage.read(key: 'theme_mode')).thenAnswer((_) async => 'light');
final container = ProviderContainer(overrides: [
secureStorageProvider.overrideWithValue(storage),
]);
addTearDown(container.dispose);
final mode = await container.read(themeModeProvider.future);
expect(mode, AppThemeMode.light);
});
test('set(.light) writes "light" to storage and updates state', () async {
when(() => storage.read(key: 'theme_mode')).thenAnswer((_) async => null);
final container = ProviderContainer(overrides: [
secureStorageProvider.overrideWithValue(storage),
]);
addTearDown(container.dispose);
await container.read(themeModeProvider.future);
await container.read(themeModeProvider.notifier).set(AppThemeMode.light);
verify(() => storage.write(key: 'theme_mode', value: 'light')).called(1);
expect(container.read(themeModeProvider).value, AppThemeMode.light);
});
test('materialMode extension maps each enum to ThemeMode', () {
expect(AppThemeMode.system.materialMode.name, 'system');
expect(AppThemeMode.dark.materialMode.name, 'dark');
expect(AppThemeMode.light.materialMode.name, 'light');
});
}