mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
test: Folder event test (#2709)
* test: add event tests * test: add folder event test * ci: rust fmt
This commit is contained in:
parent
80a273edae
commit
4f2585baed
@ -109,13 +109,12 @@ class ViewBackendService {
|
||||
required int fromIndex,
|
||||
required int toIndex,
|
||||
}) {
|
||||
final payload = MoveFolderItemPayloadPB.create()
|
||||
..itemId = viewId
|
||||
final payload = MoveViewPayloadPB.create()
|
||||
..viewId = viewId
|
||||
..from = fromIndex
|
||||
..to = toIndex
|
||||
..ty = MoveFolderItemType.MoveView;
|
||||
..to = toIndex;
|
||||
|
||||
return FolderEventMoveItem(payload).send();
|
||||
return FolderEventMoveView(payload).send();
|
||||
}
|
||||
|
||||
Future<List<(ViewPB, List<ViewPB>)>> fetchViews(
|
||||
|
@ -5,12 +5,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart'
|
||||
show
|
||||
CreateViewPayloadPB,
|
||||
MoveFolderItemPayloadPB,
|
||||
MoveFolderItemType,
|
||||
ViewLayoutPB,
|
||||
ViewPB;
|
||||
show CreateViewPayloadPB, MoveViewPayloadPB, ViewLayoutPB, ViewPB;
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/workspace.pb.dart';
|
||||
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
@ -69,12 +64,11 @@ class WorkspaceService {
|
||||
required int fromIndex,
|
||||
required int toIndex,
|
||||
}) {
|
||||
final payload = MoveFolderItemPayloadPB.create()
|
||||
..itemId = appId
|
||||
final payload = MoveViewPayloadPB.create()
|
||||
..viewId = appId
|
||||
..from = fromIndex
|
||||
..to = toIndex
|
||||
..ty = MoveFolderItemType.MoveApp;
|
||||
..to = toIndex;
|
||||
|
||||
return FolderEventMoveItem(payload).send();
|
||||
return FolderEventMoveView(payload).send();
|
||||
}
|
||||
}
|
||||
|
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=13b178#13b17802de31e75255b4303914042bdbb04361b2"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab"
|
||||
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=13b178#13b17802de31e75255b4303914042bdbb04361b2"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab"
|
||||
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=13b178#13b17802de31e75255b4303914042bdbb04361b2"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab"
|
||||
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=13b178#13b17802de31e75255b4303914042bdbb04361b2"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab"
|
||||
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=13b178#13b17802de31e75255b4303914042bdbb04361b2"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab"
|
||||
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=13b178#13b17802de31e75255b4303914042bdbb04361b2"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab"
|
||||
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=13b178#13b17802de31e75255b4303914042bdbb04361b2"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -1134,7 +1134,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-persistence"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=13b178#13b17802de31e75255b4303914042bdbb04361b2"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
@ -1154,7 +1154,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-plugins"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=13b178#13b17802de31e75255b4303914042bdbb04361b2"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -1184,7 +1184,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-sync"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=13b178#13b17802de31e75255b4303914042bdbb04361b2"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cbc2e0#cbc2e0acb8420dc997921bb3f56b99f9975c2aab"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {
|
||||
FolderEventCreateView,
|
||||
FolderEventDeleteView,
|
||||
FolderEventMoveItem,
|
||||
FolderEventMoveView,
|
||||
FolderEventReadView,
|
||||
FolderEventUpdateView,
|
||||
ViewLayoutPB,
|
||||
@ -10,8 +10,7 @@ import {
|
||||
CreateViewPayloadPB,
|
||||
RepeatedViewIdPB,
|
||||
ViewPB,
|
||||
MoveFolderItemPayloadPB,
|
||||
MoveFolderItemType,
|
||||
MoveViewPayloadPB,
|
||||
FlowyError,
|
||||
ViewIdPB,
|
||||
UpdateViewPayloadPB,
|
||||
@ -95,13 +94,12 @@ export class AppBackendService {
|
||||
};
|
||||
|
||||
moveView = (params: { view_id: string; fromIndex: number; toIndex: number }) => {
|
||||
const payload = MoveFolderItemPayloadPB.fromObject({
|
||||
item_id: params.view_id,
|
||||
const payload = MoveViewPayloadPB.fromObject({
|
||||
view_id: params.view_id,
|
||||
from: params.fromIndex,
|
||||
to: params.toIndex,
|
||||
ty: MoveFolderItemType.MoveView,
|
||||
});
|
||||
|
||||
return FolderEventMoveItem(payload);
|
||||
return FolderEventMoveView(payload);
|
||||
};
|
||||
}
|
||||
|
@ -1,17 +1,11 @@
|
||||
import { Err, Ok } from 'ts-results';
|
||||
import {
|
||||
FolderEventCreateView,
|
||||
FolderEventMoveItem,
|
||||
FolderEventMoveView,
|
||||
FolderEventReadWorkspaceViews,
|
||||
FolderEventReadAllWorkspaces,
|
||||
} from '@/services/backend/events/flowy-folder2';
|
||||
import {
|
||||
CreateViewPayloadPB,
|
||||
FlowyError,
|
||||
MoveFolderItemPayloadPB,
|
||||
ViewLayoutPB,
|
||||
WorkspaceIdPB,
|
||||
} from '@/services/backend';
|
||||
import { CreateViewPayloadPB, FlowyError, MoveViewPayloadPB, ViewLayoutPB, WorkspaceIdPB } from '@/services/backend';
|
||||
import assert from 'assert';
|
||||
|
||||
export class WorkspaceBackendService {
|
||||
@ -56,11 +50,11 @@ export class WorkspaceBackendService {
|
||||
};
|
||||
|
||||
moveApp = (params: { appId: string; fromIndex: number; toIndex: number }) => {
|
||||
const payload = MoveFolderItemPayloadPB.fromObject({
|
||||
item_id: params.appId,
|
||||
const payload = MoveViewPayloadPB.fromObject({
|
||||
view_id: params.appId,
|
||||
from: params.fromIndex,
|
||||
to: params.toIndex,
|
||||
});
|
||||
return FolderEventMoveItem(payload);
|
||||
return FolderEventMoveView(payload);
|
||||
};
|
||||
}
|
||||
|
1
frontend/rust-lib/Cargo.lock
generated
1
frontend/rust-lib/Cargo.lock
generated
@ -1863,6 +1863,7 @@ dependencies = [
|
||||
"flowy-core",
|
||||
"flowy-folder2",
|
||||
"flowy-net",
|
||||
"flowy-notification",
|
||||
"flowy-server",
|
||||
"flowy-user",
|
||||
"futures-util",
|
||||
|
@ -57,14 +57,14 @@ pub fn view_pb_with_child_views(view: View, child_views: Vec<View>) -> ViewPB {
|
||||
#[derive(Eq, PartialEq, Hash, Debug, ProtoBuf_Enum, Clone)]
|
||||
pub enum ViewLayoutPB {
|
||||
Document = 0,
|
||||
Grid = 3,
|
||||
Board = 4,
|
||||
Calendar = 5,
|
||||
Grid = 1,
|
||||
Board = 2,
|
||||
Calendar = 3,
|
||||
}
|
||||
|
||||
impl std::default::Default for ViewLayoutPB {
|
||||
fn default() -> Self {
|
||||
ViewLayoutPB::Grid
|
||||
ViewLayoutPB::Document
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,50 +271,33 @@ impl TryInto<UpdateViewParams> for UpdateViewPayloadPB {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf_Enum)]
|
||||
pub enum MoveFolderItemType {
|
||||
MoveApp = 0,
|
||||
MoveView = 1,
|
||||
}
|
||||
|
||||
impl std::default::Default for MoveFolderItemType {
|
||||
fn default() -> Self {
|
||||
MoveFolderItemType::MoveApp
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, ProtoBuf)]
|
||||
pub struct MoveFolderItemPayloadPB {
|
||||
pub struct MoveViewPayloadPB {
|
||||
#[pb(index = 1)]
|
||||
pub item_id: String,
|
||||
pub view_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub from: i32,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub to: i32,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub ty: MoveFolderItemType,
|
||||
}
|
||||
|
||||
pub struct MoveViewParams {
|
||||
pub item_id: String,
|
||||
pub from: usize,
|
||||
pub to: usize,
|
||||
pub ty: MoveFolderItemType,
|
||||
}
|
||||
|
||||
impl TryInto<MoveViewParams> for MoveFolderItemPayloadPB {
|
||||
impl TryInto<MoveViewParams> for MoveViewPayloadPB {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<MoveViewParams, Self::Error> {
|
||||
let view_id = ViewIdentify::parse(self.item_id)?.0;
|
||||
let view_id = ViewIdentify::parse(self.view_id)?.0;
|
||||
Ok(MoveViewParams {
|
||||
item_id: view_id,
|
||||
from: self.from as usize,
|
||||
to: self.to as usize,
|
||||
ty: self.ty,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataRes
|
||||
|
||||
use crate::entities::{
|
||||
view_pb_without_child_views, CreateViewParams, CreateViewPayloadPB, CreateWorkspaceParams,
|
||||
CreateWorkspacePayloadPB, ImportPB, MoveFolderItemPayloadPB, MoveViewParams, RepeatedTrashIdPB,
|
||||
CreateWorkspacePayloadPB, ImportPB, MoveViewParams, MoveViewPayloadPB, RepeatedTrashIdPB,
|
||||
RepeatedTrashPB, RepeatedViewIdPB, RepeatedViewPB, RepeatedWorkspacePB, TrashIdPB,
|
||||
UpdateViewParams, UpdateViewPayloadPB, ViewIdPB, ViewPB, WorkspaceIdPB, WorkspacePB,
|
||||
WorkspaceSettingPB,
|
||||
@ -144,7 +144,7 @@ pub(crate) async fn close_view_handler(
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||
pub(crate) async fn move_view_handler(
|
||||
data: AFPluginData<MoveFolderItemPayloadPB>,
|
||||
data: AFPluginData<MoveViewPayloadPB>,
|
||||
folder: AFPluginState<Arc<Folder2Manager>>,
|
||||
) -> Result<(), FlowyError> {
|
||||
let params: MoveViewParams = data.into_inner().try_into()?;
|
||||
|
@ -26,7 +26,7 @@ pub fn init(folder: Arc<Folder2Manager>) -> AFPlugin {
|
||||
.event(FolderEvent::DuplicateView, duplicate_view_handler)
|
||||
.event(FolderEvent::SetLatestView, set_latest_view_handler)
|
||||
.event(FolderEvent::CloseView, close_view_handler)
|
||||
.event(FolderEvent::MoveItem, move_view_handler)
|
||||
.event(FolderEvent::MoveView, move_view_handler)
|
||||
// Trash
|
||||
.event(FolderEvent::ReadTrash, read_trash_handler)
|
||||
.event(FolderEvent::PutbackTrash, putback_trash_handler)
|
||||
@ -97,8 +97,8 @@ pub enum FolderEvent {
|
||||
SetLatestView = 21,
|
||||
|
||||
/// Move the view or app to another place
|
||||
#[event(input = "MoveFolderItemPayloadPB")]
|
||||
MoveItem = 22,
|
||||
#[event(input = "MoveViewPayloadPB")]
|
||||
MoveView = 22,
|
||||
|
||||
/// Read the trash that was deleted by the user
|
||||
#[event(output = "RepeatedTrashPB")]
|
||||
|
@ -1,7 +1,5 @@
|
||||
use crate::script::{invalid_workspace_name_test_case, FolderScript::*, FolderTest};
|
||||
use crate::script::{FolderScript::*, FolderTest};
|
||||
use collab_folder::core::ViewLayout;
|
||||
use flowy_folder2::entities::CreateWorkspacePayloadPB;
|
||||
use flowy_test::{event_builder::*, FlowyCoreTest};
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_all_workspace_test() {
|
||||
@ -60,28 +58,6 @@ async fn create_parent_view_test() {
|
||||
test.run_scripts(vec![ReloadParentView(app.id)]).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_parent_view_with_invalid_name() {
|
||||
for (name, code) in invalid_workspace_name_test_case() {
|
||||
let sdk = FlowyCoreTest::new();
|
||||
let request = CreateWorkspacePayloadPB {
|
||||
name,
|
||||
desc: "".to_owned(),
|
||||
};
|
||||
assert_eq!(
|
||||
EventBuilder::new(sdk)
|
||||
.event(flowy_folder2::event_map::FolderEvent::CreateWorkspace)
|
||||
.payload(request)
|
||||
.async_send()
|
||||
.await
|
||||
.error()
|
||||
.unwrap()
|
||||
.code,
|
||||
code.value()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[should_panic]
|
||||
async fn delete_parent_view_test() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use collab_folder::core::ViewLayout;
|
||||
use flowy_error::ErrorCode;
|
||||
|
||||
use flowy_folder2::entities::*;
|
||||
use flowy_folder2::event_map::FolderEvent::*;
|
||||
use flowy_test::event_builder::EventBuilder;
|
||||
@ -161,14 +161,6 @@ impl FolderTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn invalid_workspace_name_test_case() -> Vec<(String, ErrorCode)> {
|
||||
vec![
|
||||
("".to_owned(), ErrorCode::WorkspaceNameInvalid),
|
||||
("1234".repeat(100), ErrorCode::WorkspaceNameTooLong),
|
||||
]
|
||||
}
|
||||
|
||||
pub async fn create_workspace(sdk: &FlowyCoreTest, name: &str, desc: &str) -> WorkspacePB {
|
||||
let request = CreateWorkspacePayloadPB {
|
||||
name: name.to_owned(),
|
||||
|
@ -14,6 +14,7 @@ lib-dispatch = { path = "../lib-dispatch" }
|
||||
lib-ot = { path = "../../../shared-lib/lib-ot" }
|
||||
lib-infra = { path = "../../../shared-lib/lib-infra" }
|
||||
flowy-server = { path = "../flowy-server" }
|
||||
flowy-notification = { path = "../flowy-notification" }
|
||||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = {version = "1.0"}
|
||||
|
@ -1,8 +1,7 @@
|
||||
use crate::FlowyCoreTest;
|
||||
use flowy_user::errors::FlowyError;
|
||||
use lib_dispatch::prelude::{
|
||||
AFPluginDispatcher, AFPluginEventResponse, AFPluginFromBytes, AFPluginRequest, StatusCode,
|
||||
ToBytes, *,
|
||||
AFPluginDispatcher, AFPluginEventResponse, AFPluginFromBytes, AFPluginRequest, ToBytes, *,
|
||||
};
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
@ -87,7 +86,6 @@ impl EventBuilder {
|
||||
|
||||
pub fn error(self) -> Option<FlowyError> {
|
||||
let response = self.get_response();
|
||||
assert_eq!(response.status_code, StatusCode::Err);
|
||||
<AFPluginData<FlowyError>>::try_from(response.payload)
|
||||
.ok()
|
||||
.map(|data| data.into_inner())
|
||||
|
@ -3,7 +3,9 @@ use parking_lot::RwLock;
|
||||
use std::env::temp_dir;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::event_builder::EventBuilder;
|
||||
use flowy_core::{AppFlowyCore, AppFlowyCoreConfig};
|
||||
use flowy_folder2::entities::{CreateViewPayloadPB, RepeatedViewIdPB, ViewPB, WorkspaceSettingPB};
|
||||
use flowy_user::entities::{AuthTypePB, UserProfilePB};
|
||||
|
||||
use crate::user_event::{async_sign_up, init_user_setting, SignUpContext};
|
||||
@ -36,6 +38,12 @@ impl FlowyCoreTest {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub async fn new_with_user() -> Self {
|
||||
let test = Self::default();
|
||||
test.sign_up().await;
|
||||
test
|
||||
}
|
||||
|
||||
pub async fn sign_up(&self) -> SignUpContext {
|
||||
let auth_type = self.auth_type.read().clone();
|
||||
async_sign_up(self.inner.dispatcher(), auth_type).await
|
||||
@ -51,6 +59,46 @@ impl FlowyCoreTest {
|
||||
init_user_setting(self.inner.dispatcher()).await;
|
||||
context.user_profile
|
||||
}
|
||||
|
||||
pub async fn get_current_workspace(&self) -> WorkspaceSettingPB {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::GetCurrentWorkspace)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::WorkspaceSettingPB>()
|
||||
}
|
||||
|
||||
pub async fn delete_view(&self, view_id: &str) {
|
||||
let payload = RepeatedViewIdPB {
|
||||
items: vec![view_id.to_string()],
|
||||
};
|
||||
|
||||
// delete the view. the view will be moved to trash
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::DeleteView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn create_view(&self, parent_id: &str, name: String) -> ViewPB {
|
||||
let payload = CreateViewPayloadPB {
|
||||
parent_view_id: parent_id.to_string(),
|
||||
name,
|
||||
desc: "".to_string(),
|
||||
thumbnail: None,
|
||||
layout: Default::default(),
|
||||
initial_data: vec![],
|
||||
meta: Default::default(),
|
||||
set_as_current: false,
|
||||
};
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::CreateView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::ViewPB>()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for FlowyCoreTest {
|
||||
@ -60,3 +108,13 @@ impl std::ops::Deref for FlowyCoreTest {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
// pub struct TestNotificationSender {
|
||||
// pub(crate) sender: tokio::sync::mpsc::Sender<()>,
|
||||
// }
|
||||
//
|
||||
// impl NotificationSender for TestNotificationSender {
|
||||
// fn send_subject(&self, subject: SubscribeObject) -> Result<(), String> {
|
||||
// todo!()
|
||||
// }
|
||||
// }
|
||||
|
1
frontend/rust-lib/flowy-test/tests/database/mod.rs
Normal file
1
frontend/rust-lib/flowy-test/tests/database/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
mod test;
|
1
frontend/rust-lib/flowy-test/tests/database/test.rs
Normal file
1
frontend/rust-lib/flowy-test/tests/database/test.rs
Normal file
@ -0,0 +1 @@
|
||||
|
1
frontend/rust-lib/flowy-test/tests/folder/mod.rs
Normal file
1
frontend/rust-lib/flowy-test/tests/folder/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
mod test;
|
390
frontend/rust-lib/flowy-test/tests/folder/test.rs
Normal file
390
frontend/rust-lib/flowy-test/tests/folder/test.rs
Normal file
@ -0,0 +1,390 @@
|
||||
use flowy_folder2::entities::*;
|
||||
use flowy_test::event_builder::EventBuilder;
|
||||
use flowy_test::FlowyCoreTest;
|
||||
use flowy_user::errors::ErrorCode;
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_workspace_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let request = CreateWorkspacePayloadPB {
|
||||
name: "my second workspace".to_owned(),
|
||||
desc: "".to_owned(),
|
||||
};
|
||||
let resp = EventBuilder::new(test)
|
||||
.event(flowy_folder2::event_map::FolderEvent::CreateWorkspace)
|
||||
.payload(request)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::WorkspacePB>();
|
||||
assert_eq!(resp.name, "my second workspace");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn open_workspace_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let payload = CreateWorkspacePayloadPB {
|
||||
name: "my second workspace".to_owned(),
|
||||
desc: "".to_owned(),
|
||||
};
|
||||
// create a workspace
|
||||
let resp_1 = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::CreateWorkspace)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::WorkspacePB>();
|
||||
|
||||
// open the workspace
|
||||
let payload = WorkspaceIdPB {
|
||||
value: Some(resp_1.id.clone()),
|
||||
};
|
||||
let resp_2 = EventBuilder::new(test)
|
||||
.event(flowy_folder2::event_map::FolderEvent::OpenWorkspace)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::WorkspacePB>();
|
||||
|
||||
assert_eq!(resp_1.id, resp_2.id);
|
||||
assert_eq!(resp_1.name, resp_2.name);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_view_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let view = test
|
||||
.create_view(¤t_workspace.id, format!("My first view"))
|
||||
.await;
|
||||
assert_eq!(view.parent_view_id, current_workspace.id);
|
||||
assert_eq!(view.name, "My first view");
|
||||
assert_eq!(view.layout, ViewLayoutPB::Document);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn delete_view_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let view = test
|
||||
.create_view(¤t_workspace.id, format!("My first view"))
|
||||
.await;
|
||||
test.delete_view(&view.id).await;
|
||||
|
||||
// Try the read the view
|
||||
let payload = ViewIdPB {
|
||||
value: view.id.clone(),
|
||||
};
|
||||
let error = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await
|
||||
.error()
|
||||
.unwrap();
|
||||
assert_eq!(error.code, ErrorCode::RecordNotFound.value());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn put_back_trash_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let view = test
|
||||
.create_view(¤t_workspace.id, format!("My first view"))
|
||||
.await;
|
||||
test.delete_view(&view.id).await;
|
||||
|
||||
// After delete view, the view will be moved to trash
|
||||
let payload = ViewIdPB {
|
||||
value: view.id.clone(),
|
||||
};
|
||||
let error = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await
|
||||
.error()
|
||||
.unwrap();
|
||||
assert_eq!(error.code, ErrorCode::RecordNotFound.value());
|
||||
|
||||
let payload = TrashIdPB {
|
||||
id: view.id.clone(),
|
||||
};
|
||||
EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::PutbackTrash)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await;
|
||||
|
||||
let payload = ViewIdPB {
|
||||
value: view.id.clone(),
|
||||
};
|
||||
let error = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await
|
||||
.error();
|
||||
assert!(error.is_none());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn delete_view_permanently_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let view = test
|
||||
.create_view(¤t_workspace.id, format!("My first view"))
|
||||
.await;
|
||||
let payload = RepeatedViewIdPB {
|
||||
items: vec![view.id.clone()],
|
||||
};
|
||||
|
||||
// delete the view. the view will be moved to trash
|
||||
EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::DeleteView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await;
|
||||
|
||||
let trash = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadTrash)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::RepeatedTrashPB>()
|
||||
.items;
|
||||
assert_eq!(trash.len(), 1);
|
||||
assert_eq!(trash[0].id, view.id);
|
||||
|
||||
// delete the view from trash
|
||||
let payload = RepeatedTrashIdPB {
|
||||
items: vec![TrashIdPB {
|
||||
id: view.id.clone(),
|
||||
}],
|
||||
};
|
||||
EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::DeleteTrash)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await;
|
||||
|
||||
// After delete the last view, the trash should be empty
|
||||
let trash = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadTrash)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::RepeatedTrashPB>()
|
||||
.items;
|
||||
assert!(trash.is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn delete_all_trash_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
|
||||
for i in 0..3 {
|
||||
let view = test
|
||||
.create_view(¤t_workspace.id, format!("My {} view", i))
|
||||
.await;
|
||||
let payload = RepeatedViewIdPB {
|
||||
items: vec![view.id.clone()],
|
||||
};
|
||||
// delete the view. the view will be moved to trash
|
||||
EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::DeleteView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await;
|
||||
}
|
||||
|
||||
let trash = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadTrash)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::RepeatedTrashPB>()
|
||||
.items;
|
||||
assert_eq!(trash.len(), 3);
|
||||
|
||||
// Delete all the trash
|
||||
EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::DeleteAllTrash)
|
||||
.async_send()
|
||||
.await;
|
||||
|
||||
// After delete the last view, the trash should be empty
|
||||
let trash = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadTrash)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::RepeatedTrashPB>()
|
||||
.items;
|
||||
assert!(trash.is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn multiple_hierarchy_view_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
for i in 1..4 {
|
||||
let parent = test
|
||||
.create_view(¤t_workspace.id, format!("My {} view", i))
|
||||
.await;
|
||||
for j in 1..3 {
|
||||
let child = test
|
||||
.create_view(&parent.id, format!("My {}-{} view", i, j))
|
||||
.await;
|
||||
for k in 1..2 {
|
||||
let _sub_child = test
|
||||
.create_view(&child.id, format!("My {}-{}-{} view", i, j, k))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut views = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadWorkspaceViews)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::RepeatedViewPB>()
|
||||
.items;
|
||||
|
||||
// There will be one default view when AppFlowy is initialized. So there will be 4 views in total
|
||||
assert_eq!(views.len(), 4);
|
||||
views.remove(0);
|
||||
|
||||
// workspace
|
||||
// - view1
|
||||
// - view1-1
|
||||
// - view1-1-1
|
||||
// - view1-2
|
||||
// - view1-2-1
|
||||
// - view2
|
||||
// - view2-1
|
||||
// - view2-1-1
|
||||
// - view2-2
|
||||
// - view2-2-1
|
||||
// - view3
|
||||
// - view3-1
|
||||
// - view3-1-1
|
||||
// - view3-2
|
||||
// - view3-2-1
|
||||
assert_eq!(views[0].name, "My 1 view");
|
||||
assert_eq!(views[1].name, "My 2 view");
|
||||
assert_eq!(views[2].name, "My 3 view");
|
||||
|
||||
assert_eq!(views[0].child_views.len(), 2);
|
||||
// By default only the first level of child views will be loaded
|
||||
assert!(views[0].child_views[0].child_views.is_empty());
|
||||
|
||||
for (i, view) in views.into_iter().enumerate() {
|
||||
for (j, child_view) in view.child_views.into_iter().enumerate() {
|
||||
let payload = ViewIdPB {
|
||||
value: child_view.id.clone(),
|
||||
};
|
||||
|
||||
let child = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::ViewPB>();
|
||||
assert_eq!(child.name, format!("My {}-{} view", i + 1, j + 1));
|
||||
assert_eq!(child.child_views.len(), 1);
|
||||
// By default only the first level of child views will be loaded
|
||||
assert!(child.child_views[0].child_views.is_empty());
|
||||
|
||||
for (k, _child_view) in child_view.child_views.into_iter().enumerate() {
|
||||
// Get the last level view
|
||||
let sub_child = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadView)
|
||||
.payload(ViewIdPB {
|
||||
value: child.id.clone(),
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::ViewPB>();
|
||||
|
||||
assert_eq!(child.name, format!("My {}-{}-{} view", i + 1, j + 1, k + 1));
|
||||
assert!(sub_child.child_views.is_empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn move_view_event_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
for i in 1..4 {
|
||||
let parent = test
|
||||
.create_view(¤t_workspace.id, format!("My {} view", i))
|
||||
.await;
|
||||
for j in 1..3 {
|
||||
let _ = test
|
||||
.create_view(&parent.id, format!("My {}-{} view", i, j))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
let views = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadWorkspaceViews)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::RepeatedViewPB>()
|
||||
.items;
|
||||
|
||||
// There will be one default view when AppFlowy is initialized. So there will be 4 views in total
|
||||
assert_eq!(views.len(), 4);
|
||||
assert_eq!(views[1].name, "My 1 view");
|
||||
assert_eq!(views[2].name, "My 2 view");
|
||||
assert_eq!(views[3].name, "My 3 view");
|
||||
|
||||
let payload = MoveViewPayloadPB {
|
||||
view_id: views[1].id.clone(),
|
||||
from: 1,
|
||||
to: 2,
|
||||
};
|
||||
let _ = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::MoveView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await;
|
||||
|
||||
let views = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadWorkspaceViews)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::RepeatedViewPB>()
|
||||
.items;
|
||||
|
||||
assert_eq!(views[1].name, "My 2 view");
|
||||
assert_eq!(views[2].name, "My 1 view");
|
||||
assert_eq!(views[3].name, "My 3 view");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_parent_view_with_invalid_name() {
|
||||
for (name, code) in invalid_workspace_name_test_case() {
|
||||
let sdk = FlowyCoreTest::new();
|
||||
let request = CreateWorkspacePayloadPB {
|
||||
name,
|
||||
desc: "".to_owned(),
|
||||
};
|
||||
assert_eq!(
|
||||
EventBuilder::new(sdk)
|
||||
.event(flowy_folder2::event_map::FolderEvent::CreateWorkspace)
|
||||
.payload(request)
|
||||
.async_send()
|
||||
.await
|
||||
.error()
|
||||
.unwrap()
|
||||
.code,
|
||||
code.value()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn invalid_workspace_name_test_case() -> Vec<(String, ErrorCode)> {
|
||||
vec![
|
||||
("".to_owned(), ErrorCode::WorkspaceNameInvalid),
|
||||
("1234".repeat(100), ErrorCode::WorkspaceNameTooLong),
|
||||
]
|
||||
}
|
@ -1 +1,3 @@
|
||||
mod database;
|
||||
mod folder;
|
||||
mod user;
|
||||
|
Loading…
Reference in New Issue
Block a user