Side types overhaul (#762)

* side types overhaul

* fixes, fmt clippy

* migration fix for v3 bug

* fixed migration issues

* more tested migration changes

* fmt, clippy

* bump cicd

---------

Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
This commit is contained in:
Wyatt Verchere
2023-11-28 10:36:59 -08:00
committed by GitHub
parent fd18185ef0
commit f731c1080d
28 changed files with 957 additions and 555 deletions

View File

@@ -83,8 +83,10 @@ pub fn get_public_version_creation_data_json(
// Loader fields
"game_versions": ["1.20.1"],
"client_side": "required",
"server_side": "optional"
"singleplayer": true,
"client_and_server": true,
"client_only": true,
"server_only": false,
});
if is_modpack {
j["mrpack_loaders"] = json!(["fabric"]);

View File

@@ -3,10 +3,8 @@ use actix_web::{
test::{self, TestRequest},
};
use async_trait::async_trait;
use labrinth::routes::v3::tags::GameData;
use labrinth::{
database::models::loader_fields::LoaderFieldEnumValue, routes::v3::tags::LoaderData,
};
use labrinth::database::models::loader_fields::LoaderFieldEnumValue;
use labrinth::routes::v3::tags::{GameData, LoaderData};
use crate::common::{
api_common::{

View File

@@ -24,7 +24,7 @@ use super::{
use super::{asserts::assert_status, database::USER_USER_ID, get_json_val_str};
pub const DUMMY_DATA_UPDATE: i64 = 5;
pub const DUMMY_DATA_UPDATE: i64 = 6;
#[allow(dead_code)]
pub const DUMMY_CATEGORIES: &[&str] = &[
@@ -340,8 +340,10 @@ pub async fn add_project_beta(api: &ApiV3) -> (CommonProject, CommonVersion) {
"version_title": "start",
"status": "unlisted",
"dependencies": [],
"client_side": "required",
"server_side": "optional",
"singleplayer": true,
"client_and_server": true,
"client_only": true,
"server_only": false,
"game_versions": ["1.20.1"] ,
"release_channel": "release",
"loaders": ["fabric"],

View File

@@ -68,7 +68,7 @@ INSERT INTO loader_field_enum_values(enum_id, value, metadata, ordering)
VALUES (2, 'Ordering_Positive100', '{"type":"release","major":false}', 100);
INSERT INTO loader_fields_loaders(loader_id, loader_field_id)
SELECT l.id, lf.id FROM loaders l CROSS JOIN loader_fields lf WHERE lf.field = 'game_versions' OR lf.field = 'client_side' OR lf.field = 'server_side';
SELECT l.id, lf.id FROM loaders l CROSS JOIN loader_fields lf WHERE lf.field IN ('game_versions','singleplayer', 'client_and_server', 'client_only', 'server_only');
INSERT INTO categories (id, category, project_type) VALUES
(51, 'combat', 1),

View File

@@ -112,7 +112,7 @@ async fn creating_loader_fields() {
Some(
serde_json::from_value(json!([{
"op": "remove",
"path": "/client_side"
"path": "/singleplayer"
}]))
.unwrap(),
),
@@ -183,7 +183,7 @@ async fn creating_loader_fields() {
json!(1),
json!([1]),
json!("1.20.1"),
json!(["client_side"]),
json!(["singleplayer"]),
] {
// TODO: - Create project
// - Create version
@@ -271,12 +271,12 @@ async fn creating_loader_fields() {
"value": ["1.20.1", "1.20.2"]
}, {
"op": "add",
"path": "/client_side",
"value": "optional"
"path": "/singleplayer",
"value": false
}, {
"op": "add",
"path": "/server_side",
"value": "required"
"path": "/server_only",
"value": true
}]))
.unwrap(),
),
@@ -287,16 +287,16 @@ async fn creating_loader_fields() {
v.fields.get("game_versions").unwrap(),
&json!(["1.20.1", "1.20.2"])
);
assert_eq!(v.fields.get("client_side").unwrap(), &json!("optional"));
assert_eq!(v.fields.get("server_side").unwrap(), &json!("required"));
assert_eq!(v.fields.get("singleplayer").unwrap(), &json!(false));
assert_eq!(v.fields.get("server_only").unwrap(), &json!(true));
// - Patch
let resp = api
.edit_version(
alpha_version_id,
json!({
"game_versions": ["1.20.1", "1.20.2"],
"client_side": "optional",
"server_side": "required"
"singleplayer": false,
"server_only": true
}),
USER_USER_PAT,
)
@@ -314,16 +314,13 @@ async fn creating_loader_fields() {
}
#[actix_rt::test]
async fn get_loader_fields() {
async fn get_loader_fields_variants() {
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
let api = &test_env.api;
let game_versions = api
.get_loader_field_variants_deserialized("game_versions")
.await;
let side_types = api
.get_loader_field_variants_deserialized("client_side")
.await;
// These tests match dummy data and will need to be updated if the dummy data changes
// Versions should be ordered by:
@@ -348,18 +345,64 @@ async fn get_loader_fields() {
"1.20.1"
]
);
let side_type_names = side_types
.into_iter()
.map(|x| x.value)
.collect::<HashSet<_>>();
assert_eq!(
side_type_names,
["unknown", "required", "optional", "unsupported"]
.iter()
.map(|s| s.to_string())
.collect()
);
})
.await
}
#[actix_rt::test]
async fn get_available_loader_fields() {
// Get available loader fields for a given loader
// (ie: which fields are relevant for 'fabric', etc)
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
let api = &test_env.api;
let loaders = api.get_loaders_deserialized().await;
let fabric_loader_fields = loaders
.iter()
.find(|x| x.name == "fabric")
.unwrap()
.supported_fields
.clone()
.into_iter()
.collect::<HashSet<_>>();
assert_eq!(
fabric_loader_fields,
[
"game_versions",
"singleplayer",
"client_and_server",
"client_only",
"server_only",
"test_fabric_optional" // exists for testing
]
.iter()
.map(|s| s.to_string())
.collect()
);
let mrpack_loader_fields = loaders
.iter()
.find(|x| x.name == "mrpack")
.unwrap()
.supported_fields
.clone()
.into_iter()
.collect::<HashSet<_>>();
assert_eq!(
mrpack_loader_fields,
[
"game_versions",
"singleplayer",
"client_and_server",
"client_only",
"server_only",
// mrpack has all the general fields as well as this
"mrpack_loaders"
]
.iter()
.map(|s| s.to_string())
.collect()
);
})
.await;
}

View File

@@ -2,19 +2,24 @@ use actix_http::StatusCode;
use actix_web::test;
use bytes::Bytes;
use chrono::{Duration, Utc};
use common::api_v3::request_data::get_public_version_creation_data;
use common::api_v3::ApiV3;
use common::database::*;
use common::dummy_data::DUMMY_CATEGORIES;
use common::environment::with_test_environment_all;
use common::environment::{with_test_environment, with_test_environment_all, TestEnvironment};
use common::permissions::{PermissionsTest, PermissionsTestContext};
use futures::StreamExt;
use labrinth::database::models::project_item::{PROJECTS_NAMESPACE, PROJECTS_SLUGS_NAMESPACE};
use labrinth::models::ids::base62_impl::parse_base62;
use labrinth::models::projects::ProjectId;
use labrinth::models::teams::ProjectPermissions;
use labrinth::util::actix::{AppendsMultipart, MultipartSegment, MultipartSegmentData};
use serde_json::json;
use crate::common::api_common::{ApiProject, ApiVersion};
use crate::common::api_v3::request_data::get_public_project_creation_data_json;
use crate::common::dummy_data::TestFile;
mod common;
@@ -101,32 +106,11 @@ async fn test_get_project() {
#[actix_rt::test]
async fn test_add_remove_project() {
// Test setup and dummy data
with_test_environment_all(None, |test_env| async move {
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
let api = &test_env.api;
// Generate test project data.
let mut json_data = json!(
{
"title": "Test_Add_Project project",
"slug": "demo",
"description": "Example description.",
"body": "Example body.",
"initial_versions": [{
"file_parts": ["basic-mod.jar"],
"version_number": "1.2.3",
"version_title": "start",
"dependencies": [],
"game_versions": ["1.20.1"] ,
"client_side": "required",
"server_side": "optional",
"release_channel": "release",
"loaders": ["fabric"],
"featured": true
}],
"categories": [],
"license_id": "MIT"
}
);
let mut json_data =
get_public_project_creation_data_json("demo", Some(&TestFile::BasicMod));
// Basic json
let json_segment = MultipartSegment {
@@ -730,48 +714,27 @@ async fn permissions_edit_details() {
#[actix_rt::test]
async fn permissions_upload_version() {
with_test_environment_all(None, |test_env| async move {
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
let alpha_version_id = &test_env.dummy.as_ref().unwrap().project_alpha.version_id;
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
let alpha_file_hash = &test_env.dummy.as_ref().unwrap().project_alpha.file_hash;
let upload_version = ProjectPermissions::UPLOAD_VERSION;
// Upload version with basic-mod.jar
let req_gen = |ctx: &PermissionsTestContext| {
test::TestRequest::post().uri("/v3/version").set_multipart([
MultipartSegment {
name: "data".to_string(),
filename: None,
content_type: Some("application/json".to_string()),
data: MultipartSegmentData::Text(
serde_json::to_string(&json!({
"project_id": ctx.project_id.unwrap(),
"file_parts": ["basic-mod.jar"],
"version_number": "1.0.0",
"version_title": "1.0.0",
"version_type": "release",
"client_side": "required",
"server_side": "optional",
"dependencies": [],
"game_versions": ["1.20.1"],
"loaders": ["fabric"],
"featured": false,
}))
.unwrap(),
),
},
MultipartSegment {
name: "basic-mod.jar".to_string(),
filename: Some("basic-mod.jar".to_string()),
content_type: Some("application/java-archive".to_string()),
data: MultipartSegmentData::Binary(
include_bytes!("../tests/files/basic-mod.jar").to_vec(),
),
},
])
let project_id = ctx.project_id.unwrap();
let project_id = ProjectId(parse_base62(project_id).unwrap());
let multipart = get_public_version_creation_data(
project_id,
"1.0.0",
TestFile::BasicMod,
None,
None,
);
test::TestRequest::post()
.uri("/v3/version")
.set_multipart(multipart.segment_data)
};
PermissionsTest::new(&test_env)
.simple_project_permissions_test(upload_version, req_gen)

View File

@@ -2,9 +2,16 @@ use actix_web::test::{self, TestRequest};
use bytes::Bytes;
use chrono::{Duration, Utc};
use common::environment::with_test_environment_all;
use common::api_v3::request_data::{
get_public_project_creation_data, get_public_version_creation_data,
};
use common::api_v3::ApiV3;
use common::dummy_data::TestFile;
use common::environment::{with_test_environment, with_test_environment_all, TestEnvironment};
use common::{database::*, scopes::ScopeTest};
use labrinth::models::ids::base62_impl::parse_base62;
use labrinth::models::pats::Scopes;
use labrinth::models::projects::ProjectId;
use labrinth::util::actix::{AppendsMultipart, MultipartSegment, MultipartSegmentData};
use serde_json::json;
@@ -201,93 +208,37 @@ pub async fn notifications_scopes() {
// Project version creation scopes
#[actix_rt::test]
pub async fn project_version_create_scopes() {
with_test_environment_all(None, |test_env| async move {
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
// Create project
let create_project = Scopes::PROJECT_CREATE;
let json_data = json!(
{
"title": "Test_Add_Project project",
"slug": "demo",
"description": "Example description.",
"body": "Example body.",
"initial_versions": [{
"file_parts": ["basic-mod.jar"],
"version_number": "1.2.3",
"version_title": "start",
"dependencies": [],
"game_versions": ["1.20.1"] ,
"client_side": "required",
"server_side": "optional",
"release_channel": "release",
"loaders": ["fabric"],
"featured": true
}],
"categories": [],
"license_id": "MIT"
}
);
let json_segment = MultipartSegment {
name: "data".to_string(),
filename: None,
content_type: Some("application/json".to_string()),
data: MultipartSegmentData::Text(serde_json::to_string(&json_data).unwrap()),
};
let file_segment = MultipartSegment {
name: "basic-mod.jar".to_string(),
filename: Some("basic-mod.jar".to_string()),
content_type: Some("application/java-archive".to_string()),
data: MultipartSegmentData::Binary(
include_bytes!("../tests/files/basic-mod.jar").to_vec(),
),
};
let req_gen = || {
let creation_data =
get_public_project_creation_data("demo", Some(TestFile::BasicMod), None);
test::TestRequest::post()
.uri("/v3/project")
.set_multipart(vec![json_segment.clone(), file_segment.clone()])
.set_multipart(creation_data.segment_data)
};
let (_, success) = ScopeTest::new(&test_env)
.test(req_gen, create_project)
.await
.unwrap();
let project_id = success["id"].as_str().unwrap();
let project_id = ProjectId(parse_base62(project_id).unwrap());
// Add version to project
let create_version = Scopes::VERSION_CREATE;
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
}
);
let json_segment = MultipartSegment {
name: "data".to_string(),
filename: None,
content_type: Some("application/json".to_string()),
data: MultipartSegmentData::Text(serde_json::to_string(&json_data).unwrap()),
};
let file_segment = MultipartSegment {
name: "basic-mod-different.jar".to_string(),
filename: Some("basic-mod.jar".to_string()),
content_type: Some("application/java-archive".to_string()),
data: MultipartSegmentData::Binary(
include_bytes!("../tests/files/basic-mod-different.jar").to_vec(),
),
};
let req_gen = || {
let creation_data = get_public_version_creation_data(
project_id,
"1.2.3.4",
TestFile::BasicModDifferent,
None,
None,
);
test::TestRequest::post()
.uri("/v3/version")
.set_multipart(vec![json_segment.clone(), file_segment.clone()])
.set_multipart(creation_data.segment_data)
};
ScopeTest::new(&test_env)
.test(req_gen, create_version)

View File

@@ -66,7 +66,7 @@ async fn search_projects() {
let id = 0;
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": "/initial_versions/0/server_only", "value": true },
{ "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" },
]))
.unwrap();
@@ -81,7 +81,7 @@ async fn search_projects() {
let id = 1;
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" },
{ "op": "add", "path": "/initial_versions/0/client_only", "value": false },
]))
.unwrap();
project_creation_futures.push(create_async_future(
@@ -95,7 +95,7 @@ async fn search_projects() {
let id = 2;
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": "/initial_versions/0/server_only", "value": true },
{ "op": "add", "path": "/title", "value": "Mysterious Project" },
]))
.unwrap();
@@ -110,7 +110,7 @@ async fn search_projects() {
let id = 3;
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/server_only", "value": true },
{ "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" },
@@ -127,7 +127,7 @@ async fn search_projects() {
let id = 4;
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/client_only", "value": false },
{ "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.5"] },
]))
.unwrap();
@@ -142,7 +142,7 @@ async fn search_projects() {
let id = 5;
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/client_only", "value": false },
{ "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.5"] },
{ "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" },
]))
@@ -158,8 +158,8 @@ async fn search_projects() {
let id = 6;
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": "/initial_versions/0/client_only", "value": false },
{ "op": "add", "path": "/initial_versions/0/server_only", "value": true },
{ "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" },
]))
.unwrap();
@@ -176,8 +176,8 @@ async fn search_projects() {
let id = 7;
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": "/initial_versions/0/client_only", "value": false },
{ "op": "add", "path": "/initial_versions/0/server_only", "value": true },
{ "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"] },
@@ -236,8 +236,8 @@ async fn search_projects() {
vec![1, 2, 3, 4],
),
(json!([["project_types:modpack"]]), vec![4]),
(json!([["client_side:required"]]), vec![0, 2, 3, 7]),
(json!([["server_side:required"]]), vec![0, 2, 3, 6, 7]),
(json!([["client_only:true"]]), vec![0, 2, 3, 7]),
(json!([["server_only:true"]]), vec![0, 2, 3, 6, 7]),
(json!([["open_source:true"]]), vec![0, 1, 2, 4, 5, 6, 7]),
(json!([["license:MIT"]]), vec![1, 2, 4]),
(json!([[r#"title:'Mysterious Project'"#]]), vec![2, 3]),

View File

@@ -1,6 +1,9 @@
use crate::common::{
api_common::ApiProject,
api_v2::ApiV2,
api_v2::{
request_data::{get_public_project_creation_data_json, get_public_version_creation_data},
ApiV2,
},
database::{ENEMY_USER_PAT, FRIEND_USER_ID, FRIEND_USER_PAT, MOD_USER_PAT, USER_USER_PAT},
dummy_data::{TestFile, DUMMY_CATEGORIES},
environment::{with_test_environment, TestEnvironment},
@@ -10,7 +13,7 @@ use actix_web::test;
use itertools::Itertools;
use labrinth::{
database::models::project_item::PROJECTS_SLUGS_NAMESPACE,
models::teams::ProjectPermissions,
models::{ids::base62_impl::parse_base62, projects::ProjectId, teams::ProjectPermissions},
util::actix::{AppendsMultipart, MultipartSegment, MultipartSegmentData},
};
use serde_json::json;
@@ -63,28 +66,8 @@ async fn test_add_remove_project() {
let api = &test_env.api;
// Generate test project data.
let mut json_data = json!(
{
"title": "Test_Add_Project project",
"slug": "demo",
"description": "Example description.",
"body": "Example body.",
"client_side": "required",
"server_side": "optional",
"initial_versions": [{
"file_parts": ["basic-mod.jar"],
"version_number": "1.2.3",
"version_title": "start",
"dependencies": [],
"game_versions": ["1.20.1"] ,
"release_channel": "release",
"loaders": ["fabric"],
"featured": true
}],
"categories": [],
"license_id": "MIT"
}
);
let mut json_data =
get_public_project_creation_data_json("demo", Some(&TestFile::BasicMod));
// Basic json
let json_segment = MultipartSegment {
@@ -251,36 +234,18 @@ async fn permissions_upload_version() {
// Upload version with basic-mod.jar
let req_gen = |ctx: &PermissionsTestContext| {
test::TestRequest::post().uri("/v2/version").set_multipart([
MultipartSegment {
name: "data".to_string(),
filename: None,
content_type: Some("application/json".to_string()),
data: MultipartSegmentData::Text(
serde_json::to_string(&json!({
"project_id": ctx.project_id.unwrap(),
"file_parts": ["basic-mod.jar"],
"version_number": "1.0.0",
"version_title": "1.0.0",
"version_type": "release",
"dependencies": [],
"game_versions": ["1.20.1"],
"loaders": ["fabric"],
"featured": false,
}))
.unwrap(),
),
},
MultipartSegment {
name: "basic-mod.jar".to_string(),
filename: Some("basic-mod.jar".to_string()),
content_type: Some("application/java-archive".to_string()),
data: MultipartSegmentData::Binary(
include_bytes!("../../tests/files/basic-mod.jar").to_vec(),
),
},
])
let project_id = ctx.project_id.unwrap();
let project_id = ProjectId(parse_base62(project_id).unwrap());
let multipart = get_public_version_creation_data(
project_id,
"1.0.0",
TestFile::BasicMod,
None,
None,
);
test::TestRequest::post()
.uri("/v2/version")
.set_multipart(multipart.segment_data)
};
PermissionsTest::new(&test_env)
.simple_project_permissions_test(upload_version, req_gen)
@@ -491,7 +456,7 @@ pub async fn test_patch_project() {
"issues_url": "https://github.com",
"discord_url": "https://discord.gg",
"wiki_url": "https://wiki.com",
"client_side": "optional",
"client_side": "unsupported",
"server_side": "required",
"donation_urls": [{
"id": "patreon",
@@ -520,7 +485,11 @@ pub async fn test_patch_project() {
assert_eq!(project.issues_url, Some("https://github.com".to_string()));
assert_eq!(project.discord_url, Some("https://discord.gg".to_string()));
assert_eq!(project.wiki_url, Some("https://wiki.com".to_string()));
assert_eq!(project.client_side.as_str(), "optional");
// Note: the original V2 value of this was "optional",
// but Required/Optional is no longer a carried combination in v3, as the changes made were lossy.
// Now, the test Required/Unsupported combination is tested instead.
// Setting Required/Optional in v2 will not work, this is known and accepteed.
assert_eq!(project.client_side.as_str(), "unsupported");
assert_eq!(project.server_side.as_str(), "required");
assert_eq!(project.donation_urls.unwrap()[0].url, "https://patreon.com");
})

View File

@@ -1,104 +1,50 @@
use crate::common::api_v2::request_data::get_public_project_creation_data;
use crate::common::api_v2::request_data::get_public_version_creation_data;
use crate::common::api_v2::ApiV2;
use crate::common::dummy_data::TestFile;
use crate::common::environment::with_test_environment;
use crate::common::environment::TestEnvironment;
use crate::common::scopes::ScopeTest;
use actix_web::test;
use labrinth::models::ids::base62_impl::parse_base62;
use labrinth::models::pats::Scopes;
use labrinth::models::projects::ProjectId;
use labrinth::util::actix::AppendsMultipart;
use labrinth::util::actix::MultipartSegment;
use labrinth::util::actix::MultipartSegmentData;
use serde_json::json;
// Project version creation scopes
#[actix_rt::test]
pub async fn project_version_create_scopes() {
with_test_environment(None, |test_env: TestEnvironment<ApiV2>| async move {
// Create project
let create_project = Scopes::PROJECT_CREATE;
let json_data = json!(
{
"title": "Test_Add_Project project",
"slug": "demo",
"description": "Example description.",
"body": "Example body.",
"initial_versions": [{
"file_parts": ["basic-mod.jar"],
"version_number": "1.2.3",
"version_title": "start",
"dependencies": [],
"game_versions": ["1.20.1"] ,
"client_side": "required",
"server_side": "optional",
"release_channel": "release",
"loaders": ["fabric"],
"featured": true
}],
"categories": [],
"license_id": "MIT"
}
);
let json_segment = MultipartSegment {
name: "data".to_string(),
filename: None,
content_type: Some("application/json".to_string()),
data: MultipartSegmentData::Text(serde_json::to_string(&json_data).unwrap()),
};
let file_segment = MultipartSegment {
name: "basic-mod.jar".to_string(),
filename: Some("basic-mod.jar".to_string()),
content_type: Some("application/java-archive".to_string()),
data: MultipartSegmentData::Binary(
include_bytes!("../../tests/files/basic-mod.jar").to_vec(),
),
};
let req_gen = || {
let creation_data =
get_public_project_creation_data("demo", Some(TestFile::BasicMod), None);
test::TestRequest::post()
.uri("/v3/project")
.set_multipart(vec![json_segment.clone(), file_segment.clone()])
.uri("/v2/project")
.set_multipart(creation_data.segment_data)
};
let (_, success) = ScopeTest::new(&test_env)
.test(req_gen, create_project)
.await
.unwrap();
let project_id = success["id"].as_str().unwrap();
let project_id = ProjectId(parse_base62(project_id).unwrap());
// Add version to project
let create_version = Scopes::VERSION_CREATE;
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
}
);
let json_segment = MultipartSegment {
name: "data".to_string(),
filename: None,
content_type: Some("application/json".to_string()),
data: MultipartSegmentData::Text(serde_json::to_string(&json_data).unwrap()),
};
let file_segment = MultipartSegment {
name: "basic-mod-different.jar".to_string(),
filename: Some("basic-mod.jar".to_string()),
content_type: Some("application/java-archive".to_string()),
data: MultipartSegmentData::Binary(
include_bytes!("../../tests/files/basic-mod-different.jar").to_vec(),
),
};
let req_gen = || {
let creation_data = get_public_version_creation_data(
project_id,
"1.2.3.4",
TestFile::BasicModDifferent,
None,
None,
);
test::TestRequest::post()
.uri("/v3/version")
.set_multipart(vec![json_segment.clone(), file_segment.clone()])
.uri("/v2/version")
.set_multipart(creation_data.segment_data)
};
ScopeTest::new(&test_env)
.test(req_gen, create_version)

View File

@@ -214,6 +214,15 @@ async fn search_projects() {
// 1. vec of search facets
// 2. expected project ids to be returned by this search
let pairs = vec![
// For testing: remove me
(
json!([
["client_side:required"],
["versions:1.20.5"],
[&format!("categories:{}", DUMMY_CATEGORIES[5])]
]),
vec![],
),
(json!([["categories:fabric"]]), vec![0, 1, 2, 3, 4, 5, 6, 7]),
(json!([["categories:forge"]]), vec![7]),
(
@@ -229,7 +238,9 @@ async fn search_projects() {
vec![1, 2, 3, 4],
),
(json!([["project_types:modpack"]]), vec![4]),
(json!([["client_side:required"]]), vec![0, 2, 3, 7]),
// Formerly included 7, but with v2 changes, this is no longer the case.
// This is because we assume client_side/server_side with subsequent versions.
(json!([["client_side:required"]]), vec![0, 2, 3]),
(json!([["server_side:required"]]), vec![0, 2, 3, 6, 7]),
(json!([["open_source:true"]]), vec![0, 1, 2, 4, 5, 6, 7]),
(json!([["license:MIT"]]), vec![1, 2, 4]),

View File

@@ -428,9 +428,9 @@ async fn add_version_project_types_v2() {
.get_project_deserialized(&test_project.slug.unwrap(), USER_USER_PAT)
.await;
assert_eq!(test_project.project_type, "unknown"); // No project_type set, as no versions are set
// This is a known difference between older v2 ,but is acceptable.
// This would be the appropriate test on older v2:
// assert_eq!(test_project.project_type, "modpack");
// This is a known difference between older v2 ,but is acceptable.
// This would be the appropriate test on older v2:
// assert_eq!(test_project.project_type, "modpack");
// Create a version with a modpack file attached
let test_version = api