2021-08-23 14:10:36 +00:00
|
|
|
use backend::{
|
|
|
|
application::{get_connection_pool, Application},
|
|
|
|
config::{get_configuration, DatabaseSettings},
|
|
|
|
};
|
2021-08-26 02:19:50 +00:00
|
|
|
|
2021-09-01 08:08:32 +00:00
|
|
|
use flowy_user::{errors::UserError, prelude::*};
|
2021-09-02 06:47:39 +00:00
|
|
|
use flowy_workspace::prelude::{server::*, *};
|
2021-08-23 14:10:36 +00:00
|
|
|
use sqlx::{Connection, Executor, PgConnection, PgPool};
|
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
pub struct TestApp {
|
|
|
|
pub address: String,
|
|
|
|
pub port: u16,
|
|
|
|
pub pg_pool: PgPool,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TestApp {
|
|
|
|
pub async fn register_user(&self, params: SignUpParams) -> SignUpResponse {
|
|
|
|
let url = format!("{}/api/register", self.address);
|
2021-09-01 14:50:22 +00:00
|
|
|
let resp = user_sign_up_request(params, &url).await.unwrap();
|
2021-08-23 14:10:36 +00:00
|
|
|
resp
|
|
|
|
}
|
|
|
|
|
2021-09-01 08:08:32 +00:00
|
|
|
pub async fn sign_in(&self, params: SignInParams) -> Result<SignInResponse, UserError> {
|
2021-08-23 14:10:36 +00:00
|
|
|
let url = format!("{}/api/auth", self.address);
|
2021-09-01 14:50:22 +00:00
|
|
|
user_sign_in_request(params, &url).await
|
2021-08-23 14:10:36 +00:00
|
|
|
}
|
2021-08-24 13:38:53 +00:00
|
|
|
|
2021-09-01 08:37:46 +00:00
|
|
|
pub async fn sign_out(&self, token: &str) {
|
2021-08-31 09:25:08 +00:00
|
|
|
let url = format!("{}/api/auth", self.address);
|
2021-09-01 14:50:22 +00:00
|
|
|
let _ = user_sign_out_request(token, &url).await.unwrap();
|
2021-08-31 09:25:08 +00:00
|
|
|
}
|
|
|
|
|
2021-09-04 08:53:58 +00:00
|
|
|
pub async fn get_user_profile(&self, token: &str) -> UserProfile {
|
2021-09-01 08:08:32 +00:00
|
|
|
let url = format!("{}/api/user", self.address);
|
2021-09-04 08:53:58 +00:00
|
|
|
let user_profile = get_user_profile_request(token, &url).await.unwrap();
|
|
|
|
user_profile
|
2021-08-31 09:56:38 +00:00
|
|
|
}
|
|
|
|
|
2021-09-04 08:53:58 +00:00
|
|
|
pub async fn update_user_profile(
|
2021-09-01 08:08:32 +00:00
|
|
|
&self,
|
|
|
|
token: &str,
|
|
|
|
params: UpdateUserParams,
|
|
|
|
) -> Result<(), UserError> {
|
|
|
|
let url = format!("{}/api/user", self.address);
|
2021-09-04 08:53:58 +00:00
|
|
|
update_user_profile_request(token, params, &url).await
|
2021-09-01 08:08:32 +00:00
|
|
|
}
|
|
|
|
|
2021-09-02 06:47:39 +00:00
|
|
|
pub async fn create_workspace(&self, params: CreateWorkspaceParams, token: &str) -> Workspace {
|
2021-08-24 13:38:53 +00:00
|
|
|
let url = format!("{}/api/workspace", self.address);
|
2021-09-02 06:47:39 +00:00
|
|
|
let workspace = create_workspace_request(token, params, &url).await.unwrap();
|
2021-08-24 13:38:53 +00:00
|
|
|
workspace
|
|
|
|
}
|
|
|
|
|
2021-09-02 06:47:39 +00:00
|
|
|
pub async fn read_workspaces(
|
|
|
|
&self,
|
|
|
|
params: QueryWorkspaceParams,
|
|
|
|
token: &str,
|
|
|
|
) -> RepeatedWorkspace {
|
2021-08-24 13:38:53 +00:00
|
|
|
let url = format!("{}/api/workspace", self.address);
|
2021-09-02 06:47:39 +00:00
|
|
|
let workspaces = read_workspaces_request(token, params, &url).await.unwrap();
|
2021-08-27 15:53:53 +00:00
|
|
|
workspaces
|
2021-08-24 13:38:53 +00:00
|
|
|
}
|
|
|
|
|
2021-09-02 06:47:39 +00:00
|
|
|
pub async fn update_workspace(&self, params: UpdateWorkspaceParams, token: &str) {
|
2021-08-25 09:34:20 +00:00
|
|
|
let url = format!("{}/api/workspace", self.address);
|
2021-09-02 06:47:39 +00:00
|
|
|
update_workspace_request(token, params, &url).await.unwrap();
|
2021-08-25 09:34:20 +00:00
|
|
|
}
|
|
|
|
|
2021-09-02 06:47:39 +00:00
|
|
|
pub async fn delete_workspace(&self, params: DeleteWorkspaceParams, token: &str) {
|
2021-08-25 09:34:20 +00:00
|
|
|
let url = format!("{}/api/workspace", self.address);
|
2021-09-02 06:47:39 +00:00
|
|
|
delete_workspace_request(token, params, &url).await.unwrap();
|
2021-08-25 09:34:20 +00:00
|
|
|
}
|
|
|
|
|
2021-09-02 06:47:39 +00:00
|
|
|
pub async fn create_app(&self, params: CreateAppParams, token: &str) -> App {
|
2021-08-25 09:34:20 +00:00
|
|
|
let url = format!("{}/api/app", self.address);
|
2021-09-02 06:47:39 +00:00
|
|
|
let app = create_app_request(token, params, &url).await.unwrap();
|
2021-08-25 09:34:20 +00:00
|
|
|
app
|
|
|
|
}
|
|
|
|
|
2021-09-02 06:47:39 +00:00
|
|
|
pub async fn read_app(&self, params: QueryAppParams, token: &str) -> Option<App> {
|
2021-08-25 09:34:20 +00:00
|
|
|
let url = format!("{}/api/app", self.address);
|
2021-09-02 06:47:39 +00:00
|
|
|
let app = read_app_request(token, params, &url).await.unwrap();
|
2021-08-25 09:34:20 +00:00
|
|
|
app
|
|
|
|
}
|
|
|
|
|
2021-09-02 06:47:39 +00:00
|
|
|
pub async fn update_app(&self, params: UpdateAppParams, token: &str) {
|
2021-08-25 09:34:20 +00:00
|
|
|
let url = format!("{}/api/app", self.address);
|
2021-09-02 06:47:39 +00:00
|
|
|
update_app_request(token, params, &url).await.unwrap();
|
2021-08-25 09:34:20 +00:00
|
|
|
}
|
|
|
|
|
2021-09-02 06:47:39 +00:00
|
|
|
pub async fn delete_app(&self, params: DeleteAppParams, token: &str) {
|
2021-08-25 09:34:20 +00:00
|
|
|
let url = format!("{}/api/app", self.address);
|
2021-09-02 06:47:39 +00:00
|
|
|
delete_app_request(token, params, &url).await.unwrap();
|
2021-08-25 09:34:20 +00:00
|
|
|
}
|
|
|
|
|
2021-09-02 06:47:39 +00:00
|
|
|
pub async fn create_view(&self, params: CreateViewParams, token: &str) -> View {
|
2021-08-25 13:33:29 +00:00
|
|
|
let url = format!("{}/api/view", self.address);
|
2021-09-02 06:47:39 +00:00
|
|
|
let view = create_view_request(token, params, &url).await.unwrap();
|
2021-08-25 13:33:29 +00:00
|
|
|
view
|
|
|
|
}
|
|
|
|
|
2021-09-02 06:47:39 +00:00
|
|
|
pub async fn read_view(&self, params: QueryViewParams, token: &str) -> Option<View> {
|
2021-08-25 13:33:29 +00:00
|
|
|
let url = format!("{}/api/view", self.address);
|
2021-09-02 06:47:39 +00:00
|
|
|
let view = read_view_request(token, params, &url).await.unwrap();
|
2021-08-25 13:33:29 +00:00
|
|
|
view
|
|
|
|
}
|
|
|
|
|
2021-09-02 06:47:39 +00:00
|
|
|
pub async fn update_view(&self, params: UpdateViewParams, token: &str) {
|
2021-08-25 13:33:29 +00:00
|
|
|
let url = format!("{}/api/view", self.address);
|
2021-09-02 06:47:39 +00:00
|
|
|
update_view_request(token, params, &url).await.unwrap();
|
2021-08-25 13:33:29 +00:00
|
|
|
}
|
|
|
|
|
2021-09-02 06:47:39 +00:00
|
|
|
pub async fn delete_view(&self, params: DeleteViewParams, token: &str) {
|
2021-08-25 13:33:29 +00:00
|
|
|
let url = format!("{}/api/view", self.address);
|
2021-09-02 06:47:39 +00:00
|
|
|
delete_view_request(token, params, &url).await.unwrap();
|
2021-08-25 13:33:29 +00:00
|
|
|
}
|
|
|
|
|
2021-08-25 09:34:20 +00:00
|
|
|
pub(crate) async fn register_test_user(&self) -> SignUpResponse {
|
2021-08-24 13:38:53 +00:00
|
|
|
let params = SignUpParams {
|
|
|
|
email: "annie@appflowy.io".to_string(),
|
|
|
|
name: "annie".to_string(),
|
|
|
|
password: "HelloAppFlowy123!".to_string(),
|
|
|
|
};
|
|
|
|
|
|
|
|
let response = self.register_user(params).await;
|
|
|
|
response
|
|
|
|
}
|
2021-08-23 14:10:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn spawn_app() -> TestApp {
|
2021-09-06 06:24:22 +00:00
|
|
|
let database_name = format!("{}", Uuid::new_v4().to_string());
|
2021-08-23 14:10:36 +00:00
|
|
|
let configuration = {
|
|
|
|
let mut c = get_configuration().expect("Failed to read configuration.");
|
2021-09-06 06:24:22 +00:00
|
|
|
c.database.database_name = database_name.clone();
|
2021-08-23 14:10:36 +00:00
|
|
|
// Use a random OS port
|
|
|
|
c.application.port = 0;
|
|
|
|
c
|
|
|
|
};
|
|
|
|
|
|
|
|
let _ = configure_database(&configuration.database).await;
|
|
|
|
let application = Application::build(configuration.clone())
|
|
|
|
.await
|
|
|
|
.expect("Failed to build application.");
|
|
|
|
let application_port = application.port();
|
|
|
|
|
2021-09-06 06:24:22 +00:00
|
|
|
let _ = tokio::spawn(async {
|
|
|
|
let _ = application.run_until_stopped();
|
|
|
|
drop_test_database(database_name).await;
|
|
|
|
});
|
2021-08-23 14:10:36 +00:00
|
|
|
|
|
|
|
TestApp {
|
|
|
|
address: format!("http://localhost:{}", application_port),
|
|
|
|
port: application_port,
|
|
|
|
pg_pool: get_connection_pool(&configuration.database)
|
|
|
|
.await
|
|
|
|
.expect("Failed to connect to the database"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn configure_database(config: &DatabaseSettings) -> PgPool {
|
|
|
|
// Create database
|
|
|
|
let mut connection = PgConnection::connect_with(&config.without_db())
|
|
|
|
.await
|
|
|
|
.expect("Failed to connect to Postgres");
|
|
|
|
connection
|
|
|
|
.execute(&*format!(r#"CREATE DATABASE "{}";"#, config.database_name))
|
|
|
|
.await
|
|
|
|
.expect("Failed to create database.");
|
|
|
|
|
|
|
|
// Migrate database
|
|
|
|
let connection_pool = PgPool::connect_with(config.with_db())
|
|
|
|
.await
|
|
|
|
.expect("Failed to connect to Postgres.");
|
|
|
|
|
|
|
|
sqlx::migrate!("./migrations")
|
|
|
|
.run(&connection_pool)
|
|
|
|
.await
|
|
|
|
.expect("Failed to migrate the database");
|
|
|
|
|
|
|
|
connection_pool
|
|
|
|
}
|
2021-09-06 06:24:22 +00:00
|
|
|
|
|
|
|
async fn drop_test_database(database_name: String) {
|
|
|
|
let configuration = {
|
|
|
|
let mut c = get_configuration().expect("Failed to read configuration.");
|
|
|
|
c.database.database_name = "flowy".to_owned();
|
|
|
|
c.application.port = 0;
|
|
|
|
c
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut connection = PgConnection::connect_with(&configuration.database.without_db())
|
|
|
|
.await
|
|
|
|
.expect("Failed to connect to Postgres");
|
|
|
|
|
|
|
|
connection
|
|
|
|
.execute(&*format!(r#"Drop DATABASE "{}";"#, database_name))
|
|
|
|
.await
|
|
|
|
.expect("Failed to drop database.");
|
|
|
|
}
|