refactor test to tokio::test to enable & enable test doc with server

This commit is contained in:
appflowy 2021-09-28 15:29:29 +08:00
parent 01c9620e03
commit 83acc79cd1
34 changed files with 453 additions and 372 deletions

View File

@ -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();

View File

@ -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(&params.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(&params.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)

View File

@ -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())

View File

@ -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)
}

View File

@ -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());

View File

@ -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;
}

View File

@ -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();
}

View File

@ -1,2 +1,2 @@
mod edit;
mod helper;
mod ws;

View File

@ -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]

View File

@ -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);

View File

@ -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)

View File

@ -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 }
}

View File

@ -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 {})
}

View File

@ -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()

View File

@ -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);
}

View File

@ -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));

View File

@ -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
}

View File

@ -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"}

View File

@ -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") }
}

View File

@ -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 }
}

View File

@ -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)
}

View File

@ -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>()
}

View File

@ -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)]

View File

@ -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()?;

View File

@ -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 {})
}
}

View File

@ -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();
}
}

View File

@ -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()

View File

@ -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)
}

View File

@ -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);
}

View File

@ -1,4 +1,4 @@
mod app_test;
mod helper;
// mod helper;
mod view_test;
mod workspace_test;

View File

@ -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]

View File

@ -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)

View File

@ -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"),
// };
// }
// }