Merge branch 'develop'

This commit is contained in:
appflowy 2021-11-20 09:35:16 +08:00
commit 55c05364dd
1748 changed files with 1444 additions and 953 deletions

View file

@ -1,26 +0,0 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flowy_infra_ui_example/main.dart';
void main() {
testWidgets('Verify Platform version', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const ExampleApp());
// Verify that platform version is retrieved.
expect(
find.byWidgetPredicate(
(Widget widget) => widget is Text && widget.data!.startsWith('Running on:'),
),
findsOneWidget,
);
});
}

View file

@ -1,29 +0,0 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import '../lib/main.dart';
void main() {
testWidgets('Verify Platform version', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());
// Verify that platform version is retrieved.
expect(
find.byWidgetPredicate((Widget widget) {
if (widget is Text && widget.data != null) {
return widget.data.startsWith('Running on:');
}
return false;
}),
findsOneWidget,
);
});
}

View file

@ -60,13 +60,12 @@ pin-project = "1.0.0"
byteorder = {version = "1.3.4"}
async-stream = "0.3.2"
flowy-user-infra = { path = "../rust-lib/flowy-user-infra" }
flowy-workspace-infra = { path = "../rust-lib/flowy-workspace-infra" }
flowy-document-infra = { path = "../rust-lib/flowy-document-infra" }
flowy-document = { path = "../rust-lib/flowy-document" }
flowy-ws = { path = "../rust-lib/flowy-ws" }
flowy-ot = { path = "../rust-lib/flowy-ot" }
flowy-net = { path = "../rust-lib/flowy-net", features = ["http_server"] }
flowy-user-infra = { path = "../frontend/rust-lib/flowy-user-infra" }
flowy-workspace-infra = { path = "../frontend/rust-lib/flowy-workspace-infra" }
flowy-document-infra = { path = "../frontend/rust-lib/flowy-document-infra" }
lib-ws = { path = "../frontend/rust-lib/lib-ws" }
lib-ot = { path = "../frontend/rust-lib/lib-ot" }
backend-service = { path = "../frontend/rust-lib/backend-service", features = ["http_server"] }
ormx = { version = "0.7", features = ["postgres"]}
[dependencies.sqlx]
@ -99,15 +98,14 @@ ignore_auth = []
parking_lot = "0.11"
once_cell = "1.7.2"
linkify = "0.5.0"
backend = { path = ".", features = ["flowy_test"]}
flowy-backend-api = { path = "../rust-lib/flowy-backend-api"}
flowy-sdk = { path = "../rust-lib/flowy-sdk", features = ["http_server"] }
flowy-user = { path = "../rust-lib/flowy-user", features = ["http_server"] }
flowy-document = { path = "../rust-lib/flowy-document", features = ["flowy_test", "http_server"] }
futures-util = "0.3.15"
flowy-ws = { path = "../rust-lib/flowy-ws" }
flowy-test = { path = "../rust-lib/flowy-test" }
flowy-infra = { path = "../rust-lib/flowy-infra" }
flowy-ot = { path = "../rust-lib/flowy-ot" }
flowy-sqlite = { path = "../rust-lib/flowy-sqlite" }
futures-util = "0.3.15"
backend = { path = ".", features = ["flowy_test"]}
flowy-sdk = { path = "../frontend/rust-lib/flowy-sdk", features = ["http_server"] }
flowy-user = { path = "../frontend/rust-lib/flowy-user", features = ["http_server"] }
flowy-document = { path = "../frontend/rust-lib/flowy-document", features = ["flowy_test", "http_server"] }
lib-ws = { path = "../frontend/rust-lib/lib-ws" }
flowy-test = { path = "../frontend/rust-lib/flowy-test" }
lib-infra = { path = "../frontend/rust-lib/lib-infra" }
lib-ot = { path = "../frontend/rust-lib/lib-ot" }
lib-sqlite = { path = "../frontend/rust-lib/lib-sqlite" }

View file

@ -4,7 +4,7 @@ use crate::service::{
};
use actix::Addr;
use actix_web::web::Data;
use flowy_ws::WsModule;
use lib_ws::WsModule;
use sqlx::PgPool;
use std::sync::Arc;

View file

@ -1,7 +1,7 @@
use crate::config::env::{domain, jwt_secret};
use backend_service::errors::ServerError;
use chrono::{Duration, Local};
use derive_more::{From, Into};
use flowy_net::errors::ServerError;
use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};
@ -76,7 +76,7 @@ impl Token {
use crate::service::user::EXPIRED_DURATION_DAYS;
use actix_web::{dev::Payload, FromRequest, HttpRequest};
use flowy_net::config::HEADER_TOKEN;
use backend_service::config::HEADER_TOKEN;
use futures::future::{ready, Ready};
impl FromRequest for Token {

View file

@ -9,7 +9,7 @@ use actix_web::{
use crate::config::IGNORE_ROUTES;
use actix_web::{body::AnyBody, dev::MessageBody};
use flowy_net::{config::HEADER_TOKEN, errors::ServerError};
use backend_service::{config::HEADER_TOKEN, errors::ServerError};
use futures::future::{ok, LocalBoxFuture, Ready};
use std::{
convert::TryInto,

View file

@ -5,8 +5,8 @@ use crate::{
};
use crate::service::trash::read_trash_ids;
use backend_service::errors::{invalid_params, ServerError};
use chrono::Utc;
use flowy_net::errors::{invalid_params, ServerError};
use flowy_workspace_infra::{
parser::{
app::{AppDesc, AppName},

View file

@ -2,7 +2,7 @@ use actix_web::{
web::{Data, Payload},
HttpResponse,
};
use flowy_net::errors::{invalid_params, ServerError};
use backend_service::errors::{invalid_params, ServerError};
use flowy_workspace_infra::protobuf::{AppIdentifier, CreateAppParams, UpdateAppParams};
use protobuf::Message;
use sqlx::PgPool;
@ -16,7 +16,7 @@ use crate::service::{
util::parse_from_payload,
};
use anyhow::Context;
use flowy_net::response::FlowyResponse;
use backend_service::response::FlowyResponse;
use flowy_workspace_infra::parser::app::{AppDesc, AppName};
pub async fn create_handler(

View file

@ -2,8 +2,8 @@ use crate::{
entities::workspace::{AppTable, APP_TABLE},
sqlx_ext::SqlBuilder,
};
use backend_service::errors::{invalid_params, ServerError};
use chrono::{DateTime, NaiveDateTime, Utc};
use flowy_net::errors::{invalid_params, ServerError};
use flowy_workspace_infra::{
parser::app::AppId,
protobuf::{App, ColorStyle},

View file

@ -3,8 +3,8 @@ use crate::{
sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
};
use anyhow::Context;
use backend_service::errors::ServerError;
use flowy_document_infra::protobuf::{CreateDocParams, Doc, DocIdentifier, UpdateDocParams};
use flowy_net::errors::ServerError;
use sqlx::{postgres::PgArguments, PgPool, Postgres};
use uuid::Uuid;

View file

@ -7,9 +7,9 @@ use crate::service::{
ws::{WsBizHandler, WsClientData},
};
use actix_web::web::Data;
use backend_service::errors::{internal_error, ServerError};
use dashmap::DashMap;
use flowy_document_infra::protobuf::DocIdentifier;
use flowy_net::errors::{internal_error, ServerError};
use sqlx::PgPool;
use std::sync::Arc;
use tokio::{

View file

@ -4,8 +4,8 @@ use crate::service::{
};
use actix_web::web::Data;
use async_stream::stream;
use backend_service::errors::{internal_error, Result as DocResult, ServerError};
use flowy_document_infra::protobuf::{Doc, Revision};
use flowy_net::errors::{internal_error, Result as DocResult, ServerError};
use futures::stream::StreamExt;
use sqlx::PgPool;
use std::sync::{atomic::Ordering::SeqCst, Arc};

View file

@ -1,27 +1,22 @@
use crate::service::{
doc::{edit::edit_actor::EditUser, update_doc},
util::md5,
ws::WsMessageAdaptor,
ws::{entities::Socket, WsMessageAdaptor},
};
use actix_web::web::Data;
use crate::service::ws::entities::Socket;
use bytes::Bytes;
use backend_service::errors::{internal_error, ServerError};
use dashmap::DashMap;
use flowy_document::{
use flowy_document_infra::{
core::Document,
entities::ws::{WsDataType, WsDocumentData},
services::doc::Document,
protobuf::{Doc, RevId, RevType, Revision, RevisionRange, UpdateDocParams},
};
use flowy_document_infra::protobuf::{Doc, RevId, RevType, Revision, RevisionRange, UpdateDocParams};
use flowy_net::errors::{internal_error, ServerError};
use flowy_ot::core::{Delta, OperationTransformable};
use flowy_ws::WsMessage;
use lib_ot::core::{Delta, OperationTransformable};
use parking_lot::RwLock;
use protobuf::Message;
use sqlx::PgPool;
use std::{
cmp::Ordering,
convert::TryInto,
sync::{
atomic::{AtomicI64, Ordering::SeqCst},
Arc,
@ -213,7 +208,7 @@ fn mk_push_message(doc_id: &str, revision: Revision) -> WsMessageAdaptor {
ty: WsDataType::PushRev,
data: bytes,
};
mk_ws_message(data)
data.into()
}
#[tracing::instrument(level = "debug", skip(socket, doc_id), err)]
@ -236,7 +231,7 @@ fn mk_pull_message(doc_id: &str, from_rev_id: i64, to_rev_id: i64) -> WsMessageA
ty: WsDataType::PullRev,
data: bytes,
};
mk_ws_message(data)
data.into()
}
#[tracing::instrument(level = "debug", skip(socket, revision), err)]
@ -248,7 +243,6 @@ fn send_acked_msg(socket: &Socket, revision: &Revision) -> Result<(), ServerErro
fn mk_acked_message(revision: &Revision) -> WsMessageAdaptor {
// let mut wtr = vec![];
// let _ = wtr.write_i64::<BigEndian>(revision.rev_id);
let mut rev_id = RevId::new();
rev_id.set_value(revision.rev_id);
let data = rev_id.write_to_bytes().unwrap();
@ -259,13 +253,7 @@ fn mk_acked_message(revision: &Revision) -> WsMessageAdaptor {
data,
};
mk_ws_message(data)
}
fn mk_ws_message<T: Into<WsMessage>>(data: T) -> WsMessageAdaptor {
let msg: WsMessage = data.into();
let bytes: Bytes = msg.try_into().unwrap();
WsMessageAdaptor(bytes)
data.into()
}
#[inline]

View file

@ -3,8 +3,8 @@ use crate::service::{
ws::{entities::Socket, WsUser},
};
use actix_web::web::Data;
use backend_service::errors::{internal_error, Result as DocResult, ServerError};
use flowy_document_infra::protobuf::{Doc, Revision};
use flowy_net::errors::{internal_error, Result as DocResult, ServerError};
use sqlx::PgPool;
use std::sync::Arc;
use tokio::sync::{mpsc, oneshot};

View file

@ -7,8 +7,8 @@ use actix_web::{
HttpResponse,
};
use anyhow::Context;
use backend_service::{errors::ServerError, response::FlowyResponse};
use flowy_document_infra::protobuf::{CreateDocParams, DocIdentifier, UpdateDocParams};
use flowy_net::{errors::ServerError, response::FlowyResponse};
use sqlx::PgPool;
pub async fn create_handler(payload: Payload, pool: Data<PgPool>) -> Result<HttpResponse, ServerError> {

View file

@ -6,9 +6,8 @@ use crate::service::{
use actix_rt::task::spawn_blocking;
use actix_web::web::Data;
use async_stream::stream;
use flowy_document::protobuf::{WsDataType, WsDocumentData};
use flowy_document_infra::protobuf::{NewDocUser, Revision};
use flowy_net::errors::{internal_error, Result as DocResult, ServerError};
use backend_service::errors::{internal_error, Result as DocResult, ServerError};
use flowy_document_infra::protobuf::{NewDocUser, Revision, WsDataType, WsDocumentData};
use futures::stream::StreamExt;
use sqlx::PgPool;
use std::sync::Arc;

View file

@ -9,7 +9,7 @@ use actix_web::{
HttpResponse,
};
use anyhow::Context;
use flowy_net::{
use backend_service::{
errors::{invalid_params, ServerError},
response::FlowyResponse,
};

View file

@ -8,7 +8,7 @@ use crate::{
sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
};
use ::protobuf::ProtobufEnum;
use flowy_net::errors::ServerError;
use backend_service::errors::ServerError;
use flowy_workspace_infra::protobuf::{RepeatedTrash, Trash, TrashType};
use sqlx::{postgres::PgArguments, Postgres, Row};
use uuid::Uuid;

View file

@ -4,11 +4,11 @@ use crate::{
sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
};
use anyhow::Context;
use chrono::Utc;
use flowy_net::{
use backend_service::{
errors::{invalid_params, ErrorCode, ServerError},
response::FlowyResponse,
};
use chrono::Utc;
use flowy_user_infra::{
parser::{UserEmail, UserName, UserPassword},
protobuf::{SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile},

View file

@ -1,8 +1,8 @@
use crate::entities::token::{Claim, Token};
use actix_web::http::HeaderValue;
use backend_service::errors::ServerError;
use chrono::{DateTime, Utc};
use dashmap::DashMap;
use flowy_net::errors::ServerError;
use lazy_static::lazy_static;
lazy_static! {

View file

@ -6,7 +6,7 @@ use actix_web::{
};
use sqlx::PgPool;
use flowy_net::{errors::ServerError, response::FlowyResponse};
use backend_service::{errors::ServerError, response::FlowyResponse};
use flowy_user_infra::protobuf::{SignInParams, SignUpParams, UpdateUserParams};
use crate::{

View file

@ -7,9 +7,9 @@ use crate::{
};
use crate::service::view::{create_view_with_args, sql_builder::NewViewSqlBuilder};
use backend_service::errors::ServerError;
use chrono::Utc;
use flowy_document_infra::user_default::doc_initial_string;
use flowy_net::errors::ServerError;
use flowy_workspace_infra::protobuf::Workspace;
use std::convert::TryInto;

View file

@ -1,5 +1,5 @@
use backend_service::errors::{ErrorCode, ServerError};
use bcrypt::{hash, verify, DEFAULT_COST};
use flowy_net::errors::{ErrorCode, ServerError};
#[allow(dead_code)]
pub fn uuid() -> String { uuid::Uuid::new_v4().to_string() }

View file

@ -1,6 +1,6 @@
use crate::config::MAX_PAYLOAD_SIZE;
use actix_web::web;
use flowy_net::errors::{ErrorCode, ServerError};
use backend_service::errors::{ErrorCode, ServerError};
use futures::StreamExt;
use protobuf::{Message, ProtobufResult};
@ -10,9 +10,7 @@ pub async fn parse_from_payload<T: Message>(payload: web::Payload) -> Result<T,
}
#[allow(dead_code)]
pub async fn parse_from_dev_payload<T: Message>(
payload: &mut actix_web::dev::Payload,
) -> Result<T, ServerError> {
pub async fn parse_from_dev_payload<T: Message>(payload: &mut actix_web::dev::Payload) -> Result<T, ServerError> {
let bytes = poll_payload(payload).await?;
parse_from_bytes(&bytes)
}
@ -31,9 +29,7 @@ pub fn parse_from_bytes<T: Message>(bytes: &[u8]) -> Result<T, ServerError> {
}
}
pub async fn poll_payload(
payload: &mut actix_web::dev::Payload,
) -> Result<web::BytesMut, ServerError> {
pub async fn poll_payload(payload: &mut actix_web::dev::Payload) -> Result<web::BytesMut, ServerError> {
let mut body = web::BytesMut::new();
while let Some(chunk) = payload.next().await {
let chunk = chunk.map_err(|err| ServerError::internal().context(err))?;

View file

@ -9,7 +9,7 @@ use actix_web::{
HttpResponse,
};
use anyhow::Context;
use flowy_net::{
use backend_service::{
errors::{invalid_params, ServerError},
response::FlowyResponse,
};

View file

@ -2,8 +2,8 @@ use crate::{
entities::workspace::{ViewTable, VIEW_TABLE},
sqlx_ext::SqlBuilder,
};
use backend_service::errors::{invalid_params, ServerError};
use chrono::{DateTime, NaiveDateTime, Utc};
use flowy_net::errors::{invalid_params, ServerError};
use flowy_workspace_infra::{
parser::view::ViewId,
protobuf::{View, ViewType},

View file

@ -8,9 +8,9 @@ use crate::{
},
sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
};
use backend_service::errors::{invalid_params, ServerError};
use chrono::Utc;
use flowy_document_infra::protobuf::CreateDocParams;
use flowy_net::errors::{invalid_params, ServerError};
use flowy_workspace_infra::{
parser::{
app::AppId,

View file

@ -14,7 +14,7 @@ use actix_web::{
HttpResponse,
};
use anyhow::Context;
use flowy_net::{
use backend_service::{
errors::{invalid_params, ServerError},
response::FlowyResponse,
};

View file

@ -2,8 +2,8 @@ use crate::{
entities::workspace::{WorkspaceTable, WORKSPACE_TABLE},
sqlx_ext::SqlBuilder,
};
use backend_service::errors::{invalid_params, ServerError};
use chrono::{DateTime, NaiveDateTime, Utc};
use flowy_net::errors::{invalid_params, ServerError};
use flowy_workspace_infra::{parser::workspace::WorkspaceId, protobuf::Workspace};
use sqlx::postgres::PgArguments;
use uuid::Uuid;

View file

@ -5,7 +5,7 @@ use crate::{
sqlx_ext::*,
};
use anyhow::Context;
use flowy_net::errors::{invalid_params, ServerError};
use backend_service::errors::{invalid_params, ServerError};
use flowy_workspace_infra::{
parser::workspace::WorkspaceId,
protobuf::{RepeatedApp, RepeatedWorkspace, Workspace},

View file

@ -1,6 +1,6 @@
use crate::service::ws::WsClientData;
use flowy_ws::WsModule;
use lib_ws::WsModule;
use std::{collections::HashMap, sync::Arc};
pub trait WsBizHandler: Send + Sync {
@ -13,15 +13,9 @@ pub struct WsBizHandlers {
}
impl WsBizHandlers {
pub fn new() -> Self {
Self {
inner: HashMap::new(),
}
}
pub fn new() -> Self { Self { inner: HashMap::new() } }
pub fn register(&mut self, source: WsModule, handler: BizHandler) {
self.inner.insert(source, handler);
}
pub fn register(&mut self, source: WsModule, handler: BizHandler) { self.inner.insert(source, handler); }
pub fn get(&self, source: &WsModule) -> Option<BizHandler> {
match self.inner.get(source) {

View file

@ -1,6 +1,6 @@
use crate::service::ws::WsMessageAdaptor;
use actix::{Message, Recipient};
use flowy_net::errors::ServerError;
use backend_service::errors::ServerError;
use serde::{Deserialize, Serialize};
use std::fmt::Formatter;

View file

@ -1,5 +1,8 @@
use actix::Message;
use bytes::Bytes;
use flowy_document_infra::entities::ws::WsDocumentData;
use lib_ws::{WsMessage, WsModule};
use std::convert::TryInto;
#[derive(Debug, Message, Clone)]
#[rtype(result = "()")]
@ -10,3 +13,16 @@ impl std::ops::Deref for WsMessageAdaptor {
fn deref(&self) -> &Self::Target { &self.0 }
}
impl std::convert::From<WsDocumentData> for WsMessageAdaptor {
fn from(data: WsDocumentData) -> Self {
let bytes: Bytes = data.try_into().unwrap();
let msg = WsMessage {
module: WsModule::Doc,
data: bytes.to_vec(),
};
let bytes: Bytes = msg.try_into().unwrap();
WsMessageAdaptor(bytes)
}
}

View file

@ -14,7 +14,7 @@ use actix::*;
use actix_web::web::Data;
use actix_web_actors::{ws, ws::Message::Text};
use bytes::Bytes;
use flowy_ws::WsMessage;
use lib_ws::WsMessage;
use std::{convert::TryFrom, sync::Arc, time::Instant};
#[derive(Debug)]

View file

@ -3,8 +3,8 @@ use crate::service::ws::{
WsMessageAdaptor,
};
use actix::{Actor, Context, Handler};
use backend_service::errors::ServerError;
use dashmap::DashMap;
use flowy_net::errors::ServerError;
pub struct WsServer {
sessions: DashMap<SessionId, Session>,

View file

@ -1,4 +1,4 @@
use flowy_net::errors::ServerError;
use backend_service::errors::ServerError;
use sql_builder::SqlBuilder as InnerBuilder;
use sqlx::{postgres::PgArguments, Arguments, Encode, Postgres, Type};

View file

@ -1,4 +1,4 @@
use flowy_net::errors::{ErrorCode, ServerError};
use backend_service::errors::{ErrorCode, ServerError};
use sqlx::{Error, Postgres, Transaction};
pub type DBTransaction<'a> = Transaction<'a, Postgres>;

View file

@ -1,5 +1,5 @@
use crate::helper::{spawn_user_server, TestUserServer};
use flowy_net::errors::ErrorCode;
use crate::util::helper::{spawn_user_server, TestUserServer};
use backend_service::errors::ErrorCode;
use flowy_user_infra::entities::{SignInParams, SignUpParams, SignUpResponse, UpdateUserParams};
#[actix_rt::test]

View file

@ -1,4 +1,4 @@
use crate::helper::ViewTest;
use crate::util::helper::ViewTest;
use flowy_document_infra::entities::doc::DocIdentifier;
use flowy_workspace_infra::entities::view::ViewIdentifiers;

View file

@ -1,4 +1,4 @@
use crate::helper::*;
use crate::util::helper::*;
use flowy_workspace_infra::entities::{
app::{AppIdentifier, UpdateAppParams},
trash::{TrashIdentifier, TrashIdentifiers, TrashType},

View file

@ -1,6 +1,6 @@
use crate::document::helper::{DocScript, DocumentTest};
use flowy_document::services::doc::{Document, FlowyDoc};
use flowy_ot::core::{Attribute, Interval};
use flowy_document_infra::core::{Document, FlowyDoc};
use lib_ot::core::{Attribute, Interval};
#[rustfmt::skip]
// ┌─────────┐ ┌─────────┐
@ -20,10 +20,10 @@ use flowy_ot::core::{Attribute, Interval};
async fn delta_sync_while_editing() {
let test = DocumentTest::new().await;
test.run_scripts(vec![
DocScript::ConnectWs,
DocScript::OpenDoc,
DocScript::InsertText(0, "abc"),
DocScript::InsertText(3, "123"),
DocScript::ClientConnectWs,
DocScript::ClientOpenDoc,
DocScript::ClientInsertText(0, "abc"),
DocScript::ClientInsertText(3, "123"),
DocScript::AssertClient(r#"[{"insert":"abc123\n"}]"#),
DocScript::AssertServer(r#"[{"insert":"abc123\n"}]"#, 2),
])
@ -34,12 +34,12 @@ async fn delta_sync_while_editing() {
async fn delta_sync_multi_revs() {
let test = DocumentTest::new().await;
test.run_scripts(vec![
DocScript::ConnectWs,
DocScript::OpenDoc,
DocScript::InsertText(0, "abc"),
DocScript::InsertText(3, "123"),
DocScript::InsertText(6, "efg"),
DocScript::InsertText(9, "456"),
DocScript::ClientConnectWs,
DocScript::ClientOpenDoc,
DocScript::ClientInsertText(0, "abc"),
DocScript::ClientInsertText(3, "123"),
DocScript::ClientInsertText(6, "efg"),
DocScript::ClientInsertText(9, "456"),
])
.await;
}
@ -48,14 +48,14 @@ async fn delta_sync_multi_revs() {
async fn delta_sync_while_editing_with_attribute() {
let test = DocumentTest::new().await;
test.run_scripts(vec![
DocScript::ConnectWs,
DocScript::OpenDoc,
DocScript::InsertText(0, "abc"),
DocScript::FormatText(Interval::new(0, 3), Attribute::Bold(true)),
DocScript::ClientConnectWs,
DocScript::ClientOpenDoc,
DocScript::ClientInsertText(0, "abc"),
DocScript::ClientFormatText(Interval::new(0, 3), Attribute::Bold(true)),
DocScript::AssertClient(r#"[{"insert":"abc","attributes":{"bold":true}},{"insert":"\n"}]"#),
DocScript::AssertServer(r#"[{"insert":"abc","attributes":{"bold":true}},{"insert":"\n"}]"#, 2),
DocScript::InsertText(3, "efg"),
DocScript::FormatText(Interval::new(3, 5), Attribute::Italic(true)),
DocScript::ClientInsertText(3, "efg"),
DocScript::ClientFormatText(Interval::new(3, 5), Attribute::Italic(true)),
DocScript::AssertClient(r#"[{"insert":"abc","attributes":{"bold":true}},{"insert":"ef","attributes":{"bold":true,"italic":true}},{"insert":"g","attributes":{"bold":true}},{"insert":"\n"}]"#),
DocScript::AssertServer(r#"[{"insert":"abc","attributes":{"bold":true}},{"insert":"ef","attributes":{"bold":true,"italic":true}},{"insert":"g","attributes":{"bold":true}},{"insert":"\n"}]"#, 4),
])
@ -84,8 +84,8 @@ async fn delta_sync_with_http_request() {
let json = document.to_json();
test.run_scripts(vec![
DocScript::SetServerDocument(json, 3),
DocScript::OpenDoc,
DocScript::ServerSaveDocument(json, 3),
DocScript::ClientOpenDoc,
DocScript::AssertClient(r#"[{"insert":"123456\n"}]"#),
DocScript::AssertServer(r#"[{"insert":"123456\n"}]"#, 3),
])
@ -100,9 +100,9 @@ async fn delta_sync_with_server_push_delta() {
let json = document.to_json();
test.run_scripts(vec![
DocScript::OpenDoc,
DocScript::SetServerDocument(json, 3),
DocScript::ConnectWs,
DocScript::ClientOpenDoc,
DocScript::ServerSaveDocument(json, 3),
DocScript::ClientConnectWs,
DocScript::AssertClient(r#"[{"insert":"\n123\n"}]"#),
])
.await;
@ -147,10 +147,10 @@ async fn delta_sync_while_local_rev_less_than_server_rev() {
let json = document.to_json();
test.run_scripts(vec![
DocScript::OpenDoc,
DocScript::SetServerDocument(json, 3),
DocScript::InsertText(0, "abc"),
DocScript::ConnectWs,
DocScript::ClientOpenDoc,
DocScript::ServerSaveDocument(json, 3),
DocScript::ClientInsertText(0, "abc"),
DocScript::ClientConnectWs,
DocScript::AssertClient(r#"[{"insert":"abc\n123\n"}]"#),
DocScript::AssertServer(r#"[{"insert":"abc\n123\n"}]"#, 4),
])
@ -190,14 +190,14 @@ async fn delta_sync_while_local_rev_greater_than_server_rev() {
let json = document.to_json();
test.run_scripts(vec![
DocScript::SetServerDocument(json, 1),
DocScript::OpenDoc,
DocScript::ServerSaveDocument(json, 1),
DocScript::ClientOpenDoc,
DocScript::AssertClient(r#"[{"insert":"123\n"}]"#),
DocScript::InsertText(3, "abc"),
DocScript::InsertText(6, "efg"),
DocScript::ConnectWs,
DocScript::ClientInsertText(3, "abc"),
DocScript::ClientInsertText(6, "efg"),
DocScript::ClientConnectWs,
DocScript::AssertClient(r#"[{"insert":"123abcefg\n"}]"#),
DocScript::AssertServer(r#"[{"insert":"123abcefg\n"}]"#, 3),
// DocScript::AssertServer(r#"[{"insert":"123abcefg\n"}]"#, 3),
])
.await;
}

View file

@ -1,7 +1,7 @@
use actix_web::web::Data;
use backend::service::doc::{crud::update_doc, doc::DocManager};
use backend_service::config::ServerConfig;
use flowy_document::services::doc::ClientEditDoc as ClientEditDocContext;
use flowy_net::config::ServerConfig;
use flowy_test::{workspace::ViewTest, FlowyTest};
use flowy_user::services::user::UserSession;
use futures_util::{stream, stream::StreamExt};
@ -9,9 +9,9 @@ use sqlx::PgPool;
use std::sync::Arc;
use tokio::time::{sleep, Duration};
// use crate::helper::*;
use crate::helper::{spawn_server, TestServer};
use crate::util::helper::{spawn_server, TestServer};
use flowy_document_infra::{entities::doc::DocIdentifier, protobuf::UpdateDocParams};
use flowy_ot::core::{Attribute, Delta, Interval};
use lib_ot::core::{Attribute, Delta, Interval};
use parking_lot::RwLock;
pub struct DocumentTest {
@ -20,13 +20,13 @@ pub struct DocumentTest {
}
#[derive(Clone)]
pub enum DocScript {
ConnectWs,
InsertText(usize, &'static str),
FormatText(Interval, Attribute),
ClientConnectWs,
ClientInsertText(usize, &'static str),
ClientFormatText(Interval, Attribute),
ClientOpenDoc,
AssertClient(&'static str),
AssertServer(&'static str, i64),
SetServerDocument(String, i64), // delta_json, rev_id
OpenDoc,
ServerSaveDocument(String, i64), // delta_json, rev_id
}
impl DocumentTest {
@ -95,19 +95,19 @@ async fn run_scripts(context: Arc<RwLock<ScriptContext>>, scripts: Vec<DocScript
let fut = async move {
let doc_id = context.read().doc_id.clone();
match script {
DocScript::ConnectWs => {
DocScript::ClientConnectWs => {
// sleep(Duration::from_millis(300)).await;
let user_session = context.read().client_user_session.clone();
let token = user_session.token().unwrap();
let _ = user_session.start_ws_connection(&token).await.unwrap();
},
DocScript::OpenDoc => {
DocScript::ClientOpenDoc => {
context.write().open_doc().await;
},
DocScript::InsertText(index, s) => {
DocScript::ClientInsertText(index, s) => {
context.read().client_edit_context().insert(index, s).await.unwrap();
},
DocScript::FormatText(interval, attribute) => {
DocScript::ClientFormatText(interval, attribute) => {
context
.read()
.client_edit_context()
@ -129,7 +129,7 @@ async fn run_scripts(context: Arc<RwLock<ScriptContext>>, scripts: Vec<DocScript
let json = edit_doc.document_json().await.unwrap();
assert_eq(s, &json);
},
DocScript::SetServerDocument(json, rev_id) => {
DocScript::ServerSaveDocument(json, rev_id) => {
let pg_pool = context.read().server_pg_pool.clone();
save_doc(&doc_id, json, rev_id, pg_pool).await;
},

View file

@ -1,3 +1,3 @@
mod api;
mod document;
pub mod helper;
pub mod util;

View file

@ -3,10 +3,9 @@ use backend::{
config::{get_configuration, DatabaseSettings},
context::AppContext,
};
use flowy_backend_api::{user_request::*, workspace_request::*};
use backend_service::{errors::ServerError, user_request::*, workspace_request::*};
use flowy_document::services::server::read_doc_request;
use flowy_document_infra::entities::doc::{Doc, DocIdentifier};
use flowy_net::errors::ServerError;
use flowy_user_infra::entities::*;
use flowy_workspace_infra::entities::prelude::*;
use sqlx::{Connection, Executor, PgConnection, PgPool};

View file

@ -0,0 +1 @@
pub mod helper;

View file

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 544 B

View file

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 442 B

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View file

Before

Width:  |  Height:  |  Size: 268 B

After

Width:  |  Height:  |  Size: 268 B

View file

Before

Width:  |  Height:  |  Size: 361 B

After

Width:  |  Height:  |  Size: 361 B

View file

Before

Width:  |  Height:  |  Size: 361 B

After

Width:  |  Height:  |  Size: 361 B

View file

Before

Width:  |  Height:  |  Size: 361 B

After

Width:  |  Height:  |  Size: 361 B

View file

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 195 B

View file

Before

Width:  |  Height:  |  Size: 194 B

After

Width:  |  Height:  |  Size: 194 B

View file

Before

Width:  |  Height:  |  Size: 797 B

After

Width:  |  Height:  |  Size: 797 B

View file

Before

Width:  |  Height:  |  Size: 641 B

After

Width:  |  Height:  |  Size: 641 B

View file

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 277 B

View file

Before

Width:  |  Height:  |  Size: 202 B

After

Width:  |  Height:  |  Size: 202 B

View file

Before

Width:  |  Height:  |  Size: 561 B

After

Width:  |  Height:  |  Size: 561 B

View file

Before

Width:  |  Height:  |  Size: 421 B

After

Width:  |  Height:  |  Size: 421 B

View file

Before

Width:  |  Height:  |  Size: 274 B

After

Width:  |  Height:  |  Size: 274 B

View file

Before

Width:  |  Height:  |  Size: 336 B

After

Width:  |  Height:  |  Size: 336 B

View file

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 148 B

View file

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 197 B

View file

Before

Width:  |  Height:  |  Size: 475 B

After

Width:  |  Height:  |  Size: 475 B

View file

Before

Width:  |  Height:  |  Size: 825 B

After

Width:  |  Height:  |  Size: 825 B

View file

Before

Width:  |  Height:  |  Size: 790 B

After

Width:  |  Height:  |  Size: 790 B

View file

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 369 B

View file

Before

Width:  |  Height:  |  Size: 618 B

After

Width:  |  Height:  |  Size: 618 B

View file

Before

Width:  |  Height:  |  Size: 886 B

After

Width:  |  Height:  |  Size: 886 B

Some files were not shown because too many files have changed in this diff Show more