From 71f80be8f7d3fbd90928aa89bc4ac136a699d3a2 Mon Sep 17 00:00:00 2001
From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com>
Date: Tue, 24 Oct 2023 20:11:06 +0800
Subject: [PATCH] feat: save user metadata (#3754)
* feat: save user metadata
* chore: update client api
* refactor: separate test methods
* chore: save updated at
* chore: clippy
* chore: fix test
---
.run/ProtoBuf_Gen.run.xml | 23 -
.run/Run backend.run.xml | 18 -
.run/dart-event.run.xml | 16 -
.../lib/startup/plugin/src/sandbox.dart | 5 +-
.../startup/tasks/appflowy_cloud_task.dart | 2 +
.../user/application/user_auth_listener.dart | 2 +-
.../presentation/screens/splash_screen.dart | 12 +-
frontend/appflowy_tauri/src-tauri/Cargo.lock | 15 +-
frontend/appflowy_tauri/src-tauri/Cargo.toml | 2 +-
frontend/rust-lib/Cargo.lock | 33 +-
frontend/rust-lib/Cargo.toml | 2 +-
.../src/document/document_event.rs | 14 +-
.../event-integration/src/event_builder.rs | 8 +-
.../event-integration/src/folder_event.rs | 115 ---
.../rust-lib/event-integration/src/lib.rs | 900 +-----------------
.../event-integration/src/test_database.rs | 447 +++++++++
.../event-integration/src/test_document.rs | 119 +++
.../event-integration/src/test_folder.rs | 173 ++++
.../event-integration/src/test_user.rs | 296 ++++++
.../event-integration/src/user_event.rs | 84 --
.../tests/database/local_test/test.rs | 82 +-
.../tests/document/af_cloud_test/edit_test.rs | 2 +-
.../tests/document/supabase_test/edit_test.rs | 2 +-
.../tests/folder/local_test/script.rs | 44 +-
.../folder/local_test/subscription_test.rs | 10 +-
.../tests/folder/local_test/test.rs | 34 +-
.../tests/user/af_cloud_test/test.rs | 27 +-
.../tests/user/local_test/auth_test.rs | 16 +-
.../user/local_test/user_awareness_test.rs | 4 +-
.../user/local_test/user_profile_test.rs | 24 +-
.../user/migration_test/document_test.rs | 4 +-
.../tests/user/migration_test/version_test.rs | 4 +-
.../tests/user/supabase_test/auth_test.rs | 19 +-
.../user/supabase_test/workspace_test.rs | 4 +-
.../rust-lib/event-integration/tests/util.rs | 14 +-
.../rust-lib/flowy-database2/src/manager.rs | 7 +-
.../tests/database/database_editor.rs | 19 +-
.../rust-lib/flowy-document2/src/manager.rs | 7 +-
.../flowy-document2/src/notification.rs | 1 +
.../rust-lib/flowy-folder2/src/manager.rs | 7 +-
frontend/rust-lib/flowy-server/Cargo.toml | 2 +-
.../{user.rs => user/cloud_service_impl.rs} | 101 +-
.../src/af_cloud/impls/user/dto.rs | 65 ++
.../src/af_cloud/impls/user/mod.rs | 5 +
.../src/af_cloud/impls/user/util.rs | 10 +
.../src/local_server/impls/user.rs | 7 +-
.../flowy-server/src/supabase/api/user.rs | 9 +-
.../flowy-server/src/supabase/entities.rs | 3 +
.../down.sql | 3 +
.../2023-10-24-074032_user_updated_at/up.sql | 3 +
frontend/rust-lib/flowy-sqlite/src/schema.rs | 1 +
.../rust-lib/flowy-user-deps/src/cloud.rs | 2 +-
.../rust-lib/flowy-user-deps/src/entities.rs | 91 +-
.../rust-lib/flowy-user/src/entities/auth.rs | 3 +
.../flowy-user/src/entities/user_setting.rs | 4 +-
.../rust-lib/flowy-user/src/event_handler.rs | 15 +-
frontend/rust-lib/flowy-user/src/event_map.rs | 2 +-
frontend/rust-lib/flowy-user/src/manager.rs | 50 +-
.../rust-lib/flowy-user/src/notification.rs | 1 +
.../flowy-user/src/services/user_sql.rs | 3 +
.../flowy-user/src/services/user_workspace.rs | 2 +-
frontend/scripts/makefile/tests.toml | 2 +-
62 files changed, 1525 insertions(+), 1476 deletions(-)
delete mode 100644 .run/ProtoBuf_Gen.run.xml
delete mode 100644 .run/Run backend.run.xml
delete mode 100644 .run/dart-event.run.xml
delete mode 100644 frontend/rust-lib/event-integration/src/folder_event.rs
create mode 100644 frontend/rust-lib/event-integration/src/test_database.rs
create mode 100644 frontend/rust-lib/event-integration/src/test_document.rs
create mode 100644 frontend/rust-lib/event-integration/src/test_folder.rs
create mode 100644 frontend/rust-lib/event-integration/src/test_user.rs
delete mode 100644 frontend/rust-lib/event-integration/src/user_event.rs
rename frontend/rust-lib/flowy-server/src/af_cloud/impls/{user.rs => user/cloud_service_impl.rs} (71%)
create mode 100644 frontend/rust-lib/flowy-server/src/af_cloud/impls/user/dto.rs
create mode 100644 frontend/rust-lib/flowy-server/src/af_cloud/impls/user/mod.rs
create mode 100644 frontend/rust-lib/flowy-server/src/af_cloud/impls/user/util.rs
create mode 100644 frontend/rust-lib/flowy-sqlite/migrations/2023-10-24-074032_user_updated_at/down.sql
create mode 100644 frontend/rust-lib/flowy-sqlite/migrations/2023-10-24-074032_user_updated_at/up.sql
diff --git a/.run/ProtoBuf_Gen.run.xml b/.run/ProtoBuf_Gen.run.xml
deleted file mode 100644
index 13d9202183f9..000000000000
--- a/.run/ProtoBuf_Gen.run.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.run/Run backend.run.xml b/.run/Run backend.run.xml
deleted file mode 100644
index 840a367809c6..000000000000
--- a/.run/Run backend.run.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.run/dart-event.run.xml b/.run/dart-event.run.xml
deleted file mode 100644
index c64ee9bf57cf..000000000000
--- a/.run/dart-event.run.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend/appflowy_flutter/lib/startup/plugin/src/sandbox.dart b/frontend/appflowy_flutter/lib/startup/plugin/src/sandbox.dart
index a10ff9631adc..740fb3f4d2e2 100644
--- a/frontend/appflowy_flutter/lib/startup/plugin/src/sandbox.dart
+++ b/frontend/appflowy_flutter/lib/startup/plugin/src/sandbox.dart
@@ -42,10 +42,7 @@ class PluginSandbox {
PluginConfig? config,
}) {
if (_pluginBuilders.containsKey(pluginType)) {
- throw PlatformException(
- code: '-1',
- message: "$pluginType was registered before",
- );
+ return;
}
_pluginBuilders[pluginType] = builder;
diff --git a/frontend/appflowy_flutter/lib/startup/tasks/appflowy_cloud_task.dart b/frontend/appflowy_flutter/lib/startup/tasks/appflowy_cloud_task.dart
index ca21b40c63a1..420c9d93fc20 100644
--- a/frontend/appflowy_flutter/lib/startup/tasks/appflowy_cloud_task.dart
+++ b/frontend/appflowy_flutter/lib/startup/tasks/appflowy_cloud_task.dart
@@ -2,6 +2,7 @@ import 'package:appflowy/env/env.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/auth/auth_service.dart';
import 'package:appflowy/user/application/user_auth_listener.dart';
+import 'package:appflowy_backend/log.dart';
class InitAppFlowyCloudTask extends LaunchTask {
final _authStateListener = UserAuthStateListener();
@@ -18,6 +19,7 @@ class InitAppFlowyCloudTask extends LaunchTask {
isLoggingOut = false;
},
onInvalidAuth: (message) async {
+ Log.error(message);
await getIt().signOut();
// TODO(nathan): Show a dialog to notify the user that the session is expired.
if (!isLoggingOut) {
diff --git a/frontend/appflowy_flutter/lib/user/application/user_auth_listener.dart b/frontend/appflowy_flutter/lib/user/application/user_auth_listener.dart
index c0d1231e4b2b..776d537f36af 100644
--- a/frontend/appflowy_flutter/lib/user/application/user_auth_listener.dart
+++ b/frontend/appflowy_flutter/lib/user/application/user_auth_listener.dart
@@ -53,7 +53,7 @@ class UserAuthStateListener {
_didSignIn?.call();
break;
case AuthStatePB.InvalidAuth:
- _onInvalidAuth?.call("");
+ _onInvalidAuth?.call(pb.message);
break;
default:
break;
diff --git a/frontend/appflowy_flutter/lib/user/presentation/screens/splash_screen.dart b/frontend/appflowy_flutter/lib/user/presentation/screens/splash_screen.dart
index 1b53d80bdf7f..3ea6b371da81 100644
--- a/frontend/appflowy_flutter/lib/user/presentation/screens/splash_screen.dart
+++ b/frontend/appflowy_flutter/lib/user/presentation/screens/splash_screen.dart
@@ -14,16 +14,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
-// [[diagram: splash screen]]
-// ┌────────────────┐1.get user ┌──────────┐ ┌────────────┐ 2.send UserEventCheckUser
-// │ SplashScreen │──────────▶│SplashBloc│────▶│ISplashUser │─────┐
-// └────────────────┘ └──────────┘ └────────────┘ │
-// │
-// ▼
-// ┌───────────┐ ┌─────────────┐ ┌────────┐
-// │HomeScreen │◀───────────│BlocListener │◀────────────────│RustSDK │
-// └───────────┘ └─────────────┘ └────────┘
-// 4. Show HomeScreen or SignIn 3.return AuthState
class SplashScreen extends StatelessWidget {
/// Root Page of the app.
const SplashScreen({
@@ -82,7 +72,7 @@ class SplashScreen extends StatelessWidget {
(check) async {
/// If encryption is needed, the user is navigated to the encryption screen.
/// Otherwise, it fetches the current workspace for the user and navigates them
- if (check.isNeedSecret) {
+ if (check.requireSecret) {
getIt().pushEncryptionScreen(context, userProfile);
} else {
final result = await FolderEventGetCurrentWorkspace().send();
diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock
index 37005a67164d..417a4d21a4d7 100644
--- a/frontend/appflowy_tauri/src-tauri/Cargo.lock
+++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock
@@ -762,7 +762,7 @@ dependencies = [
[[package]]
name = "client-api"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"anyhow",
"bytes",
@@ -1438,7 +1438,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
[[package]]
name = "database-entity"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"anyhow",
"chrono",
@@ -2781,7 +2781,7 @@ dependencies = [
[[package]]
name = "gotrue"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"anyhow",
"futures-util",
@@ -2797,7 +2797,7 @@ dependencies = [
[[package]]
name = "gotrue-entity"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"anyhow",
"jsonwebtoken",
@@ -3232,7 +3232,7 @@ dependencies = [
[[package]]
name = "infra"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"anyhow",
"reqwest",
@@ -4915,7 +4915,7 @@ dependencies = [
[[package]]
name = "realtime-entity"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"bytes",
"collab",
@@ -5637,9 +5637,10 @@ dependencies = [
[[package]]
name = "shared_entity"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"anyhow",
+ "collab-entity",
"database-entity",
"gotrue-entity",
"opener",
diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml
index ea85a88118e0..71833a1417fd 100644
--- a/frontend/appflowy_tauri/src-tauri/Cargo.toml
+++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml
@@ -38,7 +38,7 @@ custom-protocol = ["tauri/custom-protocol"]
# Run the script:
# scripts/tool/update_client_api_rev.sh new_rev_id
# ⚠️⚠️⚠️️
-client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "7a309c6f69d8b34709292052e9ef0561e16c82a1" }
+client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "141354bfa9d08c387cf9beb9697b89b052790e89" }
# Please use the following script to update collab.
# Working directory: frontend
#
diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock
index 1f7b9ad4368d..591e3240e62e 100644
--- a/frontend/rust-lib/Cargo.lock
+++ b/frontend/rust-lib/Cargo.lock
@@ -660,7 +660,7 @@ dependencies = [
[[package]]
name = "client-api"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"anyhow",
"bytes",
@@ -1138,7 +1138,7 @@ dependencies = [
"cssparser-macros",
"dtoa-short",
"itoa",
- "phf 0.8.0",
+ "phf 0.11.2",
"smallvec",
]
@@ -1265,7 +1265,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
[[package]]
name = "database-entity"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"anyhow",
"chrono",
@@ -2440,7 +2440,7 @@ dependencies = [
[[package]]
name = "gotrue"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"anyhow",
"futures-util",
@@ -2456,7 +2456,7 @@ dependencies = [
[[package]]
name = "gotrue-entity"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"anyhow",
"jsonwebtoken",
@@ -2816,7 +2816,7 @@ dependencies = [
[[package]]
name = "infra"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"anyhow",
"reqwest",
@@ -3623,7 +3623,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
dependencies = [
- "phf_macros",
+ "phf_macros 0.8.0",
"phf_shared 0.8.0",
"proc-macro-hack",
]
@@ -3643,6 +3643,7 @@ version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
dependencies = [
+ "phf_macros 0.11.2",
"phf_shared 0.11.2",
]
@@ -3710,6 +3711,19 @@ dependencies = [
"syn 1.0.109",
]
+[[package]]
+name = "phf_macros"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
+dependencies = [
+ "phf_generator 0.11.2",
+ "phf_shared 0.11.2",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.31",
+]
+
[[package]]
name = "phf_shared"
version = "0.8.0"
@@ -4251,7 +4265,7 @@ dependencies = [
[[package]]
name = "realtime-entity"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"bytes",
"collab",
@@ -4872,9 +4886,10 @@ dependencies = [
[[package]]
name = "shared_entity"
version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7a309c6f69d8b34709292052e9ef0561e16c82a1#7a309c6f69d8b34709292052e9ef0561e16c82a1"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
dependencies = [
"anyhow",
+ "collab-entity",
"database-entity",
"gotrue-entity",
"opener",
diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml
index 561fdfeb7ca9..9f3142145e9d 100644
--- a/frontend/rust-lib/Cargo.toml
+++ b/frontend/rust-lib/Cargo.toml
@@ -82,7 +82,7 @@ incremental = false
# Run the script:
# scripts/tool/update_client_api_rev.sh new_rev_id
# ⚠️⚠️⚠️️
-client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "7a309c6f69d8b34709292052e9ef0561e16c82a1" }
+client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "141354bfa9d08c387cf9beb9697b89b052790e89" }
# Please use the following script to update collab.
# Working directory: frontend
#
diff --git a/frontend/rust-lib/event-integration/src/document/document_event.rs b/frontend/rust-lib/event-integration/src/document/document_event.rs
index 8439d3ffb36d..ab20d240bd39 100644
--- a/frontend/rust-lib/event-integration/src/document/document_event.rs
+++ b/frontend/rust-lib/event-integration/src/document/document_event.rs
@@ -1,18 +1,20 @@
+use std::collections::HashMap;
+
+use serde_json::Value;
+
use flowy_document2::entities::*;
use flowy_document2::event_map::DocumentEvent;
use flowy_folder2::entities::{CreateViewPayloadPB, ViewLayoutPB, ViewPB};
use flowy_folder2::event_map::FolderEvent;
-use serde_json::Value;
-use std::collections::HashMap;
use crate::document::utils::{gen_delta_str, gen_id, gen_text_block_data};
use crate::event_builder::EventBuilder;
-use crate::FlowyCoreTest;
+use crate::EventIntegrationTest;
const TEXT_BLOCK_TY: &str = "paragraph";
pub struct DocumentEventTest {
- inner: FlowyCoreTest,
+ inner: EventIntegrationTest,
}
pub struct OpenDocumentData {
@@ -22,11 +24,11 @@ pub struct OpenDocumentData {
impl DocumentEventTest {
pub async fn new() -> Self {
- let sdk = FlowyCoreTest::new_with_guest_user().await;
+ let sdk = EventIntegrationTest::new_with_guest_user().await;
Self { inner: sdk }
}
- pub fn new_with_core(core: FlowyCoreTest) -> Self {
+ pub fn new_with_core(core: EventIntegrationTest) -> Self {
Self { inner: core }
}
diff --git a/frontend/rust-lib/event-integration/src/event_builder.rs b/frontend/rust-lib/event-integration/src/event_builder.rs
index 943507add39d..a6c0209622f2 100644
--- a/frontend/rust-lib/event-integration/src/event_builder.rs
+++ b/frontend/rust-lib/event-integration/src/event_builder.rs
@@ -10,7 +10,7 @@ use lib_dispatch::prelude::{
AFPluginDispatcher, AFPluginEventResponse, AFPluginFromBytes, AFPluginRequest, ToBytes, *,
};
-use crate::FlowyCoreTest;
+use crate::EventIntegrationTest;
#[derive(Clone)]
pub struct EventBuilder {
@@ -18,7 +18,7 @@ pub struct EventBuilder {
}
impl EventBuilder {
- pub fn new(sdk: FlowyCoreTest) -> Self {
+ pub fn new(sdk: EventIntegrationTest) -> Self {
Self {
context: TestContext::new(sdk),
}
@@ -121,13 +121,13 @@ impl EventBuilder {
#[derive(Clone)]
pub struct TestContext {
- pub sdk: FlowyCoreTest,
+ pub sdk: EventIntegrationTest,
request: Option,
response: Option,
}
impl TestContext {
- pub fn new(sdk: FlowyCoreTest) -> Self {
+ pub fn new(sdk: EventIntegrationTest) -> Self {
Self {
sdk,
request: None,
diff --git a/frontend/rust-lib/event-integration/src/folder_event.rs b/frontend/rust-lib/event-integration/src/folder_event.rs
deleted file mode 100644
index a6cbebf09de2..000000000000
--- a/frontend/rust-lib/event-integration/src/folder_event.rs
+++ /dev/null
@@ -1,115 +0,0 @@
-use crate::event_builder::EventBuilder;
-use crate::FlowyCoreTest;
-use flowy_folder2::entities::*;
-use flowy_folder2::event_map::FolderEvent::*;
-
-pub struct ViewTest {
- pub sdk: FlowyCoreTest,
- pub workspace: WorkspacePB,
- pub parent_view: ViewPB,
- pub child_view: ViewPB,
-}
-
-impl ViewTest {
- #[allow(dead_code)]
- pub async fn new(sdk: &FlowyCoreTest, layout: ViewLayoutPB, data: Vec) -> Self {
- let workspace = create_workspace(sdk, "Workspace", "").await;
- open_workspace(sdk, &workspace.id).await;
- let app = create_app(sdk, "App", "AppFlowy GitHub Project", &workspace.id).await;
- let view = create_view(sdk, &app.id, layout, data).await;
- Self {
- sdk: sdk.clone(),
- workspace,
- parent_view: app,
- child_view: view,
- }
- }
-
- pub async fn new_grid_view(sdk: &FlowyCoreTest, data: Vec) -> Self {
- Self::new(sdk, ViewLayoutPB::Grid, data).await
- }
-
- pub async fn new_board_view(sdk: &FlowyCoreTest, data: Vec) -> Self {
- Self::new(sdk, ViewLayoutPB::Board, data).await
- }
-
- pub async fn new_calendar_view(sdk: &FlowyCoreTest, data: Vec) -> Self {
- Self::new(sdk, ViewLayoutPB::Calendar, data).await
- }
-
- pub async fn new_document_view(sdk: &FlowyCoreTest) -> Self {
- Self::new(sdk, ViewLayoutPB::Document, vec![]).await
- }
-}
-
-async fn create_workspace(sdk: &FlowyCoreTest, name: &str, desc: &str) -> WorkspacePB {
- let request = CreateWorkspacePayloadPB {
- name: name.to_owned(),
- desc: desc.to_owned(),
- };
-
- EventBuilder::new(sdk.clone())
- .event(CreateWorkspace)
- .payload(request)
- .async_send()
- .await
- .parse::()
-}
-
-async fn open_workspace(sdk: &FlowyCoreTest, workspace_id: &str) {
- let payload = WorkspaceIdPB {
- value: Some(workspace_id.to_owned()),
- };
- let _ = EventBuilder::new(sdk.clone())
- .event(OpenWorkspace)
- .payload(payload)
- .async_send()
- .await;
-}
-
-async fn create_app(sdk: &FlowyCoreTest, name: &str, desc: &str, workspace_id: &str) -> ViewPB {
- let create_app_request = CreateViewPayloadPB {
- parent_view_id: workspace_id.to_owned(),
- name: name.to_string(),
- desc: desc.to_string(),
- thumbnail: None,
- layout: ViewLayoutPB::Document,
- initial_data: vec![],
- meta: Default::default(),
- set_as_current: true,
- index: None,
- };
-
- EventBuilder::new(sdk.clone())
- .event(CreateView)
- .payload(create_app_request)
- .async_send()
- .await
- .parse::()
-}
-
-async fn create_view(
- sdk: &FlowyCoreTest,
- app_id: &str,
- layout: ViewLayoutPB,
- data: Vec,
-) -> ViewPB {
- let payload = CreateViewPayloadPB {
- parent_view_id: app_id.to_string(),
- name: "View A".to_string(),
- desc: "".to_string(),
- thumbnail: Some("http://1.png".to_string()),
- layout,
- initial_data: data,
- meta: Default::default(),
- set_as_current: true,
- index: None,
- };
-
- EventBuilder::new(sdk.clone())
- .event(CreateView)
- .payload(payload)
- .async_send()
- .await
- .parse::()
-}
diff --git a/frontend/rust-lib/event-integration/src/lib.rs b/frontend/rust-lib/event-integration/src/lib.rs
index ea2b28c33dee..c7fe6c00d9fc 100644
--- a/frontend/rust-lib/event-integration/src/lib.rs
+++ b/frontend/rust-lib/event-integration/src/lib.rs
@@ -1,59 +1,33 @@
-use std::collections::HashMap;
-use std::convert::TryFrom;
use std::env::temp_dir;
use std::path::PathBuf;
use std::sync::Arc;
-use bytes::Bytes;
-use collab::core::collab::MutexCollab;
-use collab::core::origin::CollabOrigin;
-use collab::preclude::updates::decoder::Decode;
-use collab::preclude::{merge_updates_v1, Update};
-use collab_document::blocks::DocumentData;
-use collab_document::document::Document;
use nanoid::nanoid;
use parking_lot::RwLock;
-use protobuf::ProtobufError;
-use tokio::sync::broadcast::{channel, Sender};
-use uuid::Uuid;
use flowy_core::{AppFlowyCore, AppFlowyCoreConfig};
-use flowy_database2::entities::*;
-use flowy_database2::event_map::DatabaseEvent;
-use flowy_document2::entities::{DocumentDataPB, OpenDocumentPayloadPB};
-use flowy_document2::event_map::DocumentEvent;
-use flowy_folder2::entities::icon::UpdateViewIconPayloadPB;
-use flowy_folder2::entities::*;
-use flowy_folder2::event_map::FolderEvent;
-use flowy_notification::entities::SubscribeObject;
-use flowy_notification::{register_notification_sender, NotificationSender};
-use flowy_server::supabase::define::{USER_DEVICE_ID, USER_EMAIL, USER_SIGN_IN_URL, USER_UUID};
-use flowy_user::entities::{
- AuthTypePB, OauthSignInPB, SignInUrlPB, SignInUrlPayloadPB, UpdateCloudConfigPB,
- UserCloudConfigPB, UserProfilePB,
-};
-use flowy_user::errors::{FlowyError, FlowyResult};
-use flowy_user::event_map::UserEvent::*;
+use flowy_notification::register_notification_sender;
+use flowy_user::entities::AuthTypePB;
-use crate::document::document_event::{DocumentEventTest, OpenDocumentData};
-use crate::event_builder::EventBuilder;
-use crate::user_event::{async_sign_up, SignUpContext};
+use crate::test_user::TestNotificationSender;
pub mod document;
pub mod event_builder;
-pub mod folder_event;
-pub mod user_event;
+pub mod test_database;
+pub mod test_document;
+pub mod test_folder;
+pub mod test_user;
#[derive(Clone)]
-pub struct FlowyCoreTest {
- auth_type: Arc>,
- inner: AppFlowyCore,
+pub struct EventIntegrationTest {
+ pub auth_type: Arc>,
+ pub inner: AppFlowyCore,
#[allow(dead_code)]
cleaner: Arc,
pub notification_sender: TestNotificationSender,
}
-impl Default for FlowyCoreTest {
+impl Default for EventIntegrationTest {
fn default() -> Self {
let temp_dir = temp_dir().join(nanoid!(6));
std::fs::create_dir_all(&temp_dir).unwrap();
@@ -61,51 +35,10 @@ impl Default for FlowyCoreTest {
}
}
-impl FlowyCoreTest {
+impl EventIntegrationTest {
pub fn new() -> Self {
Self::default()
}
-
- pub async fn insert_document_text(&self, document_id: &str, text: &str, index: usize) {
- let document_event = DocumentEventTest::new_with_core(self.clone());
- document_event
- .insert_index(document_id, text, index, None)
- .await;
- }
-
- pub async fn get_document_data(&self, view_id: &str) -> DocumentData {
- let pb = EventBuilder::new(self.clone())
- .event(DocumentEvent::GetDocumentData)
- .payload(OpenDocumentPayloadPB {
- document_id: view_id.to_string(),
- })
- .async_send()
- .await
- .parse::();
-
- DocumentData::from(pb)
- }
-
- pub async fn get_document_update(&self, document_id: &str) -> Vec {
- let workspace_id = self.user_manager.workspace_id().unwrap();
- let cloud_service = self.document_manager.get_cloud_service().clone();
- let remote_updates = cloud_service
- .get_document_updates(document_id, &workspace_id)
- .await
- .unwrap();
-
- if remote_updates.is_empty() {
- return vec![];
- }
-
- let updates = remote_updates
- .iter()
- .map(|update| update.as_ref())
- .collect::>();
-
- merge_updates_v1(&updates).unwrap()
- }
-
pub fn new_with_user_data_path(path: PathBuf, name: String) -> Self {
let config = AppFlowyCoreConfig::new(path.to_str().unwrap(), name).log_filter(
"trace",
@@ -129,711 +62,9 @@ impl FlowyCoreTest {
cleaner: Arc::new(Cleaner(path)),
}
}
-
- pub async fn enable_encryption(&self) -> String {
- let config = EventBuilder::new(self.clone())
- .event(GetCloudConfig)
- .async_send()
- .await
- .parse::();
- let update = UpdateCloudConfigPB {
- enable_sync: None,
- enable_encrypt: Some(true),
- };
- let error = EventBuilder::new(self.clone())
- .event(SetCloudConfig)
- .payload(update)
- .async_send()
- .await
- .error();
- assert!(error.is_none());
- config.encrypt_secret
- }
-
- pub async fn get_user_profile(&self) -> Result {
- EventBuilder::new(self.clone())
- .event(GetUserProfile)
- .async_send()
- .await
- .try_parse::()
- }
-
- pub async fn new_with_guest_user() -> Self {
- let test = Self::default();
- test.sign_up_as_guest().await;
- test
- }
-
- pub async fn sign_up_as_guest(&self) -> SignUpContext {
- async_sign_up(self.inner.dispatcher(), AuthTypePB::Local).await
- }
-
- pub async fn supabase_party_sign_up(&self) -> UserProfilePB {
- let map = third_party_sign_up_param(Uuid::new_v4().to_string());
- let payload = OauthSignInPB {
- map,
- auth_type: AuthTypePB::Supabase,
- };
-
- EventBuilder::new(self.clone())
- .event(OauthSignIn)
- .payload(payload)
- .async_send()
- .await
- .parse::()
- }
-
- pub async fn sign_out(&self) {
- EventBuilder::new(self.clone())
- .event(SignOut)
- .async_send()
- .await;
- }
-
- pub fn set_auth_type(&self, auth_type: AuthTypePB) {
- *self.auth_type.write() = auth_type;
- }
-
- pub async fn init_user(&self) -> UserProfilePB {
- self.sign_up_as_guest().await.user_profile
- }
-
- pub async fn af_cloud_sign_in_with_email(&self, email: &str) -> FlowyResult {
- let payload = SignInUrlPayloadPB {
- email: email.to_string(),
- auth_type: AuthTypePB::AFCloud,
- };
- let sign_in_url = EventBuilder::new(self.clone())
- .event(GetSignInURL)
- .payload(payload)
- .async_send()
- .await
- .try_parse::()?
- .sign_in_url;
-
- let mut map = HashMap::new();
- map.insert(USER_SIGN_IN_URL.to_string(), sign_in_url);
- map.insert(USER_DEVICE_ID.to_string(), Uuid::new_v4().to_string());
- let payload = OauthSignInPB {
- map,
- auth_type: AuthTypePB::AFCloud,
- };
-
- let user_profile = EventBuilder::new(self.clone())
- .event(OauthSignIn)
- .payload(payload)
- .async_send()
- .await
- .try_parse::()?;
-
- Ok(user_profile)
- }
-
- pub async fn supabase_sign_up_with_uuid(
- &self,
- uuid: &str,
- email: Option,
- ) -> FlowyResult {
- let mut map = HashMap::new();
- map.insert(USER_UUID.to_string(), uuid.to_string());
- map.insert(USER_DEVICE_ID.to_string(), uuid.to_string());
- map.insert(
- USER_EMAIL.to_string(),
- email.unwrap_or_else(|| format!("{}@appflowy.io", nanoid!(10))),
- );
- let payload = OauthSignInPB {
- map,
- auth_type: AuthTypePB::Supabase,
- };
-
- let user_profile = EventBuilder::new(self.clone())
- .event(OauthSignIn)
- .payload(payload)
- .async_send()
- .await
- .try_parse::()?;
-
- Ok(user_profile)
- }
-
- // Must sign up/ sign in first
- pub async fn get_current_workspace(&self) -> WorkspaceSettingPB {
- EventBuilder::new(self.clone())
- .event(FolderEvent::GetCurrentWorkspace)
- .async_send()
- .await
- .parse::()
- }
-
- pub async fn get_all_workspace_views(&self) -> Vec {
- EventBuilder::new(self.clone())
- .event(FolderEvent::ReadWorkspaceViews)
- .async_send()
- .await
- .parse::()
- .items
- }
-
- pub async fn get_views(&self, parent_view_id: &str) -> ViewPB {
- EventBuilder::new(self.clone())
- .event(FolderEvent::ReadView)
- .payload(ViewIdPB {
- value: parent_view_id.to_string(),
- })
- .async_send()
- .await
- .parse::()
- }
-
- 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(FolderEvent::DeleteView)
- .payload(payload)
- .async_send()
- .await;
- }
-
- pub async fn update_view(&self, changeset: UpdateViewPayloadPB) -> Option {
- // delete the view. the view will be moved to trash
- EventBuilder::new(self.clone())
- .event(FolderEvent::UpdateView)
- .payload(changeset)
- .async_send()
- .await
- .error()
- }
-
- pub async fn update_view_icon(&self, payload: UpdateViewIconPayloadPB) -> Option {
- EventBuilder::new(self.clone())
- .event(FolderEvent::UpdateViewIcon)
- .payload(payload)
- .async_send()
- .await
- .error()
- }
-
- 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,
- index: None,
- };
- EventBuilder::new(self.clone())
- .event(FolderEvent::CreateView)
- .payload(payload)
- .async_send()
- .await
- .parse::()
- }
-
- pub async fn create_document(
- &self,
- parent_id: &str,
- name: String,
- initial_data: Vec,
- ) -> ViewPB {
- let payload = CreateViewPayloadPB {
- parent_view_id: parent_id.to_string(),
- name,
- desc: "".to_string(),
- thumbnail: None,
- layout: ViewLayoutPB::Document,
- initial_data,
- meta: Default::default(),
- set_as_current: true,
- index: None,
- };
- let view = EventBuilder::new(self.clone())
- .event(FolderEvent::CreateView)
- .payload(payload)
- .async_send()
- .await
- .parse::();
-
- let payload = OpenDocumentPayloadPB {
- document_id: view.id.clone(),
- };
-
- let _ = EventBuilder::new(self.clone())
- .event(DocumentEvent::OpenDocument)
- .payload(payload)
- .async_send()
- .await
- .parse::();
-
- view
- }
-
- pub async fn create_grid(&self, parent_id: &str, name: String, initial_data: Vec) -> ViewPB {
- let payload = CreateViewPayloadPB {
- parent_view_id: parent_id.to_string(),
- name,
- desc: "".to_string(),
- thumbnail: None,
- layout: ViewLayoutPB::Grid,
- initial_data,
- meta: Default::default(),
- set_as_current: true,
- index: None,
- };
- EventBuilder::new(self.clone())
- .event(FolderEvent::CreateView)
- .payload(payload)
- .async_send()
- .await
- .parse::()
- }
-
- pub async fn open_database(&self, view_id: &str) {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::GetDatabase)
- .payload(DatabaseViewIdPB {
- value: view_id.to_string(),
- })
- .async_send()
- .await;
- }
-
- pub async fn open_document(&self, doc_id: String) -> OpenDocumentData {
- let payload = OpenDocumentPayloadPB {
- document_id: doc_id.clone(),
- };
- let data = EventBuilder::new(self.clone())
- .event(DocumentEvent::OpenDocument)
- .payload(payload)
- .async_send()
- .await
- .parse::();
- OpenDocumentData { id: doc_id, data }
- }
-
- pub async fn create_board(&self, parent_id: &str, name: String, initial_data: Vec) -> 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,
- index: None,
- };
- EventBuilder::new(self.clone())
- .event(FolderEvent::CreateView)
- .payload(payload)
- .async_send()
- .await
- .parse::()
- }
-
- pub async fn create_calendar(
- &self,
- parent_id: &str,
- name: String,
- initial_data: Vec,
- ) -> 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,
- index: None,
- };
- EventBuilder::new(self.clone())
- .event(FolderEvent::CreateView)
- .payload(payload)
- .async_send()
- .await
- .parse::()
- }
-
- pub async fn get_database(&self, view_id: &str) -> DatabasePB {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::GetDatabase)
- .payload(DatabaseViewIdPB {
- value: view_id.to_string(),
- })
- .async_send()
- .await
- .parse::()
- }
-
- pub async fn get_all_database_fields(&self, view_id: &str) -> RepeatedFieldPB {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::GetFields)
- .payload(GetFieldPayloadPB {
- view_id: view_id.to_string(),
- field_ids: None,
- })
- .async_send()
- .await
- .parse::()
- }
-
- pub async fn create_field(&self, view_id: &str, field_type: FieldType) -> FieldPB {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::CreateTypeOption)
- .payload(CreateFieldPayloadPB {
- view_id: view_id.to_string(),
- field_type,
- type_option_data: None,
- })
- .async_send()
- .await
- .parse::()
- .field
- }
-
- pub async fn update_field(&self, changeset: FieldChangesetPB) {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::UpdateField)
- .payload(changeset)
- .async_send()
- .await;
- }
-
- pub async fn delete_field(&self, view_id: &str, field_id: &str) -> Option {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::DeleteField)
- .payload(DeleteFieldPayloadPB {
- view_id: view_id.to_string(),
- field_id: field_id.to_string(),
- })
- .async_send()
- .await
- .error()
- }
-
- pub async fn update_field_type(
- &self,
- view_id: &str,
- field_id: &str,
- field_type: FieldType,
- ) -> Option {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::UpdateFieldType)
- .payload(UpdateFieldTypePayloadPB {
- view_id: view_id.to_string(),
- field_id: field_id.to_string(),
- field_type,
- })
- .async_send()
- .await
- .error()
- }
-
- pub async fn duplicate_field(&self, view_id: &str, field_id: &str) -> Option {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::DuplicateField)
- .payload(DuplicateFieldPayloadPB {
- view_id: view_id.to_string(),
- field_id: field_id.to_string(),
- })
- .async_send()
- .await
- .error()
- }
-
- pub async fn get_primary_field(&self, database_view_id: &str) -> FieldPB {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::GetPrimaryField)
- .payload(DatabaseViewIdPB {
- value: database_view_id.to_string(),
- })
- .async_send()
- .await
- .parse::()
- }
-
- pub async fn create_row(
- &self,
- view_id: &str,
- start_row_id: Option,
- data: Option,
- ) -> RowMetaPB {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::CreateRow)
- .payload(CreateRowPayloadPB {
- view_id: view_id.to_string(),
- start_row_id,
- group_id: None,
- data,
- })
- .async_send()
- .await
- .parse::()
- }
-
- pub async fn delete_row(&self, view_id: &str, row_id: &str) -> Option {
- EventBuilder::new(self.clone())
- .event(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(DatabaseEvent::GetRow)
- .payload(RowIdPB {
- view_id: view_id.to_string(),
- row_id: row_id.to_string(),
- group_id: None,
- })
- .async_send()
- .await
- .parse::()
- }
-
- pub async fn get_row_meta(&self, view_id: &str, row_id: &str) -> RowMetaPB {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::GetRowMeta)
- .payload(RowIdPB {
- view_id: view_id.to_string(),
- row_id: row_id.to_string(),
- group_id: None,
- })
- .async_send()
- .await
- .parse::()
- }
-
- pub async fn update_row_meta(&self, changeset: UpdateRowMetaChangesetPB) -> Option {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::UpdateRowMeta)
- .payload(changeset)
- .async_send()
- .await
- .error()
- }
-
- pub async fn duplicate_row(&self, view_id: &str, row_id: &str) -> Option {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::DuplicateRow)
- .payload(RowIdPB {
- view_id: view_id.to_string(),
- row_id: row_id.to_string(),
- group_id: None,
- })
- .async_send()
- .await
- .error()
- }
-
- pub async fn move_row(&self, view_id: &str, row_id: &str, to_row_id: &str) -> Option {
- EventBuilder::new(self.clone())
- .event(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 {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::UpdateCell)
- .payload(changeset)
- .async_send()
- .await
- .error()
- }
-
- pub async fn update_date_cell(&self, changeset: DateChangesetPB) -> Option {
- EventBuilder::new(self.clone())
- .event(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(DatabaseEvent::GetCell)
- .payload(CellIdPB {
- view_id: view_id.to_string(),
- row_id: row_id.to_string(),
- field_id: field_id.to_string(),
- })
- .async_send()
- .await
- .parse::()
- }
-
- 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 {
- let cell = self.get_cell(view_id, row_id, field_id).await;
- ChecklistCellDataPB::try_from(Bytes::from(cell.data)).unwrap()
- }
-
- pub async fn update_checklist_cell(
- &self,
- changeset: ChecklistCellDataChangesetPB,
- ) -> Option {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::UpdateChecklistCell)
- .payload(changeset)
- .async_send()
- .await
- .error()
- }
-
- pub async fn insert_option(
- &self,
- view_id: &str,
- field_id: &str,
- row_id: &str,
- name: &str,
- ) -> Option {
- let option = EventBuilder::new(self.clone())
- .event(DatabaseEvent::CreateSelectOption)
- .payload(CreateSelectOptionPayloadPB {
- field_id: field_id.to_string(),
- view_id: view_id.to_string(),
- option_name: name.to_string(),
- })
- .async_send()
- .await
- .parse::();
-
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::InsertOrUpdateSelectOption)
- .payload(RepeatedSelectOptionPayload {
- view_id: view_id.to_string(),
- field_id: field_id.to_string(),
- row_id: row_id.to_string(),
- items: vec![option],
- })
- .async_send()
- .await
- .error()
- }
-
- pub async fn get_groups(&self, view_id: &str) -> Vec {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::GetGroups)
- .payload(DatabaseViewIdPB {
- value: view_id.to_string(),
- })
- .async_send()
- .await
- .parse::()
- .items
- }
-
- pub async fn move_group(&self, view_id: &str, from_id: &str, to_id: &str) -> Option {
- EventBuilder::new(self.clone())
- .event(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 {
- EventBuilder::new(self.clone())
- .event(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,
- visible: Option,
- ) -> Option {
- EventBuilder::new(self.clone())
- .event(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 {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::UpdateDatabaseSetting)
- .payload(changeset)
- .async_send()
- .await
- .error()
- }
-
- pub async fn get_all_calendar_events(&self, view_id: &str) -> Vec {
- EventBuilder::new(self.clone())
- .event(DatabaseEvent::GetAllCalendarEvents)
- .payload(CalendarEventRequestPB {
- view_id: view_id.to_string(),
- })
- .async_send()
- .await
- .parse::()
- .items
- }
-
- pub async fn get_view(&self, view_id: &str) -> ViewPB {
- EventBuilder::new(self.clone())
- .event(FolderEvent::ReadView)
- .payload(ViewIdPB {
- value: view_id.to_string(),
- })
- .async_send()
- .await
- .parse::()
- }
}
-impl std::ops::Deref for FlowyCoreTest {
+impl std::ops::Deref for EventIntegrationTest {
type Target = AppFlowyCore;
fn deref(&self) -> &Self::Target {
@@ -841,89 +72,6 @@ impl std::ops::Deref for FlowyCoreTest {
}
}
-#[derive(Clone)]
-pub struct TestNotificationSender {
- sender: Arc>,
-}
-
-impl Default for TestNotificationSender {
- fn default() -> Self {
- let (sender, _) = channel(1000);
- Self {
- sender: Arc::new(sender),
- }
- }
-}
-
-impl TestNotificationSender {
- pub fn new() -> Self {
- Self::default()
- }
-
- pub fn subscribe(&self, id: &str, ty: impl Into + Send) -> tokio::sync::mpsc::Receiver
- where
- T: TryFrom + Send + 'static,
- {
- let id = id.to_string();
- let (tx, rx) = tokio::sync::mpsc::channel::(10);
- let mut receiver = self.sender.subscribe();
- let ty = ty.into();
- tokio::spawn(async move {
- // DatabaseNotification::DidUpdateDatabaseSnapshotState
- while let Ok(value) = receiver.recv().await {
- if value.id == id && value.ty == ty {
- if let Some(payload) = value.payload {
- match T::try_from(Bytes::from(payload)) {
- Ok(object) => {
- let _ = tx.send(object).await;
- },
- Err(e) => {
- panic!(
- "Failed to parse notification payload to type: {:?} with error: {}",
- std::any::type_name::(),
- e
- );
- },
- }
- }
- }
- }
- });
- rx
- }
-
- pub fn subscribe_with_condition(&self, id: &str, when: F) -> tokio::sync::mpsc::Receiver
- where
- T: TryFrom + Send + 'static,
- F: Fn(&T) -> bool + Send + 'static,
- {
- let id = id.to_string();
- let (tx, rx) = tokio::sync::mpsc::channel::(10);
- let mut receiver = self.sender.subscribe();
- tokio::spawn(async move {
- while let Ok(value) = receiver.recv().await {
- if value.id == id {
- if let Some(payload) = value.payload {
- if let Ok(object) = T::try_from(Bytes::from(payload)) {
- if when(&object) {
- let _ = tx.send(object).await;
- }
- }
- }
- }
- }
- });
- rx
- }
-}
-
-impl NotificationSender for TestNotificationSender {
- fn send_subject(&self, subject: SubscribeObject) -> Result<(), String> {
- let _ = self.sender.send(subject);
- Ok(())
- }
-}
-
pub struct Cleaner(PathBuf);
impl Cleaner {
@@ -941,25 +89,3 @@ impl Drop for Cleaner {
Self::cleanup(&self.0)
}
}
-
-pub fn third_party_sign_up_param(uuid: String) -> HashMap {
- let mut params = HashMap::new();
- params.insert(USER_UUID.to_string(), uuid);
- params.insert(
- USER_EMAIL.to_string(),
- format!("{}@test.com", Uuid::new_v4()),
- );
- params.insert(USER_DEVICE_ID.to_string(), Uuid::new_v4().to_string());
- params
-}
-
-pub fn assert_document_data_equal(collab_update: &[u8], doc_id: &str, expected: DocumentData) {
- let collab = MutexCollab::new(CollabOrigin::Server, doc_id, vec![]);
- collab.lock().with_origin_transact_mut(|txn| {
- let update = Update::decode_v1(collab_update).unwrap();
- txn.apply_update(update);
- });
- let document = Document::open(Arc::new(collab)).unwrap();
- let actual = document.get_document_data().unwrap();
- assert_eq!(actual, expected);
-}
diff --git a/frontend/rust-lib/event-integration/src/test_database.rs b/frontend/rust-lib/event-integration/src/test_database.rs
new file mode 100644
index 000000000000..ebd258e4b131
--- /dev/null
+++ b/frontend/rust-lib/event-integration/src/test_database.rs
@@ -0,0 +1,447 @@
+use std::convert::TryFrom;
+
+use bytes::Bytes;
+
+use flowy_database2::entities::*;
+use flowy_database2::event_map::DatabaseEvent;
+use flowy_folder2::entities::*;
+use flowy_folder2::event_map::FolderEvent;
+use flowy_user::errors::FlowyError;
+
+use crate::event_builder::EventBuilder;
+use crate::EventIntegrationTest;
+
+impl EventIntegrationTest {
+ pub async fn create_grid(&self, parent_id: &str, name: String, initial_data: Vec) -> ViewPB {
+ let payload = CreateViewPayloadPB {
+ parent_view_id: parent_id.to_string(),
+ name,
+ desc: "".to_string(),
+ thumbnail: None,
+ layout: ViewLayoutPB::Grid,
+ initial_data,
+ meta: Default::default(),
+ set_as_current: true,
+ index: None,
+ };
+ EventBuilder::new(self.clone())
+ .event(FolderEvent::CreateView)
+ .payload(payload)
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ pub async fn open_database(&self, view_id: &str) {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::GetDatabase)
+ .payload(DatabaseViewIdPB {
+ value: view_id.to_string(),
+ })
+ .async_send()
+ .await;
+ }
+
+ pub async fn create_board(&self, parent_id: &str, name: String, initial_data: Vec) -> 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,
+ index: None,
+ };
+ EventBuilder::new(self.clone())
+ .event(FolderEvent::CreateView)
+ .payload(payload)
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ pub async fn create_calendar(
+ &self,
+ parent_id: &str,
+ name: String,
+ initial_data: Vec,
+ ) -> 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,
+ index: None,
+ };
+ EventBuilder::new(self.clone())
+ .event(FolderEvent::CreateView)
+ .payload(payload)
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ pub async fn get_database(&self, view_id: &str) -> DatabasePB {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::GetDatabase)
+ .payload(DatabaseViewIdPB {
+ value: view_id.to_string(),
+ })
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ pub async fn get_all_database_fields(&self, view_id: &str) -> RepeatedFieldPB {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::GetFields)
+ .payload(GetFieldPayloadPB {
+ view_id: view_id.to_string(),
+ field_ids: None,
+ })
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ pub async fn create_field(&self, view_id: &str, field_type: FieldType) -> FieldPB {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::CreateTypeOption)
+ .payload(CreateFieldPayloadPB {
+ view_id: view_id.to_string(),
+ field_type,
+ type_option_data: None,
+ })
+ .async_send()
+ .await
+ .parse::()
+ .field
+ }
+
+ pub async fn update_field(&self, changeset: FieldChangesetPB) {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::UpdateField)
+ .payload(changeset)
+ .async_send()
+ .await;
+ }
+
+ pub async fn delete_field(&self, view_id: &str, field_id: &str) -> Option {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::DeleteField)
+ .payload(DeleteFieldPayloadPB {
+ view_id: view_id.to_string(),
+ field_id: field_id.to_string(),
+ })
+ .async_send()
+ .await
+ .error()
+ }
+
+ pub async fn update_field_type(
+ &self,
+ view_id: &str,
+ field_id: &str,
+ field_type: FieldType,
+ ) -> Option {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::UpdateFieldType)
+ .payload(UpdateFieldTypePayloadPB {
+ view_id: view_id.to_string(),
+ field_id: field_id.to_string(),
+ field_type,
+ })
+ .async_send()
+ .await
+ .error()
+ }
+
+ pub async fn duplicate_field(&self, view_id: &str, field_id: &str) -> Option {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::DuplicateField)
+ .payload(DuplicateFieldPayloadPB {
+ view_id: view_id.to_string(),
+ field_id: field_id.to_string(),
+ })
+ .async_send()
+ .await
+ .error()
+ }
+
+ pub async fn get_primary_field(&self, database_view_id: &str) -> FieldPB {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::GetPrimaryField)
+ .payload(DatabaseViewIdPB {
+ value: database_view_id.to_string(),
+ })
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ pub async fn create_row(
+ &self,
+ view_id: &str,
+ start_row_id: Option,
+ data: Option,
+ ) -> RowMetaPB {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::CreateRow)
+ .payload(CreateRowPayloadPB {
+ view_id: view_id.to_string(),
+ start_row_id,
+ group_id: None,
+ data,
+ })
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ pub async fn delete_row(&self, view_id: &str, row_id: &str) -> Option {
+ EventBuilder::new(self.clone())
+ .event(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(DatabaseEvent::GetRow)
+ .payload(RowIdPB {
+ view_id: view_id.to_string(),
+ row_id: row_id.to_string(),
+ group_id: None,
+ })
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ pub async fn get_row_meta(&self, view_id: &str, row_id: &str) -> RowMetaPB {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::GetRowMeta)
+ .payload(RowIdPB {
+ view_id: view_id.to_string(),
+ row_id: row_id.to_string(),
+ group_id: None,
+ })
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ pub async fn update_row_meta(&self, changeset: UpdateRowMetaChangesetPB) -> Option {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::UpdateRowMeta)
+ .payload(changeset)
+ .async_send()
+ .await
+ .error()
+ }
+
+ pub async fn duplicate_row(&self, view_id: &str, row_id: &str) -> Option {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::DuplicateRow)
+ .payload(RowIdPB {
+ view_id: view_id.to_string(),
+ row_id: row_id.to_string(),
+ group_id: None,
+ })
+ .async_send()
+ .await
+ .error()
+ }
+
+ pub async fn move_row(&self, view_id: &str, row_id: &str, to_row_id: &str) -> Option {
+ EventBuilder::new(self.clone())
+ .event(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 {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::UpdateCell)
+ .payload(changeset)
+ .async_send()
+ .await
+ .error()
+ }
+
+ pub async fn update_date_cell(&self, changeset: DateChangesetPB) -> Option {
+ EventBuilder::new(self.clone())
+ .event(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(DatabaseEvent::GetCell)
+ .payload(CellIdPB {
+ view_id: view_id.to_string(),
+ row_id: row_id.to_string(),
+ field_id: field_id.to_string(),
+ })
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ 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 {
+ let cell = self.get_cell(view_id, row_id, field_id).await;
+ ChecklistCellDataPB::try_from(Bytes::from(cell.data)).unwrap()
+ }
+
+ pub async fn update_checklist_cell(
+ &self,
+ changeset: ChecklistCellDataChangesetPB,
+ ) -> Option {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::UpdateChecklistCell)
+ .payload(changeset)
+ .async_send()
+ .await
+ .error()
+ }
+
+ pub async fn insert_option(
+ &self,
+ view_id: &str,
+ field_id: &str,
+ row_id: &str,
+ name: &str,
+ ) -> Option {
+ let option = EventBuilder::new(self.clone())
+ .event(DatabaseEvent::CreateSelectOption)
+ .payload(CreateSelectOptionPayloadPB {
+ field_id: field_id.to_string(),
+ view_id: view_id.to_string(),
+ option_name: name.to_string(),
+ })
+ .async_send()
+ .await
+ .parse::();
+
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::InsertOrUpdateSelectOption)
+ .payload(RepeatedSelectOptionPayload {
+ view_id: view_id.to_string(),
+ field_id: field_id.to_string(),
+ row_id: row_id.to_string(),
+ items: vec![option],
+ })
+ .async_send()
+ .await
+ .error()
+ }
+
+ pub async fn get_groups(&self, view_id: &str) -> Vec {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::GetGroups)
+ .payload(DatabaseViewIdPB {
+ value: view_id.to_string(),
+ })
+ .async_send()
+ .await
+ .parse::()
+ .items
+ }
+
+ pub async fn move_group(&self, view_id: &str, from_id: &str, to_id: &str) -> Option {
+ EventBuilder::new(self.clone())
+ .event(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 {
+ EventBuilder::new(self.clone())
+ .event(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,
+ visible: Option,
+ ) -> Option {
+ EventBuilder::new(self.clone())
+ .event(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 {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::UpdateDatabaseSetting)
+ .payload(changeset)
+ .async_send()
+ .await
+ .error()
+ }
+
+ pub async fn get_all_calendar_events(&self, view_id: &str) -> Vec {
+ EventBuilder::new(self.clone())
+ .event(DatabaseEvent::GetAllCalendarEvents)
+ .payload(CalendarEventRequestPB {
+ view_id: view_id.to_string(),
+ })
+ .async_send()
+ .await
+ .parse::()
+ .items
+ }
+}
diff --git a/frontend/rust-lib/event-integration/src/test_document.rs b/frontend/rust-lib/event-integration/src/test_document.rs
new file mode 100644
index 000000000000..45029f2d3660
--- /dev/null
+++ b/frontend/rust-lib/event-integration/src/test_document.rs
@@ -0,0 +1,119 @@
+use std::sync::Arc;
+
+use collab::core::collab::MutexCollab;
+use collab::core::origin::CollabOrigin;
+use collab::preclude::updates::decoder::Decode;
+use collab::preclude::{merge_updates_v1, Update};
+use collab_document::blocks::DocumentData;
+use collab_document::document::Document;
+
+use flowy_document2::entities::{DocumentDataPB, OpenDocumentPayloadPB};
+use flowy_document2::event_map::DocumentEvent;
+use flowy_folder2::entities::{CreateViewPayloadPB, ViewLayoutPB, ViewPB};
+use flowy_folder2::event_map::FolderEvent;
+
+use crate::document::document_event::{DocumentEventTest, OpenDocumentData};
+use crate::event_builder::EventBuilder;
+use crate::EventIntegrationTest;
+
+impl EventIntegrationTest {
+ pub async fn create_document(
+ &self,
+ parent_id: &str,
+ name: String,
+ initial_data: Vec,
+ ) -> ViewPB {
+ let payload = CreateViewPayloadPB {
+ parent_view_id: parent_id.to_string(),
+ name,
+ desc: "".to_string(),
+ thumbnail: None,
+ layout: ViewLayoutPB::Document,
+ initial_data,
+ meta: Default::default(),
+ set_as_current: true,
+ index: None,
+ };
+ let view = EventBuilder::new(self.clone())
+ .event(FolderEvent::CreateView)
+ .payload(payload)
+ .async_send()
+ .await
+ .parse::();
+
+ let payload = OpenDocumentPayloadPB {
+ document_id: view.id.clone(),
+ };
+
+ let _ = EventBuilder::new(self.clone())
+ .event(DocumentEvent::OpenDocument)
+ .payload(payload)
+ .async_send()
+ .await
+ .parse::();
+
+ view
+ }
+ pub async fn open_document(&self, doc_id: String) -> OpenDocumentData {
+ let payload = OpenDocumentPayloadPB {
+ document_id: doc_id.clone(),
+ };
+ let data = EventBuilder::new(self.clone())
+ .event(DocumentEvent::OpenDocument)
+ .payload(payload)
+ .async_send()
+ .await
+ .parse::();
+ OpenDocumentData { id: doc_id, data }
+ }
+ pub async fn insert_document_text(&self, document_id: &str, text: &str, index: usize) {
+ let document_event = DocumentEventTest::new_with_core(self.clone());
+ document_event
+ .insert_index(document_id, text, index, None)
+ .await;
+ }
+
+ pub async fn get_document_data(&self, view_id: &str) -> DocumentData {
+ let pb = EventBuilder::new(self.clone())
+ .event(DocumentEvent::GetDocumentData)
+ .payload(OpenDocumentPayloadPB {
+ document_id: view_id.to_string(),
+ })
+ .async_send()
+ .await
+ .parse::();
+
+ DocumentData::from(pb)
+ }
+
+ pub async fn get_document_update(&self, document_id: &str) -> Vec {
+ let workspace_id = self.user_manager.workspace_id().unwrap();
+ let cloud_service = self.document_manager.get_cloud_service().clone();
+ let remote_updates = cloud_service
+ .get_document_updates(document_id, &workspace_id)
+ .await
+ .unwrap();
+
+ if remote_updates.is_empty() {
+ return vec![];
+ }
+
+ let updates = remote_updates
+ .iter()
+ .map(|update| update.as_ref())
+ .collect::>();
+
+ merge_updates_v1(&updates).unwrap()
+ }
+}
+
+pub fn assert_document_data_equal(collab_update: &[u8], doc_id: &str, expected: DocumentData) {
+ let collab = MutexCollab::new(CollabOrigin::Server, doc_id, vec![]);
+ collab.lock().with_origin_transact_mut(|txn| {
+ let update = Update::decode_v1(collab_update).unwrap();
+ txn.apply_update(update);
+ });
+ let document = Document::open(Arc::new(collab)).unwrap();
+ let actual = document.get_document_data().unwrap();
+ assert_eq!(actual, expected);
+}
diff --git a/frontend/rust-lib/event-integration/src/test_folder.rs b/frontend/rust-lib/event-integration/src/test_folder.rs
new file mode 100644
index 000000000000..d5f0e7a141c2
--- /dev/null
+++ b/frontend/rust-lib/event-integration/src/test_folder.rs
@@ -0,0 +1,173 @@
+use flowy_folder2::entities::icon::UpdateViewIconPayloadPB;
+use flowy_folder2::entities::*;
+use flowy_folder2::event_map::FolderEvent;
+use flowy_folder2::event_map::FolderEvent::*;
+use flowy_user::errors::FlowyError;
+
+use crate::event_builder::EventBuilder;
+use crate::EventIntegrationTest;
+
+impl EventIntegrationTest {
+ // Must sign up/ sign in first
+ pub async fn get_current_workspace(&self) -> WorkspaceSettingPB {
+ EventBuilder::new(self.clone())
+ .event(FolderEvent::GetCurrentWorkspace)
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ pub async fn get_all_workspace_views(&self) -> Vec {
+ EventBuilder::new(self.clone())
+ .event(FolderEvent::ReadWorkspaceViews)
+ .async_send()
+ .await
+ .parse::()
+ .items
+ }
+
+ pub async fn get_views(&self, parent_view_id: &str) -> ViewPB {
+ EventBuilder::new(self.clone())
+ .event(FolderEvent::ReadView)
+ .payload(ViewIdPB {
+ value: parent_view_id.to_string(),
+ })
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ 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(FolderEvent::DeleteView)
+ .payload(payload)
+ .async_send()
+ .await;
+ }
+
+ pub async fn update_view(&self, changeset: UpdateViewPayloadPB) -> Option {
+ // delete the view. the view will be moved to trash
+ EventBuilder::new(self.clone())
+ .event(FolderEvent::UpdateView)
+ .payload(changeset)
+ .async_send()
+ .await
+ .error()
+ }
+
+ pub async fn update_view_icon(&self, payload: UpdateViewIconPayloadPB) -> Option {
+ EventBuilder::new(self.clone())
+ .event(FolderEvent::UpdateViewIcon)
+ .payload(payload)
+ .async_send()
+ .await
+ .error()
+ }
+
+ 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,
+ index: None,
+ };
+ EventBuilder::new(self.clone())
+ .event(FolderEvent::CreateView)
+ .payload(payload)
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ pub async fn get_view(&self, view_id: &str) -> ViewPB {
+ EventBuilder::new(self.clone())
+ .event(FolderEvent::ReadView)
+ .payload(ViewIdPB {
+ value: view_id.to_string(),
+ })
+ .async_send()
+ .await
+ .parse::()
+ }
+}
+
+pub struct ViewTest {
+ pub sdk: EventIntegrationTest,
+ pub workspace: WorkspacePB,
+ pub child_view: ViewPB,
+}
+
+impl ViewTest {
+ #[allow(dead_code)]
+ pub async fn new(sdk: &EventIntegrationTest, layout: ViewLayoutPB, data: Vec) -> Self {
+ let workspace = create_workspace(sdk, "Workspace", "").await;
+ let payload = WorkspaceIdPB {
+ value: Some(workspace.id.clone()),
+ };
+ let _ = EventBuilder::new(sdk.clone())
+ .event(OpenWorkspace)
+ .payload(payload)
+ .async_send()
+ .await;
+
+ let payload = CreateViewPayloadPB {
+ parent_view_id: workspace.id.clone(),
+ name: "View A".to_string(),
+ desc: "".to_string(),
+ thumbnail: Some("http://1.png".to_string()),
+ layout,
+ initial_data: data,
+ meta: Default::default(),
+ set_as_current: true,
+ index: None,
+ };
+
+ let view = EventBuilder::new(sdk.clone())
+ .event(CreateView)
+ .payload(payload)
+ .async_send()
+ .await
+ .parse::();
+ Self {
+ sdk: sdk.clone(),
+ workspace,
+ child_view: view,
+ }
+ }
+
+ pub async fn new_grid_view(sdk: &EventIntegrationTest, data: Vec) -> Self {
+ Self::new(sdk, ViewLayoutPB::Grid, data).await
+ }
+
+ pub async fn new_board_view(sdk: &EventIntegrationTest, data: Vec) -> Self {
+ Self::new(sdk, ViewLayoutPB::Board, data).await
+ }
+
+ pub async fn new_calendar_view(sdk: &EventIntegrationTest, data: Vec) -> Self {
+ Self::new(sdk, ViewLayoutPB::Calendar, data).await
+ }
+}
+
+async fn create_workspace(sdk: &EventIntegrationTest, name: &str, desc: &str) -> WorkspacePB {
+ let request = CreateWorkspacePayloadPB {
+ name: name.to_owned(),
+ desc: desc.to_owned(),
+ };
+
+ EventBuilder::new(sdk.clone())
+ .event(CreateWorkspace)
+ .payload(request)
+ .async_send()
+ .await
+ .parse::()
+}
diff --git a/frontend/rust-lib/event-integration/src/test_user.rs b/frontend/rust-lib/event-integration/src/test_user.rs
new file mode 100644
index 000000000000..b09c4b9acc3b
--- /dev/null
+++ b/frontend/rust-lib/event-integration/src/test_user.rs
@@ -0,0 +1,296 @@
+use std::collections::HashMap;
+use std::convert::TryFrom;
+use std::sync::Arc;
+
+use bytes::Bytes;
+use nanoid::nanoid;
+use protobuf::ProtobufError;
+use tokio::sync::broadcast::{channel, Sender};
+use uuid::Uuid;
+
+use flowy_notification::entities::SubscribeObject;
+use flowy_notification::NotificationSender;
+use flowy_server::supabase::define::{USER_DEVICE_ID, USER_EMAIL, USER_SIGN_IN_URL, USER_UUID};
+use flowy_user::entities::{
+ AuthTypePB, OauthSignInPB, SignInUrlPB, SignInUrlPayloadPB, SignUpPayloadPB, UpdateCloudConfigPB,
+ UpdateUserProfilePayloadPB, UserCloudConfigPB, UserProfilePB,
+};
+use flowy_user::errors::{FlowyError, FlowyResult};
+use flowy_user::event_map::UserEvent::*;
+use lib_dispatch::prelude::{AFPluginDispatcher, AFPluginRequest, ToBytes};
+
+use crate::event_builder::EventBuilder;
+use crate::EventIntegrationTest;
+
+impl EventIntegrationTest {
+ pub async fn enable_encryption(&self) -> String {
+ let config = EventBuilder::new(self.clone())
+ .event(GetCloudConfig)
+ .async_send()
+ .await
+ .parse::();
+ let update = UpdateCloudConfigPB {
+ enable_sync: None,
+ enable_encrypt: Some(true),
+ };
+ let error = EventBuilder::new(self.clone())
+ .event(SetCloudConfig)
+ .payload(update)
+ .async_send()
+ .await
+ .error();
+ assert!(error.is_none());
+ config.encrypt_secret
+ }
+
+ pub async fn new_with_guest_user() -> Self {
+ let test = Self::default();
+ test.sign_up_as_guest().await;
+ test
+ }
+
+ pub async fn sign_up_as_guest(&self) -> SignUpContext {
+ let password = login_password();
+ let email = unique_email();
+ let payload = SignUpPayloadPB {
+ email,
+ name: "appflowy".to_string(),
+ password: password.clone(),
+ auth_type: AuthTypePB::Local,
+ device_id: uuid::Uuid::new_v4().to_string(),
+ }
+ .into_bytes()
+ .unwrap();
+
+ let request = AFPluginRequest::new(SignUp).payload(payload);
+ let user_profile = AFPluginDispatcher::async_send(self.inner.dispatcher(), request)
+ .await
+ .parse::()
+ .unwrap()
+ .unwrap();
+
+ // let _ = create_default_workspace_if_need(dispatch.clone(), &user_profile.id);
+ SignUpContext {
+ user_profile,
+ password,
+ }
+ }
+
+ pub async fn af_cloud_sign_up(&self) -> UserProfilePB {
+ let email = unique_email();
+ self.af_cloud_sign_in_with_email(&email).await.unwrap()
+ }
+
+ pub async fn supabase_party_sign_up(&self) -> UserProfilePB {
+ let map = third_party_sign_up_param(Uuid::new_v4().to_string());
+ let payload = OauthSignInPB {
+ map,
+ auth_type: AuthTypePB::Supabase,
+ };
+
+ EventBuilder::new(self.clone())
+ .event(OauthSignIn)
+ .payload(payload)
+ .async_send()
+ .await
+ .parse::()
+ }
+
+ pub async fn sign_out(&self) {
+ EventBuilder::new(self.clone())
+ .event(SignOut)
+ .async_send()
+ .await;
+ }
+
+ pub fn set_auth_type(&self, auth_type: AuthTypePB) {
+ *self.auth_type.write() = auth_type;
+ }
+
+ pub async fn init_user(&self) -> UserProfilePB {
+ self.sign_up_as_guest().await.user_profile
+ }
+
+ pub async fn get_user_profile(&self) -> Result {
+ EventBuilder::new(self.clone())
+ .event(GetUserProfile)
+ .async_send()
+ .await
+ .try_parse::()
+ }
+
+ pub async fn update_user_profile(&self, params: UpdateUserProfilePayloadPB) {
+ EventBuilder::new(self.clone())
+ .event(UpdateUserProfile)
+ .payload(params)
+ .async_send()
+ .await;
+ }
+
+ pub async fn af_cloud_sign_in_with_email(&self, email: &str) -> FlowyResult {
+ let payload = SignInUrlPayloadPB {
+ email: email.to_string(),
+ auth_type: AuthTypePB::AFCloud,
+ };
+ let sign_in_url = EventBuilder::new(self.clone())
+ .event(GetSignInURL)
+ .payload(payload)
+ .async_send()
+ .await
+ .try_parse::()?
+ .sign_in_url;
+
+ let mut map = HashMap::new();
+ map.insert(USER_SIGN_IN_URL.to_string(), sign_in_url);
+ map.insert(USER_DEVICE_ID.to_string(), Uuid::new_v4().to_string());
+ let payload = OauthSignInPB {
+ map,
+ auth_type: AuthTypePB::AFCloud,
+ };
+
+ let user_profile = EventBuilder::new(self.clone())
+ .event(OauthSignIn)
+ .payload(payload)
+ .async_send()
+ .await
+ .try_parse::()?;
+
+ Ok(user_profile)
+ }
+
+ pub async fn supabase_sign_up_with_uuid(
+ &self,
+ uuid: &str,
+ email: Option,
+ ) -> FlowyResult {
+ let mut map = HashMap::new();
+ map.insert(USER_UUID.to_string(), uuid.to_string());
+ map.insert(USER_DEVICE_ID.to_string(), uuid.to_string());
+ map.insert(
+ USER_EMAIL.to_string(),
+ email.unwrap_or_else(|| format!("{}@appflowy.io", nanoid!(10))),
+ );
+ let payload = OauthSignInPB {
+ map,
+ auth_type: AuthTypePB::Supabase,
+ };
+
+ let user_profile = EventBuilder::new(self.clone())
+ .event(OauthSignIn)
+ .payload(payload)
+ .async_send()
+ .await
+ .try_parse::()?;
+
+ Ok(user_profile)
+ }
+}
+
+#[derive(Clone)]
+pub struct TestNotificationSender {
+ sender: Arc>,
+}
+
+impl Default for TestNotificationSender {
+ fn default() -> Self {
+ let (sender, _) = channel(1000);
+ Self {
+ sender: Arc::new(sender),
+ }
+ }
+}
+
+impl TestNotificationSender {
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ pub fn subscribe(&self, id: &str, ty: impl Into + Send) -> tokio::sync::mpsc::Receiver
+ where
+ T: TryFrom + Send + 'static,
+ {
+ let id = id.to_string();
+ let (tx, rx) = tokio::sync::mpsc::channel::(10);
+ let mut receiver = self.sender.subscribe();
+ let ty = ty.into();
+ tokio::spawn(async move {
+ // DatabaseNotification::DidUpdateDatabaseSnapshotState
+ while let Ok(value) = receiver.recv().await {
+ if value.id == id && value.ty == ty {
+ if let Some(payload) = value.payload {
+ match T::try_from(Bytes::from(payload)) {
+ Ok(object) => {
+ let _ = tx.send(object).await;
+ },
+ Err(e) => {
+ panic!(
+ "Failed to parse notification payload to type: {:?} with error: {}",
+ std::any::type_name::(),
+ e
+ );
+ },
+ }
+ }
+ }
+ }
+ });
+ rx
+ }
+
+ pub fn subscribe_with_condition(&self, id: &str, when: F) -> tokio::sync::mpsc::Receiver
+ where
+ T: TryFrom + Send + 'static,
+ F: Fn(&T) -> bool + Send + 'static,
+ {
+ let id = id.to_string();
+ let (tx, rx) = tokio::sync::mpsc::channel::(10);
+ let mut receiver = self.sender.subscribe();
+ tokio::spawn(async move {
+ while let Ok(value) = receiver.recv().await {
+ if value.id == id {
+ if let Some(payload) = value.payload {
+ if let Ok(object) = T::try_from(Bytes::from(payload)) {
+ if when(&object) {
+ let _ = tx.send(object).await;
+ }
+ }
+ }
+ }
+ }
+ });
+ rx
+ }
+}
+impl NotificationSender for TestNotificationSender {
+ fn send_subject(&self, subject: SubscribeObject) -> Result<(), String> {
+ let _ = self.sender.send(subject);
+ Ok(())
+ }
+}
+
+pub fn third_party_sign_up_param(uuid: String) -> HashMap {
+ let mut params = HashMap::new();
+ params.insert(USER_UUID.to_string(), uuid);
+ params.insert(
+ USER_EMAIL.to_string(),
+ format!("{}@test.com", Uuid::new_v4()),
+ );
+ params.insert(USER_DEVICE_ID.to_string(), Uuid::new_v4().to_string());
+ params
+}
+
+pub fn unique_email() -> String {
+ format!("{}@appflowy.io", Uuid::new_v4())
+}
+
+pub fn login_email() -> String {
+ "annie2@appflowy.io".to_string()
+}
+
+pub fn login_password() -> String {
+ "HelloWorld!123".to_string()
+}
+pub struct SignUpContext {
+ pub user_profile: UserProfilePB,
+ pub password: String,
+}
diff --git a/frontend/rust-lib/event-integration/src/user_event.rs b/frontend/rust-lib/event-integration/src/user_event.rs
deleted file mode 100644
index 67e44e732e6f..000000000000
--- a/frontend/rust-lib/event-integration/src/user_event.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-use std::sync::Arc;
-
-use nanoid::nanoid;
-
-use flowy_user::entities::{AuthTypePB, SignUpPayloadPB, UserProfilePB};
-use flowy_user::errors::FlowyError;
-use flowy_user::event_map::UserEvent::*;
-use lib_dispatch::prelude::{AFPluginDispatcher, AFPluginRequest, ToBytes};
-
-pub fn random_email() -> String {
- format!("{}@appflowy.io", nanoid!(20))
-}
-
-pub fn login_email() -> String {
- "annie2@appflowy.io".to_string()
-}
-
-pub fn login_password() -> String {
- "HelloWorld!123".to_string()
-}
-
-pub struct SignUpContext {
- pub user_profile: UserProfilePB,
- pub password: String,
-}
-
-pub fn sign_up(dispatch: Arc) -> SignUpContext {
- let password = login_password();
- let payload = SignUpPayloadPB {
- email: random_email(),
- name: "app flowy".to_string(),
- password: password.clone(),
- auth_type: AuthTypePB::Local,
- device_id: uuid::Uuid::new_v4().to_string(),
- }
- .into_bytes()
- .unwrap();
-
- let request = AFPluginRequest::new(SignUp).payload(payload);
- let user_profile = AFPluginDispatcher::sync_send(dispatch, request)
- .parse::()
- .unwrap()
- .unwrap();
-
- SignUpContext {
- user_profile,
- password,
- }
-}
-
-pub async fn async_sign_up(
- dispatch: Arc,
- auth_type: AuthTypePB,
-) -> SignUpContext {
- let password = login_password();
- let email = random_email();
- let payload = SignUpPayloadPB {
- email,
- name: "appflowy".to_string(),
- password: password.clone(),
- auth_type,
- device_id: uuid::Uuid::new_v4().to_string(),
- }
- .into_bytes()
- .unwrap();
-
- let request = AFPluginRequest::new(SignUp).payload(payload);
- let user_profile = AFPluginDispatcher::async_send(dispatch.clone(), request)
- .await
- .parse::()
- .unwrap()
- .unwrap();
-
- // let _ = create_default_workspace_if_need(dispatch.clone(), &user_profile.id);
- SignUpContext {
- user_profile,
- password,
- }
-}
-
-pub async fn init_user_setting(dispatch: Arc) {
- let request = AFPluginRequest::new(InitUser);
- let _ = AFPluginDispatcher::async_send(dispatch.clone(), request).await;
-}
diff --git a/frontend/rust-lib/event-integration/tests/database/local_test/test.rs b/frontend/rust-lib/event-integration/tests/database/local_test/test.rs
index d21a1596ceb5..03c7d5cbd36e 100644
--- a/frontend/rust-lib/event-integration/tests/database/local_test/test.rs
+++ b/frontend/rust-lib/event-integration/tests/database/local_test/test.rs
@@ -3,7 +3,7 @@ use std::convert::TryFrom;
use bytes::Bytes;
use event_integration::event_builder::EventBuilder;
-use event_integration::FlowyCoreTest;
+use event_integration::EventIntegrationTest;
use flowy_database2::entities::{
CellChangesetPB, CellIdPB, ChecklistCellDataChangesetPB, DatabaseLayoutPB,
DatabaseSettingChangesetPB, DatabaseViewIdPB, DateChangesetPB, FieldType, SelectOptionCellDataPB,
@@ -13,7 +13,7 @@ use lib_infra::util::timestamp;
#[tokio::test]
async fn get_database_id_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -35,7 +35,7 @@ async fn get_database_id_event_test() {
#[tokio::test]
async fn get_database_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -49,7 +49,7 @@ async fn get_database_event_test() {
#[tokio::test]
async fn get_field_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -64,7 +64,7 @@ async fn get_field_event_test() {
#[tokio::test]
async fn create_field_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -78,7 +78,7 @@ async fn create_field_event_test() {
#[tokio::test]
async fn delete_field_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -99,7 +99,7 @@ async fn delete_field_event_test() {
// The primary field is not allowed to be deleted.
#[tokio::test]
async fn delete_primary_field_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -114,7 +114,7 @@ async fn delete_primary_field_event_test() {
#[tokio::test]
async fn update_field_type_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -132,7 +132,7 @@ async fn update_field_type_event_test() {
#[tokio::test]
async fn update_primary_field_type_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -151,7 +151,7 @@ async fn update_primary_field_type_event_test() {
#[tokio::test]
async fn duplicate_field_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -169,7 +169,7 @@ async fn duplicate_field_event_test() {
// 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_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -183,7 +183,7 @@ async fn duplicate_primary_field_test() {
#[tokio::test]
async fn get_primary_field_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -196,7 +196,7 @@ async fn get_primary_field_event_test() {
#[tokio::test]
async fn create_row_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -209,7 +209,7 @@ async fn create_row_event_test() {
#[tokio::test]
async fn delete_row_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -232,7 +232,7 @@ async fn delete_row_event_test() {
#[tokio::test]
async fn get_row_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -248,7 +248,7 @@ async fn get_row_event_test() {
#[tokio::test]
async fn update_row_meta_event_with_url_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -276,7 +276,7 @@ async fn update_row_meta_event_with_url_test() {
#[tokio::test]
async fn update_row_meta_event_with_cover_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -304,7 +304,7 @@ async fn update_row_meta_event_with_cover_test() {
#[tokio::test]
async fn delete_row_event_with_invalid_row_id_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -317,7 +317,7 @@ async fn delete_row_event_with_invalid_row_id_test() {
#[tokio::test]
async fn duplicate_row_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -334,7 +334,7 @@ async fn duplicate_row_event_test() {
#[tokio::test]
async fn duplicate_row_event_with_invalid_row_id_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -351,7 +351,7 @@ async fn duplicate_row_event_with_invalid_row_id_test() {
#[tokio::test]
async fn move_row_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -371,7 +371,7 @@ async fn move_row_event_test() {
#[tokio::test]
async fn move_row_event_test2() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -391,7 +391,7 @@ async fn move_row_event_test2() {
#[tokio::test]
async fn move_row_event_with_invalid_row_id_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -418,7 +418,7 @@ async fn move_row_event_with_invalid_row_id_test() {
#[tokio::test]
async fn update_text_cell_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -448,7 +448,7 @@ async fn update_text_cell_event_test() {
#[tokio::test]
async fn update_checkbox_cell_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -479,7 +479,7 @@ async fn update_checkbox_cell_event_test() {
#[tokio::test]
async fn update_single_select_cell_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -506,7 +506,7 @@ async fn update_single_select_cell_event_test() {
#[tokio::test]
async fn update_date_cell_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -543,7 +543,7 @@ async fn update_date_cell_event_test() {
#[tokio::test]
async fn update_date_cell_event_with_empty_time_str_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -579,7 +579,7 @@ async fn update_date_cell_event_with_empty_time_str_test() {
#[tokio::test]
async fn create_checklist_field_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -600,7 +600,7 @@ async fn create_checklist_field_test() {
#[tokio::test]
async fn update_checklist_cell_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -657,7 +657,7 @@ async fn update_checklist_cell_test() {
// 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_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -669,7 +669,7 @@ async fn get_groups_event_with_grid_test() {
#[tokio::test]
async fn get_groups_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -681,7 +681,7 @@ async fn get_groups_event_test() {
#[tokio::test]
async fn move_group_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -715,7 +715,7 @@ async fn move_group_event_test() {
#[tokio::test]
async fn move_group_event_with_invalid_id_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -737,7 +737,7 @@ async fn move_group_event_with_invalid_id_test() {
#[tokio::test]
async fn rename_group_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -761,7 +761,7 @@ async fn rename_group_event_test() {
#[tokio::test]
async fn hide_group_event_test2() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -783,7 +783,7 @@ async fn hide_group_event_test2() {
// Update the database layout type from grid to board
#[tokio::test]
async fn update_database_layout_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -805,7 +805,7 @@ async fn update_database_layout_event_test() {
// 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_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -837,7 +837,7 @@ async fn update_database_layout_event_test2() {
// 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_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -854,7 +854,7 @@ async fn set_group_by_checkbox_field_test() {
#[tokio::test]
async fn get_all_calendar_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
@@ -867,7 +867,7 @@ async fn get_all_calendar_event_test() {
#[tokio::test]
async fn create_calendar_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_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![])
diff --git a/frontend/rust-lib/event-integration/tests/document/af_cloud_test/edit_test.rs b/frontend/rust-lib/event-integration/tests/document/af_cloud_test/edit_test.rs
index 255864a0eead..772b345efa47 100644
--- a/frontend/rust-lib/event-integration/tests/document/af_cloud_test/edit_test.rs
+++ b/frontend/rust-lib/event-integration/tests/document/af_cloud_test/edit_test.rs
@@ -1,6 +1,6 @@
use std::time::Duration;
-use event_integration::assert_document_data_equal;
+use event_integration::test_document::assert_document_data_equal;
use flowy_document2::entities::DocumentSyncStatePB;
use crate::document::af_cloud_test::util::AFCloudDocumentTest;
diff --git a/frontend/rust-lib/event-integration/tests/document/supabase_test/edit_test.rs b/frontend/rust-lib/event-integration/tests/document/supabase_test/edit_test.rs
index e0596e62997a..7300c3773bd8 100644
--- a/frontend/rust-lib/event-integration/tests/document/supabase_test/edit_test.rs
+++ b/frontend/rust-lib/event-integration/tests/document/supabase_test/edit_test.rs
@@ -1,6 +1,6 @@
use std::time::Duration;
-use event_integration::assert_document_data_equal;
+use event_integration::test_document::assert_document_data_equal;
use flowy_document2::entities::DocumentSyncStatePB;
use crate::document::supabase_test::helper::FlowySupabaseDocumentTest;
diff --git a/frontend/rust-lib/event-integration/tests/folder/local_test/script.rs b/frontend/rust-lib/event-integration/tests/folder/local_test/script.rs
index 5e375e6c6ed7..24c56d8f4231 100644
--- a/frontend/rust-lib/event-integration/tests/folder/local_test/script.rs
+++ b/frontend/rust-lib/event-integration/tests/folder/local_test/script.rs
@@ -1,7 +1,7 @@
use collab_folder::core::ViewLayout;
use event_integration::event_builder::EventBuilder;
-use event_integration::FlowyCoreTest;
+use event_integration::EventIntegrationTest;
use flowy_folder2::entities::icon::{UpdateViewIconPayloadPB, ViewIconPB};
use flowy_folder2::entities::*;
use flowy_folder2::event_map::FolderEvent::*;
@@ -64,7 +64,7 @@ pub enum FolderScript {
}
pub struct FolderTest {
- pub sdk: FlowyCoreTest,
+ pub sdk: EventIntegrationTest,
pub all_workspace: Vec,
pub workspace: WorkspacePB,
pub parent_view: ViewPB,
@@ -75,7 +75,7 @@ pub struct FolderTest {
impl FolderTest {
pub async fn new() -> Self {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let _ = sdk.init_user().await;
let workspace = create_workspace(&sdk, "FolderWorkspace", "Folder test workspace").await;
let parent_view = create_app(&sdk, &workspace.id, "Folder App", "Folder test app").await;
@@ -201,7 +201,7 @@ impl FolderTest {
}
}
}
-pub async fn create_workspace(sdk: &FlowyCoreTest, name: &str, desc: &str) -> WorkspacePB {
+pub async fn create_workspace(sdk: &EventIntegrationTest, name: &str, desc: &str) -> WorkspacePB {
let request = CreateWorkspacePayloadPB {
name: name.to_owned(),
desc: desc.to_owned(),
@@ -215,7 +215,10 @@ pub async fn create_workspace(sdk: &FlowyCoreTest, name: &str, desc: &str) -> Wo
.parse::()
}
-pub async fn read_workspace(sdk: &FlowyCoreTest, workspace_id: Option) -> Vec {
+pub async fn read_workspace(
+ sdk: &EventIntegrationTest,
+ workspace_id: Option,
+) -> Vec {
let request = WorkspaceIdPB {
value: workspace_id,
};
@@ -241,7 +244,12 @@ pub async fn read_workspace(sdk: &FlowyCoreTest, workspace_id: Option) -
workspaces
}
-pub async fn create_app(sdk: &FlowyCoreTest, workspace_id: &str, name: &str, desc: &str) -> ViewPB {
+pub async fn create_app(
+ sdk: &EventIntegrationTest,
+ workspace_id: &str,
+ name: &str,
+ desc: &str,
+) -> ViewPB {
let create_view_request = CreateViewPayloadPB {
parent_view_id: workspace_id.to_owned(),
name: name.to_string(),
@@ -263,7 +271,7 @@ pub async fn create_app(sdk: &FlowyCoreTest, workspace_id: &str, name: &str, des
}
pub async fn create_view(
- sdk: &FlowyCoreTest,
+ sdk: &EventIntegrationTest,
app_id: &str,
name: &str,
desc: &str,
@@ -288,7 +296,7 @@ pub async fn create_view(
.parse::()
}
-pub async fn read_view(sdk: &FlowyCoreTest, view_id: &str) -> ViewPB {
+pub async fn read_view(sdk: &EventIntegrationTest, view_id: &str) -> ViewPB {
let view_id = ViewIdPB::from(view_id);
EventBuilder::new(sdk.clone())
.event(ReadView)
@@ -299,7 +307,7 @@ pub async fn read_view(sdk: &FlowyCoreTest, view_id: &str) -> ViewPB {
}
pub async fn move_view(
- sdk: &FlowyCoreTest,
+ sdk: &EventIntegrationTest,
view_id: String,
parent_id: String,
prev_view_id: Option,
@@ -319,7 +327,7 @@ pub async fn move_view(
assert!(error.is_none());
}
pub async fn update_view(
- sdk: &FlowyCoreTest,
+ sdk: &EventIntegrationTest,
view_id: &str,
name: Option,
desc: Option,
@@ -340,7 +348,7 @@ pub async fn update_view(
.await;
}
-pub async fn update_view_icon(sdk: &FlowyCoreTest, view_id: &str, icon: Option) {
+pub async fn update_view_icon(sdk: &EventIntegrationTest, view_id: &str, icon: Option) {
let request = UpdateViewIconPayloadPB {
view_id: view_id.to_string(),
icon,
@@ -352,7 +360,7 @@ pub async fn update_view_icon(sdk: &FlowyCoreTest, view_id: &str, icon: Option) {
+pub async fn delete_view(sdk: &EventIntegrationTest, view_ids: Vec) {
let request = RepeatedViewIdPB { items: view_ids };
EventBuilder::new(sdk.clone())
.event(DeleteView)
@@ -361,7 +369,7 @@ pub async fn delete_view(sdk: &FlowyCoreTest, view_ids: Vec) {
.await;
}
-pub async fn read_trash(sdk: &FlowyCoreTest) -> RepeatedTrashPB {
+pub async fn read_trash(sdk: &EventIntegrationTest) -> RepeatedTrashPB {
EventBuilder::new(sdk.clone())
.event(ReadTrash)
.async_send()
@@ -369,7 +377,7 @@ pub async fn read_trash(sdk: &FlowyCoreTest) -> RepeatedTrashPB {
.parse::()
}
-pub async fn restore_app_from_trash(sdk: &FlowyCoreTest, app_id: &str) {
+pub async fn restore_app_from_trash(sdk: &EventIntegrationTest, app_id: &str) {
let id = TrashIdPB {
id: app_id.to_owned(),
};
@@ -380,7 +388,7 @@ pub async fn restore_app_from_trash(sdk: &FlowyCoreTest, app_id: &str) {
.await;
}
-pub async fn restore_view_from_trash(sdk: &FlowyCoreTest, view_id: &str) {
+pub async fn restore_view_from_trash(sdk: &EventIntegrationTest, view_id: &str) {
let id = TrashIdPB {
id: view_id.to_owned(),
};
@@ -391,14 +399,14 @@ pub async fn restore_view_from_trash(sdk: &FlowyCoreTest, view_id: &str) {
.await;
}
-pub async fn delete_all_trash(sdk: &FlowyCoreTest) {
+pub async fn delete_all_trash(sdk: &EventIntegrationTest) {
EventBuilder::new(sdk.clone())
.event(DeleteAllTrash)
.async_send()
.await;
}
-pub async fn toggle_favorites(sdk: &FlowyCoreTest, view_id: Vec) {
+pub async fn toggle_favorites(sdk: &EventIntegrationTest, view_id: Vec) {
let request = RepeatedViewIdPB { items: view_id };
EventBuilder::new(sdk.clone())
.event(ToggleFavorite)
@@ -407,7 +415,7 @@ pub async fn toggle_favorites(sdk: &FlowyCoreTest, view_id: Vec) {
.await;
}
-pub async fn read_favorites(sdk: &FlowyCoreTest) -> RepeatedViewPB {
+pub async fn read_favorites(sdk: &EventIntegrationTest) -> RepeatedViewPB {
EventBuilder::new(sdk.clone())
.event(ReadFavorites)
.async_send()
diff --git a/frontend/rust-lib/event-integration/tests/folder/local_test/subscription_test.rs b/frontend/rust-lib/event-integration/tests/folder/local_test/subscription_test.rs
index f3fb6208a36f..2df246b212ac 100644
--- a/frontend/rust-lib/event-integration/tests/folder/local_test/subscription_test.rs
+++ b/frontend/rust-lib/event-integration/tests/folder/local_test/subscription_test.rs
@@ -1,6 +1,6 @@
use std::time::Duration;
-use event_integration::FlowyCoreTest;
+use event_integration::EventIntegrationTest;
use flowy_folder2::entities::{ChildViewUpdatePB, RepeatedViewPB, UpdateViewPayloadPB};
use flowy_folder2::notification::FolderNotification;
@@ -16,7 +16,7 @@ use crate::util::receive_with_timeout;
/// 5. Await the notification for workspace view updates with a timeout of 30 seconds.
/// 6. Ensure that the received views contain the newly created "test_view".
async fn create_child_view_in_workspace_subscription_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let workspace = test.get_current_workspace().await.workspace;
let mut rx = test
.notification_sender
@@ -40,7 +40,7 @@ async fn create_child_view_in_workspace_subscription_test() {
#[tokio::test]
async fn create_child_view_in_view_subscription_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let mut workspace = test.get_current_workspace().await.workspace;
let workspace_child_view = workspace.views.pop().unwrap();
let mut rx = test.notification_sender.subscribe::(
@@ -72,7 +72,7 @@ async fn create_child_view_in_view_subscription_test() {
#[tokio::test]
async fn delete_view_subscription_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let workspace = test.get_current_workspace().await.workspace;
let mut rx = test
.notification_sender
@@ -94,7 +94,7 @@ async fn delete_view_subscription_test() {
#[tokio::test]
async fn update_view_subscription_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let mut workspace = test.get_current_workspace().await.workspace;
let mut rx = test
.notification_sender
diff --git a/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs b/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs
index 25994e2a6096..87cc6b82d9e6 100644
--- a/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs
+++ b/frontend/rust-lib/event-integration/tests/folder/local_test/test.rs
@@ -1,12 +1,12 @@
use event_integration::event_builder::EventBuilder;
-use event_integration::FlowyCoreTest;
+use event_integration::EventIntegrationTest;
use flowy_folder2::entities::icon::{UpdateViewIconPayloadPB, ViewIconPB, ViewIconTypePB};
use flowy_folder2::entities::*;
use flowy_user::errors::ErrorCode;
#[tokio::test]
async fn create_workspace_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let request = CreateWorkspacePayloadPB {
name: "my second workspace".to_owned(),
desc: "".to_owned(),
@@ -22,7 +22,7 @@ async fn create_workspace_event_test() {
#[tokio::test]
async fn open_workspace_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let payload = CreateWorkspacePayloadPB {
name: "my second workspace".to_owned(),
desc: "".to_owned(),
@@ -52,7 +52,7 @@ async fn open_workspace_event_test() {
#[tokio::test]
async fn create_view_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let current_workspace = test.get_current_workspace().await.workspace;
let view = test
.create_view(¤t_workspace.id, "My first view".to_string())
@@ -64,7 +64,7 @@ async fn create_view_event_test() {
#[tokio::test]
async fn update_view_event_with_name_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let current_workspace = test.get_current_workspace().await.workspace;
let view = test
.create_view(¤t_workspace.id, "My first view".to_string())
@@ -85,7 +85,7 @@ async fn update_view_event_with_name_test() {
#[tokio::test]
async fn update_view_icon_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let current_workspace = test.get_current_workspace().await.workspace;
let view = test
.create_view(¤t_workspace.id, "My first view".to_string())
@@ -109,7 +109,7 @@ async fn update_view_icon_event_test() {
#[tokio::test]
async fn delete_view_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let current_workspace = test.get_current_workspace().await.workspace;
let view = test
.create_view(¤t_workspace.id, "My first view".to_string())
@@ -132,7 +132,7 @@ async fn delete_view_event_test() {
#[tokio::test]
async fn put_back_trash_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let current_workspace = test.get_current_workspace().await.workspace;
let view = test
.create_view(¤t_workspace.id, "My first view".to_string())
@@ -175,7 +175,7 @@ async fn put_back_trash_event_test() {
#[tokio::test]
async fn delete_view_permanently_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let current_workspace = test.get_current_workspace().await.workspace;
let view = test
.create_view(¤t_workspace.id, "My first view".to_string())
@@ -224,7 +224,7 @@ async fn delete_view_permanently_event_test() {
#[tokio::test]
async fn delete_all_trash_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let current_workspace = test.get_current_workspace().await.workspace;
for i in 0..3 {
@@ -268,7 +268,7 @@ async fn delete_all_trash_test() {
#[tokio::test]
async fn multiple_hierarchy_view_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let current_workspace = test.get_current_workspace().await.workspace;
for i in 1..4 {
let parent = test
@@ -344,7 +344,7 @@ async fn multiple_hierarchy_view_test() {
#[tokio::test]
async fn move_view_event_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let current_workspace = test.get_current_workspace().await.workspace;
for i in 1..4 {
let parent = test
@@ -382,7 +382,7 @@ async fn move_view_event_test() {
#[tokio::test]
async fn move_view_event_after_delete_view_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let current_workspace = test.get_current_workspace().await.workspace;
for i in 1..6 {
let _ = test
@@ -424,7 +424,7 @@ async fn move_view_event_after_delete_view_test() {
#[tokio::test]
async fn move_view_event_after_delete_view_test2() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let current_workspace = test.get_current_workspace().await.workspace;
let parent = test
.create_view(¤t_workspace.id, "My view".to_string())
@@ -466,7 +466,7 @@ async fn move_view_event_after_delete_view_test2() {
#[tokio::test]
async fn create_parent_view_with_invalid_name() {
for (name, code) in invalid_workspace_name_test_case() {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let request = CreateWorkspacePayloadPB {
name,
desc: "".to_owned(),
@@ -494,7 +494,7 @@ fn invalid_workspace_name_test_case() -> Vec<(String, ErrorCode)> {
#[tokio::test]
async fn move_view_across_parent_test() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let current_workspace = test.get_current_workspace().await.workspace;
let parent_1 = test
.create_view(¤t_workspace.id, "My view 1".to_string())
@@ -539,7 +539,7 @@ async fn move_view_across_parent_test() {
}
async fn move_folder_nested_view(
- sdk: FlowyCoreTest,
+ sdk: EventIntegrationTest,
view_id: String,
new_parent_id: String,
prev_view_id: Option,
diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/test.rs
index 79540f573df8..e0a138e0fac4 100644
--- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/test.rs
+++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/test.rs
@@ -1,13 +1,36 @@
-use event_integration::FlowyCoreTest;
+use event_integration::EventIntegrationTest;
+use flowy_user::entities::UpdateUserProfilePayloadPB;
use crate::util::{generate_test_email, get_af_cloud_config};
#[tokio::test]
async fn af_cloud_sign_up_test() {
if get_af_cloud_config().is_some() {
- let test = FlowyCoreTest::new();
+ let test = EventIntegrationTest::new();
let email = generate_test_email();
let user = test.af_cloud_sign_in_with_email(&email).await.unwrap();
assert_eq!(user.email, email);
}
}
+
+#[tokio::test]
+async fn af_cloud_update_user_metadata_of_open_ai_key() {
+ if get_af_cloud_config().is_some() {
+ let test = EventIntegrationTest::new();
+ let user = test.af_cloud_sign_up().await;
+
+ let old_profile = test.get_user_profile().await.unwrap();
+ assert_eq!(old_profile.openai_key, "".to_string());
+
+ test
+ .update_user_profile(UpdateUserProfilePayloadPB {
+ id: user.id,
+ openai_key: Some("new openai_key".to_string()),
+ ..Default::default()
+ })
+ .await;
+
+ let new_profile = test.get_user_profile().await.unwrap();
+ assert_eq!(new_profile.openai_key, "new openai_key".to_string());
+ }
+}
diff --git a/frontend/rust-lib/event-integration/tests/user/local_test/auth_test.rs b/frontend/rust-lib/event-integration/tests/user/local_test/auth_test.rs
index 2edb5d7d4ed4..4866d3672049 100644
--- a/frontend/rust-lib/event-integration/tests/user/local_test/auth_test.rs
+++ b/frontend/rust-lib/event-integration/tests/user/local_test/auth_test.rs
@@ -1,5 +1,5 @@
-use event_integration::user_event::*;
-use event_integration::{event_builder::EventBuilder, FlowyCoreTest};
+use event_integration::test_user::{login_password, unique_email};
+use event_integration::{event_builder::EventBuilder, EventIntegrationTest};
use flowy_user::entities::{AuthTypePB, SignInPayloadPB, SignUpPayloadPB};
use flowy_user::errors::ErrorCode;
use flowy_user::event_map::UserEvent::*;
@@ -9,7 +9,7 @@ use crate::user::local_test::helper::*;
#[tokio::test]
async fn sign_up_with_invalid_email() {
for email in invalid_email_test_case() {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let request = SignUpPayloadPB {
email: email.to_string(),
name: valid_name(),
@@ -33,9 +33,9 @@ async fn sign_up_with_invalid_email() {
}
#[tokio::test]
async fn sign_up_with_long_password() {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let request = SignUpPayloadPB {
- email: random_email(),
+ email: unique_email(),
name: valid_name(),
password: "1234".repeat(100).as_str().to_string(),
auth_type: AuthTypePB::Local,
@@ -58,7 +58,7 @@ async fn sign_up_with_long_password() {
#[tokio::test]
async fn sign_in_with_invalid_email() {
for email in invalid_email_test_case() {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let request = SignInPayloadPB {
email: email.to_string(),
password: login_password(),
@@ -84,10 +84,10 @@ async fn sign_in_with_invalid_email() {
#[tokio::test]
async fn sign_in_with_invalid_password() {
for password in invalid_password_test_case() {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let request = SignInPayloadPB {
- email: random_email(),
+ email: unique_email(),
password,
name: "".to_string(),
auth_type: AuthTypePB::Local,
diff --git a/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs b/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs
index 75348b7687a5..68bae5c7a4b7 100644
--- a/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs
+++ b/frontend/rust-lib/event-integration/tests/user/local_test/user_awareness_test.rs
@@ -1,13 +1,13 @@
use std::collections::HashMap;
use event_integration::event_builder::EventBuilder;
-use event_integration::FlowyCoreTest;
+use event_integration::EventIntegrationTest;
use flowy_user::entities::{ReminderPB, RepeatedReminderPB};
use flowy_user::event_map::UserEvent::*;
#[tokio::test]
async fn user_update_with_name() {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let _ = sdk.sign_up_as_guest().await;
let mut meta = HashMap::new();
meta.insert("object_id".to_string(), "".to_string());
diff --git a/frontend/rust-lib/event-integration/tests/user/local_test/user_profile_test.rs b/frontend/rust-lib/event-integration/tests/user/local_test/user_profile_test.rs
index 6969be29acde..a488de02a11f 100644
--- a/frontend/rust-lib/event-integration/tests/user/local_test/user_profile_test.rs
+++ b/frontend/rust-lib/event-integration/tests/user/local_test/user_profile_test.rs
@@ -1,14 +1,16 @@
-use crate::user::local_test::helper::*;
-use event_integration::{event_builder::EventBuilder, FlowyCoreTest};
+use nanoid::nanoid;
+
+use event_integration::{event_builder::EventBuilder, EventIntegrationTest};
use flowy_user::entities::{UpdateUserProfilePayloadPB, UserProfilePB};
use flowy_user::{errors::ErrorCode, event_map::UserEvent::*};
-use nanoid::nanoid;
+
+use crate::user::local_test::helper::*;
// use serial_test::*;
#[tokio::test]
async fn user_profile_get_failed() {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let result = EventBuilder::new(sdk)
.event(GetUserProfile)
.async_send()
@@ -19,7 +21,7 @@ async fn user_profile_get_failed() {
#[tokio::test]
async fn user_profile_get() {
- let test = FlowyCoreTest::new();
+ let test = EventIntegrationTest::new();
let user_profile = test.init_user().await;
let user = EventBuilder::new(test.clone())
.event(GetUserProfile)
@@ -30,7 +32,7 @@ async fn user_profile_get() {
#[tokio::test]
async fn user_update_with_name() {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let user = sdk.init_user().await;
let new_name = "hello_world".to_owned();
let request = UpdateUserProfilePayloadPB::new(user.id).name(&new_name);
@@ -49,7 +51,7 @@ async fn user_update_with_name() {
#[tokio::test]
async fn user_update_with_ai_key() {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let user = sdk.init_user().await;
let openai_key = "openai_key".to_owned();
let stability_ai_key = "stability_ai_key".to_owned();
@@ -72,7 +74,7 @@ async fn user_update_with_ai_key() {
#[tokio::test]
async fn user_update_with_email() {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let user = sdk.init_user().await;
let new_email = format!("{}@gmail.com", nanoid!(6));
let request = UpdateUserProfilePayloadPB::new(user.id).email(&new_email);
@@ -90,7 +92,7 @@ async fn user_update_with_email() {
#[tokio::test]
async fn user_update_with_invalid_email() {
- let test = FlowyCoreTest::new();
+ let test = EventIntegrationTest::new();
let user = test.init_user().await;
for email in invalid_email_test_case() {
let request = UpdateUserProfilePayloadPB::new(user.id).email(&email);
@@ -109,7 +111,7 @@ async fn user_update_with_invalid_email() {
#[tokio::test]
async fn user_update_with_invalid_password() {
- let test = FlowyCoreTest::new();
+ let test = EventIntegrationTest::new();
let user = test.init_user().await;
for password in invalid_password_test_case() {
let request = UpdateUserProfilePayloadPB::new(user.id).password(&password);
@@ -126,7 +128,7 @@ async fn user_update_with_invalid_password() {
#[tokio::test]
async fn user_update_with_invalid_name() {
- let test = FlowyCoreTest::new();
+ let test = EventIntegrationTest::new();
let user = test.init_user().await;
let request = UpdateUserProfilePayloadPB::new(user.id).name("");
assert!(EventBuilder::new(test.clone())
diff --git a/frontend/rust-lib/event-integration/tests/user/migration_test/document_test.rs b/frontend/rust-lib/event-integration/tests/user/migration_test/document_test.rs
index 167bbecc9cd9..9f3100b7ca4b 100644
--- a/frontend/rust-lib/event-integration/tests/user/migration_test/document_test.rs
+++ b/frontend/rust-lib/event-integration/tests/user/migration_test/document_test.rs
@@ -1,4 +1,4 @@
-use event_integration::FlowyCoreTest;
+use event_integration::EventIntegrationTest;
use flowy_core::DEFAULT_NAME;
use flowy_folder2::entities::ViewLayoutPB;
@@ -11,7 +11,7 @@ async fn migrate_historical_empty_document_test() {
"historical_empty_document",
)
.unwrap();
- let test = FlowyCoreTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string());
+ let test = EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string());
let views = test.get_all_workspace_views().await;
assert_eq!(views.len(), 3);
diff --git a/frontend/rust-lib/event-integration/tests/user/migration_test/version_test.rs b/frontend/rust-lib/event-integration/tests/user/migration_test/version_test.rs
index 05caa93510c3..ccd1b25e8c4a 100644
--- a/frontend/rust-lib/event-integration/tests/user/migration_test/version_test.rs
+++ b/frontend/rust-lib/event-integration/tests/user/migration_test/version_test.rs
@@ -1,4 +1,4 @@
-use event_integration::FlowyCoreTest;
+use event_integration::EventIntegrationTest;
use flowy_core::DEFAULT_NAME;
use flowy_folder2::entities::ViewLayoutPB;
@@ -11,7 +11,7 @@ async fn migrate_020_historical_empty_document_test() {
"020_historical_user_data",
)
.unwrap();
- let test = FlowyCoreTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string());
+ let test = EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string());
let mut views = test.get_all_workspace_views().await;
assert_eq!(views.len(), 1);
diff --git a/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs b/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs
index 2027a0919288..999df506ef86 100644
--- a/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs
+++ b/frontend/rust-lib/event-integration/tests/user/supabase_test/auth_test.rs
@@ -10,7 +10,7 @@ use serde_json::json;
use event_integration::document::document_event::DocumentEventTest;
use event_integration::event_builder::EventBuilder;
-use event_integration::FlowyCoreTest;
+use event_integration::EventIntegrationTest;
use flowy_core::DEFAULT_NAME;
use flowy_encrypt::decrypt_text;
use flowy_server::supabase::define::{USER_EMAIL, USER_UUID};
@@ -23,7 +23,7 @@ use crate::util::*;
#[tokio::test]
async fn third_party_sign_up_test() {
if get_supabase_config().is_some() {
- let test = FlowyCoreTest::new();
+ let test = EventIntegrationTest::new();
let mut map = HashMap::new();
map.insert(USER_UUID.to_string(), uuid::Uuid::new_v4().to_string());
map.insert(
@@ -48,7 +48,7 @@ async fn third_party_sign_up_test() {
#[tokio::test]
async fn third_party_sign_up_with_encrypt_test() {
if get_supabase_config().is_some() {
- let test = FlowyCoreTest::new();
+ let test = EventIntegrationTest::new();
test.supabase_party_sign_up().await;
let user_profile = test.get_user_profile().await.unwrap();
assert!(user_profile.encryption_sign.is_empty());
@@ -65,7 +65,7 @@ async fn third_party_sign_up_with_encrypt_test() {
#[tokio::test]
async fn third_party_sign_up_with_duplicated_uuid() {
if get_supabase_config().is_some() {
- let test = FlowyCoreTest::new();
+ let test = EventIntegrationTest::new();
let email = format!("{}@appflowy.io", nanoid!(6));
let mut map = HashMap::new();
map.insert(USER_UUID.to_string(), uuid::Uuid::new_v4().to_string());
@@ -98,7 +98,7 @@ async fn third_party_sign_up_with_duplicated_uuid() {
#[tokio::test]
async fn third_party_sign_up_with_duplicated_email() {
if get_supabase_config().is_some() {
- let test = FlowyCoreTest::new();
+ let test = EventIntegrationTest::new();
let email = format!("{}@appflowy.io", nanoid!(6));
test
.supabase_sign_up_with_uuid(&uuid::Uuid::new_v4().to_string(), Some(email.clone()))
@@ -116,7 +116,7 @@ async fn third_party_sign_up_with_duplicated_email() {
#[tokio::test]
async fn sign_up_as_guest_and_then_update_to_new_cloud_user_test() {
if get_supabase_config().is_some() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let old_views = test
.folder_manager
.get_current_workspace_views()
@@ -148,7 +148,7 @@ async fn sign_up_as_guest_and_then_update_to_new_cloud_user_test() {
#[tokio::test]
async fn sign_up_as_guest_and_then_update_to_existing_cloud_user_test() {
if get_supabase_config().is_some() {
- let test = FlowyCoreTest::new_with_guest_user().await;
+ let test = EventIntegrationTest::new_with_guest_user().await;
let uuid = uuid::Uuid::new_v4().to_string();
let email = format!("{}@appflowy.io", nanoid!(6));
@@ -260,7 +260,7 @@ async fn update_user_profile_with_existing_email_test() {
#[tokio::test]
async fn migrate_anon_document_on_cloud_signup() {
if get_supabase_config().is_some() {
- let test = FlowyCoreTest::new();
+ let test = EventIntegrationTest::new();
let user_profile = test.sign_up_as_guest().await.user_profile;
let view = test
@@ -305,7 +305,8 @@ async fn migrate_anon_data_on_cloud_signup() {
"workspace_sync",
)
.unwrap();
- let test = FlowyCoreTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string());
+ let test =
+ EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string());
let user_profile = test.supabase_party_sign_up().await;
// Get the folder data from remote
diff --git a/frontend/rust-lib/event-integration/tests/user/supabase_test/workspace_test.rs b/frontend/rust-lib/event-integration/tests/user/supabase_test/workspace_test.rs
index 74236b458e7e..49e4e289c7c2 100644
--- a/frontend/rust-lib/event-integration/tests/user/supabase_test/workspace_test.rs
+++ b/frontend/rust-lib/event-integration/tests/user/supabase_test/workspace_test.rs
@@ -1,6 +1,6 @@
use std::collections::HashMap;
-use event_integration::{event_builder::EventBuilder, FlowyCoreTest};
+use event_integration::{event_builder::EventBuilder, EventIntegrationTest};
use flowy_folder2::entities::WorkspaceSettingPB;
use flowy_folder2::event_map::FolderEvent::GetCurrentWorkspace;
use flowy_server::supabase::define::{USER_EMAIL, USER_UUID};
@@ -12,7 +12,7 @@ use crate::util::*;
#[tokio::test]
async fn initial_workspace_test() {
if get_supabase_config().is_some() {
- let test = FlowyCoreTest::new();
+ let test = EventIntegrationTest::new();
let mut map = HashMap::new();
map.insert(USER_UUID.to_string(), uuid::Uuid::new_v4().to_string());
map.insert(
diff --git a/frontend/rust-lib/event-integration/tests/util.rs b/frontend/rust-lib/event-integration/tests/util.rs
index d0c104ffb8c4..9847095458bc 100644
--- a/frontend/rust-lib/event-integration/tests/util.rs
+++ b/frontend/rust-lib/event-integration/tests/util.rs
@@ -16,7 +16,7 @@ use zip::ZipArchive;
use event_integration::event_builder::EventBuilder;
use event_integration::Cleaner;
-use event_integration::FlowyCoreTest;
+use event_integration::EventIntegrationTest;
use flowy_database_deps::cloud::DatabaseCloudService;
use flowy_folder_deps::cloud::{FolderCloudService, FolderSnapshot};
use flowy_server::supabase::api::*;
@@ -36,13 +36,13 @@ pub fn get_supabase_config() -> Option {
}
pub struct FlowySupabaseTest {
- inner: FlowyCoreTest,
+ inner: EventIntegrationTest,
}
impl FlowySupabaseTest {
pub fn new() -> Option {
let _ = get_supabase_config()?;
- let test = FlowyCoreTest::new();
+ let test = EventIntegrationTest::new();
test.set_auth_type(AuthTypePB::Supabase);
test.server_provider.set_auth_type(AuthType::Supabase);
@@ -76,7 +76,7 @@ impl FlowySupabaseTest {
}
impl Deref for FlowySupabaseTest {
- type Target = FlowyCoreTest;
+ type Target = EventIntegrationTest;
fn deref(&self) -> &Self::Target {
&self.inner
@@ -215,13 +215,13 @@ pub fn unzip_history_user_db(root: &str, folder_name: &str) -> std::io::Result<(
}
pub struct AFCloudTest {
- inner: FlowyCoreTest,
+ inner: EventIntegrationTest,
}
impl AFCloudTest {
pub fn new() -> Option {
let _ = get_af_cloud_config()?;
- let test = FlowyCoreTest::new();
+ let test = EventIntegrationTest::new();
test.set_auth_type(AuthTypePB::AFCloud);
test.server_provider.set_auth_type(AuthType::AFCloud);
@@ -230,7 +230,7 @@ impl AFCloudTest {
}
impl Deref for AFCloudTest {
- type Target = FlowyCoreTest;
+ type Target = EventIntegrationTest;
fn deref(&self) -> &Self::Target {
&self.inner
diff --git a/frontend/rust-lib/flowy-database2/src/manager.rs b/frontend/rust-lib/flowy-database2/src/manager.rs
index 96dd331e88ea..10734ba8a50a 100644
--- a/frontend/rust-lib/flowy-database2/src/manager.rs
+++ b/frontend/rust-lib/flowy-database2/src/manager.rs
@@ -132,7 +132,12 @@ impl DatabaseManager {
Ok(())
}
- #[instrument(level = "debug", skip_all, err)]
+ #[instrument(
+ name = "database_initialize_with_new_user",
+ level = "debug",
+ skip_all,
+ err
+ )]
pub async fn initialize_with_new_user(
&self,
user_id: i64,
diff --git a/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs b/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs
index 4b102fe0e96d..9fe298be3d5a 100644
--- a/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs
+++ b/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs
@@ -6,8 +6,8 @@ use collab_database::fields::Field;
use collab_database::rows::{CreateRowParams, RowDetail, RowId};
use strum::EnumCount;
-use event_integration::folder_event::ViewTest;
-use event_integration::FlowyCoreTest;
+use event_integration::test_folder::ViewTest;
+use event_integration::EventIntegrationTest;
use flowy_database2::entities::{FieldType, FilterPB, RowMetaPB};
use flowy_database2::services::cell::{CellBuilder, ToCellChangeset};
use flowy_database2::services::database::DatabaseEditor;
@@ -26,8 +26,7 @@ use crate::database::mock_data::{
};
pub struct DatabaseEditorTest {
- pub sdk: FlowyCoreTest,
- pub app_id: String,
+ pub sdk: EventIntegrationTest,
pub view_id: String,
pub editor: Arc,
pub fields: Vec>,
@@ -38,7 +37,7 @@ pub struct DatabaseEditorTest {
impl DatabaseEditorTest {
pub async fn new_grid() -> Self {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let _ = sdk.init_user().await;
let params = make_test_grid();
@@ -47,7 +46,7 @@ impl DatabaseEditorTest {
}
pub async fn new_no_date_grid() -> Self {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let _ = sdk.init_user().await;
let params = make_no_date_test_grid();
@@ -56,7 +55,7 @@ impl DatabaseEditorTest {
}
pub async fn new_board() -> Self {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let _ = sdk.init_user().await;
let params = make_test_board();
@@ -65,7 +64,7 @@ impl DatabaseEditorTest {
}
pub async fn new_calendar() -> Self {
- let sdk = FlowyCoreTest::new();
+ let sdk = EventIntegrationTest::new();
let _ = sdk.init_user().await;
let params = make_test_calendar();
@@ -73,7 +72,7 @@ impl DatabaseEditorTest {
Self::new(sdk, view_test).await
}
- pub async fn new(sdk: FlowyCoreTest, test: ViewTest) -> Self {
+ pub async fn new(sdk: EventIntegrationTest, test: ViewTest) -> Self {
let editor = sdk
.database_manager
.get_database_with_view_id(&test.child_view.id)
@@ -92,10 +91,8 @@ impl DatabaseEditorTest {
.collect();
let view_id = test.child_view.id;
- let app_id = test.parent_view.id;
Self {
sdk,
- app_id,
view_id,
editor,
fields,
diff --git a/frontend/rust-lib/flowy-document2/src/manager.rs b/frontend/rust-lib/flowy-document2/src/manager.rs
index 2fe3dd829e79..ee8a9c9a9c49 100644
--- a/frontend/rust-lib/flowy-document2/src/manager.rs
+++ b/frontend/rust-lib/flowy-document2/src/manager.rs
@@ -59,7 +59,12 @@ impl DocumentManager {
Ok(())
}
- #[instrument(level = "debug", skip_all, err)]
+ #[instrument(
+ name = "document_initialize_with_new_user",
+ level = "debug",
+ skip_all,
+ err
+ )]
pub async fn initialize_with_new_user(&self, uid: i64, workspace_id: String) -> FlowyResult<()> {
self.initialize(uid, workspace_id).await?;
Ok(())
diff --git a/frontend/rust-lib/flowy-document2/src/notification.rs b/frontend/rust-lib/flowy-document2/src/notification.rs
index 94c5bed28f9f..b468ec20c7f3 100644
--- a/frontend/rust-lib/flowy-document2/src/notification.rs
+++ b/frontend/rust-lib/flowy-document2/src/notification.rs
@@ -29,6 +29,7 @@ impl std::convert::From for DocumentNotification {
}
}
+#[tracing::instrument(level = "trace")]
pub(crate) fn send_notification(id: &str, ty: DocumentNotification) -> NotificationBuilder {
NotificationBuilder::new(id, ty, DOCUMENT_OBSERVABLE_SOURCE)
}
diff --git a/frontend/rust-lib/flowy-folder2/src/manager.rs b/frontend/rust-lib/flowy-folder2/src/manager.rs
index fda3198502b1..b15ce1b2c56c 100644
--- a/frontend/rust-lib/flowy-folder2/src/manager.rs
+++ b/frontend/rust-lib/flowy-folder2/src/manager.rs
@@ -265,7 +265,12 @@ impl FolderManager {
/// Initialize the folder for the new user.
/// Using the [DefaultFolderBuilder] to create the default workspace for the new user.
- #[instrument(level = "debug", skip_all, err)]
+ #[instrument(
+ name = "folder_initialize_with_new_user",
+ level = "debug",
+ skip_all,
+ err
+ )]
pub async fn initialize_with_new_user(
&self,
user_id: i64,
diff --git a/frontend/rust-lib/flowy-server/Cargo.toml b/frontend/rust-lib/flowy-server/Cargo.toml
index 45b2b13d49ef..ccdc0a7b5681 100644
--- a/frontend/rust-lib/flowy-server/Cargo.toml
+++ b/frontend/rust-lib/flowy-server/Cargo.toml
@@ -23,7 +23,7 @@ bytes = { version = "1.5", features = ["serde"] }
tokio-retry = "0.3"
anyhow = "1.0"
uuid = { version = "1.3.3", features = ["v4"] }
-chrono = { version = "0.4.31", default-features = false, features = ["clock"] }
+chrono = { version = "0.4.31", default-features = false, features = ["clock", "serde"] }
collab = { version = "0.1.0" }
collab-plugins = { version = "0.1.0"}
collab-document = { version = "0.1.0" }
diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs
similarity index 71%
rename from frontend/rust-lib/flowy-server/src/af_cloud/impls/user.rs
rename to frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs
index bd8419d93fe7..b5d090df87b0 100644
--- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user.rs
+++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs
@@ -2,11 +2,8 @@ use std::collections::HashMap;
use std::sync::Arc;
use anyhow::{anyhow, Error};
-use client_api::entity::dto::auth_dto::UpdateUsernameParams;
-use client_api::entity::dto::workspace_dto::CreateWorkspaceMember;
-use client_api::entity::{
- AFRole, AFUserProfileView, AFWorkspace, AFWorkspaces, InsertCollabParams, OAuthProvider,
-};
+use client_api::entity::workspace_dto::CreateWorkspaceMember;
+use client_api::entity::{AFRole, AFWorkspace, InsertCollabParams, OAuthProvider};
use collab_entity::CollabObject;
use flowy_error::{ErrorCode, FlowyError};
@@ -15,6 +12,10 @@ use flowy_user_deps::entities::*;
use lib_infra::box_any::BoxAny;
use lib_infra::future::FutureResult;
+use crate::af_cloud::impls::user::dto::{
+ af_update_from_update_params, user_profile_from_af_profile,
+};
+use crate::af_cloud::impls::user::util::encryption_type_from_profile;
use crate::af_cloud::{AFCloudClient, AFServer};
use crate::supabase::define::{USER_DEVICE_ID, USER_SIGN_IN_URL};
@@ -92,12 +93,7 @@ where
FutureResult::new(async move {
let client = try_get_client?;
client
- .update_user(UpdateUsernameParams {
- name: params.name,
- email: params.email,
- password: params.password,
- metadata: None,
- })
+ .update_user(af_update_from_update_params(params))
.await?;
Ok(())
})
@@ -111,30 +107,18 @@ where
FutureResult::new(async move {
let client = try_get_client?;
let profile = client.get_profile().await?;
- let encryption_type = encryption_type_from_profile(&profile);
- Ok(Some(UserProfile {
- email: profile.email.unwrap_or("".to_string()),
- name: profile.name.unwrap_or("".to_string()),
- token: client.get_token()?,
- icon_url: "".to_owned(),
- openai_key: "".to_owned(),
- stability_ai_key: "".to_owned(),
- workspace_id: match profile.latest_workspace_id {
- Some(w) => w.to_string(),
- None => "".to_string(),
- },
- auth_type: AuthType::AFCloud,
- encryption_type,
- uid: profile.uid.ok_or(anyhow!("no uid found"))?,
- }))
+ let token = client.get_token()?;
+ let profile = user_profile_from_af_profile(token, profile)?;
+
+ Ok(Some(profile))
})
}
- fn get_user_workspaces(&self, _uid: i64) -> FutureResult, Error> {
+ fn get_all_user_workspaces(&self, _uid: i64) -> FutureResult, Error> {
let try_get_client = self.server.try_get_client();
FutureResult::new(async move {
let workspaces = try_get_client?.get_workspaces().await?;
- Ok(to_user_workspaces(workspaces)?)
+ Ok(to_user_workspaces(workspaces.0)?)
})
}
@@ -151,7 +135,7 @@ where
let client_token = client.access_token()?;
// compare and check
- if uid != profile.uid.ok_or(anyhow!("expecting uid"))? {
+ if uid != profile.uid {
return Err(anyhow!("uid mismatch"));
}
if token != client_token {
@@ -238,59 +222,42 @@ pub async fn user_sign_in_with_url(
params: AFCloudOAuthParams,
) -> Result {
let is_new_user = client.sign_in_with_url(¶ms.sign_in_url).await?;
- let (profile, af_workspaces) = tokio::try_join!(client.get_profile(), client.get_workspaces())?;
- let latest_workspace = to_user_workspace(
- af_workspaces
- .get_latest(&profile)
- .or(af_workspaces.first().cloned())
- .ok_or(anyhow!("no workspace found"))?,
- )?;
+ let workspace_profile = client.get_user_workspace_info().await?;
+ let user_profile = workspace_profile.user_profile;
- let user_workspaces = to_user_workspaces(af_workspaces)?;
- let encryption_type = encryption_type_from_profile(&profile);
+ let latest_workspace = to_user_workspace(workspace_profile.visiting_workspace);
+ let user_workspaces = to_user_workspaces(workspace_profile.workspaces)?;
+ let encryption_type = encryption_type_from_profile(&user_profile);
Ok(AuthResponse {
- user_id: profile.uid.ok_or(anyhow!("no uid found"))?,
- name: profile.name.ok_or(anyhow!("no name found"))?,
+ user_id: user_profile.uid,
+ name: user_profile.name.unwrap_or_default(),
latest_workspace,
user_workspaces,
- email: profile.email,
+ email: user_profile.email,
token: Some(client.get_token()?),
device_id: params.device_id,
encryption_type,
is_new_user,
+ updated_at: user_profile.updated_at,
+ metadata: user_profile.metadata,
})
}
-fn encryption_type_from_profile(profile: &AFUserProfileView) -> EncryptionType {
- match &profile.encryption_sign {
- Some(e) => EncryptionType::SelfEncryption(e.to_string()),
- None => EncryptionType::NoEncryption,
- }
-}
-
-fn to_user_workspace(af_workspace: AFWorkspace) -> Result {
- Ok(UserWorkspace {
+fn to_user_workspace(af_workspace: AFWorkspace) -> UserWorkspace {
+ UserWorkspace {
id: af_workspace.workspace_id.to_string(),
- name: af_workspace
- .workspace_name
- .ok_or(anyhow!("no workspace_name found"))?,
- created_at: af_workspace
- .created_at
- .ok_or(anyhow!("no created_at found"))?,
- database_views_aggregate_id: af_workspace
- .database_storage_id
- .ok_or(anyhow!("no database_views_aggregate_id found"))?
- .to_string(),
- })
+ name: af_workspace.workspace_name,
+ created_at: af_workspace.created_at,
+ database_views_aggregate_id: af_workspace.database_storage_id.to_string(),
+ }
}
-fn to_user_workspaces(af_workspaces: AFWorkspaces) -> Result, FlowyError> {
- let mut result = Vec::with_capacity(af_workspaces.len());
- for item in af_workspaces.0.into_iter() {
- let user_workspace = to_user_workspace(item)?;
- result.push(user_workspace);
+fn to_user_workspaces(workspaces: Vec) -> Result, FlowyError> {
+ let mut result = Vec::with_capacity(workspaces.len());
+ for item in workspaces.into_iter() {
+ result.push(to_user_workspace(item));
}
Ok(result)
}
diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/dto.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/dto.rs
new file mode 100644
index 000000000000..e2c2922d0c89
--- /dev/null
+++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/dto.rs
@@ -0,0 +1,65 @@
+use anyhow::Error;
+use client_api::entity::auth_dto::{UpdateUserParams, UserMetaData};
+use client_api::entity::AFUserProfile;
+
+use flowy_user_deps::entities::{
+ AuthType, UpdateUserProfileParams, UserProfile, USER_METADATA_ICON_URL,
+ USER_METADATA_OPEN_AI_KEY, USER_METADATA_STABILITY_AI_KEY,
+};
+
+use crate::af_cloud::impls::user::util::encryption_type_from_profile;
+
+pub fn af_update_from_update_params(update: UpdateUserProfileParams) -> UpdateUserParams {
+ let mut user_metadata = UserMetaData::new();
+ if let Some(openai_key) = update.openai_key {
+ user_metadata.insert(USER_METADATA_OPEN_AI_KEY, openai_key);
+ }
+
+ if let Some(stability_ai_key) = update.stability_ai_key {
+ user_metadata.insert(USER_METADATA_STABILITY_AI_KEY, stability_ai_key);
+ }
+
+ if let Some(icon_url) = update.icon_url {
+ user_metadata.insert(USER_METADATA_ICON_URL, icon_url);
+ }
+
+ UpdateUserParams {
+ name: update.name,
+ email: update.email,
+ password: update.password,
+ metadata: Some(user_metadata),
+ }
+}
+
+pub fn user_profile_from_af_profile(
+ token: String,
+ profile: AFUserProfile,
+) -> Result {
+ let encryption_type = encryption_type_from_profile(&profile);
+ let (icon_url, openai_key, stability_ai_key) = {
+ profile
+ .metadata
+ .map(|m| {
+ (
+ m.get(USER_METADATA_ICON_URL).map(|v| v.to_string()),
+ m.get(USER_METADATA_OPEN_AI_KEY).map(|v| v.to_string()),
+ m.get(USER_METADATA_STABILITY_AI_KEY).map(|v| v.to_string()),
+ )
+ })
+ .unwrap_or_default()
+ };
+
+ Ok(UserProfile {
+ email: profile.email.unwrap_or("".to_string()),
+ name: profile.name.unwrap_or("".to_string()),
+ token,
+ icon_url: icon_url.unwrap_or_default(),
+ openai_key: openai_key.unwrap_or_default(),
+ stability_ai_key: stability_ai_key.unwrap_or_default(),
+ workspace_id: profile.latest_workspace_id.to_string(),
+ auth_type: AuthType::AFCloud,
+ encryption_type,
+ uid: profile.uid,
+ updated_at: profile.updated_at,
+ })
+}
diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/mod.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/mod.rs
new file mode 100644
index 000000000000..96e13cbc2d0f
--- /dev/null
+++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/mod.rs
@@ -0,0 +1,5 @@
+pub use cloud_service_impl::*;
+
+mod cloud_service_impl;
+mod dto;
+mod util;
diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/util.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/util.rs
new file mode 100644
index 000000000000..b357861aa3cc
--- /dev/null
+++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/util.rs
@@ -0,0 +1,10 @@
+use client_api::entity::AFUserProfile;
+
+use flowy_user_deps::entities::EncryptionType;
+
+pub fn encryption_type_from_profile(profile: &AFUserProfile) -> EncryptionType {
+ match &profile.encryption_sign {
+ Some(e) => EncryptionType::SelfEncryption(e.to_string()),
+ None => EncryptionType::NoEncryption,
+ }
+}
diff --git a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs
index 7828d9f2e80d..5cc0455ac150 100644
--- a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs
+++ b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs
@@ -11,6 +11,7 @@ use flowy_user_deps::entities::*;
use flowy_user_deps::DEFAULT_USER_NAME;
use lib_infra::box_any::BoxAny;
use lib_infra::future::FutureResult;
+use lib_infra::util::timestamp;
use crate::local_server::uid::UserIDGenerator;
use crate::local_server::LocalServerDB;
@@ -46,6 +47,8 @@ impl UserCloudService for LocalServerUserAuthServiceImpl {
token: None,
device_id: params.device_id,
encryption_type: EncryptionType::NoEncryption,
+ updated_at: timestamp(),
+ metadata: None,
})
})
}
@@ -69,6 +72,8 @@ impl UserCloudService for LocalServerUserAuthServiceImpl {
token: None,
device_id: params.device_id,
encryption_type: EncryptionType::NoEncryption,
+ updated_at: timestamp(),
+ metadata: None,
})
})
}
@@ -104,7 +109,7 @@ impl UserCloudService for LocalServerUserAuthServiceImpl {
FutureResult::new(async { Ok(None) })
}
- fn get_user_workspaces(&self, _uid: i64) -> FutureResult, Error> {
+ fn get_all_user_workspaces(&self, _uid: i64) -> FutureResult, Error> {
FutureResult::new(async { Ok(vec![]) })
}
diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs
index 6a91aafb276a..69581d69f0dd 100644
--- a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs
+++ b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs
@@ -129,6 +129,8 @@ where
token: None,
device_id: params.device_id,
encryption_type: EncryptionType::from_sign(&user_profile.encryption_sign),
+ updated_at: user_profile.updated_at.timestamp(),
+ metadata: None,
})
})
}
@@ -158,6 +160,8 @@ where
token: None,
device_id: params.device_id,
encryption_type: EncryptionType::from_sign(&response.encryption_sign),
+ updated_at: response.updated_at.timestamp(),
+ metadata: None,
})
})
}
@@ -220,12 +224,13 @@ where
workspace_id: response.latest_workspace_id,
auth_type: AuthType::Supabase,
encryption_type: EncryptionType::from_sign(&response.encryption_sign),
+ updated_at: response.updated_at.timestamp(),
})),
}
})
}
- fn get_user_workspaces(&self, uid: i64) -> FutureResult, Error> {
+ fn get_all_user_workspaces(&self, uid: i64) -> FutureResult, Error> {
let try_get_postgrest = self.server.try_get_postgrest();
FutureResult::new(async move {
let postgrest = try_get_postgrest?;
@@ -419,7 +424,7 @@ async fn get_user_profile(
) -> Result