Nathan.fooo c0aef8f4fe
fix: login issue (#4546)
* fix: reset server url when using appflowy cloud the first time

* refactor: set authenticator in frontend

* chore: log version

* chore: show hint when changing the server type

* chore: bump version

* chore: fix test

* chore: bump collab
2024-01-30 09:33:34 +08:00

177 lines
4.6 KiB
Rust

use collab::core::collab::CollabDocState;
use collab::core::origin::CollabOrigin;
use collab_document::blocks::DocumentData;
use collab_document::document::Document;
use collab_entity::CollabType;
use std::env::temp_dir;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;
use nanoid::nanoid;
use parking_lot::RwLock;
use tokio::select;
use tokio::time::sleep;
use flowy_core::config::AppFlowyCoreConfig;
use flowy_core::AppFlowyCore;
use flowy_notification::register_notification_sender;
use flowy_server::AppFlowyServer;
use flowy_user::entities::AuthenticatorPB;
use flowy_user::errors::FlowyError;
use crate::user_event::TestNotificationSender;
pub mod database_event;
pub mod document;
pub mod document_event;
pub mod event_builder;
pub mod folder_event;
pub mod user_event;
#[derive(Clone)]
pub struct EventIntegrationTest {
pub authenticator: Arc<RwLock<AuthenticatorPB>>,
pub appflowy_core: AppFlowyCore,
#[allow(dead_code)]
cleaner: Arc<Cleaner>,
pub notification_sender: TestNotificationSender,
}
impl EventIntegrationTest {
pub async fn new() -> Self {
Self::new_with_name(nanoid!(6)).await
}
pub async fn new_with_name<T: ToString>(name: T) -> Self {
let temp_dir = temp_dir().join(nanoid!(6));
std::fs::create_dir_all(&temp_dir).unwrap();
Self::new_with_user_data_path(temp_dir, name.to_string()).await
}
pub async fn new_with_user_data_path(path_buf: PathBuf, name: String) -> Self {
let path = path_buf.to_str().unwrap().to_string();
let device_id = uuid::Uuid::new_v4().to_string();
let config = AppFlowyCoreConfig::new("".to_string(), path.clone(), path, device_id, name)
.log_filter(
"trace",
vec![
"flowy_test".to_string(),
"tokio".to_string(),
// "lib_dispatch".to_string(),
],
);
let inner = init_core(config).await;
let notification_sender = TestNotificationSender::new();
let authenticator = Arc::new(RwLock::new(AuthenticatorPB::Local));
register_notification_sender(notification_sender.clone());
// In case of dropping the runtime that runs the core, we need to forget the dispatcher
std::mem::forget(inner.dispatcher());
Self {
appflowy_core: inner,
authenticator,
notification_sender,
cleaner: Arc::new(Cleaner(path_buf)),
}
}
pub fn get_server(&self) -> Arc<dyn AppFlowyServer> {
self.appflowy_core.server_provider.get_server().unwrap()
}
pub async fn wait_ws_connected(&self) {
if self.get_server().get_ws_state().is_connected() {
return;
}
let mut ws_state = self.get_server().subscribe_ws_state().unwrap();
loop {
select! {
_ = sleep(Duration::from_secs(20)) => {
panic!("wait_ws_connected timeout");
}
state = ws_state.recv() => {
if let Ok(state) = &state {
if state.is_connected() {
break;
}
}
}
}
}
}
pub async fn get_collab_doc_state(
&self,
oid: &str,
collay_type: CollabType,
) -> Result<CollabDocState, FlowyError> {
let server = self.server_provider.get_server().unwrap();
let workspace_id = self.get_current_workspace().await.id;
let uid = self.get_user_profile().await?.id;
let doc_state = server
.folder_service()
.get_collab_doc_state_f(&workspace_id, uid, collay_type, oid)
.await?;
Ok(doc_state)
}
}
pub fn document_data_from_document_doc_state(
doc_id: &str,
doc_state: CollabDocState,
) -> DocumentData {
document_from_document_doc_state(doc_id, doc_state)
.get_document_data()
.unwrap()
}
pub fn document_from_document_doc_state(doc_id: &str, doc_state: CollabDocState) -> Document {
Document::from_doc_state(CollabOrigin::Empty, doc_state, doc_id, vec![]).unwrap()
}
#[cfg(target_arch = "wasm32")]
async fn init_core(config: AppFlowyCoreConfig) -> AppFlowyCore {
// let runtime = tokio::runtime::Runtime::new().unwrap();
// let local_set = tokio::task::LocalSet::new();
// runtime.block_on(AppFlowyCore::new(config))
AppFlowyCore::new(config).await
}
#[cfg(not(target_arch = "wasm32"))]
async fn init_core(config: AppFlowyCoreConfig) -> AppFlowyCore {
std::thread::spawn(|| AppFlowyCore::new(config))
.join()
.unwrap()
}
impl std::ops::Deref for EventIntegrationTest {
type Target = AppFlowyCore;
fn deref(&self) -> &Self::Target {
&self.appflowy_core
}
}
pub struct Cleaner(PathBuf);
impl Cleaner {
pub fn new(dir: PathBuf) -> Self {
Cleaner(dir)
}
fn cleanup(dir: &PathBuf) {
let _ = std::fs::remove_dir_all(dir);
}
}
impl Drop for Cleaner {
fn drop(&mut self) {
Self::cleanup(&self.0)
}
}