mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-09-11 19:17:43 +03:00
add create app test & create default workspace when user login at first time
This commit is contained in:
parent
139222ddcb
commit
55fad84590
@ -24,6 +24,7 @@ class UserErrorCode extends $pb.ProtobufEnum {
|
||||
static const UserErrorCode UserNameInvalid = UserErrorCode._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameInvalid');
|
||||
static const UserErrorCode UserWorkspaceInvalid = UserErrorCode._(23, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserWorkspaceInvalid');
|
||||
static const UserErrorCode UserIdInvalid = UserErrorCode._(24, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdInvalid');
|
||||
static const UserErrorCode CreateDefaultWorkspaceFailed = UserErrorCode._(25, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateDefaultWorkspaceFailed');
|
||||
|
||||
static const $core.List<UserErrorCode> values = <UserErrorCode> [
|
||||
Unknown,
|
||||
@ -40,6 +41,7 @@ class UserErrorCode extends $pb.ProtobufEnum {
|
||||
UserNameInvalid,
|
||||
UserWorkspaceInvalid,
|
||||
UserIdInvalid,
|
||||
CreateDefaultWorkspaceFailed,
|
||||
];
|
||||
|
||||
static final $core.Map<$core.int, UserErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||
|
@ -26,11 +26,12 @@ const UserErrorCode$json = const {
|
||||
const {'1': 'UserNameInvalid', '2': 22},
|
||||
const {'1': 'UserWorkspaceInvalid', '2': 23},
|
||||
const {'1': 'UserIdInvalid', '2': 24},
|
||||
const {'1': 'CreateDefaultWorkspaceFailed', '2': 25},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `UserErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||
final $typed_data.Uint8List userErrorCodeDescriptor = $convert.base64Decode('Cg1Vc2VyRXJyb3JDb2RlEgsKB1Vua25vd24QABIaChZVc2VyRGF0YWJhc2VJbml0RmFpbGVkEAESGwoXVXNlckRhdGFiYXNlV3JpdGVMb2NrZWQQAhIaChZVc2VyRGF0YWJhc2VSZWFkTG9ja2VkEAMSGwoXVXNlckRhdGFiYXNlRGlkTm90TWF0Y2gQBBIdChlVc2VyRGF0YWJhc2VJbnRlcm5hbEVycm9yEAUSEwoPVXNlck5vdExvZ2luWWV0EAoSFwoTUmVhZEN1cnJlbnRJZEZhaWxlZBALEhgKFFdyaXRlQ3VycmVudElkRmFpbGVkEAwSEAoMRW1haWxJbnZhbGlkEBQSEwoPUGFzc3dvcmRJbnZhbGlkEBUSEwoPVXNlck5hbWVJbnZhbGlkEBYSGAoUVXNlcldvcmtzcGFjZUludmFsaWQQFxIRCg1Vc2VySWRJbnZhbGlkEBg=');
|
||||
final $typed_data.Uint8List userErrorCodeDescriptor = $convert.base64Decode('Cg1Vc2VyRXJyb3JDb2RlEgsKB1Vua25vd24QABIaChZVc2VyRGF0YWJhc2VJbml0RmFpbGVkEAESGwoXVXNlckRhdGFiYXNlV3JpdGVMb2NrZWQQAhIaChZVc2VyRGF0YWJhc2VSZWFkTG9ja2VkEAMSGwoXVXNlckRhdGFiYXNlRGlkTm90TWF0Y2gQBBIdChlVc2VyRGF0YWJhc2VJbnRlcm5hbEVycm9yEAUSEwoPVXNlck5vdExvZ2luWWV0EAoSFwoTUmVhZEN1cnJlbnRJZEZhaWxlZBALEhgKFFdyaXRlQ3VycmVudElkRmFpbGVkEAwSEAoMRW1haWxJbnZhbGlkEBQSEwoPUGFzc3dvcmRJbnZhbGlkEBUSEwoPVXNlck5hbWVJbnZhbGlkEBYSGAoUVXNlcldvcmtzcGFjZUludmFsaWQQFxIRCg1Vc2VySWRJbnZhbGlkEBgSIAocQ3JlYXRlRGVmYXVsdFdvcmtzcGFjZUZhaWxlZBAZ');
|
||||
@$core.Deprecated('Use userErrorDescriptor instead')
|
||||
const UserError$json = const {
|
||||
'1': 'UserError',
|
||||
|
@ -12,10 +12,12 @@ import 'package:protobuf/protobuf.dart' as $pb;
|
||||
class WorkspaceEvent extends $pb.ProtobufEnum {
|
||||
static const WorkspaceEvent CreateWorkspace = WorkspaceEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateWorkspace');
|
||||
static const WorkspaceEvent GetWorkspaceDetail = WorkspaceEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetWorkspaceDetail');
|
||||
static const WorkspaceEvent CreateApp = WorkspaceEvent._(101, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateApp');
|
||||
|
||||
static const $core.List<WorkspaceEvent> values = <WorkspaceEvent> [
|
||||
CreateWorkspace,
|
||||
GetWorkspaceDetail,
|
||||
CreateApp,
|
||||
];
|
||||
|
||||
static final $core.Map<$core.int, WorkspaceEvent> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||
|
@ -14,8 +14,9 @@ const WorkspaceEvent$json = const {
|
||||
'2': const [
|
||||
const {'1': 'CreateWorkspace', '2': 0},
|
||||
const {'1': 'GetWorkspaceDetail', '2': 1},
|
||||
const {'1': 'CreateApp', '2': 101},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `WorkspaceEvent`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||
final $typed_data.Uint8List workspaceEventDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIWChJHZXRXb3Jrc3BhY2VEZXRhaWwQAQ==');
|
||||
final $typed_data.Uint8List workspaceEventDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIWChJHZXRXb3Jrc3BhY2VEZXRhaWwQARINCglDcmVhdGVBcHAQZQ==');
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
errors::{DispatchError, Error, InternalError},
|
||||
module::{as_module_map, Module, ModuleMap, ModuleRequest},
|
||||
response::{EventResponse, Responder},
|
||||
response::EventResponse,
|
||||
service::{Service, ServiceFactory},
|
||||
util::tokio_default_runtime,
|
||||
};
|
||||
|
@ -1,4 +1,3 @@
|
||||
use crate::byte_trait::ToBytes;
|
||||
use bytes::Bytes;
|
||||
use std::{fmt, fmt::Formatter};
|
||||
|
||||
|
@ -1,9 +1,15 @@
|
||||
use flowy_dispatch::prelude::{DispatchFuture, EventDispatch, ModuleRequest, ToBytes};
|
||||
use flowy_user::{
|
||||
entities::{SignInParams, SignUpParams, UserDetail},
|
||||
errors::{ErrorBuilder, UserError, UserErrorCode},
|
||||
prelude::UserServer,
|
||||
sql_tables::UserTable,
|
||||
};
|
||||
use flowy_workspace::{
|
||||
entities::workspace::{CreateWorkspaceRequest, WorkspaceDetail},
|
||||
errors::WorkspaceError,
|
||||
event::WorkspaceEvent::CreateWorkspace,
|
||||
};
|
||||
|
||||
pub type ArcFlowyServer = std::sync::Arc<dyn FlowyServer>;
|
||||
|
||||
@ -34,11 +40,40 @@ impl UserServer for FlowyServerMocker {
|
||||
))
|
||||
}
|
||||
|
||||
fn sign_out(&self, _user_id: &str) -> Result<(), UserError> {
|
||||
Err(ErrorBuilder::new(UserErrorCode::Unknown).build())
|
||||
}
|
||||
|
||||
fn get_user_info(&self, _user_id: &str) -> Result<UserDetail, UserError> {
|
||||
Err(ErrorBuilder::new(UserErrorCode::Unknown).build())
|
||||
}
|
||||
|
||||
fn sign_out(&self, _user_id: &str) -> Result<(), UserError> {
|
||||
Err(ErrorBuilder::new(UserErrorCode::Unknown).build())
|
||||
fn create_workspace(
|
||||
&self,
|
||||
name: &str,
|
||||
desc: &str,
|
||||
_user_id: &str,
|
||||
) -> DispatchFuture<Result<(), UserError>> {
|
||||
let payload: Vec<u8> = CreateWorkspaceRequest {
|
||||
name: name.to_string(),
|
||||
desc: desc.to_string(),
|
||||
}
|
||||
.into_bytes()
|
||||
.unwrap();
|
||||
|
||||
let request = ModuleRequest::new(CreateWorkspace).payload(payload);
|
||||
DispatchFuture {
|
||||
fut: Box::pin(async move {
|
||||
let _ = EventDispatch::async_send(request)
|
||||
.await
|
||||
.parse::<WorkspaceDetail, WorkspaceError>()
|
||||
.map_err(|e| {
|
||||
ErrorBuilder::new(UserErrorCode::CreateDefaultWorkspaceFailed)
|
||||
.error(e)
|
||||
.build()
|
||||
})?;
|
||||
Ok(())
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ mod flowy_server;
|
||||
pub mod module;
|
||||
|
||||
pub use crate::flowy_server::{ArcFlowyServer, FlowyServerMocker};
|
||||
use deps_resolve::*;
|
||||
use flowy_dispatch::prelude::*;
|
||||
use module::build_modules;
|
||||
pub use module::*;
|
||||
|
@ -1,11 +1,9 @@
|
||||
use crate::flowy_server::{ArcFlowyServer, FlowyServerMocker};
|
||||
use flowy_database::DBConnection;
|
||||
use flowy_dispatch::prelude::{DispatchFuture, Module};
|
||||
use flowy_dispatch::prelude::Module;
|
||||
use flowy_user::prelude::*;
|
||||
use flowy_workspace::prelude::*;
|
||||
|
||||
use crate::deps_resolve::WorkspaceUserImpl;
|
||||
use flowy_workspace::entities::workspace::UserWorkspace;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct ModuleConfig {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{conn_ext::*, errors::*, pragma::*};
|
||||
use crate::{errors::*, pragma::*};
|
||||
use diesel::{connection::Connection, SqliteConnection};
|
||||
use r2d2::{CustomizeConnection, ManageConnection, Pool};
|
||||
use scheduled_thread_pool::ScheduledThreadPool;
|
||||
|
@ -11,17 +11,19 @@ use crate::{
|
||||
};
|
||||
use flowy_user::errors::UserError;
|
||||
use flowy_workspace::errors::WorkspaceError;
|
||||
use std::marker::PhantomData;
|
||||
use std::{marker::PhantomData, sync::Once};
|
||||
static INIT: Once = Once::new();
|
||||
|
||||
pub type WorkspaceTestBuilder = TestBuilder<FixedUserTester<WorkspaceError>>;
|
||||
impl WorkspaceTestBuilder {
|
||||
pub fn new() -> Self {
|
||||
let builder = Self {
|
||||
let mut builder = Self {
|
||||
tester: Box::new(FixedUserTester::<WorkspaceError>::new()),
|
||||
user_detail: None,
|
||||
};
|
||||
|
||||
builder.login_if_need()
|
||||
INIT.call_once(|| builder.login_if_need());
|
||||
builder
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,7 +38,7 @@ impl UserTestBuilder {
|
||||
builder
|
||||
}
|
||||
|
||||
pub fn reset(mut self) -> Self { self.logout().login() }
|
||||
pub fn reset(mut self) -> Self { self.login() }
|
||||
}
|
||||
|
||||
pub struct TestBuilder<T: TesterTrait> {
|
||||
@ -54,14 +56,13 @@ where
|
||||
self
|
||||
}
|
||||
|
||||
pub fn login_if_need(mut self) -> Self {
|
||||
pub fn login_if_need(&mut self) {
|
||||
let user_detail = self.tester.login_if_need();
|
||||
self.user_detail = Some(user_detail);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn logout(self) -> Self {
|
||||
self.tester.logout();
|
||||
// self.tester.logout();
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,8 @@ pub enum UserErrorCode {
|
||||
UserWorkspaceInvalid = 23,
|
||||
#[display(fmt = "User id is invalid")]
|
||||
UserIdInvalid = 24,
|
||||
#[display(fmt = "Create user default workspace failed")]
|
||||
CreateDefaultWorkspaceFailed = 25,
|
||||
}
|
||||
|
||||
impl std::default::Default for UserErrorCode {
|
||||
@ -66,9 +68,38 @@ impl std::convert::From<flowy_database::result::Error> for UserError {
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
use diesel::result::DatabaseErrorKind;
|
||||
impl std::convert::From<flowy_sqlite::Error> for UserError {
|
||||
fn from(error: flowy_sqlite::Error) -> Self {
|
||||
// match error.kind() {
|
||||
// ErrorKind::Msg(_) => {},
|
||||
// ErrorKind::R2D2(_) => {},
|
||||
// ErrorKind::Migrations(_) => {},
|
||||
// ErrorKind::Diesel(diesel_err) => match diesel_err {
|
||||
// Error::InvalidCString(_) => {},
|
||||
// Error::DatabaseError(kind, _) => {
|
||||
// match kind {
|
||||
// DatabaseErrorKind::UniqueViolation => {
|
||||
//
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
//
|
||||
// },
|
||||
// Error::NotFound => {},
|
||||
// Error::QueryBuilderError(_) => {},
|
||||
// Error::DeserializationError(_) => {},
|
||||
// Error::SerializationError(_) => {},
|
||||
// Error::RollbackTransaction => {},
|
||||
// Error::AlreadyInTransaction => {},
|
||||
// Error::__Nonexhaustive => {},
|
||||
// },
|
||||
// ErrorKind::Connection(_) => {},
|
||||
// ErrorKind::Io(_) => {},
|
||||
// ErrorKind::UnknownMigrationExists(_) => {},
|
||||
// ErrorKind::__Nonexhaustive { .. } => {},
|
||||
// }
|
||||
|
||||
ErrorBuilder::new(UserErrorCode::UserDatabaseInternalError)
|
||||
.error(error)
|
||||
.build()
|
||||
|
@ -15,7 +15,7 @@ pub async fn user_sign_in_handler(
|
||||
session: ModuleData<Arc<UserSession>>,
|
||||
) -> ResponseResult<UserDetail, UserError> {
|
||||
let params: SignInParams = data.into_inner().try_into()?;
|
||||
let user = session.sign_in(params)?;
|
||||
let user = session.sign_in(params).await?;
|
||||
let user_detail = UserDetail::from(user);
|
||||
response_ok(user_detail)
|
||||
}
|
||||
@ -33,7 +33,7 @@ pub async fn user_sign_up_handler(
|
||||
session: ModuleData<Arc<UserSession>>,
|
||||
) -> ResponseResult<UserDetail, UserError> {
|
||||
let params: SignUpParams = data.into_inner().try_into()?;
|
||||
let user = session.sign_up(params)?;
|
||||
let user = session.sign_up(params).await?;
|
||||
let user_detail = UserDetail::from(user);
|
||||
response_ok(user_detail)
|
||||
}
|
||||
|
@ -229,6 +229,7 @@ pub enum UserErrorCode {
|
||||
UserNameInvalid = 22,
|
||||
UserWorkspaceInvalid = 23,
|
||||
UserIdInvalid = 24,
|
||||
CreateDefaultWorkspaceFailed = 25,
|
||||
}
|
||||
|
||||
impl ::protobuf::ProtobufEnum for UserErrorCode {
|
||||
@ -252,6 +253,7 @@ impl ::protobuf::ProtobufEnum for UserErrorCode {
|
||||
22 => ::std::option::Option::Some(UserErrorCode::UserNameInvalid),
|
||||
23 => ::std::option::Option::Some(UserErrorCode::UserWorkspaceInvalid),
|
||||
24 => ::std::option::Option::Some(UserErrorCode::UserIdInvalid),
|
||||
25 => ::std::option::Option::Some(UserErrorCode::CreateDefaultWorkspaceFailed),
|
||||
_ => ::std::option::Option::None
|
||||
}
|
||||
}
|
||||
@ -272,6 +274,7 @@ impl ::protobuf::ProtobufEnum for UserErrorCode {
|
||||
UserErrorCode::UserNameInvalid,
|
||||
UserErrorCode::UserWorkspaceInvalid,
|
||||
UserErrorCode::UserIdInvalid,
|
||||
UserErrorCode::CreateDefaultWorkspaceFailed,
|
||||
];
|
||||
values
|
||||
}
|
||||
@ -302,7 +305,7 @@ impl ::protobuf::reflect::ProtobufValue for UserErrorCode {
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x0cerrors.proto\"A\n\tUserError\x12\"\n\x04code\x18\x01\x20\x01(\x0e2\
|
||||
\x0e.UserErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03msg*\
|
||||
\xde\x02\n\rUserErrorCode\x12\x0b\n\x07Unknown\x10\0\x12\x1a\n\x16UserDa\
|
||||
\x80\x03\n\rUserErrorCode\x12\x0b\n\x07Unknown\x10\0\x12\x1a\n\x16UserDa\
|
||||
tabaseInitFailed\x10\x01\x12\x1b\n\x17UserDatabaseWriteLocked\x10\x02\
|
||||
\x12\x1a\n\x16UserDatabaseReadLocked\x10\x03\x12\x1b\n\x17UserDatabaseDi\
|
||||
dNotMatch\x10\x04\x12\x1d\n\x19UserDatabaseInternalError\x10\x05\x12\x13\
|
||||
@ -310,43 +313,46 @@ static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\x18\n\x14WriteCurrentIdFailed\x10\x0c\x12\x10\n\x0cEmailInvalid\x10\x14\
|
||||
\x12\x13\n\x0fPasswordInvalid\x10\x15\x12\x13\n\x0fUserNameInvalid\x10\
|
||||
\x16\x12\x18\n\x14UserWorkspaceInvalid\x10\x17\x12\x11\n\rUserIdInvalid\
|
||||
\x10\x18J\xee\x05\n\x06\x12\x04\0\0\x15\x01\n\x08\n\x01\x0c\x12\x03\0\0\
|
||||
\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\
|
||||
\x02\x08\x11\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x1b\n\x0c\n\x05\x04\
|
||||
\0\x02\0\x06\x12\x03\x03\x04\x11\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\
|
||||
\x12\x16\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x19\x1a\n\x0b\n\x04\x04\
|
||||
\0\x02\x01\x12\x03\x04\x04\x13\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\
|
||||
\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x0e\n\x0c\n\x05\x04\
|
||||
\0\x02\x01\x03\x12\x03\x04\x11\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x15\x01\
|
||||
\n\n\n\x03\x05\0\x01\x12\x03\x06\x05\x12\n\x0b\n\x04\x05\0\x02\0\x12\x03\
|
||||
\x07\x04\x10\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x07\x04\x0b\n\x0c\n\x05\
|
||||
\x05\0\x02\0\x02\x12\x03\x07\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\
|
||||
\x08\x04\x1f\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x08\x04\x1a\n\x0c\n\
|
||||
\x05\x05\0\x02\x01\x02\x12\x03\x08\x1d\x1e\n\x0b\n\x04\x05\0\x02\x02\x12\
|
||||
\x03\t\x04\x20\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\t\x04\x1b\n\x0c\n\
|
||||
\x05\x05\0\x02\x02\x02\x12\x03\t\x1e\x1f\n\x0b\n\x04\x05\0\x02\x03\x12\
|
||||
\x03\n\x04\x1f\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\n\x04\x1a\n\x0c\n\
|
||||
\x05\x05\0\x02\x03\x02\x12\x03\n\x1d\x1e\n\x0b\n\x04\x05\0\x02\x04\x12\
|
||||
\x03\x0b\x04\x20\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x0b\x04\x1b\n\x0c\
|
||||
\n\x05\x05\0\x02\x04\x02\x12\x03\x0b\x1e\x1f\n\x0b\n\x04\x05\0\x02\x05\
|
||||
\x12\x03\x0c\x04\"\n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x0c\x04\x1d\n\
|
||||
\x0c\n\x05\x05\0\x02\x05\x02\x12\x03\x0c\x20!\n\x0b\n\x04\x05\0\x02\x06\
|
||||
\x12\x03\r\x04\x19\n\x0c\n\x05\x05\0\x02\x06\x01\x12\x03\r\x04\x13\n\x0c\
|
||||
\n\x05\x05\0\x02\x06\x02\x12\x03\r\x16\x18\n\x0b\n\x04\x05\0\x02\x07\x12\
|
||||
\x03\x0e\x04\x1d\n\x0c\n\x05\x05\0\x02\x07\x01\x12\x03\x0e\x04\x17\n\x0c\
|
||||
\n\x05\x05\0\x02\x07\x02\x12\x03\x0e\x1a\x1c\n\x0b\n\x04\x05\0\x02\x08\
|
||||
\x12\x03\x0f\x04\x1e\n\x0c\n\x05\x05\0\x02\x08\x01\x12\x03\x0f\x04\x18\n\
|
||||
\x0c\n\x05\x05\0\x02\x08\x02\x12\x03\x0f\x1b\x1d\n\x0b\n\x04\x05\0\x02\t\
|
||||
\x12\x03\x10\x04\x16\n\x0c\n\x05\x05\0\x02\t\x01\x12\x03\x10\x04\x10\n\
|
||||
\x0c\n\x05\x05\0\x02\t\x02\x12\x03\x10\x13\x15\n\x0b\n\x04\x05\0\x02\n\
|
||||
\x12\x03\x11\x04\x19\n\x0c\n\x05\x05\0\x02\n\x01\x12\x03\x11\x04\x13\n\
|
||||
\x0c\n\x05\x05\0\x02\n\x02\x12\x03\x11\x16\x18\n\x0b\n\x04\x05\0\x02\x0b\
|
||||
\x12\x03\x12\x04\x19\n\x0c\n\x05\x05\0\x02\x0b\x01\x12\x03\x12\x04\x13\n\
|
||||
\x0c\n\x05\x05\0\x02\x0b\x02\x12\x03\x12\x16\x18\n\x0b\n\x04\x05\0\x02\
|
||||
\x0c\x12\x03\x13\x04\x1e\n\x0c\n\x05\x05\0\x02\x0c\x01\x12\x03\x13\x04\
|
||||
\x18\n\x0c\n\x05\x05\0\x02\x0c\x02\x12\x03\x13\x1b\x1d\n\x0b\n\x04\x05\0\
|
||||
\x02\r\x12\x03\x14\x04\x17\n\x0c\n\x05\x05\0\x02\r\x01\x12\x03\x14\x04\
|
||||
\x11\n\x0c\n\x05\x05\0\x02\r\x02\x12\x03\x14\x14\x16b\x06proto3\
|
||||
\x10\x18\x12\x20\n\x1cCreateDefaultWorkspaceFailed\x10\x19J\x97\x06\n\
|
||||
\x06\x12\x04\0\0\x16\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\
|
||||
\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x11\n\x0b\n\
|
||||
\x04\x04\0\x02\0\x12\x03\x03\x04\x1b\n\x0c\n\x05\x04\0\x02\0\x06\x12\x03\
|
||||
\x03\x04\x11\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x12\x16\n\x0c\n\x05\
|
||||
\x04\0\x02\0\x03\x12\x03\x03\x19\x1a\n\x0b\n\x04\x04\0\x02\x01\x12\x03\
|
||||
\x04\x04\x13\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\
|
||||
\x04\0\x02\x01\x01\x12\x03\x04\x0b\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\
|
||||
\x03\x04\x11\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x16\x01\n\n\n\x03\x05\0\
|
||||
\x01\x12\x03\x06\x05\x12\n\x0b\n\x04\x05\0\x02\0\x12\x03\x07\x04\x10\n\
|
||||
\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x07\x04\x0b\n\x0c\n\x05\x05\0\x02\0\
|
||||
\x02\x12\x03\x07\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x08\x04\x1f\n\
|
||||
\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x08\x04\x1a\n\x0c\n\x05\x05\0\x02\
|
||||
\x01\x02\x12\x03\x08\x1d\x1e\n\x0b\n\x04\x05\0\x02\x02\x12\x03\t\x04\x20\
|
||||
\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\t\x04\x1b\n\x0c\n\x05\x05\0\x02\
|
||||
\x02\x02\x12\x03\t\x1e\x1f\n\x0b\n\x04\x05\0\x02\x03\x12\x03\n\x04\x1f\n\
|
||||
\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\n\x04\x1a\n\x0c\n\x05\x05\0\x02\x03\
|
||||
\x02\x12\x03\n\x1d\x1e\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x0b\x04\x20\n\
|
||||
\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x0b\x04\x1b\n\x0c\n\x05\x05\0\x02\
|
||||
\x04\x02\x12\x03\x0b\x1e\x1f\n\x0b\n\x04\x05\0\x02\x05\x12\x03\x0c\x04\"\
|
||||
\n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x0c\x04\x1d\n\x0c\n\x05\x05\0\x02\
|
||||
\x05\x02\x12\x03\x0c\x20!\n\x0b\n\x04\x05\0\x02\x06\x12\x03\r\x04\x19\n\
|
||||
\x0c\n\x05\x05\0\x02\x06\x01\x12\x03\r\x04\x13\n\x0c\n\x05\x05\0\x02\x06\
|
||||
\x02\x12\x03\r\x16\x18\n\x0b\n\x04\x05\0\x02\x07\x12\x03\x0e\x04\x1d\n\
|
||||
\x0c\n\x05\x05\0\x02\x07\x01\x12\x03\x0e\x04\x17\n\x0c\n\x05\x05\0\x02\
|
||||
\x07\x02\x12\x03\x0e\x1a\x1c\n\x0b\n\x04\x05\0\x02\x08\x12\x03\x0f\x04\
|
||||
\x1e\n\x0c\n\x05\x05\0\x02\x08\x01\x12\x03\x0f\x04\x18\n\x0c\n\x05\x05\0\
|
||||
\x02\x08\x02\x12\x03\x0f\x1b\x1d\n\x0b\n\x04\x05\0\x02\t\x12\x03\x10\x04\
|
||||
\x16\n\x0c\n\x05\x05\0\x02\t\x01\x12\x03\x10\x04\x10\n\x0c\n\x05\x05\0\
|
||||
\x02\t\x02\x12\x03\x10\x13\x15\n\x0b\n\x04\x05\0\x02\n\x12\x03\x11\x04\
|
||||
\x19\n\x0c\n\x05\x05\0\x02\n\x01\x12\x03\x11\x04\x13\n\x0c\n\x05\x05\0\
|
||||
\x02\n\x02\x12\x03\x11\x16\x18\n\x0b\n\x04\x05\0\x02\x0b\x12\x03\x12\x04\
|
||||
\x19\n\x0c\n\x05\x05\0\x02\x0b\x01\x12\x03\x12\x04\x13\n\x0c\n\x05\x05\0\
|
||||
\x02\x0b\x02\x12\x03\x12\x16\x18\n\x0b\n\x04\x05\0\x02\x0c\x12\x03\x13\
|
||||
\x04\x1e\n\x0c\n\x05\x05\0\x02\x0c\x01\x12\x03\x13\x04\x18\n\x0c\n\x05\
|
||||
\x05\0\x02\x0c\x02\x12\x03\x13\x1b\x1d\n\x0b\n\x04\x05\0\x02\r\x12\x03\
|
||||
\x14\x04\x17\n\x0c\n\x05\x05\0\x02\r\x01\x12\x03\x14\x04\x11\n\x0c\n\x05\
|
||||
\x05\0\x02\r\x02\x12\x03\x14\x14\x16\n\x0b\n\x04\x05\0\x02\x0e\x12\x03\
|
||||
\x15\x04&\n\x0c\n\x05\x05\0\x02\x0e\x01\x12\x03\x15\x04\x20\n\x0c\n\x05\
|
||||
\x05\0\x02\x0e\x02\x12\x03\x15#%b\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -19,4 +19,5 @@ enum UserErrorCode {
|
||||
UserNameInvalid = 22;
|
||||
UserWorkspaceInvalid = 23;
|
||||
UserIdInvalid = 24;
|
||||
CreateDefaultWorkspaceFailed = 25;
|
||||
}
|
||||
|
@ -3,10 +3,21 @@ use crate::{
|
||||
errors::UserError,
|
||||
sql_tables::UserTable,
|
||||
};
|
||||
use flowy_dispatch::prelude::DispatchFuture;
|
||||
|
||||
pub trait UserServer {
|
||||
fn sign_up(&self, params: SignUpParams) -> Result<UserTable, UserError>;
|
||||
|
||||
fn sign_in(&self, params: SignInParams) -> Result<UserTable, UserError>;
|
||||
fn get_user_info(&self, user_id: &str) -> Result<UserDetail, UserError>;
|
||||
|
||||
fn sign_out(&self, user_id: &str) -> Result<(), UserError>;
|
||||
|
||||
fn get_user_info(&self, user_id: &str) -> Result<UserDetail, UserError>;
|
||||
|
||||
fn create_workspace(
|
||||
&self,
|
||||
name: &str,
|
||||
desc: &str,
|
||||
user_id: &str,
|
||||
) -> DispatchFuture<Result<(), UserError>>;
|
||||
}
|
||||
|
@ -18,6 +18,10 @@ use crate::{
|
||||
};
|
||||
use flowy_dispatch::prelude::{EventDispatch, ModuleRequest, ToBytes};
|
||||
|
||||
const DEFAULT_WORKSPACE_NAME: &'static str = "My workspace";
|
||||
const DEFAULT_WORKSPACE_DESC: &'static str = "This is your first workspace";
|
||||
const DEFAULT_WORKSPACE: &'static str = "Default_Workspace";
|
||||
|
||||
pub struct UserSessionConfig {
|
||||
root_dir: String,
|
||||
}
|
||||
@ -56,17 +60,25 @@ impl UserSession {
|
||||
self.database.get_connection(&user_id)
|
||||
}
|
||||
|
||||
pub fn sign_in(&self, params: SignInParams) -> Result<UserTable, UserError> {
|
||||
pub async fn sign_in(&self, params: SignInParams) -> Result<UserTable, UserError> {
|
||||
let user = self.server.sign_in(params)?;
|
||||
let _ = self.set_user_id(Some(user.id.clone()))?;
|
||||
|
||||
self.save_user(user)
|
||||
let user_table = self.save_user(user)?;
|
||||
let _ = self
|
||||
.create_default_workspace_if_need(&user_table.id)
|
||||
.await?;
|
||||
Ok(user_table)
|
||||
}
|
||||
|
||||
pub fn sign_up(&self, params: SignUpParams) -> Result<UserTable, UserError> {
|
||||
pub async fn sign_up(&self, params: SignUpParams) -> Result<UserTable, UserError> {
|
||||
let user = self.server.sign_up(params)?;
|
||||
let _ = self.set_user_id(Some(user.id.clone()))?;
|
||||
self.save_user(user)
|
||||
let user_table = self.save_user(user)?;
|
||||
let _ = self
|
||||
.create_default_workspace_if_need(&user_table.id)
|
||||
.await?;
|
||||
Ok(user_table)
|
||||
}
|
||||
|
||||
pub fn sign_out(&self) -> Result<(), UserError> {
|
||||
@ -147,7 +159,7 @@ impl UserSession {
|
||||
|
||||
if user_id.is_none() {
|
||||
user_id = KVStore::get_str(USER_ID_CACHE_KEY);
|
||||
self.set_user_id(user_id.clone());
|
||||
let _ = self.set_user_id(user_id.clone())?;
|
||||
}
|
||||
|
||||
match user_id {
|
||||
@ -170,6 +182,21 @@ impl UserSession {
|
||||
.unwrap()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn create_default_workspace_if_need(&self, user_id: &str) -> Result<(), UserError> {
|
||||
let key = format!("{}{}", user_id, DEFAULT_WORKSPACE);
|
||||
if KVStore::get_bool(&key).unwrap_or(false) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
KVStore::set_bool(&key, true);
|
||||
log::debug!("Create user:{} default workspace", user_id);
|
||||
let _ = self
|
||||
.server
|
||||
.create_workspace(DEFAULT_WORKSPACE_NAME, DEFAULT_WORKSPACE_DESC, user_id)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn current_user_id() -> Result<String, UserError> {
|
||||
|
@ -5,7 +5,6 @@ use serial_test::*;
|
||||
#[test]
|
||||
#[serial]
|
||||
fn sign_up_success() {
|
||||
let _ = UserTestBuilder::new().event(SignOut).sync_send();
|
||||
let request = SignUpRequest {
|
||||
email: random_valid_email(),
|
||||
name: valid_name(),
|
||||
@ -17,8 +16,6 @@ fn sign_up_success() {
|
||||
.event(SignUp)
|
||||
.request(request)
|
||||
.sync_send();
|
||||
// .parse::<SignUpResponse>();
|
||||
// dbg!(&response);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -3,14 +3,13 @@ use flowy_user::{event::UserEvent::*, prelude::*};
|
||||
use serial_test::*;
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[serial]
|
||||
fn user_status_get_failed_before_login() {
|
||||
let _ = UserTestBuilder::new()
|
||||
let a = UserTestBuilder::new()
|
||||
.logout()
|
||||
.event(GetStatus)
|
||||
.sync_send()
|
||||
.parse::<UserDetail>();
|
||||
.assert_error()
|
||||
.sync_send();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -11,4 +11,8 @@ pub enum WorkspaceEvent {
|
||||
#[display(fmt = "Get user's workspace detail")]
|
||||
#[event(output = "UserWorkspaceDetail")]
|
||||
GetWorkspaceDetail = 1,
|
||||
|
||||
#[display(fmt = "Create app")]
|
||||
#[event(input = "CreateAppRequest", output = "AppDetail")]
|
||||
CreateApp = 101,
|
||||
}
|
||||
|
@ -26,4 +26,5 @@ pub fn create(user: Arc<dyn WorkspaceUser>) -> Module {
|
||||
.data(app_controller)
|
||||
.event(WorkspaceEvent::CreateWorkspace, create_workspace)
|
||||
.event(WorkspaceEvent::GetWorkspaceDetail, get_workspace_detail)
|
||||
.event(WorkspaceEvent::CreateApp, create_app)
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
pub enum WorkspaceEvent {
|
||||
CreateWorkspace = 0,
|
||||
GetWorkspaceDetail = 1,
|
||||
CreateApp = 101,
|
||||
}
|
||||
|
||||
impl ::protobuf::ProtobufEnum for WorkspaceEvent {
|
||||
@ -38,6 +39,7 @@ impl ::protobuf::ProtobufEnum for WorkspaceEvent {
|
||||
match value {
|
||||
0 => ::std::option::Option::Some(WorkspaceEvent::CreateWorkspace),
|
||||
1 => ::std::option::Option::Some(WorkspaceEvent::GetWorkspaceDetail),
|
||||
101 => ::std::option::Option::Some(WorkspaceEvent::CreateApp),
|
||||
_ => ::std::option::Option::None
|
||||
}
|
||||
}
|
||||
@ -46,6 +48,7 @@ impl ::protobuf::ProtobufEnum for WorkspaceEvent {
|
||||
static values: &'static [WorkspaceEvent] = &[
|
||||
WorkspaceEvent::CreateWorkspace,
|
||||
WorkspaceEvent::GetWorkspaceDetail,
|
||||
WorkspaceEvent::CreateApp,
|
||||
];
|
||||
values
|
||||
}
|
||||
@ -74,14 +77,17 @@ impl ::protobuf::reflect::ProtobufValue for WorkspaceEvent {
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x0bevent.proto*=\n\x0eWorkspaceEvent\x12\x13\n\x0fCreateWorkspace\x10\
|
||||
\0\x12\x16\n\x12GetWorkspaceDetail\x10\x01J|\n\x06\x12\x04\0\0\x05\x01\n\
|
||||
\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\x04\x02\0\x05\x01\n\n\
|
||||
\n\x03\x05\0\x01\x12\x03\x02\x05\x13\n\x0b\n\x04\x05\0\x02\0\x12\x03\x03\
|
||||
\x04\x18\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x03\x04\x13\n\x0c\n\x05\x05\
|
||||
\0\x02\0\x02\x12\x03\x03\x16\x17\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\
|
||||
\x04\x1b\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x04\x04\x16\n\x0c\n\x05\
|
||||
\x05\0\x02\x01\x02\x12\x03\x04\x19\x1ab\x06proto3\
|
||||
\n\x0bevent.proto*L\n\x0eWorkspaceEvent\x12\x13\n\x0fCreateWorkspace\x10\
|
||||
\0\x12\x16\n\x12GetWorkspaceDetail\x10\x01\x12\r\n\tCreateApp\x10eJ\xa5\
|
||||
\x01\n\x06\x12\x04\0\0\x06\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
|
||||
\x05\0\x12\x04\x02\0\x06\x01\n\n\n\x03\x05\0\x01\x12\x03\x02\x05\x13\n\
|
||||
\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x04\x18\n\x0c\n\x05\x05\0\x02\0\x01\
|
||||
\x12\x03\x03\x04\x13\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x03\x16\x17\n\
|
||||
\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\x04\x1b\n\x0c\n\x05\x05\0\x02\x01\
|
||||
\x01\x12\x03\x04\x04\x16\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x04\x19\
|
||||
\x1a\n\x0b\n\x04\x05\0\x02\x02\x12\x03\x05\x04\x14\n\x0c\n\x05\x05\0\x02\
|
||||
\x02\x01\x12\x03\x05\x04\r\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\x05\x10\
|
||||
\x13b\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -3,4 +3,5 @@ syntax = "proto3";
|
||||
enum WorkspaceEvent {
|
||||
CreateWorkspace = 0;
|
||||
GetWorkspaceDetail = 1;
|
||||
CreateApp = 101;
|
||||
}
|
||||
|
@ -1,15 +1,33 @@
|
||||
// #[test]
|
||||
// fn app_create_success() {
|
||||
// let request = CreateAppRequest {
|
||||
// workspace_id: "".to_string(),
|
||||
// name: "123".to_owned(),
|
||||
// desc: "".to_owned(),
|
||||
// color_style: Default::default(),
|
||||
// };
|
||||
//
|
||||
// let response = WorkspaceEventTester::new(CreateWorkspace)
|
||||
// .request(request)
|
||||
// .sync_send()
|
||||
// .parse::<WorkspaceDetail>();
|
||||
// dbg!(&response);
|
||||
// }
|
||||
use flowy_test::builder::WorkspaceTestBuilder;
|
||||
use flowy_workspace::{
|
||||
entities::{
|
||||
app::{AppDetail, CreateAppRequest},
|
||||
workspace::UserWorkspaceDetail,
|
||||
},
|
||||
event::WorkspaceEvent::{CreateApp, GetWorkspaceDetail},
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn app_create_success() {
|
||||
let user_workspace = WorkspaceTestBuilder::new()
|
||||
.event(GetWorkspaceDetail)
|
||||
.sync_send()
|
||||
.parse::<UserWorkspaceDetail>();
|
||||
|
||||
let request = CreateAppRequest {
|
||||
workspace_id: user_workspace.workspace.id,
|
||||
name: "Github".to_owned(),
|
||||
desc: "AppFlowy Github Project".to_owned(),
|
||||
color_style: Default::default(),
|
||||
};
|
||||
|
||||
let app_detail = WorkspaceTestBuilder::new()
|
||||
.event(CreateApp)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.parse::<AppDetail>();
|
||||
|
||||
dbg!(&app_detail);
|
||||
}
|
||||
|
||||
// TODO 1) test update app 2) delete app
|
||||
|
@ -22,6 +22,16 @@ fn workspace_create_success() {
|
||||
|
||||
#[test]
|
||||
fn workspace_get_detail_success() {
|
||||
let user_workspace = WorkspaceTestBuilder::new()
|
||||
.event(GetWorkspaceDetail)
|
||||
.sync_send()
|
||||
.parse::<UserWorkspaceDetail>();
|
||||
|
||||
dbg!(&user_workspace);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn workspace_create_and_then_get_detail_success() {
|
||||
let request = CreateWorkspaceRequest {
|
||||
name: "Team A".to_owned(),
|
||||
desc: "Team A Description".to_owned(),
|
||||
@ -61,21 +71,24 @@ fn workspace_create_with_invalid_name_test() {
|
||||
}
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn workspace_update_with_invalid_name_test() {
|
||||
// for name in invalid_workspace_name_test_case() {
|
||||
// let request = CreateWorkspaceRequest {
|
||||
// name,
|
||||
// desc: "".to_owned(),
|
||||
// };
|
||||
//
|
||||
// assert_eq!(
|
||||
// WorkspaceEventTester::new(CreateWorkspace)
|
||||
// .request(request)
|
||||
// .sync_send()
|
||||
// .error()
|
||||
// .code,
|
||||
// WorkspaceErrorCode::WorkspaceNameInvalid
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
#[test]
|
||||
fn workspace_update_with_invalid_name_test() {
|
||||
for name in invalid_workspace_name_test_case() {
|
||||
let request = CreateWorkspaceRequest {
|
||||
name,
|
||||
desc: "".to_owned(),
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
WorkspaceTestBuilder::new()
|
||||
.event(CreateWorkspace)
|
||||
.request(request)
|
||||
.sync_send()
|
||||
.error()
|
||||
.code,
|
||||
WorkspaceErrorCode::WorkspaceNameInvalid
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 1) delete workspace, but can't delete the last workspace
|
||||
|
Loading…
Reference in New Issue
Block a user