From a916dd08b1c4175b9e1b9f79c3f28a8d2dbd20a7 Mon Sep 17 00:00:00 2001 From: Wyatt Verchere Date: Thu, 16 Nov 2023 19:55:26 -0800 Subject: [PATCH] finished re-adding tests --- Cargo.lock | 22 ++++ Cargo.toml | 1 + src/models/v2/projects.rs | 3 +- src/routes/v3/project_creation.rs | 1 - tests/common/api_common/generic.rs | 9 +- tests/common/api_common/mod.rs | 32 +++++- tests/common/api_common/models.rs | 3 + tests/common/api_v2/project.rs | 57 ++++++----- tests/common/api_v2/request_data.rs | 24 ++++- tests/common/api_v2/version.rs | 151 +++++++++++---------------- tests/common/api_v3/project.rs | 28 +++-- tests/common/api_v3/request_data.rs | 19 +++- tests/common/api_v3/version.rs | 144 +++++++++++++------------- tests/common/asserts.rs | 11 ++ tests/common/dummy_data.rs | 39 ++++--- tests/common/environment.rs | 6 +- tests/common/permissions.rs | 7 +- tests/loader_fields.rs | 142 +++++++++++++------------- tests/oauth.rs | 20 ++-- tests/oauth_clients.rs | 18 ++-- tests/organizations.rs | 12 +-- tests/search.rs | 152 +++++++++++++--------------- tests/user.rs | 16 +-- tests/v2/project.rs | 18 +--- tests/v2/search.rs | 139 ++++++++++++------------- tests/v2/version.rs | 19 ++-- tests/version.rs | 105 +++++++++++-------- 27 files changed, 626 insertions(+), 572 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06b62adc..1b27597b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2219,6 +2219,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json-patch" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ff1e1486799e3f64129f8ccad108b38290df9cd7015cd31bed17239f0789d6" +dependencies = [ + "serde", + "serde_json", + "thiserror", + "treediff", +] + [[package]] name = "jsonwebtoken" version = "8.3.0" @@ -2267,6 +2279,7 @@ dependencies = [ "hyper-tls", "image", "itertools 0.11.0", + "json-patch", "lazy_static", "lettre", "log", @@ -4674,6 +4687,15 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "treediff" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52984d277bdf2a751072b5df30ec0377febdb02f7696d64c2d7d54630bac4303" +dependencies = [ + "serde_json", +] + [[package]] name = "try-lock" version = "0.2.4" diff --git a/Cargo.toml b/Cargo.toml index bb38733c..52d3953b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -109,3 +109,4 @@ derive-new = "0.5.9" [dev-dependencies] actix-http = "3.4.0" +json-patch = "*" \ No newline at end of file diff --git a/src/models/v2/projects.rs b/src/models/v2/projects.rs index b6a6ce81..5e146c0b 100644 --- a/src/models/v2/projects.rs +++ b/src/models/v2/projects.rs @@ -237,7 +237,8 @@ pub struct LegacyVersion { /// A list of loaders this project supports (has a newtype struct) pub loaders: Vec, - // TODO: remove this once we have v3 testing, as this is a v3 field and tests for it should be isolated to v3 + // TODO: should we remove this? as this is a v3 field and tests for it should be isolated to v3 + // it allows us to keep tests that use this struct in common pub ordering: Option, pub id: VersionId, diff --git a/src/routes/v3/project_creation.rs b/src/routes/v3/project_creation.rs index 584225f4..2faee36e 100644 --- a/src/routes/v3/project_creation.rs +++ b/src/routes/v3/project_creation.rs @@ -894,7 +894,6 @@ async fn create_initial_version( &mut loader_field_enum_values, )?; - println!("Made it past here"); let dependencies = version_data .dependencies .iter() diff --git a/tests/common/api_common/generic.rs b/tests/common/api_common/generic.rs index 9561e8c7..74f61885 100644 --- a/tests/common/api_common/generic.rs +++ b/tests/common/api_common/generic.rs @@ -2,9 +2,9 @@ use std::collections::HashMap; use actix_web::dev::ServiceResponse; use async_trait::async_trait; -use labrinth::{search::SearchResults, models::{teams::{ProjectPermissions, OrganizationPermissions}, projects::VersionType}}; +use labrinth::{search::SearchResults, models::{teams::{ProjectPermissions, OrganizationPermissions}, projects::{VersionType, ProjectId}}}; -use crate::common::{api_v2::ApiV2, api_v3::ApiV3}; +use crate::common::{api_v2::ApiV2, api_v3::ApiV3, dummy_data::TestFile}; use super::{Api, ApiProject, ApiTags, ApiTeams, ApiVersion, models::{CommonProject, CommonImageData, CommonVersion}}; @@ -59,6 +59,7 @@ impl Api for GenericApi { delegate_api_variant!( #[async_trait(?Send)] impl ApiProject for GenericApi { + [add_public_project, (CommonProject, Vec), slug: &str, version_jar: Option, modify_json: Option, pat: &str], [remove_project, ServiceResponse, project_slug_or_id: &str, pat: &str], [get_project, ServiceResponse, id_or_slug: &str, pat: &str], [get_project_deserialized_common, CommonProject, id_or_slug: &str, pat: &str], @@ -107,8 +108,12 @@ delegate_api_variant!( delegate_api_variant!( #[async_trait(?Send)] impl ApiVersion for GenericApi { + [add_public_version, ServiceResponse, project_id: ProjectId, version_number: &str, version_jar: TestFile, ordering: Option, modify_json: Option, pat: &str], + [add_public_version_deserialized_common, CommonVersion, project_id: ProjectId, version_number: &str, version_jar: TestFile, ordering: Option, modify_json: Option, pat: &str], [get_version, ServiceResponse, id_or_slug: &str, pat: &str], [get_version_deserialized_common, CommonVersion, id_or_slug: &str, pat: &str], + [get_versions, ServiceResponse, ids_or_slugs: Vec, pat: &str], + [get_versions_deserialized_common, Vec, ids_or_slugs: Vec, pat: &str], [edit_version, ServiceResponse, id_or_slug: &str, patch: serde_json::Value, pat: &str], [get_version_from_hash, ServiceResponse, id_or_slug: &str, hash: &str, pat: &str], [get_version_from_hash_deserialized_common, CommonVersion, id_or_slug: &str, hash: &str, pat: &str], diff --git a/tests/common/api_common/mod.rs b/tests/common/api_common/mod.rs index ccaa81cf..6bd193ac 100644 --- a/tests/common/api_common/mod.rs +++ b/tests/common/api_common/mod.rs @@ -3,14 +3,15 @@ use std::collections::HashMap; use actix_web::dev::ServiceResponse; use async_trait::async_trait; use chrono::{DateTime, Utc}; -use labrinth::{search::SearchResults, models::{teams::{ProjectPermissions, OrganizationPermissions}, projects::VersionType}, LabrinthConfig}; +use labrinth::{search::SearchResults, models::{teams::{ProjectPermissions, OrganizationPermissions}, projects::{VersionType, ProjectId}}, LabrinthConfig}; use rust_decimal::Decimal; use self::models::{CommonProject, CommonImageData, CommonLoaderData, CommonCategoryData, CommonTeamMember, CommonNotification, CommonVersion}; +use super::dummy_data::TestFile; + pub mod generic; pub mod models; - #[async_trait(?Send)] pub trait ApiBuildable : Api { async fn build(labrinth_config: LabrinthConfig) -> Self; @@ -24,6 +25,13 @@ pub trait Api: ApiProject + ApiTags + ApiTeams + ApiVersion { #[async_trait(?Send)] pub trait ApiProject { + async fn add_public_project( + &self, + slug : &str, + version_jar: Option, + modify_json: Option, + pat: &str, + ) -> (CommonProject, Vec); async fn remove_project(&self, id_or_slug: &str, pat: &str) -> ServiceResponse; async fn get_project(&self, id_or_slug: &str, pat: &str) -> ServiceResponse; async fn get_project_deserialized_common(&self, id_or_slug: &str, pat: &str) -> CommonProject; @@ -66,8 +74,28 @@ pub trait ApiTeams { #[async_trait(?Send)] pub trait ApiVersion { + async fn add_public_version( + &self, + project_id: ProjectId, + version_number: &str, + version_jar: TestFile, + ordering: Option, + modify_json: Option, + pat: &str, + ) -> ServiceResponse; + async fn add_public_version_deserialized_common( + &self, + project_id: ProjectId, + version_number: &str, + version_jar: TestFile, + ordering: Option, + modify_json: Option, + pat: &str, + ) -> CommonVersion; async fn get_version(&self, id_or_slug: &str, pat: &str) -> ServiceResponse; async fn get_version_deserialized_common(&self, id_or_slug: &str, pat: &str) -> CommonVersion; + async fn get_versions(&self, ids_or_slugs: Vec, pat: &str) -> ServiceResponse; + async fn get_versions_deserialized_common(&self, ids_or_slugs: Vec, pat: &str) -> Vec; async fn edit_version(&self, id_or_slug: &str, patch: serde_json::Value, pat: &str) -> ServiceResponse; async fn get_version_from_hash(&self, id_or_slug: &str, hash: &str, pat: &str) -> ServiceResponse; async fn get_version_from_hash_deserialized_common(&self, id_or_slug: &str, hash: &str, pat: &str) -> CommonVersion; diff --git a/tests/common/api_common/models.rs b/tests/common/api_common/models.rs index 992c3013..6c34121a 100644 --- a/tests/common/api_common/models.rs +++ b/tests/common/api_common/models.rs @@ -70,6 +70,9 @@ pub struct CommonVersion { pub requested_status: Option, pub files: Vec, pub dependencies: Vec, + + // TODO: should ordering be in v2? + pub ordering: Option, } #[derive(Deserialize)] diff --git a/tests/common/api_v2/project.rs b/tests/common/api_v2/project.rs index 22f28f36..02644f71 100644 --- a/tests/common/api_v2/project.rs +++ b/tests/common/api_v2/project.rs @@ -1,4 +1,4 @@ -use crate::common::{api_v2::request_data::ProjectCreationRequestData, api_common::{ApiProject, models::{CommonImageData, CommonProject, CommonVersion}, Api}}; +use crate::common::{api_common::{ApiProject, models::{CommonImageData, CommonProject, CommonVersion}, Api}, dummy_data::TestFile}; use actix_http::StatusCode; use actix_web::{ dev::ServiceResponse, @@ -17,14 +17,42 @@ use std::collections::HashMap; use crate::common::{asserts::assert_status, database::MOD_USER_PAT}; -use super::ApiV2; +use super::{ApiV2, request_data::get_public_project_creation_data}; impl ApiV2 { - pub async fn add_public_project( + pub async fn get_project_deserialized(&self, id_or_slug: &str, pat: &str) -> LegacyProject { + let resp = self.get_project(id_or_slug, pat).await; + assert_eq!(resp.status(), 200); + test::read_body_json(resp).await + } + + pub async fn get_user_projects_deserialized( &self, - creation_data: ProjectCreationRequestData, + user_id_or_username: &str, + pat: &str, + ) -> Vec { + let resp = self.get_user_projects(user_id_or_username, pat).await; + assert_eq!(resp.status(), 200); + test::read_body_json(resp).await + } +} + +#[async_trait(?Send)] +impl ApiProject for ApiV2 { + async fn add_public_project( + &self, + slug : &str, + version_jar: Option, + modify_json: Option, pat: &str, ) -> (CommonProject, Vec) { + + let creation_data = get_public_project_creation_data( + slug, + version_jar, + modify_json, + ); + // Add a project. let req = TestRequest::post() .uri("/v2/project") @@ -62,27 +90,6 @@ impl ApiV2 { (project, versions) } - pub async fn get_project_deserialized(&self, id_or_slug: &str, pat: &str) -> LegacyProject { - let resp = self.get_project(id_or_slug, pat).await; - assert_eq!(resp.status(), 200); - test::read_body_json(resp).await - } - - pub async fn get_user_projects_deserialized( - &self, - user_id_or_username: &str, - pat: &str, - ) -> Vec { - let resp = self.get_user_projects(user_id_or_username, pat).await; - assert_eq!(resp.status(), 200); - test::read_body_json(resp).await - } - - -} - -#[async_trait(?Send)] -impl ApiProject for ApiV2 { async fn remove_project(&self, project_slug_or_id: &str, pat: &str) -> ServiceResponse { let req = test::TestRequest::delete() .uri(&format!("/v2/project/{project_slug_or_id}")) diff --git a/tests/common/api_v2/request_data.rs b/tests/common/api_v2/request_data.rs index a7a84c30..332e83f9 100644 --- a/tests/common/api_v2/request_data.rs +++ b/tests/common/api_v2/request_data.rs @@ -28,8 +28,12 @@ pub struct ImageData { pub fn get_public_project_creation_data( slug: &str, version_jar: Option, + modify_json: Option, ) -> ProjectCreationRequestData { - let json_data = get_public_project_creation_data_json(slug, version_jar.as_ref()); + let mut json_data = get_public_project_creation_data_json(slug, version_jar.as_ref()); + if let Some(modify_json) = modify_json { + json_patch::patch(&mut json_data, &modify_json).unwrap(); + } let multipart_data = get_public_creation_data_multipart(&json_data, version_jar.as_ref()); ProjectCreationRequestData { slug: slug.to_string(), @@ -42,9 +46,14 @@ pub fn get_public_version_creation_data( project_id: ProjectId, version_number: &str, version_jar: TestFile, + ordering: Option, + modify_json: Option, ) -> VersionCreationRequestData { - let mut json_data = get_public_version_creation_data_json(version_number, &version_jar); + let mut json_data = get_public_version_creation_data_json(version_number, ordering, &version_jar); json_data["project_id"] = json!(project_id); + if let Some(modify_json) = modify_json { + json_patch::patch(&mut json_data, &modify_json).unwrap(); + } let multipart_data = get_public_creation_data_multipart(&json_data, Some(&version_jar)); VersionCreationRequestData { version: version_number.to_string(), @@ -55,9 +64,10 @@ pub fn get_public_version_creation_data( pub fn get_public_version_creation_data_json( version_number: &str, + ordering: Option, version_jar: &TestFile, ) -> serde_json::Value { - json!({ + let mut j = json!({ "file_parts": [version_jar.filename()], "version_number": version_number, "version_title": "start", @@ -66,7 +76,11 @@ pub fn get_public_version_creation_data_json( "release_channel": "release", "loaders": ["fabric"], "featured": true - }) + }); + if let Some(ordering) = ordering { + j["ordering"] = json!(ordering); + } + j } pub fn get_public_project_creation_data_json( @@ -74,7 +88,7 @@ pub fn get_public_project_creation_data_json( version_jar: Option<&TestFile>, ) -> serde_json::Value { let initial_versions = if let Some(jar) = version_jar { - json!([get_public_version_creation_data_json("1.2.3", jar)]) + json!([get_public_version_creation_data_json("1.2.3", None, jar)]) } else { json!([]) }; diff --git a/tests/common/api_v2/version.rs b/tests/common/api_v2/version.rs index 40fdb26d..3a6d4c41 100644 --- a/tests/common/api_v2/version.rs +++ b/tests/common/api_v2/version.rs @@ -7,15 +7,13 @@ use actix_web::{ }; use async_trait::async_trait; use labrinth::{ - models::{projects::VersionType, v2::projects::LegacyVersion}, + models::{projects::{VersionType, ProjectId}, v2::projects::LegacyVersion}, routes::v2::version_file::FileUpdateData, util::actix::AppendsMultipart, }; use serde_json::json; - -use crate::common::{asserts::assert_status, api_common::{ApiVersion, models::CommonVersion, Api}}; - -use super::{request_data::VersionCreationRequestData, ApiV2}; +use crate::common::{asserts::assert_status, api_common::{ApiVersion, models::CommonVersion, Api}, dummy_data::TestFile}; +use super::{request_data::get_public_version_creation_data, ApiV2}; pub fn url_encode_json_serialized_vec(elements: &[String]) -> String { let serialized = serde_json::to_string(&elements).unwrap(); @@ -23,39 +21,6 @@ pub fn url_encode_json_serialized_vec(elements: &[String]) -> String { } impl ApiV2 { - pub async fn add_public_version( - &self, - creation_data: VersionCreationRequestData, - pat: &str, - ) -> LegacyVersion { - // Add a project. - let req = TestRequest::post() - .uri("/v2/version") - .append_header(("Authorization", pat)) - .set_multipart(creation_data.segment_data) - .to_request(); - let resp = self.call(req).await; - assert_status(&resp, StatusCode::OK); - let value: serde_json::Value = test::read_body_json(resp).await; - let version_id = value["id"].as_str().unwrap(); - - // // Approve as a moderator. - // let req = TestRequest::patch() - // .uri(&format!("/v2/project/{}", creation_data.slug)) - // .append_header(("Authorization", MOD_USER_PAT)) - // .set_json(json!( - // { - // "status": "approved" - // } - // )) - // .to_request(); - // let resp = self.call(req).await; - // assert_status(resp, StatusCode::NO_CONTENT); - - let version = self.get_version(version_id, pat).await; - assert_status(&version, StatusCode::OK); - test::read_body_json(version).await - } pub async fn get_version_deserialized(&self, id: &str, pat: &str) -> LegacyVersion { let resp = self.get_version(id, pat).await; @@ -115,7 +80,50 @@ impl ApiV2 { } #[async_trait(?Send)] -impl ApiVersion for ApiV2{ +impl ApiVersion for ApiV2 { + async fn add_public_version( + &self, + project_id: ProjectId, + version_number: &str, + version_jar: TestFile, + ordering: Option, + modify_json: Option, + pat: &str, + ) -> ServiceResponse { + + let creation_data = get_public_version_creation_data( + project_id, + version_number, + version_jar, + ordering, + modify_json, + ); + + // Add a project. + let req = TestRequest::post() + .uri("/v2/version") + .append_header(("Authorization", pat)) + .set_multipart(creation_data.segment_data) + .to_request(); + self.call(req).await + } + + async fn add_public_version_deserialized_common( + &self, + project_id: ProjectId, + version_number: &str, + version_jar: TestFile, + ordering: Option, + modify_json: Option, + pat: &str, + ) -> CommonVersion { + let resp = self + .add_public_version(project_id, version_number, version_jar, ordering, modify_json, pat) + .await; + assert_eq!(resp.status(), 200); + test::read_body_json(resp).await + } + async fn get_version(&self, id: &str, pat: &str) -> ServiceResponse { let req = TestRequest::get() .uri(&format!("/v2/version/{id}")) @@ -378,65 +386,24 @@ impl ApiVersion for ApiV2{ .to_request(); self.call(request).await } -} -impl ApiV2 { - // TODO: remove redundancy in these functions- these are essentially repeat functions and are probably not necessary - async fn create_default_version( - &self, - project_id: &str, - ordering: Option, - pat: &str, - ) -> CommonVersion { - let json_data = json!( - { - "project_id": project_id, - "file_parts": ["basic-mod-different.jar"], - "version_number": "1.2.3.4", - "version_title": "start", - "dependencies": [], - "game_versions": ["1.20.1"] , - "release_channel": "release", - "loaders": ["fabric"], - "featured": true, - "ordering": ordering, - } - ); - let json_segment = labrinth::util::actix::MultipartSegment { - name: "data".to_string(), - filename: None, - content_type: Some("application/json".to_string()), - data: labrinth::util::actix::MultipartSegmentData::Text( - serde_json::to_string(&json_data).unwrap(), - ), - }; - let file_segment = labrinth::util::actix::MultipartSegment { - name: "basic-mod-different.jar".to_string(), - filename: Some("basic-mod.jar".to_string()), - content_type: Some("application/java-archive".to_string()), - data: labrinth::util::actix::MultipartSegmentData::Binary( - include_bytes!("../../../tests/files/basic-mod-different.jar").to_vec(), - ), - }; - - let request = test::TestRequest::post() - .uri("/v2/version") - .set_multipart(vec![json_segment.clone(), file_segment.clone()]) - .append_header((AUTHORIZATION, pat)) - .to_request(); - let resp = self.call(request).await; - assert_status(&resp, StatusCode::OK); - test::read_body_json(resp).await - } - - async fn get_versions_common(&self, version_ids: Vec, pat: &str) -> Vec { + async fn get_versions(&self, version_ids: Vec, pat: &str) -> ServiceResponse { let ids = url_encode_json_serialized_vec(&version_ids); let request = test::TestRequest::get() .uri(&format!("/v2/versions?ids={}", ids)) .append_header((AUTHORIZATION, pat)) .to_request(); - let resp = self.call(request).await; + self.call(request).await + } + + async fn get_versions_deserialized_common( + &self, + version_ids: Vec, + pat: &str, + ) -> Vec { + let resp = self.get_versions(version_ids, pat).await; assert_status(&resp, StatusCode::OK); test::read_body_json(resp).await - } + } + } \ No newline at end of file diff --git a/tests/common/api_v3/project.rs b/tests/common/api_v3/project.rs index b946b0ef..900f7900 100644 --- a/tests/common/api_v3/project.rs +++ b/tests/common/api_v3/project.rs @@ -9,26 +9,35 @@ use async_trait::async_trait; use bytes::Bytes; use chrono::{DateTime, Utc}; use labrinth::{ - models::v3::projects::{Project, Version}, search::SearchResults, util::actix::AppendsMultipart, }; use rust_decimal::Decimal; use serde_json::json; -use crate::common::{asserts::assert_status, database::MOD_USER_PAT, api_common::{ApiProject, models::{CommonProject, CommonImageData}, Api}}; +use crate::common::{asserts::assert_status, database::MOD_USER_PAT, api_common::{ApiProject, models::{CommonProject, CommonImageData, CommonVersion}, Api}, dummy_data::TestFile}; use super::{ - request_data::ProjectCreationRequestData, + request_data::get_public_project_creation_data, ApiV3, }; -impl ApiV3 { - pub async fn add_public_project( +#[async_trait(?Send)] +impl ApiProject for ApiV3 { + async fn add_public_project( &self, - creation_data: ProjectCreationRequestData, + slug : &str, + version_jar: Option, + modify_json: Option, pat: &str, - ) -> (Project, Vec) { + ) -> (CommonProject, Vec) { + + let creation_data = get_public_project_creation_data( + slug, + version_jar, + modify_json, + ); + // Add a project. let req = TestRequest::post() .uri("/v3/project") @@ -62,14 +71,11 @@ impl ApiV3 { .append_header(("Authorization", pat)) .to_request(); let resp = self.call(req).await; - let versions: Vec = test::read_body_json(resp).await; + let versions: Vec = test::read_body_json(resp).await; (project, versions) } -} -#[async_trait(?Send)] -impl ApiProject for ApiV3 { async fn remove_project(&self, project_slug_or_id: &str, pat: &str) -> ServiceResponse { let req = test::TestRequest::delete() .uri(&format!("/v3/project/{project_slug_or_id}")) diff --git a/tests/common/api_v3/request_data.rs b/tests/common/api_v3/request_data.rs index 6091992c..17d55e4d 100644 --- a/tests/common/api_v3/request_data.rs +++ b/tests/common/api_v3/request_data.rs @@ -28,8 +28,12 @@ pub struct ImageData { pub fn get_public_project_creation_data( slug: &str, version_jar: Option, + modify_json: Option, ) -> ProjectCreationRequestData { - let json_data = get_public_project_creation_data_json(slug, version_jar.as_ref()); + let mut json_data = get_public_project_creation_data_json(slug, version_jar.as_ref()); + if let Some(modify_json) = modify_json { + json_patch::patch(&mut json_data, &modify_json).unwrap(); + } let multipart_data = get_public_creation_data_multipart(&json_data, version_jar.as_ref()); ProjectCreationRequestData { slug: slug.to_string(), @@ -42,14 +46,15 @@ pub fn get_public_version_creation_data( project_id: ProjectId, version_number: &str, version_jar: TestFile, + ordering: Option, // closure that takes in a &mut serde_json::Value // and modifies it before it is serialized and sent - modify_json: Option, + modify_json: Option, ) -> VersionCreationRequestData { - let mut json_data = get_public_version_creation_data_json(version_number, &version_jar); + let mut json_data = get_public_version_creation_data_json(version_number, ordering, &version_jar); json_data["project_id"] = json!(project_id); if let Some(modify_json) = modify_json { - modify_json(&mut json_data); + json_patch::patch(&mut json_data, &modify_json).unwrap(); } let multipart_data = get_public_creation_data_multipart(&json_data, Some(&version_jar)); @@ -62,6 +67,7 @@ pub fn get_public_version_creation_data( pub fn get_public_version_creation_data_json( version_number: &str, + ordering: Option, version_jar: &TestFile, ) -> serde_json::Value { let is_modpack = version_jar.project_type() == "modpack"; @@ -82,6 +88,9 @@ pub fn get_public_version_creation_data_json( if is_modpack { j["mrpack_loaders"] = json!(["fabric"]); } + if let Some(ordering) = ordering { + j["ordering"] = json!(ordering); + } j } @@ -90,7 +99,7 @@ pub fn get_public_project_creation_data_json( version_jar: Option<&TestFile>, ) -> serde_json::Value { let initial_versions = if let Some(jar) = version_jar { - json!([get_public_version_creation_data_json("1.2.3", jar)]) + json!([get_public_version_creation_data_json("1.2.3", None, jar)]) } else { json!([]) }; diff --git a/tests/common/api_v3/version.rs b/tests/common/api_v3/version.rs index cc68d914..98ace215 100644 --- a/tests/common/api_v3/version.rs +++ b/tests/common/api_v3/version.rs @@ -7,15 +7,13 @@ use actix_web::{ }; use async_trait::async_trait; use labrinth::{ - models::{projects::VersionType, v3::projects::Version}, + models::{projects::{VersionType, ProjectId}, v3::projects::Version}, routes::v3::version_file::FileUpdateData, util::actix::AppendsMultipart, }; use serde_json::json; - -use crate::common::{asserts::assert_status, api_common::{ApiVersion, models::CommonVersion, Api}}; - -use super::{request_data::VersionCreationRequestData, ApiV3}; +use crate::common::{asserts::assert_status, api_common::{ApiVersion, models::CommonVersion, Api}, dummy_data::TestFile}; +use super::{request_data::get_public_version_creation_data, ApiV3}; pub fn url_encode_json_serialized_vec(elements: &[String]) -> String { let serialized = serde_json::to_string(&elements).unwrap(); @@ -23,26 +21,23 @@ pub fn url_encode_json_serialized_vec(elements: &[String]) -> String { } impl ApiV3 { - pub async fn add_public_version( - &self, - creation_data: VersionCreationRequestData, - pat: &str, - ) -> ServiceResponse { - // Add a project. - let req = TestRequest::post() - .uri("/v3/version") - .append_header(("Authorization", pat)) - .set_multipart(creation_data.segment_data) - .to_request(); - self.call(req).await - } - pub async fn add_public_version_deserialized( &self, - creation_data: VersionCreationRequestData, + project_id: ProjectId, + version_number: &str, + version_jar: TestFile, + ordering: Option, + modify_json: Option, pat: &str, ) -> Version { - let resp = self.add_public_version(creation_data, pat).await; + let resp = self.add_public_version( + project_id, + version_number, + version_jar, + ordering, + modify_json, + pat, + ).await; assert_status(&resp, StatusCode::OK); let value: serde_json::Value = test::read_body_json(resp).await; let version_id = value["id"].as_str().unwrap(); @@ -88,6 +83,49 @@ impl ApiV3 { #[async_trait(?Send)] impl ApiVersion for ApiV3 { + async fn add_public_version( + &self, + project_id: ProjectId, + version_number: &str, + version_jar: TestFile, + ordering: Option, + modify_json: Option, + pat: &str, + ) -> ServiceResponse { + + let creation_data = get_public_version_creation_data( + project_id, + version_number, + version_jar, + ordering, + modify_json, + ); + + // Add a versiom. + let req = TestRequest::post() + .uri("/v3/version") + .append_header(("Authorization", pat)) + .set_multipart(creation_data.segment_data) + .to_request(); + self.call(req).await + } + + async fn add_public_version_deserialized_common( + &self, + project_id: ProjectId, + version_number: &str, + version_jar: TestFile, + ordering: Option, + modify_json: Option, + pat: &str, + ) -> CommonVersion { + let resp = self + .add_public_version(project_id, version_number, version_jar, ordering, modify_json, pat) + .await; + assert_status(&resp, StatusCode::OK); + test::read_body_json(resp).await + } + async fn get_version(&self, id: &str, pat: &str) -> ServiceResponse { let req = TestRequest::get() .uri(&format!("/v3/version/{id}")) @@ -370,66 +408,22 @@ impl ApiVersion for ApiV3 { .to_request(); self.call(request).await } -} -impl ApiV3 { - - pub async fn create_default_version( - &self, - project_id: &str, - ordering: Option, - pat: &str, - ) -> Version { - let json_data = json!( - { - "project_id": project_id, - "file_parts": ["basic-mod-different.jar"], - "version_number": "1.2.3.4", - "version_title": "start", - "dependencies": [], - "game_versions": ["1.20.1"] , - "client_side": "required", - "server_side": "optional", - "release_channel": "release", - "loaders": ["fabric"], - "featured": true, - "ordering": ordering, - } - ); - let json_segment = labrinth::util::actix::MultipartSegment { - name: "data".to_string(), - filename: None, - content_type: Some("application/json".to_string()), - data: labrinth::util::actix::MultipartSegmentData::Text( - serde_json::to_string(&json_data).unwrap(), - ), - }; - let file_segment = labrinth::util::actix::MultipartSegment { - name: "basic-mod-different.jar".to_string(), - filename: Some("basic-mod.jar".to_string()), - content_type: Some("application/java-archive".to_string()), - data: labrinth::util::actix::MultipartSegmentData::Binary( - include_bytes!("../../../tests/files/basic-mod-different.jar").to_vec(), - ), - }; - - let request = test::TestRequest::post() - .uri("/v3/version") - .set_multipart(vec![json_segment.clone(), file_segment.clone()]) - .append_header((AUTHORIZATION, pat)) - .to_request(); - let resp = self.call(request).await; - assert_status(&resp, StatusCode::OK); - test::read_body_json(resp).await - } - - pub async fn get_versions(&self, version_ids: Vec, pat: &str) -> Vec { + async fn get_versions(&self, version_ids: Vec, pat: &str) -> ServiceResponse { let ids = url_encode_json_serialized_vec(&version_ids); let request = test::TestRequest::get() .uri(&format!("/v3/versions?ids={}", ids)) .append_header((AUTHORIZATION, pat)) .to_request(); - let resp = self.call(request).await; + self.call(request).await + } + + async fn get_versions_deserialized_common( + &self, + version_ids: Vec, + pat: &str, + ) -> Vec { + let resp = self.get_versions(version_ids, pat).await; assert_status(&resp, StatusCode::OK); test::read_body_json(resp).await } diff --git a/tests/common/asserts.rs b/tests/common/asserts.rs index cc6e35a6..97fbaecd 100644 --- a/tests/common/asserts.rs +++ b/tests/common/asserts.rs @@ -4,6 +4,8 @@ use crate::common::get_json_val_str; use itertools::Itertools; use labrinth::models::v3::projects::Version; +use super::api_common::models::CommonVersion; + pub fn assert_status(response: &actix_web::dev::ServiceResponse, status: actix_http::StatusCode) { assert_eq!(response.status(), status, "{:#?}", response.response()); } @@ -16,6 +18,15 @@ pub fn assert_version_ids(versions: &[Version], expected_ids: Vec) { assert_eq!(version_ids, expected_ids); } +pub fn assert_common_version_ids(versions: &[CommonVersion], expected_ids: Vec) { + let version_ids = versions + .iter() + .map(|v| get_json_val_str(v.id)) + .collect_vec(); + assert_eq!(version_ids, expected_ids); +} + + pub fn assert_any_status_except( response: &actix_web::dev::ServiceResponse, status: actix_http::StatusCode, diff --git a/tests/common/dummy_data.rs b/tests/common/dummy_data.rs index 43140de2..76e8525a 100644 --- a/tests/common/dummy_data.rs +++ b/tests/common/dummy_data.rs @@ -6,8 +6,7 @@ use actix_web::test::{self, TestRequest}; use labrinth::models::{ oauth_clients::OAuthClient, organizations::Organization, - pats::Scopes, - v3::projects::{Project, Version}, + pats::Scopes, projects::ProjectId, }; use serde_json::json; use sqlx::Executor; @@ -16,7 +15,7 @@ use zip::{write::FileOptions, CompressionMethod, ZipWriter}; use crate::common::{database::USER_USER_PAT, api_common::Api}; use labrinth::util::actix::{AppendsMultipart, MultipartSegment, MultipartSegmentData}; -use super::{api_v3::{request_data::get_public_project_creation_data, ApiV3}, database::TemporaryDatabase}; +use super::{api_v3::ApiV3, database::TemporaryDatabase, api_common::{ApiProject, models::{CommonProject, CommonVersion}}}; use super::{asserts::assert_status, database::USER_USER_ID, get_json_val_str}; @@ -170,10 +169,10 @@ pub struct DummyData { impl DummyData { pub fn new( - project_alpha: Project, - project_alpha_version: Version, - project_beta: Project, - project_beta_version: Version, + project_alpha: CommonProject, + project_alpha_version: CommonVersion, + project_beta: CommonProject, + project_beta_version: CommonVersion, organization_zeta: Organization, oauth_client_alpha: OAuthClient, ) -> Self { @@ -182,6 +181,7 @@ impl DummyData { team_id: project_alpha.team.to_string(), project_id: project_alpha.id.to_string(), project_slug: project_alpha.slug.unwrap(), + project_id_parsed: project_alpha.id, version_id: project_alpha_version.id.to_string(), thread_id: project_alpha.thread_id.to_string(), file_hash: project_alpha_version.files[0].hashes["sha1"].clone(), @@ -191,6 +191,7 @@ impl DummyData { team_id: project_beta.team.to_string(), project_id: project_beta.id.to_string(), project_slug: project_beta.slug.unwrap(), + project_id_parsed: project_beta.id, version_id: project_beta_version.id.to_string(), thread_id: project_beta.thread_id.to_string(), file_hash: project_beta_version.files[0].hashes["sha1"].clone(), @@ -220,6 +221,7 @@ impl DummyData { pub struct DummyProjectAlpha { pub project_id: String, pub project_slug: String, + pub project_id_parsed: ProjectId, pub version_id: String, pub thread_id: String, pub file_hash: String, @@ -230,6 +232,7 @@ pub struct DummyProjectAlpha { pub struct DummyProjectBeta { pub project_id: String, pub project_slug: String, + pub project_id_parsed: ProjectId, pub version_id: String, pub thread_id: String, pub file_hash: String, @@ -303,17 +306,13 @@ pub async fn get_dummy_data(api: &ApiV3) -> DummyData { ) } -pub async fn add_project_alpha(api: &ApiV3) -> (Project, Version) { +pub async fn add_project_alpha(api: &ApiV3) -> (CommonProject, CommonVersion) { let (project, versions) = api - .add_public_project( - get_public_project_creation_data("alpha", Some(TestFile::DummyProjectAlpha)), - USER_USER_PAT, - ) - .await; + .add_public_project("alpha", Some(TestFile::DummyProjectAlpha), None, USER_USER_PAT).await; (project, versions.into_iter().next().unwrap()) } -pub async fn add_project_beta(api: &ApiV3) -> (Project, Version) { +pub async fn add_project_beta(api: &ApiV3) -> (CommonProject, CommonVersion) { // Adds dummy data to the database with sqlx (projects, versions, threads) // Generate test project data. let jar = TestFile::DummyProjectBeta; @@ -389,14 +388,14 @@ pub async fn add_organization_zeta(api: &ApiV3) -> Organization { get_organization_zeta(api).await } -pub async fn get_project_alpha(api: &ApiV3) -> (Project, Version) { +pub async fn get_project_alpha(api: &ApiV3) -> (CommonProject, CommonVersion) { // Get project let req = TestRequest::get() .uri("/v3/project/alpha") .append_header(("Authorization", USER_USER_PAT)) .to_request(); let resp = api.call(req).await; - let project: Project = test::read_body_json(resp).await; + let project: CommonProject = test::read_body_json(resp).await; // Get project's versions let req = TestRequest::get() @@ -404,13 +403,13 @@ pub async fn get_project_alpha(api: &ApiV3) -> (Project, Version) { .append_header(("Authorization", USER_USER_PAT)) .to_request(); let resp = api.call(req).await; - let versions: Vec = test::read_body_json(resp).await; + let versions: Vec = test::read_body_json(resp).await; let version = versions.into_iter().next().unwrap(); (project, version) } -pub async fn get_project_beta(api : &ApiV3) -> (Project, Version) { +pub async fn get_project_beta(api : &ApiV3) -> (CommonProject, CommonVersion) { // Get project let req = TestRequest::get() .uri("/v3/project/beta") @@ -419,7 +418,7 @@ pub async fn get_project_beta(api : &ApiV3) -> (Project, Version) { let resp = api.call(req).await; assert_status(&resp, StatusCode::OK); let project: serde_json::Value = test::read_body_json(resp).await; - let project: Project = serde_json::from_value(project).unwrap(); + let project: CommonProject = serde_json::from_value(project).unwrap(); // Get project's versions let req = TestRequest::get() @@ -428,7 +427,7 @@ pub async fn get_project_beta(api : &ApiV3) -> (Project, Version) { .to_request(); let resp = api.call(req).await; assert_status(&resp, StatusCode::OK); - let versions: Vec = test::read_body_json(resp).await; + let versions: Vec = test::read_body_json(resp).await; let version = versions.into_iter().next().unwrap(); (project, version) diff --git a/tests/common/environment.rs b/tests/common/environment.rs index b7a35266..465101db 100644 --- a/tests/common/environment.rs +++ b/tests/common/environment.rs @@ -34,23 +34,25 @@ where Fut: Future, F: Fn(TestEnvironment) -> Fut, { + println!("Test environment: API v3"); let test_env_api_v3 = TestEnvironment::::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: None, + 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::::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: None, + dummy: test_env_api_v2.dummy, }; let db = test_env_api_v2.db.clone(); f(test_env_api_v2).await; diff --git a/tests/common/permissions.rs b/tests/common/permissions.rs index af896b7a..b8a7eb72 100644 --- a/tests/common/permissions.rs +++ b/tests/common/permissions.rs @@ -7,9 +7,9 @@ use serde_json::json; use crate::common::{database::{generate_random_name, ADMIN_USER_PAT}, api_common::ApiTeams}; use super::{ - api_v3::{request_data, ApiV3}, + api_v3::ApiV3, database::{ENEMY_USER_PAT, USER_USER_ID, USER_USER_PAT}, - environment::TestEnvironment, api_common::Api, + environment::TestEnvironment, api_common::{Api, ApiProject}, }; // A reusable test type that works for any permissions test testing an endpoint that: @@ -919,8 +919,7 @@ async fn create_dummy_project(setup_api: &ApiV3) -> (String, String) { // Create a very simple project let slug = generate_random_name("test_project"); - let creation_data = request_data::get_public_project_creation_data(&slug, None); - let (project, _) = setup_api.add_public_project(creation_data, ADMIN_USER_PAT).await; + let (project, _) = setup_api.add_public_project(&slug, None, None, ADMIN_USER_PAT).await; let project_id = project.id.to_string(); let team_id = project.team.to_string(); diff --git a/tests/loader_fields.rs b/tests/loader_fields.rs index 832ebec7..c3cf7bb4 100644 --- a/tests/loader_fields.rs +++ b/tests/loader_fields.rs @@ -5,7 +5,6 @@ use common::environment::{with_test_environment, TestEnvironment}; use serde_json::json; use crate::common::api_common::ApiVersion; -use crate::common::api_v3::request_data::get_public_version_creation_data; use crate::common::database::*; use crate::common::dummy_data::TestFile; @@ -38,15 +37,15 @@ async fn creating_loader_fields() { // Cannot create a version with an extra argument that cannot be tied to a loader field ("invalid loader field") // TODO: - Create project // - Create version - let version_data = get_public_version_creation_data( - alpha_project_id, + let resp = api.add_public_version(alpha_project_id, "1.0.0", TestFile::build_random_jar(), - Some(|j: &mut serde_json::Value| { - j["invalid"] = json!("invalid"); - }), - ); - let resp = api.add_public_version(version_data, USER_USER_PAT).await; + None, + Some(serde_json::from_value(json!([{ + "op": "add", + "path": "/invalid", + "value": "invalid" + }])).unwrap()), USER_USER_PAT).await; assert_eq!(resp.status(), 400); // - Patch let resp = api @@ -63,16 +62,15 @@ async fn creating_loader_fields() { // Cannot create a version with a loader field that isnt used by the loader // TODO: - Create project // - Create version - let version_data = get_public_version_creation_data( - alpha_project_id, + let resp = api.add_public_version(alpha_project_id, "1.0.0", TestFile::build_random_jar(), - Some(|j: &mut serde_json::Value| { - // This is only for mrpacks, not mods/jars - j["mrpack_loaders"] = json!(["fabric"]); - }), - ); - let resp = api.add_public_version(version_data, USER_USER_PAT).await; + None, + Some(serde_json::from_value(json!([{ + "op": "add", + "path": "/mrpack_loaders", + "value": ["fabric"] + }])).unwrap()), USER_USER_PAT).await; assert_eq!(resp.status(), 400); // - Patch let resp = api @@ -89,48 +87,44 @@ async fn creating_loader_fields() { // Cannot create a version without an applicable loader field that is not optional // TODO: - Create project // - Create version - let version_data = get_public_version_creation_data( - alpha_project_id, + let resp = api.add_public_version(alpha_project_id, "1.0.0", TestFile::build_random_jar(), - Some(|j: &mut serde_json::Value| { - let j = j.as_object_mut().unwrap(); - j.remove("client_side"); - }), - ); - let resp = api.add_public_version(version_data, USER_USER_PAT).await; + None, + Some(serde_json::from_value(json!([{ + "op": "remove", + "path": "/client_side" + }])).unwrap()), USER_USER_PAT).await; + assert_eq!(resp.status(), 400); // Cannot create a version without a loader field array that has a minimum of 1 // TODO: - Create project // - Create version - let version_data = get_public_version_creation_data( - alpha_project_id, + let resp = api.add_public_version(alpha_project_id, "1.0.0", TestFile::build_random_jar(), - Some(|j: &mut serde_json::Value| { - let j = j.as_object_mut().unwrap(); - j.remove("game_versions"); - }), - ); - let resp = api.add_public_version(version_data, USER_USER_PAT).await; + None, + Some(serde_json::from_value(json!([{ + "op": "remove", + "path": "/game_versions" + }])).unwrap()), USER_USER_PAT).await; assert_eq!(resp.status(), 400); // Cannot create a version with a loader field array that has fewer than the minimum elements or more than the maximum elements for gvs in [vec![], ["1.20.1"].repeat(30)] { // TODO: - Create project // - Create version - let version_data = get_public_version_creation_data( - alpha_project_id, - "1.0.0", - TestFile::build_random_jar(), - Some(|j: &mut serde_json::Value| { - let j: &mut serde_json::Map = j.as_object_mut().unwrap(); - j["game_versions"] = json!(gvs); - }), - ); let resp: actix_web::dev::ServiceResponse = - api.add_public_version(version_data, USER_USER_PAT).await; + api.add_public_version(alpha_project_id, + "1.0.0", + TestFile::build_random_jar(), + None, + Some(serde_json::from_value(json!([{ + "op": "add", + "path": "/game_versions", + "value": gvs + }])).unwrap()), USER_USER_PAT).await; assert_eq!(resp.status(), 400); // - Patch @@ -155,16 +149,16 @@ async fn creating_loader_fields() { ] { // TODO: - Create project // - Create version - let version_data = get_public_version_creation_data( - alpha_project_id, + let resp = api.add_public_version(alpha_project_id, "1.0.0", TestFile::build_random_jar(), - Some(|j: &mut serde_json::Value| { - let j: &mut serde_json::Map = j.as_object_mut().unwrap(); - j["game_versions"] = bad_type_game_versions.clone(); - }), - ); - let resp = api.add_public_version(version_data, USER_USER_PAT).await; + None, + Some(serde_json::from_value(json!([{ + "op": "add", + "path": "/game_versions", + "value": bad_type_game_versions + }])).unwrap()), + USER_USER_PAT).await; assert_eq!(resp.status(), 400); // - Patch @@ -183,16 +177,15 @@ async fn creating_loader_fields() { // Can create with optional loader fields (other tests have checked if we can create without them) // TODO: - Create project // - Create version - let version_data = get_public_version_creation_data( - alpha_project_id, - "1.0.0", - TestFile::build_random_jar(), - Some(|j: &mut serde_json::Value| { - j["test_fabric_optional"] = json!(555); - }), - ); let v = api - .add_public_version_deserialized(version_data, USER_USER_PAT) + .add_public_version_deserialized(alpha_project_id, "1.0.0", TestFile::build_random_jar(), + None, + Some(serde_json::from_value(json!([{ + "op": "add", + "path": "/test_fabric_optional", + "value": 555 + }])).unwrap()), + USER_USER_PAT) .await; assert_eq!(v.fields.get("test_fabric_optional").unwrap(), &json!(555)); // - Patch @@ -213,19 +206,26 @@ async fn creating_loader_fields() { // Simply setting them as expected works // - Create - let version_data = get_public_version_creation_data( - alpha_project_id, - "1.0.0", - TestFile::build_random_jar(), - Some(|j: &mut serde_json::Value| { - let j: &mut serde_json::Map = j.as_object_mut().unwrap(); - j["game_versions"] = json!(["1.20.1", "1.20.2"]); - j["client_side"] = json!("optional"); - j["server_side"] = json!("required"); - }), - ); let v = api - .add_public_version_deserialized(version_data, USER_USER_PAT) + .add_public_version_deserialized(alpha_project_id, + "1.0.0", + TestFile::build_random_jar(), + None, + Some(serde_json::from_value(json!([{ + "op": "add", + "path": "/game_versions", + "value": ["1.20.1", "1.20.2"] + }, { + "op": "add", + "path": "/client_side", + "value": "optional" + }, { + "op": "add", + "path": "/server_side", + "value": "required" + }])).unwrap()), + + USER_USER_PAT) .await; assert_eq!( v.fields.get("game_versions").unwrap(), diff --git a/tests/oauth.rs b/tests/oauth.rs index c1ddb4e9..62922e67 100644 --- a/tests/oauth.rs +++ b/tests/oauth.rs @@ -2,12 +2,12 @@ use actix_http::StatusCode; use actix_web::test::{self}; use common::{ api_v3::oauth::get_redirect_location_query_params, - api_v3::oauth::{get_auth_code_from_redirect_params, get_authorize_accept_flow_id}, + api_v3::{oauth::{get_auth_code_from_redirect_params, get_authorize_accept_flow_id}, ApiV3}, asserts::{assert_any_status_except, assert_status}, database::FRIEND_USER_ID, database::{FRIEND_USER_PAT, USER_USER_ID, USER_USER_PAT}, dummy_data::DummyOAuthClientAlpha, - environment::{with_test_environment, with_test_environment_all}, + environment::{with_test_environment, TestEnvironment}, }; use labrinth::auth::oauth::TokenResponse; use reqwest::header::{CACHE_CONTROL, PRAGMA}; @@ -16,7 +16,7 @@ mod common; #[actix_rt::test] async fn oauth_flow_happy_path() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let DummyOAuthClientAlpha { valid_redirect_uri: base_redirect_uri, client_id, @@ -78,7 +78,7 @@ async fn oauth_flow_happy_path() { #[actix_rt::test] async fn oauth_authorize_for_already_authorized_scopes_returns_auth_code() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let DummyOAuthClientAlpha { client_id, .. } = env.dummy.unwrap().oauth_client_alpha.clone(); let resp = env @@ -111,7 +111,7 @@ async fn oauth_authorize_for_already_authorized_scopes_returns_auth_code() { #[actix_rt::test] async fn get_oauth_token_with_already_used_auth_code_fails() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let DummyOAuthClientAlpha { client_id, client_secret, @@ -144,7 +144,7 @@ async fn get_oauth_token_with_already_used_auth_code_fails() { #[actix_rt::test] async fn authorize_with_broader_scopes_can_complete_flow() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let DummyOAuthClientAlpha { client_id, client_secret, @@ -193,7 +193,7 @@ async fn authorize_with_broader_scopes_can_complete_flow() { #[actix_rt::test] async fn oauth_authorize_with_broader_scopes_requires_user_accept() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let client_id = env.dummy.unwrap().oauth_client_alpha.client_id.clone(); let resp = env .api @@ -221,7 +221,7 @@ async fn oauth_authorize_with_broader_scopes_requires_user_accept() { #[actix_rt::test] async fn reject_authorize_ends_authorize_flow() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let client_id = env.dummy.unwrap().oauth_client_alpha.client_id.clone(); let resp = env .api @@ -240,7 +240,7 @@ async fn reject_authorize_ends_authorize_flow() { #[actix_rt::test] async fn accept_authorize_after_already_accepting_fails() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let client_id = env.dummy.unwrap().oauth_client_alpha.client_id.clone(); let resp = env .api @@ -258,7 +258,7 @@ async fn accept_authorize_after_already_accepting_fails() { #[actix_rt::test] async fn revoke_authorization_after_issuing_token_revokes_token() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let DummyOAuthClientAlpha { client_id, client_secret, diff --git a/tests/oauth_clients.rs b/tests/oauth_clients.rs index 002146bb..7648bdd2 100644 --- a/tests/oauth_clients.rs +++ b/tests/oauth_clients.rs @@ -3,8 +3,8 @@ use actix_web::test; use common::{ database::{FRIEND_USER_ID, FRIEND_USER_PAT, USER_USER_ID, USER_USER_PAT}, dummy_data::DummyOAuthClientAlpha, - environment::with_test_environment_all, - get_json_val_str, + environment::{with_test_environment, TestEnvironment}, + get_json_val_str, api_v3::ApiV3, }; use labrinth::{ models::{ @@ -20,7 +20,7 @@ mod common; #[actix_rt::test] async fn can_create_edit_get_oauth_client() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let client_name = "test_client".to_string(); let redirect_uris = vec![ "https://modrinth.com".to_string(), @@ -72,7 +72,7 @@ async fn can_create_edit_get_oauth_client() { #[actix_rt::test] async fn create_oauth_client_with_restricted_scopes_fails() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let resp = env .api .add_oauth_client( @@ -90,7 +90,7 @@ async fn create_oauth_client_with_restricted_scopes_fails() { #[actix_rt::test] async fn get_oauth_client_for_client_creator_succeeds() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let DummyOAuthClientAlpha { client_id, .. } = env.dummy.as_ref().unwrap().oauth_client_alpha.clone(); @@ -108,7 +108,7 @@ async fn get_oauth_client_for_client_creator_succeeds() { #[actix_rt::test] async fn get_oauth_client_for_unrelated_user_fails() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let DummyOAuthClientAlpha { client_id, .. } = env.dummy.as_ref().unwrap().oauth_client_alpha.clone(); @@ -124,7 +124,7 @@ async fn get_oauth_client_for_unrelated_user_fails() { #[actix_rt::test] async fn can_delete_oauth_client() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let client_id = env.dummy.unwrap().oauth_client_alpha.client_id.clone(); let resp = env.api.delete_oauth_client(&client_id, USER_USER_PAT).await; assert_status(&resp, StatusCode::NO_CONTENT); @@ -140,7 +140,7 @@ async fn can_delete_oauth_client() { #[actix_rt::test] async fn delete_oauth_client_after_issuing_access_tokens_revokes_tokens() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let DummyOAuthClientAlpha { client_id, client_secret, @@ -168,7 +168,7 @@ async fn delete_oauth_client_after_issuing_access_tokens_revokes_tokens() { #[actix_rt::test] async fn can_list_user_oauth_authorizations() { - with_test_environment_all(None, |env| async move { + with_test_environment(None, |env: TestEnvironment| async move { let DummyOAuthClientAlpha { client_id, client_secret, diff --git a/tests/organizations.rs b/tests/organizations.rs index 4f755def..30c5e748 100644 --- a/tests/organizations.rs +++ b/tests/organizations.rs @@ -7,7 +7,7 @@ use actix_web::test; use bytes::Bytes; use common::{ database::{FRIEND_USER_ID, FRIEND_USER_PAT, USER_USER_PAT}, - permissions::{PermissionsTest, PermissionsTestContext}, environment::with_test_environment_all, api_common::generic::GenericApi, + permissions::{PermissionsTest, PermissionsTestContext}, environment::{with_test_environment_all, TestEnvironment, with_test_environment}, api_v3::ApiV3, }; use labrinth::models::teams::{OrganizationPermissions, ProjectPermissions}; use serde_json::json; @@ -16,7 +16,7 @@ mod common; #[actix_rt::test] async fn create_organization() { - with_test_environment_all(None, |test_env| async move { + with_test_environment(None, |test_env: TestEnvironment| async move { let api = &test_env.api; let zeta_organization_slug = &test_env .dummy @@ -83,7 +83,7 @@ async fn create_organization() { #[actix_rt::test] async fn patch_organization() { - with_test_environment_all(None, |test_env| async move { + with_test_environment(None, |test_env: TestEnvironment| async move { let api = &test_env.api; let zeta_organization_id = &test_env @@ -164,7 +164,7 @@ async fn patch_organization() { // add/remove icon #[actix_rt::test] async fn add_remove_icon() { - with_test_environment_all(None, |test_env| async move { + with_test_environment(None, |test_env: TestEnvironment| async move { let api = &test_env.api; let zeta_organization_id = &test_env .dummy @@ -215,7 +215,7 @@ async fn add_remove_icon() { // delete org #[actix_rt::test] async fn delete_org() { - with_test_environment_all(None, |test_env| async move { + with_test_environment(None, |test_env: TestEnvironment| async move { let api = &test_env.api; let zeta_organization_id = &test_env .dummy @@ -240,7 +240,7 @@ async fn delete_org() { // add/remove organization projects #[actix_rt::test] async fn add_remove_organization_projects() { - with_test_environment_all(None, |test_env| async move { + with_test_environment(None, |test_env: TestEnvironment| async move { let alpha_project_id: &str = &test_env.dummy.as_ref().unwrap().project_alpha.project_id; let alpha_project_slug: &str = &test_env.dummy.as_ref().unwrap().project_alpha.project_slug; let zeta_organization_id: &str = &test_env diff --git a/tests/search.rs b/tests/search.rs index 31e6bbb6..e541a1d1 100644 --- a/tests/search.rs +++ b/tests/search.rs @@ -1,8 +1,10 @@ +use common::api_v3::ApiV3; use common::database::*; use common::dummy_data::TestFile; use common::dummy_data::DUMMY_CATEGORIES; -use common::environment::with_test_environment_all; +use common::environment::TestEnvironment; +use common::environment::with_test_environment; use futures::stream::StreamExt; use labrinth::models::ids::base62_impl::parse_base62; use serde_json::json; @@ -11,9 +13,7 @@ use std::sync::Arc; use crate::common::api_common::Api; use crate::common::api_common::ApiProject; -use crate::common::api_v3::request_data::{ - self, get_public_version_creation_data, ProjectCreationRequestData, -}; +use crate::common::api_common::ApiVersion; mod common; @@ -23,7 +23,7 @@ mod common; #[actix_rt::test] async fn search_projects() { // Test setup and dummy data - with_test_environment_all(Some(8), |test_env| async move { + with_test_environment(Some(8), |test_env : TestEnvironment| async move { let api = &test_env.api; let test_name = test_env.db.database_name.clone(); @@ -34,7 +34,7 @@ async fn search_projects() { |id: u64, pat: &'static str, is_modpack: bool, - modify_json: Box| { + modify_json: Option| { let slug = format!("{test_name}-searchable-project-{id}"); let jar = if is_modpack { @@ -42,21 +42,14 @@ async fn search_projects() { } else { TestFile::build_random_jar() }; - let mut basic_project_json = - request_data::get_public_project_creation_data_json(&slug, Some(&jar)); - modify_json(&mut basic_project_json); - let basic_project_multipart = - request_data::get_public_creation_data_multipart(&basic_project_json, Some(&jar)); - // Add a project- simple, should work. - let req = api.add_public_project( - ProjectCreationRequestData { - slug, - jar: Some(jar), - segment_data: basic_project_multipart, - }, - pat, - ); async move { + // Add a project- simple, should work. + let req = api.add_public_project( + &slug, + Some(jar), + modify_json, + pat, + ); let (project, _) = req.await; // Approve, so that the project is searchable @@ -76,122 +69,122 @@ async fn search_projects() { // Test project 0 let id = 0; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[4..6]); - json["initial_versions"][0]["server_side"] = json!("required"); - json["license_id"] = json!("LGPL-3.0-or-later"); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[4..6] }, + { "op": "add", "path": "/initial_versions/0/server_side", "value": "required" }, + { "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Test project 1 let id = 1; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[0..2]); - json["initial_versions"][0]["client_side"] = json!("optional"); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..2] }, + { "op": "add", "path": "/initial_versions/0/client_side", "value": "optional" }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Test project 2 let id = 2; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[0..2]); - json["initial_versions"][0]["server_side"] = json!("required"); - json["title"] = json!("Mysterious Project"); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..2] }, + { "op": "add", "path": "/initial_versions/0/server_side", "value": "required" }, + { "op": "add", "path": "/title", "value": "Mysterious Project" }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Test project 3 let id = 3; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[0..3]); - json["initial_versions"][0]["server_side"] = json!("required"); - json["initial_versions"][0]["game_versions"] = json!(["1.20.4"]); - json["title"] = json!("Mysterious Project"); - json["license_id"] = json!("LicenseRef-All-Rights-Reserved"); // closed source - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..3] }, + { "op": "add", "path": "/initial_versions/0/server_side", "value": "required" }, + { "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.4"] }, + { "op": "add", "path": "/title", "value": "Mysterious Project" }, + { "op": "add", "path": "/license_id", "value": "LicenseRef-All-Rights-Reserved" }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, FRIEND_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Test project 4 let id = 4; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[0..3]); - json["initial_versions"][0]["client_side"] = json!("optional"); - json["initial_versions"][0]["game_versions"] = json!(["1.20.5"]); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..3] }, + { "op": "add", "path": "/initial_versions/0/client_side", "value": "optional" }, + { "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.5"] }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, true, - Box::new(modify_json), + Some(modify_json), )); // Test project 5 let id = 5; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[5..6]); - json["initial_versions"][0]["client_side"] = json!("optional"); - json["initial_versions"][0]["game_versions"] = json!(["1.20.5"]); - json["license_id"] = json!("LGPL-3.0-or-later"); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[5..6] }, + { "op": "add", "path": "/initial_versions/0/client_side", "value": "optional" }, + { "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.5"] }, + { "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Test project 6 let id = 6; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[5..6]); - json["initial_versions"][0]["client_side"] = json!("optional"); - json["initial_versions"][0]["server_side"] = json!("required"); - json["license_id"] = json!("LGPL-3.0-or-later"); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[5..6] }, + { "op": "add", "path": "/initial_versions/0/client_side", "value": "optional" }, + { "op": "add", "path": "/initial_versions/0/server_side", "value": "required" }, + { "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, FRIEND_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Test project 7 (testing the search bug) // This project has an initial private forge version that is 1.20.3, and a fabric 1.20.5 version. // This means that a search for fabric + 1.20.3 or forge + 1.20.5 should not return this project. let id = 7; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[5..6]); - json["initial_versions"][0]["client_side"] = json!("optional"); - json["initial_versions"][0]["server_side"] = json!("required"); - json["license_id"] = json!("LGPL-3.0-or-later"); - json["initial_versions"][0]["loaders"] = json!(["forge"]); - json["initial_versions"][0]["game_versions"] = json!(["1.20.2"]); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[5..6] }, + { "op": "add", "path": "/initial_versions/0/client_side", "value": "optional" }, + { "op": "add", "path": "/initial_versions/0/server_side", "value": "required" }, + { "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" }, + { "op": "add", "path": "/initial_versions/0/loaders", "value": ["forge"] }, + { "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.2"] }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Await all project creation @@ -209,12 +202,11 @@ async fn search_projects() { .get_project_deserialized_common(&format!("{test_name}-searchable-project-7"), USER_USER_PAT) .await; api.add_public_version( - get_public_version_creation_data( - project_7.id, - "1.0.0", - TestFile::build_random_jar(), - None::, - ), + project_7.id, + "1.0.0", + TestFile::build_random_jar(), + None, + None, USER_USER_PAT, ) .await; diff --git a/tests/user.rs b/tests/user.rs index 93c5df98..2a08bba7 100644 --- a/tests/user.rs +++ b/tests/user.rs @@ -1,9 +1,8 @@ use common::{ database::{FRIEND_USER_ID, FRIEND_USER_PAT, USER_USER_ID, USER_USER_PAT}, - environment::{with_test_environment, with_test_environment_all}, + environment::with_test_environment_all, }; - -use crate::common::{api_v3::request_data::get_public_project_creation_data, api_common::{ApiTeams, ApiProject}}; +use crate::common::api_common::{ApiTeams, ApiProject}; use common::dummy_data::TestFile; mod common; @@ -25,11 +24,7 @@ pub async fn get_user_projects_after_creating_project_returns_new_project() { .await; let (project, _) = api - .add_public_project( - get_public_project_creation_data("slug", Some(TestFile::BasicMod)), - USER_USER_PAT, - ) - .await; + .add_public_project("slug", Some(TestFile::BasicMod), None, USER_USER_PAT).await; let resp_projects = api .get_user_projects_deserialized_common(USER_USER_ID, USER_USER_PAT) @@ -45,10 +40,7 @@ pub async fn get_user_projects_after_deleting_project_shows_removal() { let api = test_env.api; let (project, _) = api .add_public_project( - get_public_project_creation_data("iota", Some(TestFile::BasicMod)), - USER_USER_PAT, - ) - .await; + "iota", Some(TestFile::BasicMod), None, USER_USER_PAT).await; api.get_user_projects_deserialized_common(USER_USER_ID, USER_USER_PAT) .await; diff --git a/tests/v2/project.rs b/tests/v2/project.rs index f3ce586a..a2d761cf 100644 --- a/tests/v2/project.rs +++ b/tests/v2/project.rs @@ -1,5 +1,5 @@ use crate::common::{ - api_v2::{request_data, ApiV2}, + api_v2::ApiV2, database::{ENEMY_USER_PAT, FRIEND_USER_ID, FRIEND_USER_PAT, MOD_USER_PAT, USER_USER_PAT}, dummy_data::{TestFile, DUMMY_CATEGORIES}, permissions::{PermissionsTest, PermissionsTestContext}, api_common::ApiProject, environment::{with_test_environment, TestEnvironment}, @@ -19,20 +19,12 @@ async fn test_project_type_sanity() { let api = &test_env.api; // Perform all other patch tests on both 'mod' and 'modpack' - let test_creation_mod = request_data::get_public_project_creation_data( - "test-mod", - Some(TestFile::build_random_jar()), - ); - let test_creation_modpack = request_data::get_public_project_creation_data( - "test-modpack", - Some(TestFile::build_random_mrpack()), - ); - for (mod_or_modpack, test_creation_data) in [ - ("mod", test_creation_mod), - ("modpack", test_creation_modpack), + for (mod_or_modpack, slug, file) in [ + ("mod", "test-mod", TestFile::build_random_jar()), + ("modpack", "test-modpack", TestFile::build_random_mrpack()), ] { let (test_project, test_version) = api - .add_public_project(test_creation_data, USER_USER_PAT) + .add_public_project(slug, Some(file), None, USER_USER_PAT) .await; let test_project_slug = test_project.slug.as_ref().unwrap(); diff --git a/tests/v2/search.rs b/tests/v2/search.rs index 4d466013..43e764a5 100644 --- a/tests/v2/search.rs +++ b/tests/v2/search.rs @@ -1,9 +1,7 @@ use crate::common::api_common::Api; use crate::common::api_common::ApiProject; +use crate::common::api_common::ApiVersion; use crate::common::api_v2::ApiV2; -use crate::common::api_v2::request_data; -use crate::common::api_v2::request_data::get_public_version_creation_data; -use crate::common::api_v2::request_data::ProjectCreationRequestData; use crate::common::database::*; use crate::common::dummy_data::TestFile; use crate::common::dummy_data::DUMMY_CATEGORIES; @@ -32,7 +30,7 @@ async fn search_projects() { |id: u64, pat: &'static str, is_modpack: bool, - modify_json: Box| { + modify_json: Option| { let slug = format!("{test_name}-searchable-project-{id}"); let jar = if is_modpack { @@ -40,22 +38,14 @@ async fn search_projects() { } else { TestFile::build_random_jar() }; - let mut basic_project_json = - request_data::get_public_project_creation_data_json(&slug, Some(&jar)); - modify_json(&mut basic_project_json); - - let basic_project_multipart = - request_data::get_public_creation_data_multipart(&basic_project_json, Some(&jar)); - // Add a project- simple, should work. - let req = api.add_public_project( - ProjectCreationRequestData { - slug, - jar: Some(jar), - segment_data: basic_project_multipart, - }, - pat, - ); async move { + // Add a project- simple, should work. + let req = api.add_public_project( + &slug, + Some(jar), + modify_json, + pat, + ); let (project, _) = req.await; // Approve, so that the project is searchable @@ -75,122 +65,122 @@ async fn search_projects() { // Test project 0 let id = 0; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[4..6]); - json["server_side"] = json!("required"); - json["license_id"] = json!("LGPL-3.0-or-later"); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[4..6] }, + { "op": "add", "path": "/server_side", "value": "required" }, + { "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Test project 1 let id = 1; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[0..2]); - json["client_side"] = json!("optional"); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..2] }, + { "op": "add", "path": "/client_side", "value": "optional" }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Test project 2 let id = 2; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[0..2]); - json["server_side"] = json!("required"); - json["title"] = json!("Mysterious Project"); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..2] }, + { "op": "add", "path": "/server_side", "value": "required" }, + { "op": "add", "path": "/title", "value": "Mysterious Project" }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Test project 3 let id = 3; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[0..3]); - json["server_side"] = json!("required"); - json["initial_versions"][0]["game_versions"] = json!(["1.20.4"]); - json["title"] = json!("Mysterious Project"); - json["license_id"] = json!("LicenseRef-All-Rights-Reserved"); // closed source - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..3] }, + { "op": "add", "path": "/server_side", "value": "required" }, + { "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.4"] }, + { "op": "add", "path": "/title", "value": "Mysterious Project" }, + { "op": "add", "path": "/license_id", "value": "LicenseRef-All-Rights-Reserved" }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, FRIEND_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Test project 4 let id = 4; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[0..3]); - json["client_side"] = json!("optional"); - json["initial_versions"][0]["game_versions"] = json!(["1.20.5"]); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..3] }, + { "op": "add", "path": "/client_side", "value": "optional" }, + { "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.5"] }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, true, - Box::new(modify_json), + Some(modify_json), )); // Test project 5 let id = 5; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[5..6]); - json["client_side"] = json!("optional"); - json["initial_versions"][0]["game_versions"] = json!(["1.20.5"]); - json["license_id"] = json!("LGPL-3.0-or-later"); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[5..6] }, + { "op": "add", "path": "/client_side", "value": "optional" }, + { "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.5"] }, + { "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Test project 6 let id = 6; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[5..6]); - json["client_side"] = json!("optional"); - json["server_side"] = json!("required"); - json["license_id"] = json!("LGPL-3.0-or-later"); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[5..6] }, + { "op": "add", "path": "/client_side", "value": "optional" }, + { "op": "add", "path": "/server_side", "value": "required" }, + { "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, FRIEND_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Test project 7 (testing the search bug) // This project has an initial private forge version that is 1.20.3, and a fabric 1.20.5 version. // This means that a search for fabric + 1.20.3 or forge + 1.20.5 should not return this project. let id = 7; - let modify_json = |json: &mut serde_json::Value| { - json["categories"] = json!(DUMMY_CATEGORIES[5..6]); - json["client_side"] = json!("optional"); - json["server_side"] = json!("required"); - json["license_id"] = json!("LGPL-3.0-or-later"); - json["initial_versions"][0]["loaders"] = json!(["forge"]); - json["initial_versions"][0]["game_versions"] = json!(["1.20.2"]); - }; + let modify_json = serde_json::from_value(json!([ + { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[5..6] }, + { "op": "add", "path": "/client_side", "value": "optional" }, + { "op": "add", "path": "/server_side", "value": "required" }, + { "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" }, + { "op": "add", "path": "/initial_versions/0/loaders", "value": ["forge"] }, + { "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.2"] }, + ])).unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, - Box::new(modify_json), + Some(modify_json), )); // Await all project creation @@ -208,7 +198,8 @@ async fn search_projects() { .get_project_deserialized(&format!("{test_name}-searchable-project-7"), USER_USER_PAT) .await; api.add_public_version( - get_public_version_creation_data(project_7.id, "1.0.0", TestFile::build_random_jar()), + project_7.id, "1.0.0", TestFile::build_random_jar(), + None, None, USER_USER_PAT, ) .await; diff --git a/tests/v2/version.rs b/tests/v2/version.rs index 58633517..a6465b1d 100644 --- a/tests/v2/version.rs +++ b/tests/v2/version.rs @@ -1,18 +1,14 @@ use actix_web::test; use futures::StreamExt; -use labrinth::models::projects::{ProjectId, VersionId}; +use labrinth::models::projects::VersionId; use labrinth::{ - models::{ - ids::base62_impl::parse_base62, - projects::{Loader, VersionStatus, VersionType}, - }, + models::projects::{Loader, VersionStatus, VersionType}, routes::v2::version_file::FileUpdateData, }; use serde_json::json; use crate::common::api_common::ApiVersion; use crate::common::api_v2::ApiV2; -use crate::common::api_v2::request_data::get_public_version_creation_data; use crate::common::environment::{TestEnvironment, with_test_environment}; use crate::common::{ database::{ENEMY_USER_PAT, USER_USER_PAT}, @@ -138,6 +134,7 @@ async fn version_updates() { let api = &test_env.api; let alpha_project_id: &String = &test_env.dummy.as_ref().unwrap().project_alpha.project_id; + let alpha_project_id_parsed = test_env.dummy.as_ref().unwrap().project_alpha.project_id_parsed; let alpha_version_id = &test_env.dummy.as_ref().unwrap().project_alpha.version_id; let beta_version_id = &test_env.dummy.as_ref().unwrap().project_beta.version_id; let alpha_version_hash = &test_env.dummy.as_ref().unwrap().project_alpha.file_hash; @@ -221,13 +218,13 @@ async fn version_updates() { .iter() { let version = api - .add_public_version( - get_public_version_creation_data( - ProjectId(parse_base62(alpha_project_id).unwrap()), + .add_public_version_deserialized_common( + alpha_project_id_parsed, version_number, TestFile::build_random_jar(), - ), - USER_USER_PAT, + None, + None, + USER_USER_PAT, ) .await; update_ids.push(version.id); diff --git a/tests/version.rs b/tests/version.rs index 9f10e327..a60d93c7 100644 --- a/tests/version.rs +++ b/tests/version.rs @@ -1,24 +1,20 @@ use std::collections::HashMap; use actix_web::test; +use common::api_v3::ApiV3; +use common::asserts::assert_common_version_ids; use common::environment::{with_test_environment_all, with_test_environment}; use futures::StreamExt; use labrinth::database::models::version_item::VERSIONS_NAMESPACE; use labrinth::models::ids::base62_impl::parse_base62; -use labrinth::models::projects::{ProjectId, VersionId, VersionStatus, VersionType}; +use labrinth::models::projects::{VersionId, VersionStatus, VersionType}; use labrinth::routes::v3::version_file::FileUpdateData; use serde_json::json; - use crate::common::{asserts::assert_status, get_json_val_str}; use actix_http::StatusCode; -use common::{ - asserts::assert_version_ids, database::USER_USER_PAT, -}; - +use common::database::USER_USER_PAT; use crate::common::api_common::ApiVersion; -use crate::common::api_v3::request_data::get_public_version_creation_data; use crate::common::database::*; - use crate::common::dummy_data::TestFile; // importing common module. @@ -77,10 +73,11 @@ async fn test_get_version() { #[actix_rt::test] async fn version_updates() { // Test setup and dummy data - with_test_environment(None, |test_env| async move { + with_test_environment(None, |test_env: common::environment::TestEnvironment| async move { let api = &test_env.api; let alpha_project_id: &String = &test_env.dummy.as_ref().unwrap().project_alpha.project_id; + let alpha_project_id_parsed = test_env.dummy.as_ref().unwrap().project_alpha.project_id_parsed; let alpha_version_id = &test_env.dummy.as_ref().unwrap().project_alpha.version_id; let beta_version_id = &test_env.dummy.as_ref().unwrap().project_beta.version_id; let alpha_version_hash = &test_env.dummy.as_ref().unwrap().project_alpha.file_hash; @@ -165,13 +162,12 @@ async fn version_updates() { { let version = api .add_public_version_deserialized( - get_public_version_creation_data( - ProjectId(parse_base62(alpha_project_id).unwrap()), + alpha_project_id_parsed, version_number, TestFile::build_random_jar(), - None::, - ), - USER_USER_PAT, + None, + None, + USER_USER_PAT, ) .await; update_ids.push(version.id); @@ -499,18 +495,25 @@ pub async fn test_project_versions() { #[actix_rt::test] async fn can_create_version_with_ordering() { with_test_environment_all(None, |env| async move { - let alpha_project_id = env.dummy.as_ref().unwrap().project_alpha.project_id.clone(); + let alpha_project_id_parsed = env.dummy.as_ref().unwrap().project_alpha.project_id_parsed.clone(); let new_version_id = get_json_val_str( env.api - .create_default_version(&alpha_project_id, Some(1), USER_USER_PAT) + .add_public_version_deserialized_common( + alpha_project_id_parsed, + "1.2.3.4", + TestFile::BasicMod, + Some(1), + None, + USER_USER_PAT, + ) .await .id, ); let versions = env .api - .get_versions(vec![new_version_id.clone()], USER_USER_PAT) + .get_versions_deserialized_common(vec![new_version_id.clone()], USER_USER_PAT) .await; assert_eq!(versions[0].ordering, Some(1)); }) @@ -530,7 +533,7 @@ async fn edit_version_ordering_works() { let versions = env .api - .get_versions(vec![alpha_version_id.clone()], USER_USER_PAT) + .get_versions_deserialized_common(vec![alpha_version_id.clone()], USER_USER_PAT) .await; assert_eq!(versions[0].ordering, Some(10)); }) @@ -540,26 +543,33 @@ async fn edit_version_ordering_works() { #[actix_rt::test] async fn version_ordering_for_specified_orderings_orders_lower_order_first() { with_test_environment_all(None, |env| async move { - let alpha_project_id = env.dummy.as_ref().unwrap().project_alpha.project_id.clone(); + let alpha_project_id_parsed = env.dummy.as_ref().unwrap().project_alpha.project_id_parsed.clone(); let alpha_version_id = env.dummy.as_ref().unwrap().project_alpha.version_id.clone(); let new_version_id = get_json_val_str( env.api - .create_default_version(&alpha_project_id, Some(1), USER_USER_PAT) - .await - .id, - ); + .add_public_version_deserialized_common( + alpha_project_id_parsed, + "1.2.3.4", + TestFile::BasicMod, + Some(1), + None, + USER_USER_PAT, + ) + .await + .id, + ); env.api .edit_version_ordering(&alpha_version_id, Some(10), USER_USER_PAT) .await; let versions = env .api - .get_versions( + .get_versions_deserialized_common( vec![alpha_version_id.clone(), new_version_id.clone()], USER_USER_PAT, ) .await; - assert_version_ids(&versions, vec![new_version_id, alpha_version_id]); + assert_common_version_ids(&versions, vec![new_version_id, alpha_version_id]); }) .await; } @@ -567,23 +577,29 @@ async fn version_ordering_for_specified_orderings_orders_lower_order_first() { #[actix_rt::test] async fn version_ordering_when_unspecified_orders_oldest_first() { with_test_environment_all(None, |env| async move { - let alpha_project_id = &env.dummy.as_ref().unwrap().project_alpha.project_id.clone(); - let alpha_version_id = env.dummy.as_ref().unwrap().project_alpha.version_id.clone(); + let alpha_project_id_parsed = env.dummy.as_ref().unwrap().project_alpha.project_id_parsed.clone(); + let alpha_version_id: String = env.dummy.as_ref().unwrap().project_alpha.version_id.clone(); let new_version_id = get_json_val_str( - env.api - .create_default_version(alpha_project_id, None, USER_USER_PAT) - .await - .id, - ); + env.api.add_public_version_deserialized_common( + alpha_project_id_parsed, + "1.2.3.4", + TestFile::BasicMod, + None, + None, + USER_USER_PAT, + ) + .await + .id, + ); let versions = env .api - .get_versions( + .get_versions_deserialized_common( vec![alpha_version_id.clone(), new_version_id.clone()], USER_USER_PAT, ) .await; - assert_version_ids(&versions, vec![alpha_version_id, new_version_id]); + assert_common_version_ids(&versions, vec![alpha_version_id, new_version_id]); }) .await } @@ -591,26 +607,33 @@ async fn version_ordering_when_unspecified_orders_oldest_first() { #[actix_rt::test] async fn version_ordering_when_specified_orders_specified_before_unspecified() { with_test_environment_all(None, |env| async move { - let alpha_project_id = &env.dummy.as_ref().unwrap().project_alpha.project_id.clone(); + let alpha_project_id_parsed = env.dummy.as_ref().unwrap().project_alpha.project_id_parsed.clone(); let alpha_version_id = env.dummy.as_ref().unwrap().project_alpha.version_id.clone(); let new_version_id = get_json_val_str( env.api - .create_default_version(alpha_project_id, Some(10000), USER_USER_PAT) - .await - .id, - ); + .add_public_version_deserialized_common( + alpha_project_id_parsed, + "1.2.3.4", + TestFile::BasicMod, + Some(1000), + None, + USER_USER_PAT, + ) + .await + .id, + ); env.api .edit_version_ordering(&alpha_version_id, None, USER_USER_PAT) .await; let versions = env .api - .get_versions( + .get_versions_deserialized_common( vec![alpha_version_id.clone(), new_version_id.clone()], USER_USER_PAT, ) .await; - assert_version_ids(&versions, vec![new_version_id, alpha_version_id]); + assert_common_version_ids(&versions, vec![new_version_id, alpha_version_id]); }) .await; }