From be65589e4d6421504bb1c74d5b0dad1897941eea Mon Sep 17 00:00:00 2001 From: aecsocket <43144841+aecsocket@users.noreply.github.com> Date: Sat, 20 Jun 2026 20:30:32 +0100 Subject: [PATCH] Allow v2 version creation route to accept environment (#6454) * Allow v2 version creation route to accept environment * fix --- .../src/routes/v2/project_creation.rs | 6 ++ .../src/routes/v2/version_creation.rs | 37 +++++---- apps/labrinth/tests/v2/version.rs | 81 ++++++++++++++++++- 3 files changed, 107 insertions(+), 17 deletions(-) diff --git a/apps/labrinth/src/routes/v2/project_creation.rs b/apps/labrinth/src/routes/v2/project_creation.rs index dd14c32bd..a6b7a6292 100644 --- a/apps/labrinth/src/routes/v2/project_creation.rs +++ b/apps/labrinth/src/routes/v2/project_creation.rs @@ -184,6 +184,12 @@ pub async fn project_create( server_side, ), ); + if let Some(environment) = v.environment { + fields.insert( + "environment".to_string(), + json!(environment), + ); + } fields.insert( "game_versions".to_string(), json!(v.game_versions), diff --git a/apps/labrinth/src/routes/v2/version_creation.rs b/apps/labrinth/src/routes/v2/version_creation.rs index b3e0337f7..c60247e10 100644 --- a/apps/labrinth/src/routes/v2/version_creation.rs +++ b/apps/labrinth/src/routes/v2/version_creation.rs @@ -55,6 +55,7 @@ pub struct InitialVersionData { pub dependencies: Vec, #[validate(length(min = 1))] pub game_versions: Vec, + pub environment: Option, #[serde(alias = "version_type")] pub release_channel: VersionType, #[validate(length(min = 1))] @@ -160,22 +161,26 @@ pub async fn version_create( .iter() .any(|field| field == "environment") { - // If so, we get the field of an example version of the project, and set the side types to match. - fields.insert( - "environment".into(), - get_example_version_fields( - legacy_create.project_id, - client, - &redis, - ) - .await? - .into_iter() - .flatten() - .find(|f| f.field_name == "environment") - .map_or(json!("unknown"), |f| { - f.value.serialize_internal() - }), - ); + let environment = + if let Some(environment) = legacy_create.environment { + json!(environment) + } else { + // If so, we get the field of an example version of the project, and set the side types to match. + get_example_version_fields( + legacy_create.project_id, + client, + &redis, + ) + .await? + .into_iter() + .flatten() + .find(|f| f.field_name == "environment") + .map_or(json!("unknown"), |f| { + f.value.serialize_internal() + }) + }; + + fields.insert("environment".into(), environment); } // Handle project type via file extension prediction let mut project_type = None; diff --git a/apps/labrinth/tests/v2/version.rs b/apps/labrinth/tests/v2/version.rs index afa47e97d..788a36842 100644 --- a/apps/labrinth/tests/v2/version.rs +++ b/apps/labrinth/tests/v2/version.rs @@ -4,9 +4,10 @@ use crate::common::api_v2::ApiV2; use actix_http::StatusCode; use actix_web::test; use futures::StreamExt; -use labrinth::models::ids::VersionId; use labrinth::{ + models::ids::VersionId, models::projects::{Loader, VersionStatus, VersionType}, + models::v2::projects::LegacySideType, routes::v2::version_file::FileUpdateData, }; use serde_json::json; @@ -515,6 +516,84 @@ async fn add_version_project_types_v2() { .await; } +#[actix_rt::test] +async fn add_version_accepts_environment_v2() { + with_test_environment( + None, + |test_env: TestEnvironment| async move { + let api = &test_env.api; + + let (test_project, test_versions) = api + .add_public_project( + "test-version-environment", + None, + None, + USER_USER_PAT, + ) + .await; + assert_eq!(test_versions.len(), 0); + + let patch = json!([{ + "op": "add", + "path": "/environment", + "value": "server_only_client_optional" + }]); + + let resp = api + .add_public_version( + test_project.id, + "1.0.0", + TestFile::build_random_jar(), + None, + Some(serde_json::from_value(patch).unwrap()), + USER_USER_PAT, + ) + .await; + assert_status!(&resp, StatusCode::OK); + + let project = api + .get_project_deserialized( + &test_project.slug.unwrap(), + USER_USER_PAT, + ) + .await; + assert_eq!(project.client_side, LegacySideType::Optional); + assert_eq!(project.server_side, LegacySideType::Required); + }, + ) + .await; +} + +#[actix_rt::test] +async fn create_project_initial_version_accepts_environment_v2() { + with_test_environment( + None, + |test_env: TestEnvironment| async move { + let api = &test_env.api; + let slug = "test-project-version-environment"; + let patch = json!([{ + "op": "add", + "path": "/initial_versions/0/environment", + "value": "client_only_server_optional" + }]); + let creation_data = get_public_project_creation_data( + slug, + Some(TestFile::build_random_jar()), + Some(serde_json::from_value(patch).unwrap()), + ); + + let resp = api.create_project(creation_data, USER_USER_PAT).await; + assert_status!(&resp, StatusCode::OK); + + let project = + api.get_project_deserialized(slug, USER_USER_PAT).await; + assert_eq!(project.client_side, LegacySideType::Required); + assert_eq!(project.server_side, LegacySideType::Optional); + }, + ) + .await; +} + #[actix_rt::test] async fn test_incorrect_file_parts() { // Ensures that a version get that 'should' have mrpack_loaders does still display them