mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
extract tester as trait
This commit is contained in:
parent
4354ff0c59
commit
bab373ba35
@ -18,6 +18,7 @@ class WorkspaceErrorCode extends $pb.ProtobufEnum {
|
|||||||
static const WorkspaceErrorCode DatabaseConnectionFail = WorkspaceErrorCode._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseConnectionFail');
|
static const WorkspaceErrorCode DatabaseConnectionFail = WorkspaceErrorCode._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseConnectionFail');
|
||||||
static const WorkspaceErrorCode DatabaseInternalError = WorkspaceErrorCode._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseInternalError');
|
static const WorkspaceErrorCode DatabaseInternalError = WorkspaceErrorCode._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseInternalError');
|
||||||
static const WorkspaceErrorCode UserInternalError = WorkspaceErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserInternalError');
|
static const WorkspaceErrorCode UserInternalError = WorkspaceErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserInternalError');
|
||||||
|
static const WorkspaceErrorCode UserNotLoginYet = WorkspaceErrorCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotLoginYet');
|
||||||
|
|
||||||
static const $core.List<WorkspaceErrorCode> values = <WorkspaceErrorCode> [
|
static const $core.List<WorkspaceErrorCode> values = <WorkspaceErrorCode> [
|
||||||
Unknown,
|
Unknown,
|
||||||
@ -28,6 +29,7 @@ class WorkspaceErrorCode extends $pb.ProtobufEnum {
|
|||||||
DatabaseConnectionFail,
|
DatabaseConnectionFail,
|
||||||
DatabaseInternalError,
|
DatabaseInternalError,
|
||||||
UserInternalError,
|
UserInternalError,
|
||||||
|
UserNotLoginYet,
|
||||||
];
|
];
|
||||||
|
|
||||||
static final $core.Map<$core.int, WorkspaceErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values);
|
static final $core.Map<$core.int, WorkspaceErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||||
|
@ -20,11 +20,12 @@ const WorkspaceErrorCode$json = const {
|
|||||||
const {'1': 'DatabaseConnectionFail', '2': 5},
|
const {'1': 'DatabaseConnectionFail', '2': 5},
|
||||||
const {'1': 'DatabaseInternalError', '2': 6},
|
const {'1': 'DatabaseInternalError', '2': 6},
|
||||||
const {'1': 'UserInternalError', '2': 10},
|
const {'1': 'UserInternalError', '2': 10},
|
||||||
|
const {'1': 'UserNotLoginYet', '2': 11},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Descriptor for `WorkspaceErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
/// Descriptor for `WorkspaceErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||||
final $typed_data.Uint8List workspaceErrorCodeDescriptor = $convert.base64Decode('ChJXb3Jrc3BhY2VFcnJvckNvZGUSCwoHVW5rbm93bhAAEhgKFFdvcmtzcGFjZU5hbWVJbnZhbGlkEAESFgoSV29ya3NwYWNlSWRJbnZhbGlkEAISGAoUQXBwQ29sb3JTdHlsZUludmFsaWQQAxIQCgxBcHBJZEludmFsaWQQBBIaChZEYXRhYmFzZUNvbm5lY3Rpb25GYWlsEAUSGQoVRGF0YWJhc2VJbnRlcm5hbEVycm9yEAYSFQoRVXNlckludGVybmFsRXJyb3IQCg==');
|
final $typed_data.Uint8List workspaceErrorCodeDescriptor = $convert.base64Decode('ChJXb3Jrc3BhY2VFcnJvckNvZGUSCwoHVW5rbm93bhAAEhgKFFdvcmtzcGFjZU5hbWVJbnZhbGlkEAESFgoSV29ya3NwYWNlSWRJbnZhbGlkEAISGAoUQXBwQ29sb3JTdHlsZUludmFsaWQQAxIQCgxBcHBJZEludmFsaWQQBBIaChZEYXRhYmFzZUNvbm5lY3Rpb25GYWlsEAUSGQoVRGF0YWJhc2VJbnRlcm5hbEVycm9yEAYSFQoRVXNlckludGVybmFsRXJyb3IQChITCg9Vc2VyTm90TG9naW5ZZXQQCw==');
|
||||||
@$core.Deprecated('Use workspaceErrorDescriptor instead')
|
@$core.Deprecated('Use workspaceErrorDescriptor instead')
|
||||||
const WorkspaceError$json = const {
|
const WorkspaceError$json = const {
|
||||||
'1': 'WorkspaceError',
|
'1': 'WorkspaceError',
|
||||||
|
@ -11,9 +11,11 @@ import 'package:protobuf/protobuf.dart' as $pb;
|
|||||||
|
|
||||||
class WorkspaceEvent extends $pb.ProtobufEnum {
|
class WorkspaceEvent extends $pb.ProtobufEnum {
|
||||||
static const WorkspaceEvent CreateWorkspace = WorkspaceEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateWorkspace');
|
static const WorkspaceEvent CreateWorkspace = WorkspaceEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateWorkspace');
|
||||||
|
static const WorkspaceEvent GetWorkspaceUserDetail = WorkspaceEvent._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetWorkspaceUserDetail');
|
||||||
|
|
||||||
static const $core.List<WorkspaceEvent> values = <WorkspaceEvent> [
|
static const $core.List<WorkspaceEvent> values = <WorkspaceEvent> [
|
||||||
CreateWorkspace,
|
CreateWorkspace,
|
||||||
|
GetWorkspaceUserDetail,
|
||||||
];
|
];
|
||||||
|
|
||||||
static final $core.Map<$core.int, WorkspaceEvent> _byValue = $pb.ProtobufEnum.initByValue(values);
|
static final $core.Map<$core.int, WorkspaceEvent> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||||
|
@ -13,8 +13,9 @@ const WorkspaceEvent$json = const {
|
|||||||
'1': 'WorkspaceEvent',
|
'1': 'WorkspaceEvent',
|
||||||
'2': const [
|
'2': const [
|
||||||
const {'1': 'CreateWorkspace', '2': 0},
|
const {'1': 'CreateWorkspace', '2': 0},
|
||||||
|
const {'1': 'GetWorkspaceUserDetail', '2': 100},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Descriptor for `WorkspaceEvent`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
/// Descriptor for `WorkspaceEvent`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||||
final $typed_data.Uint8List workspaceEventDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQAA==');
|
final $typed_data.Uint8List workspaceEventDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIaChZHZXRXb3Jrc3BhY2VVc2VyRGV0YWlsEGQ=');
|
||||||
|
@ -40,7 +40,7 @@ pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) {
|
|||||||
port
|
port
|
||||||
);
|
);
|
||||||
|
|
||||||
let _ = EventDispatch::async_send(request, move |resp: EventResponse| {
|
let _ = EventDispatch::async_send_with_callback(request, move |resp: EventResponse| {
|
||||||
log::trace!("[FFI]: Post data to dart through {} port", port);
|
log::trace!("[FFI]: Post data to dart through {} port", port);
|
||||||
Box::pin(post_to_flutter(resp, port))
|
Box::pin(post_to_flutter(resp, port))
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn tests() {
|
async fn tests() {
|
||||||
let t = trybuild::TestCases::new();
|
let _t = trybuild::TestCases::new();
|
||||||
// t.pass("tests/protobuf_enum.rs");
|
// t.pass("tests/protobuf_enum.rs");
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,17 @@ impl EventDispatch {
|
|||||||
*(EVENT_DISPATCH.write().unwrap()) = Some(dispatch);
|
*(EVENT_DISPATCH.write().unwrap()) = Some(dispatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn async_send<Req, Callback>(request: Req, callback: Callback) -> DispatchFuture
|
pub fn async_send<Req>(request: Req) -> DispatchFuture
|
||||||
|
where
|
||||||
|
Req: std::convert::Into<ModuleRequest>,
|
||||||
|
{
|
||||||
|
EventDispatch::async_send_with_callback(request, |_| Box::pin(async {}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn async_send_with_callback<Req, Callback>(
|
||||||
|
request: Req,
|
||||||
|
callback: Callback,
|
||||||
|
) -> DispatchFuture
|
||||||
where
|
where
|
||||||
Req: std::convert::Into<ModuleRequest>,
|
Req: std::convert::Into<ModuleRequest>,
|
||||||
Callback: FnOnce(EventResponse) -> BoxFuture<'static, ()> + 'static + Send + Sync,
|
Callback: FnOnce(EventResponse) -> BoxFuture<'static, ()> + 'static + Send + Sync,
|
||||||
@ -83,7 +93,7 @@ impl EventDispatch {
|
|||||||
|
|
||||||
pub fn sync_send(request: ModuleRequest) -> EventResponse {
|
pub fn sync_send(request: ModuleRequest) -> EventResponse {
|
||||||
futures::executor::block_on(async {
|
futures::executor::block_on(async {
|
||||||
EventDispatch::async_send(request, |_| Box::pin(async {})).await
|
EventDispatch::async_send_with_callback(request, |_| Box::pin(async {})).await
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::byte_trait::ToBytes;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use std::{fmt, fmt::Formatter};
|
use std::{fmt, fmt::Formatter};
|
||||||
|
|
||||||
@ -48,16 +49,6 @@ impl std::convert::Into<Payload> for Vec<u8> {
|
|||||||
fn into(self) -> Payload { Payload::Bytes(self) }
|
fn into(self) -> Payload { Payload::Bytes(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// = note: conflicting implementation in crate `core`:
|
|
||||||
// - impl<T, U> TryInto<U> for T where U: TryFrom<T>;
|
|
||||||
//
|
|
||||||
// impl std::convert::TryInto<Payload> for Vec<u8> {
|
|
||||||
// type Error = String;
|
|
||||||
// fn try_into(self) -> Result<Payload, Self::Error> {
|
|
||||||
// Ok(Payload::Bytes(self))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
impl std::convert::Into<Payload> for &str {
|
impl std::convert::Into<Payload> for &str {
|
||||||
fn into(self) -> Payload { self.to_string().into() }
|
fn into(self) -> Payload { self.to_string().into() }
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ async fn test_init() {
|
|||||||
init_dispatch(|| vec![Module::new().event(event, hello)]);
|
init_dispatch(|| vec![Module::new().event(event, hello)]);
|
||||||
|
|
||||||
let request = ModuleRequest::new(event);
|
let request = ModuleRequest::new(event);
|
||||||
let _ = EventDispatch::async_send(request, |resp| {
|
let _ = EventDispatch::async_send_with_callback(request, |resp| {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
dbg!(&resp);
|
dbg!(&resp);
|
||||||
})
|
})
|
||||||
|
@ -3,7 +3,7 @@ use flowy_user::prelude::*;
|
|||||||
|
|
||||||
use crate::flowy_server::{ArcFlowyServer, MockFlowyServer};
|
use crate::flowy_server::{ArcFlowyServer, MockFlowyServer};
|
||||||
use flowy_database::DBConnection;
|
use flowy_database::DBConnection;
|
||||||
use flowy_user::errors::UserError;
|
|
||||||
use flowy_workspace::prelude::*;
|
use flowy_workspace::prelude::*;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ pub struct ModuleConfig {
|
|||||||
pub root: String,
|
pub root: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_modules(config: ModuleConfig, server: ArcFlowyServer) -> Vec<Module> {
|
pub fn build_modules(config: ModuleConfig, _server: ArcFlowyServer) -> Vec<Module> {
|
||||||
let user_session = Arc::new(
|
let user_session = Arc::new(
|
||||||
UserSessionBuilder::new()
|
UserSessionBuilder::new()
|
||||||
.root_dir(&config.root)
|
.root_dir(&config.root)
|
||||||
@ -33,14 +33,15 @@ pub struct WorkspaceUserImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WorkspaceUser for WorkspaceUserImpl {
|
impl WorkspaceUser for WorkspaceUserImpl {
|
||||||
fn set_current_workspace(&self, id: &str) { unimplemented!() }
|
fn set_current_workspace(&self, id: &str) { UserSession::set_current_workspace(id); }
|
||||||
|
|
||||||
fn get_current_workspace(&self) -> Result<String, WorkspaceError> {
|
fn get_current_workspace(&self) -> Result<String, WorkspaceError> {
|
||||||
self.user_session.get_current_workspace().map_err(|e| {
|
let user_detail = self.user_session.user_detail().map_err(|e| {
|
||||||
ErrorBuilder::new(WorkspaceErrorCode::UserInternalError)
|
ErrorBuilder::new(WorkspaceErrorCode::UserNotLoginYet)
|
||||||
.error(e)
|
.error(e)
|
||||||
.build()
|
.build()
|
||||||
})
|
})?;
|
||||||
|
Ok(user_detail.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn db_connection(&self) -> Result<DBConnection, WorkspaceError> {
|
fn db_connection(&self) -> Result<DBConnection, WorkspaceError> {
|
||||||
|
82
rust-lib/flowy-test/src/builder.rs
Normal file
82
rust-lib/flowy-test/src/builder.rs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
use crate::{helper::new_user_after_login, init_sdk, tester::Tester};
|
||||||
|
use flowy_dispatch::prelude::{EventDispatch, FromBytes, ModuleRequest, ToBytes};
|
||||||
|
use flowy_user::{entities::UserDetail, event::UserEvent::SignOut};
|
||||||
|
use std::{
|
||||||
|
fmt::{Debug, Display},
|
||||||
|
hash::Hash,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct TestBuilder<Error> {
|
||||||
|
login: Option<bool>,
|
||||||
|
inner: Option<Tester<Error>>,
|
||||||
|
pub user_detail: Option<UserDetail>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Error> TestBuilder<Error>
|
||||||
|
where
|
||||||
|
Error: FromBytes + Debug,
|
||||||
|
{
|
||||||
|
pub fn new() -> Self {
|
||||||
|
TestBuilder::<Error> {
|
||||||
|
login: None,
|
||||||
|
inner: None,
|
||||||
|
user_detail: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn login(mut self) -> Self {
|
||||||
|
let user_detail = new_user_after_login();
|
||||||
|
self.user_detail = Some(user_detail);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn logout(self) -> Self {
|
||||||
|
init_sdk();
|
||||||
|
let _ = EventDispatch::sync_send(ModuleRequest::new(SignOut));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn event<E>(mut self, event: E) -> Self
|
||||||
|
where
|
||||||
|
E: Eq + Hash + Debug + Clone + Display,
|
||||||
|
{
|
||||||
|
self.inner = Some(Tester::<Error>::new(event));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn request<P>(mut self, request: P) -> Self
|
||||||
|
where
|
||||||
|
P: ToBytes,
|
||||||
|
{
|
||||||
|
self.inner.as_mut().unwrap().set_request(request);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sync_send(mut self) -> Self {
|
||||||
|
self.inner.as_mut().unwrap().sync_send();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse<R>(mut self) -> R
|
||||||
|
where
|
||||||
|
R: FromBytes,
|
||||||
|
{
|
||||||
|
let inner = self.inner.take().unwrap();
|
||||||
|
inner.parse::<R>()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn error(mut self) -> Error {
|
||||||
|
let inner = self.inner.take().unwrap();
|
||||||
|
inner.error()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn assert_error(mut self) -> Self {
|
||||||
|
self.inner.as_mut().unwrap().assert_error();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn assert_success(mut self) -> Self {
|
||||||
|
self.inner.as_mut().unwrap().assert_success();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
43
rust-lib/flowy-test/src/helper.rs
Normal file
43
rust-lib/flowy-test/src/helper.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use crate::{init_sdk, tester::Tester};
|
||||||
|
use flowy_dispatch::prelude::*;
|
||||||
|
use flowy_user::{
|
||||||
|
entities::{SignInRequest, UserDetail},
|
||||||
|
errors::UserError,
|
||||||
|
event::UserEvent::{SignIn, SignOut},
|
||||||
|
};
|
||||||
|
use std::{fs, path::PathBuf};
|
||||||
|
|
||||||
|
pub fn root_dir() -> String {
|
||||||
|
// https://doc.rust-lang.org/cargo/reference/environment-variables.html
|
||||||
|
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap_or("./".to_owned());
|
||||||
|
let mut path_buf = fs::canonicalize(&PathBuf::from(&manifest_dir)).unwrap();
|
||||||
|
path_buf.pop(); // rust-lib
|
||||||
|
path_buf.push("flowy-test");
|
||||||
|
path_buf.push("temp");
|
||||||
|
path_buf.push("flowy");
|
||||||
|
|
||||||
|
let root_dir = path_buf.to_str().unwrap().to_string();
|
||||||
|
if !std::path::Path::new(&root_dir).exists() {
|
||||||
|
std::fs::create_dir_all(&root_dir).unwrap();
|
||||||
|
}
|
||||||
|
root_dir
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_user_after_login() -> UserDetail {
|
||||||
|
init_sdk();
|
||||||
|
let _ = EventDispatch::sync_send(ModuleRequest::new(SignOut));
|
||||||
|
let request = SignInRequest {
|
||||||
|
email: valid_email(),
|
||||||
|
password: valid_password(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut tester = Tester::<UserError>::new(SignIn);
|
||||||
|
tester.set_request(request);
|
||||||
|
tester.sync_send();
|
||||||
|
|
||||||
|
tester.parse::<UserDetail>()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn valid_email() -> String { "annie@appflowy.io".to_string() }
|
||||||
|
|
||||||
|
pub(crate) fn valid_password() -> String { "HelloWorld!123".to_string() }
|
@ -1,25 +1,14 @@
|
|||||||
use flowy_dispatch::prelude::*;
|
mod builder;
|
||||||
pub use flowy_sdk::*;
|
mod helper;
|
||||||
use flowy_user::{
|
mod tester;
|
||||||
errors::UserError,
|
|
||||||
event::UserEvent::{SignIn, SignOut},
|
use crate::helper::root_dir;
|
||||||
prelude::*,
|
use flowy_sdk::FlowySDK;
|
||||||
};
|
use std::{sync::Once, thread};
|
||||||
use std::{
|
|
||||||
convert::TryFrom,
|
|
||||||
fmt::{Debug, Display},
|
|
||||||
fs,
|
|
||||||
hash::Hash,
|
|
||||||
marker::PhantomData,
|
|
||||||
path::PathBuf,
|
|
||||||
sync::Once,
|
|
||||||
thread,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::Tester;
|
pub use crate::{builder::TestBuilder, tester::Tester};
|
||||||
pub use flowy_dispatch::prelude::*;
|
pub use flowy_dispatch::prelude::*;
|
||||||
pub use std::convert::TryFrom;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static INIT: Once = Once::new();
|
static INIT: Once = Once::new();
|
||||||
@ -30,224 +19,3 @@ pub fn init_sdk() {
|
|||||||
FlowySDK::new(&root_dir).construct();
|
FlowySDK::new(&root_dir).construct();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn root_dir() -> String {
|
|
||||||
// https://doc.rust-lang.org/cargo/reference/environment-variables.html
|
|
||||||
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap_or("./".to_owned());
|
|
||||||
let mut path_buf = fs::canonicalize(&PathBuf::from(&manifest_dir)).unwrap();
|
|
||||||
path_buf.pop(); // rust-lib
|
|
||||||
path_buf.push("flowy-test");
|
|
||||||
path_buf.push("temp");
|
|
||||||
path_buf.push("flowy");
|
|
||||||
|
|
||||||
let root_dir = path_buf.to_str().unwrap().to_string();
|
|
||||||
if !std::path::Path::new(&root_dir).exists() {
|
|
||||||
std::fs::create_dir_all(&root_dir).unwrap();
|
|
||||||
}
|
|
||||||
root_dir
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TestBuilder<Error> {
|
|
||||||
login: Option<bool>,
|
|
||||||
inner: Option<Tester<Error>>,
|
|
||||||
pub user_detail: Option<UserDetail>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Error> TestBuilder<Error>
|
|
||||||
where
|
|
||||||
Error: FromBytes + Debug,
|
|
||||||
{
|
|
||||||
pub fn new() -> Self {
|
|
||||||
TestBuilder::<Error> {
|
|
||||||
login: None,
|
|
||||||
inner: None,
|
|
||||||
user_detail: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn login(mut self) -> Self {
|
|
||||||
let user_detail = new_user_after_login();
|
|
||||||
self.user_detail = Some(user_detail);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn logout(self) -> Self {
|
|
||||||
init_sdk();
|
|
||||||
let _ = EventDispatch::sync_send(ModuleRequest::new(SignOut));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn event<E>(mut self, event: E) -> Self
|
|
||||||
where
|
|
||||||
E: Eq + Hash + Debug + Clone + Display,
|
|
||||||
{
|
|
||||||
self.inner = Some(Tester::<Error>::new(event));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn request<P>(mut self, request: P) -> Self
|
|
||||||
where
|
|
||||||
P: ToBytes,
|
|
||||||
{
|
|
||||||
let mut inner = self.inner.unwrap();
|
|
||||||
self.inner = Some(inner.request(request));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sync_send(mut self) -> Self {
|
|
||||||
let inner = self.inner.take().unwrap();
|
|
||||||
self.inner = Some(inner.sync_send());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse<R>(mut self) -> R
|
|
||||||
where
|
|
||||||
R: FromBytes,
|
|
||||||
{
|
|
||||||
let inner = self.inner.take().unwrap();
|
|
||||||
inner.parse::<R>()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn error(mut self) -> Error {
|
|
||||||
let inner = self.inner.take().unwrap();
|
|
||||||
inner.error()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn assert_error(mut self) -> Self {
|
|
||||||
let inner = self.inner.take().unwrap();
|
|
||||||
self.inner = Some(inner.assert_error());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn assert_success(mut self) -> Self {
|
|
||||||
let inner = self.inner.take().unwrap();
|
|
||||||
self.inner = Some(inner.assert_success());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Tester<Error> {
|
|
||||||
inner_request: Option<ModuleRequest>,
|
|
||||||
assert_status_code: Option<StatusCode>,
|
|
||||||
response: Option<EventResponse>,
|
|
||||||
err_phantom: PhantomData<Error>,
|
|
||||||
user_detail: Option<UserDetail>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Error> Tester<Error>
|
|
||||||
where
|
|
||||||
Error: FromBytes + Debug,
|
|
||||||
{
|
|
||||||
pub fn new<E>(event: E) -> Self
|
|
||||||
where
|
|
||||||
E: Eq + Hash + Debug + Clone + Display,
|
|
||||||
{
|
|
||||||
init_sdk();
|
|
||||||
log::trace!(
|
|
||||||
"{:?} thread started: thread_id= {}",
|
|
||||||
thread::current(),
|
|
||||||
thread_id::get()
|
|
||||||
);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
inner_request: Some(ModuleRequest::new(event)),
|
|
||||||
assert_status_code: None,
|
|
||||||
response: None,
|
|
||||||
err_phantom: PhantomData,
|
|
||||||
user_detail: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn request<P>(mut self, request: P) -> Self
|
|
||||||
where
|
|
||||||
P: ToBytes,
|
|
||||||
{
|
|
||||||
let mut inner_request = self.inner_request.take().unwrap();
|
|
||||||
let bytes = request.into_bytes().unwrap();
|
|
||||||
inner_request = inner_request.payload(bytes);
|
|
||||||
self.inner_request = Some(inner_request);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn assert_status_code(mut self, status_code: StatusCode) -> Self {
|
|
||||||
self.assert_status_code = Some(status_code);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn assert_error(mut self) -> Self {
|
|
||||||
self.assert_status_code = Some(StatusCode::Err);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn assert_success(mut self) -> Self {
|
|
||||||
self.assert_status_code = Some(StatusCode::Ok);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn async_send(mut self) -> Self {
|
|
||||||
assert_eq!(self.inner_request.is_some(), true, "must set event");
|
|
||||||
|
|
||||||
let resp =
|
|
||||||
EventDispatch::async_send(self.inner_request.take().unwrap(), |_| Box::pin(async {}))
|
|
||||||
.await;
|
|
||||||
check(&resp, &self.assert_status_code);
|
|
||||||
self.response = Some(resp);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sync_send(mut self) -> Self {
|
|
||||||
let resp = EventDispatch::sync_send(self.inner_request.take().unwrap());
|
|
||||||
check(&resp, &self.assert_status_code);
|
|
||||||
self.response = Some(resp);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse<R>(self) -> R
|
|
||||||
where
|
|
||||||
R: FromBytes,
|
|
||||||
{
|
|
||||||
let response = self.response.unwrap();
|
|
||||||
match response.parse::<R, Error>() {
|
|
||||||
Ok(Ok(data)) => data,
|
|
||||||
Ok(Err(e)) => panic!("parse failed: {:?}", e),
|
|
||||||
Err(e) => panic!("Internal error: {:?}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn error(self) -> Error {
|
|
||||||
let response = self.response.unwrap();
|
|
||||||
assert_eq!(response.status_code, StatusCode::Err);
|
|
||||||
<Data<Error>>::try_from(response.payload)
|
|
||||||
.unwrap()
|
|
||||||
.into_inner()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check(response: &EventResponse, status_code: &Option<StatusCode>) {
|
|
||||||
if let Some(ref status_code) = status_code {
|
|
||||||
if &response.status_code != status_code {
|
|
||||||
eprintln!("{:#?}", response);
|
|
||||||
}
|
|
||||||
assert_eq!(&response.status_code, status_code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_user_after_login() -> UserDetail {
|
|
||||||
init_sdk();
|
|
||||||
let _ = EventDispatch::sync_send(ModuleRequest::new(SignOut));
|
|
||||||
let request = SignInRequest {
|
|
||||||
email: valid_email(),
|
|
||||||
password: valid_password(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let user_detail = Tester::<UserError>::new(SignIn)
|
|
||||||
.request(request)
|
|
||||||
.sync_send()
|
|
||||||
.parse::<UserDetail>();
|
|
||||||
|
|
||||||
user_detail
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn valid_email() -> String { "annie@appflowy.io".to_string() }
|
|
||||||
|
|
||||||
pub(crate) fn valid_password() -> String { "HelloWorld!123".to_string() }
|
|
||||||
|
176
rust-lib/flowy-test/src/tester.rs
Normal file
176
rust-lib/flowy-test/src/tester.rs
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
use crate::init_sdk;
|
||||||
|
use flowy_dispatch::prelude::*;
|
||||||
|
pub use flowy_sdk::*;
|
||||||
|
use flowy_user::prelude::*;
|
||||||
|
use std::{
|
||||||
|
convert::TryFrom,
|
||||||
|
fmt::{Debug, Display},
|
||||||
|
hash::Hash,
|
||||||
|
marker::PhantomData,
|
||||||
|
thread,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Tester<Error> {
|
||||||
|
inner_request: Option<ModuleRequest>,
|
||||||
|
assert_status_code: Option<StatusCode>,
|
||||||
|
response: Option<EventResponse>,
|
||||||
|
err_phantom: PhantomData<Error>,
|
||||||
|
user_detail: Option<UserDetail>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Error> Tester<Error>
|
||||||
|
where
|
||||||
|
Error: FromBytes + Debug,
|
||||||
|
{
|
||||||
|
pub fn new<E>(event: E) -> Self
|
||||||
|
where
|
||||||
|
E: Eq + Hash + Debug + Clone + Display,
|
||||||
|
{
|
||||||
|
init_sdk();
|
||||||
|
log::trace!(
|
||||||
|
"{:?} thread started: thread_id= {}",
|
||||||
|
thread::current(),
|
||||||
|
thread_id::get()
|
||||||
|
);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
inner_request: Some(ModuleRequest::new(event)),
|
||||||
|
assert_status_code: None,
|
||||||
|
response: None,
|
||||||
|
err_phantom: PhantomData,
|
||||||
|
user_detail: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_request<P>(&mut self, request: P)
|
||||||
|
where
|
||||||
|
P: ToBytes,
|
||||||
|
{
|
||||||
|
let mut inner_request = self.inner_request.take().unwrap();
|
||||||
|
let bytes = request.into_bytes().unwrap();
|
||||||
|
inner_request = inner_request.payload(bytes);
|
||||||
|
self.inner_request = Some(inner_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn assert_error(&mut self) { self.assert_status_code = Some(StatusCode::Err); }
|
||||||
|
|
||||||
|
pub fn assert_success(&mut self) { self.assert_status_code = Some(StatusCode::Ok); }
|
||||||
|
|
||||||
|
pub async fn async_send(&mut self) {
|
||||||
|
assert_eq!(self.inner_request.is_some(), true, "must set event");
|
||||||
|
|
||||||
|
let resp = EventDispatch::async_send(self.inner_request.take().unwrap()).await;
|
||||||
|
self.response = Some(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sync_send(&mut self) {
|
||||||
|
let resp = EventDispatch::sync_send(self.inner_request.take().unwrap());
|
||||||
|
self.response = Some(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse<R>(self) -> R
|
||||||
|
where
|
||||||
|
R: FromBytes,
|
||||||
|
{
|
||||||
|
let response = self.response.unwrap();
|
||||||
|
match response.parse::<R, Error>() {
|
||||||
|
Ok(Ok(data)) => data,
|
||||||
|
Ok(Err(e)) => panic!("parse failed: {:?}", e),
|
||||||
|
Err(e) => panic!("Internal error: {:?}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn error(self) -> Error {
|
||||||
|
let response = self.response.unwrap();
|
||||||
|
assert_eq!(response.status_code, StatusCode::Err);
|
||||||
|
<Data<Error>>::try_from(response.payload)
|
||||||
|
.unwrap()
|
||||||
|
.into_inner()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RandomUserTester<Error> {
|
||||||
|
context: TesterContext,
|
||||||
|
err_phantom: PhantomData<Error>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Error> RandomUserTester<Error>
|
||||||
|
where
|
||||||
|
Error: FromBytes + Debug,
|
||||||
|
{
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
context: TesterContext::default(),
|
||||||
|
err_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Error> TesterTrait for RandomUserTester<Error>
|
||||||
|
where
|
||||||
|
Error: FromBytes + Debug,
|
||||||
|
{
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn context(&mut self) -> &mut TesterContext { &mut self.context }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TesterContext {
|
||||||
|
request: Option<ModuleRequest>,
|
||||||
|
status_code: StatusCode,
|
||||||
|
response: Option<EventResponse>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::default::Default for TesterContext {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
request: None,
|
||||||
|
status_code: StatusCode::Ok,
|
||||||
|
response: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait TesterTrait {
|
||||||
|
type Error: FromBytes + Debug;
|
||||||
|
|
||||||
|
fn context(&mut self) -> &mut TesterContext;
|
||||||
|
|
||||||
|
fn assert_error(&mut self) { self.context().status_code = StatusCode::Err; }
|
||||||
|
|
||||||
|
fn assert_success(&mut self) { self.context().status_code = StatusCode::Ok; }
|
||||||
|
|
||||||
|
fn set_payload<P>(&mut self, payload: P)
|
||||||
|
where
|
||||||
|
P: ToBytes,
|
||||||
|
{
|
||||||
|
let bytes = payload.into_bytes().unwrap();
|
||||||
|
let mut module_request = self.context().request.take().unwrap();
|
||||||
|
self.context().request = Some(module_request.payload(bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sync_send(&mut self) {
|
||||||
|
let resp = EventDispatch::sync_send(self.context().request.take().unwrap());
|
||||||
|
self.context().response = Some(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse<R>(&mut self) -> R
|
||||||
|
where
|
||||||
|
R: FromBytes,
|
||||||
|
{
|
||||||
|
let response = self.context().response.clone().unwrap();
|
||||||
|
match response.parse::<R, Self::Error>() {
|
||||||
|
Ok(Ok(data)) => data,
|
||||||
|
Ok(Err(e)) => panic!("parse failed: {:?}", e),
|
||||||
|
Err(e) => panic!("Internal error: {:?}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn error(&mut self) -> Self::Error {
|
||||||
|
let response = self.context().response.clone().unwrap();
|
||||||
|
assert_eq!(response.status_code, StatusCode::Err);
|
||||||
|
<Data<Self::Error>>::try_from(response.payload)
|
||||||
|
.unwrap()
|
||||||
|
.into_inner()
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,7 @@ pub async fn user_sign_in_handler(
|
|||||||
session: ModuleData<Arc<UserSession>>,
|
session: ModuleData<Arc<UserSession>>,
|
||||||
) -> ResponseResult<UserDetail, UserError> {
|
) -> ResponseResult<UserDetail, UserError> {
|
||||||
let params: SignInParams = data.into_inner().try_into()?;
|
let params: SignInParams = data.into_inner().try_into()?;
|
||||||
let user = session.sign_in(params).await?;
|
let user = session.sign_in(params)?;
|
||||||
let user_detail = UserDetail::from(user);
|
let user_detail = UserDetail::from(user);
|
||||||
response_ok(user_detail)
|
response_ok(user_detail)
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ pub async fn user_sign_up_handler(
|
|||||||
session: ModuleData<Arc<UserSession>>,
|
session: ModuleData<Arc<UserSession>>,
|
||||||
) -> ResponseResult<UserDetail, UserError> {
|
) -> ResponseResult<UserDetail, UserError> {
|
||||||
let params: SignUpParams = data.into_inner().try_into()?;
|
let params: SignUpParams = data.into_inner().try_into()?;
|
||||||
let user = session.sign_up(params).await?;
|
let user = session.sign_up(params)?;
|
||||||
let user_detail = UserDetail::from(user);
|
let user_detail = UserDetail::from(user);
|
||||||
response_ok(user_detail)
|
response_ok(user_detail)
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,12 @@ use std::{convert::TryInto, sync::Arc};
|
|||||||
pub async fn user_get_status_handler(
|
pub async fn user_get_status_handler(
|
||||||
session: ModuleData<Arc<UserSession>>,
|
session: ModuleData<Arc<UserSession>>,
|
||||||
) -> ResponseResult<UserDetail, UserError> {
|
) -> ResponseResult<UserDetail, UserError> {
|
||||||
let user_detail = session.current_user_detail()?;
|
let user_detail = session.user_detail()?;
|
||||||
response_ok(user_detail)
|
response_ok(user_detail)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn sign_out_handler(session: ModuleData<Arc<UserSession>>) -> Result<(), UserError> {
|
pub async fn sign_out_handler(session: ModuleData<Arc<UserSession>>) -> Result<(), UserError> {
|
||||||
let _ = session.sign_out().await?;
|
let _ = session.sign_out()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,6 +19,6 @@ pub async fn update_user_handler(
|
|||||||
session: ModuleData<Arc<UserSession>>,
|
session: ModuleData<Arc<UserSession>>,
|
||||||
) -> ResponseResult<UserDetail, UserError> {
|
) -> ResponseResult<UserDetail, UserError> {
|
||||||
let params: UpdateUserParams = data.into_inner().try_into()?;
|
let params: UpdateUserParams = data.into_inner().try_into()?;
|
||||||
let user_detail = session.update_user(params).await?;
|
let user_detail = session.update_user(params)?;
|
||||||
response_ok(user_detail)
|
response_ok(user_detail)
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
entities::{SignInParams, SignUpParams, UserDetail},
|
entities::{SignInParams, SignUpParams, UserDetail},
|
||||||
errors::{ErrorBuilder, UserError, UserErrorCode},
|
errors::UserError,
|
||||||
sql_tables::User,
|
sql_tables::User,
|
||||||
};
|
};
|
||||||
use flowy_infra::uuid;
|
|
||||||
|
|
||||||
pub trait UserServer {
|
pub trait UserServer {
|
||||||
fn sign_up(&self, params: SignUpParams) -> Result<User, UserError>;
|
fn sign_up(&self, params: SignUpParams) -> Result<User, UserError>;
|
||||||
|
@ -10,14 +10,13 @@ use lazy_static::lazy_static;
|
|||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
entities::{SignInParams, SignUpParams, UpdateUserParams, UserDetail},
|
entities::{SignInParams, SignUpParams, UpdateUserParams, UpdateUserRequest, UserDetail},
|
||||||
errors::{ErrorBuilder, UserError, UserErrorCode},
|
errors::{ErrorBuilder, UserError, UserErrorCode},
|
||||||
event::UserEvent::GetStatus,
|
event::UserEvent::*,
|
||||||
services::user_session::{database::UserDB, user_server::UserServer},
|
services::user_session::{database::UserDB, user_server::UserServer},
|
||||||
sql_tables::{User, UserChangeset},
|
sql_tables::{User, UserChangeset},
|
||||||
};
|
};
|
||||||
use flowy_dispatch::prelude::{Data, EventDispatch, ModuleRequest};
|
use flowy_dispatch::prelude::{EventDispatch, ModuleRequest, ToBytes};
|
||||||
use std::convert::TryFrom;
|
|
||||||
|
|
||||||
pub struct UserSessionConfig {
|
pub struct UserSessionConfig {
|
||||||
root_dir: String,
|
root_dir: String,
|
||||||
@ -50,20 +49,25 @@ impl UserSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn sign_in(&self, params: SignInParams) -> Result<User, UserError> {
|
pub fn get_db_connection(&self) -> Result<DBConnection, UserError> {
|
||||||
|
let user_id = get_current_user_id()?;
|
||||||
|
self.database.get_connection(&user_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sign_in(&self, params: SignInParams) -> Result<User, UserError> {
|
||||||
let user = self.server.sign_in(params)?;
|
let user = self.server.sign_in(params)?;
|
||||||
let _ = set_current_user_id(Some(user.id.clone()))?;
|
let _ = set_current_user_id(Some(user.id.clone()))?;
|
||||||
self.save_user(user)
|
self.save_user(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn sign_up(&self, params: SignUpParams) -> Result<User, UserError> {
|
pub fn sign_up(&self, params: SignUpParams) -> Result<User, UserError> {
|
||||||
let user = self.server.sign_up(params)?;
|
let user = self.server.sign_up(params)?;
|
||||||
let _ = set_current_user_id(Some(user.id.clone()))?;
|
let _ = set_current_user_id(Some(user.id.clone()))?;
|
||||||
self.save_user(user)
|
self.save_user(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn sign_out(&self) -> Result<(), UserError> {
|
pub fn sign_out(&self) -> Result<(), UserError> {
|
||||||
let user_id = self.current_user_id()?;
|
let user_id = current_user_id()?;
|
||||||
let conn = self.get_db_connection()?;
|
let conn = self.get_db_connection()?;
|
||||||
let _ = diesel::delete(dsl::user_table.filter(dsl::id.eq(&user_id))).execute(&*conn)?;
|
let _ = diesel::delete(dsl::user_table.filter(dsl::id.eq(&user_id))).execute(&*conn)?;
|
||||||
|
|
||||||
@ -77,17 +81,26 @@ impl UserSession {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_user(&self, params: UpdateUserParams) -> Result<UserDetail, UserError> {
|
fn save_user(&self, user: User) -> Result<User, UserError> {
|
||||||
|
let conn = self.get_db_connection()?;
|
||||||
|
let _ = diesel::insert_into(user_table::table)
|
||||||
|
.values(user.clone())
|
||||||
|
.execute(&*conn)?;
|
||||||
|
|
||||||
|
Ok(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_user(&self, params: UpdateUserParams) -> Result<UserDetail, UserError> {
|
||||||
let changeset = UserChangeset::new(params);
|
let changeset = UserChangeset::new(params);
|
||||||
let conn = self.get_db_connection()?;
|
let conn = self.get_db_connection()?;
|
||||||
diesel_update_table!(user_table, changeset, conn);
|
diesel_update_table!(user_table, changeset, conn);
|
||||||
|
|
||||||
let user_detail = self.current_user_detail()?;
|
let user_detail = self.user_detail()?;
|
||||||
Ok(user_detail)
|
Ok(user_detail)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_user_detail(&self) -> Result<UserDetail, UserError> {
|
pub fn user_detail(&self) -> Result<UserDetail, UserError> {
|
||||||
let user_id = self.current_user_id()?;
|
let user_id = current_user_id()?;
|
||||||
let conn = self.get_db_connection()?;
|
let conn = self.get_db_connection()?;
|
||||||
|
|
||||||
let user = dsl::user_table
|
let user = dsl::user_table
|
||||||
@ -105,61 +118,36 @@ impl UserSession {
|
|||||||
|
|
||||||
Ok(UserDetail::from(user))
|
Ok(UserDetail::from(user))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_db_connection(&self) -> Result<DBConnection, UserError> {
|
|
||||||
let user_id = get_current_user_id()?;
|
|
||||||
self.database.get_connection(&user_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_current_workspace() {
|
|
||||||
unimplemented!()
|
|
||||||
|
|
||||||
// let request = SignInRequest {
|
|
||||||
// email: valid_email(),
|
|
||||||
// password: valid_password(),
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// let user_detail = Tester::<UserError>::new(SignIn)
|
|
||||||
// .request(request)
|
|
||||||
// .sync_send()
|
|
||||||
// .parse::<UserDetail>();
|
|
||||||
//
|
|
||||||
// user_detail
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn get_current_workspace(&self) -> Result<String, UserError> {
|
|
||||||
// let response = EventDispatch::sync_send(ModuleRequest::new(GetStatus));
|
|
||||||
// let user_detail =
|
|
||||||
// <Data<UserDetail>>::try_from(response.payload).unwrap().into_inner();
|
|
||||||
let user_id = get_current_user_id()?;
|
|
||||||
let conn = self.get_db_connection()?;
|
|
||||||
|
|
||||||
let workspace = dsl::user_table
|
|
||||||
.filter(user_table::id.eq(&user_id))
|
|
||||||
.select(user_table::workspace)
|
|
||||||
.first::<String>(&*conn)?;
|
|
||||||
|
|
||||||
Ok(workspace)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserSession {
|
impl UserSession {
|
||||||
fn save_user(&self, user: User) -> Result<User, UserError> {
|
pub async fn set_current_workspace(workspace: &str) -> Result<(), UserError> {
|
||||||
let conn = self.get_db_connection()?;
|
let user_id = current_user_id()?;
|
||||||
let _ = diesel::insert_into(user_table::table)
|
let payload: Vec<u8> = UpdateUserRequest {
|
||||||
.values(user.clone())
|
id: user_id,
|
||||||
.execute(&*conn)?;
|
name: None,
|
||||||
|
email: None,
|
||||||
Ok(user)
|
workspace: Some(workspace.to_owned()),
|
||||||
|
password: None,
|
||||||
}
|
}
|
||||||
|
.into_bytes()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
fn current_user_id(&self) -> Result<String, UserError> {
|
let request = ModuleRequest::new(UpdateUser).payload(payload);
|
||||||
|
let _user_detail = EventDispatch::async_send(request)
|
||||||
|
.await
|
||||||
|
.parse::<UserDetail, UserError>()
|
||||||
|
.unwrap()
|
||||||
|
.unwrap();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_user_id() -> Result<String, UserError> {
|
||||||
match KVStore::get_str(USER_ID_DISK_CACHE_KEY) {
|
match KVStore::get_str(USER_ID_DISK_CACHE_KEY) {
|
||||||
None => Err(ErrorBuilder::new(UserErrorCode::UserNotLoginYet).build()),
|
None => Err(ErrorBuilder::new(UserErrorCode::UserNotLoginYet).build()),
|
||||||
Some(user_id) => Ok(user_id),
|
Some(user_id) => Ok(user_id),
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserDatabaseConnection for UserSession {
|
impl UserDatabaseConnection for UserSession {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use flowy_test::{TestBuilder, Tester};
|
use flowy_test::prelude::TestBuilder;
|
||||||
use flowy_user::errors::UserError;
|
use flowy_user::errors::UserError;
|
||||||
|
|
||||||
pub type UserTestBuilder = TestBuilder<UserError>;
|
pub type UserTestBuilder = TestBuilder<UserError>;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
mod helper;
|
mod helper;
|
||||||
mod sign_in_test;
|
mod sign_in_test;
|
||||||
mod sign_up_test;
|
mod sign_up_test;
|
||||||
mod user_detail_test;
|
|
||||||
mod user_status_test;
|
mod user_status_test;
|
||||||
|
mod user_update_test;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::helper::*;
|
use crate::helper::*;
|
||||||
use flowy_user::{errors::UserErrorCode, event::UserEvent::*, prelude::*};
|
use flowy_user::{event::UserEvent::*, prelude::*};
|
||||||
use serial_test::*;
|
use serial_test::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
pub use workspace_create::*;
|
pub use workspace_create::*;
|
||||||
pub use workspace_query::*;
|
pub use workspace_query::*;
|
||||||
pub use workspace_update::*;
|
pub use workspace_update::*;
|
||||||
|
pub use workspace_user_detail::*;
|
||||||
|
|
||||||
pub(crate) mod parser;
|
pub(crate) mod parser;
|
||||||
mod workspace_create;
|
mod workspace_create;
|
||||||
mod workspace_query;
|
mod workspace_query;
|
||||||
mod workspace_update;
|
mod workspace_update;
|
||||||
|
mod workspace_user_detail;
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
pub struct WorkspaceUserQueryRequest {
|
||||||
|
fetch_owner: bool,
|
||||||
|
fetch_all: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WorkspaceUserDetail {}
|
@ -46,6 +46,9 @@ pub enum WorkspaceErrorCode {
|
|||||||
|
|
||||||
#[display(fmt = "User internal error")]
|
#[display(fmt = "User internal error")]
|
||||||
UserInternalError = 10,
|
UserInternalError = 10,
|
||||||
|
|
||||||
|
#[display(fmt = "User not login yet")]
|
||||||
|
UserNotLoginYet = 11,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::default::Default for WorkspaceErrorCode {
|
impl std::default::Default for WorkspaceErrorCode {
|
||||||
|
@ -7,4 +7,8 @@ pub enum WorkspaceEvent {
|
|||||||
#[display(fmt = "Create workspace")]
|
#[display(fmt = "Create workspace")]
|
||||||
#[event(input = "CreateSpaceRequest", output = "WorkspaceDetail")]
|
#[event(input = "CreateSpaceRequest", output = "WorkspaceDetail")]
|
||||||
CreateWorkspace = 0,
|
CreateWorkspace = 0,
|
||||||
|
|
||||||
|
#[display(fmt = "Get workspace user")]
|
||||||
|
#[event(output = "UserDetail")]
|
||||||
|
GetWorkspaceUserDetail = 100,
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
handlers::create_workspace,
|
handlers::create_workspace,
|
||||||
services::{AppController, WorkspaceController},
|
services::{AppController, WorkspaceController},
|
||||||
};
|
};
|
||||||
use flowy_database::{DBConnection, UserDatabaseConnection};
|
use flowy_database::DBConnection;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub trait WorkspaceUser: Send + Sync {
|
pub trait WorkspaceUser: Send + Sync {
|
||||||
|
@ -223,6 +223,7 @@ pub enum WorkspaceErrorCode {
|
|||||||
DatabaseConnectionFail = 5,
|
DatabaseConnectionFail = 5,
|
||||||
DatabaseInternalError = 6,
|
DatabaseInternalError = 6,
|
||||||
UserInternalError = 10,
|
UserInternalError = 10,
|
||||||
|
UserNotLoginYet = 11,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::protobuf::ProtobufEnum for WorkspaceErrorCode {
|
impl ::protobuf::ProtobufEnum for WorkspaceErrorCode {
|
||||||
@ -240,6 +241,7 @@ impl ::protobuf::ProtobufEnum for WorkspaceErrorCode {
|
|||||||
5 => ::std::option::Option::Some(WorkspaceErrorCode::DatabaseConnectionFail),
|
5 => ::std::option::Option::Some(WorkspaceErrorCode::DatabaseConnectionFail),
|
||||||
6 => ::std::option::Option::Some(WorkspaceErrorCode::DatabaseInternalError),
|
6 => ::std::option::Option::Some(WorkspaceErrorCode::DatabaseInternalError),
|
||||||
10 => ::std::option::Option::Some(WorkspaceErrorCode::UserInternalError),
|
10 => ::std::option::Option::Some(WorkspaceErrorCode::UserInternalError),
|
||||||
|
11 => ::std::option::Option::Some(WorkspaceErrorCode::UserNotLoginYet),
|
||||||
_ => ::std::option::Option::None
|
_ => ::std::option::Option::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,6 +256,7 @@ impl ::protobuf::ProtobufEnum for WorkspaceErrorCode {
|
|||||||
WorkspaceErrorCode::DatabaseConnectionFail,
|
WorkspaceErrorCode::DatabaseConnectionFail,
|
||||||
WorkspaceErrorCode::DatabaseInternalError,
|
WorkspaceErrorCode::DatabaseInternalError,
|
||||||
WorkspaceErrorCode::UserInternalError,
|
WorkspaceErrorCode::UserInternalError,
|
||||||
|
WorkspaceErrorCode::UserNotLoginYet,
|
||||||
];
|
];
|
||||||
values
|
values
|
||||||
}
|
}
|
||||||
@ -284,36 +287,39 @@ impl ::protobuf::reflect::ProtobufValue for WorkspaceErrorCode {
|
|||||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||||
\n\x0cerrors.proto\"K\n\x0eWorkspaceError\x12'\n\x04code\x18\x01\x20\x01\
|
\n\x0cerrors.proto\"K\n\x0eWorkspaceError\x12'\n\x04code\x18\x01\x20\x01\
|
||||||
(\x0e2\x13.WorkspaceErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\
|
(\x0e2\x13.WorkspaceErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\
|
||||||
\tR\x03msg*\xcd\x01\n\x12WorkspaceErrorCode\x12\x0b\n\x07Unknown\x10\0\
|
\tR\x03msg*\xe2\x01\n\x12WorkspaceErrorCode\x12\x0b\n\x07Unknown\x10\0\
|
||||||
\x12\x18\n\x14WorkspaceNameInvalid\x10\x01\x12\x16\n\x12WorkspaceIdInval\
|
\x12\x18\n\x14WorkspaceNameInvalid\x10\x01\x12\x16\n\x12WorkspaceIdInval\
|
||||||
id\x10\x02\x12\x18\n\x14AppColorStyleInvalid\x10\x03\x12\x10\n\x0cAppIdI\
|
id\x10\x02\x12\x18\n\x14AppColorStyleInvalid\x10\x03\x12\x10\n\x0cAppIdI\
|
||||||
nvalid\x10\x04\x12\x1a\n\x16DatabaseConnectionFail\x10\x05\x12\x19\n\x15\
|
nvalid\x10\x04\x12\x1a\n\x16DatabaseConnectionFail\x10\x05\x12\x19\n\x15\
|
||||||
DatabaseInternalError\x10\x06\x12\x15\n\x11UserInternalError\x10\nJ\xf8\
|
DatabaseInternalError\x10\x06\x12\x15\n\x11UserInternalError\x10\n\x12\
|
||||||
\x03\n\x06\x12\x04\0\0\x0f\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
|
\x13\n\x0fUserNotLoginYet\x10\x0bJ\xa1\x04\n\x06\x12\x04\0\0\x10\x01\n\
|
||||||
\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x16\n\
|
\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\
|
||||||
\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x20\n\x0c\n\x05\x04\0\x02\0\x06\
|
\n\x03\x04\0\x01\x12\x03\x02\x08\x16\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\
|
||||||
\x12\x03\x03\x04\x16\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x17\x1b\n\
|
\x04\x20\n\x0c\n\x05\x04\0\x02\0\x06\x12\x03\x03\x04\x16\n\x0c\n\x05\x04\
|
||||||
\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x1e\x1f\n\x0b\n\x04\x04\0\x02\x01\
|
\0\x02\0\x01\x12\x03\x03\x17\x1b\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\
|
||||||
\x12\x03\x04\x04\x13\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\
|
\x1e\x1f\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x13\n\x0c\n\x05\x04\0\
|
||||||
\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x0e\n\x0c\n\x05\x04\0\x02\
|
\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\
|
||||||
\x01\x03\x12\x03\x04\x11\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x0f\x01\n\n\n\
|
\x0b\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x11\x12\n\n\n\x02\x05\
|
||||||
\x03\x05\0\x01\x12\x03\x06\x05\x17\n\x0b\n\x04\x05\0\x02\0\x12\x03\x07\
|
\0\x12\x04\x06\0\x10\x01\n\n\n\x03\x05\0\x01\x12\x03\x06\x05\x17\n\x0b\n\
|
||||||
\x04\x10\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x07\x04\x0b\n\x0c\n\x05\x05\
|
\x04\x05\0\x02\0\x12\x03\x07\x04\x10\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\
|
||||||
\0\x02\0\x02\x12\x03\x07\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x08\
|
\x07\x04\x0b\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x07\x0e\x0f\n\x0b\n\x04\
|
||||||
\x04\x1d\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x08\x04\x18\n\x0c\n\x05\
|
\x05\0\x02\x01\x12\x03\x08\x04\x1d\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\
|
||||||
\x05\0\x02\x01\x02\x12\x03\x08\x1b\x1c\n\x0b\n\x04\x05\0\x02\x02\x12\x03\
|
\x08\x04\x18\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x08\x1b\x1c\n\x0b\n\
|
||||||
\t\x04\x1b\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\t\x04\x16\n\x0c\n\x05\
|
\x04\x05\0\x02\x02\x12\x03\t\x04\x1b\n\x0c\n\x05\x05\0\x02\x02\x01\x12\
|
||||||
\x05\0\x02\x02\x02\x12\x03\t\x19\x1a\n\x0b\n\x04\x05\0\x02\x03\x12\x03\n\
|
\x03\t\x04\x16\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\t\x19\x1a\n\x0b\n\
|
||||||
\x04\x1d\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\n\x04\x18\n\x0c\n\x05\x05\
|
\x04\x05\0\x02\x03\x12\x03\n\x04\x1d\n\x0c\n\x05\x05\0\x02\x03\x01\x12\
|
||||||
\0\x02\x03\x02\x12\x03\n\x1b\x1c\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x0b\
|
\x03\n\x04\x18\n\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\n\x1b\x1c\n\x0b\n\
|
||||||
\x04\x15\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x0b\x04\x10\n\x0c\n\x05\
|
\x04\x05\0\x02\x04\x12\x03\x0b\x04\x15\n\x0c\n\x05\x05\0\x02\x04\x01\x12\
|
||||||
\x05\0\x02\x04\x02\x12\x03\x0b\x13\x14\n\x0b\n\x04\x05\0\x02\x05\x12\x03\
|
\x03\x0b\x04\x10\n\x0c\n\x05\x05\0\x02\x04\x02\x12\x03\x0b\x13\x14\n\x0b\
|
||||||
\x0c\x04\x1f\n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x0c\x04\x1a\n\x0c\n\
|
\n\x04\x05\0\x02\x05\x12\x03\x0c\x04\x1f\n\x0c\n\x05\x05\0\x02\x05\x01\
|
||||||
\x05\x05\0\x02\x05\x02\x12\x03\x0c\x1d\x1e\n\x0b\n\x04\x05\0\x02\x06\x12\
|
\x12\x03\x0c\x04\x1a\n\x0c\n\x05\x05\0\x02\x05\x02\x12\x03\x0c\x1d\x1e\n\
|
||||||
\x03\r\x04\x1e\n\x0c\n\x05\x05\0\x02\x06\x01\x12\x03\r\x04\x19\n\x0c\n\
|
\x0b\n\x04\x05\0\x02\x06\x12\x03\r\x04\x1e\n\x0c\n\x05\x05\0\x02\x06\x01\
|
||||||
\x05\x05\0\x02\x06\x02\x12\x03\r\x1c\x1d\n\x0b\n\x04\x05\0\x02\x07\x12\
|
\x12\x03\r\x04\x19\n\x0c\n\x05\x05\0\x02\x06\x02\x12\x03\r\x1c\x1d\n\x0b\
|
||||||
\x03\x0e\x04\x1b\n\x0c\n\x05\x05\0\x02\x07\x01\x12\x03\x0e\x04\x15\n\x0c\
|
\n\x04\x05\0\x02\x07\x12\x03\x0e\x04\x1b\n\x0c\n\x05\x05\0\x02\x07\x01\
|
||||||
\n\x05\x05\0\x02\x07\x02\x12\x03\x0e\x18\x1ab\x06proto3\
|
\x12\x03\x0e\x04\x15\n\x0c\n\x05\x05\0\x02\x07\x02\x12\x03\x0e\x18\x1a\n\
|
||||||
|
\x0b\n\x04\x05\0\x02\x08\x12\x03\x0f\x04\x19\n\x0c\n\x05\x05\0\x02\x08\
|
||||||
|
\x01\x12\x03\x0f\x04\x13\n\x0c\n\x05\x05\0\x02\x08\x02\x12\x03\x0f\x16\
|
||||||
|
\x18b\x06proto3\
|
||||||
";
|
";
|
||||||
|
|
||||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
|
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
|
||||||
pub enum WorkspaceEvent {
|
pub enum WorkspaceEvent {
|
||||||
CreateWorkspace = 0,
|
CreateWorkspace = 0,
|
||||||
|
GetWorkspaceUserDetail = 100,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::protobuf::ProtobufEnum for WorkspaceEvent {
|
impl ::protobuf::ProtobufEnum for WorkspaceEvent {
|
||||||
@ -36,6 +37,7 @@ impl ::protobuf::ProtobufEnum for WorkspaceEvent {
|
|||||||
fn from_i32(value: i32) -> ::std::option::Option<WorkspaceEvent> {
|
fn from_i32(value: i32) -> ::std::option::Option<WorkspaceEvent> {
|
||||||
match value {
|
match value {
|
||||||
0 => ::std::option::Option::Some(WorkspaceEvent::CreateWorkspace),
|
0 => ::std::option::Option::Some(WorkspaceEvent::CreateWorkspace),
|
||||||
|
100 => ::std::option::Option::Some(WorkspaceEvent::GetWorkspaceUserDetail),
|
||||||
_ => ::std::option::Option::None
|
_ => ::std::option::Option::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,6 +45,7 @@ impl ::protobuf::ProtobufEnum for WorkspaceEvent {
|
|||||||
fn values() -> &'static [Self] {
|
fn values() -> &'static [Self] {
|
||||||
static values: &'static [WorkspaceEvent] = &[
|
static values: &'static [WorkspaceEvent] = &[
|
||||||
WorkspaceEvent::CreateWorkspace,
|
WorkspaceEvent::CreateWorkspace,
|
||||||
|
WorkspaceEvent::GetWorkspaceUserDetail,
|
||||||
];
|
];
|
||||||
values
|
values
|
||||||
}
|
}
|
||||||
@ -71,12 +74,14 @@ impl ::protobuf::reflect::ProtobufValue for WorkspaceEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||||
\n\x0bevent.proto*%\n\x0eWorkspaceEvent\x12\x13\n\x0fCreateWorkspace\x10\
|
\n\x0bevent.proto*A\n\x0eWorkspaceEvent\x12\x13\n\x0fCreateWorkspace\x10\
|
||||||
\0JS\n\x06\x12\x04\0\0\x04\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
|
\0\x12\x1a\n\x16GetWorkspaceUserDetail\x10dJ|\n\x06\x12\x04\0\0\x05\x01\
|
||||||
\x05\0\x12\x04\x02\0\x04\x01\n\n\n\x03\x05\0\x01\x12\x03\x02\x05\x13\n\
|
\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\x04\x02\0\x05\x01\n\
|
||||||
\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x04\x18\n\x0c\n\x05\x05\0\x02\0\x01\
|
\n\n\x03\x05\0\x01\x12\x03\x02\x05\x13\n\x0b\n\x04\x05\0\x02\0\x12\x03\
|
||||||
\x12\x03\x03\x04\x13\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x03\x16\x17b\
|
\x03\x04\x18\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x03\x04\x13\n\x0c\n\x05\
|
||||||
\x06proto3\
|
\x05\0\x02\0\x02\x12\x03\x03\x16\x17\n\x0b\n\x04\x05\0\x02\x01\x12\x03\
|
||||||
|
\x04\x04!\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x04\x04\x1a\n\x0c\n\x05\
|
||||||
|
\x05\0\x02\x01\x02\x12\x03\x04\x1d\x20b\x06proto3\
|
||||||
";
|
";
|
||||||
|
|
||||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||||
|
@ -13,4 +13,5 @@ enum WorkspaceErrorCode {
|
|||||||
DatabaseConnectionFail = 5;
|
DatabaseConnectionFail = 5;
|
||||||
DatabaseInternalError = 6;
|
DatabaseInternalError = 6;
|
||||||
UserInternalError = 10;
|
UserInternalError = 10;
|
||||||
|
UserNotLoginYet = 11;
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,5 @@ syntax = "proto3";
|
|||||||
|
|
||||||
enum WorkspaceEvent {
|
enum WorkspaceEvent {
|
||||||
CreateWorkspace = 0;
|
CreateWorkspace = 0;
|
||||||
|
GetWorkspaceUserDetail = 100;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use flowy_test::TestBuilder;
|
use flowy_test::prelude::TestBuilder;
|
||||||
use flowy_workspace::errors::WorkspaceError;
|
use flowy_workspace::errors::WorkspaceError;
|
||||||
|
|
||||||
pub type WorkspaceTestBuilder = TestBuilder<WorkspaceError>;
|
pub type WorkspaceTestBuilder = TestBuilder<WorkspaceError>;
|
||||||
|
Loading…
Reference in New Issue
Block a user