mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: add grid header bloc test (#1341)
Co-authored-by: nathan <nathan@appflowy.io>
This commit is contained in:
parent
aa58c79dbb
commit
96b1c6a540
@ -11,9 +11,16 @@ class FieldActionSheetBloc
|
||||
extends Bloc<FieldActionSheetEvent, FieldActionSheetState> {
|
||||
final FieldService fieldService;
|
||||
|
||||
FieldActionSheetBloc({required FieldPB field, required this.fieldService})
|
||||
: super(FieldActionSheetState.initial(
|
||||
FieldTypeOptionDataPB.create()..field_2 = field)) {
|
||||
FieldActionSheetBloc({required GridFieldCellContext fieldCellContext})
|
||||
: fieldService = FieldService(
|
||||
gridId: fieldCellContext.gridId,
|
||||
fieldId: fieldCellContext.field.id,
|
||||
),
|
||||
super(
|
||||
FieldActionSheetState.initial(
|
||||
FieldTypeOptionDataPB.create()..field_2 = fieldCellContext.field,
|
||||
),
|
||||
) {
|
||||
on<FieldActionSheetEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
@ -31,6 +38,13 @@ class FieldActionSheetBloc
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
},
|
||||
showField: (_ShowField value) async {
|
||||
final result = await fieldService.updateField(visibility: true);
|
||||
result.fold(
|
||||
(l) => null,
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
},
|
||||
deleteField: (_DeleteField value) async {
|
||||
final result = await fieldService.deleteField();
|
||||
result.fold(
|
||||
@ -62,6 +76,7 @@ class FieldActionSheetEvent with _$FieldActionSheetEvent {
|
||||
const factory FieldActionSheetEvent.updateFieldName(String name) =
|
||||
_UpdateFieldName;
|
||||
const factory FieldActionSheetEvent.hideField() = _HideField;
|
||||
const factory FieldActionSheetEvent.showField() = _ShowField;
|
||||
const factory FieldActionSheetEvent.duplicateField() = _DuplicateField;
|
||||
const factory FieldActionSheetEvent.deleteField() = _DeleteField;
|
||||
const factory FieldActionSheetEvent.saveField() = _SaveField;
|
||||
|
@ -16,8 +16,7 @@ class _GridFieldNotifier extends ChangeNotifier {
|
||||
List<GridFieldContext> _fieldContexts = [];
|
||||
|
||||
set fieldContexts(List<GridFieldContext> fieldContexts) {
|
||||
_fieldContexts =
|
||||
fieldContexts.where((element) => element.visibility).toList();
|
||||
_fieldContexts = fieldContexts;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,13 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
||||
_startListening();
|
||||
},
|
||||
didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) {
|
||||
emit(state.copyWith(fields: value.fields));
|
||||
emit(
|
||||
state.copyWith(
|
||||
fields: value.fields
|
||||
.where((element) => element.visibility)
|
||||
.toList(),
|
||||
),
|
||||
);
|
||||
},
|
||||
moveField: (_MoveField value) async {
|
||||
await _moveField(value, emit);
|
||||
|
@ -158,10 +158,7 @@ void _resolveGridDeps(GetIt getIt) {
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<FieldActionSheetBloc, GridFieldCellContext, void>(
|
||||
(data, _) => FieldActionSheetBloc(
|
||||
field: data.field,
|
||||
fieldService: FieldService(gridId: data.gridId, fieldId: data.field.id),
|
||||
),
|
||||
(data, _) => FieldActionSheetBloc(fieldCellContext: data),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<TextCellBloc, GridCellController, void>(
|
||||
|
@ -0,0 +1,125 @@
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_action_sheet_bloc.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/grid_header_bloc.dart';
|
||||
import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'util.dart';
|
||||
|
||||
void main() {
|
||||
late AppFlowyGridTest gridTest;
|
||||
|
||||
setUpAll(() async {
|
||||
gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
});
|
||||
|
||||
group('GridHeaderBloc', () {
|
||||
late FieldActionSheetBloc actionSheetBloc;
|
||||
setUp(() async {
|
||||
await gridTest.createTestGrid();
|
||||
actionSheetBloc = FieldActionSheetBloc(
|
||||
fieldCellContext: gridTest.singleSelectFieldCellContext(),
|
||||
);
|
||||
});
|
||||
|
||||
blocTest<GridHeaderBloc, GridHeaderState>(
|
||||
"hides property",
|
||||
build: () {
|
||||
final bloc = GridHeaderBloc(
|
||||
gridId: gridTest.gridView.id,
|
||||
fieldController: gridTest.fieldController,
|
||||
)..add(const GridHeaderEvent.initial());
|
||||
return bloc;
|
||||
},
|
||||
act: (bloc) async {
|
||||
actionSheetBloc.add(const FieldActionSheetEvent.hideField());
|
||||
await Future.delayed(gridResponseDuration());
|
||||
},
|
||||
wait: gridResponseDuration(),
|
||||
verify: (bloc) {
|
||||
assert(bloc.state.fields.length == 2);
|
||||
},
|
||||
);
|
||||
|
||||
blocTest<GridHeaderBloc, GridHeaderState>(
|
||||
"shows property",
|
||||
build: () {
|
||||
final bloc = GridHeaderBloc(
|
||||
gridId: gridTest.gridView.id,
|
||||
fieldController: gridTest.fieldController,
|
||||
)..add(const GridHeaderEvent.initial());
|
||||
return bloc;
|
||||
},
|
||||
act: (bloc) async {
|
||||
actionSheetBloc.add(const FieldActionSheetEvent.hideField());
|
||||
await Future.delayed(gridResponseDuration());
|
||||
actionSheetBloc.add(const FieldActionSheetEvent.showField());
|
||||
await Future.delayed(gridResponseDuration());
|
||||
},
|
||||
wait: gridResponseDuration(),
|
||||
verify: (bloc) {
|
||||
assert(bloc.state.fields.length == 3);
|
||||
},
|
||||
);
|
||||
|
||||
blocTest<GridHeaderBloc, GridHeaderState>(
|
||||
"duplicate property",
|
||||
build: () {
|
||||
final bloc = GridHeaderBloc(
|
||||
gridId: gridTest.gridView.id,
|
||||
fieldController: gridTest.fieldController,
|
||||
)..add(const GridHeaderEvent.initial());
|
||||
return bloc;
|
||||
},
|
||||
act: (bloc) async {
|
||||
actionSheetBloc.add(const FieldActionSheetEvent.duplicateField());
|
||||
await Future.delayed(gridResponseDuration());
|
||||
},
|
||||
wait: gridResponseDuration(),
|
||||
verify: (bloc) {
|
||||
assert(bloc.state.fields.length == 4);
|
||||
},
|
||||
);
|
||||
|
||||
blocTest<GridHeaderBloc, GridHeaderState>(
|
||||
"delete property",
|
||||
build: () {
|
||||
final bloc = GridHeaderBloc(
|
||||
gridId: gridTest.gridView.id,
|
||||
fieldController: gridTest.fieldController,
|
||||
)..add(const GridHeaderEvent.initial());
|
||||
return bloc;
|
||||
},
|
||||
act: (bloc) async {
|
||||
actionSheetBloc.add(const FieldActionSheetEvent.deleteField());
|
||||
await Future.delayed(gridResponseDuration());
|
||||
},
|
||||
wait: gridResponseDuration(),
|
||||
verify: (bloc) {
|
||||
assert(bloc.state.fields.length == 2);
|
||||
},
|
||||
);
|
||||
|
||||
blocTest<GridHeaderBloc, GridHeaderState>(
|
||||
"update name",
|
||||
build: () {
|
||||
final bloc = GridHeaderBloc(
|
||||
gridId: gridTest.gridView.id,
|
||||
fieldController: gridTest.fieldController,
|
||||
)..add(const GridHeaderEvent.initial());
|
||||
return bloc;
|
||||
},
|
||||
act: (bloc) async {
|
||||
actionSheetBloc
|
||||
.add(const FieldActionSheetEvent.updateFieldName("Hello world"));
|
||||
await Future.delayed(gridResponseDuration());
|
||||
},
|
||||
wait: gridResponseDuration(),
|
||||
verify: (bloc) {
|
||||
final field = bloc.state.fields.firstWhere(
|
||||
(element) => element.id == actionSheetBloc.fieldService.fieldId);
|
||||
|
||||
assert(field.name == "Hello world");
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
@ -1,4 +1,8 @@
|
||||
import 'dart:collection';
|
||||
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_service.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';
|
||||
@ -12,9 +16,10 @@ import '../../util.dart';
|
||||
|
||||
/// Create a empty Grid for test
|
||||
class AppFlowyGridTest {
|
||||
// ignore: unused_field
|
||||
final AppFlowyUnitTest _inner;
|
||||
late ViewPB gridView;
|
||||
late GridDataController _dataController;
|
||||
|
||||
AppFlowyGridTest(AppFlowyUnitTest unitTest) : _inner = unitTest;
|
||||
|
||||
static Future<AppFlowyGridTest> ensureInitialized() async {
|
||||
@ -22,6 +27,31 @@ class AppFlowyGridTest {
|
||||
return AppFlowyGridTest(inner);
|
||||
}
|
||||
|
||||
List<RowInfo> get rowInfos => _dataController.rowInfos;
|
||||
|
||||
UnmodifiableMapView<String, GridBlockCache> get blocks =>
|
||||
_dataController.blocks;
|
||||
|
||||
List<GridFieldContext> get fieldContexts =>
|
||||
_dataController.fieldController.fieldContexts;
|
||||
|
||||
GridFieldController get fieldController => _dataController.fieldController;
|
||||
|
||||
Future<void> createRow() async {
|
||||
await _dataController.createRow();
|
||||
}
|
||||
|
||||
GridFieldContext singleSelectFieldContext() {
|
||||
final fieldContext = fieldContexts
|
||||
.firstWhere((element) => element.fieldType == FieldType.SingleSelect);
|
||||
return fieldContext;
|
||||
}
|
||||
|
||||
GridFieldCellContext singleSelectFieldCellContext() {
|
||||
final field = singleSelectFieldContext().field;
|
||||
return GridFieldCellContext(gridId: gridView.id, field: field);
|
||||
}
|
||||
|
||||
Future<void> createTestGrid() async {
|
||||
final app = await _inner.createTestApp();
|
||||
final builder = GridPluginBuilder();
|
||||
@ -32,13 +62,63 @@ class AppFlowyGridTest {
|
||||
pluginType: builder.pluginType,
|
||||
layoutType: builder.layoutType!,
|
||||
);
|
||||
result.fold(
|
||||
(view) => gridView = view,
|
||||
await result.fold(
|
||||
(view) async {
|
||||
gridView = view;
|
||||
_dataController = GridDataController(view: view);
|
||||
final result = await _dataController.loadData();
|
||||
result.fold((l) => null, (r) => throw Exception(r));
|
||||
},
|
||||
(error) {},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new Grid for cell test
|
||||
class AppFlowyGridCellTest {
|
||||
final AppFlowyGridTest _gridTest;
|
||||
AppFlowyGridCellTest(AppFlowyGridTest gridTest) : _gridTest = gridTest;
|
||||
|
||||
static Future<AppFlowyGridCellTest> ensureInitialized() async {
|
||||
final gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
return AppFlowyGridCellTest(gridTest);
|
||||
}
|
||||
|
||||
Future<void> createTestRow() async {
|
||||
await _gridTest.createRow();
|
||||
}
|
||||
|
||||
Future<void> createTestGrid() async {
|
||||
await _gridTest.createTestGrid();
|
||||
}
|
||||
|
||||
Future<GridCellControllerBuilder> cellControllerBuilder(
|
||||
String fieldId,
|
||||
) async {
|
||||
final RowInfo rowInfo = _gridTest.rowInfos.last;
|
||||
final blockCache = _gridTest.blocks[rowInfo.rowPB.blockId];
|
||||
final rowCache = blockCache?.rowCache;
|
||||
|
||||
final rowDataController = GridRowDataController(
|
||||
rowInfo: rowInfo,
|
||||
fieldController: _gridTest._dataController.fieldController,
|
||||
rowCache: rowCache!,
|
||||
);
|
||||
|
||||
final rowBloc = RowBloc(
|
||||
rowInfo: rowInfo,
|
||||
dataController: rowDataController,
|
||||
)..add(const RowEvent.initial());
|
||||
await gridResponseFuture();
|
||||
|
||||
return GridCellControllerBuilder(
|
||||
cellId: rowBloc.state.gridCellMap[fieldId]!,
|
||||
cellCache: rowCache.cellCache,
|
||||
delegate: rowDataController,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AppFlowyGridSelectOptionCellTest {
|
||||
final AppFlowyGridCellTest _gridCellTest;
|
||||
|
||||
@ -63,8 +143,7 @@ class AppFlowyGridSelectOptionCellTest {
|
||||
assert(fieldType == FieldType.SingleSelect ||
|
||||
fieldType == FieldType.MultiSelect);
|
||||
|
||||
final fieldContexts =
|
||||
_gridCellTest._dataController.fieldController.fieldContexts;
|
||||
final fieldContexts = _gridCellTest._gridTest.fieldContexts;
|
||||
final field =
|
||||
fieldContexts.firstWhere((element) => element.fieldType == fieldType);
|
||||
final builder = await _gridCellTest.cellControllerBuilder(field.id);
|
||||
@ -73,55 +152,6 @@ class AppFlowyGridSelectOptionCellTest {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new Grid for cell test
|
||||
class AppFlowyGridCellTest {
|
||||
final AppFlowyGridTest _gridTest;
|
||||
late GridDataController _dataController;
|
||||
AppFlowyGridCellTest(AppFlowyGridTest gridTest) : _gridTest = gridTest;
|
||||
|
||||
static Future<AppFlowyGridCellTest> ensureInitialized() async {
|
||||
final gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
return AppFlowyGridCellTest(gridTest);
|
||||
}
|
||||
|
||||
Future<void> createTestRow() async {
|
||||
await _dataController.createRow();
|
||||
}
|
||||
|
||||
Future<void> createTestGrid() async {
|
||||
await _gridTest.createTestGrid();
|
||||
_dataController = GridDataController(view: _gridTest.gridView);
|
||||
final result = await _dataController.loadData();
|
||||
result.fold((l) => null, (r) => throw Exception(r));
|
||||
}
|
||||
|
||||
Future<GridCellControllerBuilder> cellControllerBuilder(
|
||||
String fieldId,
|
||||
) async {
|
||||
final RowInfo rowInfo = _dataController.rowInfos.last;
|
||||
final blockCache = _dataController.blocks[rowInfo.rowPB.blockId];
|
||||
final rowCache = blockCache?.rowCache;
|
||||
|
||||
final rowDataController = GridRowDataController(
|
||||
rowInfo: rowInfo,
|
||||
fieldController: _dataController.fieldController,
|
||||
rowCache: rowCache!,
|
||||
);
|
||||
|
||||
final rowBloc = RowBloc(
|
||||
rowInfo: rowInfo,
|
||||
dataController: rowDataController,
|
||||
)..add(const RowEvent.initial());
|
||||
await gridResponseFuture();
|
||||
|
||||
return GridCellControllerBuilder(
|
||||
cellId: rowBloc.state.gridCellMap[fieldId]!,
|
||||
cellCache: rowCache.cellCache,
|
||||
delegate: rowDataController,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> gridResponseFuture() {
|
||||
return Future.delayed(gridResponseDuration(milliseconds: 200));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user