You've already forked AstralRinth
forked from didirus/AstralRinth
Tests v2 recreate (#760)
* added common project information; setup for v2 test change * all tests now use with_test_environment * progress, failing * finished re-adding tests * prepare * cargo sqlx prepare -- --tests * fmt; clippy; prepare * sqlx prepare * adds version_create fix and corresponding test * merge fixes; rev * fmt, clippy, prepare * test cargo sqlx prepare
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::{rc::Rc, sync::Arc};
|
||||
|
||||
use super::{
|
||||
api_common::{generic::GenericApi, Api, ApiBuildable},
|
||||
api_v2::ApiV2,
|
||||
api_v3::ApiV3,
|
||||
asserts::assert_status,
|
||||
@@ -11,76 +10,103 @@ use super::{
|
||||
};
|
||||
use crate::common::setup;
|
||||
use actix_http::StatusCode;
|
||||
use actix_web::{dev::ServiceResponse, test, App};
|
||||
use actix_web::dev::ServiceResponse;
|
||||
use futures::Future;
|
||||
|
||||
pub async fn with_test_environment<Fut>(f: impl FnOnce(TestEnvironment) -> Fut)
|
||||
where
|
||||
pub async fn with_test_environment<Fut, A>(
|
||||
max_connections: Option<u32>,
|
||||
f: impl FnOnce(TestEnvironment<A>) -> Fut,
|
||||
) where
|
||||
Fut: Future<Output = ()>,
|
||||
A: ApiBuildable + 'static,
|
||||
{
|
||||
let test_env = TestEnvironment::build(None).await;
|
||||
let test_env: TestEnvironment<A> = TestEnvironment::build(max_connections).await;
|
||||
let db = test_env.db.clone();
|
||||
|
||||
f(test_env).await;
|
||||
|
||||
db.cleanup().await;
|
||||
}
|
||||
|
||||
// TODO: This needs to be slightly redesigned in order to do both V2 and v3 tests.
|
||||
// TODO: Most tests, since they use API functions, can be applied to both. The ones that weren't are in v2/, but
|
||||
// all tests that can be applied to both should use both v2 and v3 (extract api to a trait with all the API functions and call both).
|
||||
pub async fn with_test_environment_all<Fut, F>(max_connections: Option<u32>, f: F)
|
||||
where
|
||||
Fut: Future<Output = ()>,
|
||||
F: Fn(TestEnvironment<GenericApi>) -> Fut,
|
||||
{
|
||||
println!("Test environment: API v3");
|
||||
let test_env_api_v3 = TestEnvironment::<ApiV3>::build(max_connections).await;
|
||||
let test_env_api_v3 = TestEnvironment {
|
||||
db: test_env_api_v3.db.clone(),
|
||||
api: GenericApi::V3(test_env_api_v3.api),
|
||||
setup_api: test_env_api_v3.setup_api,
|
||||
dummy: test_env_api_v3.dummy,
|
||||
};
|
||||
let db = test_env_api_v3.db.clone();
|
||||
f(test_env_api_v3).await;
|
||||
db.cleanup().await;
|
||||
|
||||
println!("Test environment: API v2");
|
||||
let test_env_api_v2 = TestEnvironment::<ApiV2>::build(max_connections).await;
|
||||
let test_env_api_v2 = TestEnvironment {
|
||||
db: test_env_api_v2.db.clone(),
|
||||
api: GenericApi::V2(test_env_api_v2.api),
|
||||
setup_api: test_env_api_v2.setup_api,
|
||||
dummy: test_env_api_v2.dummy,
|
||||
};
|
||||
let db = test_env_api_v2.db.clone();
|
||||
f(test_env_api_v2).await;
|
||||
db.cleanup().await;
|
||||
}
|
||||
|
||||
// A complete test environment, with a test actix app and a database.
|
||||
// Must be called in an #[actix_rt::test] context. It also simulates a
|
||||
// temporary sqlx db like #[sqlx::test] would.
|
||||
// Use .call(req) on it directly to make a test call as if test::call_service(req) were being used.
|
||||
#[derive(Clone)]
|
||||
pub struct TestEnvironment {
|
||||
test_app: Rc<dyn LocalService>, // Rc as it's not Send
|
||||
pub struct TestEnvironment<A> {
|
||||
// test_app: Rc<dyn LocalService>, // Rc as it's not Send
|
||||
pub db: TemporaryDatabase,
|
||||
pub v2: ApiV2,
|
||||
pub v3: ApiV3,
|
||||
|
||||
pub dummy: Option<Arc<dummy_data::DummyData>>,
|
||||
pub api: A,
|
||||
pub setup_api: ApiV3, // Used for setting up tests only (ie: in ScopesTest)
|
||||
pub dummy: Option<dummy_data::DummyData>,
|
||||
}
|
||||
|
||||
impl TestEnvironment {
|
||||
pub async fn build(max_connections: Option<u32>) -> Self {
|
||||
impl<A: ApiBuildable> TestEnvironment<A> {
|
||||
async fn build(max_connections: Option<u32>) -> Self {
|
||||
let db = TemporaryDatabase::create(max_connections).await;
|
||||
let mut test_env = Self::build_with_db(db).await;
|
||||
|
||||
let dummy = dummy_data::get_dummy_data(&test_env).await;
|
||||
test_env.dummy = Some(Arc::new(dummy));
|
||||
let dummy = dummy_data::get_dummy_data(&test_env.setup_api).await;
|
||||
test_env.dummy = Some(dummy);
|
||||
test_env
|
||||
}
|
||||
|
||||
pub async fn build_with_db(db: TemporaryDatabase) -> Self {
|
||||
let labrinth_config = setup(&db).await;
|
||||
let app = App::new().configure(|cfg| labrinth::app_config(cfg, labrinth_config.clone()));
|
||||
let test_app: Rc<dyn LocalService> = Rc::new(test::init_service(app).await);
|
||||
Self {
|
||||
v2: ApiV2 {
|
||||
test_app: test_app.clone(),
|
||||
},
|
||||
v3: ApiV3 {
|
||||
test_app: test_app.clone(),
|
||||
},
|
||||
test_app,
|
||||
db,
|
||||
api: A::build(labrinth_config.clone()).await,
|
||||
setup_api: ApiV3::build(labrinth_config.clone()).await,
|
||||
dummy: None,
|
||||
// test_app
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Api> TestEnvironment<A> {
|
||||
pub async fn cleanup(self) {
|
||||
self.db.cleanup().await;
|
||||
}
|
||||
|
||||
pub async fn call(&self, req: actix_http::Request) -> ServiceResponse {
|
||||
self.test_app.call(req).await.unwrap()
|
||||
self.api.call(req).await
|
||||
}
|
||||
|
||||
// Setup data, create a friend user notification
|
||||
pub async fn generate_friend_user_notification(&self) {
|
||||
let resp = self
|
||||
.v3
|
||||
.api
|
||||
.add_user_to_team(
|
||||
&self.dummy.as_ref().unwrap().project_alpha.team_id,
|
||||
FRIEND_USER_ID,
|
||||
@@ -92,23 +118,25 @@ impl TestEnvironment {
|
||||
assert_status(&resp, StatusCode::NO_CONTENT);
|
||||
}
|
||||
|
||||
// Setup data, assert that a user can read notifications
|
||||
pub async fn assert_read_notifications_status(
|
||||
&self,
|
||||
user_id: &str,
|
||||
pat: &str,
|
||||
status_code: StatusCode,
|
||||
) {
|
||||
let resp = self.v3.get_user_notifications(user_id, pat).await;
|
||||
let resp = self.api.get_user_notifications(user_id, pat).await;
|
||||
assert_status(&resp, status_code);
|
||||
}
|
||||
|
||||
// Setup data, assert that a user can read projects notifications
|
||||
pub async fn assert_read_user_projects_status(
|
||||
&self,
|
||||
user_id: &str,
|
||||
pat: &str,
|
||||
status_code: StatusCode,
|
||||
) {
|
||||
let resp = self.v3.get_user_projects(user_id, pat).await;
|
||||
let resp = self.api.get_user_projects(user_id, pat).await;
|
||||
assert_status(&resp, status_code);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user