mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
add test builder
This commit is contained in:
parent
182adafee5
commit
e767cc3a01
@ -1,10 +1,7 @@
|
|||||||
mod flowy_server;
|
mod flowy_server;
|
||||||
pub mod module;
|
pub mod module;
|
||||||
|
|
||||||
use crate::{
|
use crate::flowy_server::{ArcFlowyServer, MockFlowyServer};
|
||||||
flowy_server::{ArcFlowyServer, MockFlowyServer},
|
|
||||||
user_server::MockUserServer,
|
|
||||||
};
|
|
||||||
use flowy_dispatch::prelude::*;
|
use flowy_dispatch::prelude::*;
|
||||||
use module::build_modules;
|
use module::build_modules;
|
||||||
pub use module::*;
|
pub use module::*;
|
||||||
@ -32,7 +29,7 @@ impl FlowySDK {
|
|||||||
FlowySDK::init_log(&self.root);
|
FlowySDK::init_log(&self.root);
|
||||||
|
|
||||||
tracing::info!("🔥 Root path: {}", self.root);
|
tracing::info!("🔥 Root path: {}", self.root);
|
||||||
flowy_infra::kv::KVStore::init(path);
|
flowy_infra::kv::KVStore::init(&self.root);
|
||||||
FlowySDK::init_modules(&self.root, self.server);
|
FlowySDK::init_modules(&self.root, self.server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use flowy_dispatch::prelude::Module;
|
use flowy_dispatch::prelude::Module;
|
||||||
use flowy_user::prelude::*;
|
use flowy_user::prelude::*;
|
||||||
|
|
||||||
use crate::{flowy_server::ArcFlowyServer, user_server::MockUserServer};
|
use crate::flowy_server::{ArcFlowyServer, MockFlowyServer};
|
||||||
use flowy_database::DBConnection;
|
use flowy_database::DBConnection;
|
||||||
use flowy_user::errors::UserError;
|
use flowy_user::errors::UserError;
|
||||||
use flowy_workspace::prelude::*;
|
use flowy_workspace::prelude::*;
|
||||||
@ -15,7 +15,7 @@ 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)
|
||||||
.build(config.server),
|
.build(Arc::new(MockFlowyServer {})),
|
||||||
);
|
);
|
||||||
|
|
||||||
let workspace_user_impl = Arc::new(WorkspaceUserImpl {
|
let workspace_user_impl = Arc::new(WorkspaceUserImpl {
|
||||||
|
@ -8,6 +8,7 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
flowy-sdk = { path = "../flowy-sdk"}
|
flowy-sdk = { path = "../flowy-sdk"}
|
||||||
flowy-dispatch = { path = "../flowy-dispatch"}
|
flowy-dispatch = { path = "../flowy-dispatch"}
|
||||||
|
flowy-user = { path = "../flowy-user"}
|
||||||
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
bincode = { version = "1.3"}
|
bincode = { version = "1.3"}
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
use flowy_dispatch::prelude::*;
|
use flowy_dispatch::prelude::*;
|
||||||
pub use flowy_sdk::*;
|
pub use flowy_sdk::*;
|
||||||
|
use flowy_user::{
|
||||||
|
errors::UserError,
|
||||||
|
event::UserEvent::{SignIn, SignOut},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
use std::{
|
use std::{
|
||||||
convert::TryFrom,
|
convert::TryFrom,
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
@ -12,7 +17,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::EventTester;
|
pub use crate::Tester;
|
||||||
pub use flowy_dispatch::prelude::*;
|
pub use flowy_dispatch::prelude::*;
|
||||||
pub use std::convert::TryFrom;
|
pub use std::convert::TryFrom;
|
||||||
}
|
}
|
||||||
@ -42,18 +47,82 @@ fn root_dir() -> String {
|
|||||||
root_dir
|
root_dir
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TesterConfig {
|
pub struct TestBuilder<Error> {
|
||||||
fn auto_sign_in() -> bool { false }
|
login: Option<bool>,
|
||||||
|
inner: Option<Tester<Error>>,
|
||||||
|
pub user_detail: Option<UserDetail>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventTester<Error> {
|
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 struct Tester<Error> {
|
||||||
inner_request: Option<ModuleRequest>,
|
inner_request: Option<ModuleRequest>,
|
||||||
assert_status_code: Option<StatusCode>,
|
assert_status_code: Option<StatusCode>,
|
||||||
response: Option<EventResponse>,
|
response: Option<EventResponse>,
|
||||||
err_phantom: PhantomData<Error>,
|
err_phantom: PhantomData<Error>,
|
||||||
|
user_detail: Option<UserDetail>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Error> EventTester<Error>
|
impl<Error> Tester<Error>
|
||||||
where
|
where
|
||||||
Error: FromBytes + Debug,
|
Error: FromBytes + Debug,
|
||||||
{
|
{
|
||||||
@ -73,6 +142,7 @@ where
|
|||||||
assert_status_code: None,
|
assert_status_code: None,
|
||||||
response: None,
|
response: None,
|
||||||
err_phantom: PhantomData,
|
err_phantom: PhantomData,
|
||||||
|
user_detail: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +167,6 @@ where
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub async fn async_send(mut self) -> Self {
|
pub async fn async_send(mut self) -> Self {
|
||||||
let resp =
|
let resp =
|
||||||
EventDispatch::async_send(self.inner_request.take().unwrap(), |_| Box::pin(async {}))
|
EventDispatch::async_send(self.inner_request.take().unwrap(), |_| Box::pin(async {}))
|
||||||
@ -148,3 +217,23 @@ fn check(response: &EventResponse, status_code: &Option<StatusCode>) {
|
|||||||
assert_eq!(&response.status_code, status_code)
|
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() }
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::services::user_session::{user_server::UserServer, UserSession, UserSessionConfig};
|
use crate::services::user_session::{user_server::UserServer, UserSession, UserSessionConfig};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct UserSessionBuilder {
|
pub struct UserSessionBuilder {
|
||||||
config: Option<UserSessionConfig>,
|
config: Option<UserSessionConfig>,
|
||||||
@ -12,7 +13,7 @@ impl UserSessionBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build<S>(mut self, server: S) -> UserSession
|
pub fn build<S>(mut self, server: Arc<S>) -> UserSession
|
||||||
where
|
where
|
||||||
S: 'static + UserServer + Send + Sync,
|
S: 'static + UserServer + Send + Sync,
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ use flowy_database::{
|
|||||||
};
|
};
|
||||||
use flowy_infra::kv::KVStore;
|
use flowy_infra::kv::KVStore;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use std::sync::RwLock;
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
entities::{SignInParams, SignUpParams, UpdateUserParams, UserDetail},
|
entities::{SignInParams, SignUpParams, UpdateUserParams, UserDetail},
|
||||||
@ -31,11 +31,11 @@ impl UserSessionConfig {
|
|||||||
pub struct UserSession {
|
pub struct UserSession {
|
||||||
database: UserDB,
|
database: UserDB,
|
||||||
config: UserSessionConfig,
|
config: UserSessionConfig,
|
||||||
server: Box<dyn UserServer + Send + Sync>,
|
server: Arc<dyn UserServer + Send + Sync>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserSession {
|
impl UserSession {
|
||||||
pub fn new<R>(config: UserSessionConfig, server: R) -> Self
|
pub fn new<R>(config: UserSessionConfig, server: Arc<R>) -> Self
|
||||||
where
|
where
|
||||||
R: 'static + UserServer + Send + Sync,
|
R: 'static + UserServer + Send + Sync,
|
||||||
{
|
{
|
||||||
@ -43,7 +43,7 @@ impl UserSession {
|
|||||||
Self {
|
Self {
|
||||||
database: db,
|
database: db,
|
||||||
config,
|
config,
|
||||||
server: Box::new(server),
|
server,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use flowy_test::{EventTester, TesterConfig};
|
use flowy_test::{TestBuilder, Tester};
|
||||||
use flowy_user::errors::UserError;
|
use flowy_user::errors::UserError;
|
||||||
|
|
||||||
pub type UserEventTester = EventTester<UserError, TesterConfig>;
|
pub type UserTestBuilder = TestBuilder<UserError>;
|
||||||
|
|
||||||
pub(crate) fn invalid_email_test_case() -> Vec<String> {
|
pub(crate) fn invalid_email_test_case() -> Vec<String> {
|
||||||
// https://gist.github.com/cjaoude/fd9910626629b53c4d25
|
// https://gist.github.com/cjaoude/fd9910626629b53c4d25
|
||||||
|
@ -6,13 +6,14 @@ use serial_test::*;
|
|||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
fn sign_in_success() {
|
fn sign_in_success() {
|
||||||
let _ = UserEventTester::new(SignOut).sync_send();
|
|
||||||
let request = SignInRequest {
|
let request = SignInRequest {
|
||||||
email: valid_email(),
|
email: valid_email(),
|
||||||
password: valid_password(),
|
password: valid_password(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = UserEventTester::new(SignIn)
|
let response = UserTestBuilder::new()
|
||||||
|
.logout()
|
||||||
|
.event(SignIn)
|
||||||
.request(request)
|
.request(request)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.parse::<UserDetail>();
|
.parse::<UserDetail>();
|
||||||
@ -28,7 +29,8 @@ fn sign_in_with_invalid_email() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
UserEventTester::new(SignIn)
|
UserTestBuilder::new()
|
||||||
|
.event(SignIn)
|
||||||
.request(request)
|
.request(request)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.error()
|
.error()
|
||||||
@ -47,7 +49,8 @@ fn sign_in_with_invalid_password() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
UserEventTester::new(SignIn)
|
UserTestBuilder::new()
|
||||||
|
.event(SignIn)
|
||||||
.request(request)
|
.request(request)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.error()
|
.error()
|
||||||
|
@ -6,14 +6,17 @@ use serial_test::*;
|
|||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
fn sign_up_success() {
|
fn sign_up_success() {
|
||||||
let _ = UserEventTester::new(SignOut).sync_send();
|
let _ = UserTestBuilder::new().event(SignOut).sync_send();
|
||||||
let request = SignUpRequest {
|
let request = SignUpRequest {
|
||||||
email: valid_email(),
|
email: valid_email(),
|
||||||
name: valid_name(),
|
name: valid_name(),
|
||||||
password: valid_password(),
|
password: valid_password(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let _response = UserEventTester::new(SignUp).request(request).sync_send();
|
let _response = UserTestBuilder::new()
|
||||||
|
.event(SignUp)
|
||||||
|
.request(request)
|
||||||
|
.sync_send();
|
||||||
// .parse::<SignUpResponse>();
|
// .parse::<SignUpResponse>();
|
||||||
// dbg!(&response);
|
// dbg!(&response);
|
||||||
}
|
}
|
||||||
@ -28,7 +31,8 @@ fn sign_up_with_invalid_email() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
UserEventTester::new(SignUp)
|
UserTestBuilder::new()
|
||||||
|
.event(SignUp)
|
||||||
.request(request)
|
.request(request)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.error()
|
.error()
|
||||||
@ -47,7 +51,8 @@ fn sign_up_with_invalid_password() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
UserEventTester::new(SignUp)
|
UserTestBuilder::new()
|
||||||
|
.event(SignUp)
|
||||||
.request(request)
|
.request(request)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.error()
|
.error()
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::helper::*;
|
use crate::helper::*;
|
||||||
|
|
||||||
use flowy_user::{errors::UserErrorCode, event::UserEvent::*, prelude::*};
|
use flowy_user::{errors::UserErrorCode, event::UserEvent::*, prelude::*};
|
||||||
use serial_test::*;
|
use serial_test::*;
|
||||||
|
|
||||||
@ -7,8 +6,9 @@ use serial_test::*;
|
|||||||
#[should_panic]
|
#[should_panic]
|
||||||
#[serial]
|
#[serial]
|
||||||
fn user_status_not_found_before_login() {
|
fn user_status_not_found_before_login() {
|
||||||
let _ = UserEventTester::new(SignOut).sync_send();
|
let _ = UserTestBuilder::new()
|
||||||
let _ = UserEventTester::new(GetStatus)
|
.logout()
|
||||||
|
.event(GetStatus)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.parse::<UserDetail>();
|
.parse::<UserDetail>();
|
||||||
}
|
}
|
||||||
@ -16,19 +16,21 @@ fn user_status_not_found_before_login() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
fn user_status_did_found_after_login() {
|
fn user_status_did_found_after_login() {
|
||||||
let _ = UserEventTester::new(SignOut).sync_send();
|
|
||||||
let request = SignInRequest {
|
let request = SignInRequest {
|
||||||
email: valid_email(),
|
email: valid_email(),
|
||||||
password: valid_password(),
|
password: valid_password(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = UserEventTester::new(SignIn)
|
let response = UserTestBuilder::new()
|
||||||
|
.logout()
|
||||||
|
.event(SignIn)
|
||||||
.request(request)
|
.request(request)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.parse::<UserDetail>();
|
.parse::<UserDetail>();
|
||||||
dbg!(&response);
|
dbg!(&response);
|
||||||
|
|
||||||
let _ = UserEventTester::new(GetStatus)
|
let _ = UserTestBuilder::new()
|
||||||
|
.event(GetStatus)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.parse::<UserDetail>();
|
.parse::<UserDetail>();
|
||||||
}
|
}
|
||||||
@ -36,20 +38,7 @@ fn user_status_did_found_after_login() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
fn user_update_with_invalid_email() {
|
fn user_update_with_invalid_email() {
|
||||||
let _ = UserEventTester::new(SignOut).sync_send();
|
let user_detail = UserTestBuilder::new().login().user_detail.unwrap();
|
||||||
let request = SignInRequest {
|
|
||||||
email: valid_email(),
|
|
||||||
password: valid_password(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let _ = UserEventTester::new(SignIn)
|
|
||||||
.request(request)
|
|
||||||
.sync_send()
|
|
||||||
.parse::<UserDetail>();
|
|
||||||
|
|
||||||
let user_detail = UserEventTester::new(GetStatus)
|
|
||||||
.sync_send()
|
|
||||||
.parse::<UserDetail>();
|
|
||||||
|
|
||||||
for email in invalid_email_test_case() {
|
for email in invalid_email_test_case() {
|
||||||
let request = UpdateUserRequest {
|
let request = UpdateUserRequest {
|
||||||
@ -61,7 +50,8 @@ fn user_update_with_invalid_email() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
UserEventTester::new(UpdateUser)
|
UserTestBuilder::new()
|
||||||
|
.event(UpdateUser)
|
||||||
.request(request)
|
.request(request)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.error()
|
.error()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use flowy_test::EventTester;
|
use flowy_test::TestBuilder;
|
||||||
use flowy_workspace::errors::WorkspaceError;
|
use flowy_workspace::errors::WorkspaceError;
|
||||||
|
|
||||||
pub type WorkspaceEventTester = EventTester<WorkspaceError>;
|
pub type WorkspaceTestBuilder = TestBuilder<WorkspaceError>;
|
||||||
|
|
||||||
pub(crate) fn invalid_workspace_name_test_case() -> Vec<String> {
|
pub(crate) fn invalid_workspace_name_test_case() -> Vec<String> {
|
||||||
vec!["", "1234".repeat(100).as_str()]
|
vec!["", "1234".repeat(100).as_str()]
|
||||||
|
@ -12,7 +12,8 @@ fn workspace_create_success() {
|
|||||||
desc: "".to_owned(),
|
desc: "".to_owned(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = WorkspaceEventTester::new(CreateWorkspace)
|
let response = WorkspaceTestBuilder::new()
|
||||||
|
.event(CreateWorkspace)
|
||||||
.request(request)
|
.request(request)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.parse::<WorkspaceDetail>();
|
.parse::<WorkspaceDetail>();
|
||||||
@ -28,7 +29,8 @@ fn workspace_create_with_invalid_name_test() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
WorkspaceEventTester::new(CreateWorkspace)
|
WorkspaceTestBuilder::new()
|
||||||
|
.event(CreateWorkspace)
|
||||||
.request(request)
|
.request(request)
|
||||||
.sync_send()
|
.sync_send()
|
||||||
.error()
|
.error()
|
||||||
|
Loading…
Reference in New Issue
Block a user