use actix_http::StatusCode; use common::api_v3::ApiV3; use common::database::*; use common::dummy_data::DUMMY_CATEGORIES; use ariadne::ids::base62_impl::parse_base62; use common::environment::TestEnvironment; use common::environment::with_test_environment; use common::search::setup_search_projects; use futures::stream::StreamExt; use serde_json::json; use crate::common::api_common::Api; use crate::common::api_common::ApiProject; pub mod common; // TODO: Revisit this wit h the new modify_json in the version maker // That change here should be able to simplify it vastly #[actix_rt::test] async fn search_projects() { // Test setup and dummy data with_test_environment( Some(10), |test_env: TestEnvironment| async move { let id_conversion = setup_search_projects(&test_env).await; let api = &test_env.api; let test_name = test_env.db.database_name.clone(); // Pairs of: // 1. vec of search facets // 2. expected project ids to be returned by this search let pairs = vec![ ( json!([["categories:fabric"]]), vec![0, 1, 2, 3, 4, 5, 6, 7, 9], ), (json!([["categories:forge"]]), vec![7]), ( json!([["categories:fabric", "categories:forge"]]), vec![0, 1, 2, 3, 4, 5, 6, 7, 9], ), (json!([["categories:fabric"], ["categories:forge"]]), vec![]), ( json!([ ["categories:fabric"], [&format!("categories:{}", DUMMY_CATEGORIES[0])], ]), vec![1, 2, 3, 4], ), (json!([["project_types:modpack"]]), vec![4]), (json!([["environment:server_only"]]), vec![0, 2, 3]), ( json!([["environment:client_or_server_prefers_both"]]), vec![6, 7], ), (json!([["open_source:true"]]), vec![0, 1, 2, 4, 5, 6, 7, 9]), (json!([["license:MIT"]]), vec![1, 2, 4, 9]), (json!([[r#"name:'Mysterious Project'"#]]), vec![2, 3]), (json!([["author:user"]]), vec![0, 1, 2, 4, 5, 7, 9]), // Organization test '9' is included here as user is owner of org (json!([["game_versions:1.20.5"]]), vec![4, 5]), // bug fix ( json!([ // Only the forge one has 1.20.2, so its true that this project 'has' // 1.20.2 and a fabric version, but not true that it has a 1.20.2 fabric version. ["categories:fabric"], ["game_versions:1.20.2"] ]), vec![], ), // Project type change // Modpack should still be able to search based on former loader, even though technically the loader is 'mrpack' // (json!([["categories:mrpack"]]), vec![4]), // ( // json!([["categories:fabric"]]), // vec![4], // ), ( json!([["categories:fabric"], ["project_types:modpack"]]), vec![4], ), ]; // TODO: versions, game versions // Untested: // - downloads (not varied) // - color (not varied) // - created_timestamp (not varied) // - modified_timestamp (not varied) // TODO: multiple different project types test // Test searches let stream = futures::stream::iter(pairs); stream .for_each_concurrent(1, |(facets, mut expected_project_ids)| { let id_conversion = id_conversion.clone(); let test_name = test_name.clone(); async move { let projects = api .search_deserialized( Some(&format!("\"&{test_name}\"")), Some(facets.clone()), USER_USER_PAT, ) .await; let mut found_project_ids: Vec = projects .hits .into_iter() .map(|p| { id_conversion [&parse_base62(&p.project_id).unwrap()] }) .collect(); let num_hits = projects.total_hits; expected_project_ids.sort(); found_project_ids.sort(); println!("Facets: {facets:?}"); assert_eq!(found_project_ids, expected_project_ids); assert_eq!(num_hits, { expected_project_ids.len() }); } }) .await; }, ) .await; } #[actix_rt::test] async fn index_swaps() { with_test_environment( Some(10), |test_env: TestEnvironment| async move { // Reindex let resp = test_env.api.reset_search_index().await; assert_status!(&resp, StatusCode::NO_CONTENT); // Now we should get results let projects = test_env .api .search_deserialized( None, Some(json!([["categories:fabric"]])), USER_USER_PAT, ) .await; assert_eq!(projects.total_hits, 1); assert!(projects.hits[0].slug.as_ref().unwrap().contains("alpha")); // Delete the project let resp = test_env.api.remove_project("alpha", USER_USER_PAT).await; assert_status!(&resp, StatusCode::NO_CONTENT); // We should wait for deletions to be indexed let projects = test_env .api .search_deserialized( None, Some(json!([["categories:fabric"]])), USER_USER_PAT, ) .await; assert_eq!(projects.total_hits, 0); // When we reindex, it should be still gone let resp = test_env.api.reset_search_index().await; assert_status!(&resp, StatusCode::NO_CONTENT); let projects = test_env .api .search_deserialized( None, Some(json!([["categories:fabric"]])), USER_USER_PAT, ) .await; assert_eq!(projects.total_hits, 0); }, ) .await; }