mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: add app setting test (#1361)
This commit is contained in:
parent
67e4a759c7
commit
18185cc90c
@ -19,9 +19,9 @@ class InitAppWidgetTask extends LaunchTask {
|
||||
Future<void> initialize(LaunchContext context) async {
|
||||
final widget = context.getIt<EntryPoint>().create();
|
||||
final setting = await SettingsFFIService().getAppearanceSetting();
|
||||
final settingModel = AppearanceSetting(setting);
|
||||
final appearanceSetting = AppearanceSetting(setting);
|
||||
final app = ApplicationWidget(
|
||||
settingModel: settingModel,
|
||||
appearanceSetting: appearanceSetting,
|
||||
child: widget,
|
||||
);
|
||||
Bloc.observer = ApplicationBlocObserver();
|
||||
@ -61,23 +61,23 @@ class InitAppWidgetTask extends LaunchTask {
|
||||
|
||||
class ApplicationWidget extends StatelessWidget {
|
||||
final Widget child;
|
||||
final AppearanceSetting settingModel;
|
||||
final AppearanceSetting appearanceSetting;
|
||||
|
||||
const ApplicationWidget({
|
||||
Key? key,
|
||||
required this.child,
|
||||
required this.settingModel,
|
||||
required this.appearanceSetting,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider.value(
|
||||
value: settingModel,
|
||||
value: appearanceSetting,
|
||||
builder: (context, _) {
|
||||
const ratio = 1.73;
|
||||
const minWidth = 600.0;
|
||||
setWindowMinSize(const Size(minWidth, minWidth / ratio));
|
||||
settingModel.readLocaleWhenAppLaunch(context);
|
||||
appearanceSetting.readLocaleWhenAppLaunch(context);
|
||||
AppTheme theme = context.select<AppearanceSetting, AppTheme>(
|
||||
(value) => value.theme,
|
||||
);
|
||||
|
@ -13,7 +13,6 @@ class AppearanceSetting extends ChangeNotifier with EquatableMixin {
|
||||
final AppearanceSettingsPB _setting;
|
||||
AppTheme _theme;
|
||||
Locale _locale;
|
||||
Timer? _debounceSaveOperation;
|
||||
|
||||
AppearanceSetting(AppearanceSettingsPB setting)
|
||||
: _setting = setting,
|
||||
@ -83,10 +82,17 @@ class AppearanceSetting extends ChangeNotifier with EquatableMixin {
|
||||
} else {
|
||||
_setting.settingKeyValue[key] = value;
|
||||
}
|
||||
|
||||
_saveAppearSetting();
|
||||
notifyListeners();
|
||||
}
|
||||
_saveAppearSetting();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
String? getValue(String key) {
|
||||
if (key.isEmpty) {
|
||||
Log.warn("The key should not be empty");
|
||||
return null;
|
||||
}
|
||||
return _setting.settingKeyValue[key];
|
||||
}
|
||||
|
||||
/// Called when the application launch.
|
||||
@ -103,15 +109,12 @@ class AppearanceSetting extends ChangeNotifier with EquatableMixin {
|
||||
}
|
||||
|
||||
Future<void> _saveAppearSetting() async {
|
||||
_debounceSaveOperation?.cancel();
|
||||
_debounceSaveOperation = Timer(
|
||||
const Duration(seconds: 1),
|
||||
() {
|
||||
SettingsFFIService().setAppearanceSetting(_setting).then((result) {
|
||||
result.fold((l) => null, (error) => Log.error(error));
|
||||
});
|
||||
},
|
||||
);
|
||||
SettingsFFIService().setAppearanceSetting(_setting).then((result) {
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(error) => Log.error(error),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -0,0 +1,43 @@
|
||||
import 'package:app_flowy/user/application/user_settings_service.dart';
|
||||
import 'package:app_flowy/workspace/application/appearance.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../../util.dart';
|
||||
|
||||
void main() {
|
||||
// ignore: unused_local_variable
|
||||
late AppFlowyUnitTest context;
|
||||
setUpAll(() async {
|
||||
context = await AppFlowyUnitTest.ensureInitialized();
|
||||
});
|
||||
|
||||
group('$AppearanceSetting', () {
|
||||
late AppearanceSetting appearanceSetting;
|
||||
setUp(() async {
|
||||
final setting = await SettingsFFIService().getAppearanceSetting();
|
||||
appearanceSetting = AppearanceSetting(setting);
|
||||
await blocResponseFuture();
|
||||
});
|
||||
|
||||
test('default theme', () {
|
||||
expect(appearanceSetting.theme.ty, ThemeType.light);
|
||||
});
|
||||
|
||||
test('save key/value', () async {
|
||||
appearanceSetting.setKeyValue("123", "456");
|
||||
});
|
||||
|
||||
test('read key/value', () {
|
||||
expect(appearanceSetting.getValue("123"), "456");
|
||||
});
|
||||
|
||||
test('remove key/value', () {
|
||||
appearanceSetting.setKeyValue("123", null);
|
||||
});
|
||||
|
||||
test('read key/value', () {
|
||||
expect(appearanceSetting.getValue("123"), null);
|
||||
});
|
||||
});
|
||||
}
|
@ -12,38 +12,42 @@ void main() {
|
||||
late AppFlowyUnitTest test;
|
||||
late AppPB app;
|
||||
late AppBloc appBloc;
|
||||
late List<ViewPB> allViews;
|
||||
late TrashBloc trashBloc;
|
||||
setUpAll(() async {
|
||||
test = await AppFlowyUnitTest.ensureInitialized();
|
||||
|
||||
/// Create a new app with three documents
|
||||
app = await test.createTestApp();
|
||||
appBloc = AppBloc(app: app)
|
||||
..add(const AppEvent.initial())
|
||||
..add(AppEvent.createView(
|
||||
"Document 1",
|
||||
DocumentPluginBuilder(),
|
||||
))
|
||||
..add(AppEvent.createView(
|
||||
"Document 2",
|
||||
DocumentPluginBuilder(),
|
||||
))
|
||||
..add(
|
||||
AppEvent.createView(
|
||||
"Document 3",
|
||||
DocumentPluginBuilder(),
|
||||
),
|
||||
);
|
||||
await blocResponseFuture(millisecond: 200);
|
||||
allViews = [...appBloc.state.app.belongings.items];
|
||||
assert(allViews.length == 3);
|
||||
});
|
||||
|
||||
// 1. Create three views
|
||||
// 2. Delete a view and check the state
|
||||
// 3. Delete all views and check the state
|
||||
// 4. Put back a view
|
||||
// 5. Put back all views
|
||||
group('$TrashBloc', () {
|
||||
late TrashBloc trashBloc;
|
||||
late ViewPB deletedView;
|
||||
|
||||
setUpAll(() {});
|
||||
late List<ViewPB> allViews;
|
||||
setUpAll(() async {
|
||||
/// Create a new app with three documents
|
||||
app = await test.createTestApp();
|
||||
appBloc = AppBloc(app: app)
|
||||
..add(const AppEvent.initial())
|
||||
..add(AppEvent.createView(
|
||||
"Document 1",
|
||||
DocumentPluginBuilder(),
|
||||
))
|
||||
..add(AppEvent.createView(
|
||||
"Document 2",
|
||||
DocumentPluginBuilder(),
|
||||
))
|
||||
..add(
|
||||
AppEvent.createView(
|
||||
"Document 3",
|
||||
DocumentPluginBuilder(),
|
||||
),
|
||||
);
|
||||
await blocResponseFuture(millisecond: 200);
|
||||
allViews = [...appBloc.state.app.belongings.items];
|
||||
assert(allViews.length == 3);
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
trashBloc = TrashBloc()..add(const TrashEvent.initial());
|
||||
@ -51,7 +55,7 @@ void main() {
|
||||
});
|
||||
|
||||
blocTest<TrashBloc, TrashState>(
|
||||
"delete view",
|
||||
"delete a view",
|
||||
build: () => trashBloc,
|
||||
act: (bloc) async {
|
||||
deletedView = appBloc.state.app.belongings.items[0];
|
||||
@ -82,7 +86,7 @@ void main() {
|
||||
},
|
||||
);
|
||||
blocTest<TrashBloc, TrashState>(
|
||||
"put back",
|
||||
"put back a trash",
|
||||
build: () => trashBloc,
|
||||
act: (bloc) async {
|
||||
bloc.add(TrashEvent.putback(allViews[0].id));
|
||||
@ -94,7 +98,7 @@ void main() {
|
||||
},
|
||||
);
|
||||
blocTest<TrashBloc, TrashState>(
|
||||
"put back all",
|
||||
"put back all trash",
|
||||
build: () => trashBloc,
|
||||
act: (bloc) async {
|
||||
bloc.add(const TrashEvent.restoreAll());
|
||||
@ -107,4 +111,69 @@ void main() {
|
||||
);
|
||||
//
|
||||
});
|
||||
|
||||
// 1. Create three views
|
||||
// 2. Delete a trash permanently and check the state
|
||||
// 3. Delete all views permanently
|
||||
group('$TrashBloc', () {
|
||||
setUpAll(() async {
|
||||
/// Create a new app with three documents
|
||||
app = await test.createTestApp();
|
||||
appBloc = AppBloc(app: app)
|
||||
..add(const AppEvent.initial())
|
||||
..add(AppEvent.createView(
|
||||
"Document 1",
|
||||
DocumentPluginBuilder(),
|
||||
))
|
||||
..add(AppEvent.createView(
|
||||
"Document 2",
|
||||
DocumentPluginBuilder(),
|
||||
))
|
||||
..add(
|
||||
AppEvent.createView(
|
||||
"Document 3",
|
||||
DocumentPluginBuilder(),
|
||||
),
|
||||
);
|
||||
await blocResponseFuture(millisecond: 200);
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
trashBloc = TrashBloc()..add(const TrashEvent.initial());
|
||||
await blocResponseFuture();
|
||||
});
|
||||
|
||||
blocTest<TrashBloc, TrashState>(
|
||||
"delete a view permanently",
|
||||
build: () => trashBloc,
|
||||
act: (bloc) async {
|
||||
final view = appBloc.state.app.belongings.items[0];
|
||||
appBloc.add(AppEvent.deleteView(view.id));
|
||||
await blocResponseFuture();
|
||||
|
||||
trashBloc.add(TrashEvent.delete(trashBloc.state.objects[0]));
|
||||
},
|
||||
wait: blocResponseDuration(),
|
||||
verify: (bloc) {
|
||||
assert(appBloc.state.app.belongings.items.length == 2);
|
||||
assert(bloc.state.objects.isEmpty);
|
||||
},
|
||||
);
|
||||
blocTest<TrashBloc, TrashState>(
|
||||
"delete all view permanently",
|
||||
build: () => trashBloc,
|
||||
act: (bloc) async {
|
||||
for (final view in appBloc.state.app.belongings.items) {
|
||||
appBloc.add(AppEvent.deleteView(view.id));
|
||||
}
|
||||
await blocResponseFuture();
|
||||
trashBloc.add(const TrashEvent.deleteAll());
|
||||
},
|
||||
wait: blocResponseDuration(),
|
||||
verify: (bloc) {
|
||||
assert(appBloc.state.app.belongings.items.isEmpty);
|
||||
assert(bloc.state.objects.isEmpty);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user