enable test target parse response if need

This commit is contained in:
appflowy 2021-07-06 21:20:53 +08:00
parent 2c1e8eee23
commit f1a229002f
6 changed files with 115 additions and 78 deletions

View File

@ -13,6 +13,18 @@ fi
printf "\e[33;1m%s\e[0m\n" 'Finished running the Flutter analyzer'
printf "\e[33;1m%s\e[0m\n" 'Running unit tests'
#current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
#if [ "$current_branch" = "main" ]; then
# echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
# echo ""
# echo " Should not push to main directly. Use Pull Request instead"
# echo ""
# echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
# exit 1
#fi
#flutter test
#if [ $? -ne 0 ]; then
# printf "\e[31;1m%s\e[0m\n" 'Unit tests error'

View File

@ -113,7 +113,6 @@
<value>
<list>
<option value="$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/built_collection-5.1.0/lib" />
<option value="$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/built_collection-4.3.2/lib" />
</list>
</value>
</entry>
@ -121,7 +120,6 @@
<value>
<list>
<option value="$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/built_value-8.1.0/lib" />
<option value="$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/built_value-7.1.0/lib" />
</list>
</value>
</entry>
@ -247,7 +245,6 @@
<value>
<list>
<option value="$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/fixnum-1.0.0/lib" />
<option value="$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/fixnum-0.10.11/lib" />
</list>
</value>
</entry>
@ -528,7 +525,6 @@
<value>
<list>
<option value="$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/protobuf-2.0.0/lib" />
<option value="$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/protobuf-1.1.4/lib" />
</list>
</value>
</entry>
@ -553,13 +549,6 @@
</list>
</value>
</entry>
<entry key="quiver">
<value>
<list>
<option value="$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/quiver-2.1.5/lib" />
</list>
</value>
</entry>
<entry key="shelf">
<value>
<list>
@ -773,9 +762,7 @@
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/build_runner-2.0.4/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/build_runner_core-6.1.12/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/build_runner_core-7.0.0/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/built_collection-4.3.2/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/built_collection-5.1.0/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/built_value-7.1.0/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/built_value-8.1.0/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/characters-1.1.0/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/charcode-1.2.0/lib" />
@ -799,7 +786,6 @@
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/file-6.1.0/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/file-6.1.1/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/file-6.1.2/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/fixnum-0.10.11/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/fixnum-1.0.0/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_bloc-7.0.1/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_lints-1.0.3/lib" />
@ -841,12 +827,10 @@
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/plugin_platform_interface-2.0.0/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/pool-1.5.0/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/process-4.2.1/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/protobuf-1.1.4/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/protobuf-2.0.0/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/provider-5.0.0/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.0.0/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-1.0.0/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/quiver-2.1.5/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/shelf-0.7.9/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/shelf-1.1.4/lib" />
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-0.2.3/lib" />

View File

@ -95,15 +95,27 @@ where
T: FromBytes,
{
type Error = String;
fn try_from(payload: &Payload) -> Result<Data<T>, Self::Error> { parse_payload(payload) }
}
fn try_from(payload: &Payload) -> Result<Data<T>, Self::Error> {
match payload {
Payload::None => Err(format!("Expected payload")),
Payload::Bytes(bytes) => match T::parse_from_bytes(bytes) {
Ok(data) => Ok(Data(data)),
Err(e) => Err(e),
},
}
impl<T> std::convert::TryFrom<Payload> for Data<T>
where
T: FromBytes,
{
type Error = String;
fn try_from(payload: Payload) -> Result<Data<T>, Self::Error> { parse_payload(&payload) }
}
fn parse_payload<T>(payload: &Payload) -> Result<Data<T>, String>
where
T: FromBytes,
{
match payload {
Payload::None => Err(format!("Expected payload")),
Payload::Bytes(bytes) => match T::parse_from_bytes(&bytes) {
Ok(data) => Ok(Data(data)),
Err(e) => Err(e),
},
}
}

View File

@ -42,8 +42,9 @@ fn root_dir() -> String {
}
pub struct EventTester {
request: DispatchRequest,
request: Option<DispatchRequest>,
assert_status_code: Option<StatusCode>,
response: Option<EventResponse>,
}
impl EventTester {
@ -54,8 +55,9 @@ impl EventTester {
init_sdk();
let request = DispatchRequest::new(event);
Self {
request,
request: Some(request),
assert_status_code: None,
response: None,
}
}
@ -63,7 +65,9 @@ impl EventTester {
where
P: ToBytes,
{
self.request = self.request.payload(Data(payload));
let mut request = self.request.take().unwrap();
request = request.payload(Data(payload));
self.request = Some(request);
self
}
@ -73,26 +77,32 @@ impl EventTester {
}
#[allow(dead_code)]
pub async fn async_send<R>(self) -> R
where
R: FromBytes,
{
let resp = async_send(self.request).await;
pub async fn async_send(mut self) -> Self {
let resp = async_send(self.request.take().unwrap()).await;
if let Some(ref status_code) = self.assert_status_code {
assert_eq!(&resp.status_code, status_code)
}
dbg!(&resp);
data_from_response(&resp)
self.response = Some(resp);
self
}
pub fn sync_send<R>(self) -> R
pub fn sync_send(mut self) -> Self {
let resp = sync_send(self.request.take().unwrap());
if let Some(ref status_code) = self.assert_status_code {
assert_eq!(&resp.status_code, status_code)
}
dbg!(&resp);
self.response = Some(resp);
self
}
pub fn parse<R>(self) -> R
where
R: FromBytes,
{
let resp = sync_send(self.request);
if let Some(status_code) = self.assert_status_code {
assert_eq!(resp.status_code, status_code)
}
dbg!(&resp);
data_from_response(&resp)
let response = self.response.unwrap();
<Data<R>>::try_from(response.payload).unwrap().into_inner()
}
}

View File

@ -6,20 +6,25 @@ pub struct UserPassword(pub String);
impl UserPassword {
pub fn parse(s: String) -> Result<UserPassword, String> {
let is_empty_or_whitespace = s.trim().is_empty();
if is_empty_or_whitespace {
if s.trim().is_empty() {
return Err(format!("Password can not be empty or whitespace."));
}
let is_too_long = s.graphemes(true).count() > 100;
if s.graphemes(true).count() > 100 {
return Err(format!("Password too long."));
}
let forbidden_characters = ['/', '(', ')', '"', '<', '>', '\\', '{', '}'];
let contains_forbidden_characters = s.chars().any(|g| forbidden_characters.contains(&g));
let is_invalid_password = !validate_password(&s);
if is_too_long || contains_forbidden_characters || is_invalid_password {
Err(format!("{} is not a valid password.", s))
} else {
Ok(Self(s))
if contains_forbidden_characters {
return Err(format!("Password contains forbidden characters."));
}
if !validate_password(&s) {
return Err(format!("Password should contain a minimum of 6 characters with 1 special 1 letter and 1 numeric"));
}
Ok(Self(s))
}
}
@ -27,7 +32,7 @@ lazy_static! {
// Test it in https://regex101.com/
// https://stackoverflow.com/questions/2370015/regular-expression-for-password-validation/2370045
// Hell1!
// [invalid, less than 6]
// [invalid, greater or equal to 6]
// Hel1!
//
// Hello1!
@ -40,4 +45,12 @@ lazy_static! {
static ref PASSWORD: Regex = Regex::new("((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\\W]).{6,20})").unwrap();
}
pub fn validate_password(password: &str) -> bool { PASSWORD.is_match(password).is_ok() }
pub fn validate_password(password: &str) -> bool {
match PASSWORD.is_match(password) {
Ok(is_match) => is_match,
Err(e) => {
log::error!("validate_password fail: {:?}", e);
false
},
}
}

View File

@ -2,46 +2,52 @@ use flowy_test::prelude::*;
use flowy_user::prelude::*;
#[test]
#[should_panic]
fn sign_in_without_password() {
let params = UserSignInParams {
email: "annie@appflowy.io".to_string(),
password: "".to_string(),
};
fn sign_in_with_invalid_email() {
let test_cases = vec!["", "annie@", "annie@gmail@"];
let password = "Appflowy!123".to_string();
let result = EventTester::new(SignIn)
.payload(params)
.assert_status_code(StatusCode::Err)
.sync_send::<UserSignInResult>();
dbg!(&result);
for email in test_cases {
let params = UserSignInParams {
email: email.to_string(),
password: password.clone(),
};
let _ = EventTester::new(SignIn)
.payload(params)
.assert_status_code(StatusCode::Err)
.sync_send();
}
}
#[test]
#[should_panic]
fn sign_in_with_invalid_password() {
let params = UserSignInParams {
email: "annie@appflowy.io".to_string(),
password: "123".to_string(),
};
let test_cases = vec!["".to_string(), "123456".to_owned(), "1234".repeat(100)];
let email = "annie@appflowy.io".to_string();
let result = EventTester::new(SignIn)
.payload(params)
.assert_status_code(StatusCode::Err)
.sync_send::<UserSignInResult>();
dbg!(&result);
for password in test_cases {
let params = UserSignInParams {
email: email.clone(),
password,
};
let _ = EventTester::new(SignIn)
.payload(params)
.assert_status_code(StatusCode::Err)
.sync_send();
}
}
#[test]
#[should_panic]
fn sign_in_without_email() {
fn sign_in_success() {
let params = UserSignInParams {
email: "".to_string(),
email: "annie@appflowy.io".to_string(),
password: "HelloWorld!123".to_string(),
};
let result = EventTester::new(SignIn)
.payload(params)
.assert_status_code(StatusCode::Err)
.sync_send::<UserSignInResult>();
.assert_status_code(StatusCode::Ok)
.sync_send()
.parse::<UserSignInResult>();
dbg!(&result);
}