add test builder

This commit is contained in:
appflowy 2021-07-14 23:00:58 +08:00
parent 182adafee5
commit e767cc3a01
12 changed files with 141 additions and 53 deletions

View File

@ -1,10 +1,7 @@
mod flowy_server;
pub mod module;
use crate::{
flowy_server::{ArcFlowyServer, MockFlowyServer},
user_server::MockUserServer,
};
use crate::flowy_server::{ArcFlowyServer, MockFlowyServer};
use flowy_dispatch::prelude::*;
use module::build_modules;
pub use module::*;
@ -32,7 +29,7 @@ impl FlowySDK {
FlowySDK::init_log(&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);
}

View File

@ -1,7 +1,7 @@
use flowy_dispatch::prelude::Module;
use flowy_user::prelude::*;
use crate::{flowy_server::ArcFlowyServer, user_server::MockUserServer};
use crate::flowy_server::{ArcFlowyServer, MockFlowyServer};
use flowy_database::DBConnection;
use flowy_user::errors::UserError;
use flowy_workspace::prelude::*;
@ -15,7 +15,7 @@ pub fn build_modules(config: ModuleConfig, server: ArcFlowyServer) -> Vec<Module
let user_session = Arc::new(
UserSessionBuilder::new()
.root_dir(&config.root)
.build(config.server),
.build(Arc::new(MockFlowyServer {})),
);
let workspace_user_impl = Arc::new(WorkspaceUserImpl {

View File

@ -8,6 +8,7 @@ edition = "2018"
[dependencies]
flowy-sdk = { path = "../flowy-sdk"}
flowy-dispatch = { path = "../flowy-dispatch"}
flowy-user = { path = "../flowy-user"}
serde = { version = "1.0", features = ["derive"] }
bincode = { version = "1.3"}

View File

@ -1,5 +1,10 @@
use flowy_dispatch::prelude::*;
pub use flowy_sdk::*;
use flowy_user::{
errors::UserError,
event::UserEvent::{SignIn, SignOut},
prelude::*,
};
use std::{
convert::TryFrom,
fmt::{Debug, Display},
@ -12,7 +17,7 @@ use std::{
};
pub mod prelude {
pub use crate::EventTester;
pub use crate::Tester;
pub use flowy_dispatch::prelude::*;
pub use std::convert::TryFrom;
}
@ -42,18 +47,82 @@ fn root_dir() -> String {
root_dir
}
pub trait TesterConfig {
fn auto_sign_in() -> bool { false }
pub struct TestBuilder<Error> {
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>,
assert_status_code: Option<StatusCode>,
response: Option<EventResponse>,
err_phantom: PhantomData<Error>,
user_detail: Option<UserDetail>,
}
impl<Error> EventTester<Error>
impl<Error> Tester<Error>
where
Error: FromBytes + Debug,
{
@ -73,6 +142,7 @@ where
assert_status_code: None,
response: None,
err_phantom: PhantomData,
user_detail: None,
}
}
@ -97,7 +167,6 @@ where
self
}
#[allow(dead_code)]
pub async fn async_send(mut self) -> Self {
let resp =
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)
}
}
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() }

View File

@ -1,4 +1,5 @@
use crate::services::user_session::{user_server::UserServer, UserSession, UserSessionConfig};
use std::sync::Arc;
pub struct UserSessionBuilder {
config: Option<UserSessionConfig>,
@ -12,7 +13,7 @@ impl UserSessionBuilder {
self
}
pub fn build<S>(mut self, server: S) -> UserSession
pub fn build<S>(mut self, server: Arc<S>) -> UserSession
where
S: 'static + UserServer + Send + Sync,
{

View File

@ -7,7 +7,7 @@ use flowy_database::{
};
use flowy_infra::kv::KVStore;
use lazy_static::lazy_static;
use std::sync::RwLock;
use std::sync::{Arc, RwLock};
use crate::{
entities::{SignInParams, SignUpParams, UpdateUserParams, UserDetail},
@ -31,11 +31,11 @@ impl UserSessionConfig {
pub struct UserSession {
database: UserDB,
config: UserSessionConfig,
server: Box<dyn UserServer + Send + Sync>,
server: Arc<dyn UserServer + Send + Sync>,
}
impl UserSession {
pub fn new<R>(config: UserSessionConfig, server: R) -> Self
pub fn new<R>(config: UserSessionConfig, server: Arc<R>) -> Self
where
R: 'static + UserServer + Send + Sync,
{
@ -43,7 +43,7 @@ impl UserSession {
Self {
database: db,
config,
server: Box::new(server),
server,
}
}

View File

@ -1,7 +1,7 @@
use flowy_test::{EventTester, TesterConfig};
use flowy_test::{TestBuilder, Tester};
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> {
// https://gist.github.com/cjaoude/fd9910626629b53c4d25

View File

@ -6,13 +6,14 @@ use serial_test::*;
#[test]
#[serial]
fn sign_in_success() {
let _ = UserEventTester::new(SignOut).sync_send();
let request = SignInRequest {
email: valid_email(),
password: valid_password(),
};
let response = UserEventTester::new(SignIn)
let response = UserTestBuilder::new()
.logout()
.event(SignIn)
.request(request)
.sync_send()
.parse::<UserDetail>();
@ -28,7 +29,8 @@ fn sign_in_with_invalid_email() {
};
assert_eq!(
UserEventTester::new(SignIn)
UserTestBuilder::new()
.event(SignIn)
.request(request)
.sync_send()
.error()
@ -47,7 +49,8 @@ fn sign_in_with_invalid_password() {
};
assert_eq!(
UserEventTester::new(SignIn)
UserTestBuilder::new()
.event(SignIn)
.request(request)
.sync_send()
.error()

View File

@ -6,14 +6,17 @@ use serial_test::*;
#[test]
#[serial]
fn sign_up_success() {
let _ = UserEventTester::new(SignOut).sync_send();
let _ = UserTestBuilder::new().event(SignOut).sync_send();
let request = SignUpRequest {
email: valid_email(),
name: valid_name(),
password: valid_password(),
};
let _response = UserEventTester::new(SignUp).request(request).sync_send();
let _response = UserTestBuilder::new()
.event(SignUp)
.request(request)
.sync_send();
// .parse::<SignUpResponse>();
// dbg!(&response);
}
@ -28,7 +31,8 @@ fn sign_up_with_invalid_email() {
};
assert_eq!(
UserEventTester::new(SignUp)
UserTestBuilder::new()
.event(SignUp)
.request(request)
.sync_send()
.error()
@ -47,7 +51,8 @@ fn sign_up_with_invalid_password() {
};
assert_eq!(
UserEventTester::new(SignUp)
UserTestBuilder::new()
.event(SignUp)
.request(request)
.sync_send()
.error()

View File

@ -1,5 +1,4 @@
use crate::helper::*;
use flowy_user::{errors::UserErrorCode, event::UserEvent::*, prelude::*};
use serial_test::*;
@ -7,8 +6,9 @@ use serial_test::*;
#[should_panic]
#[serial]
fn user_status_not_found_before_login() {
let _ = UserEventTester::new(SignOut).sync_send();
let _ = UserEventTester::new(GetStatus)
let _ = UserTestBuilder::new()
.logout()
.event(GetStatus)
.sync_send()
.parse::<UserDetail>();
}
@ -16,19 +16,21 @@ fn user_status_not_found_before_login() {
#[test]
#[serial]
fn user_status_did_found_after_login() {
let _ = UserEventTester::new(SignOut).sync_send();
let request = SignInRequest {
email: valid_email(),
password: valid_password(),
};
let response = UserEventTester::new(SignIn)
let response = UserTestBuilder::new()
.logout()
.event(SignIn)
.request(request)
.sync_send()
.parse::<UserDetail>();
dbg!(&response);
let _ = UserEventTester::new(GetStatus)
let _ = UserTestBuilder::new()
.event(GetStatus)
.sync_send()
.parse::<UserDetail>();
}
@ -36,20 +38,7 @@ fn user_status_did_found_after_login() {
#[test]
#[serial]
fn user_update_with_invalid_email() {
let _ = UserEventTester::new(SignOut).sync_send();
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>();
let user_detail = UserTestBuilder::new().login().user_detail.unwrap();
for email in invalid_email_test_case() {
let request = UpdateUserRequest {
@ -61,7 +50,8 @@ fn user_update_with_invalid_email() {
};
assert_eq!(
UserEventTester::new(UpdateUser)
UserTestBuilder::new()
.event(UpdateUser)
.request(request)
.sync_send()
.error()

View File

@ -1,7 +1,7 @@
use flowy_test::EventTester;
use flowy_test::TestBuilder;
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> {
vec!["", "1234".repeat(100).as_str()]

View File

@ -12,7 +12,8 @@ fn workspace_create_success() {
desc: "".to_owned(),
};
let response = WorkspaceEventTester::new(CreateWorkspace)
let response = WorkspaceTestBuilder::new()
.event(CreateWorkspace)
.request(request)
.sync_send()
.parse::<WorkspaceDetail>();
@ -28,7 +29,8 @@ fn workspace_create_with_invalid_name_test() {
};
assert_eq!(
WorkspaceEventTester::new(CreateWorkspace)
WorkspaceTestBuilder::new()
.event(CreateWorkspace)
.request(request)
.sync_send()
.error()