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;