use std::{collections::HashMap, sync::Arc}; use actix_http::StatusCode; use serde_json::json; use crate::{ assert_status, common::{ api_common::{Api, ApiProject, ApiVersion}, database::{FRIEND_USER_PAT, MOD_USER_PAT, USER_USER_PAT}, dummy_data::{DUMMY_CATEGORIES, TestFile}, }, }; use super::{api_v3::ApiV3, environment::TestEnvironment}; pub async fn setup_search_projects( test_env: &TestEnvironment, ) -> Arc> { // Test setup and dummy data let api = &test_env.api; let test_name = test_env.db.database_name.clone(); let zeta_organization_id = &test_env.dummy.organization_zeta.organization_id; // Add dummy projects of various categories for searchability let mut project_creation_futures = vec![]; let create_async_future = |id: u64, pat: Option<&'static str>, is_modpack: bool, modify_json: Option| { let slug = format!("{test_name}-searchable-project-{id}"); let jar = if is_modpack { TestFile::build_random_mrpack() } else { TestFile::build_random_jar() }; 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 let resp = api .edit_project( &project.id.to_string(), json!({ "status": "approved" }), MOD_USER_PAT, ) .await; assert_status!(&resp, StatusCode::NO_CONTENT); (project.id.0, id) } }; // Test project 0 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/environment", "value": "server_only" }, { "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" }, ])) .unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, Some(modify_json), )); // Test project 1 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/environment", "value": "client_or_server" }, ])) .unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, Some(modify_json), )); // Test project 2 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/environment", "value": "server_only" }, { "op": "add", "path": "/name", "value": "Mysterious Project" }, ])) .unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, Some(modify_json), )); // Test project 3 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/environment", "value": "server_only" }, { "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.4"] }, { "op": "add", "path": "/name", "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, Some(modify_json), )); // Test project 4 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/environment", "value": "client_or_server" }, { "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, Some(modify_json), )); // Test project 5 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/environment", "value": "client_or_server" }, { "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, Some(modify_json), )); // Test project 6 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/environment", "value": "client_or_server_prefers_both" }, { "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" }, ])) .unwrap(); project_creation_futures.push(create_async_future( id, FRIEND_USER_PAT, false, 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 = serde_json::from_value(json!([ { "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[5..6] }, { "op": "add", "path": "/initial_versions/0/environment", "value": "client_or_server_prefers_both" }, { "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, Some(modify_json), )); // Test project 9 (organization) // This project gets added to the Zeta organization automatically let id = 9; let modify_json = serde_json::from_value(json!([ { "op": "add", "path": "/organization_id", "value": zeta_organization_id }, ])) .unwrap(); project_creation_futures.push(create_async_future( id, USER_USER_PAT, false, Some(modify_json), )); // Await all project creation // Returns a mapping of: // project id -> test id let id_conversion: Arc> = Arc::new( futures::future::join_all(project_creation_futures) .await .into_iter() .collect(), ); // Create a second version for project 7 let project_7 = api .get_project_deserialized_common( &format!("{test_name}-searchable-project-7"), USER_USER_PAT, ) .await; api.add_public_version( project_7.id, "1.0.0", TestFile::build_random_jar(), None, None, USER_USER_PAT, ) .await; // Forcibly reset the search index let resp = api.reset_search_index().await; assert_status!(&resp, StatusCode::NO_CONTENT); id_conversion }