mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-22 00:12:09 +03:00
theme preferences tests
This commit is contained in:
parent
8a7ba46a48
commit
a43bacc073
@ -4,3 +4,4 @@ const prefNfcOpenApp = 'prefNfcOpenApp';
|
||||
const prefNfcBypassTouch = 'prefNfcBypassTouch';
|
||||
const prefNfcCopyOtp = 'prefNfcCopyOtp';
|
||||
const prefClipKbdLayout = 'prefClipKbdLayout';
|
||||
const prefTheme = 'APP_STATE_THEME';
|
||||
|
@ -7,6 +7,7 @@ const betaDialogView = Key('$_prefix.beta_dialog');
|
||||
const nfcTapSetting = Key('$_prefix.nfc_tap');
|
||||
const nfcKeyboardLayoutSetting = Key('$_prefix.nfc_keyboard_layout');
|
||||
const nfcBypassTouchSetting = Key('$_prefix.nfc_bypass_touch');
|
||||
const themeModeSetting = Key('$_prefix.theme_mode');
|
||||
|
||||
const okButton = Key('$_prefix.ok');
|
||||
const manualEntryButton = Key('$_prefix.manual_entry');
|
||||
@ -15,4 +16,9 @@ const launchTapAction = Key('$_prefix.tap_action_launch');
|
||||
const copyTapAction = Key('$_prefix.tap_action_copy');
|
||||
const bothTapAction = Key('$_prefix.tap_action_both');
|
||||
|
||||
const themeModeSystem = Key('$_prefix.theme_mode_system');
|
||||
const themeModeLight = Key('$_prefix.theme_mode_light');
|
||||
const themeModeDark = Key('$_prefix.theme_mode_dark');
|
||||
|
||||
|
||||
Key keyboardLayoutOption(String name) => Key('$_prefix.keyboard_layout.$name');
|
||||
|
@ -152,6 +152,7 @@ class _AndroidSettingsPageState extends ConsumerState<AndroidSettingsPage> {
|
||||
ListTile(
|
||||
title: const Text('App theme'),
|
||||
subtitle: Text(themeMode.displayName),
|
||||
key: keys.themeModeSetting,
|
||||
onTap: () async {
|
||||
final newMode = await _selectAppearance(
|
||||
ref.read(supportedThemesProvider), context, themeMode);
|
||||
@ -223,6 +224,7 @@ class _AndroidSettingsPageState extends ConsumerState<AndroidSettingsPage> {
|
||||
.map((e) => RadioListTile(
|
||||
title: Text(e.displayName),
|
||||
value: e,
|
||||
key: Key('android.keys.theme_mode_${e.name}'),
|
||||
groupValue: themeMode,
|
||||
toggleable: true,
|
||||
onChanged: (mode) {
|
||||
|
@ -20,8 +20,9 @@ final windowStateProvider = Provider<WindowState>(
|
||||
(ref) => WindowState(focused: true, visible: true, active: true),
|
||||
);
|
||||
|
||||
final supportedThemesProvider =
|
||||
StateProvider<List<ThemeMode>>((ref) => ThemeMode.values);
|
||||
final supportedThemesProvider = StateProvider<List<ThemeMode>>(
|
||||
(ref) => throw UnimplementedError(),
|
||||
);
|
||||
|
||||
final themeModeProvider = StateNotifierProvider<ThemeModeNotifier, ThemeMode>(
|
||||
(ref) => ThemeModeNotifier(
|
||||
|
@ -118,7 +118,8 @@ Future<Widget> initialize(List<String> argv) async {
|
||||
fidoStateProvider.overrideWithProvider(desktopFidoState),
|
||||
fingerprintProvider.overrideWithProvider(desktopFingerprintProvider),
|
||||
credentialProvider.overrideWithProvider(desktopCredentialProvider),
|
||||
clipboardProvider.overrideWithProvider(desktopClipboardProvider)
|
||||
clipboardProvider.overrideWithProvider(desktopClipboardProvider),
|
||||
supportedThemesProvider.overrideWithProvider(desktopSupportedThemesProvider)
|
||||
],
|
||||
child: YubicoAuthenticatorApp(
|
||||
page: Consumer(
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
@ -130,6 +131,10 @@ class _DesktopClipboard extends AppClipboard {
|
||||
}
|
||||
}
|
||||
|
||||
final desktopSupportedThemesProvider = StateProvider<List<ThemeMode>>(
|
||||
(ref) => ThemeMode.values,
|
||||
);
|
||||
|
||||
final desktopCurrentDeviceProvider =
|
||||
StateNotifierProvider<CurrentDeviceNotifier, DeviceNode?>((ref) {
|
||||
final provider = _DesktopCurrentDeviceNotifier(ref.watch(prefProvider));
|
||||
|
@ -5,7 +5,9 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:yubico_authenticator/android/keys.dart' as keys;
|
||||
import 'package:yubico_authenticator/android/state.dart';
|
||||
import 'package:yubico_authenticator/android/views/android_settings_page.dart';
|
||||
import 'package:yubico_authenticator/app/state.dart';
|
||||
import 'package:yubico_authenticator/core/state.dart';
|
||||
|
||||
import '../integration_test/android/constants.dart';
|
||||
@ -84,8 +86,48 @@ extension _WidgetTesterHelper on WidgetTester {
|
||||
await tap(find.byKey(keys.nfcBypassTouchSetting));
|
||||
await pumpAndSettle();
|
||||
}
|
||||
|
||||
ListTile themeModeListTile() =>
|
||||
find.byKey(keys.themeModeSetting).evaluate().single.widget as ListTile;
|
||||
|
||||
Future<void> openAppThemeOptionSelection() async {
|
||||
var widget = find.byKey(keys.themeModeSetting).hitTestable();
|
||||
expect(widget, findsOneWidget);
|
||||
await tap(widget);
|
||||
await pumpAndSettle();
|
||||
}
|
||||
|
||||
Future<void> selectSystemTheme() async {
|
||||
await openAppThemeOptionSelection();
|
||||
await tap(find.byKey(keys.themeModeSystem));
|
||||
await pumpAndSettle();
|
||||
}
|
||||
|
||||
Future<void> selectLightTheme() async {
|
||||
await openAppThemeOptionSelection();
|
||||
await tap(find.byKey(keys.themeModeLight));
|
||||
await pumpAndSettle();
|
||||
}
|
||||
|
||||
Future<void> selectDarkTheme() async {
|
||||
await openAppThemeOptionSelection();
|
||||
await tap(find.byKey(keys.themeModeDark));
|
||||
await pumpAndSettle();
|
||||
}
|
||||
}
|
||||
|
||||
Widget androidWidget({
|
||||
required SharedPreferences sharedPrefs,
|
||||
required Widget child,
|
||||
int sdkVersion = 33,
|
||||
}) =>
|
||||
ProviderScope(overrides: [
|
||||
prefProvider.overrideWithValue(sharedPrefs),
|
||||
androidSdkVersionProvider.overrideWithValue(sdkVersion),
|
||||
supportedThemesProvider
|
||||
.overrideWithProvider(androidSupportedThemesProvider)
|
||||
], child: child);
|
||||
|
||||
void main() {
|
||||
var widget = createMaterialApp(child: const AndroidSettingsPage());
|
||||
|
||||
@ -95,9 +137,10 @@ void main() {
|
||||
|
||||
SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
|
||||
|
||||
await tester.pumpWidget(ProviderScope(
|
||||
overrides: [prefProvider.overrideWithValue(sharedPrefs)],
|
||||
child: widget));
|
||||
await tester.pumpWidget(androidWidget(
|
||||
sharedPrefs: sharedPrefs,
|
||||
child: widget,
|
||||
));
|
||||
|
||||
// launch - preserves original value
|
||||
await tester.selectLaunchOption();
|
||||
@ -126,9 +169,10 @@ void main() {
|
||||
|
||||
SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
|
||||
|
||||
await tester.pumpWidget(ProviderScope(
|
||||
overrides: [prefProvider.overrideWithValue(sharedPrefs)],
|
||||
child: widget));
|
||||
await tester.pumpWidget(androidWidget(
|
||||
sharedPrefs: sharedPrefs,
|
||||
child: widget,
|
||||
));
|
||||
|
||||
// option is disabled for "open"
|
||||
expect(tester.keyboardLayoutListTile().enabled, equals(false));
|
||||
@ -161,9 +205,10 @@ void main() {
|
||||
SharedPreferences.setMockInitialValues({prefNfcBypassTouch: false});
|
||||
SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
|
||||
|
||||
await tester.pumpWidget(ProviderScope(
|
||||
overrides: [prefProvider.overrideWithValue(sharedPrefs)],
|
||||
child: widget));
|
||||
await tester.pumpWidget(androidWidget(
|
||||
sharedPrefs: sharedPrefs,
|
||||
child: widget,
|
||||
));
|
||||
|
||||
// change to true
|
||||
await tester.tapBypassTouch();
|
||||
@ -173,4 +218,60 @@ void main() {
|
||||
await tester.tapBypassTouch();
|
||||
expect(sharedPrefs.getBool(prefNfcBypassTouch), equals(false));
|
||||
});
|
||||
|
||||
group('Theme settings', () {
|
||||
testWidgets('Theme default on Android 10+', (WidgetTester tester) async {
|
||||
// no value for theme
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
|
||||
|
||||
await tester.pumpWidget(androidWidget(
|
||||
sharedPrefs: sharedPrefs,
|
||||
child: widget,
|
||||
// Android 10 (API Level 29)
|
||||
sdkVersion: 29,
|
||||
));
|
||||
|
||||
// we expect System theme default
|
||||
expect((tester.themeModeListTile().subtitle as Text).data,
|
||||
equals('System default'));
|
||||
});
|
||||
|
||||
testWidgets('Theme default on Android <10', (WidgetTester tester) async {
|
||||
// no value for theme
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
|
||||
|
||||
await tester.pumpWidget(androidWidget(
|
||||
sharedPrefs: sharedPrefs,
|
||||
child: widget,
|
||||
// Android 9 (API Level 28)
|
||||
sdkVersion: 28,
|
||||
));
|
||||
|
||||
// we expect System theme default
|
||||
expect((tester.themeModeListTile().subtitle as Text).data,
|
||||
equals('Light theme'));
|
||||
});
|
||||
|
||||
testWidgets('Theme preferences update', (WidgetTester tester) async {
|
||||
// no value for theme
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
|
||||
|
||||
await tester.pumpWidget(androidWidget(
|
||||
sharedPrefs: sharedPrefs,
|
||||
child: widget,
|
||||
));
|
||||
|
||||
await tester.selectSystemTheme();
|
||||
expect(sharedPrefs.getString(prefTheme), equals('system'));
|
||||
|
||||
await tester.selectLightTheme();
|
||||
expect(sharedPrefs.getString(prefTheme), equals('light'));
|
||||
|
||||
await tester.selectDarkTheme();
|
||||
expect(sharedPrefs.getString(prefTheme), equals('dark'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user