diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index 083a4ffa5f..e83749026f 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -47,6 +47,7 @@ PROTOBUF_DERIVE_CACHE = "../shared-lib/flowy-derive/src/derive_cache/derive_cach # Test default config TEST_CRATE_TYPE = "cdylib" TEST_LIB_EXT = "dylib" +TEST_RUST_LOG = "info" TEST_BUILD_FLAG = "debug" TEST_COMPILE_TARGET = "x86_64-apple-darwin" diff --git a/frontend/app_flowy/lib/plugins/board/application/board_data_controller.dart b/frontend/app_flowy/lib/plugins/board/application/board_data_controller.dart index e2d8cf35b8..7ca035d375 100644 --- a/frontend/app_flowy/lib/plugins/board/application/board_data_controller.dart +++ b/frontend/app_flowy/lib/plugins/board/application/board_data_controller.dart @@ -34,7 +34,8 @@ class BoardDataController { // key: the block id final LinkedHashMap _blocks; - LinkedHashMap get blocks => _blocks; + UnmodifiableMapView get blocks => + UnmodifiableMapView(_blocks); OnFieldsChanged? _onFieldsChanged; OnGridChanged? _onGridChanged; @@ -113,15 +114,16 @@ class BoardDataController { () => result.fold( (grid) async { _onGridChanged?.call(grid); - return await fieldController.loadFields(fieldIds: grid.fields).then( - (result) => result.fold( - (l) { - _loadGroups(grid.blocks); - return left(l); - }, - (err) => right(err), - ), - ); + final result = await fieldController.loadFields( + fieldIds: grid.fields, + ); + return result.fold( + (l) { + _loadGroups(grid.blocks); + return left(l); + }, + (err) => right(err), + ); }, (err) => right(err), ), diff --git a/frontend/app_flowy/lib/plugins/grid/application/field/type_option/type_option_data_controller.dart b/frontend/app_flowy/lib/plugins/grid/application/field/type_option/type_option_data_controller.dart index d11a35e764..e52b9f33cd 100644 --- a/frontend/app_flowy/lib/plugins/grid/application/field/type_option/type_option_data_controller.dart +++ b/frontend/app_flowy/lib/plugins/grid/application/field/type_option/type_option_data_controller.dart @@ -15,6 +15,12 @@ class TypeOptionDataController { late FieldTypeOptionDataPB _data; final PublishNotifier _fieldNotifier = PublishNotifier(); + /// Returns a [TypeOptionDataController] used to modify the specified + /// [FieldPB]'s data + /// + /// Should call [loadTypeOptionData] if the passed-in [GridFieldContext] + /// is null + /// TypeOptionDataController({ required this.gridId, required this.loader, @@ -77,18 +83,17 @@ class TypeOptionDataController { ); } - Future switchToField(FieldType newFieldType) { - return loader.switchToField(field.id, newFieldType).then((result) { - return result.fold( - (_) { - // Should load the type-option data after switching to a new field. - // After loading the type-option data, the editor widget that uses - // the type-option data will be rebuild. - loadTypeOptionData(); - }, - (err) => Log.error(err), - ); - }); + Future switchToField(FieldType newFieldType) async { + final result = await loader.switchToField(field.id, newFieldType); + await result.fold( + (_) { + // Should load the type-option data after switching to a new field. + // After loading the type-option data, the editor widget that uses + // the type-option data will be rebuild. + loadTypeOptionData(); + }, + (err) => Future(() => Log.error(err)), + ); } void Function() addFieldListener(void Function(FieldPB) callback) { diff --git a/frontend/app_flowy/lib/plugins/grid/application/setting/group_bloc.dart b/frontend/app_flowy/lib/plugins/grid/application/setting/group_bloc.dart index 8b58d5ea0c..a4341517ac 100644 --- a/frontend/app_flowy/lib/plugins/grid/application/setting/group_bloc.dart +++ b/frontend/app_flowy/lib/plugins/grid/application/setting/group_bloc.dart @@ -1,3 +1,4 @@ +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -13,9 +14,10 @@ class GridGroupBloc extends Bloc { final SettingFFIService _settingFFIService; Function(List)? _onFieldsFn; - GridGroupBloc( - {required String viewId, required GridFieldController fieldController}) - : _fieldController = fieldController, + GridGroupBloc({ + required String viewId, + required GridFieldController fieldController, + }) : _fieldController = fieldController, _settingFFIService = SettingFFIService(viewId: viewId), super(GridGroupState.initial(viewId, fieldController.fieldContexts)) { on( @@ -27,11 +29,12 @@ class GridGroupBloc extends Bloc { didReceiveFieldUpdate: (fieldContexts) { emit(state.copyWith(fieldContexts: fieldContexts)); }, - setGroupByField: (String fieldId, FieldType fieldType) { - _settingFFIService.groupByField( + setGroupByField: (String fieldId, FieldType fieldType) async { + final result = await _settingFFIService.groupByField( fieldId: fieldId, fieldType: fieldType, ); + result.fold((l) => null, (err) => Log.error(err)); }, ); }, diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart index e4af73fd3a..d69930d95f 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart @@ -21,8 +21,8 @@ class FieldEditor extends StatefulWidget { final String fieldName; final bool isGroupField; final Function(String)? onDeleted; - final IFieldTypeOptionLoader typeOptionLoader; + const FieldEditor({ required this.gridId, this.fieldName = "", diff --git a/frontend/app_flowy/test/bloc_test/board_test/create_card_test.dart b/frontend/app_flowy/test/bloc_test/board_test/create_card_test.dart index cfadaaf5c8..52609f323f 100644 --- a/frontend/app_flowy/test/bloc_test/board_test/create_card_test.dart +++ b/frontend/app_flowy/test/bloc_test/board_test/create_card_test.dart @@ -11,13 +11,13 @@ void main() { boardTest = await AppFlowyBoardTest.ensureInitialized(); }); - group('description', () { + group('$BoardBloc', () { late BoardBloc boardBloc; late String groupId; setUp(() async { - await boardTest.createTestBoard(); - boardBloc = BoardBloc(view: boardTest.boardView) + await boardTest.context.createTestBoard(); + boardBloc = BoardBloc(view: boardTest.context.gridView) ..add(const BoardEvent.initial()); await boardResponseFuture(); groupId = boardBloc.state.groupIds.first; diff --git a/frontend/app_flowy/test/bloc_test/board_test/group_by_field_test.dart b/frontend/app_flowy/test/bloc_test/board_test/group_by_field_test.dart new file mode 100644 index 0000000000..25895f2e8e --- /dev/null +++ b/frontend/app_flowy/test/bloc_test/board_test/group_by_field_test.dart @@ -0,0 +1,113 @@ +import 'package:app_flowy/plugins/board/application/board_bloc.dart'; +import 'package:app_flowy/plugins/grid/application/field/field_editor_bloc.dart'; +import 'package:app_flowy/plugins/grid/application/setting/group_bloc.dart'; +import 'package:bloc_test/bloc_test.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pbserver.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'util.dart'; + +void main() { + late AppFlowyBoardTest boardTest; + + setUpAll(() async { + boardTest = await AppFlowyBoardTest.ensureInitialized(); + }); + + // Group with not support grouping field + group('Group with not support grouping field:', () { + late FieldEditorBloc editorBloc; + setUpAll(() async { + await boardTest.context.createTestBoard(); + final fieldContext = boardTest.context.singleSelectFieldContext(); + editorBloc = boardTest.context.createFieldEditor( + fieldContext: fieldContext, + )..add(const FieldEditorEvent.initial()); + + await boardResponseFuture(); + }); + + blocTest( + "switch to text field", + build: () => editorBloc, + wait: boardResponseDuration(), + act: (bloc) async { + await bloc.dataController.switchToField(FieldType.RichText); + }, + verify: (bloc) { + bloc.state.field.fold( + () => throw Exception(), + (field) => field.fieldType == FieldType.RichText, + ); + }, + ); + blocTest( + 'assert the number of groups is 1', + build: () => BoardBloc(view: boardTest.context.gridView) + ..add(const BoardEvent.initial()), + wait: boardResponseDuration(), + verify: (bloc) { + assert(bloc.groupControllers.values.length == 1, + "Expected 1, but receive ${bloc.groupControllers.values.length}"); + }, + ); + }); + + // Group by checkbox field + group('Group by checkbox field:', () { + late BoardBloc boardBloc; + late FieldPB checkboxField; + setUpAll(() async { + await boardTest.context.createTestBoard(); + }); + + setUp(() async { + boardBloc = BoardBloc(view: boardTest.context.gridView) + ..add(const BoardEvent.initial()); + await boardResponseFuture(); + }); + + blocTest( + "initial", + build: () => boardBloc, + wait: boardResponseDuration(), + verify: (bloc) { + assert(bloc.groupControllers.values.length == 4); + assert(boardTest.context.fieldContexts.length == 2); + }, + ); + + test('create checkbox field', () async { + await boardTest.context.createFieldFromType(FieldType.Checkbox); + await boardResponseFuture(); + + assert(boardTest.context.fieldContexts.length == 3); + checkboxField = boardTest.context.fieldContexts.last.field; + assert(checkboxField.fieldType == FieldType.Checkbox); + }); + + blocTest( + "set grouped by checkbox field", + build: () => GridGroupBloc( + viewId: boardTest.context.gridView.id, + fieldController: boardTest.context.fieldController, + ), + act: (bloc) async { + bloc.add(GridGroupEvent.setGroupByField( + checkboxField.id, + checkboxField.fieldType, + )); + }, + wait: boardResponseDuration(), + ); + + blocTest( + "check the number of groups is 2", + build: () => boardBloc, + wait: boardResponseDuration(), + verify: (bloc) { + assert(bloc.groupControllers.values.length == 2); + }, + ); + }); +} diff --git a/frontend/app_flowy/test/bloc_test/board_test/util.dart b/frontend/app_flowy/test/bloc_test/board_test/util.dart index 94ba81a80a..a757a97bab 100644 --- a/frontend/app_flowy/test/bloc_test/board_test/util.dart +++ b/frontend/app_flowy/test/bloc_test/board_test/util.dart @@ -1,36 +1,13 @@ -import 'package:app_flowy/plugins/board/board.dart'; -import 'package:app_flowy/workspace/application/app/app_service.dart'; -import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart'; - -import '../../util.dart'; +import '../grid_test/util.dart'; class AppFlowyBoardTest { - final AppFlowyUnitTest _inner; - late ViewPB boardView; - AppFlowyBoardTest(AppFlowyUnitTest unitTest) : _inner = unitTest; + final AppFlowyGridTest context; + AppFlowyBoardTest(this.context); static Future ensureInitialized() async { - final inner = await AppFlowyUnitTest.ensureInitialized(); + final inner = await AppFlowyGridTest.ensureInitialized(); return AppFlowyBoardTest(inner); } - - Future createTestBoard() async { - final app = await _inner.createTestApp(); - final builder = BoardPluginBuilder(); - final result = await AppService().createView( - appId: app.id, - name: "Test Board", - dataFormatType: builder.dataFormatType, - pluginType: builder.pluginType, - layoutType: builder.layoutType!, - ); - await result.fold( - (view) async { - boardView = view; - }, - (error) {}, - ); - } } Future boardResponseFuture() { diff --git a/frontend/app_flowy/test/bloc_test/grid_test/util.dart b/frontend/app_flowy/test/bloc_test/grid_test/util.dart index b5282ea291..3e28883a1a 100644 --- a/frontend/app_flowy/test/bloc_test/grid_test/util.dart +++ b/frontend/app_flowy/test/bloc_test/grid_test/util.dart @@ -1,8 +1,12 @@ import 'dart:collection'; +import 'package:app_flowy/plugins/board/application/board_data_controller.dart'; +import 'package:app_flowy/plugins/board/board.dart'; import 'package:app_flowy/plugins/grid/application/block/block_cache.dart'; import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart'; import 'package:app_flowy/plugins/grid/application/field/field_controller.dart'; +import 'package:app_flowy/plugins/grid/application/field/field_editor_bloc.dart'; import 'package:app_flowy/plugins/grid/application/field/field_service.dart'; +import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart'; import 'package:app_flowy/plugins/grid/application/grid_data_controller.dart'; import 'package:app_flowy/plugins/grid/application/row/row_bloc.dart'; import 'package:app_flowy/plugins/grid/application/row/row_cache.dart'; @@ -16,29 +20,90 @@ import '../../util.dart'; /// Create a empty Grid for test class AppFlowyGridTest { - final AppFlowyUnitTest _inner; + final AppFlowyUnitTest unitTest; late ViewPB gridView; - late GridDataController _dataController; + GridDataController? _gridDataController; + BoardDataController? _boardDataController; - AppFlowyGridTest(AppFlowyUnitTest unitTest) : _inner = unitTest; + AppFlowyGridTest({required this.unitTest}); static Future ensureInitialized() async { final inner = await AppFlowyUnitTest.ensureInitialized(); - return AppFlowyGridTest(inner); + return AppFlowyGridTest(unitTest: inner); } - List get rowInfos => _dataController.rowInfos; + List get rowInfos { + if (_gridDataController != null) { + return _gridDataController!.rowInfos; + } - UnmodifiableMapView get blocks => - _dataController.blocks; + if (_boardDataController != null) { + return _boardDataController!.rowInfos; + } - List get fieldContexts => - _dataController.fieldController.fieldContexts; + throw Exception(); + } - GridFieldController get fieldController => _dataController.fieldController; + UnmodifiableMapView get blocks { + if (_gridDataController != null) { + return _gridDataController!.blocks; + } + + if (_boardDataController != null) { + return _boardDataController!.blocks; + } + + throw Exception(); + } + + List get fieldContexts => fieldController.fieldContexts; + + GridFieldController get fieldController { + if (_gridDataController != null) { + return _gridDataController!.fieldController; + } + + if (_boardDataController != null) { + return _boardDataController!.fieldController; + } + + throw Exception(); + } Future createRow() async { - await _dataController.createRow(); + if (_gridDataController != null) { + return _gridDataController!.createRow(); + } + + throw Exception(); + } + + FieldEditorBloc createFieldEditor({ + GridFieldContext? fieldContext, + }) { + IFieldTypeOptionLoader loader; + if (fieldContext == null) { + loader = NewFieldTypeOptionLoader(gridId: gridView.id); + } else { + loader = + FieldTypeOptionLoader(gridId: gridView.id, field: fieldContext.field); + } + + final editorBloc = FieldEditorBloc( + fieldName: fieldContext?.name ?? '', + isGroupField: fieldContext?.isGroupField ?? false, + loader: loader, + gridId: gridView.id, + ); + return editorBloc; + } + + Future createFieldFromType(FieldType fieldType) async { + final editor = createFieldEditor()..add(const FieldEditorEvent.initial()); + await gridResponseFuture(); + editor.dataController.switchToField(fieldType); + await gridResponseFuture(); + return Future(() => editor); } GridFieldContext singleSelectFieldContext() { @@ -53,7 +118,7 @@ class AppFlowyGridTest { } Future createTestGrid() async { - final app = await _inner.createTestApp(); + final app = await unitTest.createTestApp(); final builder = GridPluginBuilder(); final result = await AppService().createView( appId: app.id, @@ -65,13 +130,34 @@ class AppFlowyGridTest { await result.fold( (view) async { gridView = view; - _dataController = GridDataController(view: view); - final result = await _dataController.openGrid(); + _gridDataController = GridDataController(view: view); + final result = await _gridDataController!.openGrid(); result.fold((l) => null, (r) => throw Exception(r)); }, (error) {}, ); } + + Future createTestBoard() async { + final app = await unitTest.createTestApp(); + final builder = BoardPluginBuilder(); + final result = await AppService().createView( + appId: app.id, + name: "Test Board", + dataFormatType: builder.dataFormatType, + pluginType: builder.pluginType, + layoutType: builder.layoutType!, + ); + await result.fold( + (view) async { + _boardDataController = BoardDataController(view: view); + final result = await _boardDataController!.openGrid(); + result.fold((l) => null, (r) => throw Exception(r)); + gridView = view; + }, + (error) {}, + ); + } } /// Create a new Grid for cell test @@ -101,7 +187,7 @@ class AppFlowyGridCellTest { final rowDataController = GridRowDataController( rowInfo: rowInfo, - fieldController: _gridTest._dataController.fieldController, + fieldController: _gridTest._gridDataController!.fieldController, rowCache: rowCache!, ); diff --git a/frontend/app_flowy/test/bloc_test/home_test/home_bloc_test.dart b/frontend/app_flowy/test/bloc_test/home_test/home_bloc_test.dart index 69ab062922..97a6f5f506 100644 --- a/frontend/app_flowy/test/bloc_test/home_test/home_bloc_test.dart +++ b/frontend/app_flowy/test/bloc_test/home_test/home_bloc_test.dart @@ -66,7 +66,7 @@ void main() { wait: blocResponseDuration(), ); - test('description', () async { + test('check the latest view is the document', () async { assert(homeBloc.state.workspaceSetting.latestView.id == latestCreatedView.id); }); diff --git a/frontend/app_flowy/test/bloc_test/home_test/trash_bloc_test.dart b/frontend/app_flowy/test/bloc_test/home_test/trash_bloc_test.dart index 35ba491d39..bebe459a52 100644 --- a/frontend/app_flowy/test/bloc_test/home_test/trash_bloc_test.dart +++ b/frontend/app_flowy/test/bloc_test/home_test/trash_bloc_test.dart @@ -165,8 +165,8 @@ void main() { act: (bloc) async { for (final view in appBloc.state.app.belongings.items) { appBloc.add(AppEvent.deleteView(view.id)); + await blocResponseFuture(); } - await blocResponseFuture(); trashBloc.add(const TrashEvent.deleteAll()); }, wait: blocResponseDuration(), diff --git a/frontend/app_flowy/test/util.dart b/frontend/app_flowy/test/util.dart index 414f732b96..3637cf0a22 100644 --- a/frontend/app_flowy/test/util.dart +++ b/frontend/app_flowy/test/util.dart @@ -113,10 +113,10 @@ class FlowyTestApp implements EntryPoint { } } -Future blocResponseFuture({int millisecond = 100}) { +Future blocResponseFuture({int millisecond = 200}) { return Future.delayed(Duration(milliseconds: millisecond)); } -Duration blocResponseDuration({int milliseconds = 100}) { +Duration blocResponseDuration({int milliseconds = 200}) { return Duration(milliseconds: milliseconds); } diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs index 9ef1049369..de1e8dcebd 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs @@ -36,7 +36,7 @@ pub trait FolderPersistenceTransaction { fn read_view(&self, view_id: &str) -> FlowyResult; fn read_views(&self, belong_to_id: &str) -> FlowyResult>; fn update_view(&self, changeset: ViewChangeset) -> FlowyResult<()>; - fn delete_view(&self, view_id: &str) -> FlowyResult<()>; + fn delete_view(&self, view_id: &str) -> FlowyResult; fn move_view(&self, view_id: &str, from: usize, to: usize) -> FlowyResult<()>; fn create_trash(&self, trashes: Vec) -> FlowyResult<()>; diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs index f73c8c9e61..67e4c660d6 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs @@ -84,9 +84,10 @@ impl<'a> FolderPersistenceTransaction for V1Transaction<'a> { Ok(()) } - fn delete_view(&self, view_id: &str) -> FlowyResult<()> { + fn delete_view(&self, view_id: &str) -> FlowyResult { + let view_revision: ViewRevision = ViewTableSql::read_view(view_id, &*self.0)?.into(); let _ = ViewTableSql::delete_view(view_id, &*self.0)?; - Ok(()) + Ok(view_revision) } fn move_view(&self, _view_id: &str, _from: usize, _to: usize) -> FlowyResult<()> { @@ -182,7 +183,7 @@ where (**self).update_view(changeset) } - fn delete_view(&self, view_id: &str) -> FlowyResult<()> { + fn delete_view(&self, view_id: &str) -> FlowyResult { (**self).delete_view(view_id) } diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs index 44d63cf660..721fff43ee 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs @@ -113,11 +113,12 @@ impl FolderPersistenceTransaction for FolderEditor { Ok(()) } - fn delete_view(&self, view_id: &str) -> FlowyResult<()> { - if let Some(change) = self.folder.write().delete_view(view_id)? { + fn delete_view(&self, view_id: &str) -> FlowyResult { + let view = self.folder.read().read_view(view_id)?; + if let Some(change) = self.folder.write().delete_view(&view.app_id, view_id)? { let _ = self.apply_change(change)?; } - Ok(()) + Ok(view) } fn move_view(&self, view_id: &str, from: usize, to: usize) -> FlowyResult<()> { @@ -207,7 +208,7 @@ where (**self).update_view(changeset) } - fn delete_view(&self, view_id: &str) -> FlowyResult<()> { + fn delete_view(&self, view_id: &str) -> FlowyResult { (**self).delete_view(view_id) } diff --git a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs index 50f8ca6101..3f054f07e5 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -462,10 +462,10 @@ async fn handle_trash_event( let mut notify_ids = HashSet::new(); let mut views = vec![]; for identifier in identifiers.items { - let view = transaction.read_view(&identifier.id)?; - let _ = transaction.delete_view(&view.id)?; - notify_ids.insert(view.app_id.clone()); - views.push(view); + if let Ok(view_rev) = transaction.delete_view(&identifier.id) { + notify_ids.insert(view_rev.app_id.clone()); + views.push(view_rev); + } } for notify_id in notify_ids { let _ = notify_views_changed(¬ify_id, trash_can.clone(), &transaction)?; @@ -480,9 +480,7 @@ async fn handle_trash_event( Ok(processor) => { let _ = processor.close_view(&view.id).await?; } - Err(e) => { - tracing::error!("{}", e) - } + Err(e) => tracing::error!("{}", e), } } Ok(()) diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 8d2ac8d9f0..5555c841bf 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -136,7 +136,7 @@ pub(crate) async fn switch_to_field_handler( .switch_to_field_type(¶ms.field_id, ¶ms.field_type) .await?; - // Get the field_rev with field_id, if it doesn't exist, we create the default FieldMeta from the FieldType. + // Get the field_rev with field_id, if it doesn't exist, we create the default FieldRevision from the FieldType. let field_rev = editor .get_field_rev(¶ms.field_id) .await diff --git a/frontend/scripts/makefile/tests.toml b/frontend/scripts/makefile/tests.toml index 02c680e71c..f067baee93 100644 --- a/frontend/scripts/makefile/tests.toml +++ b/frontend/scripts/makefile/tests.toml @@ -1,4 +1,12 @@ +[tasks.dart_unit_test] +dependencies = ["build-test-lib"] +description = "Run flutter unit tests" +script = ''' +cd app_flowy +flutter test --dart-define=RUST_LOG=${TEST_RUST_LOG} +''' + [tasks.rust_unit_test] run_task = { name = ["rust_lib_unit_test", "shared_lib_unit_test"] } diff --git a/shared-lib/flowy-sync/src/client_folder/folder_pad.rs b/shared-lib/flowy-sync/src/client_folder/folder_pad.rs index 2c67900fa3..e11d73963d 100644 --- a/shared-lib/flowy-sync/src/client_folder/folder_pad.rs +++ b/shared-lib/flowy-sync/src/client_folder/folder_pad.rs @@ -258,9 +258,8 @@ impl FolderPad { } #[tracing::instrument(level = "trace", skip(self), err)] - pub fn delete_view(&mut self, view_id: &str) -> CollaborateResult> { - let view = self.read_view(view_id)?; - self.with_app(&view.app_id, |app| { + pub fn delete_view(&mut self, app_id: &str, view_id: &str) -> CollaborateResult> { + self.with_app(app_id, |app| { app.belongings.retain(|view| view.id != view_id); Ok(Some(())) }) @@ -724,7 +723,7 @@ mod tests { #[test] fn folder_delete_view() { let (mut folder, initial_operations, view) = test_view_folder(); - let operations = folder.delete_view(&view.id).unwrap().unwrap().operations; + let operations = folder.delete_view(&view.app_id, &view.id).unwrap().unwrap().operations; let new_folder = make_folder_from_operations(initial_operations, vec![operations]); assert_folder_equal(