mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
test: add database event tests (#2744)
* chore: add tests * test: add tests * test: add tests
This commit is contained in:
parent
0f9f5251f2
commit
e9be37a961
@ -47,7 +47,7 @@ class DateCellDataPersistence implements CellDataPersistence<DateCellData> {
|
||||
@override
|
||||
Future<Option<FlowyError>> save(DateCellData data) {
|
||||
final payload = DateChangesetPB.create()
|
||||
..cellPath = _makeCellPath(cellContext);
|
||||
..cellId = _makeCellPath(cellContext);
|
||||
if (data.dateTime != null) {
|
||||
final date = (data.dateTime!.millisecondsSinceEpoch ~/ 1000).toString();
|
||||
payload.date = date;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/group.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
@ -10,12 +9,10 @@ class GroupBackendService {
|
||||
|
||||
Future<Either<Unit, FlowyError>> groupByField({
|
||||
required String fieldId,
|
||||
required FieldType fieldType,
|
||||
}) {
|
||||
final payload = GroupByFieldPayloadPB.create()
|
||||
..viewId = viewId
|
||||
..fieldId = fieldId
|
||||
..fieldType = fieldType;
|
||||
..fieldId = fieldId;
|
||||
|
||||
return DatabaseEventSetGroupByField(payload).send();
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ class DatabaseGroupBloc extends Bloc<DatabaseGroupEvent, DatabaseGroupState> {
|
||||
setGroupByField: (String fieldId, FieldType fieldType) async {
|
||||
final result = await _groupBackendSvc.groupByField(
|
||||
fieldId: fieldId,
|
||||
fieldType: fieldType,
|
||||
);
|
||||
result.fold((l) => null, (err) => Log.error(err));
|
||||
},
|
||||
|
@ -230,7 +230,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
for (final group in updatedGroups) {
|
||||
final columnController =
|
||||
boardController.getGroupController(group.groupId);
|
||||
columnController?.updateGroupName(group.desc);
|
||||
columnController?.updateGroupName(group.groupName);
|
||||
}
|
||||
},
|
||||
);
|
||||
@ -285,7 +285,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
AppFlowyGroupData initializeGroupData(GroupPB group) {
|
||||
return AppFlowyGroupData(
|
||||
id: group.groupId,
|
||||
name: group.desc,
|
||||
name: group.groupName,
|
||||
items: _buildGroupItems(group),
|
||||
customData: GroupData(
|
||||
group: group,
|
||||
|
@ -285,10 +285,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: csslib
|
||||
sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f"
|
||||
sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.17.3"
|
||||
version: "1.0.0"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -648,10 +648,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: html
|
||||
sha256: "58e3491f7bf0b6a4ea5110c0c688877460d1a6366731155c4a4580e7ded773e8"
|
||||
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.15.3"
|
||||
version: "0.15.4"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -48,8 +48,9 @@ void main() {
|
||||
);
|
||||
final expectedGroupName = "No ${multiSelectField.name}";
|
||||
assert(
|
||||
boardBloc.groupControllers.values.first.group.desc == expectedGroupName,
|
||||
"Expected $expectedGroupName, but receive ${boardBloc.groupControllers.values.first.group.desc}",
|
||||
boardBloc.groupControllers.values.first.group.groupName ==
|
||||
expectedGroupName,
|
||||
"Expected $expectedGroupName, but receive ${boardBloc.groupControllers.values.first.group.groupName}",
|
||||
);
|
||||
});
|
||||
|
||||
@ -101,8 +102,8 @@ void main() {
|
||||
|
||||
final groups =
|
||||
boardBloc.groupControllers.values.map((e) => e.group).toList();
|
||||
assert(groups[0].desc == "No ${multiSelectField.name}");
|
||||
assert(groups[1].desc == "B");
|
||||
assert(groups[2].desc == "A");
|
||||
assert(groups[0].groupName == "No ${multiSelectField.name}");
|
||||
assert(groups[1].groupName == "B");
|
||||
assert(groups[2].groupName == "A");
|
||||
});
|
||||
}
|
||||
|
20
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
20
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
@ -99,7 +99,7 @@ checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
||||
[[package]]
|
||||
name = "appflowy-integrate"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -1024,7 +1024,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -1042,7 +1042,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-client-ws"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab-sync",
|
||||
@ -1060,7 +1060,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-database"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -1086,7 +1086,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1098,7 +1098,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-document"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -1115,7 +1115,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-folder"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -1135,7 +1135,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-persistence"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
@ -1155,7 +1155,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-plugins"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -1186,7 +1186,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-sync"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab",
|
||||
|
@ -34,12 +34,12 @@ default = ["custom-protocol"]
|
||||
custom-protocol = ["tauri/custom-protocol"]
|
||||
|
||||
[patch.crates-io]
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
||||
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||
|
||||
#collab = { path = "../../AppFlowy-Collab/collab" }
|
||||
#collab-folder = { path = "../../AppFlowy-Collab/collab-folder" }
|
||||
|
@ -24,7 +24,7 @@ export class DateCellDataPersistence extends CellDataPersistence<CalendarData> {
|
||||
}
|
||||
|
||||
save(data: CalendarData): Promise<Result<void, FlowyError>> {
|
||||
const payload = DateChangesetPB.fromObject({ cell_path: _makeCellPath(this.cellIdentifier) });
|
||||
const payload = DateChangesetPB.fromObject({ cell_id: _makeCellId(this.cellIdentifier) });
|
||||
payload.date = ((data.date.getTime() / 1000) | 0).toString();
|
||||
if (data.time !== undefined) {
|
||||
payload.time = data.time;
|
||||
@ -34,7 +34,7 @@ export class DateCellDataPersistence extends CellDataPersistence<CalendarData> {
|
||||
}
|
||||
}
|
||||
|
||||
function _makeCellPath(cellIdentifier: CellIdentifier): CellIdPB {
|
||||
function _makeCellId(cellIdentifier: CellIdentifier): CellIdPB {
|
||||
return CellIdPB.fromObject({
|
||||
view_id: cellIdentifier.viewId,
|
||||
field_id: cellIdentifier.fieldId,
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { DatabaseNotification, FlowyError, GroupPB, GroupRowsNotificationPB, RowPB } from "@/services/backend";
|
||||
import { ChangeNotifier } from "$app/utils/change_notifier";
|
||||
import { None, Ok, Option, Result, Some } from "ts-results";
|
||||
import { DatabaseNotificationObserver } from "../notifications/observer";
|
||||
import { Log } from "$app/utils/log";
|
||||
import { DatabaseBackendService } from "../database_bd_svc";
|
||||
import { DatabaseNotification, FlowyError, GroupPB, GroupRowsNotificationPB, RowPB } from '@/services/backend';
|
||||
import { ChangeNotifier } from '$app/utils/change_notifier';
|
||||
import { None, Ok, Option, Result, Some } from 'ts-results';
|
||||
import { DatabaseNotificationObserver } from '../notifications/observer';
|
||||
import { Log } from '$app/utils/log';
|
||||
import { DatabaseBackendService } from '../database_bd_svc';
|
||||
|
||||
export type GroupDataCallbacks = {
|
||||
onRemoveRow: (groupId: string, rowId: string) => void;
|
||||
@ -30,7 +30,7 @@ export class DatabaseGroupController {
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.group.desc;
|
||||
return this.group.group_name;
|
||||
}
|
||||
|
||||
updateGroup = (group: GroupPB) => {
|
||||
@ -83,7 +83,7 @@ export class DatabaseGroupController {
|
||||
} else {
|
||||
Log.error(result.val);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@ -111,8 +111,7 @@ class GroupDataObserver {
|
||||
private notifier?: ChangeNotifier<Result<GroupRowsNotificationPB, FlowyError>>;
|
||||
private listener?: DatabaseNotificationObserver;
|
||||
|
||||
constructor(public readonly groupId: string) {
|
||||
}
|
||||
constructor(public readonly groupId: string) {}
|
||||
|
||||
subscribe = async (callbacks: { onRowsChanged: GroupRowsSubscribeCallback }) => {
|
||||
this.notifier = new ChangeNotifier();
|
||||
@ -132,7 +131,7 @@ class GroupDataObserver {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
await this.listener.start();
|
||||
};
|
||||
|
20
frontend/rust-lib/Cargo.lock
generated
20
frontend/rust-lib/Cargo.lock
generated
@ -85,7 +85,7 @@ checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
|
||||
[[package]]
|
||||
name = "appflowy-integrate"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -887,7 +887,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -905,7 +905,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-client-ws"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab-sync",
|
||||
@ -923,7 +923,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-database"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -949,7 +949,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -961,7 +961,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-document"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -978,7 +978,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-folder"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -998,7 +998,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-persistence"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
@ -1018,7 +1018,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-plugins"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -1049,7 +1049,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-sync"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab",
|
||||
|
@ -33,11 +33,11 @@ opt-level = 3
|
||||
incremental = false
|
||||
|
||||
[patch.crates-io]
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||
|
||||
#collab = { path = "../AppFlowy-Collab/collab" }
|
||||
#collab-folder = { path = "../AppFlowy-Collab/collab-folder" }
|
||||
|
@ -80,17 +80,11 @@ impl std::convert::From<CalendarLayout> for CalendarLayoutPB {
|
||||
pub struct CalendarEventRequestPB {
|
||||
#[pb(index = 1)]
|
||||
pub view_id: String,
|
||||
|
||||
// Currently, requesting the events within the specified month
|
||||
// is not supported
|
||||
#[pb(index = 2)]
|
||||
pub month: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct CalendarEventRequestParams {
|
||||
pub view_id: String,
|
||||
pub month: String,
|
||||
}
|
||||
|
||||
impl TryInto<CalendarEventRequestParams> for CalendarEventRequestPB {
|
||||
@ -98,10 +92,7 @@ impl TryInto<CalendarEventRequestParams> for CalendarEventRequestPB {
|
||||
|
||||
fn try_into(self) -> Result<CalendarEventRequestParams, Self::Error> {
|
||||
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::ViewIdIsInvalid)?;
|
||||
Ok(CalendarEventRequestParams {
|
||||
view_id: view_id.0,
|
||||
month: self.month,
|
||||
})
|
||||
Ok(CalendarEventRequestParams { view_id: view_id.0 })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,11 +135,13 @@ impl TryInto<MoveRowParams> for MoveRowPayloadPB {
|
||||
|
||||
fn try_into(self) -> Result<MoveRowParams, Self::Error> {
|
||||
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseViewIdIsEmpty)?;
|
||||
let from_row_id = NotEmptyStr::parse(self.from_row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
|
||||
let to_row_id = NotEmptyStr::parse(self.to_row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
|
||||
|
||||
Ok(MoveRowParams {
|
||||
view_id: view_id.0,
|
||||
from_row_id: RowId::from(self.from_row_id),
|
||||
to_row_id: RowId::from(self.to_row_id),
|
||||
from_row_id: RowId::from(from_row_id.0),
|
||||
to_row_id: RowId::from(to_row_id.0),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ pub struct GroupPB {
|
||||
pub group_id: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub desc: String,
|
||||
pub group_name: String,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub rows: Vec<RowPB>,
|
||||
@ -93,7 +93,7 @@ impl std::convert::From<GroupData> for GroupPB {
|
||||
Self {
|
||||
field_id: group_data.field_id,
|
||||
group_id: group_data.id,
|
||||
desc: group_data.name,
|
||||
group_name: group_data.name,
|
||||
rows: group_data.rows.into_iter().map(RowPB::from).collect(),
|
||||
is_default: group_data.is_default,
|
||||
is_visible: group_data.is_visible,
|
||||
@ -108,9 +108,6 @@ pub struct GroupByFieldPayloadPB {
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub view_id: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub field_type: FieldType,
|
||||
}
|
||||
|
||||
impl TryInto<GroupByFieldParams> for GroupByFieldPayloadPB {
|
||||
@ -124,18 +121,13 @@ impl TryInto<GroupByFieldParams> for GroupByFieldPayloadPB {
|
||||
.map_err(|_| ErrorCode::ViewIdIsInvalid)?
|
||||
.0;
|
||||
|
||||
Ok(GroupByFieldParams {
|
||||
field_id,
|
||||
view_id,
|
||||
field_type: self.field_type,
|
||||
})
|
||||
Ok(GroupByFieldParams { field_id, view_id })
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GroupByFieldParams {
|
||||
pub field_id: String,
|
||||
pub view_id: String,
|
||||
pub field_type: FieldType,
|
||||
}
|
||||
|
||||
pub struct DeleteGroupParams {
|
||||
|
@ -158,6 +158,7 @@ impl TryInto<RowIdParams> for RowIdPB {
|
||||
|
||||
fn try_into(self) -> Result<RowIdParams, Self::Error> {
|
||||
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
|
||||
let row_id = NotEmptyStr::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
|
||||
let group_id = match self.group_id {
|
||||
Some(group_id) => Some(
|
||||
NotEmptyStr::parse(group_id)
|
||||
@ -169,7 +170,7 @@ impl TryInto<RowIdParams> for RowIdPB {
|
||||
|
||||
Ok(RowIdParams {
|
||||
view_id: view_id.0,
|
||||
row_id: RowId::from(self.row_id),
|
||||
row_id: RowId::from(row_id.0),
|
||||
group_id,
|
||||
})
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
use collab_database::rows::RowId;
|
||||
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::{ErrorCode, FlowyError};
|
||||
|
||||
use crate::entities::parser::NotEmptyStr;
|
||||
use crate::entities::SelectOptionPB;
|
||||
use crate::services::field::checklist_type_option::ChecklistCellData;
|
||||
|
||||
use crate::services::field::SelectOption;
|
||||
use collab_database::rows::RowId;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::{ErrorCode, FlowyError};
|
||||
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct ChecklistCellDataPB {
|
||||
@ -16,7 +17,7 @@ pub struct ChecklistCellDataPB {
|
||||
pub selected_options: Vec<SelectOptionPB>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub(crate) percentage: f64,
|
||||
pub percentage: f64,
|
||||
}
|
||||
|
||||
impl From<ChecklistCellData> for ChecklistCellDataPB {
|
||||
|
@ -25,7 +25,7 @@ pub struct DateCellDataPB {
|
||||
#[derive(Clone, Debug, Default, ProtoBuf)]
|
||||
pub struct DateChangesetPB {
|
||||
#[pb(index = 1)]
|
||||
pub cell_path: CellIdPB,
|
||||
pub cell_id: CellIdPB,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub date: Option<String>,
|
||||
|
@ -294,7 +294,9 @@ pub(crate) async fn get_row_handler(
|
||||
) -> DataResult<OptionalRowPB, FlowyError> {
|
||||
let params: RowIdParams = data.into_inner().try_into()?;
|
||||
let database_editor = manager.get_database_with_view_id(¶ms.view_id).await?;
|
||||
let row = database_editor.get_row(¶ms.row_id).map(RowPB::from);
|
||||
let row = database_editor
|
||||
.get_row(¶ms.view_id, ¶ms.row_id)
|
||||
.map(RowPB::from);
|
||||
data_result_ok(OptionalRowPB { row })
|
||||
}
|
||||
|
||||
@ -525,7 +527,7 @@ pub(crate) async fn update_date_cell_handler(
|
||||
manager: AFPluginState<Arc<DatabaseManager2>>,
|
||||
) -> Result<(), FlowyError> {
|
||||
let data = data.into_inner();
|
||||
let cell_id: CellIdParams = data.cell_path.try_into()?;
|
||||
let cell_id: CellIdParams = data.cell_id.try_into()?;
|
||||
let cell_changeset = DateCellChangeset {
|
||||
date: data.date,
|
||||
time: data.time,
|
||||
|
@ -496,8 +496,12 @@ impl DatabaseEditor {
|
||||
Ok(view_editor.v_get_rows().await)
|
||||
}
|
||||
|
||||
pub fn get_row(&self, row_id: &RowId) -> Option<Row> {
|
||||
self.database.lock().get_row(row_id)
|
||||
pub fn get_row(&self, view_id: &str, row_id: &RowId) -> Option<Row> {
|
||||
if self.database.lock().views.is_row_exist(view_id, row_id) {
|
||||
return None;
|
||||
} else {
|
||||
self.database.lock().get_row(row_id)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn delete_row(&self, row_id: &RowId) {
|
||||
@ -832,6 +836,11 @@ impl DatabaseEditor {
|
||||
from_group: &str,
|
||||
to_group: &str,
|
||||
) -> FlowyResult<()> {
|
||||
// Do nothing if the group is the same
|
||||
if from_group == to_group {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let view = self.database_views.get_view_editor(view_id).await?;
|
||||
view.v_move_group(from_group, to_group).await?;
|
||||
Ok(())
|
||||
|
@ -375,6 +375,7 @@ impl DatabaseViewEditor {
|
||||
.as_ref()?
|
||||
.groups()
|
||||
.into_iter()
|
||||
.filter(|group| group.is_visible)
|
||||
.map(|group_data| GroupPB::from(group_data.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
tracing::trace!("Number of groups: {}", groups.len());
|
||||
|
@ -351,15 +351,21 @@ where
|
||||
}
|
||||
|
||||
pub(crate) fn update_group(&mut self, group_changeset: GroupChangeset) -> FlowyResult<()> {
|
||||
self.mut_group(&group_changeset.group_id, |group| {
|
||||
let update_group = self.mut_group(&group_changeset.group_id, |group| {
|
||||
if let Some(visible) = group_changeset.visible {
|
||||
group.visible = visible;
|
||||
}
|
||||
|
||||
if let Some(name) = &group_changeset.name {
|
||||
group.name = name.clone();
|
||||
}
|
||||
})?;
|
||||
|
||||
if let Some(group) = update_group {
|
||||
self.group_by_id.get_mut(&group.id).map(|group_data| {
|
||||
group_data.name = group.name.clone();
|
||||
group_data.is_visible = group.visible;
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -370,6 +376,11 @@ where
|
||||
.await
|
||||
}
|
||||
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `mut_configuration_fn`: mutate the [GroupSetting] and return whether the [GroupSetting] is
|
||||
/// changed. If the [GroupSetting] is changed, the [GroupSetting] will be saved to the storage.
|
||||
///
|
||||
fn mut_configuration(
|
||||
&mut self,
|
||||
mut_configuration_fn: impl FnOnce(&mut GroupSetting) -> bool,
|
||||
@ -392,7 +403,12 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mut_group(&mut self, group_id: &str, mut_groups_fn: impl Fn(&mut Group)) -> FlowyResult<()> {
|
||||
fn mut_group(
|
||||
&mut self,
|
||||
group_id: &str,
|
||||
mut_groups_fn: impl Fn(&mut Group),
|
||||
) -> FlowyResult<Option<Group>> {
|
||||
let mut updated_group = None;
|
||||
self.mut_configuration(|configuration| {
|
||||
match configuration
|
||||
.groups
|
||||
@ -402,10 +418,12 @@ where
|
||||
None => false,
|
||||
Some(group) => {
|
||||
mut_groups_fn(group);
|
||||
updated_group = Some(group.clone());
|
||||
true
|
||||
},
|
||||
}
|
||||
})
|
||||
})?;
|
||||
Ok(updated_group)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use collab_database::database::gen_row_id;
|
||||
use collab_database::fields::Field;
|
||||
use collab_database::rows::{CreateRowParams, RowId};
|
||||
|
||||
use flowy_database2::entities::{FieldType, GroupPB, RowPB};
|
||||
use flowy_database2::services::cell::{
|
||||
delete_select_option_cell, insert_select_option_cell, insert_url_cell,
|
||||
@ -233,7 +234,7 @@ impl DatabaseGroupTest {
|
||||
} => {
|
||||
let group = self.group_at_index(group_index).await;
|
||||
assert_eq!(group.group_id, group_pb.group_id);
|
||||
assert_eq!(group.desc, group_pb.desc);
|
||||
assert_eq!(group.group_name, group_pb.group_name);
|
||||
},
|
||||
GroupScript::UpdateSingleSelectSelectOption { inserted_options } => {
|
||||
self
|
||||
|
@ -463,7 +463,7 @@ async fn group_insert_single_select_option_test() {
|
||||
];
|
||||
test.run_scripts(scripts).await;
|
||||
let new_group = test.group_at_index(1).await;
|
||||
assert_eq!(new_group.desc, new_option_name);
|
||||
assert_eq!(new_group.group_name, new_option_name);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -1,3 +1,5 @@
|
||||
use bytes::Bytes;
|
||||
use std::convert::TryFrom;
|
||||
use std::env::temp_dir;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -132,6 +134,49 @@ impl FlowyCoreTest {
|
||||
.parse::<flowy_folder2::entities::ViewPB>()
|
||||
}
|
||||
|
||||
pub async fn create_board(&self, parent_id: &str, name: String, initial_data: Vec<u8>) -> ViewPB {
|
||||
let payload = CreateViewPayloadPB {
|
||||
parent_view_id: parent_id.to_string(),
|
||||
name,
|
||||
desc: "".to_string(),
|
||||
thumbnail: None,
|
||||
layout: ViewLayoutPB::Board,
|
||||
initial_data,
|
||||
meta: Default::default(),
|
||||
set_as_current: true,
|
||||
};
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::CreateView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::ViewPB>()
|
||||
}
|
||||
|
||||
pub async fn create_calendar(
|
||||
&self,
|
||||
parent_id: &str,
|
||||
name: String,
|
||||
initial_data: Vec<u8>,
|
||||
) -> ViewPB {
|
||||
let payload = CreateViewPayloadPB {
|
||||
parent_view_id: parent_id.to_string(),
|
||||
name,
|
||||
desc: "".to_string(),
|
||||
thumbnail: None,
|
||||
layout: ViewLayoutPB::Calendar,
|
||||
initial_data,
|
||||
meta: Default::default(),
|
||||
set_as_current: true,
|
||||
};
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::CreateView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::ViewPB>()
|
||||
}
|
||||
|
||||
pub async fn get_database(&self, view_id: &str) -> DatabasePB {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::GetDatabase)
|
||||
@ -238,7 +283,20 @@ impl FlowyCoreTest {
|
||||
.parse::<RowPB>()
|
||||
}
|
||||
|
||||
pub async fn get_row(&self, view_id: &str, row_id: &str) -> RowPB {
|
||||
pub async fn delete_row(&self, view_id: &str, row_id: &str) -> Option<FlowyError> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::DeleteRow)
|
||||
.payload(RowIdPB {
|
||||
view_id: view_id.to_string(),
|
||||
row_id: row_id.to_string(),
|
||||
group_id: None,
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.error()
|
||||
}
|
||||
|
||||
pub async fn get_row(&self, view_id: &str, row_id: &str) -> OptionalRowPB {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::GetRow)
|
||||
.payload(RowIdPB {
|
||||
@ -248,7 +306,7 @@ impl FlowyCoreTest {
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<RowPB>()
|
||||
.parse::<OptionalRowPB>()
|
||||
}
|
||||
|
||||
pub async fn duplicate_row(&self, view_id: &str, row_id: &str) -> Option<FlowyError> {
|
||||
@ -264,6 +322,19 @@ impl FlowyCoreTest {
|
||||
.error()
|
||||
}
|
||||
|
||||
pub async fn move_row(&self, view_id: &str, row_id: &str, to_row_id: &str) -> Option<FlowyError> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::MoveRow)
|
||||
.payload(MoveRowPayloadPB {
|
||||
view_id: view_id.to_string(),
|
||||
from_row_id: row_id.to_string(),
|
||||
to_row_id: to_row_id.to_string(),
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.error()
|
||||
}
|
||||
|
||||
pub async fn update_cell(&self, changeset: CellChangesetPB) -> Option<FlowyError> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::UpdateCell)
|
||||
@ -273,6 +344,15 @@ impl FlowyCoreTest {
|
||||
.error()
|
||||
}
|
||||
|
||||
pub async fn update_date_cell(&self, changeset: DateChangesetPB) -> Option<FlowyError> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::UpdateDateCell)
|
||||
.payload(changeset)
|
||||
.async_send()
|
||||
.await
|
||||
.error()
|
||||
}
|
||||
|
||||
pub async fn get_cell(&self, view_id: &str, row_id: &str, field_id: &str) -> CellPB {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::GetCell)
|
||||
@ -286,6 +366,41 @@ impl FlowyCoreTest {
|
||||
.parse::<CellPB>()
|
||||
}
|
||||
|
||||
pub async fn get_date_cell(&self, view_id: &str, row_id: &str, field_id: &str) -> DateCellDataPB {
|
||||
let cell = self.get_cell(view_id, row_id, field_id).await;
|
||||
DateCellDataPB::try_from(Bytes::from(cell.data)).unwrap()
|
||||
}
|
||||
|
||||
pub async fn get_checklist_cell(
|
||||
&self,
|
||||
view_id: &str,
|
||||
field_id: &str,
|
||||
row_id: &str,
|
||||
) -> ChecklistCellDataPB {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::GetChecklistCellData)
|
||||
.payload(CellIdPB {
|
||||
view_id: view_id.to_string(),
|
||||
row_id: row_id.to_string(),
|
||||
field_id: field_id.to_string(),
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<ChecklistCellDataPB>()
|
||||
}
|
||||
|
||||
pub async fn update_checklist_cell(
|
||||
&self,
|
||||
changeset: ChecklistCellDataChangesetPB,
|
||||
) -> Option<FlowyError> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::UpdateChecklistCell)
|
||||
.payload(changeset)
|
||||
.async_send()
|
||||
.await
|
||||
.error()
|
||||
}
|
||||
|
||||
pub async fn insert_option(
|
||||
&self,
|
||||
view_id: &str,
|
||||
@ -317,6 +432,84 @@ impl FlowyCoreTest {
|
||||
.error()
|
||||
}
|
||||
|
||||
pub async fn get_groups(&self, view_id: &str) -> Vec<GroupPB> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::GetGroups)
|
||||
.payload(DatabaseViewIdPB {
|
||||
value: view_id.to_string(),
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<RepeatedGroupPB>()
|
||||
.items
|
||||
}
|
||||
|
||||
pub async fn move_group(&self, view_id: &str, from_id: &str, to_id: &str) -> Option<FlowyError> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::MoveGroup)
|
||||
.payload(MoveGroupPayloadPB {
|
||||
view_id: view_id.to_string(),
|
||||
from_group_id: from_id.to_string(),
|
||||
to_group_id: to_id.to_string(),
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.error()
|
||||
}
|
||||
|
||||
pub async fn set_group_by_field(&self, view_id: &str, field_id: &str) -> Option<FlowyError> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::SetGroupByField)
|
||||
.payload(GroupByFieldPayloadPB {
|
||||
field_id: field_id.to_string(),
|
||||
view_id: view_id.to_string(),
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.error()
|
||||
}
|
||||
|
||||
pub async fn update_group(
|
||||
&self,
|
||||
view_id: &str,
|
||||
group_id: &str,
|
||||
name: Option<String>,
|
||||
visible: Option<bool>,
|
||||
) -> Option<FlowyError> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::UpdateGroup)
|
||||
.payload(UpdateGroupPB {
|
||||
view_id: view_id.to_string(),
|
||||
group_id: group_id.to_string(),
|
||||
name,
|
||||
visible,
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.error()
|
||||
}
|
||||
|
||||
pub async fn update_setting(&self, changeset: DatabaseSettingChangesetPB) -> Option<FlowyError> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::UpdateDatabaseSetting)
|
||||
.payload(changeset)
|
||||
.async_send()
|
||||
.await
|
||||
.error()
|
||||
}
|
||||
|
||||
pub async fn get_all_calendar_events(&self, view_id: &str) -> Vec<CalendarEventPB> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_database2::event_map::DatabaseEvent::GetAllCalendarEvents)
|
||||
.payload(CalendarEventRequestPB {
|
||||
view_id: view_id.to_string(),
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<RepeatedCalendarEventPB>()
|
||||
.items
|
||||
}
|
||||
|
||||
pub async fn get_view(&self, view_id: &str) -> ViewPB {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadView)
|
||||
|
@ -1,9 +1,11 @@
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use bytes::Bytes;
|
||||
use lib_infra::util::timestamp;
|
||||
|
||||
use flowy_database2::entities::{
|
||||
CellChangesetPB, DatabaseLayoutPB, DatabaseViewIdPB, FieldType, SelectOptionCellDataPB,
|
||||
CellChangesetPB, CellIdPB, ChecklistCellDataChangesetPB, DatabaseLayoutPB,
|
||||
DatabaseSettingChangesetPB, DatabaseViewIdPB, DateChangesetPB, FieldType, SelectOptionCellDataPB,
|
||||
};
|
||||
use flowy_test::event_builder::EventBuilder;
|
||||
use flowy_test::FlowyCoreTest;
|
||||
@ -93,6 +95,7 @@ async fn delete_field_event_test() {
|
||||
assert_eq!(fields.len(), 2);
|
||||
}
|
||||
|
||||
// The primary field is not allowed to be deleted.
|
||||
#[tokio::test]
|
||||
async fn delete_primary_field_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
@ -162,6 +165,7 @@ async fn duplicate_field_event_test() {
|
||||
assert_eq!(fields.len(), 4);
|
||||
}
|
||||
|
||||
// The primary field is not allowed to be duplicated. So this test should return an error.
|
||||
#[tokio::test]
|
||||
async fn duplicate_primary_field_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
@ -189,6 +193,40 @@ async fn create_row_event_test() {
|
||||
assert_eq!(database.rows.len(), 4);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn delete_row_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let grid_view = test
|
||||
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||
.await;
|
||||
|
||||
// delete the row
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
let error = test.delete_row(&grid_view.id, &database.rows[0].id).await;
|
||||
assert!(error.is_none());
|
||||
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
assert_eq!(database.rows.len(), 2);
|
||||
|
||||
// get the row again and check if it is deleted.
|
||||
let optional_row = test.get_row(&grid_view.id, &database.rows[0].id).await;
|
||||
assert!(optional_row.row.is_none());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn delete_row_event_with_invalid_row_id_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let grid_view = test
|
||||
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||
.await;
|
||||
|
||||
// delete the row with empty row_id. It should return an error.
|
||||
let error = test.delete_row(&grid_view.id, "").await;
|
||||
assert!(error.is_some());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn duplicate_row_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
@ -206,6 +244,90 @@ async fn duplicate_row_event_test() {
|
||||
assert_eq!(database.rows.len(), 4);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn duplicate_row_event_with_invalid_row_id_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let grid_view = test
|
||||
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||
.await;
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
assert_eq!(database.rows.len(), 3);
|
||||
|
||||
let error = test.duplicate_row(&grid_view.id, "").await;
|
||||
assert!(error.is_some());
|
||||
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
assert_eq!(database.rows.len(), 3);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn move_row_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let grid_view = test
|
||||
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||
.await;
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
let row_1 = database.rows[0].id.clone();
|
||||
let row_2 = database.rows[1].id.clone();
|
||||
let row_3 = database.rows[2].id.clone();
|
||||
let error = test.move_row(&grid_view.id, &row_1, &row_3).await;
|
||||
assert!(error.is_none());
|
||||
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
assert_eq!(database.rows[0].id, row_2);
|
||||
assert_eq!(database.rows[1].id, row_3);
|
||||
assert_eq!(database.rows[2].id, row_1);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn move_row_event_test2() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let grid_view = test
|
||||
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||
.await;
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
let row_1 = database.rows[0].id.clone();
|
||||
let row_2 = database.rows[1].id.clone();
|
||||
let row_3 = database.rows[2].id.clone();
|
||||
let error = test.move_row(&grid_view.id, &row_2, &row_1).await;
|
||||
assert!(error.is_none());
|
||||
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
assert_eq!(database.rows[0].id, row_2);
|
||||
assert_eq!(database.rows[1].id, row_1);
|
||||
assert_eq!(database.rows[2].id, row_3);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn move_row_event_with_invalid_row_id_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let grid_view = test
|
||||
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||
.await;
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
let row_1 = database.rows[0].id.clone();
|
||||
let row_2 = database.rows[1].id.clone();
|
||||
let row_3 = database.rows[2].id.clone();
|
||||
|
||||
for i in 0..2 {
|
||||
if i == 0 {
|
||||
let error = test.move_row(&grid_view.id, &row_1, "").await;
|
||||
assert!(error.is_some());
|
||||
} else {
|
||||
let error = test.move_row(&grid_view.id, "", &row_1).await;
|
||||
assert!(error.is_some());
|
||||
}
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
assert_eq!(database.rows[0].id, row_1);
|
||||
assert_eq!(database.rows[1].id, row_2);
|
||||
assert_eq!(database.rows[2].id, row_3);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_text_cell_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
@ -280,14 +402,415 @@ async fn update_single_select_cell_event_test() {
|
||||
let field_id = fields[1].id.clone();
|
||||
assert_eq!(fields[1].field_type, FieldType::SingleSelect);
|
||||
|
||||
// Insert a new option. This should update the cell with the new option.
|
||||
let error = test
|
||||
.insert_option(&grid_view.id, &field_id, &row_id, "task 1")
|
||||
.await;
|
||||
assert!(error.is_none());
|
||||
|
||||
// Check that the cell data is updated.
|
||||
let cell = test.get_cell(&grid_view.id, &row_id, &field_id).await;
|
||||
let select_option_cell = SelectOptionCellDataPB::try_from(Bytes::from(cell.data)).unwrap();
|
||||
|
||||
assert_eq!(select_option_cell.options.len(), 1);
|
||||
assert_eq!(select_option_cell.select_options.len(), 1);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_date_cell_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let grid_view = test
|
||||
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||
.await;
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
|
||||
// Create a date field
|
||||
let date_field = test.create_field(&grid_view.id, FieldType::DateTime).await;
|
||||
|
||||
let cell_path = CellIdPB {
|
||||
view_id: grid_view.id.clone(),
|
||||
field_id: date_field.id.clone(),
|
||||
row_id: database.rows[0].id.clone(),
|
||||
};
|
||||
|
||||
// Insert data into the date cell of the first row.
|
||||
let timestamp = 1686300557;
|
||||
let timestamp_str = 1686300557.to_string();
|
||||
let error = test
|
||||
.update_date_cell(DateChangesetPB {
|
||||
cell_id: cell_path,
|
||||
date: Some(timestamp_str.clone()),
|
||||
time: None,
|
||||
include_time: None,
|
||||
})
|
||||
.await;
|
||||
assert!(error.is_none());
|
||||
|
||||
// Check that the cell data is updated.
|
||||
let cell = test
|
||||
.get_date_cell(&grid_view.id, &database.rows[0].id, &date_field.id)
|
||||
.await;
|
||||
assert_eq!(cell.date, "Jun 09, 2023");
|
||||
assert_eq!(cell.timestamp, timestamp);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_date_cell_event_with_empty_time_str_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let grid_view = test
|
||||
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||
.await;
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
let row_id = database.rows[0].id.clone();
|
||||
|
||||
// Create a date field
|
||||
let date_field = test.create_field(&grid_view.id, FieldType::DateTime).await;
|
||||
let cell_path = CellIdPB {
|
||||
view_id: grid_view.id.clone(),
|
||||
field_id: date_field.id.clone(),
|
||||
row_id: row_id.clone(),
|
||||
};
|
||||
|
||||
// Insert empty timestamp string
|
||||
let error = test
|
||||
.update_date_cell(DateChangesetPB {
|
||||
cell_id: cell_path,
|
||||
date: Some("".to_string()),
|
||||
..Default::default()
|
||||
})
|
||||
.await;
|
||||
assert!(error.is_none());
|
||||
|
||||
// Check that the cell data is updated.
|
||||
let cell = test
|
||||
.get_date_cell(&grid_view.id, &row_id, &date_field.id)
|
||||
.await;
|
||||
assert_eq!(cell.date, "");
|
||||
assert_eq!(cell.timestamp, 0);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_checklist_field_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let grid_view = test
|
||||
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||
.await;
|
||||
|
||||
// create checklist field
|
||||
let checklist_field = test.create_field(&grid_view.id, FieldType::Checklist).await;
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
|
||||
// Get the checklist cell
|
||||
let cell = test
|
||||
.get_checklist_cell(&grid_view.id, &checklist_field.id, &database.rows[0].id)
|
||||
.await;
|
||||
assert_eq!(cell.options.len(), 0);
|
||||
assert_eq!(cell.selected_options.len(), 0);
|
||||
assert_eq!(cell.percentage, 0.0);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_checklist_cell_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let grid_view = test
|
||||
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||
.await;
|
||||
|
||||
// create checklist field
|
||||
let checklist_field = test.create_field(&grid_view.id, FieldType::Checklist).await;
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
|
||||
// update the checklist cell
|
||||
let changeset = ChecklistCellDataChangesetPB {
|
||||
view_id: grid_view.id.clone(),
|
||||
row_id: database.rows[0].id.clone(),
|
||||
field_id: checklist_field.id.clone(),
|
||||
insert_options: vec![
|
||||
"task 1".to_string(),
|
||||
"task 2".to_string(),
|
||||
"task 3".to_string(),
|
||||
],
|
||||
selected_option_ids: vec![],
|
||||
delete_option_ids: vec![],
|
||||
update_options: vec![],
|
||||
};
|
||||
test.update_checklist_cell(changeset).await;
|
||||
|
||||
// get the cell
|
||||
let cell = test
|
||||
.get_checklist_cell(&grid_view.id, &checklist_field.id, &database.rows[0].id)
|
||||
.await;
|
||||
|
||||
assert_eq!(cell.options.len(), 3);
|
||||
assert_eq!(cell.selected_options.len(), 0);
|
||||
|
||||
// select some options
|
||||
let changeset = ChecklistCellDataChangesetPB {
|
||||
view_id: grid_view.id.clone(),
|
||||
row_id: database.rows[0].id.clone(),
|
||||
field_id: checklist_field.id.clone(),
|
||||
selected_option_ids: vec![cell.options[0].id.clone(), cell.options[1].id.clone()],
|
||||
..Default::default()
|
||||
};
|
||||
test.update_checklist_cell(changeset).await;
|
||||
|
||||
// get the cell
|
||||
let cell = test
|
||||
.get_checklist_cell(&grid_view.id, &checklist_field.id, &database.rows[0].id)
|
||||
.await;
|
||||
|
||||
assert_eq!(cell.options.len(), 3);
|
||||
assert_eq!(cell.selected_options.len(), 2);
|
||||
assert_eq!(cell.percentage, 0.6666666666666666);
|
||||
}
|
||||
|
||||
// The number of groups should be 0 if there is no group by field in grid
|
||||
#[tokio::test]
|
||||
async fn get_groups_event_with_grid_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let grid_view = test
|
||||
.create_grid(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||
.await;
|
||||
|
||||
let groups = test.get_groups(&grid_view.id).await;
|
||||
assert_eq!(groups.len(), 0);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_groups_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let board_view = test
|
||||
.create_board(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||
.await;
|
||||
|
||||
let groups = test.get_groups(&board_view.id).await;
|
||||
assert_eq!(groups.len(), 4);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn move_group_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let board_view = test
|
||||
.create_board(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||
.await;
|
||||
|
||||
let groups = test.get_groups(&board_view.id).await;
|
||||
assert_eq!(groups.len(), 4);
|
||||
let group_1 = groups[0].group_id.clone();
|
||||
let group_2 = groups[1].group_id.clone();
|
||||
let group_3 = groups[2].group_id.clone();
|
||||
let group_4 = groups[3].group_id.clone();
|
||||
|
||||
let error = test.move_group(&board_view.id, &group_2, &group_3).await;
|
||||
assert!(error.is_none());
|
||||
|
||||
let groups = test.get_groups(&board_view.id).await;
|
||||
assert_eq!(groups[0].group_id, group_1);
|
||||
assert_eq!(groups[1].group_id, group_3);
|
||||
assert_eq!(groups[2].group_id, group_2);
|
||||
assert_eq!(groups[3].group_id, group_4);
|
||||
|
||||
let error = test.move_group(&board_view.id, &group_1, &group_4).await;
|
||||
assert!(error.is_none());
|
||||
|
||||
let groups = test.get_groups(&board_view.id).await;
|
||||
assert_eq!(groups[0].group_id, group_3);
|
||||
assert_eq!(groups[1].group_id, group_2);
|
||||
assert_eq!(groups[2].group_id, group_4);
|
||||
assert_eq!(groups[3].group_id, group_1);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn move_group_event_with_invalid_id_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let board_view = test
|
||||
.create_board(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||
.await;
|
||||
|
||||
// Empty to group id
|
||||
let groups = test.get_groups(&board_view.id).await;
|
||||
let error = test
|
||||
.move_group(&board_view.id, &groups[0].group_id, "")
|
||||
.await;
|
||||
assert!(error.is_some());
|
||||
|
||||
// empty from group id
|
||||
let error = test
|
||||
.move_group(&board_view.id, "", &groups[1].group_id)
|
||||
.await;
|
||||
assert!(error.is_some());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn rename_group_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let board_view = test
|
||||
.create_board(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||
.await;
|
||||
|
||||
// Empty to group id
|
||||
let groups = test.get_groups(&board_view.id).await;
|
||||
let error = test
|
||||
.update_group(
|
||||
&board_view.id,
|
||||
&groups[0].group_id,
|
||||
Some("new name".to_owned()),
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
assert!(error.is_none());
|
||||
|
||||
let groups = test.get_groups(&board_view.id).await;
|
||||
assert_eq!(groups[0].group_name, "new name".to_owned());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn hide_group_event_test2() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let board_view = test
|
||||
.create_board(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||
.await;
|
||||
|
||||
// Empty to group id
|
||||
let groups = test.get_groups(&board_view.id).await;
|
||||
assert_eq!(groups.len(), 4);
|
||||
|
||||
let error = test
|
||||
.update_group(&board_view.id, &groups[0].group_id, None, Some(false))
|
||||
.await;
|
||||
assert!(error.is_none());
|
||||
|
||||
let groups = test.get_groups(&board_view.id).await;
|
||||
assert_eq!(groups.len(), 3);
|
||||
}
|
||||
|
||||
// Update the database layout type from grid to board
|
||||
#[tokio::test]
|
||||
async fn update_database_layout_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let grid_view = test
|
||||
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||
.await;
|
||||
|
||||
let error = test
|
||||
.update_setting(DatabaseSettingChangesetPB {
|
||||
view_id: grid_view.id.clone(),
|
||||
layout_type: Some(DatabaseLayoutPB::Board),
|
||||
..Default::default()
|
||||
})
|
||||
.await;
|
||||
assert!(error.is_none());
|
||||
|
||||
let database = test.get_database(&grid_view.id).await;
|
||||
assert_eq!(database.layout_type, DatabaseLayoutPB::Board);
|
||||
}
|
||||
|
||||
// Update the database layout type from grid to board. Set the checkbox field as the grouping field
|
||||
#[tokio::test]
|
||||
async fn update_database_layout_event_test2() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let grid_view = test
|
||||
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||
.await;
|
||||
let fields = test.get_all_database_fields(&grid_view.id).await.items;
|
||||
|
||||
let checkbox_field = fields
|
||||
.iter()
|
||||
.find(|field| field.field_type == FieldType::Checkbox)
|
||||
.unwrap();
|
||||
test
|
||||
.set_group_by_field(&grid_view.id, &checkbox_field.id)
|
||||
.await;
|
||||
|
||||
let error = test
|
||||
.update_setting(DatabaseSettingChangesetPB {
|
||||
view_id: grid_view.id.clone(),
|
||||
layout_type: Some(DatabaseLayoutPB::Board),
|
||||
..Default::default()
|
||||
})
|
||||
.await;
|
||||
assert!(error.is_none());
|
||||
|
||||
// Empty to group id
|
||||
let groups = test.get_groups(&grid_view.id).await;
|
||||
assert_eq!(groups.len(), 2);
|
||||
}
|
||||
|
||||
// Create a checkbox field in the default board and then set it as the grouping field.
|
||||
#[tokio::test]
|
||||
async fn set_group_by_checkbox_field_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let board_view = test
|
||||
.create_board(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||
.await;
|
||||
|
||||
let checkbox_field = test.create_field(&board_view.id, FieldType::Checkbox).await;
|
||||
test
|
||||
.set_group_by_field(&board_view.id, &checkbox_field.id)
|
||||
.await;
|
||||
|
||||
let groups = test.get_groups(&board_view.id).await;
|
||||
assert_eq!(groups.len(), 2);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_all_calendar_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let calendar_view = test
|
||||
.create_calendar(¤t_workspace.id, "my calendar view".to_owned(), vec![])
|
||||
.await;
|
||||
|
||||
// By default, there should be no events
|
||||
let events = test.get_all_calendar_events(&calendar_view.id).await;
|
||||
assert!(events.is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_calendar_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let calendar_view = test
|
||||
.create_calendar(¤t_workspace.id, "my calendar view".to_owned(), vec![])
|
||||
.await;
|
||||
let fields = test.get_all_database_fields(&calendar_view.id).await.items;
|
||||
let date_field = fields
|
||||
.iter()
|
||||
.find(|field| field.field_type == FieldType::DateTime)
|
||||
.unwrap();
|
||||
|
||||
// create a new row
|
||||
let row = test.create_row(&calendar_view.id, None, None).await;
|
||||
|
||||
// Insert data into the date cell of the first row.
|
||||
let timestamp_str = timestamp().to_string();
|
||||
let error = test
|
||||
.update_date_cell(DateChangesetPB {
|
||||
cell_id: CellIdPB {
|
||||
view_id: calendar_view.id.clone(),
|
||||
field_id: date_field.id.clone(),
|
||||
row_id: row.id,
|
||||
},
|
||||
date: Some(timestamp_str.clone()),
|
||||
time: None,
|
||||
include_time: None,
|
||||
})
|
||||
.await;
|
||||
assert!(error.is_none());
|
||||
|
||||
let events = test.get_all_calendar_events(&calendar_view.id).await;
|
||||
assert_eq!(events.len(), 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user