You've already forked AstralRinth
forked from didirus/AstralRinth
Testing bug fixes (#788)
* fixes * adds tests- fixes failures * changes * moved transaction commits/caches around * collections nullable * merge fixes * sqlx prepare * revs * lf fixes * made changes back * added collections update --------- Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
This commit is contained in:
@@ -80,6 +80,8 @@ delegate_api_variant!(
|
||||
[add_gallery_item, ServiceResponse, id_or_slug: &str, image: ImageData, featured: bool, title: Option<String>, description: Option<String>, ordering: Option<i32>, pat: Option<&str>],
|
||||
[remove_gallery_item, ServiceResponse, id_or_slug: &str, image_url: &str, pat: Option<&str>],
|
||||
[edit_gallery_item, ServiceResponse, id_or_slug: &str, image_url: &str, patch: HashMap<String, String>, pat: Option<&str>],
|
||||
[create_report, ServiceResponse, report_type: &str, id: &str, item_type: crate::common::api_common::models::CommonItemType, body: &str, pat: Option<&str>],
|
||||
[get_report, ServiceResponse, id: &str, pat: Option<&str>],
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use self::models::{
|
||||
CommonCategoryData, CommonLoaderData, CommonNotification, CommonProject, CommonTeamMember,
|
||||
CommonVersion,
|
||||
CommonCategoryData, CommonItemType, CommonLoaderData, CommonNotification, CommonProject,
|
||||
CommonTeamMember, CommonVersion,
|
||||
};
|
||||
use self::request_data::{ImageData, ProjectCreationRequestData};
|
||||
use actix_web::dev::ServiceResponse;
|
||||
@@ -118,6 +118,15 @@ pub trait ApiProject {
|
||||
patch: HashMap<String, String>,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn create_report(
|
||||
&self,
|
||||
report_type: &str,
|
||||
id: &str,
|
||||
item_type: CommonItemType,
|
||||
body: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn get_report(&self, id: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
|
||||
@@ -11,7 +11,7 @@ use labrinth::models::{
|
||||
users::{User, UserId},
|
||||
};
|
||||
use rust_decimal::Decimal;
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// Fields shared by every version of the API.
|
||||
// No struct in here should have ANY field that
|
||||
@@ -119,3 +119,23 @@ pub struct CommonNotification {
|
||||
pub struct CommonNotificationAction {
|
||||
pub action_route: (String, String),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum CommonItemType {
|
||||
Project,
|
||||
Version,
|
||||
User,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl CommonItemType {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
CommonItemType::Project => "project",
|
||||
CommonItemType::Version => "version",
|
||||
CommonItemType::User => "user",
|
||||
CommonItemType::Unknown => "unknown",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||
|
||||
use crate::common::{
|
||||
api_common::{
|
||||
models::{CommonProject, CommonVersion},
|
||||
models::{CommonItemType, CommonProject, CommonVersion},
|
||||
request_data::{ImageData, ProjectCreationRequestData},
|
||||
Api, ApiProject, AppendsOptionalPat,
|
||||
},
|
||||
@@ -266,6 +266,39 @@ impl ApiProject for ApiV2 {
|
||||
}
|
||||
}
|
||||
|
||||
async fn create_report(
|
||||
&self,
|
||||
report_type: &str,
|
||||
id: &str,
|
||||
item_type: CommonItemType,
|
||||
body: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::post()
|
||||
.uri("/v3/report")
|
||||
.append_pat(pat)
|
||||
.set_json(json!(
|
||||
{
|
||||
"report_type": report_type,
|
||||
"item_id": id,
|
||||
"item_type": item_type.as_str(),
|
||||
"body": body,
|
||||
}
|
||||
))
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_report(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v3/report/{id}", id = id))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn schedule_project(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
|
||||
@@ -3,7 +3,9 @@ use actix_web::{
|
||||
test::{self, TestRequest},
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use labrinth::routes::v2::tags::{CategoryData, GameVersionQueryData, LoaderData};
|
||||
use labrinth::routes::v2::tags::{
|
||||
CategoryData, DonationPlatformQueryData, GameVersionQueryData, LoaderData,
|
||||
};
|
||||
|
||||
use crate::common::{
|
||||
api_common::{
|
||||
@@ -57,6 +59,21 @@ impl ApiV2 {
|
||||
assert_eq!(resp.status(), 200);
|
||||
test::read_body_json(resp).await
|
||||
}
|
||||
|
||||
pub async fn get_donation_platforms(&self) -> ServiceResponse {
|
||||
let req = TestRequest::get()
|
||||
.uri("/v2/tag/donation_platform")
|
||||
.append_pat(ADMIN_USER_PAT)
|
||||
.to_request();
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
pub async fn get_donation_platforms_deserialized(&self) -> Vec<DonationPlatformQueryData> {
|
||||
let resp = self.get_donation_platforms().await;
|
||||
println!("Response: {:?}", resp.response().body());
|
||||
assert_eq!(resp.status(), 200);
|
||||
test::read_body_json(resp).await
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
|
||||
@@ -17,7 +17,7 @@ use serde_json::json;
|
||||
|
||||
use crate::common::{
|
||||
api_common::{
|
||||
models::{CommonProject, CommonVersion},
|
||||
models::{CommonItemType, CommonProject, CommonVersion},
|
||||
request_data::{ImageData, ProjectCreationRequestData},
|
||||
Api, ApiProject, AppendsOptionalPat,
|
||||
},
|
||||
@@ -219,6 +219,39 @@ impl ApiProject for ApiV3 {
|
||||
}
|
||||
}
|
||||
|
||||
async fn create_report(
|
||||
&self,
|
||||
report_type: &str,
|
||||
id: &str,
|
||||
item_type: CommonItemType,
|
||||
body: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse {
|
||||
let req = test::TestRequest::post()
|
||||
.uri("/v3/report")
|
||||
.append_pat(pat)
|
||||
.set_json(json!(
|
||||
{
|
||||
"report_type": report_type,
|
||||
"item_id": id,
|
||||
"item_type": item_type.as_str(),
|
||||
"body": body,
|
||||
}
|
||||
))
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn get_report(&self, id: &str, pat: Option<&str>) -> ServiceResponse {
|
||||
let req = test::TestRequest::get()
|
||||
.uri(&format!("/v3/report/{id}", id = id))
|
||||
.append_pat(pat)
|
||||
.to_request();
|
||||
|
||||
self.call(req).await
|
||||
}
|
||||
|
||||
async fn schedule_project(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
|
||||
@@ -18,6 +18,7 @@ use labrinth::models::teams::ProjectPermissions;
|
||||
use labrinth::util::actix::{MultipartSegment, MultipartSegmentData};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::common::api_common::models::CommonItemType;
|
||||
use crate::common::api_common::request_data::ProjectCreationRequestData;
|
||||
use crate::common::api_common::{ApiProject, ApiTeams, ApiVersion, AppendsOptionalPat};
|
||||
use crate::common::dummy_data::{DummyImage, TestFile};
|
||||
@@ -590,6 +591,94 @@ pub async fn test_bulk_edit_links() {
|
||||
.await;
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn delete_project_with_report() {
|
||||
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
|
||||
let api = &test_env.api;
|
||||
let alpha_project_id: &str = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
||||
let beta_project_id: &str = &test_env.dummy.as_ref().unwrap().project_beta.project_id;
|
||||
|
||||
// Create a report for the project
|
||||
let resp = api
|
||||
.create_report(
|
||||
"copyright",
|
||||
alpha_project_id,
|
||||
CommonItemType::Project,
|
||||
"Hey! This is my project, copied without permission!",
|
||||
ENEMY_USER_PAT, // Enemy makes a report
|
||||
)
|
||||
.await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
let value = test::read_body_json::<serde_json::Value, _>(resp).await;
|
||||
let alpha_report_id = value["id"].as_str().unwrap();
|
||||
|
||||
// Confirm existence
|
||||
let resp = api
|
||||
.get_report(
|
||||
alpha_report_id,
|
||||
ENEMY_USER_PAT, // Enemy makes a report
|
||||
)
|
||||
.await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
||||
// Do the same for beta
|
||||
let resp = api
|
||||
.create_report(
|
||||
"copyright",
|
||||
beta_project_id,
|
||||
CommonItemType::Project,
|
||||
"Hey! This is my project, copied without permission!",
|
||||
ENEMY_USER_PAT, // Enemy makes a report
|
||||
)
|
||||
.await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
let value = test::read_body_json::<serde_json::Value, _>(resp).await;
|
||||
let beta_report_id = value["id"].as_str().unwrap();
|
||||
|
||||
// Delete the project
|
||||
let resp = api.remove_project(alpha_project_id, USER_USER_PAT).await;
|
||||
assert_eq!(resp.status(), StatusCode::NO_CONTENT);
|
||||
|
||||
// Confirm that the project is gone from the cache
|
||||
let mut redis_pool = test_env.db.redis_pool.connect().await.unwrap();
|
||||
assert_eq!(
|
||||
redis_pool
|
||||
.get(PROJECTS_SLUGS_NAMESPACE, "demo")
|
||||
.await
|
||||
.unwrap()
|
||||
.and_then(|x| x.parse::<i64>().ok()),
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
redis_pool
|
||||
.get(PROJECTS_SLUGS_NAMESPACE, alpha_project_id)
|
||||
.await
|
||||
.unwrap()
|
||||
.and_then(|x| x.parse::<i64>().ok()),
|
||||
None
|
||||
);
|
||||
|
||||
// Report for alpha no longer exists
|
||||
let resp = api
|
||||
.get_report(
|
||||
alpha_report_id,
|
||||
ENEMY_USER_PAT, // Enemy makes a report
|
||||
)
|
||||
.await;
|
||||
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
|
||||
|
||||
// Confirm that report for beta still exists
|
||||
let resp = api
|
||||
.get_report(
|
||||
beta_report_id,
|
||||
ENEMY_USER_PAT, // Enemy makes a report
|
||||
)
|
||||
.await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn permissions_patch_project_v3() {
|
||||
with_test_environment(Some(8), |test_env: TestEnvironment<ApiV3>| async move {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use itertools::Itertools;
|
||||
use labrinth::routes::v2::tags::DonationPlatformQueryData;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
@@ -62,3 +63,45 @@ async fn get_tags() {
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn get_donation_platforms() {
|
||||
with_test_environment(None, |test_env: TestEnvironment<ApiV2>| async move {
|
||||
let api = &test_env.api;
|
||||
let mut donation_platforms_unsorted = api.get_donation_platforms_deserialized().await;
|
||||
|
||||
// These tests match dummy data and will need to be updated if the dummy data changes
|
||||
let mut included = vec![
|
||||
DonationPlatformQueryData {
|
||||
short: "patreon".to_string(),
|
||||
name: "Patreon".to_string(),
|
||||
},
|
||||
DonationPlatformQueryData {
|
||||
short: "ko-fi".to_string(),
|
||||
name: "Ko-fi".to_string(),
|
||||
},
|
||||
DonationPlatformQueryData {
|
||||
short: "paypal".to_string(),
|
||||
name: "PayPal".to_string(),
|
||||
},
|
||||
DonationPlatformQueryData {
|
||||
short: "bmac".to_string(),
|
||||
name: "Buy Me A Coffee".to_string(),
|
||||
},
|
||||
DonationPlatformQueryData {
|
||||
short: "github".to_string(),
|
||||
name: "GitHub Sponsors".to_string(),
|
||||
},
|
||||
DonationPlatformQueryData {
|
||||
short: "other".to_string(),
|
||||
name: "Other".to_string(),
|
||||
},
|
||||
];
|
||||
|
||||
included.sort_by(|a, b| a.short.cmp(&b.short));
|
||||
donation_platforms_unsorted.sort_by(|a, b| a.short.cmp(&b.short));
|
||||
|
||||
assert_eq!(donation_platforms_unsorted, included);
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user