mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[rust]: fix bugs to pass backend tests
This commit is contained in:
parent
823c9f9bd6
commit
2972c40b9b
@ -1,7 +1,10 @@
|
||||
use crate::{
|
||||
entities::{token::Token, user::UserTable},
|
||||
service::user::{hash_password, verify_password, LoggedUser},
|
||||
sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
|
||||
};
|
||||
use anyhow::Context;
|
||||
|
||||
use sqlx::{PgPool, Postgres};
|
||||
|
||||
use chrono::Utc;
|
||||
use flowy_net::{
|
||||
errors::{invalid_params, ErrorCode, ServerError},
|
||||
response::FlowyResponse,
|
||||
@ -10,12 +13,7 @@ use flowy_user_infra::{
|
||||
parser::{UserEmail, UserName, UserPassword},
|
||||
protobuf::{SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
entities::{token::Token, user::UserTable},
|
||||
service::user::{hash_password, verify_password, LoggedUser},
|
||||
sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
|
||||
};
|
||||
use sqlx::{PgPool, Postgres};
|
||||
|
||||
use super::AUTHORIZED_USERS;
|
||||
use crate::service::user::user_default::create_default_workspace;
|
||||
|
@ -210,7 +210,7 @@ async fn workspace_list_read() {
|
||||
let _ = server.create_workspace(params).await;
|
||||
}
|
||||
|
||||
let read_params = WorkspaceIdentifier::new();
|
||||
let read_params = WorkspaceIdentifier::new(None);
|
||||
let workspaces = server.read_workspaces(read_params).await;
|
||||
assert_eq!(workspaces.len(), 4);
|
||||
}
|
||||
|
@ -4,11 +4,7 @@ use diesel::{Connection, SqliteConnection};
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_sqlite::{DBConnection, Database, PoolConfig};
|
||||
use lazy_static::lazy_static;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
path::Path,
|
||||
sync::{PoisonError, RwLock, RwLockWriteGuard},
|
||||
};
|
||||
use std::{collections::HashMap, path::Path, sync::RwLock};
|
||||
|
||||
const DB_NAME: &str = "kv.db";
|
||||
lazy_static! {
|
||||
|
0
rust-lib/flowy-log/flowy_log_test.2021-11-09
Normal file
0
rust-lib/flowy-log/flowy_log_test.2021-11-09
Normal file
@ -102,37 +102,6 @@ mod tests {
|
||||
say("hello world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_log2() {
|
||||
let env_filter = EnvFilter::new("Debug");
|
||||
let file_appender = tracing_appender::rolling::daily(".", "flowy_log_test");
|
||||
let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
|
||||
|
||||
let subscriber = tracing_subscriber::fmt()
|
||||
.with_target(false)
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.with_writer(std::io::stderr)
|
||||
.with_thread_ids(true)
|
||||
.with_writer(non_blocking)
|
||||
.json()
|
||||
.compact()
|
||||
.finish()
|
||||
.with(env_filter);
|
||||
|
||||
let formatting_layer = FlowyFormattingLayer::new(std::io::stdout);
|
||||
let _ = set_global_default(subscriber.with(JsonStorageLayer).with(formatting_layer))
|
||||
.map_err(|e| format!("{:?}", e))
|
||||
.unwrap();
|
||||
|
||||
let _ = LogTracer::builder()
|
||||
.with_max_level(LevelFilter::Trace)
|
||||
.init()
|
||||
.map_err(|e| format!("{:?}", e))
|
||||
.unwrap();
|
||||
|
||||
tracing::info!("😁");
|
||||
}
|
||||
|
||||
#[tracing::instrument(name = "say")]
|
||||
fn say(s: &str) {
|
||||
tracing::info!("{}", s);
|
||||
|
@ -110,8 +110,8 @@ async fn _listen_user_status(
|
||||
Ok(status) => {
|
||||
let result = || async {
|
||||
match status {
|
||||
UserStatus::Login { .. } => {
|
||||
let _ = workspace_controller.user_did_login()?;
|
||||
UserStatus::Login { token } => {
|
||||
let _ = workspace_controller.user_did_sign_in(&token)?;
|
||||
},
|
||||
UserStatus::Logout { .. } => {
|
||||
workspace_controller.user_did_logout();
|
||||
@ -119,8 +119,8 @@ async fn _listen_user_status(
|
||||
UserStatus::Expired { .. } => {
|
||||
workspace_controller.user_session_expired();
|
||||
},
|
||||
UserStatus::SignUp { .. } => {
|
||||
let _ = workspace_controller.user_did_sign_up().await?;
|
||||
UserStatus::SignUp { profile } => {
|
||||
let _ = workspace_controller.user_did_sign_up(&profile.token).await?;
|
||||
},
|
||||
}
|
||||
Ok::<(), WorkspaceError>(())
|
||||
|
@ -40,8 +40,6 @@ impl FlowyTest {
|
||||
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 _ = sdk.workspace.init().unwrap();
|
||||
|
||||
Self { sdk }
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ use flowy_workspace::{
|
||||
view::*,
|
||||
workspace::*,
|
||||
},
|
||||
errors::ErrorCode,
|
||||
event::WorkspaceEvent::*,
|
||||
};
|
||||
|
||||
@ -98,11 +99,11 @@ impl ViewTest {
|
||||
}
|
||||
}
|
||||
|
||||
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 invalid_workspace_name_test_case() -> Vec<(String, ErrorCode)> {
|
||||
vec![
|
||||
("".to_owned(), ErrorCode::WorkspaceNameInvalid),
|
||||
("1234".repeat(100), ErrorCode::WorkspaceNameTooLong),
|
||||
]
|
||||
}
|
||||
|
||||
pub async fn create_workspace(sdk: &FlowyTestSDK, name: &str, desc: &str) -> Workspace {
|
||||
@ -131,7 +132,7 @@ async fn open_workspace(sdk: &FlowyTestSDK, workspace_id: &str) {
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn read_workspace(sdk: &FlowyTestSDK, request: QueryWorkspaceRequest) -> Option<Workspace> {
|
||||
pub async fn read_workspace(sdk: &FlowyTestSDK, request: QueryWorkspaceRequest) -> Vec<Workspace> {
|
||||
let mut repeated_workspace = FlowyWorkspaceTest::new(sdk.clone())
|
||||
.event(ReadWorkspaces)
|
||||
.request(request.clone())
|
||||
@ -139,7 +140,7 @@ pub async fn read_workspace(sdk: &FlowyTestSDK, request: QueryWorkspaceRequest)
|
||||
.await
|
||||
.parse::<RepeatedWorkspace>();
|
||||
|
||||
let mut workspaces;
|
||||
let workspaces;
|
||||
if let Some(workspace_id) = &request.workspace_id {
|
||||
workspaces = repeated_workspace
|
||||
.into_inner()
|
||||
@ -151,7 +152,7 @@ pub async fn read_workspace(sdk: &FlowyTestSDK, request: QueryWorkspaceRequest)
|
||||
workspaces = repeated_workspace.items;
|
||||
}
|
||||
|
||||
workspaces.drain(..1).collect::<Vec<Workspace>>().pop()
|
||||
workspaces
|
||||
}
|
||||
|
||||
pub async fn create_app(sdk: &FlowyTestSDK, name: &str, desc: &str, workspace_id: &str) -> App {
|
||||
|
@ -75,7 +75,6 @@ impl UserSession {
|
||||
}
|
||||
|
||||
pub fn init(&self) {
|
||||
log::debug!("😁😁😁 user did login");
|
||||
match self.get_session() {
|
||||
Ok(session) => {
|
||||
let _ = self.status_notifier.send(UserStatus::Login { token: session.token });
|
||||
|
@ -50,7 +50,7 @@ async fn user_update_with_name() {
|
||||
async fn user_update_with_email() {
|
||||
let test = FlowyTest::setup();
|
||||
let user = test.init_user().await;
|
||||
let new_email = format!("{}@gmai.com", uuid());
|
||||
let new_email = format!("{}@gmail.com", uuid());
|
||||
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())
|
||||
|
@ -10,12 +10,7 @@ pub struct QueryWorkspaceRequest {
|
||||
}
|
||||
|
||||
impl QueryWorkspaceRequest {
|
||||
pub fn new() -> Self { Self { workspace_id: None } }
|
||||
|
||||
pub fn workspace_id(mut self, workspace_id: &str) -> Self {
|
||||
self.workspace_id = Some(workspace_id.to_owned());
|
||||
self
|
||||
}
|
||||
pub fn new(workspace_id: Option<String>) -> Self { Self { workspace_id } }
|
||||
}
|
||||
|
||||
// Read all workspaces if the workspace_id is None
|
||||
|
@ -15,6 +15,7 @@ pub mod handlers;
|
||||
mod notify;
|
||||
pub mod protobuf;
|
||||
mod sql_tables;
|
||||
mod util;
|
||||
|
||||
pub mod prelude {
|
||||
pub use flowy_workspace_infra::entities::{app::*, trash::*, view::*, workspace::*};
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||
errors::*,
|
||||
module::{WorkspaceDatabase, WorkspaceUser},
|
||||
notify::*,
|
||||
services::{helper::spawn, server::Server, TrashCan, TrashEvent},
|
||||
services::{server::Server, TrashCan, TrashEvent},
|
||||
sql_tables::app::{AppTable, AppTableChangeset, AppTableSql},
|
||||
};
|
||||
|
||||
@ -122,7 +122,7 @@ impl AppController {
|
||||
fn update_app_on_server(&self, params: UpdateAppParams) -> Result<(), WorkspaceError> {
|
||||
let token = self.user.token()?;
|
||||
let server = self.server.clone();
|
||||
spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
match server.update_app(&token, params).await {
|
||||
Ok(_) => {},
|
||||
Err(e) => {
|
||||
@ -139,7 +139,7 @@ impl AppController {
|
||||
let token = self.user.token()?;
|
||||
let server = self.server.clone();
|
||||
let pool = self.database.db_pool()?;
|
||||
spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
// Opti: retry?
|
||||
match server.read_app(&token, params).await {
|
||||
Ok(Some(app)) => match pool.get() {
|
||||
|
@ -1,9 +0,0 @@
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
pub fn spawn<F>(f: F) -> JoinHandle<F::Output>
|
||||
where
|
||||
F: std::future::Future + Send + 'static,
|
||||
F::Output: Send + 'static,
|
||||
{
|
||||
tokio::spawn(f)
|
||||
}
|
@ -5,9 +5,7 @@ pub use workspace_controller::*;
|
||||
|
||||
mod app_controller;
|
||||
mod database;
|
||||
mod helper;
|
||||
pub mod server;
|
||||
pub(crate) mod server;
|
||||
mod trash_can;
|
||||
mod util;
|
||||
mod view_controller;
|
||||
mod workspace_controller;
|
||||
|
@ -10,7 +10,7 @@ use crate::{
|
||||
errors::{WorkspaceError, WorkspaceResult},
|
||||
module::{WorkspaceDatabase, WorkspaceUser},
|
||||
notify::{send_anonymous_dart_notification, WorkspaceNotification},
|
||||
services::{helper::spawn, server::Server},
|
||||
services::server::Server,
|
||||
sql_tables::trash::TrashTableSql,
|
||||
};
|
||||
|
||||
@ -232,7 +232,7 @@ impl TrashCan {
|
||||
let server = self.server.clone();
|
||||
let pool = self.database.db_pool()?;
|
||||
|
||||
spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
match server.read_trash(&token).await {
|
||||
Ok(repeated_trash) => {
|
||||
tracing::debug!("Remote trash count: {}", repeated_trash.items.len());
|
||||
|
@ -16,7 +16,7 @@ use crate::{
|
||||
errors::{internal_error, WorkspaceError, WorkspaceResult},
|
||||
module::{WorkspaceDatabase, WorkspaceUser},
|
||||
notify::{send_dart_notification, WorkspaceNotification},
|
||||
services::{helper::spawn, server::Server, TrashCan, TrashEvent},
|
||||
services::{server::Server, TrashCan, TrashEvent},
|
||||
sql_tables::view::{ViewTable, ViewTableChangeset, ViewTableSql},
|
||||
};
|
||||
|
||||
@ -187,7 +187,7 @@ impl ViewController {
|
||||
fn update_view_on_server(&self, params: UpdateViewParams) -> Result<(), WorkspaceError> {
|
||||
let token = self.user.token()?;
|
||||
let server = self.server.clone();
|
||||
spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
match server.update_view(&token, params).await {
|
||||
Ok(_) => {},
|
||||
Err(e) => {
|
||||
@ -205,7 +205,7 @@ impl ViewController {
|
||||
let server = self.server.clone();
|
||||
let pool = self.database.db_pool()?;
|
||||
// Opti: retry?
|
||||
spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
match server.read_view(&token, params).await {
|
||||
Ok(Some(view)) => match pool.get() {
|
||||
Ok(conn) => {
|
||||
|
@ -2,7 +2,7 @@ use crate::{
|
||||
errors::*,
|
||||
module::{WorkspaceDatabase, WorkspaceUser},
|
||||
notify::*,
|
||||
services::{helper::spawn, read_local_workspace_apps, server::Server, AppController, TrashCan, ViewController},
|
||||
services::{read_local_workspace_apps, server::Server, AppController, TrashCan, ViewController},
|
||||
sql_tables::workspace::{WorkspaceTable, WorkspaceTableChangeset, WorkspaceTableSql},
|
||||
};
|
||||
use chrono::Utc;
|
||||
@ -12,12 +12,19 @@ use flowy_workspace_infra::{
|
||||
entities::{app::RepeatedApp, workspace::*},
|
||||
user_default,
|
||||
};
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
use lazy_static::lazy_static;
|
||||
use parking_lot::RwLock;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
},
|
||||
};
|
||||
|
||||
static INIT_WORKSPACE: AtomicBool = AtomicBool::new(false);
|
||||
lazy_static! {
|
||||
static ref INIT_WORKSPACE: RwLock<HashMap<String, bool>> = RwLock::new(HashMap::new());
|
||||
}
|
||||
|
||||
pub struct WorkspaceController {
|
||||
pub user: Arc<dyn WorkspaceUser>,
|
||||
@ -50,13 +57,14 @@ impl WorkspaceController {
|
||||
}
|
||||
}
|
||||
|
||||
fn init(&self) -> Result<(), WorkspaceError> {
|
||||
if INIT_WORKSPACE.load(Ordering::SeqCst) {
|
||||
return Ok(());
|
||||
fn init(&self, token: &str) -> Result<(), WorkspaceError> {
|
||||
if let Some(is_init) = INIT_WORKSPACE.read().get(token) {
|
||||
if *is_init {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
INIT_WORKSPACE.write().insert(token.to_owned(), true);
|
||||
|
||||
log::debug!("workspace initialize");
|
||||
INIT_WORKSPACE.store(true, Ordering::SeqCst);
|
||||
let _ = self.server.init();
|
||||
let _ = self.trash_can.init()?;
|
||||
let _ = self.view_controller.init()?;
|
||||
@ -65,9 +73,11 @@ impl WorkspaceController {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn user_did_login(&self) -> WorkspaceResult<()> {
|
||||
pub fn user_did_sign_in(&self, token: &str) -> WorkspaceResult<()> {
|
||||
// TODO: (nathan) do something here
|
||||
let _ = self.init()?;
|
||||
|
||||
log::debug!("workspace initialize after sign in");
|
||||
let _ = self.init(token)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -79,7 +89,7 @@ impl WorkspaceController {
|
||||
// TODO: (nathan) do something here
|
||||
}
|
||||
|
||||
pub async fn user_did_sign_up(&self) -> WorkspaceResult<()> {
|
||||
pub async fn user_did_sign_up(&self, _token: &str) -> WorkspaceResult<()> {
|
||||
log::debug!("Create user default workspace");
|
||||
let time = Utc::now();
|
||||
let mut workspace = user_default::create_default_workspace(time);
|
||||
@ -103,7 +113,9 @@ impl WorkspaceController {
|
||||
send_dart_notification(&token, WorkspaceNotification::UserCreateWorkspace)
|
||||
.payload(repeated_workspace)
|
||||
.send();
|
||||
let _ = self.init()?;
|
||||
|
||||
log::debug!("workspace initialize after sign up");
|
||||
let _ = self.init(&token)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -290,7 +302,7 @@ impl WorkspaceController {
|
||||
#[tracing::instrument(level = "debug", skip(self), err)]
|
||||
fn update_workspace_on_server(&self, params: UpdateWorkspaceParams) -> Result<(), WorkspaceError> {
|
||||
let (token, server) = self.token_with_server()?;
|
||||
spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
match server.update_workspace(&token, params).await {
|
||||
Ok(_) => {},
|
||||
Err(e) => {
|
||||
@ -308,7 +320,7 @@ impl WorkspaceController {
|
||||
workspace_id: workspace_id.to_string(),
|
||||
};
|
||||
let (token, server) = self.token_with_server()?;
|
||||
spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
match server.delete_workspace(&token, params).await {
|
||||
Ok(_) => {},
|
||||
Err(e) => {
|
||||
@ -327,7 +339,7 @@ impl WorkspaceController {
|
||||
let app_ctrl = self.app_controller.clone();
|
||||
let view_ctrl = self.view_controller.clone();
|
||||
let conn = self.database.db_connection()?;
|
||||
spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
// Opti: handle the error and retry?
|
||||
let workspaces = server.read_workspace(&token, params).await?;
|
||||
let _ = (&*conn).immediate_transaction::<_, WorkspaceError, _>(|| {
|
||||
|
@ -8,30 +8,40 @@ use flowy_workspace::{
|
||||
#[tokio::test]
|
||||
async fn workspace_read_all() {
|
||||
let test = WorkspaceTest::new().await;
|
||||
let workspace = read_workspace(&test.sdk, QueryWorkspaceRequest::new()).await.unwrap();
|
||||
assert_eq!(test.workspace, workspace);
|
||||
let workspace = read_workspace(&test.sdk, QueryWorkspaceRequest::new(None)).await;
|
||||
assert_eq!(workspace.len(), 2);
|
||||
}
|
||||
|
||||
#[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).await.unwrap();
|
||||
assert_eq!(test.workspace, workspace);
|
||||
let request = QueryWorkspaceRequest::new(Some(test.workspace.id.clone()));
|
||||
let workspace_from_db = read_workspace(&test.sdk, request)
|
||||
.await
|
||||
.drain(..1)
|
||||
.collect::<Vec<Workspace>>()
|
||||
.pop()
|
||||
.unwrap();
|
||||
assert_eq!(test.workspace, workspace_from_db);
|
||||
}
|
||||
|
||||
#[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).await.unwrap();
|
||||
let request = QueryWorkspaceRequest::new(Some(test.workspace.id.clone()));
|
||||
let workspace_from_db = read_workspace(&test.sdk, request)
|
||||
.await
|
||||
.drain(..1)
|
||||
.collect::<Vec<Workspace>>()
|
||||
.pop()
|
||||
.unwrap();
|
||||
assert_eq!(&app, workspace_from_db.apps.first_or_crash());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn workspace_create_with_invalid_name() {
|
||||
for name in invalid_workspace_name_test_case() {
|
||||
for (name, code) in invalid_workspace_name_test_case() {
|
||||
let sdk = FlowyTest::setup().sdk;
|
||||
let request = CreateWorkspaceRequest {
|
||||
name,
|
||||
@ -45,7 +55,7 @@ async fn workspace_create_with_invalid_name() {
|
||||
.await
|
||||
.error()
|
||||
.code,
|
||||
ErrorCode::WorkspaceNameInvalid.value()
|
||||
code.value()
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -53,7 +63,7 @@ async fn workspace_create_with_invalid_name() {
|
||||
#[tokio::test]
|
||||
async fn workspace_update_with_invalid_name() {
|
||||
let sdk = FlowyTest::setup().sdk;
|
||||
for name in invalid_workspace_name_test_case() {
|
||||
for (name, code) in invalid_workspace_name_test_case() {
|
||||
let request = CreateWorkspaceRequest {
|
||||
name,
|
||||
desc: "".to_owned(),
|
||||
@ -66,7 +76,7 @@ async fn workspace_update_with_invalid_name() {
|
||||
.await
|
||||
.error()
|
||||
.code,
|
||||
ErrorCode::WorkspaceNameInvalid.value()
|
||||
code.value()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user