mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor test to tokio::test to enable & enable test doc with server
This commit is contained in:
parent
01c9620e03
commit
83acc79cd1
@ -32,10 +32,7 @@ pub struct Application {
|
||||
|
||||
impl Application {
|
||||
pub async fn build(configuration: Settings) -> Result<Self, std::io::Error> {
|
||||
let address = format!(
|
||||
"{}:{}",
|
||||
configuration.application.host, configuration.application.port
|
||||
);
|
||||
let address = format!("{}:{}", configuration.application.host, configuration.application.port);
|
||||
let listener = TcpListener::bind(&address)?;
|
||||
let port = listener.local_addr().unwrap().port();
|
||||
let app_ctx = init_app_context(&configuration).await;
|
||||
@ -122,6 +119,7 @@ fn user_scope() -> Scope {
|
||||
.route(web::patch().to(view::update_handler))
|
||||
)
|
||||
.service(web::resource("/doc")
|
||||
.route(web::get().to(doc::create_handler))
|
||||
.route(web::get().to(doc::read_handler))
|
||||
.route(web::patch().to(doc::update_handler))
|
||||
)
|
||||
@ -132,15 +130,11 @@ fn user_scope() -> Scope {
|
||||
}
|
||||
|
||||
async fn init_app_context(configuration: &Settings) -> AppContext {
|
||||
let _ = crate::service::log::Builder::new("flowy")
|
||||
.env_filter("Trace")
|
||||
.build();
|
||||
let pg_pool = get_connection_pool(&configuration.database)
|
||||
.await
|
||||
.expect(&format!(
|
||||
"Failed to connect to Postgres at {:?}.",
|
||||
configuration.database
|
||||
));
|
||||
let _ = crate::service::log::Builder::new("flowy").env_filter("Trace").build();
|
||||
let pg_pool = get_connection_pool(&configuration.database).await.expect(&format!(
|
||||
"Failed to connect to Postgres at {:?}.",
|
||||
configuration.database
|
||||
));
|
||||
|
||||
let ws_server = WsServer::new().start();
|
||||
|
||||
|
@ -9,6 +9,7 @@ use flowy_net::errors::ServerError;
|
||||
use sqlx::{postgres::PgArguments, PgPool, Postgres};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(transaction), err)]
|
||||
pub(crate) async fn create_doc(
|
||||
transaction: &mut DBTransaction<'_>,
|
||||
params: CreateDocParams,
|
||||
@ -23,6 +24,7 @@ pub(crate) async fn create_doc(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(pool), err)]
|
||||
pub(crate) async fn read_doc(pool: &PgPool, params: QueryDocParams) -> Result<Doc, ServerError> {
|
||||
let doc_id = Uuid::parse_str(¶ms.doc_id)?;
|
||||
let mut transaction = pool
|
||||
@ -30,9 +32,7 @@ pub(crate) async fn read_doc(pool: &PgPool, params: QueryDocParams) -> Result<Do
|
||||
.await
|
||||
.context("Failed to acquire a Postgres connection to read doc")?;
|
||||
|
||||
let builder = SqlBuilder::select(DOC_TABLE)
|
||||
.add_field("*")
|
||||
.and_where_eq("id", &doc_id);
|
||||
let builder = SqlBuilder::select(DOC_TABLE).add_field("*").and_where_eq("id", &doc_id);
|
||||
|
||||
let (sql, args) = builder.build()?;
|
||||
// TODO: benchmark the speed of different documents with different size
|
||||
@ -51,10 +51,7 @@ pub(crate) async fn read_doc(pool: &PgPool, params: QueryDocParams) -> Result<Do
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(pool, params), err)]
|
||||
pub(crate) async fn update_doc(
|
||||
pool: &PgPool,
|
||||
mut params: UpdateDocParams,
|
||||
) -> Result<(), ServerError> {
|
||||
pub(crate) async fn update_doc(pool: &PgPool, mut params: UpdateDocParams) -> Result<(), ServerError> {
|
||||
let doc_id = Uuid::parse_str(¶ms.doc_id)?;
|
||||
let mut transaction = pool
|
||||
.begin()
|
||||
@ -82,13 +79,9 @@ pub(crate) async fn update_doc(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn delete_doc(
|
||||
transaction: &mut DBTransaction<'_>,
|
||||
doc_id: Uuid,
|
||||
) -> Result<(), ServerError> {
|
||||
let (sql, args) = SqlBuilder::delete(DOC_TABLE)
|
||||
.and_where_eq("id", doc_id)
|
||||
.build()?;
|
||||
#[tracing::instrument(level = "debug", skip(transaction), err)]
|
||||
pub(crate) async fn delete_doc(transaction: &mut DBTransaction<'_>, doc_id: Uuid) -> Result<(), ServerError> {
|
||||
let (sql, args) = SqlBuilder::delete(DOC_TABLE).and_where_eq("id", doc_id).build()?;
|
||||
|
||||
let _ = sqlx::query_with(&sql, args)
|
||||
.execute(transaction)
|
||||
|
@ -1,32 +1,42 @@
|
||||
use crate::service::{
|
||||
doc::{create_doc, read_doc, update_doc},
|
||||
util::parse_from_payload,
|
||||
};
|
||||
use actix_web::{
|
||||
web::{Data, Payload},
|
||||
HttpResponse,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use flowy_document::protobuf::{CreateDocParams, QueryDocParams, UpdateDocParams};
|
||||
use flowy_net::{errors::ServerError, response::FlowyResponse};
|
||||
use sqlx::PgPool;
|
||||
|
||||
use flowy_document::protobuf::{QueryDocParams, UpdateDocParams};
|
||||
use flowy_net::errors::ServerError;
|
||||
pub async fn create_handler(payload: Payload, pool: Data<PgPool>) -> Result<HttpResponse, ServerError> {
|
||||
let params: CreateDocParams = parse_from_payload(payload).await?;
|
||||
|
||||
use crate::service::{
|
||||
doc::{read_doc, update_doc},
|
||||
util::parse_from_payload,
|
||||
};
|
||||
use flowy_net::response::FlowyResponse;
|
||||
let mut transaction = pool
|
||||
.begin()
|
||||
.await
|
||||
.context("Failed to acquire a Postgres connection to create doc")?;
|
||||
|
||||
pub async fn read_handler(
|
||||
payload: Payload,
|
||||
pool: Data<PgPool>,
|
||||
) -> Result<HttpResponse, ServerError> {
|
||||
let _ = create_doc(&mut transaction, params).await?;
|
||||
|
||||
transaction
|
||||
.commit()
|
||||
.await
|
||||
.context("Failed to commit SQL transaction to create doc.")?;
|
||||
|
||||
Ok(FlowyResponse::success().into())
|
||||
}
|
||||
|
||||
pub async fn read_handler(payload: Payload, pool: Data<PgPool>) -> Result<HttpResponse, ServerError> {
|
||||
let params: QueryDocParams = parse_from_payload(payload).await?;
|
||||
let doc = read_doc(pool.get_ref(), params).await?;
|
||||
let response = FlowyResponse::success().pb(doc)?;
|
||||
Ok(response.into())
|
||||
}
|
||||
|
||||
pub async fn update_handler(
|
||||
payload: Payload,
|
||||
pool: Data<PgPool>,
|
||||
) -> Result<HttpResponse, ServerError> {
|
||||
pub async fn update_handler(payload: Payload, pool: Data<PgPool>) -> Result<HttpResponse, ServerError> {
|
||||
let params: UpdateDocParams = parse_from_payload(payload).await?;
|
||||
let _ = update_doc(pool.get_ref(), params).await?;
|
||||
Ok(FlowyResponse::success().into())
|
||||
|
@ -24,10 +24,7 @@ use crate::{
|
||||
sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
|
||||
};
|
||||
|
||||
pub(crate) async fn create_view(
|
||||
pool: &PgPool,
|
||||
params: CreateViewParams,
|
||||
) -> Result<FlowyResponse, ServerError> {
|
||||
pub(crate) async fn create_view(pool: &PgPool, params: CreateViewParams) -> Result<FlowyResponse, ServerError> {
|
||||
let mut transaction = pool
|
||||
.begin()
|
||||
.await
|
||||
@ -41,6 +38,7 @@ pub(crate) async fn create_view(
|
||||
FlowyResponse::success().pb(view)
|
||||
}
|
||||
|
||||
#[tracing::instrument(name = "create_view", level = "debug", skip(transaction), err)]
|
||||
pub(crate) async fn create_view_with_transaction(
|
||||
transaction: &mut DBTransaction<'_>,
|
||||
params: CreateViewParams,
|
||||
@ -69,10 +67,7 @@ pub(crate) async fn create_view_with_transaction(
|
||||
Ok(view)
|
||||
}
|
||||
|
||||
pub(crate) async fn read_view(
|
||||
pool: &PgPool,
|
||||
params: QueryViewParams,
|
||||
) -> Result<FlowyResponse, ServerError> {
|
||||
pub(crate) async fn read_view(pool: &PgPool, params: QueryViewParams) -> Result<FlowyResponse, ServerError> {
|
||||
let view_id = check_view_id(params.view_id)?;
|
||||
let mut transaction = pool
|
||||
.begin()
|
||||
@ -109,28 +104,17 @@ pub(crate) async fn read_view(
|
||||
FlowyResponse::success().pb(view)
|
||||
}
|
||||
|
||||
pub(crate) async fn update_view(
|
||||
pool: &PgPool,
|
||||
params: UpdateViewParams,
|
||||
) -> Result<FlowyResponse, ServerError> {
|
||||
pub(crate) async fn update_view(pool: &PgPool, params: UpdateViewParams) -> Result<FlowyResponse, ServerError> {
|
||||
let view_id = check_view_id(params.view_id.clone())?;
|
||||
|
||||
let name = match params.has_name() {
|
||||
false => None,
|
||||
true => Some(
|
||||
ViewName::parse(params.get_name().to_owned())
|
||||
.map_err(invalid_params)?
|
||||
.0,
|
||||
),
|
||||
true => Some(ViewName::parse(params.get_name().to_owned()).map_err(invalid_params)?.0),
|
||||
};
|
||||
|
||||
let desc = match params.has_desc() {
|
||||
false => None,
|
||||
true => Some(
|
||||
ViewDesc::parse(params.get_desc().to_owned())
|
||||
.map_err(invalid_params)?
|
||||
.0,
|
||||
),
|
||||
true => Some(ViewDesc::parse(params.get_desc().to_owned()).map_err(invalid_params)?.0),
|
||||
};
|
||||
|
||||
let thumbnail = match params.has_thumbnail() {
|
||||
@ -169,19 +153,14 @@ pub(crate) async fn update_view(
|
||||
Ok(FlowyResponse::success())
|
||||
}
|
||||
|
||||
pub(crate) async fn delete_view(
|
||||
pool: &PgPool,
|
||||
view_id: &str,
|
||||
) -> Result<FlowyResponse, ServerError> {
|
||||
pub(crate) async fn delete_view(pool: &PgPool, view_id: &str) -> Result<FlowyResponse, ServerError> {
|
||||
let view_id = check_view_id(view_id.to_owned())?;
|
||||
let mut transaction = pool
|
||||
.begin()
|
||||
.await
|
||||
.context("Failed to acquire a Postgres connection to delete view")?;
|
||||
|
||||
let (sql, args) = SqlBuilder::delete(VIEW_TABLE)
|
||||
.and_where_eq("id", &view_id)
|
||||
.build()?;
|
||||
let (sql, args) = SqlBuilder::delete(VIEW_TABLE).and_where_eq("id", &view_id).build()?;
|
||||
|
||||
let _ = sqlx::query_with(&sql, args)
|
||||
.execute(&mut transaction)
|
||||
@ -215,10 +194,7 @@ pub(crate) async fn read_views_belong_to_id<'c>(
|
||||
.await
|
||||
.map_err(map_sqlx_error)?;
|
||||
|
||||
let views = tables
|
||||
.into_iter()
|
||||
.map(|table| table.into())
|
||||
.collect::<Vec<View>>();
|
||||
let views = tables.into_iter().map(|table| table.into()).collect::<Vec<View>>();
|
||||
|
||||
Ok(views)
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ pub async fn establish_ws_connection(
|
||||
server: Data<Addr<WsServer>>,
|
||||
biz_handlers: Data<WsBizHandlers>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
log::debug!("establish_ws_connection");
|
||||
match LoggedUser::from_token(token.clone()) {
|
||||
Ok(user) => {
|
||||
let ws_user = WsUser::new(user.clone());
|
||||
|
@ -1,12 +1,7 @@
|
||||
use crate::document::helper::{DocScript, DocumentTest};
|
||||
use tokio::time::{interval, Duration};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn ws_connect() {
|
||||
async fn edit_doc_insert_text() {
|
||||
let test = DocumentTest::new().await;
|
||||
test.run_scripts(vec![DocScript::SendText("abc")]).await;
|
||||
|
||||
let mut interval = interval(Duration::from_secs(10));
|
||||
interval.tick().await;
|
||||
interval.tick().await;
|
||||
}
|
@ -1,20 +1,23 @@
|
||||
use crate::helper::*;
|
||||
// use crate::helper::*;
|
||||
use crate::helper::{spawn_server, TestServer};
|
||||
use flowy_document::{
|
||||
entities::doc::{CreateDocParams, DocDelta, QueryDocParams},
|
||||
entities::doc::{DocDelta, QueryDocParams},
|
||||
module::FlowyDocument,
|
||||
services::doc::edit_doc_context::EditDocContext,
|
||||
};
|
||||
use flowy_infra::uuid;
|
||||
|
||||
use flowy_net::config::ServerConfig;
|
||||
use flowy_ot::core::Delta;
|
||||
use flowy_sdk::{FlowySDK, FlowySDKConfig};
|
||||
use flowy_test::{prelude::root_dir, FlowyTestSDK};
|
||||
use flowy_user::{entities::SignUpParams, services::user::UserSession};
|
||||
use flowy_workspace::prelude::DOC_DEFAULT_DATA;
|
||||
|
||||
use flowy_test::{workspace::ViewTest, FlowyTest, FlowyTestSDK};
|
||||
use flowy_user::services::user::UserSession;
|
||||
|
||||
use std::{str::FromStr, sync::Arc};
|
||||
use tokio::time::{interval, Duration};
|
||||
|
||||
pub struct DocumentTest {
|
||||
server: TestServer,
|
||||
sdk: FlowyTestSDK,
|
||||
flowy_test: FlowyTest,
|
||||
flowy_document: Arc<FlowyDocument>,
|
||||
user_session: Arc<UserSession>,
|
||||
edit_context: Arc<EditDocContext>,
|
||||
@ -26,50 +29,20 @@ pub enum DocScript {
|
||||
SendBinary(Vec<u8>),
|
||||
}
|
||||
|
||||
async fn create_doc(user_session: Arc<UserSession>, flowy_document: Arc<FlowyDocument>) -> Arc<EditDocContext> {
|
||||
let conn = user_session.db_pool().unwrap().get().unwrap();
|
||||
let doc_id = uuid();
|
||||
let params = CreateDocParams {
|
||||
id: doc_id.clone(),
|
||||
data: DOC_DEFAULT_DATA.to_string(),
|
||||
};
|
||||
let _ = flowy_document.create(params, &*conn).unwrap();
|
||||
|
||||
let edit_context = flowy_document
|
||||
.open(QueryDocParams { doc_id }, user_session.db_pool().unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
edit_context
|
||||
}
|
||||
|
||||
async fn init_user(user_session: Arc<UserSession>) {
|
||||
let params = SignUpParams {
|
||||
email: format!("{}@gmail.com", uuid()),
|
||||
name: "nathan".to_string(),
|
||||
password: "HelloWorld!@12".to_string(),
|
||||
};
|
||||
|
||||
user_session.sign_up(params).await.unwrap();
|
||||
user_session.init_user().await.unwrap();
|
||||
}
|
||||
|
||||
impl DocumentTest {
|
||||
pub async fn new() -> Self {
|
||||
let server = spawn_server().await;
|
||||
let config = FlowySDKConfig::new(&root_dir(), &server.host, "http", "ws").log_filter("debug");
|
||||
let sdk = FlowySDK::new(config);
|
||||
let server_config = ServerConfig::new(&server.host, "http", "ws");
|
||||
let flowy_test = FlowyTest::setup_with(server_config);
|
||||
|
||||
let flowy_document = sdk.flowy_document.clone();
|
||||
let user_session = sdk.user_session.clone();
|
||||
|
||||
init_user(user_session.clone()).await;
|
||||
|
||||
let edit_context = create_doc(user_session.clone(), flowy_document.clone()).await;
|
||||
init_user(&flowy_test).await;
|
||||
|
||||
let edit_context = create_doc(&flowy_test).await;
|
||||
let user_session = flowy_test.sdk.user_session.clone();
|
||||
let flowy_document = flowy_test.sdk.flowy_document.clone();
|
||||
Self {
|
||||
server,
|
||||
sdk,
|
||||
flowy_test,
|
||||
flowy_document,
|
||||
user_session,
|
||||
edit_context,
|
||||
@ -93,5 +66,30 @@ impl DocumentTest {
|
||||
}
|
||||
}
|
||||
std::mem::forget(self);
|
||||
|
||||
let mut interval = interval(Duration::from_secs(5));
|
||||
interval.tick().await;
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
|
||||
async fn create_doc(flowy_test: &FlowyTest) -> Arc<EditDocContext> {
|
||||
let view_test = ViewTest::new(flowy_test).await;
|
||||
let doc_id = view_test.view.id.clone();
|
||||
let user_session = flowy_test.sdk.user_session.clone();
|
||||
let flowy_document = flowy_test.sdk.flowy_document.clone();
|
||||
|
||||
let edit_context = flowy_document
|
||||
.open(QueryDocParams { doc_id }, user_session.db_pool().unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
edit_context
|
||||
}
|
||||
|
||||
async fn init_user(flowy_test: &FlowyTest) {
|
||||
let _ = flowy_test.sign_up().await;
|
||||
|
||||
let user_session = flowy_test.sdk.user_session.clone();
|
||||
user_session.init_user().await.unwrap();
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
mod edit;
|
||||
mod helper;
|
||||
mod ws;
|
||||
|
@ -31,6 +31,7 @@ flowy-dispatch = {path = "../flowy-dispatch"}
|
||||
flowy-sdk = {path = "../flowy-sdk"}
|
||||
flowy-derive = {path = "../flowy-derive"}
|
||||
flowy-observable = {path = "../flowy-observable"}
|
||||
flowy-net = {path = "../flowy-net"}
|
||||
|
||||
|
||||
[features]
|
||||
|
@ -24,10 +24,8 @@ pub extern "C" fn init_sdk(path: *mut c_char) -> i64 {
|
||||
let c_str: &CStr = unsafe { CStr::from_ptr(path) };
|
||||
let path: &str = c_str.to_str().unwrap();
|
||||
|
||||
let host = "localhost";
|
||||
let http_schema = "http";
|
||||
let ws_schema = "ws";
|
||||
let config = FlowySDKConfig::new(path, host, http_schema, ws_schema).log_filter("debug");
|
||||
let server_config = ServerConfig::default();
|
||||
let config = FlowySDKConfig::new(path, server_config).log_filter("debug");
|
||||
*FLOWY_SDK.write() = Some(Arc::new(FlowySDK::new(config)));
|
||||
|
||||
return 1;
|
||||
@ -72,6 +70,8 @@ pub extern "C" fn set_stream_port(port: i64) -> i32 {
|
||||
pub extern "C" fn link_me_please() {}
|
||||
|
||||
use flowy_dispatch::prelude::ToBytes;
|
||||
use flowy_net::config::ServerConfig;
|
||||
|
||||
#[inline(always)]
|
||||
async fn post_to_flutter(response: EventResponse, port: i64) {
|
||||
let isolate = allo_isolate::Isolate::new(port);
|
||||
|
@ -8,7 +8,6 @@ use crate::{
|
||||
use derivative::*;
|
||||
use futures_core::future::BoxFuture;
|
||||
use futures_util::task::Context;
|
||||
|
||||
use pin_project::pin_project;
|
||||
use std::{future::Future, sync::Arc};
|
||||
use tokio::macros::support::{Pin, Poll};
|
||||
@ -73,7 +72,9 @@ impl EventDispatch {
|
||||
}
|
||||
|
||||
pub fn sync_send(dispatch: Arc<EventDispatch>, request: ModuleRequest) -> EventResponse {
|
||||
futures::executor::block_on(async { EventDispatch::async_send_with_callback(dispatch, request, |_| Box::pin(async {})).await })
|
||||
futures::executor::block_on(async {
|
||||
EventDispatch::async_send_with_callback(dispatch, request, |_| Box::pin(async {})).await
|
||||
})
|
||||
}
|
||||
|
||||
pub fn spawn<F>(&self, f: F)
|
||||
|
@ -14,6 +14,7 @@ use crate::{
|
||||
ws::WsDocumentManager,
|
||||
},
|
||||
};
|
||||
use flowy_net::config::ServerConfig;
|
||||
|
||||
pub trait DocumentUser: Send + Sync {
|
||||
fn user_dir(&self) -> Result<String, DocError>;
|
||||
@ -26,8 +27,12 @@ pub struct FlowyDocument {
|
||||
}
|
||||
|
||||
impl FlowyDocument {
|
||||
pub fn new(user: Arc<dyn DocumentUser>, ws_manager: Arc<RwLock<WsDocumentManager>>) -> FlowyDocument {
|
||||
let server = construct_doc_server();
|
||||
pub fn new(
|
||||
user: Arc<dyn DocumentUser>,
|
||||
ws_manager: Arc<RwLock<WsDocumentManager>>,
|
||||
server_config: &ServerConfig,
|
||||
) -> FlowyDocument {
|
||||
let server = construct_doc_server(server_config);
|
||||
let controller = Arc::new(DocController::new(server.clone(), user.clone(), ws_manager.clone()));
|
||||
Self { doc_ctrl: controller }
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ use crate::{
|
||||
errors::DocError,
|
||||
};
|
||||
use flowy_infra::future::ResultFuture;
|
||||
use flowy_net::config::ServerConfig;
|
||||
pub use server_api_mock::*;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -23,9 +24,9 @@ pub trait DocumentServerAPI {
|
||||
fn delete_doc(&self, token: &str, params: QueryDocParams) -> ResultFuture<(), DocError>;
|
||||
}
|
||||
|
||||
pub(crate) fn construct_doc_server() -> Arc<dyn DocumentServerAPI + Send + Sync> {
|
||||
pub(crate) fn construct_doc_server(server_config: &ServerConfig) -> Arc<dyn DocumentServerAPI + Send + Sync> {
|
||||
if cfg!(feature = "http_server") {
|
||||
Arc::new(DocServer {})
|
||||
Arc::new(DocServer::new(server_config.clone()))
|
||||
} else {
|
||||
Arc::new(DocServerMock {})
|
||||
}
|
||||
|
@ -6,31 +6,43 @@ use crate::{
|
||||
use flowy_infra::future::ResultFuture;
|
||||
use flowy_net::{config::*, request::HttpRequestBuilder};
|
||||
|
||||
pub struct DocServer {}
|
||||
pub struct DocServer {
|
||||
config: ServerConfig,
|
||||
}
|
||||
|
||||
impl DocServer {
|
||||
pub fn new(config: ServerConfig) -> Self { Self { config } }
|
||||
}
|
||||
|
||||
impl DocumentServerAPI for DocServer {
|
||||
fn create_doc(&self, token: &str, params: CreateDocParams) -> ResultFuture<(), DocError> {
|
||||
let token = token.to_owned();
|
||||
ResultFuture::new(async move { create_doc_request(&token, params, DOC_URL.as_ref()).await })
|
||||
let url = self.config.doc_url();
|
||||
ResultFuture::new(async move { create_doc_request(&token, params, &url).await })
|
||||
}
|
||||
|
||||
fn read_doc(&self, token: &str, params: QueryDocParams) -> ResultFuture<Option<Doc>, DocError> {
|
||||
let token = token.to_owned();
|
||||
ResultFuture::new(async move { read_doc_request(&token, params, DOC_URL.as_ref()).await })
|
||||
let url = self.config.doc_url();
|
||||
ResultFuture::new(async move { read_doc_request(&token, params, &url).await })
|
||||
}
|
||||
|
||||
fn update_doc(&self, token: &str, params: UpdateDocParams) -> ResultFuture<(), DocError> {
|
||||
let token = token.to_owned();
|
||||
ResultFuture::new(async move { update_doc_request(&token, params, DOC_URL.as_ref()).await })
|
||||
let url = self.config.doc_url();
|
||||
ResultFuture::new(async move { update_doc_request(&token, params, &url).await })
|
||||
}
|
||||
|
||||
fn delete_doc(&self, token: &str, params: QueryDocParams) -> ResultFuture<(), DocError> {
|
||||
let token = token.to_owned();
|
||||
ResultFuture::new(async move { delete_doc_request(&token, params, DOC_URL.as_ref()).await })
|
||||
let url = self.config.doc_url();
|
||||
ResultFuture::new(async move { delete_doc_request(&token, params, &url).await })
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn request_builder() -> HttpRequestBuilder { HttpRequestBuilder::new().middleware(super::middleware::MIDDLEWARE.clone()) }
|
||||
pub(crate) fn request_builder() -> HttpRequestBuilder {
|
||||
HttpRequestBuilder::new().middleware(super::middleware::MIDDLEWARE.clone())
|
||||
}
|
||||
|
||||
pub async fn create_doc_request(token: &str, params: CreateDocParams, url: &str) -> Result<(), DocError> {
|
||||
let _ = request_builder()
|
||||
|
@ -1,7 +1,6 @@
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
pub const HOST: &'static str = "localhost:8000";
|
||||
pub const SCHEMA: &'static str = "http://";
|
||||
pub const HTTP_SCHEMA: &'static str = "http";
|
||||
pub const WS_SCHEMA: &'static str = "ws";
|
||||
pub const HEADER_TOKEN: &'static str = "token";
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -11,6 +10,16 @@ pub struct ServerConfig {
|
||||
ws_schema: String,
|
||||
}
|
||||
|
||||
impl std::default::Default for ServerConfig {
|
||||
fn default() -> Self {
|
||||
ServerConfig {
|
||||
http_schema: HTTP_SCHEMA.to_string(),
|
||||
host: HOST.to_string(),
|
||||
ws_schema: WS_SCHEMA.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ServerConfig {
|
||||
pub fn new(host: &str, http_schema: &str, ws_schema: &str) -> Self {
|
||||
Self {
|
||||
@ -40,19 +49,3 @@ impl ServerConfig {
|
||||
|
||||
pub fn ws_addr(&self) -> String { format!("{}://{}/ws", self.ws_schema, self.host) }
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref SIGN_UP_URL: String = format!("{}/{}/api/register", SCHEMA, HOST);
|
||||
pub static ref SIGN_IN_URL: String = format!("{}/{}/api/auth", SCHEMA, HOST);
|
||||
pub static ref SIGN_OUT_URL: String = format!("{}/{}/api/auth", SCHEMA, HOST);
|
||||
pub static ref USER_PROFILE_URL: String = format!("{}/{}/api/user", SCHEMA, HOST);
|
||||
|
||||
//
|
||||
pub static ref WORKSPACE_URL: String = format!("{}/{}/api/workspace", SCHEMA, HOST);
|
||||
pub static ref APP_URL: String = format!("{}/{}/api/app", SCHEMA, HOST);
|
||||
pub static ref VIEW_URL: String = format!("{}/{}/api/view", SCHEMA, HOST);
|
||||
pub static ref DOC_URL: String = format!("{}/{}/api/doc", SCHEMA, HOST);
|
||||
|
||||
//
|
||||
pub static ref WS_ADDR: String = format!("ws://{}/ws", HOST);
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ pub struct FlowySDKConfig {
|
||||
}
|
||||
|
||||
impl FlowySDKConfig {
|
||||
pub fn new(root: &str, host: &str, http_schema: &str, ws_schema: &str) -> Self {
|
||||
let server_config = ServerConfig::new(host, http_schema, ws_schema);
|
||||
pub fn new(root: &str, server_config: ServerConfig) -> Self {
|
||||
FlowySDKConfig {
|
||||
root: root.to_owned(),
|
||||
log_filter: crate_log_filter(None),
|
||||
@ -71,7 +70,7 @@ impl FlowySDK {
|
||||
.root_dir(&config.root, &config.server_config)
|
||||
.build(),
|
||||
);
|
||||
let flowy_document = build_document_module(user_session.clone());
|
||||
let flowy_document = build_document_module(user_session.clone(), &config.server_config);
|
||||
let modules = build_modules(&config.server_config, user_session.clone(), flowy_document.clone());
|
||||
let dispatch = Arc::new(EventDispatch::construct(|| modules));
|
||||
|
||||
|
@ -28,9 +28,9 @@ fn build_workspace_module(
|
||||
flowy_workspace::module::create(user, database, flowy_document, server_config)
|
||||
}
|
||||
|
||||
pub fn build_document_module(user_session: Arc<UserSession>) -> Arc<FlowyDocument> {
|
||||
pub fn build_document_module(user_session: Arc<UserSession>, server_config: &ServerConfig) -> Arc<FlowyDocument> {
|
||||
let document_deps = DocumentDepsResolver::new(user_session.clone());
|
||||
let (user, ws_manager) = document_deps.split_into();
|
||||
let document = Arc::new(FlowyDocument::new(user, ws_manager));
|
||||
let document = Arc::new(FlowyDocument::new(user, ws_manager, server_config));
|
||||
document
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ flowy-user = { path = "../flowy-user"}
|
||||
flowy-workspace = { path = "../flowy-workspace"}
|
||||
flowy-infra = { path = "../flowy-infra"}
|
||||
flowy-document = { path = "../flowy-document"}
|
||||
flowy-net = { path = "../flowy-net"}
|
||||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
bincode = { version = "1.3"}
|
||||
|
@ -74,6 +74,13 @@ where
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn async_send(mut self) -> Self {
|
||||
let request = self.get_request();
|
||||
let resp = EventDispatch::async_send(self.dispatch(), request).await;
|
||||
self.context.response = Some(resp);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn parse<R>(self) -> R
|
||||
where
|
||||
R: FromBytes,
|
||||
@ -108,7 +115,13 @@ where
|
||||
|
||||
fn dispatch(&self) -> Arc<EventDispatch> { self.context.sdk.dispatch() }
|
||||
|
||||
fn get_response(&self) -> EventResponse { self.context.response.as_ref().expect("must call sync_send first").clone() }
|
||||
fn get_response(&self) -> EventResponse {
|
||||
self.context
|
||||
.response
|
||||
.as_ref()
|
||||
.expect("must call sync_send first")
|
||||
.clone()
|
||||
}
|
||||
|
||||
fn get_request(&mut self) -> ModuleRequest { self.context.request.take().expect("must call event first") }
|
||||
}
|
||||
|
@ -97,6 +97,26 @@ pub fn sign_up(dispatch: Arc<EventDispatch>) -> SignUpContext {
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
SignUpContext { user_profile, password }
|
||||
}
|
||||
|
||||
pub async fn async_sign_up(dispatch: Arc<EventDispatch>) -> SignUpContext {
|
||||
let password = login_password();
|
||||
let payload = SignUpRequest {
|
||||
email: random_email(),
|
||||
name: "app flowy".to_string(),
|
||||
password: password.clone(),
|
||||
}
|
||||
.into_bytes()
|
||||
.unwrap();
|
||||
|
||||
let request = ModuleRequest::new(SignUp).payload(payload);
|
||||
let user_profile = EventDispatch::async_send(dispatch.clone(), request)
|
||||
.await
|
||||
.parse::<UserProfile, UserError>()
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
// let _ = create_default_workspace_if_need(dispatch.clone(), &user_profile.id);
|
||||
SignUpContext { user_profile, password }
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
pub mod builder;
|
||||
mod helper;
|
||||
pub mod workspace;
|
||||
|
||||
use crate::helper::*;
|
||||
use flowy_net::config::ServerConfig;
|
||||
use flowy_sdk::{FlowySDK, FlowySDKConfig};
|
||||
use flowy_user::entities::UserProfile;
|
||||
|
||||
@ -13,37 +15,34 @@ pub mod prelude {
|
||||
pub type FlowyTestSDK = FlowySDK;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FlowyEnv {
|
||||
pub struct FlowyTest {
|
||||
pub sdk: FlowyTestSDK,
|
||||
pub user: UserProfile,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
impl FlowyEnv {
|
||||
impl FlowyTest {
|
||||
pub fn setup() -> Self {
|
||||
let host = "localhost";
|
||||
let http_schema = "http";
|
||||
let ws_schema = "ws";
|
||||
let server_config = ServerConfig::default();
|
||||
let test = Self::setup_with(server_config);
|
||||
std::mem::forget(test.sdk.dispatch());
|
||||
test
|
||||
}
|
||||
|
||||
let config = FlowySDKConfig::new(&root_dir(), host, http_schema, ws_schema).log_filter("debug");
|
||||
pub async fn sign_up(&self) -> SignUpContext {
|
||||
let context = async_sign_up(self.sdk.dispatch()).await;
|
||||
context
|
||||
}
|
||||
|
||||
pub async fn init_user(&self) -> UserProfile {
|
||||
let context = async_sign_up(self.sdk.dispatch()).await;
|
||||
context.user_profile
|
||||
}
|
||||
|
||||
pub fn setup_with(server_config: ServerConfig) -> Self {
|
||||
let config = FlowySDKConfig::new(&root_dir(), server_config).log_filter("debug");
|
||||
let sdk = FlowySDK::new(config);
|
||||
let result = sign_up(sdk.dispatch());
|
||||
let env = Self {
|
||||
sdk,
|
||||
user: result.user_profile,
|
||||
password: result.password,
|
||||
};
|
||||
env
|
||||
|
||||
Self { sdk }
|
||||
}
|
||||
|
||||
pub fn sdk(&self) -> FlowyTestSDK { self.sdk.clone() }
|
||||
}
|
||||
|
||||
pub fn init_test_sdk() -> FlowyTestSDK {
|
||||
let host = "localhost";
|
||||
let http_schema = "http";
|
||||
let ws_schema = "ws";
|
||||
|
||||
let config = FlowySDKConfig::new(&root_dir(), host, http_schema, ws_schema).log_filter("debug");
|
||||
FlowySDK::new(config)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::prelude::*;
|
||||
use flowy_document::entities::doc::Doc;
|
||||
use flowy_test::prelude::*;
|
||||
use flowy_workspace::{
|
||||
entities::{app::*, view::*, workspace::*},
|
||||
event::WorkspaceEvent::*,
|
||||
@ -11,12 +11,16 @@ pub struct WorkspaceTest {
|
||||
}
|
||||
|
||||
impl WorkspaceTest {
|
||||
pub fn new() -> Self {
|
||||
let sdk = FlowyEnv::setup().sdk;
|
||||
let workspace = create_workspace(&sdk, "Workspace", "");
|
||||
open_workspace(&sdk, &workspace.id);
|
||||
pub async fn new() -> Self {
|
||||
let test = FlowyTest::setup();
|
||||
let _ = test.init_user().await;
|
||||
let workspace = create_workspace(&test.sdk, "Workspace", "").await;
|
||||
open_workspace(&test.sdk, &workspace.id).await;
|
||||
|
||||
Self { sdk, workspace }
|
||||
Self {
|
||||
sdk: test.sdk,
|
||||
workspace,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,15 +31,20 @@ pub struct AppTest {
|
||||
}
|
||||
|
||||
impl AppTest {
|
||||
pub fn new() -> Self {
|
||||
let sdk = FlowyEnv::setup().sdk;
|
||||
let workspace = create_workspace(&sdk, "Workspace", "");
|
||||
open_workspace(&sdk, &workspace.id);
|
||||
let app = create_app(&sdk, "App", "AppFlowy Github Project", &workspace.id);
|
||||
Self { sdk, workspace, app }
|
||||
pub async fn new() -> Self {
|
||||
let test = FlowyTest::setup();
|
||||
let _ = test.init_user().await;
|
||||
let workspace = create_workspace(&test.sdk, "Workspace", "").await;
|
||||
open_workspace(&test.sdk, &workspace.id).await;
|
||||
let app = create_app(&test.sdk, "App", "AppFlowy Github Project", &workspace.id).await;
|
||||
Self {
|
||||
sdk: test.sdk,
|
||||
workspace,
|
||||
app,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_app_to_trash(&self) {
|
||||
pub async fn move_app_to_trash(&self) {
|
||||
let request = UpdateAppRequest {
|
||||
app_id: self.app.id.clone(),
|
||||
name: None,
|
||||
@ -43,11 +52,11 @@ impl AppTest {
|
||||
color_style: None,
|
||||
is_trash: Some(true),
|
||||
};
|
||||
update_app(&self.sdk, request);
|
||||
update_app(&self.sdk, request).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct ViewTest {
|
||||
pub struct ViewTest {
|
||||
pub sdk: FlowyTestSDK,
|
||||
pub workspace: Workspace,
|
||||
pub app: App,
|
||||
@ -55,16 +64,20 @@ pub(crate) struct ViewTest {
|
||||
}
|
||||
|
||||
impl ViewTest {
|
||||
pub fn new() -> Self {
|
||||
let sdk = FlowyEnv::setup().sdk;
|
||||
let workspace = create_workspace(&sdk, "Workspace", "");
|
||||
open_workspace(&sdk, &workspace.id);
|
||||
let app = create_app(&sdk, "App", "AppFlowy Github Project", &workspace.id);
|
||||
let view = create_view(&sdk, &app.id);
|
||||
Self { sdk, workspace, app, view }
|
||||
pub async fn new(test: &FlowyTest) -> Self {
|
||||
let workspace = create_workspace(&test.sdk, "Workspace", "").await;
|
||||
open_workspace(&test.sdk, &workspace.id).await;
|
||||
let app = create_app(&test.sdk, "App", "AppFlowy Github Project", &workspace.id).await;
|
||||
let view = create_view(&test.sdk, &app.id).await;
|
||||
Self {
|
||||
sdk: test.sdk.clone(),
|
||||
workspace,
|
||||
app,
|
||||
view,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_view_to_trash(&self) {
|
||||
pub async fn move_view_to_trash(&self) {
|
||||
let request = UpdateViewRequest {
|
||||
view_id: self.view.id.clone(),
|
||||
name: None,
|
||||
@ -72,18 +85,18 @@ impl ViewTest {
|
||||
thumbnail: None,
|
||||
is_trash: Some(true),
|
||||
};
|
||||
update_view(&self.sdk, request);
|
||||
update_view(&self.sdk, request).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn invalid_workspace_name_test_case() -> Vec<String> {
|
||||
pub fn invalid_workspace_name_test_case() -> Vec<String> {
|
||||
vec!["", "1234".repeat(100).as_str()]
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub fn create_workspace(sdk: &FlowyTestSDK, name: &str, desc: &str) -> Workspace {
|
||||
pub async fn create_workspace(sdk: &FlowyTestSDK, name: &str, desc: &str) -> Workspace {
|
||||
let request = CreateWorkspaceRequest {
|
||||
name: name.to_owned(),
|
||||
desc: desc.to_owned(),
|
||||
@ -92,19 +105,21 @@ pub fn create_workspace(sdk: &FlowyTestSDK, name: &str, desc: &str) -> Workspace
|
||||
let workspace = FlowyWorkspaceTest::new(sdk.clone())
|
||||
.event(CreateWorkspace)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<Workspace>();
|
||||
workspace
|
||||
}
|
||||
|
||||
fn open_workspace(sdk: &FlowyTestSDK, workspace_id: &str) {
|
||||
async fn open_workspace(sdk: &FlowyTestSDK, workspace_id: &str) {
|
||||
let request = QueryWorkspaceRequest {
|
||||
workspace_id: Some(workspace_id.to_owned()),
|
||||
};
|
||||
let _ = FlowyWorkspaceTest::new(sdk.clone())
|
||||
.event(OpenWorkspace)
|
||||
.request(request)
|
||||
.sync_send();
|
||||
.async_send()
|
||||
.await;
|
||||
}
|
||||
|
||||
pub fn read_workspace(sdk: &FlowyTestSDK, request: QueryWorkspaceRequest) -> Option<Workspace> {
|
||||
@ -129,7 +144,7 @@ pub fn read_workspace(sdk: &FlowyTestSDK, request: QueryWorkspaceRequest) -> Opt
|
||||
workspaces.drain(..1).collect::<Vec<Workspace>>().pop()
|
||||
}
|
||||
|
||||
pub fn create_app(sdk: &FlowyTestSDK, name: &str, desc: &str, workspace_id: &str) -> App {
|
||||
pub async fn create_app(sdk: &FlowyTestSDK, name: &str, desc: &str, workspace_id: &str) -> App {
|
||||
let create_app_request = CreateAppRequest {
|
||||
workspace_id: workspace_id.to_owned(),
|
||||
name: name.to_string(),
|
||||
@ -140,7 +155,8 @@ pub fn create_app(sdk: &FlowyTestSDK, name: &str, desc: &str, workspace_id: &str
|
||||
let app = FlowyWorkspaceTest::new(sdk.clone())
|
||||
.event(CreateApp)
|
||||
.request(create_app_request)
|
||||
.sync_send()
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<App>();
|
||||
app
|
||||
}
|
||||
@ -156,8 +172,12 @@ pub fn delete_app(sdk: &FlowyTestSDK, app_id: &str) {
|
||||
.sync_send();
|
||||
}
|
||||
|
||||
pub fn update_app(sdk: &FlowyTestSDK, request: UpdateAppRequest) {
|
||||
FlowyWorkspaceTest::new(sdk.clone()).event(UpdateApp).request(request).sync_send();
|
||||
pub async fn update_app(sdk: &FlowyTestSDK, request: UpdateAppRequest) {
|
||||
FlowyWorkspaceTest::new(sdk.clone())
|
||||
.event(UpdateApp)
|
||||
.request(request)
|
||||
.async_send()
|
||||
.await;
|
||||
}
|
||||
|
||||
pub fn read_app(sdk: &FlowyTestSDK, request: QueryAppRequest) -> App {
|
||||
@ -170,17 +190,17 @@ pub fn read_app(sdk: &FlowyTestSDK, request: QueryAppRequest) -> App {
|
||||
app
|
||||
}
|
||||
|
||||
pub fn create_view_with_request(sdk: &FlowyTestSDK, request: CreateViewRequest) -> View {
|
||||
pub async fn create_view_with_request(sdk: &FlowyTestSDK, request: CreateViewRequest) -> View {
|
||||
let view = FlowyWorkspaceTest::new(sdk.clone())
|
||||
.event(CreateView)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<View>();
|
||||
|
||||
view
|
||||
}
|
||||
|
||||
pub fn create_view(sdk: &FlowyTestSDK, app_id: &str) -> View {
|
||||
pub async fn create_view(sdk: &FlowyTestSDK, app_id: &str) -> View {
|
||||
let request = CreateViewRequest {
|
||||
belong_to_id: app_id.to_string(),
|
||||
name: "View A".to_string(),
|
||||
@ -189,25 +209,31 @@ pub fn create_view(sdk: &FlowyTestSDK, app_id: &str) -> View {
|
||||
view_type: ViewType::Doc,
|
||||
};
|
||||
|
||||
create_view_with_request(sdk, request)
|
||||
create_view_with_request(sdk, request).await
|
||||
}
|
||||
|
||||
pub fn update_view(sdk: &FlowyTestSDK, request: UpdateViewRequest) {
|
||||
FlowyWorkspaceTest::new(sdk.clone()).event(UpdateView).request(request).sync_send();
|
||||
pub async fn update_view(sdk: &FlowyTestSDK, request: UpdateViewRequest) {
|
||||
FlowyWorkspaceTest::new(sdk.clone())
|
||||
.event(UpdateView)
|
||||
.request(request)
|
||||
.async_send()
|
||||
.await;
|
||||
}
|
||||
|
||||
pub fn read_view(sdk: &FlowyTestSDK, request: QueryViewRequest) -> View {
|
||||
pub async fn read_view(sdk: &FlowyTestSDK, request: QueryViewRequest) -> View {
|
||||
FlowyWorkspaceTest::new(sdk.clone())
|
||||
.event(ReadView)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<View>()
|
||||
}
|
||||
|
||||
pub fn open_view(sdk: &FlowyTestSDK, request: OpenViewRequest) -> Doc {
|
||||
pub async fn open_view(sdk: &FlowyTestSDK, request: OpenViewRequest) -> Doc {
|
||||
FlowyWorkspaceTest::new(sdk.clone())
|
||||
.event(OpenView)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<Doc>()
|
||||
}
|
@ -2,7 +2,7 @@ use bytes::Bytes;
|
||||
use derive_more::Display;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_dispatch::prelude::{EventResponse, ResponseBuilder};
|
||||
use std::{convert::TryInto, fmt::Debug};
|
||||
use std::{convert::TryInto, fmt, fmt::Debug};
|
||||
|
||||
#[derive(Debug, Default, Clone, ProtoBuf)]
|
||||
pub struct UserError {
|
||||
@ -13,6 +13,10 @@ pub struct UserError {
|
||||
pub msg: String,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for UserError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}: {}", &self.code, &self.msg) }
|
||||
}
|
||||
|
||||
macro_rules! static_user_error {
|
||||
($name:ident, $status:expr) => {
|
||||
#[allow(non_snake_case, missing_docs)]
|
||||
|
@ -3,7 +3,7 @@ use flowy_dispatch::prelude::*;
|
||||
use std::{convert::TryInto, sync::Arc};
|
||||
|
||||
// tracing instrument 👉🏻 https://docs.rs/tracing/0.1.26/tracing/attr.instrument.html
|
||||
#[tracing::instrument(name = "sign_in", skip(data, session), fields(email = %data.email))]
|
||||
#[tracing::instrument(name = "sign_in", skip(data, session), fields(email = %data.email), err)]
|
||||
pub async fn sign_in(data: Data<SignInRequest>, session: Unit<Arc<UserSession>>) -> DataResult<UserProfile, UserError> {
|
||||
let params: SignInParams = data.into_inner().try_into()?;
|
||||
let user_profile = session.sign_in(params).await?;
|
||||
@ -16,7 +16,8 @@ pub async fn sign_in(data: Data<SignInRequest>, session: Unit<Arc<UserSession>>)
|
||||
fields(
|
||||
email = %data.email,
|
||||
name = %data.name,
|
||||
)
|
||||
),
|
||||
err
|
||||
)]
|
||||
pub async fn sign_up(data: Data<SignUpRequest>, session: Unit<Arc<UserSession>>) -> DataResult<UserProfile, UserError> {
|
||||
let params: SignUpParams = data.into_inner().try_into()?;
|
||||
|
@ -25,7 +25,6 @@ pub(crate) fn construct_user_server(config: &ServerConfig) -> Arc<dyn UserServer
|
||||
if cfg!(feature = "http_server") {
|
||||
Arc::new(UserServer::new(config.clone()))
|
||||
} else {
|
||||
// Arc::new(UserServerMock {})
|
||||
Arc::new(UserServer::new(config.clone()))
|
||||
Arc::new(UserServerMock {})
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::helper::*;
|
||||
use flowy_test::{builder::UserTest, init_test_sdk, FlowyEnv};
|
||||
use flowy_test::{builder::UserTest, FlowyTest};
|
||||
use flowy_user::{errors::ErrorCode, event::UserEvent::*, prelude::*};
|
||||
use serial_test::*;
|
||||
|
||||
@ -7,7 +7,7 @@ use serial_test::*;
|
||||
#[serial]
|
||||
fn sign_up_with_invalid_email() {
|
||||
for email in invalid_email_test_case() {
|
||||
let sdk = init_test_sdk();
|
||||
let test = FlowyTest::setup();
|
||||
let request = SignUpRequest {
|
||||
email: email.to_string(),
|
||||
name: valid_name(),
|
||||
@ -15,7 +15,12 @@ fn sign_up_with_invalid_email() {
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
UserTest::new(sdk).event(SignUp).request(request).sync_send().error().code,
|
||||
UserTest::new(test.sdk)
|
||||
.event(SignUp)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.error()
|
||||
.code,
|
||||
ErrorCode::EmailFormatInvalid
|
||||
);
|
||||
}
|
||||
@ -24,29 +29,33 @@ fn sign_up_with_invalid_email() {
|
||||
#[serial]
|
||||
fn sign_up_with_invalid_password() {
|
||||
for password in invalid_password_test_case() {
|
||||
let sdk = init_test_sdk();
|
||||
let test = FlowyTest::setup();
|
||||
let request = SignUpRequest {
|
||||
email: random_email(),
|
||||
name: valid_name(),
|
||||
password,
|
||||
};
|
||||
|
||||
UserTest::new(sdk).event(SignUp).request(request).sync_send().assert_error();
|
||||
UserTest::new(test.sdk)
|
||||
.event(SignUp)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.assert_error();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn sign_in_success() {
|
||||
let env = FlowyEnv::setup();
|
||||
let _ = UserTest::new(env.sdk()).event(SignOut).sync_send();
|
||||
#[tokio::test]
|
||||
async fn sign_in_success() {
|
||||
let test = FlowyTest::setup();
|
||||
let _ = UserTest::new(test.sdk()).event(SignOut).sync_send();
|
||||
let sign_up_context = test.sign_up().await;
|
||||
|
||||
let request = SignInRequest {
|
||||
email: env.user.email.clone(),
|
||||
password: env.password.clone(),
|
||||
email: sign_up_context.user_profile.email.clone(),
|
||||
password: sign_up_context.password.clone(),
|
||||
};
|
||||
|
||||
let response = UserTest::new(env.sdk())
|
||||
let response = UserTest::new(test.sdk())
|
||||
.event(SignIn)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
@ -58,14 +67,19 @@ fn sign_in_success() {
|
||||
#[serial]
|
||||
fn sign_in_with_invalid_email() {
|
||||
for email in invalid_email_test_case() {
|
||||
let sdk = init_test_sdk();
|
||||
let test = FlowyTest::setup();
|
||||
let request = SignInRequest {
|
||||
email: email.to_string(),
|
||||
password: login_password(),
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
UserTest::new(sdk).event(SignIn).request(request).sync_send().error().code,
|
||||
UserTest::new(test.sdk)
|
||||
.event(SignIn)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.error()
|
||||
.code,
|
||||
ErrorCode::EmailFormatInvalid
|
||||
);
|
||||
}
|
||||
@ -75,12 +89,17 @@ fn sign_in_with_invalid_email() {
|
||||
#[serial]
|
||||
fn sign_in_with_invalid_password() {
|
||||
for password in invalid_password_test_case() {
|
||||
let sdk = init_test_sdk();
|
||||
let test = FlowyTest::setup();
|
||||
|
||||
let request = SignInRequest {
|
||||
email: random_email(),
|
||||
password,
|
||||
};
|
||||
|
||||
UserTest::new(sdk).event(SignIn).request(request).sync_send().assert_error();
|
||||
UserTest::new(test.sdk)
|
||||
.event(SignIn)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.assert_error();
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +1,39 @@
|
||||
use crate::helper::*;
|
||||
use flowy_infra::uuid;
|
||||
use flowy_test::{builder::UserTest, init_test_sdk, FlowyEnv};
|
||||
use flowy_test::{builder::UserTest, FlowyTest};
|
||||
use flowy_user::{errors::ErrorCode, event::UserEvent::*, prelude::*};
|
||||
use serial_test::*;
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn user_profile_get_failed() {
|
||||
let sdk = init_test_sdk();
|
||||
let result = UserTest::new(sdk).event(GetUserProfile).assert_error().sync_send();
|
||||
let test = FlowyTest::setup();
|
||||
let result = UserTest::new(test.sdk).event(GetUserProfile).assert_error().sync_send();
|
||||
assert!(result.user_profile().is_none())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
fn user_profile_get() {
|
||||
let env = FlowyEnv::setup();
|
||||
let user = UserTest::new(env.sdk.clone())
|
||||
async fn user_profile_get() {
|
||||
let test = FlowyTest::setup();
|
||||
let user_profile = test.init_user().await;
|
||||
let user = UserTest::new(test.sdk.clone())
|
||||
.event(GetUserProfile)
|
||||
.sync_send()
|
||||
.parse::<UserProfile>();
|
||||
assert_eq!(env.user, user);
|
||||
assert_eq!(user_profile, user);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
fn user_update_with_name() {
|
||||
let env = FlowyEnv::setup();
|
||||
async fn user_update_with_name() {
|
||||
let test = FlowyTest::setup();
|
||||
let user = test.init_user().await;
|
||||
let new_name = "hello_world".to_owned();
|
||||
let request = UpdateUserRequest::new(&env.user.id).name(&new_name);
|
||||
let _ = UserTest::new(env.sdk()).event(UpdateUser).request(request).sync_send();
|
||||
let request = UpdateUserRequest::new(&user.id).name(&new_name);
|
||||
let _ = UserTest::new(test.sdk()).event(UpdateUser).request(request).sync_send();
|
||||
|
||||
let user_profile = UserTest::new(env.sdk())
|
||||
let user_profile = UserTest::new(test.sdk())
|
||||
.event(GetUserProfile)
|
||||
.assert_error()
|
||||
.sync_send()
|
||||
@ -40,14 +42,15 @@ fn user_update_with_name() {
|
||||
assert_eq!(user_profile.name, new_name,);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
fn user_update_with_email() {
|
||||
let env = FlowyEnv::setup();
|
||||
async fn user_update_with_email() {
|
||||
let test = FlowyTest::setup();
|
||||
let user = test.init_user().await;
|
||||
let new_email = format!("{}@gmai.com", uuid());
|
||||
let request = UpdateUserRequest::new(&env.user.id).email(&new_email);
|
||||
let _ = UserTest::new(env.sdk()).event(UpdateUser).request(request).sync_send();
|
||||
let user_profile = UserTest::new(env.sdk())
|
||||
let request = UpdateUserRequest::new(&user.id).email(&new_email);
|
||||
let _ = UserTest::new(test.sdk()).event(UpdateUser).request(request).sync_send();
|
||||
let user_profile = UserTest::new(test.sdk())
|
||||
.event(GetUserProfile)
|
||||
.assert_error()
|
||||
.sync_send()
|
||||
@ -56,41 +59,49 @@ fn user_update_with_email() {
|
||||
assert_eq!(user_profile.email, new_email,);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
fn user_update_with_password() {
|
||||
let env = FlowyEnv::setup();
|
||||
async fn user_update_with_password() {
|
||||
let test = FlowyTest::setup();
|
||||
let user = test.init_user().await;
|
||||
let new_password = "H123world!".to_owned();
|
||||
let request = UpdateUserRequest::new(&env.user.id).password(&new_password);
|
||||
let request = UpdateUserRequest::new(&user.id).password(&new_password);
|
||||
|
||||
let _ = UserTest::new(env.sdk())
|
||||
let _ = UserTest::new(test.sdk())
|
||||
.event(UpdateUser)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.assert_success();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
fn user_update_with_invalid_email() {
|
||||
let env = FlowyEnv::setup();
|
||||
async fn user_update_with_invalid_email() {
|
||||
let test = FlowyTest::setup();
|
||||
let user = test.init_user().await;
|
||||
for email in invalid_email_test_case() {
|
||||
let request = UpdateUserRequest::new(&env.user.id).email(&email);
|
||||
let request = UpdateUserRequest::new(&user.id).email(&email);
|
||||
assert_eq!(
|
||||
UserTest::new(env.sdk()).event(UpdateUser).request(request).sync_send().error().code,
|
||||
UserTest::new(test.sdk())
|
||||
.event(UpdateUser)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.error()
|
||||
.code,
|
||||
ErrorCode::EmailFormatInvalid
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
fn user_update_with_invalid_password() {
|
||||
let env = FlowyEnv::setup();
|
||||
async fn user_update_with_invalid_password() {
|
||||
let test = FlowyTest::setup();
|
||||
let user = test.init_user().await;
|
||||
for password in invalid_password_test_case() {
|
||||
let request = UpdateUserRequest::new(&env.user.id).password(&password);
|
||||
let request = UpdateUserRequest::new(&user.id).password(&password);
|
||||
|
||||
UserTest::new(env.sdk())
|
||||
UserTest::new(test.sdk())
|
||||
.event(UpdateUser)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
@ -98,12 +109,13 @@ fn user_update_with_invalid_password() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
fn user_update_with_invalid_name() {
|
||||
let env = FlowyEnv::setup();
|
||||
let request = UpdateUserRequest::new(&env.user.id).name("");
|
||||
UserTest::new(env.sdk())
|
||||
async fn user_update_with_invalid_name() {
|
||||
let test = FlowyTest::setup();
|
||||
let user = test.init_user().await;
|
||||
let request = UpdateUserRequest::new(&user.id).name("");
|
||||
UserTest::new(test.sdk())
|
||||
.event(UpdateUser)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
|
@ -101,7 +101,6 @@ impl AppController {
|
||||
async fn create_app_on_server(&self, params: CreateAppParams) -> Result<App, WorkspaceError> {
|
||||
let token = self.user.token()?;
|
||||
let app = self.server.create_app(&token, params).await?;
|
||||
log::info!("😁 {:?}", app);
|
||||
Ok(app)
|
||||
}
|
||||
|
||||
|
@ -1,27 +1,26 @@
|
||||
use crate::helper::*;
|
||||
|
||||
use flowy_test::workspace::*;
|
||||
use flowy_workspace::entities::{app::QueryAppRequest, view::*};
|
||||
|
||||
#[test]
|
||||
#[tokio::test]
|
||||
#[should_panic]
|
||||
fn app_delete() {
|
||||
let test = AppTest::new();
|
||||
async fn app_delete() {
|
||||
let test = AppTest::new().await;
|
||||
delete_app(&test.sdk, &test.app.id);
|
||||
let query = QueryAppRequest::new(&test.app.id);
|
||||
let _ = read_app(&test.sdk, query);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn app_read() {
|
||||
let test = AppTest::new();
|
||||
#[tokio::test]
|
||||
async fn app_read() {
|
||||
let test = AppTest::new().await;
|
||||
let query = QueryAppRequest::new(&test.app.id);
|
||||
let app_from_db = read_app(&test.sdk, query);
|
||||
assert_eq!(app_from_db, test.app);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn app_create_with_view() {
|
||||
let test = AppTest::new();
|
||||
#[tokio::test]
|
||||
async fn app_create_with_view() {
|
||||
let test = AppTest::new().await;
|
||||
let request_a = CreateViewRequest {
|
||||
belong_to_id: test.app.id.clone(),
|
||||
name: "View A".to_string(),
|
||||
@ -38,8 +37,8 @@ fn app_create_with_view() {
|
||||
view_type: ViewType::Doc,
|
||||
};
|
||||
|
||||
let view_a = create_view_with_request(&test.sdk, request_a);
|
||||
let view_b = create_view_with_request(&test.sdk, request_b);
|
||||
let view_a = create_view_with_request(&test.sdk, request_a).await;
|
||||
let view_b = create_view_with_request(&test.sdk, request_b).await;
|
||||
|
||||
let query = QueryAppRequest::new(&test.app.id).read_views();
|
||||
let view_from_db = read_app(&test.sdk, query);
|
||||
@ -48,20 +47,20 @@ fn app_create_with_view() {
|
||||
assert_eq!(view_from_db.belongings[1], view_b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn app_set_trash_flag() {
|
||||
let test = AppTest::new();
|
||||
test.move_app_to_trash();
|
||||
#[tokio::test]
|
||||
async fn app_set_trash_flag() {
|
||||
let test = AppTest::new().await;
|
||||
test.move_app_to_trash().await;
|
||||
|
||||
let query = QueryAppRequest::new(&test.app.id).trash();
|
||||
let _ = read_app(&test.sdk, query);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[tokio::test]
|
||||
#[should_panic]
|
||||
fn app_set_trash_flag_2() {
|
||||
let test = AppTest::new();
|
||||
test.move_app_to_trash();
|
||||
async fn app_set_trash_flag_2() {
|
||||
let test = AppTest::new().await;
|
||||
test.move_app_to_trash().await;
|
||||
let query = QueryAppRequest::new(&test.app.id);
|
||||
let _ = read_app(&test.sdk, query);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
mod app_test;
|
||||
mod helper;
|
||||
// mod helper;
|
||||
mod view_test;
|
||||
mod workspace_test;
|
||||
|
@ -1,34 +1,41 @@
|
||||
use crate::helper::*;
|
||||
|
||||
use flowy_test::{workspace::*, FlowyTest};
|
||||
use flowy_workspace::entities::view::*;
|
||||
|
||||
#[test]
|
||||
fn view_move_to_trash() {
|
||||
let test = ViewTest::new();
|
||||
test.move_view_to_trash();
|
||||
#[tokio::test]
|
||||
async fn view_move_to_trash() {
|
||||
let test = FlowyTest::setup();
|
||||
let _ = test.init_user().await;
|
||||
|
||||
let test = ViewTest::new(&test).await;
|
||||
test.move_view_to_trash().await;
|
||||
|
||||
let query = QueryViewRequest::new(&test.view.id).trash();
|
||||
let view = read_view(&test.sdk, query);
|
||||
let view = read_view(&test.sdk, query).await;
|
||||
assert_eq!(view, test.view);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[tokio::test]
|
||||
#[should_panic]
|
||||
fn view_move_to_trash2() {
|
||||
let test = ViewTest::new();
|
||||
test.move_view_to_trash();
|
||||
async fn view_move_to_trash2() {
|
||||
let test = FlowyTest::setup();
|
||||
let _ = test.init_user();
|
||||
|
||||
let test = ViewTest::new(&test).await;
|
||||
test.move_view_to_trash().await;
|
||||
let query = QueryViewRequest::new(&test.view.id);
|
||||
let _ = read_view(&test.sdk, query);
|
||||
let _ = read_view(&test.sdk, query).await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn view_open_doc() {
|
||||
let test = ViewTest::new();
|
||||
#[tokio::test]
|
||||
async fn view_open_doc() {
|
||||
let test = FlowyTest::setup();
|
||||
let _ = test.init_user().await;
|
||||
|
||||
let test = ViewTest::new(&test).await;
|
||||
let request = OpenViewRequest {
|
||||
view_id: test.view.id.clone(),
|
||||
};
|
||||
let _ = open_view(&test.sdk, request);
|
||||
let _ = open_view(&test.sdk, request).await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1,30 +1,29 @@
|
||||
use crate::helper::*;
|
||||
use flowy_test::{builder::*, FlowyEnv};
|
||||
use flowy_test::{builder::*, workspace::*, FlowyTest};
|
||||
use flowy_workspace::{
|
||||
entities::workspace::{CreateWorkspaceRequest, QueryWorkspaceRequest},
|
||||
event::WorkspaceEvent::*,
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn workspace_read_all() {
|
||||
let test = WorkspaceTest::new();
|
||||
#[tokio::test]
|
||||
async fn workspace_read_all() {
|
||||
let test = WorkspaceTest::new().await;
|
||||
let workspace = read_workspace(&test.sdk, QueryWorkspaceRequest::new()).unwrap();
|
||||
assert_eq!(test.workspace, workspace);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn workspace_read() {
|
||||
let test = WorkspaceTest::new();
|
||||
#[tokio::test]
|
||||
async fn workspace_read() {
|
||||
let test = WorkspaceTest::new().await;
|
||||
let request = QueryWorkspaceRequest::new().workspace_id(&test.workspace.id);
|
||||
let workspace = read_workspace(&test.sdk, request).unwrap();
|
||||
assert_eq!(test.workspace, workspace);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn workspace_create_with_apps() {
|
||||
let test = WorkspaceTest::new();
|
||||
let app = create_app(&test.sdk, "App A", "AppFlowy Github Project", &test.workspace.id);
|
||||
#[tokio::test]
|
||||
async fn workspace_create_with_apps() {
|
||||
let test = WorkspaceTest::new().await;
|
||||
let app = create_app(&test.sdk, "App A", "AppFlowy Github Project", &test.workspace.id).await;
|
||||
let request = QueryWorkspaceRequest::new().workspace_id(&test.workspace.id);
|
||||
let workspace_from_db = read_workspace(&test.sdk, request).unwrap();
|
||||
assert_eq!(&app, workspace_from_db.apps.first_or_crash());
|
||||
@ -33,8 +32,11 @@ fn workspace_create_with_apps() {
|
||||
#[test]
|
||||
fn workspace_create_with_invalid_name() {
|
||||
for name in invalid_workspace_name_test_case() {
|
||||
let sdk = FlowyEnv::setup().sdk;
|
||||
let request = CreateWorkspaceRequest { name, desc: "".to_owned() };
|
||||
let sdk = FlowyTest::setup().sdk;
|
||||
let request = CreateWorkspaceRequest {
|
||||
name,
|
||||
desc: "".to_owned(),
|
||||
};
|
||||
assert_eq!(
|
||||
FlowyWorkspaceTest::new(sdk)
|
||||
.event(CreateWorkspace)
|
||||
@ -49,9 +51,12 @@ fn workspace_create_with_invalid_name() {
|
||||
|
||||
#[test]
|
||||
fn workspace_update_with_invalid_name() {
|
||||
let sdk = FlowyEnv::setup().sdk;
|
||||
let sdk = FlowyTest::setup().sdk;
|
||||
for name in invalid_workspace_name_test_case() {
|
||||
let request = CreateWorkspaceRequest { name, desc: "".to_owned() };
|
||||
let request = CreateWorkspaceRequest {
|
||||
name,
|
||||
desc: "".to_owned(),
|
||||
};
|
||||
assert_eq!(
|
||||
FlowyWorkspaceTest::new(sdk.clone())
|
||||
.event(CreateWorkspace)
|
||||
|
@ -260,21 +260,21 @@ impl WsSender {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::WsController;
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect() {
|
||||
std::env::set_var("RUST_LOG", "Debug");
|
||||
env_logger::init();
|
||||
|
||||
let mut controller = WsController::new();
|
||||
let addr = format!("{}/123", flowy_net::config::WS_ADDR.as_str());
|
||||
let (a, b) = controller.make_connect(addr);
|
||||
tokio::select! {
|
||||
r = a => println!("write completed {:?}", r),
|
||||
_ = b => println!("read completed"),
|
||||
};
|
||||
}
|
||||
}
|
||||
// #[cfg(test)]
|
||||
// mod tests {
|
||||
// use super::WsController;
|
||||
//
|
||||
// #[tokio::test]
|
||||
// async fn connect() {
|
||||
// std::env::set_var("RUST_LOG", "Debug");
|
||||
// env_logger::init();
|
||||
//
|
||||
// let mut controller = WsController::new();
|
||||
// let addr = format!("{}/123", flowy_net::config::WS_ADDR.as_str());
|
||||
// let (a, b) = controller.make_connect(addr);
|
||||
// tokio::select! {
|
||||
// r = a => println!("write completed {:?}", r),
|
||||
// _ = b => println!("read completed"),
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
|
Loading…
Reference in New Issue
Block a user