You've already forked AstralRinth
forked from didirus/AstralRinth
Tests v2 recreate (#760)
* added common project information; setup for v2 test change * all tests now use with_test_environment * progress, failing * finished re-adding tests * prepare * cargo sqlx prepare -- --tests * fmt; clippy; prepare * sqlx prepare * adds version_create fix and corresponding test * merge fixes; rev * fmt, clippy, prepare * test cargo sqlx prepare
This commit is contained in:
17
.sqlx/query-2efd0efe9ce16b2da01d9bcc1603e3a7ad0f9a1e5a457770608bc41dbb83f2dd.json
generated
Normal file
17
.sqlx/query-2efd0efe9ce16b2da01d9bcc1603e3a7ad0f9a1e5a457770608bc41dbb83f2dd.json
generated
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "\n INSERT INTO payouts_values (user_id, mod_id, amount, created)\n SELECT * FROM UNNEST ($1::bigint[], $2::bigint[], $3::numeric[], $4::timestamptz[])\n ",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Int8Array",
|
||||||
|
"Int8Array",
|
||||||
|
"NumericArray",
|
||||||
|
"TimestamptzArray"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "2efd0efe9ce16b2da01d9bcc1603e3a7ad0f9a1e5a457770608bc41dbb83f2dd"
|
||||||
|
}
|
||||||
22
Cargo.lock
generated
22
Cargo.lock
generated
@@ -2219,6 +2219,18 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"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]]
|
[[package]]
|
||||||
name = "jsonwebtoken"
|
name = "jsonwebtoken"
|
||||||
version = "8.3.0"
|
version = "8.3.0"
|
||||||
@@ -2267,6 +2279,7 @@ dependencies = [
|
|||||||
"hyper-tls",
|
"hyper-tls",
|
||||||
"image",
|
"image",
|
||||||
"itertools 0.11.0",
|
"itertools 0.11.0",
|
||||||
|
"json-patch",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"lettre",
|
"lettre",
|
||||||
"log",
|
"log",
|
||||||
@@ -4674,6 +4687,15 @@ dependencies = [
|
|||||||
"tracing-core",
|
"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]]
|
[[package]]
|
||||||
name = "try-lock"
|
name = "try-lock"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ derive-new = "0.5.9"
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-http = "3.4.0"
|
actix-http = "3.4.0"
|
||||||
|
json-patch = "*"
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 0 # Minimal optimization, speeds up compilation
|
opt-level = 0 # Minimal optimization, speeds up compilation
|
||||||
lto = false # Disables Link Time Optimization
|
lto = false # Disables Link Time Optimization
|
||||||
|
|||||||
@@ -233,10 +233,12 @@ pub struct LegacyVersion {
|
|||||||
/// and are now part of the dynamic fields system
|
/// and are now part of the dynamic fields system
|
||||||
/// A list of game versions this project supports
|
/// A list of game versions this project supports
|
||||||
pub game_versions: Vec<String>,
|
pub game_versions: Vec<String>,
|
||||||
/// A list of loaders this project supports
|
|
||||||
|
/// A list of loaders this project supports (has a newtype struct)
|
||||||
pub loaders: Vec<Loader>,
|
pub loaders: Vec<Loader>,
|
||||||
|
|
||||||
// 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<i32>,
|
pub ordering: Option<i32>,
|
||||||
|
|
||||||
pub id: VersionId,
|
pub id: VersionId,
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ pub async fn version_create(
|
|||||||
for file_part in &legacy_create.file_parts {
|
for file_part in &legacy_create.file_parts {
|
||||||
if let Some(ext) = file_part.split('.').last() {
|
if let Some(ext) = file_part.split('.').last() {
|
||||||
match ext {
|
match ext {
|
||||||
"mrpack" => {
|
"mrpack" | "mrpack-primary" => {
|
||||||
project_type = Some("modpack");
|
project_type = Some("modpack");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -894,7 +894,6 @@ async fn create_initial_version(
|
|||||||
&mut loader_field_enum_values,
|
&mut loader_field_enum_values,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
println!("Made it past here");
|
|
||||||
let dependencies = version_data
|
let dependencies = version_data
|
||||||
.dependencies
|
.dependencies
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
use actix_web::test;
|
use actix_web::test;
|
||||||
use chrono::{DateTime, Duration, Utc};
|
use chrono::{DateTime, Duration, Utc};
|
||||||
use common::environment::TestEnvironment;
|
|
||||||
use common::permissions::PermissionsTest;
|
use common::permissions::PermissionsTest;
|
||||||
use common::{database::*, permissions::PermissionsTestContext};
|
use common::permissions::PermissionsTestContext;
|
||||||
|
use common::{
|
||||||
|
api_v3::ApiV3,
|
||||||
|
database::*,
|
||||||
|
environment::{with_test_environment, TestEnvironment},
|
||||||
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use labrinth::models::ids::base62_impl::parse_base62;
|
use labrinth::models::ids::base62_impl::parse_base62;
|
||||||
use labrinth::models::teams::ProjectPermissions;
|
use labrinth::models::teams::ProjectPermissions;
|
||||||
@@ -12,8 +16,8 @@ mod common;
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn analytics_revenue() {
|
pub async fn analytics_revenue() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
|
|
||||||
let alpha_project_id = test_env
|
let alpha_project_id = test_env
|
||||||
.dummy
|
.dummy
|
||||||
@@ -124,9 +128,8 @@ pub async fn analytics_revenue() {
|
|||||||
for k in sorted_keys {
|
for k in sorted_keys {
|
||||||
assert_eq!(k % day, 0);
|
assert_eq!(k % day, 0);
|
||||||
}
|
}
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_f64_rounded_up(d: Decimal) -> f64 {
|
fn to_f64_rounded_up(d: Decimal) -> f64 {
|
||||||
@@ -141,8 +144,7 @@ fn to_f64_vec_rounded_up(d: Vec<Decimal>) -> Vec<f64> {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn permissions_analytics_revenue() {
|
pub async fn permissions_analytics_revenue() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
|
||||||
|
|
||||||
let alpha_project_id = test_env
|
let alpha_project_id = test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -226,4 +228,6 @@ pub async fn permissions_analytics_revenue() {
|
|||||||
|
|
||||||
// Cleanup test db
|
// Cleanup test db
|
||||||
test_env.cleanup().await;
|
test_env.cleanup().await;
|
||||||
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|||||||
136
tests/common/api_common/generic.rs
Normal file
136
tests/common/api_common/generic.rs
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use actix_web::dev::ServiceResponse;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use labrinth::{
|
||||||
|
models::{
|
||||||
|
projects::{ProjectId, VersionType},
|
||||||
|
teams::{OrganizationPermissions, ProjectPermissions},
|
||||||
|
},
|
||||||
|
search::SearchResults,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::common::{api_v2::ApiV2, api_v3::ApiV3, dummy_data::TestFile};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
models::{CommonImageData, CommonProject, CommonVersion},
|
||||||
|
Api, ApiProject, ApiTags, ApiTeams, ApiVersion,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum GenericApi {
|
||||||
|
V2(ApiV2),
|
||||||
|
V3(ApiV3),
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! delegate_api_variant {
|
||||||
|
(
|
||||||
|
$(#[$meta:meta])*
|
||||||
|
impl $impl_name:ident for $struct_name:ident {
|
||||||
|
$(
|
||||||
|
[$method_name:ident, $ret:ty, $($param_name:ident: $param_type:ty),*]
|
||||||
|
),* $(,)?
|
||||||
|
}
|
||||||
|
|
||||||
|
) => {
|
||||||
|
$(#[$meta])*
|
||||||
|
impl $impl_name for $struct_name {
|
||||||
|
$(
|
||||||
|
async fn $method_name(&self, $($param_name: $param_type),*) -> $ret {
|
||||||
|
match self {
|
||||||
|
$struct_name::V2(api) => api.$method_name($($param_name),*).await,
|
||||||
|
$struct_name::V3(api) => api.$method_name($($param_name),*).await,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
impl Api for GenericApi {
|
||||||
|
async fn call(&self, req: actix_http::Request) -> ServiceResponse {
|
||||||
|
match self {
|
||||||
|
Self::V2(api) => api.call(req).await,
|
||||||
|
Self::V3(api) => api.call(req).await,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn reset_search_index(&self) -> ServiceResponse {
|
||||||
|
match self {
|
||||||
|
Self::V2(api) => api.reset_search_index().await,
|
||||||
|
Self::V3(api) => api.reset_search_index().await,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate_api_variant!(
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
impl ApiProject for GenericApi {
|
||||||
|
[add_public_project, (CommonProject, Vec<CommonVersion>), slug: &str, version_jar: Option<TestFile>, modify_json: Option<json_patch::Patch>, 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],
|
||||||
|
[get_user_projects, ServiceResponse, user_id_or_username: &str, pat: &str],
|
||||||
|
[get_user_projects_deserialized_common, Vec<CommonProject>, user_id_or_username: &str, pat: &str],
|
||||||
|
[edit_project, ServiceResponse, id_or_slug: &str, patch: serde_json::Value, pat: &str],
|
||||||
|
[edit_project_bulk, ServiceResponse, ids_or_slugs: &[&str], patch: serde_json::Value, pat: &str],
|
||||||
|
[edit_project_icon, ServiceResponse, id_or_slug: &str, icon: Option<CommonImageData>, pat: &str],
|
||||||
|
[search_deserialized_common, SearchResults, query: Option<&str>, facets: Option<serde_json::Value>, pat: &str],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
delegate_api_variant!(
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
impl ApiTags for GenericApi {
|
||||||
|
[get_loaders, ServiceResponse,],
|
||||||
|
[get_loaders_deserialized_common, Vec<crate::common::api_common::models::CommonLoaderData>,],
|
||||||
|
[get_categories, ServiceResponse,],
|
||||||
|
[get_categories_deserialized_common, Vec<crate::common::api_common::models::CommonCategoryData>,],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
delegate_api_variant!(
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
impl ApiTeams for GenericApi {
|
||||||
|
[get_team_members, ServiceResponse, team_id: &str, pat: &str],
|
||||||
|
[get_team_members_deserialized_common, Vec<crate::common::api_common::models::CommonTeamMember>, team_id: &str, pat: &str],
|
||||||
|
[get_project_members, ServiceResponse, id_or_slug: &str, pat: &str],
|
||||||
|
[get_project_members_deserialized_common, Vec<crate::common::api_common::models::CommonTeamMember>, id_or_slug: &str, pat: &str],
|
||||||
|
[get_organization_members, ServiceResponse, id_or_title: &str, pat: &str],
|
||||||
|
[get_organization_members_deserialized_common, Vec<crate::common::api_common::models::CommonTeamMember>, id_or_title: &str, pat: &str],
|
||||||
|
[join_team, ServiceResponse, team_id: &str, pat: &str],
|
||||||
|
[remove_from_team, ServiceResponse, team_id: &str, user_id: &str, pat: &str],
|
||||||
|
[edit_team_member, ServiceResponse, team_id: &str, user_id: &str, patch: serde_json::Value, pat: &str],
|
||||||
|
[transfer_team_ownership, ServiceResponse, team_id: &str, user_id: &str, pat: &str],
|
||||||
|
[get_user_notifications, ServiceResponse, user_id: &str, pat: &str],
|
||||||
|
[get_user_notifications_deserialized_common, Vec<crate::common::api_common::models::CommonNotification>, user_id: &str, pat: &str],
|
||||||
|
[mark_notification_read, ServiceResponse, notification_id: &str, pat: &str],
|
||||||
|
[add_user_to_team, ServiceResponse, team_id: &str, user_id: &str, project_permissions: Option<ProjectPermissions>, organization_permissions: Option<OrganizationPermissions>, pat: &str],
|
||||||
|
[delete_notification, ServiceResponse, notification_id: &str, pat: &str],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
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<i32>, modify_json: Option<json_patch::Patch>, pat: &str],
|
||||||
|
[add_public_version_deserialized_common, CommonVersion, project_id: ProjectId, version_number: &str, version_jar: TestFile, ordering: Option<i32>, modify_json: Option<json_patch::Patch>, 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<String>, pat: &str],
|
||||||
|
[get_versions_deserialized_common, Vec<CommonVersion>, ids_or_slugs: Vec<String>, 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],
|
||||||
|
[get_versions_from_hashes, ServiceResponse, hashes: &[&str], algorithm: &str, pat: &str],
|
||||||
|
[get_versions_from_hashes_deserialized_common, HashMap<String, CommonVersion>, hashes: &[&str], algorithm: &str, pat: &str],
|
||||||
|
[get_update_from_hash, ServiceResponse, hash: &str, algorithm: &str, loaders: Option<Vec<String>>,game_versions: Option<Vec<String>>, version_types: Option<Vec<String>>, pat: &str],
|
||||||
|
[get_update_from_hash_deserialized_common, CommonVersion, hash: &str, algorithm: &str,loaders: Option<Vec<String>>,game_versions: Option<Vec<String>>,version_types: Option<Vec<String>>, pat: &str],
|
||||||
|
[update_files, ServiceResponse, algorithm: &str, hashes: Vec<String>, loaders: Option<Vec<String>>, game_versions: Option<Vec<String>>, version_types: Option<Vec<String>>, pat: &str],
|
||||||
|
[update_files_deserialized_common, HashMap<String, CommonVersion>, algorithm: &str, hashes: Vec<String>, loaders: Option<Vec<String>>, game_versions: Option<Vec<String>>, version_types: Option<Vec<String>>, pat: &str],
|
||||||
|
[get_project_versions, ServiceResponse, project_id_slug: &str, game_versions: Option<Vec<String>>,loaders: Option<Vec<String>>,featured: Option<bool>, version_type: Option<VersionType>, limit: Option<usize>, offset: Option<usize>,pat: &str],
|
||||||
|
[get_project_versions_deserialized_common, Vec<CommonVersion>, project_id_slug: &str, game_versions: Option<Vec<String>>, loaders: Option<Vec<String>>,featured: Option<bool>,version_type: Option<VersionType>,limit: Option<usize>,offset: Option<usize>,pat: &str],
|
||||||
|
[edit_version_ordering, ServiceResponse, version_id: &str,ordering: Option<i32>,pat: &str],
|
||||||
|
}
|
||||||
|
);
|
||||||
262
tests/common/api_common/mod.rs
Normal file
262
tests/common/api_common/mod.rs
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use self::models::{
|
||||||
|
CommonCategoryData, CommonImageData, CommonLoaderData, CommonNotification, CommonProject,
|
||||||
|
CommonTeamMember, CommonVersion,
|
||||||
|
};
|
||||||
|
use actix_web::dev::ServiceResponse;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use labrinth::{
|
||||||
|
models::{
|
||||||
|
projects::{ProjectId, VersionType},
|
||||||
|
teams::{OrganizationPermissions, ProjectPermissions},
|
||||||
|
},
|
||||||
|
search::SearchResults,
|
||||||
|
LabrinthConfig,
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
pub trait Api: ApiProject + ApiTags + ApiTeams + ApiVersion {
|
||||||
|
async fn call(&self, req: actix_http::Request) -> ServiceResponse;
|
||||||
|
async fn reset_search_index(&self) -> ServiceResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
pub trait ApiProject {
|
||||||
|
async fn add_public_project(
|
||||||
|
&self,
|
||||||
|
slug: &str,
|
||||||
|
version_jar: Option<TestFile>,
|
||||||
|
modify_json: Option<json_patch::Patch>,
|
||||||
|
pat: &str,
|
||||||
|
) -> (CommonProject, Vec<CommonVersion>);
|
||||||
|
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;
|
||||||
|
async fn get_user_projects(&self, user_id_or_username: &str, pat: &str) -> ServiceResponse;
|
||||||
|
async fn get_user_projects_deserialized_common(
|
||||||
|
&self,
|
||||||
|
user_id_or_username: &str,
|
||||||
|
pat: &str,
|
||||||
|
) -> Vec<CommonProject>;
|
||||||
|
async fn edit_project(
|
||||||
|
&self,
|
||||||
|
id_or_slug: &str,
|
||||||
|
patch: serde_json::Value,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse;
|
||||||
|
async fn edit_project_bulk(
|
||||||
|
&self,
|
||||||
|
ids_or_slugs: &[&str],
|
||||||
|
patch: serde_json::Value,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse;
|
||||||
|
async fn edit_project_icon(
|
||||||
|
&self,
|
||||||
|
id_or_slug: &str,
|
||||||
|
icon: Option<CommonImageData>,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse;
|
||||||
|
async fn search_deserialized_common(
|
||||||
|
&self,
|
||||||
|
query: Option<&str>,
|
||||||
|
facets: Option<serde_json::Value>,
|
||||||
|
pat: &str,
|
||||||
|
) -> SearchResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
pub trait ApiTags {
|
||||||
|
async fn get_loaders(&self) -> ServiceResponse;
|
||||||
|
async fn get_loaders_deserialized_common(&self) -> Vec<CommonLoaderData>;
|
||||||
|
async fn get_categories(&self) -> ServiceResponse;
|
||||||
|
async fn get_categories_deserialized_common(&self) -> Vec<CommonCategoryData>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
pub trait ApiTeams {
|
||||||
|
async fn get_team_members(&self, team_id: &str, pat: &str) -> ServiceResponse;
|
||||||
|
async fn get_team_members_deserialized_common(
|
||||||
|
&self,
|
||||||
|
team_id: &str,
|
||||||
|
pat: &str,
|
||||||
|
) -> Vec<CommonTeamMember>;
|
||||||
|
async fn get_project_members(&self, id_or_slug: &str, pat: &str) -> ServiceResponse;
|
||||||
|
async fn get_project_members_deserialized_common(
|
||||||
|
&self,
|
||||||
|
id_or_slug: &str,
|
||||||
|
pat: &str,
|
||||||
|
) -> Vec<CommonTeamMember>;
|
||||||
|
async fn get_organization_members(&self, id_or_title: &str, pat: &str) -> ServiceResponse;
|
||||||
|
async fn get_organization_members_deserialized_common(
|
||||||
|
&self,
|
||||||
|
id_or_title: &str,
|
||||||
|
pat: &str,
|
||||||
|
) -> Vec<CommonTeamMember>;
|
||||||
|
async fn join_team(&self, team_id: &str, pat: &str) -> ServiceResponse;
|
||||||
|
async fn remove_from_team(&self, team_id: &str, user_id: &str, pat: &str) -> ServiceResponse;
|
||||||
|
async fn edit_team_member(
|
||||||
|
&self,
|
||||||
|
team_id: &str,
|
||||||
|
user_id: &str,
|
||||||
|
patch: serde_json::Value,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse;
|
||||||
|
async fn transfer_team_ownership(
|
||||||
|
&self,
|
||||||
|
team_id: &str,
|
||||||
|
user_id: &str,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse;
|
||||||
|
async fn get_user_notifications(&self, user_id: &str, pat: &str) -> ServiceResponse;
|
||||||
|
async fn get_user_notifications_deserialized_common(
|
||||||
|
&self,
|
||||||
|
user_id: &str,
|
||||||
|
pat: &str,
|
||||||
|
) -> Vec<CommonNotification>;
|
||||||
|
async fn mark_notification_read(&self, notification_id: &str, pat: &str) -> ServiceResponse;
|
||||||
|
async fn add_user_to_team(
|
||||||
|
&self,
|
||||||
|
team_id: &str,
|
||||||
|
user_id: &str,
|
||||||
|
project_permissions: Option<ProjectPermissions>,
|
||||||
|
organization_permissions: Option<OrganizationPermissions>,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse;
|
||||||
|
async fn delete_notification(&self, notification_id: &str, pat: &str) -> ServiceResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
pub trait ApiVersion {
|
||||||
|
async fn add_public_version(
|
||||||
|
&self,
|
||||||
|
project_id: ProjectId,
|
||||||
|
version_number: &str,
|
||||||
|
version_jar: TestFile,
|
||||||
|
ordering: Option<i32>,
|
||||||
|
modify_json: Option<json_patch::Patch>,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse;
|
||||||
|
async fn add_public_version_deserialized_common(
|
||||||
|
&self,
|
||||||
|
project_id: ProjectId,
|
||||||
|
version_number: &str,
|
||||||
|
version_jar: TestFile,
|
||||||
|
ordering: Option<i32>,
|
||||||
|
modify_json: Option<json_patch::Patch>,
|
||||||
|
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<String>, pat: &str) -> ServiceResponse;
|
||||||
|
async fn get_versions_deserialized_common(
|
||||||
|
&self,
|
||||||
|
ids_or_slugs: Vec<String>,
|
||||||
|
pat: &str,
|
||||||
|
) -> Vec<CommonVersion>;
|
||||||
|
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;
|
||||||
|
async fn get_versions_from_hashes(
|
||||||
|
&self,
|
||||||
|
hashes: &[&str],
|
||||||
|
algorithm: &str,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse;
|
||||||
|
async fn get_versions_from_hashes_deserialized_common(
|
||||||
|
&self,
|
||||||
|
hashes: &[&str],
|
||||||
|
algorithm: &str,
|
||||||
|
pat: &str,
|
||||||
|
) -> HashMap<String, CommonVersion>;
|
||||||
|
async fn get_update_from_hash(
|
||||||
|
&self,
|
||||||
|
hash: &str,
|
||||||
|
algorithm: &str,
|
||||||
|
loaders: Option<Vec<String>>,
|
||||||
|
game_versions: Option<Vec<String>>,
|
||||||
|
version_types: Option<Vec<String>>,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse;
|
||||||
|
async fn get_update_from_hash_deserialized_common(
|
||||||
|
&self,
|
||||||
|
hash: &str,
|
||||||
|
algorithm: &str,
|
||||||
|
loaders: Option<Vec<String>>,
|
||||||
|
game_versions: Option<Vec<String>>,
|
||||||
|
version_types: Option<Vec<String>>,
|
||||||
|
pat: &str,
|
||||||
|
) -> CommonVersion;
|
||||||
|
async fn update_files(
|
||||||
|
&self,
|
||||||
|
algorithm: &str,
|
||||||
|
hashes: Vec<String>,
|
||||||
|
loaders: Option<Vec<String>>,
|
||||||
|
game_versions: Option<Vec<String>>,
|
||||||
|
version_types: Option<Vec<String>>,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse;
|
||||||
|
async fn update_files_deserialized_common(
|
||||||
|
&self,
|
||||||
|
algorithm: &str,
|
||||||
|
hashes: Vec<String>,
|
||||||
|
loaders: Option<Vec<String>>,
|
||||||
|
game_versions: Option<Vec<String>>,
|
||||||
|
version_types: Option<Vec<String>>,
|
||||||
|
pat: &str,
|
||||||
|
) -> HashMap<String, CommonVersion>;
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
async fn get_project_versions(
|
||||||
|
&self,
|
||||||
|
project_id_slug: &str,
|
||||||
|
game_versions: Option<Vec<String>>,
|
||||||
|
loaders: Option<Vec<String>>,
|
||||||
|
featured: Option<bool>,
|
||||||
|
version_type: Option<VersionType>,
|
||||||
|
limit: Option<usize>,
|
||||||
|
offset: Option<usize>,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse;
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
async fn get_project_versions_deserialized_common(
|
||||||
|
&self,
|
||||||
|
slug: &str,
|
||||||
|
game_versions: Option<Vec<String>>,
|
||||||
|
loaders: Option<Vec<String>>,
|
||||||
|
featured: Option<bool>,
|
||||||
|
version_type: Option<VersionType>,
|
||||||
|
limit: Option<usize>,
|
||||||
|
offset: Option<usize>,
|
||||||
|
pat: &str,
|
||||||
|
) -> Vec<CommonVersion>;
|
||||||
|
async fn edit_version_ordering(
|
||||||
|
&self,
|
||||||
|
version_id: &str,
|
||||||
|
ordering: Option<i32>,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse;
|
||||||
|
}
|
||||||
141
tests/common/api_common/models.rs
Normal file
141
tests/common/api_common/models.rs
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use labrinth::models::{
|
||||||
|
notifications::{NotificationAction, NotificationBody, NotificationId},
|
||||||
|
organizations::OrganizationId,
|
||||||
|
projects::{
|
||||||
|
Dependency, DonationLink, GalleryItem, License, ModeratorMessage, MonetizationStatus,
|
||||||
|
ProjectId, ProjectStatus, VersionFile, VersionId, VersionStatus, VersionType,
|
||||||
|
},
|
||||||
|
teams::{OrganizationPermissions, ProjectPermissions, TeamId},
|
||||||
|
threads::ThreadId,
|
||||||
|
users::{User, UserId},
|
||||||
|
};
|
||||||
|
use rust_decimal::Decimal;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
// Fields shared by every version of the API.
|
||||||
|
// No struct in here should have ANY field that
|
||||||
|
// is not present in *every* version of the API.
|
||||||
|
|
||||||
|
// These are used for common tests- tests that can be used on both V2 AND v3 of the API and have the same results.
|
||||||
|
|
||||||
|
// Any test that requires version-specific fields should have its own test that is not done for each version,
|
||||||
|
// as the environment generator for both uses common fields.
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct CommonProject {
|
||||||
|
// For example, for CommonProject, we do not include:
|
||||||
|
// - game_versions (v2 only)
|
||||||
|
// - loader_fields (v3 only)
|
||||||
|
// - etc.
|
||||||
|
// For any tests that require those fields, we make a separate test with separate API functions tht do not use Common models.
|
||||||
|
pub id: ProjectId,
|
||||||
|
pub slug: Option<String>,
|
||||||
|
pub team: TeamId,
|
||||||
|
pub organization: Option<OrganizationId>,
|
||||||
|
pub title: String,
|
||||||
|
pub description: String,
|
||||||
|
pub body: String,
|
||||||
|
pub body_url: Option<String>,
|
||||||
|
pub published: DateTime<Utc>,
|
||||||
|
pub updated: DateTime<Utc>,
|
||||||
|
pub approved: Option<DateTime<Utc>>,
|
||||||
|
pub queued: Option<DateTime<Utc>>,
|
||||||
|
pub status: ProjectStatus,
|
||||||
|
pub requested_status: Option<ProjectStatus>,
|
||||||
|
pub moderator_message: Option<ModeratorMessage>,
|
||||||
|
pub license: License,
|
||||||
|
pub downloads: u32,
|
||||||
|
pub followers: u32,
|
||||||
|
pub categories: Vec<String>,
|
||||||
|
pub additional_categories: Vec<String>,
|
||||||
|
pub loaders: Vec<String>,
|
||||||
|
pub versions: Vec<VersionId>,
|
||||||
|
pub icon_url: Option<String>,
|
||||||
|
pub issues_url: Option<String>,
|
||||||
|
pub source_url: Option<String>,
|
||||||
|
pub wiki_url: Option<String>,
|
||||||
|
pub discord_url: Option<String>,
|
||||||
|
pub donation_urls: Option<Vec<DonationLink>>,
|
||||||
|
pub gallery: Vec<GalleryItem>,
|
||||||
|
pub color: Option<u32>,
|
||||||
|
pub thread_id: ThreadId,
|
||||||
|
pub monetization_status: MonetizationStatus,
|
||||||
|
}
|
||||||
|
#[derive(Deserialize, Clone)]
|
||||||
|
pub struct CommonVersion {
|
||||||
|
pub id: VersionId,
|
||||||
|
pub loaders: Vec<String>,
|
||||||
|
pub project_id: ProjectId,
|
||||||
|
pub author_id: UserId,
|
||||||
|
pub featured: bool,
|
||||||
|
pub name: String,
|
||||||
|
pub version_number: String,
|
||||||
|
pub changelog: String,
|
||||||
|
pub changelog_url: Option<String>,
|
||||||
|
pub date_published: DateTime<Utc>,
|
||||||
|
pub downloads: u32,
|
||||||
|
pub version_type: VersionType,
|
||||||
|
pub status: VersionStatus,
|
||||||
|
pub requested_status: Option<VersionStatus>,
|
||||||
|
pub files: Vec<VersionFile>,
|
||||||
|
pub dependencies: Vec<Dependency>,
|
||||||
|
|
||||||
|
// TODO: should ordering be in v2?
|
||||||
|
pub ordering: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct CommonImageData {
|
||||||
|
pub filename: String,
|
||||||
|
pub extension: String,
|
||||||
|
pub icon: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct CommonLoaderData {
|
||||||
|
pub icon: String,
|
||||||
|
pub name: String,
|
||||||
|
pub supported_project_types: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct CommonCategoryData {
|
||||||
|
pub icon: String,
|
||||||
|
pub name: String,
|
||||||
|
pub project_type: String,
|
||||||
|
pub header: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A member of a team
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct CommonTeamMember {
|
||||||
|
pub team_id: TeamId,
|
||||||
|
pub user: User,
|
||||||
|
pub role: String,
|
||||||
|
|
||||||
|
// TODO: Should these be removed from the Common?
|
||||||
|
pub permissions: Option<ProjectPermissions>,
|
||||||
|
pub organization_permissions: Option<OrganizationPermissions>,
|
||||||
|
|
||||||
|
pub accepted: bool,
|
||||||
|
pub payouts_split: Option<Decimal>,
|
||||||
|
pub ordering: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct CommonNotification {
|
||||||
|
pub id: NotificationId,
|
||||||
|
pub user_id: UserId,
|
||||||
|
pub read: bool,
|
||||||
|
pub created: DateTime<Utc>,
|
||||||
|
pub body: NotificationBody,
|
||||||
|
|
||||||
|
// DEPRECATED: use body field instead
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub type_: Option<String>,
|
||||||
|
pub title: String,
|
||||||
|
pub text: String,
|
||||||
|
pub link: String,
|
||||||
|
pub actions: Vec<NotificationAction>,
|
||||||
|
}
|
||||||
@@ -1,7 +1,12 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use super::environment::LocalService;
|
use super::{
|
||||||
use actix_web::dev::ServiceResponse;
|
api_common::{Api, ApiBuildable},
|
||||||
|
environment::LocalService,
|
||||||
|
};
|
||||||
|
use actix_web::{dev::ServiceResponse, test, App};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use labrinth::LabrinthConfig;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub mod project;
|
pub mod project;
|
||||||
@@ -15,12 +20,23 @@ pub struct ApiV2 {
|
|||||||
pub test_app: Rc<dyn LocalService>,
|
pub test_app: Rc<dyn LocalService>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApiV2 {
|
#[async_trait(?Send)]
|
||||||
pub async fn call(&self, req: actix_http::Request) -> ServiceResponse {
|
impl ApiBuildable for ApiV2 {
|
||||||
|
async fn build(labrinth_config: LabrinthConfig) -> Self {
|
||||||
|
let app = App::new().configure(|cfg| labrinth::app_config(cfg, labrinth_config.clone()));
|
||||||
|
let test_app: Rc<dyn LocalService> = Rc::new(test::init_service(app).await);
|
||||||
|
|
||||||
|
Self { test_app }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
impl Api for ApiV2 {
|
||||||
|
async fn call(&self, req: actix_http::Request) -> ServiceResponse {
|
||||||
self.test_app.call(req).await.unwrap()
|
self.test_app.call(req).await.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn reset_search_index(&self) -> ServiceResponse {
|
async fn reset_search_index(&self) -> ServiceResponse {
|
||||||
let req = actix_web::test::TestRequest::post()
|
let req = actix_web::test::TestRequest::post()
|
||||||
.uri("/v2/admin/_force_reindex")
|
.uri("/v2/admin/_force_reindex")
|
||||||
.append_header((
|
.append_header((
|
||||||
|
|||||||
@@ -1,30 +1,55 @@
|
|||||||
use crate::common::api_v2::request_data::ProjectCreationRequestData;
|
use crate::common::{
|
||||||
|
api_common::{
|
||||||
|
models::{CommonImageData, CommonProject, CommonVersion},
|
||||||
|
Api, ApiProject,
|
||||||
|
},
|
||||||
|
dummy_data::TestFile,
|
||||||
|
};
|
||||||
use actix_http::StatusCode;
|
use actix_http::StatusCode;
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
dev::ServiceResponse,
|
dev::ServiceResponse,
|
||||||
test::{self, TestRequest},
|
test::{self, TestRequest},
|
||||||
};
|
};
|
||||||
|
use async_trait::async_trait;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use chrono::{DateTime, Utc};
|
|
||||||
use labrinth::{
|
use labrinth::{
|
||||||
models::v2::projects::{LegacyProject, LegacyVersion},
|
models::v2::projects::LegacyProject, search::SearchResults, util::actix::AppendsMultipart,
|
||||||
search::SearchResults,
|
|
||||||
util::actix::AppendsMultipart,
|
|
||||||
};
|
};
|
||||||
use rust_decimal::Decimal;
|
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use crate::common::{asserts::assert_status, database::MOD_USER_PAT};
|
use crate::common::{asserts::assert_status, database::MOD_USER_PAT};
|
||||||
|
|
||||||
use super::{request_data::ImageData, ApiV2};
|
use super::{request_data::get_public_project_creation_data, ApiV2};
|
||||||
|
|
||||||
impl ApiV2 {
|
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,
|
&self,
|
||||||
creation_data: ProjectCreationRequestData,
|
user_id_or_username: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> (LegacyProject, Vec<LegacyVersion>) {
|
) -> Vec<LegacyProject> {
|
||||||
|
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<TestFile>,
|
||||||
|
modify_json: Option<json_patch::Patch>,
|
||||||
|
pat: &str,
|
||||||
|
) -> (CommonProject, Vec<CommonVersion>) {
|
||||||
|
let creation_data = get_public_project_creation_data(slug, version_jar, modify_json);
|
||||||
|
|
||||||
// Add a project.
|
// Add a project.
|
||||||
let req = TestRequest::post()
|
let req = TestRequest::post()
|
||||||
.uri("/v2/project")
|
.uri("/v2/project")
|
||||||
@@ -48,7 +73,7 @@ impl ApiV2 {
|
|||||||
assert_status(&resp, StatusCode::NO_CONTENT);
|
assert_status(&resp, StatusCode::NO_CONTENT);
|
||||||
|
|
||||||
let project = self
|
let project = self
|
||||||
.get_project_deserialized(&creation_data.slug, pat)
|
.get_project_deserialized_common(&creation_data.slug, pat)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
// Get project's versions
|
// Get project's versions
|
||||||
@@ -57,12 +82,12 @@ impl ApiV2 {
|
|||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = self.call(req).await;
|
let resp = self.call(req).await;
|
||||||
let versions: Vec<LegacyVersion> = test::read_body_json(resp).await;
|
let versions: Vec<CommonVersion> = test::read_body_json(resp).await;
|
||||||
|
|
||||||
(project, versions)
|
(project, versions)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove_project(&self, project_slug_or_id: &str, pat: &str) -> ServiceResponse {
|
async fn remove_project(&self, project_slug_or_id: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::delete()
|
let req = test::TestRequest::delete()
|
||||||
.uri(&format!("/v2/project/{project_slug_or_id}"))
|
.uri(&format!("/v2/project/{project_slug_or_id}"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -72,20 +97,21 @@ impl ApiV2 {
|
|||||||
resp
|
resp
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_project(&self, id_or_slug: &str, pat: &str) -> ServiceResponse {
|
async fn get_project(&self, id_or_slug: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
.uri(&format!("/v2/project/{id_or_slug}"))
|
.uri(&format!("/v2/project/{id_or_slug}"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
.to_request();
|
.to_request();
|
||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
pub async fn get_project_deserialized(&self, id_or_slug: &str, pat: &str) -> LegacyProject {
|
|
||||||
|
async fn get_project_deserialized_common(&self, id_or_slug: &str, pat: &str) -> CommonProject {
|
||||||
let resp = self.get_project(id_or_slug, pat).await;
|
let resp = self.get_project(id_or_slug, pat).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_user_projects(&self, user_id_or_username: &str, pat: &str) -> ServiceResponse {
|
async fn get_user_projects(&self, user_id_or_username: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::get()
|
let req = test::TestRequest::get()
|
||||||
.uri(&format!("/v2/user/{}/projects", user_id_or_username))
|
.uri(&format!("/v2/user/{}/projects", user_id_or_username))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -93,17 +119,17 @@ impl ApiV2 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_user_projects_deserialized(
|
async fn get_user_projects_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
user_id_or_username: &str,
|
user_id_or_username: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Vec<LegacyProject> {
|
) -> Vec<CommonProject> {
|
||||||
let resp = self.get_user_projects(user_id_or_username, pat).await;
|
let resp = self.get_user_projects(user_id_or_username, pat).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_project(
|
async fn edit_project(
|
||||||
&self,
|
&self,
|
||||||
id_or_slug: &str,
|
id_or_slug: &str,
|
||||||
patch: serde_json::Value,
|
patch: serde_json::Value,
|
||||||
@@ -118,14 +144,14 @@ impl ApiV2 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_project_bulk(
|
async fn edit_project_bulk(
|
||||||
&self,
|
&self,
|
||||||
ids_or_slugs: impl IntoIterator<Item = &str>,
|
ids_or_slugs: &[&str],
|
||||||
patch: serde_json::Value,
|
patch: serde_json::Value,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> ServiceResponse {
|
) -> ServiceResponse {
|
||||||
let projects_str = ids_or_slugs
|
let projects_str = ids_or_slugs
|
||||||
.into_iter()
|
.iter()
|
||||||
.map(|s| format!("\"{}\"", s))
|
.map(|s| format!("\"{}\"", s))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(",");
|
.join(",");
|
||||||
@@ -141,10 +167,10 @@ impl ApiV2 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_project_icon(
|
async fn edit_project_icon(
|
||||||
&self,
|
&self,
|
||||||
id_or_slug: &str,
|
id_or_slug: &str,
|
||||||
icon: Option<ImageData>,
|
icon: Option<CommonImageData>,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> ServiceResponse {
|
) -> ServiceResponse {
|
||||||
if let Some(icon) = icon {
|
if let Some(icon) = icon {
|
||||||
@@ -170,7 +196,7 @@ impl ApiV2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn search_deserialized(
|
async fn search_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
query: Option<&str>,
|
query: Option<&str>,
|
||||||
facets: Option<serde_json::Value>,
|
facets: Option<serde_json::Value>,
|
||||||
@@ -197,57 +223,4 @@ impl ApiV2 {
|
|||||||
assert_eq!(status, 200);
|
assert_eq!(status, 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_analytics_revenue(
|
|
||||||
&self,
|
|
||||||
id_or_slugs: Vec<&str>,
|
|
||||||
start_date: Option<DateTime<Utc>>,
|
|
||||||
end_date: Option<DateTime<Utc>>,
|
|
||||||
resolution_minutes: Option<u32>,
|
|
||||||
pat: &str,
|
|
||||||
) -> ServiceResponse {
|
|
||||||
let projects_string = serde_json::to_string(&id_or_slugs).unwrap();
|
|
||||||
let projects_string = urlencoding::encode(&projects_string);
|
|
||||||
|
|
||||||
let mut extra_args = String::new();
|
|
||||||
if let Some(start_date) = start_date {
|
|
||||||
let start_date = start_date.to_rfc3339();
|
|
||||||
// let start_date = serde_json::to_string(&start_date).unwrap();
|
|
||||||
let start_date = urlencoding::encode(&start_date);
|
|
||||||
extra_args.push_str(&format!("&start_date={start_date}"));
|
|
||||||
}
|
|
||||||
if let Some(end_date) = end_date {
|
|
||||||
let end_date = end_date.to_rfc3339();
|
|
||||||
// let end_date = serde_json::to_string(&end_date).unwrap();
|
|
||||||
let end_date = urlencoding::encode(&end_date);
|
|
||||||
extra_args.push_str(&format!("&end_date={end_date}"));
|
|
||||||
}
|
|
||||||
if let Some(resolution_minutes) = resolution_minutes {
|
|
||||||
extra_args.push_str(&format!("&resolution_minutes={}", resolution_minutes));
|
|
||||||
}
|
|
||||||
|
|
||||||
let req = test::TestRequest::get()
|
|
||||||
.uri(&format!(
|
|
||||||
"/v2/analytics/revenue?{projects_string}{extra_args}",
|
|
||||||
))
|
|
||||||
.append_header(("Authorization", pat))
|
|
||||||
.to_request();
|
|
||||||
|
|
||||||
self.call(req).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_analytics_revenue_deserialized(
|
|
||||||
&self,
|
|
||||||
id_or_slugs: Vec<&str>,
|
|
||||||
start_date: Option<DateTime<Utc>>,
|
|
||||||
end_date: Option<DateTime<Utc>>,
|
|
||||||
resolution_minutes: Option<u32>,
|
|
||||||
pat: &str,
|
|
||||||
) -> HashMap<String, HashMap<i64, Decimal>> {
|
|
||||||
let resp = self
|
|
||||||
.get_analytics_revenue(id_or_slugs, start_date, end_date, resolution_minutes, pat)
|
|
||||||
.await;
|
|
||||||
assert_eq!(resp.status(), 200);
|
|
||||||
test::read_body_json(resp).await
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,12 @@ pub struct ImageData {
|
|||||||
pub fn get_public_project_creation_data(
|
pub fn get_public_project_creation_data(
|
||||||
slug: &str,
|
slug: &str,
|
||||||
version_jar: Option<TestFile>,
|
version_jar: Option<TestFile>,
|
||||||
|
modify_json: Option<json_patch::Patch>,
|
||||||
) -> ProjectCreationRequestData {
|
) -> 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());
|
let multipart_data = get_public_creation_data_multipart(&json_data, version_jar.as_ref());
|
||||||
ProjectCreationRequestData {
|
ProjectCreationRequestData {
|
||||||
slug: slug.to_string(),
|
slug: slug.to_string(),
|
||||||
@@ -42,9 +46,15 @@ pub fn get_public_version_creation_data(
|
|||||||
project_id: ProjectId,
|
project_id: ProjectId,
|
||||||
version_number: &str,
|
version_number: &str,
|
||||||
version_jar: TestFile,
|
version_jar: TestFile,
|
||||||
|
ordering: Option<i32>,
|
||||||
|
modify_json: Option<json_patch::Patch>,
|
||||||
) -> VersionCreationRequestData {
|
) -> 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);
|
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));
|
let multipart_data = get_public_creation_data_multipart(&json_data, Some(&version_jar));
|
||||||
VersionCreationRequestData {
|
VersionCreationRequestData {
|
||||||
version: version_number.to_string(),
|
version: version_number.to_string(),
|
||||||
@@ -55,9 +65,10 @@ pub fn get_public_version_creation_data(
|
|||||||
|
|
||||||
pub fn get_public_version_creation_data_json(
|
pub fn get_public_version_creation_data_json(
|
||||||
version_number: &str,
|
version_number: &str,
|
||||||
|
ordering: Option<i32>,
|
||||||
version_jar: &TestFile,
|
version_jar: &TestFile,
|
||||||
) -> serde_json::Value {
|
) -> serde_json::Value {
|
||||||
json!({
|
let mut j = json!({
|
||||||
"file_parts": [version_jar.filename()],
|
"file_parts": [version_jar.filename()],
|
||||||
"version_number": version_number,
|
"version_number": version_number,
|
||||||
"version_title": "start",
|
"version_title": "start",
|
||||||
@@ -66,7 +77,11 @@ pub fn get_public_version_creation_data_json(
|
|||||||
"release_channel": "release",
|
"release_channel": "release",
|
||||||
"loaders": ["fabric"],
|
"loaders": ["fabric"],
|
||||||
"featured": true
|
"featured": true
|
||||||
})
|
});
|
||||||
|
if let Some(ordering) = ordering {
|
||||||
|
j["ordering"] = json!(ordering);
|
||||||
|
}
|
||||||
|
j
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_public_project_creation_data_json(
|
pub fn get_public_project_creation_data_json(
|
||||||
@@ -74,7 +89,7 @@ pub fn get_public_project_creation_data_json(
|
|||||||
version_jar: Option<&TestFile>,
|
version_jar: Option<&TestFile>,
|
||||||
) -> serde_json::Value {
|
) -> serde_json::Value {
|
||||||
let initial_versions = if let Some(jar) = version_jar {
|
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 {
|
} else {
|
||||||
json!([])
|
json!([])
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,16 +2,23 @@ use actix_web::{
|
|||||||
dev::ServiceResponse,
|
dev::ServiceResponse,
|
||||||
test::{self, TestRequest},
|
test::{self, TestRequest},
|
||||||
};
|
};
|
||||||
|
use async_trait::async_trait;
|
||||||
use labrinth::routes::v2::tags::{CategoryData, GameVersionQueryData, LoaderData};
|
use labrinth::routes::v2::tags::{CategoryData, GameVersionQueryData, LoaderData};
|
||||||
|
|
||||||
use crate::common::database::ADMIN_USER_PAT;
|
use crate::common::{
|
||||||
|
api_common::{
|
||||||
|
models::{CommonCategoryData, CommonLoaderData},
|
||||||
|
Api, ApiTags,
|
||||||
|
},
|
||||||
|
database::ADMIN_USER_PAT,
|
||||||
|
};
|
||||||
|
|
||||||
use super::ApiV2;
|
use super::ApiV2;
|
||||||
|
|
||||||
impl ApiV2 {
|
// TODO: Tag gets do not include PAT, as they are public.
|
||||||
// Tag gets do not include PAT, as they are public.
|
|
||||||
|
|
||||||
pub async fn get_side_types(&self) -> ServiceResponse {
|
impl ApiV2 {
|
||||||
|
async fn get_side_types(&self) -> ServiceResponse {
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
.uri("/v2/tag/side_type")
|
.uri("/v2/tag/side_type")
|
||||||
.append_header(("Authorization", ADMIN_USER_PAT))
|
.append_header(("Authorization", ADMIN_USER_PAT))
|
||||||
@@ -25,34 +32,6 @@ impl ApiV2 {
|
|||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_loaders(&self) -> ServiceResponse {
|
|
||||||
let req = TestRequest::get()
|
|
||||||
.uri("/v2/tag/loader")
|
|
||||||
.append_header(("Authorization", ADMIN_USER_PAT))
|
|
||||||
.to_request();
|
|
||||||
self.call(req).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_loaders_deserialized(&self) -> Vec<LoaderData> {
|
|
||||||
let resp = self.get_loaders().await;
|
|
||||||
assert_eq!(resp.status(), 200);
|
|
||||||
test::read_body_json(resp).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_categories(&self) -> ServiceResponse {
|
|
||||||
let req = TestRequest::get()
|
|
||||||
.uri("/v2/tag/category")
|
|
||||||
.append_header(("Authorization", ADMIN_USER_PAT))
|
|
||||||
.to_request();
|
|
||||||
self.call(req).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_categories_deserialized(&self) -> Vec<CategoryData> {
|
|
||||||
let resp = self.get_categories().await;
|
|
||||||
assert_eq!(resp.status(), 200);
|
|
||||||
test::read_body_json(resp).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_game_versions(&self) -> ServiceResponse {
|
pub async fn get_game_versions(&self) -> ServiceResponse {
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
.uri("/v2/tag/game_version")
|
.uri("/v2/tag/game_version")
|
||||||
@@ -66,4 +45,47 @@ impl ApiV2 {
|
|||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_loaders_deserialized(&self) -> Vec<LoaderData> {
|
||||||
|
let resp = self.get_loaders().await;
|
||||||
|
assert_eq!(resp.status(), 200);
|
||||||
|
test::read_body_json(resp).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_categories_deserialized(&self) -> Vec<CategoryData> {
|
||||||
|
let resp = self.get_categories().await;
|
||||||
|
assert_eq!(resp.status(), 200);
|
||||||
|
test::read_body_json(resp).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
impl ApiTags for ApiV2 {
|
||||||
|
async fn get_loaders(&self) -> ServiceResponse {
|
||||||
|
let req = TestRequest::get()
|
||||||
|
.uri("/v2/tag/loader")
|
||||||
|
.append_header(("Authorization", ADMIN_USER_PAT))
|
||||||
|
.to_request();
|
||||||
|
self.call(req).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_loaders_deserialized_common(&self) -> Vec<CommonLoaderData> {
|
||||||
|
let resp = self.get_loaders().await;
|
||||||
|
assert_eq!(resp.status(), 200);
|
||||||
|
test::read_body_json(resp).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_categories(&self) -> ServiceResponse {
|
||||||
|
let req = TestRequest::get()
|
||||||
|
.uri("/v2/tag/category")
|
||||||
|
.append_header(("Authorization", ADMIN_USER_PAT))
|
||||||
|
.to_request();
|
||||||
|
self.call(req).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_categories_deserialized_common(&self) -> Vec<CommonCategoryData> {
|
||||||
|
let resp = self.get_categories().await;
|
||||||
|
assert_eq!(resp.status(), 200);
|
||||||
|
test::read_body_json(resp).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
use actix_http::StatusCode;
|
use actix_http::StatusCode;
|
||||||
use actix_web::{dev::ServiceResponse, test};
|
use actix_web::{dev::ServiceResponse, test};
|
||||||
use labrinth::models::{
|
use async_trait::async_trait;
|
||||||
notifications::Notification,
|
use labrinth::models::teams::{OrganizationPermissions, ProjectPermissions};
|
||||||
teams::{OrganizationPermissions, ProjectPermissions, TeamMember},
|
|
||||||
};
|
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::common::asserts::assert_status;
|
use crate::common::{
|
||||||
|
api_common::{
|
||||||
|
models::{CommonNotification, CommonTeamMember},
|
||||||
|
Api, ApiTeams,
|
||||||
|
},
|
||||||
|
asserts::assert_status,
|
||||||
|
};
|
||||||
|
|
||||||
use super::ApiV2;
|
use super::ApiV2;
|
||||||
|
|
||||||
impl ApiV2 {
|
#[async_trait(?Send)]
|
||||||
pub async fn get_team_members(&self, id_or_title: &str, pat: &str) -> ServiceResponse {
|
impl ApiTeams for ApiV2 {
|
||||||
|
async fn get_team_members(&self, id_or_title: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::get()
|
let req = test::TestRequest::get()
|
||||||
.uri(&format!("/v2/team/{id_or_title}/members"))
|
.uri(&format!("/v2/team/{id_or_title}/members"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -19,17 +24,17 @@ impl ApiV2 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_team_members_deserialized(
|
async fn get_team_members_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
id_or_title: &str,
|
id_or_title: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Vec<TeamMember> {
|
) -> Vec<CommonTeamMember> {
|
||||||
let resp = self.get_team_members(id_or_title, pat).await;
|
let resp = self.get_team_members(id_or_title, pat).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_project_members(&self, id_or_title: &str, pat: &str) -> ServiceResponse {
|
async fn get_project_members(&self, id_or_title: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::get()
|
let req = test::TestRequest::get()
|
||||||
.uri(&format!("/v2/project/{id_or_title}/members"))
|
.uri(&format!("/v2/project/{id_or_title}/members"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -37,17 +42,17 @@ impl ApiV2 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_project_members_deserialized(
|
async fn get_project_members_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
id_or_title: &str,
|
id_or_title: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Vec<TeamMember> {
|
) -> Vec<CommonTeamMember> {
|
||||||
let resp = self.get_project_members(id_or_title, pat).await;
|
let resp = self.get_project_members(id_or_title, pat).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_organization_members(&self, id_or_title: &str, pat: &str) -> ServiceResponse {
|
async fn get_organization_members(&self, id_or_title: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::get()
|
let req = test::TestRequest::get()
|
||||||
.uri(&format!("/v2/organization/{id_or_title}/members"))
|
.uri(&format!("/v2/organization/{id_or_title}/members"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -55,17 +60,17 @@ impl ApiV2 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_organization_members_deserialized(
|
async fn get_organization_members_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
id_or_title: &str,
|
id_or_title: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Vec<TeamMember> {
|
) -> Vec<CommonTeamMember> {
|
||||||
let resp = self.get_organization_members(id_or_title, pat).await;
|
let resp = self.get_organization_members(id_or_title, pat).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn join_team(&self, team_id: &str, pat: &str) -> ServiceResponse {
|
async fn join_team(&self, team_id: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::post()
|
let req = test::TestRequest::post()
|
||||||
.uri(&format!("/v2/team/{team_id}/join"))
|
.uri(&format!("/v2/team/{team_id}/join"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -73,12 +78,7 @@ impl ApiV2 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove_from_team(
|
async fn remove_from_team(&self, team_id: &str, user_id: &str, pat: &str) -> ServiceResponse {
|
||||||
&self,
|
|
||||||
team_id: &str,
|
|
||||||
user_id: &str,
|
|
||||||
pat: &str,
|
|
||||||
) -> ServiceResponse {
|
|
||||||
let req = test::TestRequest::delete()
|
let req = test::TestRequest::delete()
|
||||||
.uri(&format!("/v2/team/{team_id}/members/{user_id}"))
|
.uri(&format!("/v2/team/{team_id}/members/{user_id}"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -86,7 +86,7 @@ impl ApiV2 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_team_member(
|
async fn edit_team_member(
|
||||||
&self,
|
&self,
|
||||||
team_id: &str,
|
team_id: &str,
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
@@ -101,7 +101,7 @@ impl ApiV2 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn transfer_team_ownership(
|
async fn transfer_team_ownership(
|
||||||
&self,
|
&self,
|
||||||
team_id: &str,
|
team_id: &str,
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
@@ -117,7 +117,7 @@ impl ApiV2 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_user_notifications(&self, user_id: &str, pat: &str) -> ServiceResponse {
|
async fn get_user_notifications(&self, user_id: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::get()
|
let req = test::TestRequest::get()
|
||||||
.uri(&format!("/v2/user/{user_id}/notifications"))
|
.uri(&format!("/v2/user/{user_id}/notifications"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -125,28 +125,25 @@ impl ApiV2 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_user_notifications_deserialized(
|
async fn get_user_notifications_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Vec<Notification> {
|
) -> Vec<CommonNotification> {
|
||||||
let resp = self.get_user_notifications(user_id, pat).await;
|
let resp = self.get_user_notifications(user_id, pat).await;
|
||||||
assert_status(&resp, StatusCode::OK);
|
assert_status(&resp, StatusCode::OK);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn mark_notification_read(
|
async fn mark_notification_read(&self, notification_id: &str, pat: &str) -> ServiceResponse {
|
||||||
&self,
|
|
||||||
notification_id: &str,
|
|
||||||
pat: &str,
|
|
||||||
) -> ServiceResponse {
|
|
||||||
let req = test::TestRequest::patch()
|
let req = test::TestRequest::patch()
|
||||||
.uri(&format!("/v2/notification/{notification_id}"))
|
.uri(&format!("/v2/notification/{notification_id}"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
.to_request();
|
.to_request();
|
||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
pub async fn add_user_to_team(
|
|
||||||
|
async fn add_user_to_team(
|
||||||
&self,
|
&self,
|
||||||
team_id: &str,
|
team_id: &str,
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
@@ -166,7 +163,7 @@ impl ApiV2 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_notification(&self, notification_id: &str, pat: &str) -> ServiceResponse {
|
async fn delete_notification(&self, notification_id: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::delete()
|
let req = test::TestRequest::delete()
|
||||||
.uri(&format!("/v2/notification/{notification_id}"))
|
.uri(&format!("/v2/notification/{notification_id}"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
|
|||||||
@@ -1,101 +1,39 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use super::{request_data::get_public_version_creation_data, ApiV2};
|
||||||
|
use crate::common::{
|
||||||
|
api_common::{models::CommonVersion, Api, ApiVersion},
|
||||||
|
asserts::assert_status,
|
||||||
|
dummy_data::TestFile,
|
||||||
|
};
|
||||||
use actix_http::{header::AUTHORIZATION, StatusCode};
|
use actix_http::{header::AUTHORIZATION, StatusCode};
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
dev::ServiceResponse,
|
dev::ServiceResponse,
|
||||||
test::{self, TestRequest},
|
test::{self, TestRequest},
|
||||||
};
|
};
|
||||||
|
use async_trait::async_trait;
|
||||||
use labrinth::{
|
use labrinth::{
|
||||||
models::{projects::VersionType, v2::projects::LegacyVersion},
|
models::{
|
||||||
|
projects::{ProjectId, VersionType},
|
||||||
|
v2::projects::LegacyVersion,
|
||||||
|
},
|
||||||
routes::v2::version_file::FileUpdateData,
|
routes::v2::version_file::FileUpdateData,
|
||||||
util::actix::AppendsMultipart,
|
util::actix::AppendsMultipart,
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::common::asserts::assert_status;
|
|
||||||
|
|
||||||
use super::{request_data::VersionCreationRequestData, ApiV2};
|
|
||||||
|
|
||||||
pub fn url_encode_json_serialized_vec(elements: &[String]) -> String {
|
pub fn url_encode_json_serialized_vec(elements: &[String]) -> String {
|
||||||
let serialized = serde_json::to_string(&elements).unwrap();
|
let serialized = serde_json::to_string(&elements).unwrap();
|
||||||
urlencoding::encode(&serialized).to_string()
|
urlencoding::encode(&serialized).to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApiV2 {
|
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);
|
|
||||||
|
|
||||||
self.get_version_deserialized(version_id, pat).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_version(&self, id: &str, pat: &str) -> ServiceResponse {
|
|
||||||
let req = TestRequest::get()
|
|
||||||
.uri(&format!("/v2/version/{id}"))
|
|
||||||
.append_header(("Authorization", pat))
|
|
||||||
.to_request();
|
|
||||||
self.call(req).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_version_deserialized(&self, id: &str, pat: &str) -> LegacyVersion {
|
pub async fn get_version_deserialized(&self, id: &str, pat: &str) -> LegacyVersion {
|
||||||
let resp = self.get_version(id, pat).await;
|
let resp = self.get_version(id, pat).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_version(
|
|
||||||
&self,
|
|
||||||
version_id: &str,
|
|
||||||
patch: serde_json::Value,
|
|
||||||
pat: &str,
|
|
||||||
) -> ServiceResponse {
|
|
||||||
let req = test::TestRequest::patch()
|
|
||||||
.uri(&format!("/v2/version/{version_id}"))
|
|
||||||
.append_header(("Authorization", pat))
|
|
||||||
.set_json(patch)
|
|
||||||
.to_request();
|
|
||||||
|
|
||||||
self.call(req).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_version_from_hash(
|
|
||||||
&self,
|
|
||||||
hash: &str,
|
|
||||||
algorithm: &str,
|
|
||||||
pat: &str,
|
|
||||||
) -> ServiceResponse {
|
|
||||||
let req = test::TestRequest::get()
|
|
||||||
.uri(&format!("/v2/version_file/{hash}?algorithm={algorithm}"))
|
|
||||||
.append_header(("Authorization", pat))
|
|
||||||
.to_request();
|
|
||||||
self.call(req).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_version_from_hash_deserialized(
|
pub async fn get_version_from_hash_deserialized(
|
||||||
&self,
|
&self,
|
||||||
hash: &str,
|
hash: &str,
|
||||||
@@ -107,23 +45,6 @@ impl ApiV2 {
|
|||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_versions_from_hashes(
|
|
||||||
&self,
|
|
||||||
hashes: &[&str],
|
|
||||||
algorithm: &str,
|
|
||||||
pat: &str,
|
|
||||||
) -> ServiceResponse {
|
|
||||||
let req = TestRequest::post()
|
|
||||||
.uri("/v2/version_files")
|
|
||||||
.append_header(("Authorization", pat))
|
|
||||||
.set_json(json!({
|
|
||||||
"hashes": hashes,
|
|
||||||
"algorithm": algorithm,
|
|
||||||
}))
|
|
||||||
.to_request();
|
|
||||||
self.call(req).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_versions_from_hashes_deserialized(
|
pub async fn get_versions_from_hashes_deserialized(
|
||||||
&self,
|
&self,
|
||||||
hashes: &[&str],
|
hashes: &[&str],
|
||||||
@@ -135,91 +56,6 @@ impl ApiV2 {
|
|||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_update_from_hash(
|
|
||||||
&self,
|
|
||||||
hash: &str,
|
|
||||||
algorithm: &str,
|
|
||||||
loaders: Option<Vec<String>>,
|
|
||||||
game_versions: Option<Vec<String>>,
|
|
||||||
version_types: Option<Vec<String>>,
|
|
||||||
pat: &str,
|
|
||||||
) -> ServiceResponse {
|
|
||||||
let req = test::TestRequest::post()
|
|
||||||
.uri(&format!(
|
|
||||||
"/v2/version_file/{hash}/update?algorithm={algorithm}"
|
|
||||||
))
|
|
||||||
.append_header(("Authorization", pat))
|
|
||||||
.set_json(json!({
|
|
||||||
"loaders": loaders,
|
|
||||||
"game_versions": game_versions,
|
|
||||||
"version_types": version_types,
|
|
||||||
}))
|
|
||||||
.to_request();
|
|
||||||
self.call(req).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_update_from_hash_deserialized(
|
|
||||||
&self,
|
|
||||||
hash: &str,
|
|
||||||
algorithm: &str,
|
|
||||||
loaders: Option<Vec<String>>,
|
|
||||||
game_versions: Option<Vec<String>>,
|
|
||||||
version_types: Option<Vec<String>>,
|
|
||||||
pat: &str,
|
|
||||||
) -> LegacyVersion {
|
|
||||||
let resp = self
|
|
||||||
.get_update_from_hash(hash, algorithm, loaders, game_versions, version_types, pat)
|
|
||||||
.await;
|
|
||||||
assert_eq!(resp.status(), 200);
|
|
||||||
test::read_body_json(resp).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn update_files(
|
|
||||||
&self,
|
|
||||||
algorithm: &str,
|
|
||||||
hashes: Vec<String>,
|
|
||||||
loaders: Option<Vec<String>>,
|
|
||||||
game_versions: Option<Vec<String>>,
|
|
||||||
version_types: Option<Vec<String>>,
|
|
||||||
pat: &str,
|
|
||||||
) -> ServiceResponse {
|
|
||||||
let req = test::TestRequest::post()
|
|
||||||
.uri("/v2/version_files/update")
|
|
||||||
.append_header(("Authorization", pat))
|
|
||||||
.set_json(json!({
|
|
||||||
"algorithm": algorithm,
|
|
||||||
"hashes": hashes,
|
|
||||||
"loaders": loaders,
|
|
||||||
"game_versions": game_versions,
|
|
||||||
"version_types": version_types,
|
|
||||||
}))
|
|
||||||
.to_request();
|
|
||||||
self.call(req).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn update_files_deserialized(
|
|
||||||
&self,
|
|
||||||
algorithm: &str,
|
|
||||||
hashes: Vec<String>,
|
|
||||||
loaders: Option<Vec<String>>,
|
|
||||||
game_versions: Option<Vec<String>>,
|
|
||||||
version_types: Option<Vec<String>>,
|
|
||||||
pat: &str,
|
|
||||||
) -> HashMap<String, LegacyVersion> {
|
|
||||||
let resp = self
|
|
||||||
.update_files(
|
|
||||||
algorithm,
|
|
||||||
hashes,
|
|
||||||
loaders,
|
|
||||||
game_versions,
|
|
||||||
version_types,
|
|
||||||
pat,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
assert_eq!(resp.status(), 200);
|
|
||||||
test::read_body_json(resp).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn update_individual_files(
|
pub async fn update_individual_files(
|
||||||
&self,
|
&self,
|
||||||
algorithm: &str,
|
algorithm: &str,
|
||||||
@@ -247,10 +83,228 @@ impl ApiV2 {
|
|||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
impl ApiVersion for ApiV2 {
|
||||||
|
async fn add_public_version(
|
||||||
|
&self,
|
||||||
|
project_id: ProjectId,
|
||||||
|
version_number: &str,
|
||||||
|
version_jar: TestFile,
|
||||||
|
ordering: Option<i32>,
|
||||||
|
modify_json: Option<json_patch::Patch>,
|
||||||
|
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<i32>,
|
||||||
|
modify_json: Option<json_patch::Patch>,
|
||||||
|
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}"))
|
||||||
|
.append_header(("Authorization", pat))
|
||||||
|
.to_request();
|
||||||
|
self.call(req).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_version_deserialized_common(&self, id: &str, pat: &str) -> CommonVersion {
|
||||||
|
let resp = self.get_version(id, pat).await;
|
||||||
|
assert_eq!(resp.status(), 200);
|
||||||
|
test::read_body_json(resp).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn edit_version(
|
||||||
|
&self,
|
||||||
|
version_id: &str,
|
||||||
|
patch: serde_json::Value,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse {
|
||||||
|
let req = test::TestRequest::patch()
|
||||||
|
.uri(&format!("/v2/version/{version_id}"))
|
||||||
|
.append_header(("Authorization", pat))
|
||||||
|
.set_json(patch)
|
||||||
|
.to_request();
|
||||||
|
|
||||||
|
self.call(req).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_version_from_hash(
|
||||||
|
&self,
|
||||||
|
hash: &str,
|
||||||
|
algorithm: &str,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse {
|
||||||
|
let req = test::TestRequest::get()
|
||||||
|
.uri(&format!("/v2/version_file/{hash}?algorithm={algorithm}"))
|
||||||
|
.append_header(("Authorization", pat))
|
||||||
|
.to_request();
|
||||||
|
self.call(req).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_version_from_hash_deserialized_common(
|
||||||
|
&self,
|
||||||
|
hash: &str,
|
||||||
|
algorithm: &str,
|
||||||
|
pat: &str,
|
||||||
|
) -> CommonVersion {
|
||||||
|
let resp = self.get_version_from_hash(hash, algorithm, pat).await;
|
||||||
|
assert_eq!(resp.status(), 200);
|
||||||
|
test::read_body_json(resp).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_versions_from_hashes(
|
||||||
|
&self,
|
||||||
|
hashes: &[&str],
|
||||||
|
algorithm: &str,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse {
|
||||||
|
let req = TestRequest::post()
|
||||||
|
.uri("/v2/version_files")
|
||||||
|
.append_header(("Authorization", pat))
|
||||||
|
.set_json(json!({
|
||||||
|
"hashes": hashes,
|
||||||
|
"algorithm": algorithm,
|
||||||
|
}))
|
||||||
|
.to_request();
|
||||||
|
self.call(req).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_versions_from_hashes_deserialized_common(
|
||||||
|
&self,
|
||||||
|
hashes: &[&str],
|
||||||
|
algorithm: &str,
|
||||||
|
pat: &str,
|
||||||
|
) -> HashMap<String, CommonVersion> {
|
||||||
|
let resp = self.get_versions_from_hashes(hashes, algorithm, pat).await;
|
||||||
|
assert_eq!(resp.status(), 200);
|
||||||
|
test::read_body_json(resp).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_update_from_hash(
|
||||||
|
&self,
|
||||||
|
hash: &str,
|
||||||
|
algorithm: &str,
|
||||||
|
loaders: Option<Vec<String>>,
|
||||||
|
game_versions: Option<Vec<String>>,
|
||||||
|
version_types: Option<Vec<String>>,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse {
|
||||||
|
let req = test::TestRequest::post()
|
||||||
|
.uri(&format!(
|
||||||
|
"/v2/version_file/{hash}/update?algorithm={algorithm}"
|
||||||
|
))
|
||||||
|
.append_header(("Authorization", pat))
|
||||||
|
.set_json(json!({
|
||||||
|
"loaders": loaders,
|
||||||
|
"game_versions": game_versions,
|
||||||
|
"version_types": version_types,
|
||||||
|
}))
|
||||||
|
.to_request();
|
||||||
|
self.call(req).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_update_from_hash_deserialized_common(
|
||||||
|
&self,
|
||||||
|
hash: &str,
|
||||||
|
algorithm: &str,
|
||||||
|
loaders: Option<Vec<String>>,
|
||||||
|
game_versions: Option<Vec<String>>,
|
||||||
|
version_types: Option<Vec<String>>,
|
||||||
|
pat: &str,
|
||||||
|
) -> CommonVersion {
|
||||||
|
let resp = self
|
||||||
|
.get_update_from_hash(hash, algorithm, loaders, game_versions, version_types, pat)
|
||||||
|
.await;
|
||||||
|
assert_eq!(resp.status(), 200);
|
||||||
|
test::read_body_json(resp).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update_files(
|
||||||
|
&self,
|
||||||
|
algorithm: &str,
|
||||||
|
hashes: Vec<String>,
|
||||||
|
loaders: Option<Vec<String>>,
|
||||||
|
game_versions: Option<Vec<String>>,
|
||||||
|
version_types: Option<Vec<String>>,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse {
|
||||||
|
let req = test::TestRequest::post()
|
||||||
|
.uri("/v2/version_files/update")
|
||||||
|
.append_header(("Authorization", pat))
|
||||||
|
.set_json(json!({
|
||||||
|
"algorithm": algorithm,
|
||||||
|
"hashes": hashes,
|
||||||
|
"loaders": loaders,
|
||||||
|
"game_versions": game_versions,
|
||||||
|
"version_types": version_types,
|
||||||
|
}))
|
||||||
|
.to_request();
|
||||||
|
self.call(req).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update_files_deserialized_common(
|
||||||
|
&self,
|
||||||
|
algorithm: &str,
|
||||||
|
hashes: Vec<String>,
|
||||||
|
loaders: Option<Vec<String>>,
|
||||||
|
game_versions: Option<Vec<String>>,
|
||||||
|
version_types: Option<Vec<String>>,
|
||||||
|
pat: &str,
|
||||||
|
) -> HashMap<String, CommonVersion> {
|
||||||
|
let resp = self
|
||||||
|
.update_files(
|
||||||
|
algorithm,
|
||||||
|
hashes,
|
||||||
|
loaders,
|
||||||
|
game_versions,
|
||||||
|
version_types,
|
||||||
|
pat,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(resp.status(), 200);
|
||||||
|
test::read_body_json(resp).await
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Not all fields are tested currently in the V2 tests, only the v2-v3 relevant ones are
|
// TODO: Not all fields are tested currently in the V2 tests, only the v2-v3 relevant ones are
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub async fn get_project_versions(
|
async fn get_project_versions(
|
||||||
&self,
|
&self,
|
||||||
project_id_slug: &str,
|
project_id_slug: &str,
|
||||||
game_versions: Option<Vec<String>>,
|
game_versions: Option<Vec<String>>,
|
||||||
@@ -300,7 +354,7 @@ impl ApiV2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub async fn get_project_versions_deserialized(
|
async fn get_project_versions_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
slug: &str,
|
slug: &str,
|
||||||
game_versions: Option<Vec<String>>,
|
game_versions: Option<Vec<String>>,
|
||||||
@@ -310,7 +364,7 @@ impl ApiV2 {
|
|||||||
limit: Option<usize>,
|
limit: Option<usize>,
|
||||||
offset: Option<usize>,
|
offset: Option<usize>,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Vec<LegacyVersion> {
|
) -> Vec<CommonVersion> {
|
||||||
let resp = self
|
let resp = self
|
||||||
.get_project_versions(
|
.get_project_versions(
|
||||||
slug,
|
slug,
|
||||||
@@ -327,66 +381,7 @@ impl ApiV2 {
|
|||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove redundancy in these functions- some are essentially repeats
|
async fn edit_version_ordering(
|
||||||
pub async fn create_default_version(
|
|
||||||
&self,
|
|
||||||
project_id: &str,
|
|
||||||
ordering: Option<i32>,
|
|
||||||
pat: &str,
|
|
||||||
) -> LegacyVersion {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_versions(&self, version_ids: Vec<String>, pat: &str) -> Vec<LegacyVersion> {
|
|
||||||
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;
|
|
||||||
assert_status(&resp, StatusCode::OK);
|
|
||||||
test::read_body_json(resp).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn edit_version_ordering(
|
|
||||||
&self,
|
&self,
|
||||||
version_id: &str,
|
version_id: &str,
|
||||||
ordering: Option<i32>,
|
ordering: Option<i32>,
|
||||||
@@ -403,4 +398,23 @@ impl ApiV2 {
|
|||||||
.to_request();
|
.to_request();
|
||||||
self.call(request).await
|
self.call(request).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_versions(&self, version_ids: Vec<String>, 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();
|
||||||
|
self.call(request).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_versions_deserialized_common(
|
||||||
|
&self,
|
||||||
|
version_ids: Vec<String>,
|
||||||
|
pat: &str,
|
||||||
|
) -> Vec<CommonVersion> {
|
||||||
|
let resp = self.get_versions(version_ids, pat).await;
|
||||||
|
assert_status(&resp, StatusCode::OK);
|
||||||
|
test::read_body_json(resp).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use super::environment::LocalService;
|
use super::{
|
||||||
use actix_web::dev::ServiceResponse;
|
api_common::{Api, ApiBuildable},
|
||||||
|
environment::LocalService,
|
||||||
|
};
|
||||||
|
use actix_web::{dev::ServiceResponse, test, App};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use labrinth::LabrinthConfig;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub mod oauth;
|
pub mod oauth;
|
||||||
@@ -18,12 +23,23 @@ pub struct ApiV3 {
|
|||||||
pub test_app: Rc<dyn LocalService>,
|
pub test_app: Rc<dyn LocalService>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApiV3 {
|
#[async_trait(?Send)]
|
||||||
pub async fn call(&self, req: actix_http::Request) -> ServiceResponse {
|
impl ApiBuildable for ApiV3 {
|
||||||
|
async fn build(labrinth_config: LabrinthConfig) -> Self {
|
||||||
|
let app = App::new().configure(|cfg| labrinth::app_config(cfg, labrinth_config.clone()));
|
||||||
|
let test_app: Rc<dyn LocalService> = Rc::new(test::init_service(app).await);
|
||||||
|
|
||||||
|
Self { test_app }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
impl Api for ApiV3 {
|
||||||
|
async fn call(&self, req: actix_http::Request) -> ServiceResponse {
|
||||||
self.test_app.call(req).await.unwrap()
|
self.test_app.call(req).await.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn reset_search_index(&self) -> ServiceResponse {
|
async fn reset_search_index(&self) -> ServiceResponse {
|
||||||
let req = actix_web::test::TestRequest::post()
|
let req = actix_web::test::TestRequest::post()
|
||||||
.uri("/v3/admin/_force_reindex")
|
.uri("/v3/admin/_force_reindex")
|
||||||
.append_header((
|
.append_header((
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use labrinth::auth::oauth::{
|
|||||||
};
|
};
|
||||||
use reqwest::header::{AUTHORIZATION, LOCATION};
|
use reqwest::header::{AUTHORIZATION, LOCATION};
|
||||||
|
|
||||||
use crate::common::asserts::assert_status;
|
use crate::common::{api_common::Api, asserts::assert_status};
|
||||||
|
|
||||||
use super::ApiV3;
|
use super::ApiV3;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use labrinth::{
|
|||||||
use reqwest::header::AUTHORIZATION;
|
use reqwest::header::AUTHORIZATION;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::common::asserts::assert_status;
|
use crate::common::{api_common::Api, asserts::assert_status};
|
||||||
|
|
||||||
use super::ApiV3;
|
use super::ApiV3;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ use bytes::Bytes;
|
|||||||
use labrinth::models::{organizations::Organization, v3::projects::Project};
|
use labrinth::models::{organizations::Organization, v3::projects::Project};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
|
use crate::common::api_common::Api;
|
||||||
|
|
||||||
use super::{request_data::ImageData, ApiV3};
|
use super::{request_data::ImageData, ApiV3};
|
||||||
|
|
||||||
impl ApiV3 {
|
impl ApiV3 {
|
||||||
|
|||||||
@@ -5,29 +5,36 @@ use actix_web::{
|
|||||||
dev::ServiceResponse,
|
dev::ServiceResponse,
|
||||||
test::{self, TestRequest},
|
test::{self, TestRequest},
|
||||||
};
|
};
|
||||||
|
use async_trait::async_trait;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use labrinth::{
|
use labrinth::{search::SearchResults, util::actix::AppendsMultipart};
|
||||||
models::v3::projects::{Project, Version},
|
|
||||||
search::SearchResults,
|
|
||||||
util::actix::AppendsMultipart,
|
|
||||||
};
|
|
||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::common::{asserts::assert_status, database::MOD_USER_PAT};
|
use crate::common::{
|
||||||
|
api_common::{
|
||||||
use super::{
|
models::{CommonImageData, CommonProject, CommonVersion},
|
||||||
request_data::{ImageData, ProjectCreationRequestData},
|
Api, ApiProject,
|
||||||
ApiV3,
|
},
|
||||||
|
asserts::assert_status,
|
||||||
|
database::MOD_USER_PAT,
|
||||||
|
dummy_data::TestFile,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl ApiV3 {
|
use super::{request_data::get_public_project_creation_data, ApiV3};
|
||||||
pub async fn add_public_project(
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
impl ApiProject for ApiV3 {
|
||||||
|
async fn add_public_project(
|
||||||
&self,
|
&self,
|
||||||
creation_data: ProjectCreationRequestData,
|
slug: &str,
|
||||||
|
version_jar: Option<TestFile>,
|
||||||
|
modify_json: Option<json_patch::Patch>,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> (Project, Vec<Version>) {
|
) -> (CommonProject, Vec<CommonVersion>) {
|
||||||
|
let creation_data = get_public_project_creation_data(slug, version_jar, modify_json);
|
||||||
|
|
||||||
// Add a project.
|
// Add a project.
|
||||||
let req = TestRequest::post()
|
let req = TestRequest::post()
|
||||||
.uri("/v3/project")
|
.uri("/v3/project")
|
||||||
@@ -50,9 +57,8 @@ impl ApiV3 {
|
|||||||
let resp = self.call(req).await;
|
let resp = self.call(req).await;
|
||||||
assert_status(&resp, StatusCode::NO_CONTENT);
|
assert_status(&resp, StatusCode::NO_CONTENT);
|
||||||
|
|
||||||
let project = self
|
let project = self.get_project(&creation_data.slug, pat).await;
|
||||||
.get_project_deserialized(&creation_data.slug, pat)
|
let project = test::read_body_json(project).await;
|
||||||
.await;
|
|
||||||
|
|
||||||
// Get project's versions
|
// Get project's versions
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
@@ -60,12 +66,12 @@ impl ApiV3 {
|
|||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = self.call(req).await;
|
let resp = self.call(req).await;
|
||||||
let versions: Vec<Version> = test::read_body_json(resp).await;
|
let versions: Vec<CommonVersion> = test::read_body_json(resp).await;
|
||||||
|
|
||||||
(project, versions)
|
(project, versions)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove_project(&self, project_slug_or_id: &str, pat: &str) -> ServiceResponse {
|
async fn remove_project(&self, project_slug_or_id: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::delete()
|
let req = test::TestRequest::delete()
|
||||||
.uri(&format!("/v3/project/{project_slug_or_id}"))
|
.uri(&format!("/v3/project/{project_slug_or_id}"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -75,20 +81,21 @@ impl ApiV3 {
|
|||||||
resp
|
resp
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_project(&self, id_or_slug: &str, pat: &str) -> ServiceResponse {
|
async fn get_project(&self, id_or_slug: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
.uri(&format!("/v3/project/{id_or_slug}"))
|
.uri(&format!("/v3/project/{id_or_slug}"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
.to_request();
|
.to_request();
|
||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
pub async fn get_project_deserialized(&self, id_or_slug: &str, pat: &str) -> Project {
|
|
||||||
|
async fn get_project_deserialized_common(&self, id_or_slug: &str, pat: &str) -> CommonProject {
|
||||||
let resp = self.get_project(id_or_slug, pat).await;
|
let resp = self.get_project(id_or_slug, pat).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_user_projects(&self, user_id_or_username: &str, pat: &str) -> ServiceResponse {
|
async fn get_user_projects(&self, user_id_or_username: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::get()
|
let req = test::TestRequest::get()
|
||||||
.uri(&format!("/v3/user/{}/projects", user_id_or_username))
|
.uri(&format!("/v3/user/{}/projects", user_id_or_username))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -96,17 +103,17 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_user_projects_deserialized(
|
async fn get_user_projects_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
user_id_or_username: &str,
|
user_id_or_username: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Vec<Project> {
|
) -> Vec<CommonProject> {
|
||||||
let resp = self.get_user_projects(user_id_or_username, pat).await;
|
let resp = self.get_user_projects(user_id_or_username, pat).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_project(
|
async fn edit_project(
|
||||||
&self,
|
&self,
|
||||||
id_or_slug: &str,
|
id_or_slug: &str,
|
||||||
patch: serde_json::Value,
|
patch: serde_json::Value,
|
||||||
@@ -121,14 +128,14 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_project_bulk(
|
async fn edit_project_bulk(
|
||||||
&self,
|
&self,
|
||||||
ids_or_slugs: impl IntoIterator<Item = &str>,
|
ids_or_slugs: &[&str],
|
||||||
patch: serde_json::Value,
|
patch: serde_json::Value,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> ServiceResponse {
|
) -> ServiceResponse {
|
||||||
let projects_str = ids_or_slugs
|
let projects_str = ids_or_slugs
|
||||||
.into_iter()
|
.iter()
|
||||||
.map(|s| format!("\"{}\"", s))
|
.map(|s| format!("\"{}\"", s))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(",");
|
.join(",");
|
||||||
@@ -144,10 +151,10 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_project_icon(
|
async fn edit_project_icon(
|
||||||
&self,
|
&self,
|
||||||
id_or_slug: &str,
|
id_or_slug: &str,
|
||||||
icon: Option<ImageData>,
|
icon: Option<CommonImageData>,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> ServiceResponse {
|
) -> ServiceResponse {
|
||||||
if let Some(icon) = icon {
|
if let Some(icon) = icon {
|
||||||
@@ -173,7 +180,7 @@ impl ApiV3 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn search_deserialized(
|
async fn search_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
query: Option<&str>,
|
query: Option<&str>,
|
||||||
facets: Option<serde_json::Value>,
|
facets: Option<serde_json::Value>,
|
||||||
@@ -200,7 +207,9 @@ impl ApiV3 {
|
|||||||
assert_eq!(status, 200);
|
assert_eq!(status, 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ApiV3 {
|
||||||
pub async fn get_analytics_revenue(
|
pub async fn get_analytics_revenue(
|
||||||
&self,
|
&self,
|
||||||
id_or_slugs: Vec<&str>,
|
id_or_slugs: Vec<&str>,
|
||||||
|
|||||||
@@ -28,8 +28,12 @@ pub struct ImageData {
|
|||||||
pub fn get_public_project_creation_data(
|
pub fn get_public_project_creation_data(
|
||||||
slug: &str,
|
slug: &str,
|
||||||
version_jar: Option<TestFile>,
|
version_jar: Option<TestFile>,
|
||||||
|
modify_json: Option<json_patch::Patch>,
|
||||||
) -> ProjectCreationRequestData {
|
) -> 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());
|
let multipart_data = get_public_creation_data_multipart(&json_data, version_jar.as_ref());
|
||||||
ProjectCreationRequestData {
|
ProjectCreationRequestData {
|
||||||
slug: slug.to_string(),
|
slug: slug.to_string(),
|
||||||
@@ -42,14 +46,16 @@ pub fn get_public_version_creation_data(
|
|||||||
project_id: ProjectId,
|
project_id: ProjectId,
|
||||||
version_number: &str,
|
version_number: &str,
|
||||||
version_jar: TestFile,
|
version_jar: TestFile,
|
||||||
|
ordering: Option<i32>,
|
||||||
// closure that takes in a &mut serde_json::Value
|
// closure that takes in a &mut serde_json::Value
|
||||||
// and modifies it before it is serialized and sent
|
// and modifies it before it is serialized and sent
|
||||||
modify_json: Option<impl FnOnce(&mut serde_json::Value)>,
|
modify_json: Option<json_patch::Patch>,
|
||||||
) -> VersionCreationRequestData {
|
) -> 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);
|
json_data["project_id"] = json!(project_id);
|
||||||
if let Some(modify_json) = modify_json {
|
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));
|
let multipart_data = get_public_creation_data_multipart(&json_data, Some(&version_jar));
|
||||||
@@ -62,6 +68,7 @@ pub fn get_public_version_creation_data(
|
|||||||
|
|
||||||
pub fn get_public_version_creation_data_json(
|
pub fn get_public_version_creation_data_json(
|
||||||
version_number: &str,
|
version_number: &str,
|
||||||
|
ordering: Option<i32>,
|
||||||
version_jar: &TestFile,
|
version_jar: &TestFile,
|
||||||
) -> serde_json::Value {
|
) -> serde_json::Value {
|
||||||
let is_modpack = version_jar.project_type() == "modpack";
|
let is_modpack = version_jar.project_type() == "modpack";
|
||||||
@@ -82,6 +89,9 @@ pub fn get_public_version_creation_data_json(
|
|||||||
if is_modpack {
|
if is_modpack {
|
||||||
j["mrpack_loaders"] = json!(["fabric"]);
|
j["mrpack_loaders"] = json!(["fabric"]);
|
||||||
}
|
}
|
||||||
|
if let Some(ordering) = ordering {
|
||||||
|
j["ordering"] = json!(ordering);
|
||||||
|
}
|
||||||
j
|
j
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +100,7 @@ pub fn get_public_project_creation_data_json(
|
|||||||
version_jar: Option<&TestFile>,
|
version_jar: Option<&TestFile>,
|
||||||
) -> serde_json::Value {
|
) -> serde_json::Value {
|
||||||
let initial_versions = if let Some(jar) = version_jar {
|
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 {
|
} else {
|
||||||
json!([])
|
json!([])
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,18 +2,23 @@ use actix_web::{
|
|||||||
dev::ServiceResponse,
|
dev::ServiceResponse,
|
||||||
test::{self, TestRequest},
|
test::{self, TestRequest},
|
||||||
};
|
};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use labrinth::database::models::loader_fields::LoaderFieldEnumValue;
|
||||||
use labrinth::routes::v3::tags::GameData;
|
use labrinth::routes::v3::tags::GameData;
|
||||||
use labrinth::{
|
|
||||||
database::models::loader_fields::LoaderFieldEnumValue,
|
|
||||||
routes::v3::tags::{CategoryData, LoaderData},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::common::database::ADMIN_USER_PAT;
|
use crate::common::{
|
||||||
|
api_common::{
|
||||||
|
models::{CommonCategoryData, CommonLoaderData},
|
||||||
|
Api, ApiTags,
|
||||||
|
},
|
||||||
|
database::ADMIN_USER_PAT,
|
||||||
|
};
|
||||||
|
|
||||||
use super::ApiV3;
|
use super::ApiV3;
|
||||||
|
|
||||||
impl ApiV3 {
|
#[async_trait(?Send)]
|
||||||
pub async fn get_loaders(&self) -> ServiceResponse {
|
impl ApiTags for ApiV3 {
|
||||||
|
async fn get_loaders(&self) -> ServiceResponse {
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
.uri("/v3/tag/loader")
|
.uri("/v3/tag/loader")
|
||||||
.append_header(("Authorization", ADMIN_USER_PAT))
|
.append_header(("Authorization", ADMIN_USER_PAT))
|
||||||
@@ -21,13 +26,13 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_loaders_deserialized(&self) -> Vec<LoaderData> {
|
async fn get_loaders_deserialized_common(&self) -> Vec<CommonLoaderData> {
|
||||||
let resp = self.get_loaders().await;
|
let resp = self.get_loaders().await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_categories(&self) -> ServiceResponse {
|
async fn get_categories(&self) -> ServiceResponse {
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
.uri("/v3/tag/category")
|
.uri("/v3/tag/category")
|
||||||
.append_header(("Authorization", ADMIN_USER_PAT))
|
.append_header(("Authorization", ADMIN_USER_PAT))
|
||||||
@@ -35,12 +40,14 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_categories_deserialized(&self) -> Vec<CategoryData> {
|
async fn get_categories_deserialized_common(&self) -> Vec<CommonCategoryData> {
|
||||||
let resp = self.get_categories().await;
|
let resp = self.get_categories().await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ApiV3 {
|
||||||
pub async fn get_loader_field_variants(&self, loader_field: &str) -> ServiceResponse {
|
pub async fn get_loader_field_variants(&self, loader_field: &str) -> ServiceResponse {
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
.uri(&format!("/v3/loader_field?loader_field={}", loader_field))
|
.uri(&format!("/v3/loader_field?loader_field={}", loader_field))
|
||||||
@@ -59,7 +66,7 @@ impl ApiV3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: fold this into v3 API of other v3 testing PR
|
// TODO: fold this into v3 API of other v3 testing PR
|
||||||
pub async fn get_games(&self) -> ServiceResponse {
|
async fn get_games(&self) -> ServiceResponse {
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
.uri("/v3/games")
|
.uri("/v3/games")
|
||||||
.append_header(("Authorization", ADMIN_USER_PAT))
|
.append_header(("Authorization", ADMIN_USER_PAT))
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
use actix_http::StatusCode;
|
use actix_http::StatusCode;
|
||||||
use actix_web::{dev::ServiceResponse, test};
|
use actix_web::{dev::ServiceResponse, test};
|
||||||
use labrinth::models::{
|
use async_trait::async_trait;
|
||||||
notifications::Notification,
|
use labrinth::models::teams::{OrganizationPermissions, ProjectPermissions};
|
||||||
teams::{OrganizationPermissions, ProjectPermissions, TeamMember},
|
|
||||||
};
|
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::common::asserts::assert_status;
|
use crate::common::{
|
||||||
|
api_common::{
|
||||||
|
models::{CommonNotification, CommonTeamMember},
|
||||||
|
Api, ApiTeams,
|
||||||
|
},
|
||||||
|
asserts::assert_status,
|
||||||
|
};
|
||||||
|
|
||||||
use super::ApiV3;
|
use super::ApiV3;
|
||||||
|
|
||||||
impl ApiV3 {
|
#[async_trait(?Send)]
|
||||||
pub async fn get_team_members(&self, id_or_title: &str, pat: &str) -> ServiceResponse {
|
impl ApiTeams for ApiV3 {
|
||||||
|
async fn get_team_members(&self, id_or_title: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::get()
|
let req = test::TestRequest::get()
|
||||||
.uri(&format!("/v3/team/{id_or_title}/members"))
|
.uri(&format!("/v3/team/{id_or_title}/members"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -19,17 +24,17 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_team_members_deserialized(
|
async fn get_team_members_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
id_or_title: &str,
|
id_or_title: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Vec<TeamMember> {
|
) -> Vec<CommonTeamMember> {
|
||||||
let resp = self.get_team_members(id_or_title, pat).await;
|
let resp = self.get_team_members(id_or_title, pat).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_project_members(&self, id_or_title: &str, pat: &str) -> ServiceResponse {
|
async fn get_project_members(&self, id_or_title: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::get()
|
let req = test::TestRequest::get()
|
||||||
.uri(&format!("/v3/project/{id_or_title}/members"))
|
.uri(&format!("/v3/project/{id_or_title}/members"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -37,17 +42,17 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_project_members_deserialized(
|
async fn get_project_members_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
id_or_title: &str,
|
id_or_title: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Vec<TeamMember> {
|
) -> Vec<CommonTeamMember> {
|
||||||
let resp = self.get_project_members(id_or_title, pat).await;
|
let resp = self.get_project_members(id_or_title, pat).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_organization_members(&self, id_or_title: &str, pat: &str) -> ServiceResponse {
|
async fn get_organization_members(&self, id_or_title: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::get()
|
let req = test::TestRequest::get()
|
||||||
.uri(&format!("/v3/organization/{id_or_title}/members"))
|
.uri(&format!("/v3/organization/{id_or_title}/members"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -55,17 +60,17 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_organization_members_deserialized(
|
async fn get_organization_members_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
id_or_title: &str,
|
id_or_title: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Vec<TeamMember> {
|
) -> Vec<CommonTeamMember> {
|
||||||
let resp = self.get_organization_members(id_or_title, pat).await;
|
let resp = self.get_organization_members(id_or_title, pat).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn join_team(&self, team_id: &str, pat: &str) -> ServiceResponse {
|
async fn join_team(&self, team_id: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::post()
|
let req = test::TestRequest::post()
|
||||||
.uri(&format!("/v3/team/{team_id}/join"))
|
.uri(&format!("/v3/team/{team_id}/join"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -73,12 +78,7 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove_from_team(
|
async fn remove_from_team(&self, team_id: &str, user_id: &str, pat: &str) -> ServiceResponse {
|
||||||
&self,
|
|
||||||
team_id: &str,
|
|
||||||
user_id: &str,
|
|
||||||
pat: &str,
|
|
||||||
) -> ServiceResponse {
|
|
||||||
let req = test::TestRequest::delete()
|
let req = test::TestRequest::delete()
|
||||||
.uri(&format!("/v3/team/{team_id}/members/{user_id}"))
|
.uri(&format!("/v3/team/{team_id}/members/{user_id}"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -86,7 +86,7 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_team_member(
|
async fn edit_team_member(
|
||||||
&self,
|
&self,
|
||||||
team_id: &str,
|
team_id: &str,
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
@@ -101,7 +101,7 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn transfer_team_ownership(
|
async fn transfer_team_ownership(
|
||||||
&self,
|
&self,
|
||||||
team_id: &str,
|
team_id: &str,
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
@@ -117,7 +117,7 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_user_notifications(&self, user_id: &str, pat: &str) -> ServiceResponse {
|
async fn get_user_notifications(&self, user_id: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::get()
|
let req = test::TestRequest::get()
|
||||||
.uri(&format!("/v3/user/{user_id}/notifications"))
|
.uri(&format!("/v3/user/{user_id}/notifications"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
@@ -125,28 +125,24 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_user_notifications_deserialized(
|
async fn get_user_notifications_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Vec<Notification> {
|
) -> Vec<CommonNotification> {
|
||||||
let resp = self.get_user_notifications(user_id, pat).await;
|
let resp = self.get_user_notifications(user_id, pat).await;
|
||||||
assert_status(&resp, StatusCode::OK);
|
assert_status(&resp, StatusCode::OK);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn mark_notification_read(
|
async fn mark_notification_read(&self, notification_id: &str, pat: &str) -> ServiceResponse {
|
||||||
&self,
|
|
||||||
notification_id: &str,
|
|
||||||
pat: &str,
|
|
||||||
) -> ServiceResponse {
|
|
||||||
let req = test::TestRequest::patch()
|
let req = test::TestRequest::patch()
|
||||||
.uri(&format!("/v3/notification/{notification_id}"))
|
.uri(&format!("/v3/notification/{notification_id}"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
.to_request();
|
.to_request();
|
||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
pub async fn add_user_to_team(
|
async fn add_user_to_team(
|
||||||
&self,
|
&self,
|
||||||
team_id: &str,
|
team_id: &str,
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
@@ -166,7 +162,7 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_notification(&self, notification_id: &str, pat: &str) -> ServiceResponse {
|
async fn delete_notification(&self, notification_id: &str, pat: &str) -> ServiceResponse {
|
||||||
let req = test::TestRequest::delete()
|
let req = test::TestRequest::delete()
|
||||||
.uri(&format!("/v3/notification/{notification_id}"))
|
.uri(&format!("/v3/notification/{notification_id}"))
|
||||||
.append_header(("Authorization", pat))
|
.append_header(("Authorization", pat))
|
||||||
|
|||||||
@@ -1,59 +1,58 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use super::{request_data::get_public_version_creation_data, ApiV3};
|
||||||
|
use crate::common::{
|
||||||
|
api_common::{models::CommonVersion, Api, ApiVersion},
|
||||||
|
asserts::assert_status,
|
||||||
|
dummy_data::TestFile,
|
||||||
|
};
|
||||||
use actix_http::{header::AUTHORIZATION, StatusCode};
|
use actix_http::{header::AUTHORIZATION, StatusCode};
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
dev::ServiceResponse,
|
dev::ServiceResponse,
|
||||||
test::{self, TestRequest},
|
test::{self, TestRequest},
|
||||||
};
|
};
|
||||||
|
use async_trait::async_trait;
|
||||||
use labrinth::{
|
use labrinth::{
|
||||||
models::{projects::VersionType, v3::projects::Version},
|
models::{
|
||||||
|
projects::{ProjectId, VersionType},
|
||||||
|
v3::projects::Version,
|
||||||
|
},
|
||||||
routes::v3::version_file::FileUpdateData,
|
routes::v3::version_file::FileUpdateData,
|
||||||
util::actix::AppendsMultipart,
|
util::actix::AppendsMultipart,
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::common::asserts::assert_status;
|
|
||||||
|
|
||||||
use super::{request_data::VersionCreationRequestData, ApiV3};
|
|
||||||
|
|
||||||
pub fn url_encode_json_serialized_vec(elements: &[String]) -> String {
|
pub fn url_encode_json_serialized_vec(elements: &[String]) -> String {
|
||||||
let serialized = serde_json::to_string(&elements).unwrap();
|
let serialized = serde_json::to_string(&elements).unwrap();
|
||||||
urlencoding::encode(&serialized).to_string()
|
urlencoding::encode(&serialized).to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApiV3 {
|
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(
|
pub async fn add_public_version_deserialized(
|
||||||
&self,
|
&self,
|
||||||
creation_data: VersionCreationRequestData,
|
project_id: ProjectId,
|
||||||
|
version_number: &str,
|
||||||
|
version_jar: TestFile,
|
||||||
|
ordering: Option<i32>,
|
||||||
|
modify_json: Option<json_patch::Patch>,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Version {
|
) -> 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);
|
assert_status(&resp, StatusCode::OK);
|
||||||
let value: serde_json::Value = test::read_body_json(resp).await;
|
let value: serde_json::Value = test::read_body_json(resp).await;
|
||||||
let version_id = value["id"].as_str().unwrap();
|
let version_id = value["id"].as_str().unwrap();
|
||||||
self.get_version_deserialized(version_id, pat).await
|
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(&self, id: &str, pat: &str) -> ServiceResponse {
|
|
||||||
let req = TestRequest::get()
|
|
||||||
.uri(&format!("/v3/version/{id}"))
|
|
||||||
.append_header(("Authorization", pat))
|
|
||||||
.to_request();
|
|
||||||
self.call(req).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_version_deserialized(&self, id: &str, pat: &str) -> Version {
|
pub async fn get_version_deserialized(&self, id: &str, pat: &str) -> Version {
|
||||||
@@ -62,7 +61,101 @@ impl ApiV3 {
|
|||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_version(
|
pub async fn update_individual_files(
|
||||||
|
&self,
|
||||||
|
algorithm: &str,
|
||||||
|
hashes: Vec<FileUpdateData>,
|
||||||
|
pat: &str,
|
||||||
|
) -> ServiceResponse {
|
||||||
|
let req = test::TestRequest::post()
|
||||||
|
.uri("/v3/version_files/update_individual")
|
||||||
|
.append_header(("Authorization", pat))
|
||||||
|
.set_json(json!({
|
||||||
|
"algorithm": algorithm,
|
||||||
|
"hashes": hashes
|
||||||
|
}))
|
||||||
|
.to_request();
|
||||||
|
self.call(req).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn update_individual_files_deserialized(
|
||||||
|
&self,
|
||||||
|
algorithm: &str,
|
||||||
|
hashes: Vec<FileUpdateData>,
|
||||||
|
pat: &str,
|
||||||
|
) -> HashMap<String, Version> {
|
||||||
|
let resp = self.update_individual_files(algorithm, hashes, pat).await;
|
||||||
|
assert_eq!(resp.status(), 200);
|
||||||
|
test::read_body_json(resp).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
impl ApiVersion for ApiV3 {
|
||||||
|
async fn add_public_version(
|
||||||
|
&self,
|
||||||
|
project_id: ProjectId,
|
||||||
|
version_number: &str,
|
||||||
|
version_jar: TestFile,
|
||||||
|
ordering: Option<i32>,
|
||||||
|
modify_json: Option<json_patch::Patch>,
|
||||||
|
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<i32>,
|
||||||
|
modify_json: Option<json_patch::Patch>,
|
||||||
|
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}"))
|
||||||
|
.append_header(("Authorization", pat))
|
||||||
|
.to_request();
|
||||||
|
self.call(req).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_version_deserialized_common(&self, id: &str, pat: &str) -> CommonVersion {
|
||||||
|
let resp = self.get_version(id, pat).await;
|
||||||
|
assert_eq!(resp.status(), 200);
|
||||||
|
test::read_body_json(resp).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn edit_version(
|
||||||
&self,
|
&self,
|
||||||
version_id: &str,
|
version_id: &str,
|
||||||
patch: serde_json::Value,
|
patch: serde_json::Value,
|
||||||
@@ -77,7 +170,7 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_version_from_hash(
|
async fn get_version_from_hash(
|
||||||
&self,
|
&self,
|
||||||
hash: &str,
|
hash: &str,
|
||||||
algorithm: &str,
|
algorithm: &str,
|
||||||
@@ -90,18 +183,18 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_version_from_hash_deserialized(
|
async fn get_version_from_hash_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
hash: &str,
|
hash: &str,
|
||||||
algorithm: &str,
|
algorithm: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Version {
|
) -> CommonVersion {
|
||||||
let resp = self.get_version_from_hash(hash, algorithm, pat).await;
|
let resp = self.get_version_from_hash(hash, algorithm, pat).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_versions_from_hashes(
|
async fn get_versions_from_hashes(
|
||||||
&self,
|
&self,
|
||||||
hashes: &[&str],
|
hashes: &[&str],
|
||||||
algorithm: &str,
|
algorithm: &str,
|
||||||
@@ -118,18 +211,18 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_versions_from_hashes_deserialized(
|
async fn get_versions_from_hashes_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
hashes: &[&str],
|
hashes: &[&str],
|
||||||
algorithm: &str,
|
algorithm: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> HashMap<String, Version> {
|
) -> HashMap<String, CommonVersion> {
|
||||||
let resp = self.get_versions_from_hashes(hashes, algorithm, pat).await;
|
let resp = self.get_versions_from_hashes(hashes, algorithm, pat).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_update_from_hash(
|
async fn get_update_from_hash(
|
||||||
&self,
|
&self,
|
||||||
hash: &str,
|
hash: &str,
|
||||||
algorithm: &str,
|
algorithm: &str,
|
||||||
@@ -161,7 +254,7 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_update_from_hash_deserialized(
|
async fn get_update_from_hash_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
hash: &str,
|
hash: &str,
|
||||||
algorithm: &str,
|
algorithm: &str,
|
||||||
@@ -169,7 +262,7 @@ impl ApiV3 {
|
|||||||
game_versions: Option<Vec<String>>,
|
game_versions: Option<Vec<String>>,
|
||||||
version_types: Option<Vec<String>>,
|
version_types: Option<Vec<String>>,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Version {
|
) -> CommonVersion {
|
||||||
let resp = self
|
let resp = self
|
||||||
.get_update_from_hash(hash, algorithm, loaders, game_versions, version_types, pat)
|
.get_update_from_hash(hash, algorithm, loaders, game_versions, version_types, pat)
|
||||||
.await;
|
.await;
|
||||||
@@ -177,7 +270,7 @@ impl ApiV3 {
|
|||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_files(
|
async fn update_files(
|
||||||
&self,
|
&self,
|
||||||
algorithm: &str,
|
algorithm: &str,
|
||||||
hashes: Vec<String>,
|
hashes: Vec<String>,
|
||||||
@@ -210,7 +303,7 @@ impl ApiV3 {
|
|||||||
self.call(req).await
|
self.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_files_deserialized(
|
async fn update_files_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
algorithm: &str,
|
algorithm: &str,
|
||||||
hashes: Vec<String>,
|
hashes: Vec<String>,
|
||||||
@@ -218,7 +311,7 @@ impl ApiV3 {
|
|||||||
game_versions: Option<Vec<String>>,
|
game_versions: Option<Vec<String>>,
|
||||||
version_types: Option<Vec<String>>,
|
version_types: Option<Vec<String>>,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> HashMap<String, Version> {
|
) -> HashMap<String, CommonVersion> {
|
||||||
let resp = self
|
let resp = self
|
||||||
.update_files(
|
.update_files(
|
||||||
algorithm,
|
algorithm,
|
||||||
@@ -233,37 +326,9 @@ impl ApiV3 {
|
|||||||
test::read_body_json(resp).await
|
test::read_body_json(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_individual_files(
|
|
||||||
&self,
|
|
||||||
algorithm: &str,
|
|
||||||
hashes: Vec<FileUpdateData>,
|
|
||||||
pat: &str,
|
|
||||||
) -> ServiceResponse {
|
|
||||||
let req = test::TestRequest::post()
|
|
||||||
.uri("/v3/version_files/update_individual")
|
|
||||||
.append_header(("Authorization", pat))
|
|
||||||
.set_json(json!({
|
|
||||||
"algorithm": algorithm,
|
|
||||||
"hashes": hashes
|
|
||||||
}))
|
|
||||||
.to_request();
|
|
||||||
self.call(req).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn update_individual_files_deserialized(
|
|
||||||
&self,
|
|
||||||
algorithm: &str,
|
|
||||||
hashes: Vec<FileUpdateData>,
|
|
||||||
pat: &str,
|
|
||||||
) -> HashMap<String, Version> {
|
|
||||||
let resp = self.update_individual_files(algorithm, hashes, pat).await;
|
|
||||||
assert_eq!(resp.status(), 200);
|
|
||||||
test::read_body_json(resp).await
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Not all fields are tested currently in the v3 tests, only the v2-v3 relevant ones are
|
// TODO: Not all fields are tested currently in the v3 tests, only the v2-v3 relevant ones are
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub async fn get_project_versions(
|
async fn get_project_versions(
|
||||||
&self,
|
&self,
|
||||||
project_id_slug: &str,
|
project_id_slug: &str,
|
||||||
game_versions: Option<Vec<String>>,
|
game_versions: Option<Vec<String>>,
|
||||||
@@ -313,7 +378,7 @@ impl ApiV3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub async fn get_project_versions_deserialized(
|
async fn get_project_versions_deserialized_common(
|
||||||
&self,
|
&self,
|
||||||
slug: &str,
|
slug: &str,
|
||||||
game_versions: Option<Vec<String>>,
|
game_versions: Option<Vec<String>>,
|
||||||
@@ -323,7 +388,7 @@ impl ApiV3 {
|
|||||||
limit: Option<usize>,
|
limit: Option<usize>,
|
||||||
offset: Option<usize>,
|
offset: Option<usize>,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
) -> Vec<Version> {
|
) -> Vec<CommonVersion> {
|
||||||
let resp = self
|
let resp = self
|
||||||
.get_project_versions(
|
.get_project_versions(
|
||||||
slug,
|
slug,
|
||||||
@@ -341,68 +406,7 @@ impl ApiV3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove redundancy in these functions
|
// TODO: remove redundancy in these functions
|
||||||
|
async fn edit_version_ordering(
|
||||||
pub async fn create_default_version(
|
|
||||||
&self,
|
|
||||||
project_id: &str,
|
|
||||||
ordering: Option<i32>,
|
|
||||||
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<String>, pat: &str) -> Vec<Version> {
|
|
||||||
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;
|
|
||||||
assert_status(&resp, StatusCode::OK);
|
|
||||||
test::read_body_json(resp).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn edit_version_ordering(
|
|
||||||
&self,
|
&self,
|
||||||
version_id: &str,
|
version_id: &str,
|
||||||
ordering: Option<i32>,
|
ordering: Option<i32>,
|
||||||
@@ -419,4 +423,23 @@ impl ApiV3 {
|
|||||||
.to_request();
|
.to_request();
|
||||||
self.call(request).await
|
self.call(request).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_versions(&self, version_ids: Vec<String>, 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();
|
||||||
|
self.call(request).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_versions_deserialized_common(
|
||||||
|
&self,
|
||||||
|
version_ids: Vec<String>,
|
||||||
|
pat: &str,
|
||||||
|
) -> Vec<CommonVersion> {
|
||||||
|
let resp = self.get_versions(version_ids, pat).await;
|
||||||
|
assert_status(&resp, StatusCode::OK);
|
||||||
|
test::read_body_json(resp).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ use crate::common::get_json_val_str;
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use labrinth::models::v3::projects::Version;
|
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) {
|
pub fn assert_status(response: &actix_web::dev::ServiceResponse, status: actix_http::StatusCode) {
|
||||||
assert_eq!(response.status(), status, "{:#?}", response.response());
|
assert_eq!(response.status(), status, "{:#?}", response.response());
|
||||||
}
|
}
|
||||||
@@ -16,6 +18,14 @@ pub fn assert_version_ids(versions: &[Version], expected_ids: Vec<String>) {
|
|||||||
assert_eq!(version_ids, expected_ids);
|
assert_eq!(version_ids, expected_ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn assert_common_version_ids(versions: &[CommonVersion], expected_ids: Vec<String>) {
|
||||||
|
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(
|
pub fn assert_any_status_except(
|
||||||
response: &actix_web::dev::ServiceResponse,
|
response: &actix_web::dev::ServiceResponse,
|
||||||
status: actix_http::StatusCode,
|
status: actix_http::StatusCode,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use url::Url;
|
|||||||
|
|
||||||
use crate::common::{dummy_data, environment::TestEnvironment};
|
use crate::common::{dummy_data, environment::TestEnvironment};
|
||||||
|
|
||||||
use super::dummy_data::DUMMY_DATA_UPDATE;
|
use super::{api_v3::ApiV3, dummy_data::DUMMY_DATA_UPDATE};
|
||||||
|
|
||||||
// The dummy test database adds a fair bit of 'dummy' data to test with.
|
// The dummy test database adds a fair bit of 'dummy' data to test with.
|
||||||
// Some constants are used to refer to that data, and are described here.
|
// Some constants are used to refer to that data, and are described here.
|
||||||
@@ -168,13 +168,20 @@ impl TemporaryDatabase {
|
|||||||
|
|
||||||
if !dummy_data_exists {
|
if !dummy_data_exists {
|
||||||
// Add dummy data
|
// Add dummy data
|
||||||
let temporary_test_env = TestEnvironment::build_with_db(TemporaryDatabase {
|
let temporary_test_env =
|
||||||
|
TestEnvironment::<ApiV3>::build_with_db(TemporaryDatabase {
|
||||||
pool: pool.clone(),
|
pool: pool.clone(),
|
||||||
database_name: TEMPLATE_DATABASE_NAME.to_string(),
|
database_name: TEMPLATE_DATABASE_NAME.to_string(),
|
||||||
redis_pool: RedisPool::new(Some(generate_random_name("test_template_"))),
|
redis_pool: RedisPool::new(Some(generate_random_name(
|
||||||
|
"test_template_",
|
||||||
|
))),
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
dummy_data::add_dummy_data(&temporary_test_env).await;
|
dummy_data::add_dummy_data(
|
||||||
|
&temporary_test_env.setup_api,
|
||||||
|
temporary_test_env.db.clone(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
temporary_test_env.db.pool.close().await;
|
temporary_test_env.db.pool.close().await;
|
||||||
}
|
}
|
||||||
pool.close().await;
|
pool.close().await;
|
||||||
|
|||||||
@@ -4,19 +4,23 @@ use std::io::{Cursor, Write};
|
|||||||
use actix_http::StatusCode;
|
use actix_http::StatusCode;
|
||||||
use actix_web::test::{self, TestRequest};
|
use actix_web::test::{self, TestRequest};
|
||||||
use labrinth::models::{
|
use labrinth::models::{
|
||||||
oauth_clients::OAuthClient,
|
oauth_clients::OAuthClient, organizations::Organization, pats::Scopes, projects::ProjectId,
|
||||||
organizations::Organization,
|
|
||||||
pats::Scopes,
|
|
||||||
v3::projects::{Project, Version},
|
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use sqlx::Executor;
|
use sqlx::Executor;
|
||||||
use zip::{write::FileOptions, CompressionMethod, ZipWriter};
|
use zip::{write::FileOptions, CompressionMethod, ZipWriter};
|
||||||
|
|
||||||
use crate::common::database::USER_USER_PAT;
|
use crate::common::{api_common::Api, database::USER_USER_PAT};
|
||||||
use labrinth::util::actix::{AppendsMultipart, MultipartSegment, MultipartSegmentData};
|
use labrinth::util::actix::{AppendsMultipart, MultipartSegment, MultipartSegmentData};
|
||||||
|
|
||||||
use super::{api_v3::request_data::get_public_project_creation_data, environment::TestEnvironment};
|
use super::{
|
||||||
|
api_common::{
|
||||||
|
models::{CommonProject, CommonVersion},
|
||||||
|
ApiProject,
|
||||||
|
},
|
||||||
|
api_v3::ApiV3,
|
||||||
|
database::TemporaryDatabase,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{asserts::assert_status, database::USER_USER_ID, get_json_val_str};
|
use super::{asserts::assert_status, database::USER_USER_ID, get_json_val_str};
|
||||||
|
|
||||||
@@ -170,10 +174,10 @@ pub struct DummyData {
|
|||||||
|
|
||||||
impl DummyData {
|
impl DummyData {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
project_alpha: Project,
|
project_alpha: CommonProject,
|
||||||
project_alpha_version: Version,
|
project_alpha_version: CommonVersion,
|
||||||
project_beta: Project,
|
project_beta: CommonProject,
|
||||||
project_beta_version: Version,
|
project_beta_version: CommonVersion,
|
||||||
organization_zeta: Organization,
|
organization_zeta: Organization,
|
||||||
oauth_client_alpha: OAuthClient,
|
oauth_client_alpha: OAuthClient,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -182,6 +186,7 @@ impl DummyData {
|
|||||||
team_id: project_alpha.team.to_string(),
|
team_id: project_alpha.team.to_string(),
|
||||||
project_id: project_alpha.id.to_string(),
|
project_id: project_alpha.id.to_string(),
|
||||||
project_slug: project_alpha.slug.unwrap(),
|
project_slug: project_alpha.slug.unwrap(),
|
||||||
|
project_id_parsed: project_alpha.id,
|
||||||
version_id: project_alpha_version.id.to_string(),
|
version_id: project_alpha_version.id.to_string(),
|
||||||
thread_id: project_alpha.thread_id.to_string(),
|
thread_id: project_alpha.thread_id.to_string(),
|
||||||
file_hash: project_alpha_version.files[0].hashes["sha1"].clone(),
|
file_hash: project_alpha_version.files[0].hashes["sha1"].clone(),
|
||||||
@@ -191,6 +196,7 @@ impl DummyData {
|
|||||||
team_id: project_beta.team.to_string(),
|
team_id: project_beta.team.to_string(),
|
||||||
project_id: project_beta.id.to_string(),
|
project_id: project_beta.id.to_string(),
|
||||||
project_slug: project_beta.slug.unwrap(),
|
project_slug: project_beta.slug.unwrap(),
|
||||||
|
project_id_parsed: project_beta.id,
|
||||||
version_id: project_beta_version.id.to_string(),
|
version_id: project_beta_version.id.to_string(),
|
||||||
thread_id: project_beta.thread_id.to_string(),
|
thread_id: project_beta.thread_id.to_string(),
|
||||||
file_hash: project_beta_version.files[0].hashes["sha1"].clone(),
|
file_hash: project_beta_version.files[0].hashes["sha1"].clone(),
|
||||||
@@ -220,6 +226,7 @@ impl DummyData {
|
|||||||
pub struct DummyProjectAlpha {
|
pub struct DummyProjectAlpha {
|
||||||
pub project_id: String,
|
pub project_id: String,
|
||||||
pub project_slug: String,
|
pub project_slug: String,
|
||||||
|
pub project_id_parsed: ProjectId,
|
||||||
pub version_id: String,
|
pub version_id: String,
|
||||||
pub thread_id: String,
|
pub thread_id: String,
|
||||||
pub file_hash: String,
|
pub file_hash: String,
|
||||||
@@ -230,6 +237,7 @@ pub struct DummyProjectAlpha {
|
|||||||
pub struct DummyProjectBeta {
|
pub struct DummyProjectBeta {
|
||||||
pub project_id: String,
|
pub project_id: String,
|
||||||
pub project_slug: String,
|
pub project_slug: String,
|
||||||
|
pub project_id_parsed: ProjectId,
|
||||||
pub version_id: String,
|
pub version_id: String,
|
||||||
pub thread_id: String,
|
pub thread_id: String,
|
||||||
pub file_hash: String,
|
pub file_hash: String,
|
||||||
@@ -250,9 +258,9 @@ pub struct DummyOAuthClientAlpha {
|
|||||||
pub valid_redirect_uri: String,
|
pub valid_redirect_uri: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_dummy_data(test_env: &TestEnvironment) -> DummyData {
|
pub async fn add_dummy_data(api: &ApiV3, db: TemporaryDatabase) -> DummyData {
|
||||||
// Adds basic dummy data to the database directly with sql (user, pats)
|
// Adds basic dummy data to the database directly with sql (user, pats)
|
||||||
let pool = &test_env.db.pool.clone();
|
let pool = &db.pool.clone();
|
||||||
|
|
||||||
pool.execute(
|
pool.execute(
|
||||||
include_str!("../files/dummy_data.sql")
|
include_str!("../files/dummy_data.sql")
|
||||||
@@ -262,12 +270,12 @@ pub async fn add_dummy_data(test_env: &TestEnvironment) -> DummyData {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let (alpha_project, alpha_version) = add_project_alpha(test_env).await;
|
let (alpha_project, alpha_version) = add_project_alpha(api).await;
|
||||||
let (beta_project, beta_version) = add_project_beta(test_env).await;
|
let (beta_project, beta_version) = add_project_beta(api).await;
|
||||||
|
|
||||||
let zeta_organization = add_organization_zeta(test_env).await;
|
let zeta_organization = add_organization_zeta(api).await;
|
||||||
|
|
||||||
let oauth_client_alpha = get_oauth_client_alpha(test_env).await;
|
let oauth_client_alpha = get_oauth_client_alpha(api).await;
|
||||||
|
|
||||||
sqlx::query("INSERT INTO dummy_data (update_id) VALUES ($1)")
|
sqlx::query("INSERT INTO dummy_data (update_id) VALUES ($1)")
|
||||||
.bind(DUMMY_DATA_UPDATE)
|
.bind(DUMMY_DATA_UPDATE)
|
||||||
@@ -285,13 +293,13 @@ pub async fn add_dummy_data(test_env: &TestEnvironment) -> DummyData {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_dummy_data(test_env: &TestEnvironment) -> DummyData {
|
pub async fn get_dummy_data(api: &ApiV3) -> DummyData {
|
||||||
let (alpha_project, alpha_version) = get_project_alpha(test_env).await;
|
let (alpha_project, alpha_version) = get_project_alpha(api).await;
|
||||||
let (beta_project, beta_version) = get_project_beta(test_env).await;
|
let (beta_project, beta_version) = get_project_beta(api).await;
|
||||||
|
|
||||||
let zeta_organization = get_organization_zeta(test_env).await;
|
let zeta_organization = get_organization_zeta(api).await;
|
||||||
|
|
||||||
let oauth_client_alpha = get_oauth_client_alpha(test_env).await;
|
let oauth_client_alpha = get_oauth_client_alpha(api).await;
|
||||||
|
|
||||||
DummyData::new(
|
DummyData::new(
|
||||||
alpha_project,
|
alpha_project,
|
||||||
@@ -303,18 +311,19 @@ pub async fn get_dummy_data(test_env: &TestEnvironment) -> DummyData {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_project_alpha(test_env: &TestEnvironment) -> (Project, Version) {
|
pub async fn add_project_alpha(api: &ApiV3) -> (CommonProject, CommonVersion) {
|
||||||
let (project, versions) = test_env
|
let (project, versions) = api
|
||||||
.v3
|
|
||||||
.add_public_project(
|
.add_public_project(
|
||||||
get_public_project_creation_data("alpha", Some(TestFile::DummyProjectAlpha)),
|
"alpha",
|
||||||
|
Some(TestFile::DummyProjectAlpha),
|
||||||
|
None,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
(project, versions.into_iter().next().unwrap())
|
(project, versions.into_iter().next().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_project_beta(test_env: &TestEnvironment) -> (Project, Version) {
|
pub async fn add_project_beta(api: &ApiV3) -> (CommonProject, CommonVersion) {
|
||||||
// Adds dummy data to the database with sqlx (projects, versions, threads)
|
// Adds dummy data to the database with sqlx (projects, versions, threads)
|
||||||
// Generate test project data.
|
// Generate test project data.
|
||||||
let jar = TestFile::DummyProjectBeta;
|
let jar = TestFile::DummyProjectBeta;
|
||||||
@@ -367,13 +376,13 @@ pub async fn add_project_beta(test_env: &TestEnvironment) -> (Project, Version)
|
|||||||
.append_header(("Authorization", USER_USER_PAT))
|
.append_header(("Authorization", USER_USER_PAT))
|
||||||
.set_multipart(vec![json_segment.clone(), file_segment.clone()])
|
.set_multipart(vec![json_segment.clone(), file_segment.clone()])
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = test_env.call(req).await;
|
let resp = api.call(req).await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
|
|
||||||
get_project_beta(test_env).await
|
get_project_beta(api).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_organization_zeta(test_env: &TestEnvironment) -> Organization {
|
pub async fn add_organization_zeta(api: &ApiV3) -> Organization {
|
||||||
// Add an organzation.
|
// Add an organzation.
|
||||||
let req = TestRequest::post()
|
let req = TestRequest::post()
|
||||||
.uri("/v3/organization")
|
.uri("/v3/organization")
|
||||||
@@ -383,73 +392,72 @@ pub async fn add_organization_zeta(test_env: &TestEnvironment) -> Organization {
|
|||||||
"description": "A dummy organization for testing with."
|
"description": "A dummy organization for testing with."
|
||||||
}))
|
}))
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = test_env.call(req).await;
|
let resp = api.call(req).await;
|
||||||
|
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
|
|
||||||
get_organization_zeta(test_env).await
|
get_organization_zeta(api).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_project_alpha(test_env: &TestEnvironment) -> (Project, Version) {
|
pub async fn get_project_alpha(api: &ApiV3) -> (CommonProject, CommonVersion) {
|
||||||
// Get project
|
// Get project
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
.uri("/v3/project/alpha")
|
.uri("/v3/project/alpha")
|
||||||
.append_header(("Authorization", USER_USER_PAT))
|
.append_header(("Authorization", USER_USER_PAT))
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = test_env.call(req).await;
|
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
|
// Get project's versions
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
.uri("/v3/project/alpha/version")
|
.uri("/v3/project/alpha/version")
|
||||||
.append_header(("Authorization", USER_USER_PAT))
|
.append_header(("Authorization", USER_USER_PAT))
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = test_env.call(req).await;
|
let resp = api.call(req).await;
|
||||||
let versions: Vec<Version> = test::read_body_json(resp).await;
|
let versions: Vec<CommonVersion> = test::read_body_json(resp).await;
|
||||||
let version = versions.into_iter().next().unwrap();
|
let version = versions.into_iter().next().unwrap();
|
||||||
|
|
||||||
(project, version)
|
(project, version)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_project_beta(test_env: &TestEnvironment) -> (Project, Version) {
|
pub async fn get_project_beta(api: &ApiV3) -> (CommonProject, CommonVersion) {
|
||||||
// Get project
|
// Get project
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
.uri("/v3/project/beta")
|
.uri("/v3/project/beta")
|
||||||
.append_header(("Authorization", USER_USER_PAT))
|
.append_header(("Authorization", USER_USER_PAT))
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = test_env.call(req).await;
|
let resp = api.call(req).await;
|
||||||
assert_status(&resp, StatusCode::OK);
|
assert_status(&resp, StatusCode::OK);
|
||||||
let project: serde_json::Value = test::read_body_json(resp).await;
|
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
|
// Get project's versions
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
.uri("/v3/project/beta/version")
|
.uri("/v3/project/beta/version")
|
||||||
.append_header(("Authorization", USER_USER_PAT))
|
.append_header(("Authorization", USER_USER_PAT))
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = test_env.call(req).await;
|
let resp = api.call(req).await;
|
||||||
assert_status(&resp, StatusCode::OK);
|
assert_status(&resp, StatusCode::OK);
|
||||||
let versions: Vec<Version> = test::read_body_json(resp).await;
|
let versions: Vec<CommonVersion> = test::read_body_json(resp).await;
|
||||||
let version = versions.into_iter().next().unwrap();
|
let version = versions.into_iter().next().unwrap();
|
||||||
|
|
||||||
(project, version)
|
(project, version)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_organization_zeta(test_env: &TestEnvironment) -> Organization {
|
pub async fn get_organization_zeta(api: &ApiV3) -> Organization {
|
||||||
// Get organization
|
// Get organization
|
||||||
let req = TestRequest::get()
|
let req = TestRequest::get()
|
||||||
.uri("/v3/organization/zeta")
|
.uri("/v3/organization/zeta")
|
||||||
.append_header(("Authorization", USER_USER_PAT))
|
.append_header(("Authorization", USER_USER_PAT))
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = test_env.call(req).await;
|
let resp = api.call(req).await;
|
||||||
let organization: Organization = test::read_body_json(resp).await;
|
let organization: Organization = test::read_body_json(resp).await;
|
||||||
|
|
||||||
organization
|
organization
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_oauth_client_alpha(test_env: &TestEnvironment) -> OAuthClient {
|
pub async fn get_oauth_client_alpha(api: &ApiV3) -> OAuthClient {
|
||||||
let oauth_clients = test_env
|
let oauth_clients = api
|
||||||
.v3
|
|
||||||
.get_user_oauth_clients(USER_USER_ID, USER_USER_PAT)
|
.get_user_oauth_clients(USER_USER_ID, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
oauth_clients.into_iter().next().unwrap()
|
oauth_clients.into_iter().next().unwrap()
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::{rc::Rc, sync::Arc};
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
api_common::{generic::GenericApi, Api, ApiBuildable},
|
||||||
api_v2::ApiV2,
|
api_v2::ApiV2,
|
||||||
api_v3::ApiV3,
|
api_v3::ApiV3,
|
||||||
asserts::assert_status,
|
asserts::assert_status,
|
||||||
@@ -11,76 +10,103 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::common::setup;
|
use crate::common::setup;
|
||||||
use actix_http::StatusCode;
|
use actix_http::StatusCode;
|
||||||
use actix_web::{dev::ServiceResponse, test, App};
|
use actix_web::dev::ServiceResponse;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
|
|
||||||
pub async fn with_test_environment<Fut>(f: impl FnOnce(TestEnvironment) -> Fut)
|
pub async fn with_test_environment<Fut, A>(
|
||||||
where
|
max_connections: Option<u32>,
|
||||||
|
f: impl FnOnce(TestEnvironment<A>) -> Fut,
|
||||||
|
) where
|
||||||
Fut: Future<Output = ()>,
|
Fut: Future<Output = ()>,
|
||||||
|
A: ApiBuildable + 'static,
|
||||||
{
|
{
|
||||||
let test_env = TestEnvironment::build(None).await;
|
let test_env: TestEnvironment<A> = TestEnvironment::build(max_connections).await;
|
||||||
let db = test_env.db.clone();
|
let db = test_env.db.clone();
|
||||||
|
|
||||||
f(test_env).await;
|
f(test_env).await;
|
||||||
|
|
||||||
db.cleanup().await;
|
db.cleanup().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This needs to be slightly redesigned in order to do both V2 and v3 tests.
|
// TODO: This needs to be slightly redesigned in order to do both V2 and v3 tests.
|
||||||
// TODO: Most tests, since they use API functions, can be applied to both. The ones that weren't are in v2/, but
|
// TODO: Most tests, since they use API functions, can be applied to both. The ones that weren't are in v2/, but
|
||||||
// all tests that can be applied to both should use both v2 and v3 (extract api to a trait with all the API functions and call both).
|
// all tests that can be applied to both should use both v2 and v3 (extract api to a trait with all the API functions and call both).
|
||||||
|
pub async fn with_test_environment_all<Fut, F>(max_connections: Option<u32>, f: F)
|
||||||
|
where
|
||||||
|
Fut: Future<Output = ()>,
|
||||||
|
F: Fn(TestEnvironment<GenericApi>) -> Fut,
|
||||||
|
{
|
||||||
|
println!("Test environment: API v3");
|
||||||
|
let test_env_api_v3 = TestEnvironment::<ApiV3>::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: 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::<ApiV2>::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: test_env_api_v2.dummy,
|
||||||
|
};
|
||||||
|
let db = test_env_api_v2.db.clone();
|
||||||
|
f(test_env_api_v2).await;
|
||||||
|
db.cleanup().await;
|
||||||
|
}
|
||||||
|
|
||||||
// A complete test environment, with a test actix app and a database.
|
// A complete test environment, with a test actix app and a database.
|
||||||
// Must be called in an #[actix_rt::test] context. It also simulates a
|
// Must be called in an #[actix_rt::test] context. It also simulates a
|
||||||
// temporary sqlx db like #[sqlx::test] would.
|
// temporary sqlx db like #[sqlx::test] would.
|
||||||
// Use .call(req) on it directly to make a test call as if test::call_service(req) were being used.
|
// Use .call(req) on it directly to make a test call as if test::call_service(req) were being used.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct TestEnvironment {
|
pub struct TestEnvironment<A> {
|
||||||
test_app: Rc<dyn LocalService>, // Rc as it's not Send
|
// test_app: Rc<dyn LocalService>, // Rc as it's not Send
|
||||||
pub db: TemporaryDatabase,
|
pub db: TemporaryDatabase,
|
||||||
pub v2: ApiV2,
|
pub api: A,
|
||||||
pub v3: ApiV3,
|
pub setup_api: ApiV3, // Used for setting up tests only (ie: in ScopesTest)
|
||||||
|
pub dummy: Option<dummy_data::DummyData>,
|
||||||
pub dummy: Option<Arc<dummy_data::DummyData>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestEnvironment {
|
impl<A: ApiBuildable> TestEnvironment<A> {
|
||||||
pub async fn build(max_connections: Option<u32>) -> Self {
|
async fn build(max_connections: Option<u32>) -> Self {
|
||||||
let db = TemporaryDatabase::create(max_connections).await;
|
let db = TemporaryDatabase::create(max_connections).await;
|
||||||
let mut test_env = Self::build_with_db(db).await;
|
let mut test_env = Self::build_with_db(db).await;
|
||||||
|
|
||||||
let dummy = dummy_data::get_dummy_data(&test_env).await;
|
let dummy = dummy_data::get_dummy_data(&test_env.setup_api).await;
|
||||||
test_env.dummy = Some(Arc::new(dummy));
|
test_env.dummy = Some(dummy);
|
||||||
test_env
|
test_env
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn build_with_db(db: TemporaryDatabase) -> Self {
|
pub async fn build_with_db(db: TemporaryDatabase) -> Self {
|
||||||
let labrinth_config = setup(&db).await;
|
let labrinth_config = setup(&db).await;
|
||||||
let app = App::new().configure(|cfg| labrinth::app_config(cfg, labrinth_config.clone()));
|
|
||||||
let test_app: Rc<dyn LocalService> = Rc::new(test::init_service(app).await);
|
|
||||||
Self {
|
Self {
|
||||||
v2: ApiV2 {
|
|
||||||
test_app: test_app.clone(),
|
|
||||||
},
|
|
||||||
v3: ApiV3 {
|
|
||||||
test_app: test_app.clone(),
|
|
||||||
},
|
|
||||||
test_app,
|
|
||||||
db,
|
db,
|
||||||
|
api: A::build(labrinth_config.clone()).await,
|
||||||
|
setup_api: ApiV3::build(labrinth_config.clone()).await,
|
||||||
dummy: None,
|
dummy: None,
|
||||||
|
// test_app
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A: Api> TestEnvironment<A> {
|
||||||
pub async fn cleanup(self) {
|
pub async fn cleanup(self) {
|
||||||
self.db.cleanup().await;
|
self.db.cleanup().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn call(&self, req: actix_http::Request) -> ServiceResponse {
|
pub async fn call(&self, req: actix_http::Request) -> ServiceResponse {
|
||||||
self.test_app.call(req).await.unwrap()
|
self.api.call(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup data, create a friend user notification
|
||||||
pub async fn generate_friend_user_notification(&self) {
|
pub async fn generate_friend_user_notification(&self) {
|
||||||
let resp = self
|
let resp = self
|
||||||
.v3
|
.api
|
||||||
.add_user_to_team(
|
.add_user_to_team(
|
||||||
&self.dummy.as_ref().unwrap().project_alpha.team_id,
|
&self.dummy.as_ref().unwrap().project_alpha.team_id,
|
||||||
FRIEND_USER_ID,
|
FRIEND_USER_ID,
|
||||||
@@ -92,23 +118,25 @@ impl TestEnvironment {
|
|||||||
assert_status(&resp, StatusCode::NO_CONTENT);
|
assert_status(&resp, StatusCode::NO_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup data, assert that a user can read notifications
|
||||||
pub async fn assert_read_notifications_status(
|
pub async fn assert_read_notifications_status(
|
||||||
&self,
|
&self,
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
status_code: StatusCode,
|
status_code: StatusCode,
|
||||||
) {
|
) {
|
||||||
let resp = self.v3.get_user_notifications(user_id, pat).await;
|
let resp = self.api.get_user_notifications(user_id, pat).await;
|
||||||
assert_status(&resp, status_code);
|
assert_status(&resp, status_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup data, assert that a user can read projects notifications
|
||||||
pub async fn assert_read_user_projects_status(
|
pub async fn assert_read_user_projects_status(
|
||||||
&self,
|
&self,
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
pat: &str,
|
pat: &str,
|
||||||
status_code: StatusCode,
|
status_code: StatusCode,
|
||||||
) {
|
) {
|
||||||
let resp = self.v3.get_user_projects(user_id, pat).await;
|
let resp = self.api.get_user_projects(user_id, pat).await;
|
||||||
assert_status(&resp, status_code);
|
assert_status(&resp, status_code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use labrinth::{check_env_vars, clickhouse};
|
|||||||
use labrinth::{file_hosting, queue, LabrinthConfig};
|
use labrinth::{file_hosting, queue, LabrinthConfig};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub mod api_common;
|
||||||
pub mod api_v2;
|
pub mod api_v2;
|
||||||
pub mod api_v3;
|
pub mod api_v3;
|
||||||
pub mod asserts;
|
pub mod asserts;
|
||||||
|
|||||||
@@ -5,10 +5,14 @@ use itertools::Itertools;
|
|||||||
use labrinth::models::teams::{OrganizationPermissions, ProjectPermissions};
|
use labrinth::models::teams::{OrganizationPermissions, ProjectPermissions};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::common::database::{generate_random_name, ADMIN_USER_PAT};
|
use crate::common::{
|
||||||
|
api_common::ApiTeams,
|
||||||
|
database::{generate_random_name, ADMIN_USER_PAT},
|
||||||
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
api_v3::request_data,
|
api_common::{Api, ApiProject},
|
||||||
|
api_v3::ApiV3,
|
||||||
database::{ENEMY_USER_PAT, USER_USER_ID, USER_USER_PAT},
|
database::{ENEMY_USER_PAT, USER_USER_ID, USER_USER_PAT},
|
||||||
environment::TestEnvironment,
|
environment::TestEnvironment,
|
||||||
};
|
};
|
||||||
@@ -18,8 +22,9 @@ use super::{
|
|||||||
// - returns a 200-299 if the scope is present
|
// - returns a 200-299 if the scope is present
|
||||||
// - returns failure and success JSON bodies for requests that are 200 (for performing non-simple follow-up tests on)
|
// - returns failure and success JSON bodies for requests that are 200 (for performing non-simple follow-up tests on)
|
||||||
// This uses a builder format, so you can chain methods to set the parameters to non-defaults (most will probably be not need to be set).
|
// This uses a builder format, so you can chain methods to set the parameters to non-defaults (most will probably be not need to be set).
|
||||||
pub struct PermissionsTest<'a> {
|
type JsonCheck = Box<dyn Fn(&serde_json::Value) + Send>;
|
||||||
test_env: &'a TestEnvironment,
|
pub struct PermissionsTest<'a, A: Api> {
|
||||||
|
test_env: &'a TestEnvironment<A>,
|
||||||
// Permissions expected to fail on this test. By default, this is all permissions except the success permissions.
|
// Permissions expected to fail on this test. By default, this is all permissions except the success permissions.
|
||||||
// (To ensure we have isolated the permissions we are testing)
|
// (To ensure we have isolated the permissions we are testing)
|
||||||
failure_project_permissions: Option<ProjectPermissions>,
|
failure_project_permissions: Option<ProjectPermissions>,
|
||||||
@@ -50,12 +55,12 @@ pub struct PermissionsTest<'a> {
|
|||||||
// Closures that check the JSON body of the response for failure and success cases.
|
// Closures that check the JSON body of the response for failure and success cases.
|
||||||
// These are used to perform more complex tests than just checking the status code.
|
// These are used to perform more complex tests than just checking the status code.
|
||||||
// (eg: checking that the response contains the correct data)
|
// (eg: checking that the response contains the correct data)
|
||||||
failure_json_check: Option<Box<dyn Fn(&serde_json::Value) + Send>>,
|
failure_json_check: Option<JsonCheck>,
|
||||||
success_json_check: Option<Box<dyn Fn(&serde_json::Value) + Send>>,
|
success_json_check: Option<JsonCheck>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PermissionsTestContext<'a> {
|
pub struct PermissionsTestContext<'a> {
|
||||||
pub test_env: &'a TestEnvironment,
|
// pub test_env: &'a TestEnvironment<A>,
|
||||||
pub user_id: &'a str,
|
pub user_id: &'a str,
|
||||||
pub user_pat: &'a str,
|
pub user_pat: &'a str,
|
||||||
pub project_id: Option<&'a str>,
|
pub project_id: Option<&'a str>,
|
||||||
@@ -64,8 +69,8 @@ pub struct PermissionsTestContext<'a> {
|
|||||||
pub organization_team_id: Option<&'a str>,
|
pub organization_team_id: Option<&'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PermissionsTest<'a> {
|
impl<'a, A: Api> PermissionsTest<'a, A> {
|
||||||
pub fn new(test_env: &'a TestEnvironment) -> Self {
|
pub fn new(test_env: &'a TestEnvironment<A>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
test_env,
|
test_env,
|
||||||
failure_project_permissions: None,
|
failure_project_permissions: None,
|
||||||
@@ -157,7 +162,6 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
.failure_project_permissions
|
.failure_project_permissions
|
||||||
.unwrap_or(ProjectPermissions::all() ^ success_permissions);
|
.unwrap_or(ProjectPermissions::all() ^ success_permissions);
|
||||||
let test_context = PermissionsTestContext {
|
let test_context = PermissionsTestContext {
|
||||||
test_env,
|
|
||||||
user_id: self.user_id,
|
user_id: self.user_id,
|
||||||
user_pat: self.user_pat,
|
user_pat: self.user_pat,
|
||||||
project_id: None,
|
project_id: None,
|
||||||
@@ -172,7 +176,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
self.project_team_id.clone().unwrap(),
|
self.project_team_id.clone().unwrap(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
create_dummy_project(test_env).await
|
create_dummy_project(&test_env.setup_api).await
|
||||||
};
|
};
|
||||||
|
|
||||||
add_user_to_team(
|
add_user_to_team(
|
||||||
@@ -181,7 +185,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
&team_id,
|
&team_id,
|
||||||
Some(failure_project_permissions),
|
Some(failure_project_permissions),
|
||||||
None,
|
None,
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -268,7 +272,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
&team_id,
|
&team_id,
|
||||||
Some(success_permissions),
|
Some(success_permissions),
|
||||||
None,
|
None,
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -297,7 +301,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
// If the remove_user flag is set, remove the user from the project
|
// If the remove_user flag is set, remove the user from the project
|
||||||
// Relevant for existing projects/users
|
// Relevant for existing projects/users
|
||||||
if self.remove_user {
|
if self.remove_user {
|
||||||
remove_user_from_team(self.user_id, &team_id, test_env).await;
|
remove_user_from_team(self.user_id, &team_id, &test_env.setup_api).await;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -315,7 +319,6 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
.failure_organization_permissions
|
.failure_organization_permissions
|
||||||
.unwrap_or(OrganizationPermissions::all() ^ success_permissions);
|
.unwrap_or(OrganizationPermissions::all() ^ success_permissions);
|
||||||
let test_context = PermissionsTestContext {
|
let test_context = PermissionsTestContext {
|
||||||
test_env,
|
|
||||||
user_id: self.user_id,
|
user_id: self.user_id,
|
||||||
user_pat: self.user_pat,
|
user_pat: self.user_pat,
|
||||||
project_id: None,
|
project_id: None,
|
||||||
@@ -331,7 +334,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
self.organization_team_id.clone().unwrap(),
|
self.organization_team_id.clone().unwrap(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
create_dummy_org(test_env).await
|
create_dummy_org(&test_env.setup_api).await
|
||||||
};
|
};
|
||||||
|
|
||||||
add_user_to_team(
|
add_user_to_team(
|
||||||
@@ -340,7 +343,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
&team_id,
|
&team_id,
|
||||||
None,
|
None,
|
||||||
Some(failure_organization_permissions),
|
Some(failure_organization_permissions),
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -371,7 +374,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
&team_id,
|
&team_id,
|
||||||
None,
|
None,
|
||||||
Some(success_permissions),
|
Some(success_permissions),
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -395,7 +398,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
// If the remove_user flag is set, remove the user from the organization
|
// If the remove_user flag is set, remove the user from the organization
|
||||||
// Relevant for existing projects/users
|
// Relevant for existing projects/users
|
||||||
if self.remove_user {
|
if self.remove_user {
|
||||||
remove_user_from_team(self.user_id, &team_id, test_env).await;
|
remove_user_from_team(self.user_id, &team_id, &test_env.setup_api).await;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -413,7 +416,6 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
.failure_project_permissions
|
.failure_project_permissions
|
||||||
.unwrap_or(ProjectPermissions::all() ^ success_permissions);
|
.unwrap_or(ProjectPermissions::all() ^ success_permissions);
|
||||||
let test_context = PermissionsTestContext {
|
let test_context = PermissionsTestContext {
|
||||||
test_env,
|
|
||||||
user_id: self.user_id,
|
user_id: self.user_id,
|
||||||
user_pat: self.user_pat,
|
user_pat: self.user_pat,
|
||||||
project_id: None,
|
project_id: None,
|
||||||
@@ -426,7 +428,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
// This should always fail, regardless of permissions
|
// This should always fail, regardless of permissions
|
||||||
// (As we are testing permissions-based failures)
|
// (As we are testing permissions-based failures)
|
||||||
let test_1 = async {
|
let test_1 = async {
|
||||||
let (project_id, team_id) = create_dummy_project(test_env).await;
|
let (project_id, team_id) = create_dummy_project(&test_env.setup_api).await;
|
||||||
|
|
||||||
let request = req_gen(&PermissionsTestContext {
|
let request = req_gen(&PermissionsTestContext {
|
||||||
project_id: Some(&project_id),
|
project_id: Some(&project_id),
|
||||||
@@ -447,8 +449,13 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let p =
|
let p = get_project_permissions(
|
||||||
get_project_permissions(self.user_id, self.user_pat, &project_id, test_env).await;
|
self.user_id,
|
||||||
|
self.user_pat,
|
||||||
|
&project_id,
|
||||||
|
&test_env.setup_api,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
if p != ProjectPermissions::empty() {
|
if p != ProjectPermissions::empty() {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Test 1 failed. Expected no permissions, got {:?}",
|
"Test 1 failed. Expected no permissions, got {:?}",
|
||||||
@@ -462,7 +469,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
// TEST 2: Failure
|
// TEST 2: Failure
|
||||||
// Random user, unaffiliated with the project, with no permissions
|
// Random user, unaffiliated with the project, with no permissions
|
||||||
let test_2 = async {
|
let test_2 = async {
|
||||||
let (project_id, team_id) = create_dummy_project(test_env).await;
|
let (project_id, team_id) = create_dummy_project(&test_env.setup_api).await;
|
||||||
|
|
||||||
let request = req_gen(&PermissionsTestContext {
|
let request = req_gen(&PermissionsTestContext {
|
||||||
project_id: Some(&project_id),
|
project_id: Some(&project_id),
|
||||||
@@ -483,8 +490,13 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let p =
|
let p = get_project_permissions(
|
||||||
get_project_permissions(self.user_id, self.user_pat, &project_id, test_env).await;
|
self.user_id,
|
||||||
|
self.user_pat,
|
||||||
|
&project_id,
|
||||||
|
&test_env.setup_api,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
if p != ProjectPermissions::empty() {
|
if p != ProjectPermissions::empty() {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Test 2 failed. Expected no permissions, got {:?}",
|
"Test 2 failed. Expected no permissions, got {:?}",
|
||||||
@@ -498,14 +510,14 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
// TEST 3: Failure
|
// TEST 3: Failure
|
||||||
// User affiliated with the project, with failure permissions
|
// User affiliated with the project, with failure permissions
|
||||||
let test_3 = async {
|
let test_3 = async {
|
||||||
let (project_id, team_id) = create_dummy_project(test_env).await;
|
let (project_id, team_id) = create_dummy_project(&test_env.setup_api).await;
|
||||||
add_user_to_team(
|
add_user_to_team(
|
||||||
self.user_id,
|
self.user_id,
|
||||||
self.user_pat,
|
self.user_pat,
|
||||||
&team_id,
|
&team_id,
|
||||||
Some(failure_project_permissions),
|
Some(failure_project_permissions),
|
||||||
None,
|
None,
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -529,8 +541,13 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let p =
|
let p = get_project_permissions(
|
||||||
get_project_permissions(self.user_id, self.user_pat, &project_id, test_env).await;
|
self.user_id,
|
||||||
|
self.user_pat,
|
||||||
|
&project_id,
|
||||||
|
&test_env.setup_api,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
if p != failure_project_permissions {
|
if p != failure_project_permissions {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Test 3 failed. Expected {:?}, got {:?}",
|
"Test 3 failed. Expected {:?}, got {:?}",
|
||||||
@@ -544,14 +561,14 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
// TEST 4: Success
|
// TEST 4: Success
|
||||||
// User affiliated with the project, with the given permissions
|
// User affiliated with the project, with the given permissions
|
||||||
let test_4 = async {
|
let test_4 = async {
|
||||||
let (project_id, team_id) = create_dummy_project(test_env).await;
|
let (project_id, team_id) = create_dummy_project(&test_env.setup_api).await;
|
||||||
add_user_to_team(
|
add_user_to_team(
|
||||||
self.user_id,
|
self.user_id,
|
||||||
self.user_pat,
|
self.user_pat,
|
||||||
&team_id,
|
&team_id,
|
||||||
Some(success_permissions),
|
Some(success_permissions),
|
||||||
None,
|
None,
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -571,8 +588,13 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let p =
|
let p = get_project_permissions(
|
||||||
get_project_permissions(self.user_id, self.user_pat, &project_id, test_env).await;
|
self.user_id,
|
||||||
|
self.user_pat,
|
||||||
|
&project_id,
|
||||||
|
&test_env.setup_api,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
if p != success_permissions {
|
if p != success_permissions {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Test 4 failed. Expected {:?}, got {:?}",
|
"Test 4 failed. Expected {:?}, got {:?}",
|
||||||
@@ -587,16 +609,17 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
// Project has an organization
|
// Project has an organization
|
||||||
// User affiliated with the project's org, with default failure permissions
|
// User affiliated with the project's org, with default failure permissions
|
||||||
let test_5 = async {
|
let test_5 = async {
|
||||||
let (project_id, team_id) = create_dummy_project(test_env).await;
|
let (project_id, team_id) = create_dummy_project(&test_env.setup_api).await;
|
||||||
let (organization_id, organization_team_id) = create_dummy_org(test_env).await;
|
let (organization_id, organization_team_id) =
|
||||||
add_project_to_org(test_env, &project_id, &organization_id).await;
|
create_dummy_org(&test_env.setup_api).await;
|
||||||
|
add_project_to_org(&test_env.setup_api, &project_id, &organization_id).await;
|
||||||
add_user_to_team(
|
add_user_to_team(
|
||||||
self.user_id,
|
self.user_id,
|
||||||
self.user_pat,
|
self.user_pat,
|
||||||
&organization_team_id,
|
&organization_team_id,
|
||||||
Some(failure_project_permissions),
|
Some(failure_project_permissions),
|
||||||
None,
|
None,
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -620,8 +643,13 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let p =
|
let p = get_project_permissions(
|
||||||
get_project_permissions(self.user_id, self.user_pat, &project_id, test_env).await;
|
self.user_id,
|
||||||
|
self.user_pat,
|
||||||
|
&project_id,
|
||||||
|
&test_env.setup_api,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
if p != failure_project_permissions {
|
if p != failure_project_permissions {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Test 5 failed. Expected {:?}, got {:?}",
|
"Test 5 failed. Expected {:?}, got {:?}",
|
||||||
@@ -636,16 +664,17 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
// Project has an organization
|
// Project has an organization
|
||||||
// User affiliated with the project's org, with the default success
|
// User affiliated with the project's org, with the default success
|
||||||
let test_6 = async {
|
let test_6 = async {
|
||||||
let (project_id, team_id) = create_dummy_project(test_env).await;
|
let (project_id, team_id) = create_dummy_project(&test_env.setup_api).await;
|
||||||
let (organization_id, organization_team_id) = create_dummy_org(test_env).await;
|
let (organization_id, organization_team_id) =
|
||||||
add_project_to_org(test_env, &project_id, &organization_id).await;
|
create_dummy_org(&test_env.setup_api).await;
|
||||||
|
add_project_to_org(&test_env.setup_api, &project_id, &organization_id).await;
|
||||||
add_user_to_team(
|
add_user_to_team(
|
||||||
self.user_id,
|
self.user_id,
|
||||||
self.user_pat,
|
self.user_pat,
|
||||||
&organization_team_id,
|
&organization_team_id,
|
||||||
Some(success_permissions),
|
Some(success_permissions),
|
||||||
None,
|
None,
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -665,8 +694,13 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let p =
|
let p = get_project_permissions(
|
||||||
get_project_permissions(self.user_id, self.user_pat, &project_id, test_env).await;
|
self.user_id,
|
||||||
|
self.user_pat,
|
||||||
|
&project_id,
|
||||||
|
&test_env.setup_api,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
if p != success_permissions {
|
if p != success_permissions {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Test 6 failed. Expected {:?}, got {:?}",
|
"Test 6 failed. Expected {:?}, got {:?}",
|
||||||
@@ -682,16 +716,17 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
// User affiliated with the project's org (even can have successful permissions!)
|
// User affiliated with the project's org (even can have successful permissions!)
|
||||||
// User overwritten on the project team with failure permissions
|
// User overwritten on the project team with failure permissions
|
||||||
let test_7 = async {
|
let test_7 = async {
|
||||||
let (project_id, team_id) = create_dummy_project(test_env).await;
|
let (project_id, team_id) = create_dummy_project(&test_env.setup_api).await;
|
||||||
let (organization_id, organization_team_id) = create_dummy_org(test_env).await;
|
let (organization_id, organization_team_id) =
|
||||||
add_project_to_org(test_env, &project_id, &organization_id).await;
|
create_dummy_org(&test_env.setup_api).await;
|
||||||
|
add_project_to_org(&test_env.setup_api, &project_id, &organization_id).await;
|
||||||
add_user_to_team(
|
add_user_to_team(
|
||||||
self.user_id,
|
self.user_id,
|
||||||
self.user_pat,
|
self.user_pat,
|
||||||
&organization_team_id,
|
&organization_team_id,
|
||||||
Some(success_permissions),
|
Some(success_permissions),
|
||||||
None,
|
None,
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
add_user_to_team(
|
add_user_to_team(
|
||||||
@@ -700,7 +735,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
&team_id,
|
&team_id,
|
||||||
Some(failure_project_permissions),
|
Some(failure_project_permissions),
|
||||||
None,
|
None,
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -724,8 +759,13 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let p =
|
let p = get_project_permissions(
|
||||||
get_project_permissions(self.user_id, self.user_pat, &project_id, test_env).await;
|
self.user_id,
|
||||||
|
self.user_pat,
|
||||||
|
&project_id,
|
||||||
|
&test_env.setup_api,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
if p != failure_project_permissions {
|
if p != failure_project_permissions {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Test 7 failed. Expected {:?}, got {:?}",
|
"Test 7 failed. Expected {:?}, got {:?}",
|
||||||
@@ -741,16 +781,17 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
// User affiliated with the project's org with default failure permissions
|
// User affiliated with the project's org with default failure permissions
|
||||||
// User overwritten to the project with the success permissions
|
// User overwritten to the project with the success permissions
|
||||||
let test_8 = async {
|
let test_8 = async {
|
||||||
let (project_id, team_id) = create_dummy_project(test_env).await;
|
let (project_id, team_id) = create_dummy_project(&test_env.setup_api).await;
|
||||||
let (organization_id, organization_team_id) = create_dummy_org(test_env).await;
|
let (organization_id, organization_team_id) =
|
||||||
add_project_to_org(test_env, &project_id, &organization_id).await;
|
create_dummy_org(&test_env.setup_api).await;
|
||||||
|
add_project_to_org(&test_env.setup_api, &project_id, &organization_id).await;
|
||||||
add_user_to_team(
|
add_user_to_team(
|
||||||
self.user_id,
|
self.user_id,
|
||||||
self.user_pat,
|
self.user_pat,
|
||||||
&organization_team_id,
|
&organization_team_id,
|
||||||
Some(failure_project_permissions),
|
Some(failure_project_permissions),
|
||||||
None,
|
None,
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
add_user_to_team(
|
add_user_to_team(
|
||||||
@@ -759,7 +800,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
&team_id,
|
&team_id,
|
||||||
Some(success_permissions),
|
Some(success_permissions),
|
||||||
None,
|
None,
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -780,8 +821,13 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let p =
|
let p = get_project_permissions(
|
||||||
get_project_permissions(self.user_id, self.user_pat, &project_id, test_env).await;
|
self.user_id,
|
||||||
|
self.user_pat,
|
||||||
|
&project_id,
|
||||||
|
&test_env.setup_api,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
if p != success_permissions {
|
if p != success_permissions {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Test 8 failed. Expected {:?}, got {:?}",
|
"Test 8 failed. Expected {:?}, got {:?}",
|
||||||
@@ -811,7 +857,6 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
.failure_organization_permissions
|
.failure_organization_permissions
|
||||||
.unwrap_or(OrganizationPermissions::all() ^ success_permissions);
|
.unwrap_or(OrganizationPermissions::all() ^ success_permissions);
|
||||||
let test_context = PermissionsTestContext {
|
let test_context = PermissionsTestContext {
|
||||||
test_env,
|
|
||||||
user_id: self.user_id,
|
user_id: self.user_id,
|
||||||
user_pat: self.user_pat,
|
user_pat: self.user_pat,
|
||||||
project_id: None, // Will be overwritten on each test
|
project_id: None, // Will be overwritten on each test
|
||||||
@@ -823,7 +868,8 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
// TEST 1: Failure
|
// TEST 1: Failure
|
||||||
// Random user, entirely unaffliaited with the organization
|
// Random user, entirely unaffliaited with the organization
|
||||||
let test_1 = async {
|
let test_1 = async {
|
||||||
let (organization_id, organization_team_id) = create_dummy_org(test_env).await;
|
let (organization_id, organization_team_id) =
|
||||||
|
create_dummy_org(&test_env.setup_api).await;
|
||||||
|
|
||||||
let request = req_gen(&PermissionsTestContext {
|
let request = req_gen(&PermissionsTestContext {
|
||||||
organization_id: Some(&organization_id),
|
organization_id: Some(&organization_id),
|
||||||
@@ -848,7 +894,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
self.user_id,
|
self.user_id,
|
||||||
self.user_pat,
|
self.user_pat,
|
||||||
&organization_id,
|
&organization_id,
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
if p != OrganizationPermissions::empty() {
|
if p != OrganizationPermissions::empty() {
|
||||||
@@ -863,14 +909,15 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
// TEST 2: Failure
|
// TEST 2: Failure
|
||||||
// User affiliated with the organization, with failure permissions
|
// User affiliated with the organization, with failure permissions
|
||||||
let test_2 = async {
|
let test_2 = async {
|
||||||
let (organization_id, organization_team_id) = create_dummy_org(test_env).await;
|
let (organization_id, organization_team_id) =
|
||||||
|
create_dummy_org(&test_env.setup_api).await;
|
||||||
add_user_to_team(
|
add_user_to_team(
|
||||||
self.user_id,
|
self.user_id,
|
||||||
self.user_pat,
|
self.user_pat,
|
||||||
&organization_team_id,
|
&organization_team_id,
|
||||||
None,
|
None,
|
||||||
Some(failure_organization_permissions),
|
Some(failure_organization_permissions),
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -898,7 +945,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
self.user_id,
|
self.user_id,
|
||||||
self.user_pat,
|
self.user_pat,
|
||||||
&organization_id,
|
&organization_id,
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
if p != failure_organization_permissions {
|
if p != failure_organization_permissions {
|
||||||
@@ -913,14 +960,15 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
// TEST 3: Success
|
// TEST 3: Success
|
||||||
// User affiliated with the organization, with the given permissions
|
// User affiliated with the organization, with the given permissions
|
||||||
let test_3 = async {
|
let test_3 = async {
|
||||||
let (organization_id, organization_team_id) = create_dummy_org(test_env).await;
|
let (organization_id, organization_team_id) =
|
||||||
|
create_dummy_org(&test_env.setup_api).await;
|
||||||
add_user_to_team(
|
add_user_to_team(
|
||||||
self.user_id,
|
self.user_id,
|
||||||
self.user_pat,
|
self.user_pat,
|
||||||
&organization_team_id,
|
&organization_team_id,
|
||||||
None,
|
None,
|
||||||
Some(success_permissions),
|
Some(success_permissions),
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -944,7 +992,7 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
self.user_id,
|
self.user_id,
|
||||||
self.user_pat,
|
self.user_pat,
|
||||||
&organization_id,
|
&organization_id,
|
||||||
test_env,
|
&test_env.setup_api,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
if p != success_permissions {
|
if p != success_permissions {
|
||||||
@@ -962,31 +1010,29 @@ impl<'a> PermissionsTest<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_dummy_project(test_env: &TestEnvironment) -> (String, String) {
|
async fn create_dummy_project(setup_api: &ApiV3) -> (String, String) {
|
||||||
let api = &test_env.v3;
|
|
||||||
|
|
||||||
// Create a very simple project
|
// Create a very simple project
|
||||||
let slug = generate_random_name("test_project");
|
let slug = generate_random_name("test_project");
|
||||||
|
|
||||||
let creation_data = request_data::get_public_project_creation_data(&slug, None);
|
let (project, _) = setup_api
|
||||||
let (project, _) = api.add_public_project(creation_data, ADMIN_USER_PAT).await;
|
.add_public_project(&slug, None, None, ADMIN_USER_PAT)
|
||||||
|
.await;
|
||||||
let project_id = project.id.to_string();
|
let project_id = project.id.to_string();
|
||||||
let team_id = project.team.to_string();
|
let team_id = project.team.to_string();
|
||||||
|
|
||||||
(project_id, team_id)
|
(project_id, team_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_dummy_org(test_env: &TestEnvironment) -> (String, String) {
|
async fn create_dummy_org(setup_api: &ApiV3) -> (String, String) {
|
||||||
// Create a very simple organization
|
// Create a very simple organization
|
||||||
let name = generate_random_name("test_org");
|
let name = generate_random_name("test_org");
|
||||||
let api = &test_env.v3;
|
|
||||||
|
|
||||||
let resp = api
|
let resp = setup_api
|
||||||
.create_organization(&name, "Example description.", ADMIN_USER_PAT)
|
.create_organization(&name, "Example description.", ADMIN_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert!(resp.status().is_success());
|
assert!(resp.status().is_success());
|
||||||
|
|
||||||
let organization = api
|
let organization = setup_api
|
||||||
.get_organization_deserialized(&name, ADMIN_USER_PAT)
|
.get_organization_deserialized(&name, ADMIN_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
let organizaion_id = organization.id.to_string();
|
let organizaion_id = organization.id.to_string();
|
||||||
@@ -995,9 +1041,8 @@ async fn create_dummy_org(test_env: &TestEnvironment) -> (String, String) {
|
|||||||
(organizaion_id, team_id)
|
(organizaion_id, team_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn add_project_to_org(test_env: &TestEnvironment, project_id: &str, organization_id: &str) {
|
async fn add_project_to_org(setup_api: &ApiV3, project_id: &str, organization_id: &str) {
|
||||||
let api = &test_env.v3;
|
let resp = setup_api
|
||||||
let resp = api
|
|
||||||
.organization_add_project(organization_id, project_id, ADMIN_USER_PAT)
|
.organization_add_project(organization_id, project_id, ADMIN_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert!(resp.status().is_success());
|
assert!(resp.status().is_success());
|
||||||
@@ -1009,12 +1054,10 @@ async fn add_user_to_team(
|
|||||||
team_id: &str,
|
team_id: &str,
|
||||||
project_permissions: Option<ProjectPermissions>,
|
project_permissions: Option<ProjectPermissions>,
|
||||||
organization_permissions: Option<OrganizationPermissions>,
|
organization_permissions: Option<OrganizationPermissions>,
|
||||||
test_env: &TestEnvironment,
|
setup_api: &ApiV3,
|
||||||
) {
|
) {
|
||||||
let api = &test_env.v3;
|
|
||||||
|
|
||||||
// Invite user
|
// Invite user
|
||||||
let resp = api
|
let resp = setup_api
|
||||||
.add_user_to_team(
|
.add_user_to_team(
|
||||||
team_id,
|
team_id,
|
||||||
user_id,
|
user_id,
|
||||||
@@ -1026,7 +1069,7 @@ async fn add_user_to_team(
|
|||||||
assert!(resp.status().is_success());
|
assert!(resp.status().is_success());
|
||||||
|
|
||||||
// Accept invitation
|
// Accept invitation
|
||||||
let resp = api.join_team(team_id, user_pat).await;
|
let resp = setup_api.join_team(team_id, user_pat).await;
|
||||||
assert!(resp.status().is_success());
|
assert!(resp.status().is_success());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1035,12 +1078,10 @@ async fn modify_user_team_permissions(
|
|||||||
team_id: &str,
|
team_id: &str,
|
||||||
permissions: Option<ProjectPermissions>,
|
permissions: Option<ProjectPermissions>,
|
||||||
organization_permissions: Option<OrganizationPermissions>,
|
organization_permissions: Option<OrganizationPermissions>,
|
||||||
test_env: &TestEnvironment,
|
setup_api: &ApiV3,
|
||||||
) {
|
) {
|
||||||
let api = &test_env.v3;
|
|
||||||
|
|
||||||
// Send invitation to user
|
// Send invitation to user
|
||||||
let resp = api
|
let resp = setup_api
|
||||||
.edit_team_member(
|
.edit_team_member(
|
||||||
team_id,
|
team_id,
|
||||||
user_id,
|
user_id,
|
||||||
@@ -1054,10 +1095,11 @@ async fn modify_user_team_permissions(
|
|||||||
assert!(resp.status().is_success());
|
assert!(resp.status().is_success());
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn remove_user_from_team(user_id: &str, team_id: &str, test_env: &TestEnvironment) {
|
async fn remove_user_from_team(user_id: &str, team_id: &str, setup_api: &ApiV3) {
|
||||||
// Send invitation to user
|
// Send invitation to user
|
||||||
let api = &test_env.v3;
|
let resp = setup_api
|
||||||
let resp = api.remove_from_team(team_id, user_id, ADMIN_USER_PAT).await;
|
.remove_from_team(team_id, user_id, ADMIN_USER_PAT)
|
||||||
|
.await;
|
||||||
assert!(resp.status().is_success());
|
assert!(resp.status().is_success());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1065,9 +1107,9 @@ async fn get_project_permissions(
|
|||||||
user_id: &str,
|
user_id: &str,
|
||||||
user_pat: &str,
|
user_pat: &str,
|
||||||
project_id: &str,
|
project_id: &str,
|
||||||
test_env: &TestEnvironment,
|
setup_api: &ApiV3,
|
||||||
) -> ProjectPermissions {
|
) -> ProjectPermissions {
|
||||||
let resp = test_env.v3.get_project_members(project_id, user_pat).await;
|
let resp = setup_api.get_project_members(project_id, user_pat).await;
|
||||||
let permissions = if resp.status().as_u16() == 200 {
|
let permissions = if resp.status().as_u16() == 200 {
|
||||||
let value: serde_json::Value = test::read_body_json(resp).await;
|
let value: serde_json::Value = test::read_body_json(resp).await;
|
||||||
value
|
value
|
||||||
@@ -1088,10 +1130,9 @@ async fn get_organization_permissions(
|
|||||||
user_id: &str,
|
user_id: &str,
|
||||||
user_pat: &str,
|
user_pat: &str,
|
||||||
organization_id: &str,
|
organization_id: &str,
|
||||||
test_env: &TestEnvironment,
|
setup_api: &ApiV3,
|
||||||
) -> OrganizationPermissions {
|
) -> OrganizationPermissions {
|
||||||
let api = &test_env.v3;
|
let resp = setup_api
|
||||||
let resp = api
|
|
||||||
.get_organization_members(organization_id, user_pat)
|
.get_organization_members(organization_id, user_pat)
|
||||||
.await;
|
.await;
|
||||||
let permissions = if resp.status().as_u16() == 200 {
|
let permissions = if resp.status().as_u16() == 200 {
|
||||||
|
|||||||
@@ -2,15 +2,18 @@
|
|||||||
use actix_web::test::{self, TestRequest};
|
use actix_web::test::{self, TestRequest};
|
||||||
use labrinth::models::pats::Scopes;
|
use labrinth::models::pats::Scopes;
|
||||||
|
|
||||||
use super::{database::USER_USER_ID_PARSED, environment::TestEnvironment, pats::create_test_pat};
|
use super::{
|
||||||
|
api_common::Api, database::USER_USER_ID_PARSED, environment::TestEnvironment,
|
||||||
|
pats::create_test_pat,
|
||||||
|
};
|
||||||
|
|
||||||
// A reusable test type that works for any scope test testing an endpoint that:
|
// A reusable test type that works for any scope test testing an endpoint that:
|
||||||
// - returns a known 'expected_failure_code' if the scope is not present (defaults to 401)
|
// - returns a known 'expected_failure_code' if the scope is not present (defaults to 401)
|
||||||
// - returns a 200-299 if the scope is present
|
// - returns a 200-299 if the scope is present
|
||||||
// - returns failure and success JSON bodies for requests that are 200 (for performing non-simple follow-up tests on)
|
// - returns failure and success JSON bodies for requests that are 200 (for performing non-simple follow-up tests on)
|
||||||
// This uses a builder format, so you can chain methods to set the parameters to non-defaults (most will probably be not need to be set).
|
// This uses a builder format, so you can chain methods to set the parameters to non-defaults (most will probably be not need to be set).
|
||||||
pub struct ScopeTest<'a> {
|
pub struct ScopeTest<'a, A> {
|
||||||
test_env: &'a TestEnvironment,
|
test_env: &'a TestEnvironment<A>,
|
||||||
// Scopes expected to fail on this test. By default, this is all scopes except the success scopes.
|
// Scopes expected to fail on this test. By default, this is all scopes except the success scopes.
|
||||||
// (To ensure we have isolated the scope we are testing)
|
// (To ensure we have isolated the scope we are testing)
|
||||||
failure_scopes: Option<Scopes>,
|
failure_scopes: Option<Scopes>,
|
||||||
@@ -20,8 +23,8 @@ pub struct ScopeTest<'a> {
|
|||||||
expected_failure_code: u16,
|
expected_failure_code: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ScopeTest<'a> {
|
impl<'a, A: Api> ScopeTest<'a, A> {
|
||||||
pub fn new(test_env: &'a TestEnvironment) -> Self {
|
pub fn new(test_env: &'a TestEnvironment<A>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
test_env,
|
test_env,
|
||||||
failure_scopes: None,
|
failure_scopes: None,
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
// TODO: fold this into loader_fields.rs or tags.rs of other v3 testing PR
|
// TODO: fold this into loader_fields.rs or tags.rs of other v3 testing PR
|
||||||
|
|
||||||
use crate::common::environment::TestEnvironment;
|
use common::{
|
||||||
|
api_v3::ApiV3,
|
||||||
|
environment::{with_test_environment, TestEnvironment},
|
||||||
|
};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn get_games() {
|
async fn get_games() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
|
||||||
let api = &test_env.v3;
|
let api = test_env.api;
|
||||||
|
|
||||||
let games = api.get_games_deserialized().await;
|
let games = api.get_games_deserialized().await;
|
||||||
|
|
||||||
@@ -18,6 +21,6 @@ async fn get_games() {
|
|||||||
|
|
||||||
assert_eq!(games[0].slug, "minecraft-java");
|
assert_eq!(games[0].slug, "minecraft-java");
|
||||||
assert_eq!(games[1].slug, "minecraft-bedrock");
|
assert_eq!(games[1].slug, "minecraft-bedrock");
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use common::environment::TestEnvironment;
|
use common::api_v3::ApiV3;
|
||||||
|
use common::environment::{with_test_environment, TestEnvironment};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::common::api_v3::request_data::get_public_version_creation_data;
|
use crate::common::api_common::ApiVersion;
|
||||||
use crate::common::database::*;
|
use crate::common::database::*;
|
||||||
|
|
||||||
use crate::common::dummy_data::TestFile;
|
use crate::common::dummy_data::TestFile;
|
||||||
@@ -13,8 +14,8 @@ mod common;
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn creating_loader_fields() {
|
async fn creating_loader_fields() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
|
|
||||||
let alpha_project_id = &test_env
|
let alpha_project_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
@@ -36,15 +37,23 @@ async fn creating_loader_fields() {
|
|||||||
// Cannot create a version with an extra argument that cannot be tied to a loader field ("invalid loader field")
|
// Cannot create a version with an extra argument that cannot be tied to a loader field ("invalid loader field")
|
||||||
// TODO: - Create project
|
// TODO: - Create project
|
||||||
// - Create version
|
// - Create version
|
||||||
let version_data = get_public_version_creation_data(
|
let resp = api
|
||||||
|
.add_public_version(
|
||||||
alpha_project_id,
|
alpha_project_id,
|
||||||
"1.0.0",
|
"1.0.0",
|
||||||
TestFile::build_random_jar(),
|
TestFile::build_random_jar(),
|
||||||
Some(|j: &mut serde_json::Value| {
|
None,
|
||||||
j["invalid"] = json!("invalid");
|
Some(
|
||||||
}),
|
serde_json::from_value(json!([{
|
||||||
);
|
"op": "add",
|
||||||
let resp = api.add_public_version(version_data, USER_USER_PAT).await;
|
"path": "/invalid",
|
||||||
|
"value": "invalid"
|
||||||
|
}]))
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
assert_eq!(resp.status(), 400);
|
assert_eq!(resp.status(), 400);
|
||||||
// - Patch
|
// - Patch
|
||||||
let resp = api
|
let resp = api
|
||||||
@@ -61,16 +70,23 @@ async fn creating_loader_fields() {
|
|||||||
// Cannot create a version with a loader field that isnt used by the loader
|
// Cannot create a version with a loader field that isnt used by the loader
|
||||||
// TODO: - Create project
|
// TODO: - Create project
|
||||||
// - Create version
|
// - Create version
|
||||||
let version_data = get_public_version_creation_data(
|
let resp = api
|
||||||
|
.add_public_version(
|
||||||
alpha_project_id,
|
alpha_project_id,
|
||||||
"1.0.0",
|
"1.0.0",
|
||||||
TestFile::build_random_jar(),
|
TestFile::build_random_jar(),
|
||||||
Some(|j: &mut serde_json::Value| {
|
None,
|
||||||
// This is only for mrpacks, not mods/jars
|
Some(
|
||||||
j["mrpack_loaders"] = json!(["fabric"]);
|
serde_json::from_value(json!([{
|
||||||
}),
|
"op": "add",
|
||||||
);
|
"path": "/mrpack_loaders",
|
||||||
let resp = api.add_public_version(version_data, USER_USER_PAT).await;
|
"value": ["fabric"]
|
||||||
|
}]))
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
assert_eq!(resp.status(), 400);
|
assert_eq!(resp.status(), 400);
|
||||||
// - Patch
|
// - Patch
|
||||||
let resp = api
|
let resp = api
|
||||||
@@ -87,48 +103,67 @@ async fn creating_loader_fields() {
|
|||||||
// Cannot create a version without an applicable loader field that is not optional
|
// Cannot create a version without an applicable loader field that is not optional
|
||||||
// TODO: - Create project
|
// TODO: - Create project
|
||||||
// - Create version
|
// - Create version
|
||||||
let version_data = get_public_version_creation_data(
|
let resp = api
|
||||||
|
.add_public_version(
|
||||||
alpha_project_id,
|
alpha_project_id,
|
||||||
"1.0.0",
|
"1.0.0",
|
||||||
TestFile::build_random_jar(),
|
TestFile::build_random_jar(),
|
||||||
Some(|j: &mut serde_json::Value| {
|
None,
|
||||||
let j = j.as_object_mut().unwrap();
|
Some(
|
||||||
j.remove("client_side");
|
serde_json::from_value(json!([{
|
||||||
}),
|
"op": "remove",
|
||||||
);
|
"path": "/client_side"
|
||||||
let resp = api.add_public_version(version_data, USER_USER_PAT).await;
|
}]))
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
assert_eq!(resp.status(), 400);
|
assert_eq!(resp.status(), 400);
|
||||||
|
|
||||||
// Cannot create a version without a loader field array that has a minimum of 1
|
// Cannot create a version without a loader field array that has a minimum of 1
|
||||||
// TODO: - Create project
|
// TODO: - Create project
|
||||||
// - Create version
|
// - Create version
|
||||||
let version_data = get_public_version_creation_data(
|
let resp = api
|
||||||
|
.add_public_version(
|
||||||
alpha_project_id,
|
alpha_project_id,
|
||||||
"1.0.0",
|
"1.0.0",
|
||||||
TestFile::build_random_jar(),
|
TestFile::build_random_jar(),
|
||||||
Some(|j: &mut serde_json::Value| {
|
None,
|
||||||
let j = j.as_object_mut().unwrap();
|
Some(
|
||||||
j.remove("game_versions");
|
serde_json::from_value(json!([{
|
||||||
}),
|
"op": "remove",
|
||||||
);
|
"path": "/game_versions"
|
||||||
let resp = api.add_public_version(version_data, USER_USER_PAT).await;
|
}]))
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
assert_eq!(resp.status(), 400);
|
assert_eq!(resp.status(), 400);
|
||||||
|
|
||||||
// TODO: Create a test for too many elements in the array when we have a LF that has a max (past max)
|
// TODO: Create a test for too many elements in the array when we have a LF that has a max (past max)
|
||||||
// Cannot create a version with a loader field array that has fewer than the minimum elements
|
// Cannot create a version with a loader field array that has fewer than the minimum elements
|
||||||
// TODO: - Create project
|
// TODO: - Create project
|
||||||
// - Create version
|
// - Create version
|
||||||
let version_data = get_public_version_creation_data(
|
let resp: actix_web::dev::ServiceResponse = api
|
||||||
|
.add_public_version(
|
||||||
alpha_project_id,
|
alpha_project_id,
|
||||||
"1.0.0",
|
"1.0.0",
|
||||||
TestFile::build_random_jar(),
|
TestFile::build_random_jar(),
|
||||||
Some(|j: &mut serde_json::Value| {
|
None,
|
||||||
let j: &mut serde_json::Map<String, serde_json::Value> = j.as_object_mut().unwrap();
|
Some(
|
||||||
j["game_versions"] = json!([]);
|
serde_json::from_value(json!([{
|
||||||
}),
|
"op": "add",
|
||||||
);
|
"path": "/game_versions",
|
||||||
let resp: actix_web::dev::ServiceResponse =
|
"value": []
|
||||||
api.add_public_version(version_data, USER_USER_PAT).await;
|
}]))
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
assert_eq!(resp.status(), 400);
|
assert_eq!(resp.status(), 400);
|
||||||
|
|
||||||
// - Patch
|
// - Patch
|
||||||
@@ -152,16 +187,23 @@ async fn creating_loader_fields() {
|
|||||||
] {
|
] {
|
||||||
// TODO: - Create project
|
// TODO: - Create project
|
||||||
// - Create version
|
// - Create version
|
||||||
let version_data = get_public_version_creation_data(
|
let resp = api
|
||||||
|
.add_public_version(
|
||||||
alpha_project_id,
|
alpha_project_id,
|
||||||
"1.0.0",
|
"1.0.0",
|
||||||
TestFile::build_random_jar(),
|
TestFile::build_random_jar(),
|
||||||
Some(|j: &mut serde_json::Value| {
|
None,
|
||||||
let j: &mut serde_json::Map<String, serde_json::Value> = j.as_object_mut().unwrap();
|
Some(
|
||||||
j["game_versions"] = bad_type_game_versions.clone();
|
serde_json::from_value(json!([{
|
||||||
}),
|
"op": "add",
|
||||||
);
|
"path": "/game_versions",
|
||||||
let resp = api.add_public_version(version_data, USER_USER_PAT).await;
|
"value": bad_type_game_versions
|
||||||
|
}]))
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
assert_eq!(resp.status(), 400);
|
assert_eq!(resp.status(), 400);
|
||||||
|
|
||||||
// - Patch
|
// - Patch
|
||||||
@@ -180,16 +222,22 @@ async fn creating_loader_fields() {
|
|||||||
// Can create with optional loader fields (other tests have checked if we can create without them)
|
// Can create with optional loader fields (other tests have checked if we can create without them)
|
||||||
// TODO: - Create project
|
// TODO: - Create project
|
||||||
// - Create version
|
// - Create version
|
||||||
let version_data = get_public_version_creation_data(
|
let v = api
|
||||||
|
.add_public_version_deserialized(
|
||||||
alpha_project_id,
|
alpha_project_id,
|
||||||
"1.0.0",
|
"1.0.0",
|
||||||
TestFile::build_random_jar(),
|
TestFile::build_random_jar(),
|
||||||
Some(|j: &mut serde_json::Value| {
|
None,
|
||||||
j["test_fabric_optional"] = json!(555);
|
Some(
|
||||||
}),
|
serde_json::from_value(json!([{
|
||||||
);
|
"op": "add",
|
||||||
let v = api
|
"path": "/test_fabric_optional",
|
||||||
.add_public_version_deserialized(version_data, USER_USER_PAT)
|
"value": 555
|
||||||
|
}]))
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(v.fields.get("test_fabric_optional").unwrap(), &json!(555));
|
assert_eq!(v.fields.get("test_fabric_optional").unwrap(), &json!(555));
|
||||||
// - Patch
|
// - Patch
|
||||||
@@ -210,19 +258,30 @@ async fn creating_loader_fields() {
|
|||||||
|
|
||||||
// Simply setting them as expected works
|
// Simply setting them as expected works
|
||||||
// - Create
|
// - Create
|
||||||
let version_data = get_public_version_creation_data(
|
let v = api
|
||||||
|
.add_public_version_deserialized(
|
||||||
alpha_project_id,
|
alpha_project_id,
|
||||||
"1.0.0",
|
"1.0.0",
|
||||||
TestFile::build_random_jar(),
|
TestFile::build_random_jar(),
|
||||||
Some(|j: &mut serde_json::Value| {
|
None,
|
||||||
let j: &mut serde_json::Map<String, serde_json::Value> = j.as_object_mut().unwrap();
|
Some(
|
||||||
j["game_versions"] = json!(["1.20.1", "1.20.2"]);
|
serde_json::from_value(json!([{
|
||||||
j["client_side"] = json!("optional");
|
"op": "add",
|
||||||
j["server_side"] = json!("required");
|
"path": "/game_versions",
|
||||||
}),
|
"value": ["1.20.1", "1.20.2"]
|
||||||
);
|
}, {
|
||||||
let v = api
|
"op": "add",
|
||||||
.add_public_version_deserialized(version_data, USER_USER_PAT)
|
"path": "/client_side",
|
||||||
|
"value": "optional"
|
||||||
|
}, {
|
||||||
|
"op": "add",
|
||||||
|
"path": "/server_side",
|
||||||
|
"value": "required"
|
||||||
|
}]))
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
v.fields.get("game_versions").unwrap(),
|
v.fields.get("game_versions").unwrap(),
|
||||||
@@ -250,14 +309,14 @@ async fn creating_loader_fields() {
|
|||||||
v.fields.get("game_versions").unwrap(),
|
v.fields.get("game_versions").unwrap(),
|
||||||
&json!(["1.20.1", "1.20.2"])
|
&json!(["1.20.1", "1.20.2"])
|
||||||
);
|
);
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn get_loader_fields() {
|
async fn get_loader_fields() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
|
|
||||||
let game_versions = api
|
let game_versions = api
|
||||||
.get_loader_field_variants_deserialized("game_versions")
|
.get_loader_field_variants_deserialized("game_versions")
|
||||||
@@ -301,6 +360,6 @@ async fn get_loader_fields() {
|
|||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.collect()
|
.collect()
|
||||||
);
|
);
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
use common::{
|
use common::{
|
||||||
database::{FRIEND_USER_ID, FRIEND_USER_PAT, USER_USER_PAT},
|
database::{FRIEND_USER_ID, FRIEND_USER_PAT, USER_USER_PAT},
|
||||||
environment::with_test_environment,
|
environment::with_test_environment_all,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::common::api_common::ApiTeams;
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn get_user_notifications_after_team_invitation_returns_notification() {
|
pub async fn get_user_notifications_after_team_invitation_returns_notification() {
|
||||||
with_test_environment(|test_env| async move {
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_team_id = test_env
|
let alpha_team_id = test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -15,15 +17,15 @@ pub async fn get_user_notifications_after_team_invitation_returns_notification()
|
|||||||
.project_alpha
|
.project_alpha
|
||||||
.team_id
|
.team_id
|
||||||
.clone();
|
.clone();
|
||||||
let api = test_env.v3;
|
let api = test_env.api;
|
||||||
api.get_user_notifications_deserialized(FRIEND_USER_ID, FRIEND_USER_PAT)
|
api.get_user_notifications_deserialized_common(FRIEND_USER_ID, FRIEND_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
api.add_user_to_team(&alpha_team_id, FRIEND_USER_ID, None, None, USER_USER_PAT)
|
api.add_user_to_team(&alpha_team_id, FRIEND_USER_ID, None, None, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let notifications = api
|
let notifications = api
|
||||||
.get_user_notifications_deserialized(FRIEND_USER_ID, FRIEND_USER_PAT)
|
.get_user_notifications_deserialized_common(FRIEND_USER_ID, FRIEND_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(1, notifications.len());
|
assert_eq!(1, notifications.len());
|
||||||
})
|
})
|
||||||
@@ -32,11 +34,11 @@ pub async fn get_user_notifications_after_team_invitation_returns_notification()
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn get_user_notifications_after_reading_indicates_notification_read() {
|
pub async fn get_user_notifications_after_reading_indicates_notification_read() {
|
||||||
with_test_environment(|test_env| async move {
|
with_test_environment_all(None, |test_env| async move {
|
||||||
test_env.generate_friend_user_notification().await;
|
test_env.generate_friend_user_notification().await;
|
||||||
let api = test_env.v3;
|
let api = test_env.api;
|
||||||
let notifications = api
|
let notifications = api
|
||||||
.get_user_notifications_deserialized(FRIEND_USER_ID, FRIEND_USER_PAT)
|
.get_user_notifications_deserialized_common(FRIEND_USER_ID, FRIEND_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(1, notifications.len());
|
assert_eq!(1, notifications.len());
|
||||||
let notification_id = notifications[0].id.to_string();
|
let notification_id = notifications[0].id.to_string();
|
||||||
@@ -45,7 +47,7 @@ pub async fn get_user_notifications_after_reading_indicates_notification_read()
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
let notifications = api
|
let notifications = api
|
||||||
.get_user_notifications_deserialized(FRIEND_USER_ID, FRIEND_USER_PAT)
|
.get_user_notifications_deserialized_common(FRIEND_USER_ID, FRIEND_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(1, notifications.len());
|
assert_eq!(1, notifications.len());
|
||||||
assert!(notifications[0].read);
|
assert!(notifications[0].read);
|
||||||
@@ -55,11 +57,11 @@ pub async fn get_user_notifications_after_reading_indicates_notification_read()
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn get_user_notifications_after_deleting_does_not_show_notification() {
|
pub async fn get_user_notifications_after_deleting_does_not_show_notification() {
|
||||||
with_test_environment(|test_env| async move {
|
with_test_environment_all(None, |test_env| async move {
|
||||||
test_env.generate_friend_user_notification().await;
|
test_env.generate_friend_user_notification().await;
|
||||||
let api = test_env.v3;
|
let api = test_env.api;
|
||||||
let notifications = api
|
let notifications = api
|
||||||
.get_user_notifications_deserialized(FRIEND_USER_ID, FRIEND_USER_PAT)
|
.get_user_notifications_deserialized_common(FRIEND_USER_ID, FRIEND_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(1, notifications.len());
|
assert_eq!(1, notifications.len());
|
||||||
let notification_id = notifications[0].id.to_string();
|
let notification_id = notifications[0].id.to_string();
|
||||||
@@ -68,7 +70,7 @@ pub async fn get_user_notifications_after_deleting_does_not_show_notification()
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
let notifications = api
|
let notifications = api
|
||||||
.get_user_notifications_deserialized(FRIEND_USER_ID, FRIEND_USER_PAT)
|
.get_user_notifications_deserialized_common(FRIEND_USER_ID, FRIEND_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(0, notifications.len());
|
assert_eq!(0, notifications.len());
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,12 +2,15 @@ use actix_http::StatusCode;
|
|||||||
use actix_web::test;
|
use actix_web::test;
|
||||||
use common::{
|
use common::{
|
||||||
api_v3::oauth::get_redirect_location_query_params,
|
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},
|
asserts::{assert_any_status_except, assert_status},
|
||||||
database::FRIEND_USER_ID,
|
database::FRIEND_USER_ID,
|
||||||
database::{FRIEND_USER_PAT, USER_USER_ID, USER_USER_PAT},
|
database::{FRIEND_USER_PAT, USER_USER_ID, USER_USER_PAT},
|
||||||
dummy_data::DummyOAuthClientAlpha,
|
dummy_data::DummyOAuthClientAlpha,
|
||||||
environment::with_test_environment,
|
environment::{with_test_environment, TestEnvironment},
|
||||||
};
|
};
|
||||||
use labrinth::auth::oauth::TokenResponse;
|
use labrinth::auth::oauth::TokenResponse;
|
||||||
use reqwest::header::{CACHE_CONTROL, PRAGMA};
|
use reqwest::header::{CACHE_CONTROL, PRAGMA};
|
||||||
@@ -16,7 +19,7 @@ mod common;
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn oauth_flow_happy_path() {
|
async fn oauth_flow_happy_path() {
|
||||||
with_test_environment(|env| async move {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let DummyOAuthClientAlpha {
|
let DummyOAuthClientAlpha {
|
||||||
valid_redirect_uri: base_redirect_uri,
|
valid_redirect_uri: base_redirect_uri,
|
||||||
client_id,
|
client_id,
|
||||||
@@ -27,7 +30,7 @@ async fn oauth_flow_happy_path() {
|
|||||||
let redirect_uri = format!("{}?foo=bar", base_redirect_uri);
|
let redirect_uri = format!("{}?foo=bar", base_redirect_uri);
|
||||||
let original_state = "1234";
|
let original_state = "1234";
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.oauth_authorize(
|
.oauth_authorize(
|
||||||
&client_id,
|
&client_id,
|
||||||
Some("USER_READ NOTIFICATION_READ"),
|
Some("USER_READ NOTIFICATION_READ"),
|
||||||
@@ -40,7 +43,7 @@ async fn oauth_flow_happy_path() {
|
|||||||
let flow_id = get_authorize_accept_flow_id(resp).await;
|
let flow_id = get_authorize_accept_flow_id(resp).await;
|
||||||
|
|
||||||
// Accept the authorization request
|
// Accept the authorization request
|
||||||
let resp = env.v3.oauth_accept(&flow_id, FRIEND_USER_PAT).await;
|
let resp = env.api.oauth_accept(&flow_id, FRIEND_USER_PAT).await;
|
||||||
assert_status(&resp, StatusCode::OK);
|
assert_status(&resp, StatusCode::OK);
|
||||||
let query = get_redirect_location_query_params(&resp);
|
let query = get_redirect_location_query_params(&resp);
|
||||||
|
|
||||||
@@ -52,7 +55,7 @@ async fn oauth_flow_happy_path() {
|
|||||||
|
|
||||||
// Get the token
|
// Get the token
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.oauth_token(
|
.oauth_token(
|
||||||
auth_code.to_string(),
|
auth_code.to_string(),
|
||||||
Some(redirect_uri.clone()),
|
Some(redirect_uri.clone()),
|
||||||
@@ -78,11 +81,11 @@ async fn oauth_flow_happy_path() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn oauth_authorize_for_already_authorized_scopes_returns_auth_code() {
|
async fn oauth_authorize_for_already_authorized_scopes_returns_auth_code() {
|
||||||
with_test_environment(|env| async {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let DummyOAuthClientAlpha { client_id, .. } = env.dummy.unwrap().oauth_client_alpha.clone();
|
let DummyOAuthClientAlpha { client_id, .. } = env.dummy.unwrap().oauth_client_alpha.clone();
|
||||||
|
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.oauth_authorize(
|
.oauth_authorize(
|
||||||
&client_id,
|
&client_id,
|
||||||
Some("USER_READ NOTIFICATION_READ"),
|
Some("USER_READ NOTIFICATION_READ"),
|
||||||
@@ -92,10 +95,10 @@ async fn oauth_authorize_for_already_authorized_scopes_returns_auth_code() {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
let flow_id = get_authorize_accept_flow_id(resp).await;
|
let flow_id = get_authorize_accept_flow_id(resp).await;
|
||||||
env.v3.oauth_accept(&flow_id, USER_USER_PAT).await;
|
env.api.oauth_accept(&flow_id, USER_USER_PAT).await;
|
||||||
|
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.oauth_authorize(
|
.oauth_authorize(
|
||||||
&client_id,
|
&client_id,
|
||||||
Some("USER_READ"),
|
Some("USER_READ"),
|
||||||
@@ -111,7 +114,7 @@ async fn oauth_authorize_for_already_authorized_scopes_returns_auth_code() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn get_oauth_token_with_already_used_auth_code_fails() {
|
async fn get_oauth_token_with_already_used_auth_code_fails() {
|
||||||
with_test_environment(|env| async {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let DummyOAuthClientAlpha {
|
let DummyOAuthClientAlpha {
|
||||||
client_id,
|
client_id,
|
||||||
client_secret,
|
client_secret,
|
||||||
@@ -119,22 +122,22 @@ async fn get_oauth_token_with_already_used_auth_code_fails() {
|
|||||||
} = env.dummy.unwrap().oauth_client_alpha.clone();
|
} = env.dummy.unwrap().oauth_client_alpha.clone();
|
||||||
|
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.oauth_authorize(&client_id, None, None, None, USER_USER_PAT)
|
.oauth_authorize(&client_id, None, None, None, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
let flow_id = get_authorize_accept_flow_id(resp).await;
|
let flow_id = get_authorize_accept_flow_id(resp).await;
|
||||||
|
|
||||||
let resp = env.v3.oauth_accept(&flow_id, USER_USER_PAT).await;
|
let resp = env.api.oauth_accept(&flow_id, USER_USER_PAT).await;
|
||||||
let auth_code = get_auth_code_from_redirect_params(&resp).await;
|
let auth_code = get_auth_code_from_redirect_params(&resp).await;
|
||||||
|
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.oauth_token(auth_code.clone(), None, client_id.clone(), &client_secret)
|
.oauth_token(auth_code.clone(), None, client_id.clone(), &client_secret)
|
||||||
.await;
|
.await;
|
||||||
assert_status(&resp, StatusCode::OK);
|
assert_status(&resp, StatusCode::OK);
|
||||||
|
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.oauth_token(auth_code, None, client_id, &client_secret)
|
.oauth_token(auth_code, None, client_id, &client_secret)
|
||||||
.await;
|
.await;
|
||||||
assert_status(&resp, StatusCode::BAD_REQUEST);
|
assert_status(&resp, StatusCode::BAD_REQUEST);
|
||||||
@@ -144,7 +147,7 @@ async fn get_oauth_token_with_already_used_auth_code_fails() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn authorize_with_broader_scopes_can_complete_flow() {
|
async fn authorize_with_broader_scopes_can_complete_flow() {
|
||||||
with_test_environment(|env| async move {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let DummyOAuthClientAlpha {
|
let DummyOAuthClientAlpha {
|
||||||
client_id,
|
client_id,
|
||||||
client_secret,
|
client_secret,
|
||||||
@@ -152,7 +155,7 @@ async fn authorize_with_broader_scopes_can_complete_flow() {
|
|||||||
} = env.dummy.as_ref().unwrap().oauth_client_alpha.clone();
|
} = env.dummy.as_ref().unwrap().oauth_client_alpha.clone();
|
||||||
|
|
||||||
let first_access_token = env
|
let first_access_token = env
|
||||||
.v3
|
.api
|
||||||
.complete_full_authorize_flow(
|
.complete_full_authorize_flow(
|
||||||
&client_id,
|
&client_id,
|
||||||
&client_secret,
|
&client_secret,
|
||||||
@@ -163,7 +166,7 @@ async fn authorize_with_broader_scopes_can_complete_flow() {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
let second_access_token = env
|
let second_access_token = env
|
||||||
.v3
|
.api
|
||||||
.complete_full_authorize_flow(
|
.complete_full_authorize_flow(
|
||||||
&client_id,
|
&client_id,
|
||||||
&client_secret,
|
&client_secret,
|
||||||
@@ -193,17 +196,17 @@ async fn authorize_with_broader_scopes_can_complete_flow() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn oauth_authorize_with_broader_scopes_requires_user_accept() {
|
async fn oauth_authorize_with_broader_scopes_requires_user_accept() {
|
||||||
with_test_environment(|env| async {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let client_id = env.dummy.unwrap().oauth_client_alpha.client_id.clone();
|
let client_id = env.dummy.unwrap().oauth_client_alpha.client_id.clone();
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.oauth_authorize(&client_id, Some("USER_READ"), None, None, USER_USER_PAT)
|
.oauth_authorize(&client_id, Some("USER_READ"), None, None, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
let flow_id = get_authorize_accept_flow_id(resp).await;
|
let flow_id = get_authorize_accept_flow_id(resp).await;
|
||||||
env.v3.oauth_accept(&flow_id, USER_USER_PAT).await;
|
env.api.oauth_accept(&flow_id, USER_USER_PAT).await;
|
||||||
|
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.oauth_authorize(
|
.oauth_authorize(
|
||||||
&client_id,
|
&client_id,
|
||||||
Some("USER_READ NOTIFICATION_READ"),
|
Some("USER_READ NOTIFICATION_READ"),
|
||||||
@@ -221,18 +224,18 @@ async fn oauth_authorize_with_broader_scopes_requires_user_accept() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn reject_authorize_ends_authorize_flow() {
|
async fn reject_authorize_ends_authorize_flow() {
|
||||||
with_test_environment(|env| async move {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let client_id = env.dummy.unwrap().oauth_client_alpha.client_id.clone();
|
let client_id = env.dummy.unwrap().oauth_client_alpha.client_id.clone();
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.oauth_authorize(&client_id, None, None, None, USER_USER_PAT)
|
.oauth_authorize(&client_id, None, None, None, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
let flow_id = get_authorize_accept_flow_id(resp).await;
|
let flow_id = get_authorize_accept_flow_id(resp).await;
|
||||||
|
|
||||||
let resp = env.v3.oauth_reject(&flow_id, USER_USER_PAT).await;
|
let resp = env.api.oauth_reject(&flow_id, USER_USER_PAT).await;
|
||||||
assert_status(&resp, StatusCode::OK);
|
assert_status(&resp, StatusCode::OK);
|
||||||
|
|
||||||
let resp = env.v3.oauth_accept(&flow_id, USER_USER_PAT).await;
|
let resp = env.api.oauth_accept(&flow_id, USER_USER_PAT).await;
|
||||||
assert_any_status_except(&resp, StatusCode::OK);
|
assert_any_status_except(&resp, StatusCode::OK);
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -240,17 +243,17 @@ async fn reject_authorize_ends_authorize_flow() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn accept_authorize_after_already_accepting_fails() {
|
async fn accept_authorize_after_already_accepting_fails() {
|
||||||
with_test_environment(|env| async move {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let client_id = env.dummy.unwrap().oauth_client_alpha.client_id.clone();
|
let client_id = env.dummy.unwrap().oauth_client_alpha.client_id.clone();
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.oauth_authorize(&client_id, None, None, None, USER_USER_PAT)
|
.oauth_authorize(&client_id, None, None, None, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
let flow_id = get_authorize_accept_flow_id(resp).await;
|
let flow_id = get_authorize_accept_flow_id(resp).await;
|
||||||
let resp = env.v3.oauth_accept(&flow_id, USER_USER_PAT).await;
|
let resp = env.api.oauth_accept(&flow_id, USER_USER_PAT).await;
|
||||||
assert_status(&resp, StatusCode::OK);
|
assert_status(&resp, StatusCode::OK);
|
||||||
|
|
||||||
let resp = env.v3.oauth_accept(&flow_id, USER_USER_PAT).await;
|
let resp = env.api.oauth_accept(&flow_id, USER_USER_PAT).await;
|
||||||
assert_status(&resp, StatusCode::BAD_REQUEST);
|
assert_status(&resp, StatusCode::BAD_REQUEST);
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -258,14 +261,14 @@ async fn accept_authorize_after_already_accepting_fails() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn revoke_authorization_after_issuing_token_revokes_token() {
|
async fn revoke_authorization_after_issuing_token_revokes_token() {
|
||||||
with_test_environment(|env| async move {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let DummyOAuthClientAlpha {
|
let DummyOAuthClientAlpha {
|
||||||
client_id,
|
client_id,
|
||||||
client_secret,
|
client_secret,
|
||||||
..
|
..
|
||||||
} = env.dummy.as_ref().unwrap().oauth_client_alpha.clone();
|
} = env.dummy.as_ref().unwrap().oauth_client_alpha.clone();
|
||||||
let access_token = env
|
let access_token = env
|
||||||
.v3
|
.api
|
||||||
.complete_full_authorize_flow(
|
.complete_full_authorize_flow(
|
||||||
&client_id,
|
&client_id,
|
||||||
&client_secret,
|
&client_secret,
|
||||||
@@ -279,7 +282,7 @@ async fn revoke_authorization_after_issuing_token_revokes_token() {
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.revoke_oauth_authorization(&client_id, USER_USER_PAT)
|
.revoke_oauth_authorization(&client_id, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_status(&resp, StatusCode::OK);
|
assert_status(&resp, StatusCode::OK);
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
use actix_http::StatusCode;
|
use actix_http::StatusCode;
|
||||||
use actix_web::test;
|
use actix_web::test;
|
||||||
use common::{
|
use common::{
|
||||||
|
api_v3::ApiV3,
|
||||||
database::{FRIEND_USER_ID, FRIEND_USER_PAT, USER_USER_ID, USER_USER_PAT},
|
database::{FRIEND_USER_ID, FRIEND_USER_PAT, USER_USER_ID, USER_USER_PAT},
|
||||||
dummy_data::DummyOAuthClientAlpha,
|
dummy_data::DummyOAuthClientAlpha,
|
||||||
environment::with_test_environment,
|
environment::{with_test_environment, TestEnvironment},
|
||||||
get_json_val_str,
|
get_json_val_str,
|
||||||
};
|
};
|
||||||
use labrinth::{
|
use labrinth::{
|
||||||
@@ -20,14 +21,14 @@ mod common;
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn can_create_edit_get_oauth_client() {
|
async fn can_create_edit_get_oauth_client() {
|
||||||
with_test_environment(|env| async move {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let client_name = "test_client".to_string();
|
let client_name = "test_client".to_string();
|
||||||
let redirect_uris = vec![
|
let redirect_uris = vec![
|
||||||
"https://modrinth.com".to_string(),
|
"https://modrinth.com".to_string(),
|
||||||
"https://modrinth.com/a".to_string(),
|
"https://modrinth.com/a".to_string(),
|
||||||
];
|
];
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.add_oauth_client(
|
.add_oauth_client(
|
||||||
client_name.clone(),
|
client_name.clone(),
|
||||||
Scopes::all() - Scopes::restricted(),
|
Scopes::all() - Scopes::restricted(),
|
||||||
@@ -51,13 +52,13 @@ async fn can_create_edit_get_oauth_client() {
|
|||||||
redirect_uris: Some(edited_redirect_uris.clone()),
|
redirect_uris: Some(edited_redirect_uris.clone()),
|
||||||
};
|
};
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.edit_oauth_client(&client_id, edit, FRIEND_USER_PAT)
|
.edit_oauth_client(&client_id, edit, FRIEND_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_status(&resp, StatusCode::OK);
|
assert_status(&resp, StatusCode::OK);
|
||||||
|
|
||||||
let clients = env
|
let clients = env
|
||||||
.v3
|
.api
|
||||||
.get_user_oauth_clients(FRIEND_USER_ID, FRIEND_USER_PAT)
|
.get_user_oauth_clients(FRIEND_USER_ID, FRIEND_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(1, clients.len());
|
assert_eq!(1, clients.len());
|
||||||
@@ -72,9 +73,9 @@ async fn can_create_edit_get_oauth_client() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn create_oauth_client_with_restricted_scopes_fails() {
|
async fn create_oauth_client_with_restricted_scopes_fails() {
|
||||||
with_test_environment(|env| async move {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.add_oauth_client(
|
.add_oauth_client(
|
||||||
"test_client".to_string(),
|
"test_client".to_string(),
|
||||||
Scopes::restricted(),
|
Scopes::restricted(),
|
||||||
@@ -90,12 +91,12 @@ async fn create_oauth_client_with_restricted_scopes_fails() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn get_oauth_client_for_client_creator_succeeds() {
|
async fn get_oauth_client_for_client_creator_succeeds() {
|
||||||
with_test_environment(|env| async move {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let DummyOAuthClientAlpha { client_id, .. } =
|
let DummyOAuthClientAlpha { client_id, .. } =
|
||||||
env.dummy.as_ref().unwrap().oauth_client_alpha.clone();
|
env.dummy.as_ref().unwrap().oauth_client_alpha.clone();
|
||||||
|
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.get_oauth_client(client_id.clone(), USER_USER_PAT)
|
.get_oauth_client(client_id.clone(), USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -108,12 +109,12 @@ async fn get_oauth_client_for_client_creator_succeeds() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn get_oauth_client_for_unrelated_user_fails() {
|
async fn get_oauth_client_for_unrelated_user_fails() {
|
||||||
with_test_environment(|env| async move {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let DummyOAuthClientAlpha { client_id, .. } =
|
let DummyOAuthClientAlpha { client_id, .. } =
|
||||||
env.dummy.as_ref().unwrap().oauth_client_alpha.clone();
|
env.dummy.as_ref().unwrap().oauth_client_alpha.clone();
|
||||||
|
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.get_oauth_client(client_id.clone(), FRIEND_USER_PAT)
|
.get_oauth_client(client_id.clone(), FRIEND_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -124,13 +125,13 @@ async fn get_oauth_client_for_unrelated_user_fails() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn can_delete_oauth_client() {
|
async fn can_delete_oauth_client() {
|
||||||
with_test_environment(|env| async move {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let client_id = env.dummy.unwrap().oauth_client_alpha.client_id.clone();
|
let client_id = env.dummy.unwrap().oauth_client_alpha.client_id.clone();
|
||||||
let resp = env.v3.delete_oauth_client(&client_id, USER_USER_PAT).await;
|
let resp = env.api.delete_oauth_client(&client_id, USER_USER_PAT).await;
|
||||||
assert_status(&resp, StatusCode::NO_CONTENT);
|
assert_status(&resp, StatusCode::NO_CONTENT);
|
||||||
|
|
||||||
let clients = env
|
let clients = env
|
||||||
.v3
|
.api
|
||||||
.get_user_oauth_clients(USER_USER_ID, USER_USER_PAT)
|
.get_user_oauth_clients(USER_USER_ID, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(0, clients.len());
|
assert_eq!(0, clients.len());
|
||||||
@@ -140,14 +141,14 @@ async fn can_delete_oauth_client() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn delete_oauth_client_after_issuing_access_tokens_revokes_tokens() {
|
async fn delete_oauth_client_after_issuing_access_tokens_revokes_tokens() {
|
||||||
with_test_environment(|env| async move {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let DummyOAuthClientAlpha {
|
let DummyOAuthClientAlpha {
|
||||||
client_id,
|
client_id,
|
||||||
client_secret,
|
client_secret,
|
||||||
..
|
..
|
||||||
} = env.dummy.as_ref().unwrap().oauth_client_alpha.clone();
|
} = env.dummy.as_ref().unwrap().oauth_client_alpha.clone();
|
||||||
let access_token = env
|
let access_token = env
|
||||||
.v3
|
.api
|
||||||
.complete_full_authorize_flow(
|
.complete_full_authorize_flow(
|
||||||
&client_id,
|
&client_id,
|
||||||
&client_secret,
|
&client_secret,
|
||||||
@@ -158,7 +159,7 @@ async fn delete_oauth_client_after_issuing_access_tokens_revokes_tokens() {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
env.v3.delete_oauth_client(&client_id, USER_USER_PAT).await;
|
env.api.delete_oauth_client(&client_id, USER_USER_PAT).await;
|
||||||
|
|
||||||
env.assert_read_notifications_status(USER_USER_ID, &access_token, StatusCode::UNAUTHORIZED)
|
env.assert_read_notifications_status(USER_USER_ID, &access_token, StatusCode::UNAUTHORIZED)
|
||||||
.await;
|
.await;
|
||||||
@@ -168,13 +169,13 @@ async fn delete_oauth_client_after_issuing_access_tokens_revokes_tokens() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn can_list_user_oauth_authorizations() {
|
async fn can_list_user_oauth_authorizations() {
|
||||||
with_test_environment(|env| async move {
|
with_test_environment(None, |env: TestEnvironment<ApiV3>| async move {
|
||||||
let DummyOAuthClientAlpha {
|
let DummyOAuthClientAlpha {
|
||||||
client_id,
|
client_id,
|
||||||
client_secret,
|
client_secret,
|
||||||
..
|
..
|
||||||
} = env.dummy.as_ref().unwrap().oauth_client_alpha.clone();
|
} = env.dummy.as_ref().unwrap().oauth_client_alpha.clone();
|
||||||
env.v3
|
env.api
|
||||||
.complete_full_authorize_flow(
|
.complete_full_authorize_flow(
|
||||||
&client_id,
|
&client_id,
|
||||||
&client_secret,
|
&client_secret,
|
||||||
@@ -185,7 +186,7 @@ async fn can_list_user_oauth_authorizations() {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let authorizations = env.v3.get_user_oauth_authorizations(USER_USER_PAT).await;
|
let authorizations = env.api.get_user_oauth_authorizations(USER_USER_PAT).await;
|
||||||
assert_eq!(1, authorizations.len());
|
assert_eq!(1, authorizations.len());
|
||||||
assert_eq!(USER_USER_ID_PARSED, authorizations[0].user_id.0 as i64);
|
assert_eq!(USER_USER_ID_PARSED, authorizations[0].user_id.0 as i64);
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
use crate::common::{
|
use crate::common::{
|
||||||
|
api_common::ApiTeams,
|
||||||
api_v3::request_data::get_icon_data,
|
api_v3::request_data::get_icon_data,
|
||||||
database::{generate_random_name, ADMIN_USER_PAT, MOD_USER_ID, MOD_USER_PAT, USER_USER_ID},
|
database::{generate_random_name, ADMIN_USER_PAT, MOD_USER_ID, MOD_USER_PAT, USER_USER_ID},
|
||||||
dummy_data::DummyImage,
|
dummy_data::DummyImage,
|
||||||
environment::TestEnvironment,
|
|
||||||
};
|
};
|
||||||
use actix_web::test;
|
use actix_web::test;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use common::{
|
use common::{
|
||||||
|
api_v3::ApiV3,
|
||||||
database::{FRIEND_USER_ID, FRIEND_USER_PAT, USER_USER_PAT},
|
database::{FRIEND_USER_ID, FRIEND_USER_PAT, USER_USER_PAT},
|
||||||
|
environment::{with_test_environment, with_test_environment_all, TestEnvironment},
|
||||||
permissions::{PermissionsTest, PermissionsTestContext},
|
permissions::{PermissionsTest, PermissionsTestContext},
|
||||||
};
|
};
|
||||||
use labrinth::models::teams::{OrganizationPermissions, ProjectPermissions};
|
use labrinth::models::teams::{OrganizationPermissions, ProjectPermissions};
|
||||||
@@ -17,8 +19,8 @@ mod common;
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn create_organization() {
|
async fn create_organization() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
let zeta_organization_slug = &test_env
|
let zeta_organization_slug = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -69,7 +71,7 @@ async fn create_organization() {
|
|||||||
|
|
||||||
// Get created team
|
// Get created team
|
||||||
let members = api
|
let members = api
|
||||||
.get_organization_members_deserialized("theta", USER_USER_PAT)
|
.get_organization_members_deserialized_common("theta", USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
// Should only be one member, which is USER_USER_ID, and is the owner with full permissions
|
// Should only be one member, which is USER_USER_ID, and is the owner with full permissions
|
||||||
@@ -79,14 +81,14 @@ async fn create_organization() {
|
|||||||
Some(OrganizationPermissions::all())
|
Some(OrganizationPermissions::all())
|
||||||
);
|
);
|
||||||
assert_eq!(members[0].role, "Owner");
|
assert_eq!(members[0].role, "Owner");
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn patch_organization() {
|
async fn patch_organization() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
|
|
||||||
let zeta_organization_id = &test_env
|
let zeta_organization_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
@@ -160,15 +162,15 @@ async fn patch_organization() {
|
|||||||
.await;
|
.await;
|
||||||
assert_eq!(new_title.title, "new_title");
|
assert_eq!(new_title.title, "new_title");
|
||||||
assert_eq!(new_title.description, "not url safe%&^!#$##!@#$%^&");
|
assert_eq!(new_title.description, "not url safe%&^!#$##!@#$%^&");
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add/remove icon
|
// add/remove icon
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn add_remove_icon() {
|
async fn add_remove_icon() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
let zeta_organization_id = &test_env
|
let zeta_organization_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -178,7 +180,7 @@ async fn add_remove_icon() {
|
|||||||
|
|
||||||
// Get project
|
// Get project
|
||||||
let resp = test_env
|
let resp = test_env
|
||||||
.v3
|
.api
|
||||||
.get_organization_deserialized(zeta_organization_id, USER_USER_PAT)
|
.get_organization_deserialized(zeta_organization_id, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(resp.icon_url, None);
|
assert_eq!(resp.icon_url, None);
|
||||||
@@ -212,15 +214,15 @@ async fn add_remove_icon() {
|
|||||||
.get_organization_deserialized(zeta_organization_id, USER_USER_PAT)
|
.get_organization_deserialized(zeta_organization_id, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert!(zeta_org.icon_url.is_none());
|
assert!(zeta_org.icon_url.is_none());
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete org
|
// delete org
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn delete_org() {
|
async fn delete_org() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
let zeta_organization_id = &test_env
|
let zeta_organization_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -238,14 +240,14 @@ async fn delete_org() {
|
|||||||
.get_organization(zeta_organization_id, USER_USER_PAT)
|
.get_organization(zeta_organization_id, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(resp.status(), 404);
|
assert_eq!(resp.status(), 404);
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add/remove organization projects
|
// add/remove organization projects
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn add_remove_organization_projects() {
|
async fn add_remove_organization_projects() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
|
||||||
let alpha_project_id: &str = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
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 alpha_project_slug: &str = &test_env.dummy.as_ref().unwrap().project_alpha.project_slug;
|
||||||
let zeta_organization_id: &str = &test_env
|
let zeta_organization_id: &str = &test_env
|
||||||
@@ -258,14 +260,14 @@ async fn add_remove_organization_projects() {
|
|||||||
// Add/remove project to organization, first by ID, then by slug
|
// Add/remove project to organization, first by ID, then by slug
|
||||||
for alpha in [alpha_project_id, alpha_project_slug] {
|
for alpha in [alpha_project_id, alpha_project_slug] {
|
||||||
let resp = test_env
|
let resp = test_env
|
||||||
.v3
|
.api
|
||||||
.organization_add_project(zeta_organization_id, alpha, USER_USER_PAT)
|
.organization_add_project(zeta_organization_id, alpha, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
|
|
||||||
// Get organization projects
|
// Get organization projects
|
||||||
let projects = test_env
|
let projects = test_env
|
||||||
.v3
|
.api
|
||||||
.get_organization_projects_deserialized(zeta_organization_id, USER_USER_PAT)
|
.get_organization_projects_deserialized(zeta_organization_id, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(projects[0].id.to_string(), alpha_project_id);
|
assert_eq!(projects[0].id.to_string(), alpha_project_id);
|
||||||
@@ -273,26 +275,25 @@ async fn add_remove_organization_projects() {
|
|||||||
|
|
||||||
// Remove project from organization
|
// Remove project from organization
|
||||||
let resp = test_env
|
let resp = test_env
|
||||||
.v3
|
.api
|
||||||
.organization_remove_project(zeta_organization_id, alpha, USER_USER_PAT)
|
.organization_remove_project(zeta_organization_id, alpha, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
|
|
||||||
// Get organization projects
|
// Get organization projects
|
||||||
let projects = test_env
|
let projects = test_env
|
||||||
.v3
|
.api
|
||||||
.get_organization_projects_deserialized(zeta_organization_id, USER_USER_PAT)
|
.get_organization_projects_deserialized(zeta_organization_id, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert!(projects.is_empty());
|
assert!(projects.is_empty());
|
||||||
}
|
}
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn permissions_patch_organization() {
|
async fn permissions_patch_organization() {
|
||||||
let test_env = TestEnvironment::build(Some(8)).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
|
|
||||||
// For each permission covered by EDIT_DETAILS, ensure the permission is required
|
// For each permission covered by EDIT_DETAILS, ensure the permission is required
|
||||||
let edit_details = OrganizationPermissions::EDIT_DETAILS;
|
let edit_details = OrganizationPermissions::EDIT_DETAILS;
|
||||||
let test_pairs = [
|
let test_pairs = [
|
||||||
@@ -320,15 +321,14 @@ async fn permissions_patch_organization() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not covered by PATCH /organization
|
// Not covered by PATCH /organization
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn permissions_edit_details() {
|
async fn permissions_edit_details() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
|
|
||||||
let zeta_organization_id = &test_env
|
let zeta_organization_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -372,13 +372,15 @@ async fn permissions_edit_details() {
|
|||||||
.simple_organization_permissions_test(edit_details, req_gen)
|
.simple_organization_permissions_test(edit_details, req_gen)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn permissions_manage_invites() {
|
async fn permissions_manage_invites() {
|
||||||
// Add member, remove member, edit member
|
// Add member, remove member, edit member
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
|
|
||||||
let zeta_organization_id = &test_env
|
let zeta_organization_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
@@ -464,14 +466,14 @@ async fn permissions_manage_invites() {
|
|||||||
.simple_organization_permissions_test(remove_member, req_gen)
|
.simple_organization_permissions_test(remove_member, req_gen)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn permissions_add_remove_project() {
|
async fn permissions_add_remove_project() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
|
|
||||||
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
||||||
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
||||||
@@ -531,13 +533,13 @@ async fn permissions_add_remove_project() {
|
|||||||
.simple_organization_permissions_test(remove_project, req_gen)
|
.simple_organization_permissions_test(remove_project, req_gen)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn permissions_delete_organization() {
|
async fn permissions_delete_organization() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let delete_organization = OrganizationPermissions::DELETE_ORGANIZATION;
|
let delete_organization = OrganizationPermissions::DELETE_ORGANIZATION;
|
||||||
|
|
||||||
// Now, FRIEND_USER_ID owns the alpha project
|
// Now, FRIEND_USER_ID owns the alpha project
|
||||||
@@ -552,13 +554,13 @@ async fn permissions_delete_organization() {
|
|||||||
.simple_organization_permissions_test(delete_organization, req_gen)
|
.simple_organization_permissions_test(delete_organization, req_gen)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn permissions_add_default_project_permissions() {
|
async fn permissions_add_default_project_permissions() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let zeta_organization_id = &test_env
|
let zeta_organization_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -621,12 +623,12 @@ async fn permissions_add_default_project_permissions() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
test_env.cleanup().await;
|
}).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn permissions_organization_permissions_consistency_test() {
|
async fn permissions_organization_permissions_consistency_test() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
// Ensuring that permission are as we expect them to be
|
// Ensuring that permission are as we expect them to be
|
||||||
// Full organization permissions test
|
// Full organization permissions test
|
||||||
let success_permissions = OrganizationPermissions::EDIT_DETAILS;
|
let success_permissions = OrganizationPermissions::EDIT_DETAILS;
|
||||||
@@ -644,6 +646,6 @@ async fn permissions_organization_permissions_consistency_test() {
|
|||||||
.full_organization_permissions_tests(success_permissions, req_gen)
|
.full_organization_permissions_tests(success_permissions, req_gen)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use actix_web::test;
|
use actix_web::test;
|
||||||
use chrono::{Duration, Utc};
|
use chrono::{Duration, Utc};
|
||||||
use common::database::*;
|
use common::{database::*, environment::with_test_environment_all};
|
||||||
use common::environment::TestEnvironment;
|
|
||||||
use labrinth::models::pats::Scopes;
|
use labrinth::models::pats::Scopes;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
@@ -16,8 +16,7 @@ mod common;
|
|||||||
// - ensure PATs can be deleted
|
// - ensure PATs can be deleted
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn pat_full_test() {
|
pub async fn pat_full_test() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
|
|
||||||
// Create a PAT for a full test
|
// Create a PAT for a full test
|
||||||
let req = test::TestRequest::post()
|
let req = test::TestRequest::post()
|
||||||
.uri("/v3/pat")
|
.uri("/v3/pat")
|
||||||
@@ -153,16 +152,14 @@ pub async fn pat_full_test() {
|
|||||||
.to_request();
|
.to_request();
|
||||||
let resp = test_env.call(req).await;
|
let resp = test_env.call(req).await;
|
||||||
assert_eq!(resp.status().as_u16(), 204);
|
assert_eq!(resp.status().as_u16(), 204);
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test illegal PAT setting, both in POST and PATCH
|
// Test illegal PAT setting, both in POST and PATCH
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn bad_pats() {
|
pub async fn bad_pats() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
|
|
||||||
// Creating a PAT with no name should fail
|
// Creating a PAT with no name should fail
|
||||||
let req = test::TestRequest::post()
|
let req = test::TestRequest::post()
|
||||||
.uri("/v3/pat")
|
.uri("/v3/pat")
|
||||||
@@ -284,7 +281,6 @@ pub async fn bad_pats() {
|
|||||||
if scope.is_restricted() { 400 } else { 204 }
|
if scope.is_restricted() { 400 } else { 204 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ use bytes::Bytes;
|
|||||||
use chrono::{Duration, Utc};
|
use chrono::{Duration, Utc};
|
||||||
use common::database::*;
|
use common::database::*;
|
||||||
use common::dummy_data::DUMMY_CATEGORIES;
|
use common::dummy_data::DUMMY_CATEGORIES;
|
||||||
use common::environment::{with_test_environment, TestEnvironment};
|
|
||||||
|
use common::environment::with_test_environment_all;
|
||||||
use common::permissions::{PermissionsTest, PermissionsTestContext};
|
use common::permissions::{PermissionsTest, PermissionsTestContext};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use labrinth::database::models::project_item::{PROJECTS_NAMESPACE, PROJECTS_SLUGS_NAMESPACE};
|
use labrinth::database::models::project_item::{PROJECTS_NAMESPACE, PROJECTS_SLUGS_NAMESPACE};
|
||||||
@@ -13,12 +14,14 @@ use labrinth::models::teams::ProjectPermissions;
|
|||||||
use labrinth::util::actix::{AppendsMultipart, MultipartSegment, MultipartSegmentData};
|
use labrinth::util::actix::{AppendsMultipart, MultipartSegment, MultipartSegmentData};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
|
use crate::common::api_common::{ApiProject, ApiVersion};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_get_project() {
|
async fn test_get_project() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
||||||
let beta_project_id = &test_env.dummy.as_ref().unwrap().project_beta.project_id;
|
let beta_project_id = &test_env.dummy.as_ref().unwrap().project_beta.project_id;
|
||||||
let alpha_project_slug = &test_env.dummy.as_ref().unwrap().project_alpha.project_slug;
|
let alpha_project_slug = &test_env.dummy.as_ref().unwrap().project_alpha.project_slug;
|
||||||
@@ -91,16 +94,15 @@ async fn test_get_project() {
|
|||||||
|
|
||||||
let resp = test_env.call(req).await;
|
let resp = test_env.call(req).await;
|
||||||
assert_eq!(resp.status(), 404);
|
assert_eq!(resp.status(), 404);
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_add_remove_project() {
|
async fn test_add_remove_project() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
|
|
||||||
// Generate test project data.
|
// Generate test project data.
|
||||||
let mut json_data = json!(
|
let mut json_data = json!(
|
||||||
@@ -155,7 +157,9 @@ async fn test_add_remove_project() {
|
|||||||
filename: Some("basic-mod.jar".to_string()),
|
filename: Some("basic-mod.jar".to_string()),
|
||||||
content_type: Some("application/java-archive".to_string()),
|
content_type: Some("application/java-archive".to_string()),
|
||||||
// TODO: look at these: can be used in the reuse data
|
// TODO: look at these: can be used in the reuse data
|
||||||
data: MultipartSegmentData::Binary(include_bytes!("../tests/files/basic-mod.jar").to_vec()),
|
data: MultipartSegmentData::Binary(
|
||||||
|
include_bytes!("../tests/files/basic-mod.jar").to_vec(),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Differently named file, with the same content (for hash testing)
|
// Differently named file, with the same content (for hash testing)
|
||||||
@@ -163,7 +167,9 @@ async fn test_add_remove_project() {
|
|||||||
name: "basic-mod-different.jar".to_string(),
|
name: "basic-mod-different.jar".to_string(),
|
||||||
filename: Some("basic-mod-different.jar".to_string()),
|
filename: Some("basic-mod-different.jar".to_string()),
|
||||||
content_type: Some("application/java-archive".to_string()),
|
content_type: Some("application/java-archive".to_string()),
|
||||||
data: MultipartSegmentData::Binary(include_bytes!("../tests/files/basic-mod.jar").to_vec()),
|
data: MultipartSegmentData::Binary(
|
||||||
|
include_bytes!("../tests/files/basic-mod.jar").to_vec(),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Differently named file, with different content
|
// Differently named file, with different content
|
||||||
@@ -188,7 +194,9 @@ async fn test_add_remove_project() {
|
|||||||
assert_eq!(status, 200);
|
assert_eq!(status, 200);
|
||||||
|
|
||||||
// Get the project we just made, and confirm that it's correct
|
// Get the project we just made, and confirm that it's correct
|
||||||
let project = api.get_project_deserialized("demo", USER_USER_PAT).await;
|
let project = api
|
||||||
|
.get_project_deserialized_common("demo", USER_USER_PAT)
|
||||||
|
.await;
|
||||||
assert!(project.versions.len() == 1);
|
assert!(project.versions.len() == 1);
|
||||||
let uploaded_version_id = project.versions[0];
|
let uploaded_version_id = project.versions[0];
|
||||||
|
|
||||||
@@ -197,7 +205,7 @@ async fn test_add_remove_project() {
|
|||||||
.digest()
|
.digest()
|
||||||
.to_string();
|
.to_string();
|
||||||
let version = api
|
let version = api
|
||||||
.get_version_from_hash_deserialized(&hash, "sha1", USER_USER_PAT)
|
.get_version_from_hash_deserialized_common(&hash, "sha1", USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(version.id, uploaded_version_id);
|
assert_eq!(version.id, uploaded_version_id);
|
||||||
|
|
||||||
@@ -242,11 +250,13 @@ async fn test_add_remove_project() {
|
|||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
|
|
||||||
// Get
|
// Get
|
||||||
let project = api.get_project_deserialized("demo", USER_USER_PAT).await;
|
let project = api
|
||||||
|
.get_project_deserialized_common("demo", USER_USER_PAT)
|
||||||
|
.await;
|
||||||
let id = project.id.to_string();
|
let id = project.id.to_string();
|
||||||
|
|
||||||
// Remove the project
|
// Remove the project
|
||||||
let resp = test_env.v3.remove_project("demo", USER_USER_PAT).await;
|
let resp = test_env.api.remove_project("demo", USER_USER_PAT).await;
|
||||||
assert_eq!(resp.status(), 204);
|
assert_eq!(resp.status(), 204);
|
||||||
|
|
||||||
// Confirm that the project is gone from the cache
|
// Confirm that the project is gone from the cache
|
||||||
@@ -271,15 +281,14 @@ async fn test_add_remove_project() {
|
|||||||
// Old slug no longer works
|
// Old slug no longer works
|
||||||
let resp = api.get_project("demo", USER_USER_PAT).await;
|
let resp = api.get_project("demo", USER_USER_PAT).await;
|
||||||
assert_eq!(resp.status(), 404);
|
assert_eq!(resp.status(), 404);
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn test_patch_project() {
|
pub async fn test_patch_project() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
|
|
||||||
let alpha_project_slug = &test_env.dummy.as_ref().unwrap().project_alpha.project_slug;
|
let alpha_project_slug = &test_env.dummy.as_ref().unwrap().project_alpha.project_slug;
|
||||||
let beta_project_slug = &test_env.dummy.as_ref().unwrap().project_beta.project_slug;
|
let beta_project_slug = &test_env.dummy.as_ref().unwrap().project_beta.project_slug;
|
||||||
@@ -417,7 +426,9 @@ pub async fn test_patch_project() {
|
|||||||
assert_eq!(resp.status(), 404);
|
assert_eq!(resp.status(), 404);
|
||||||
|
|
||||||
// New slug does work
|
// New slug does work
|
||||||
let project = api.get_project_deserialized("newslug", USER_USER_PAT).await;
|
let project = api
|
||||||
|
.get_project_deserialized_common("newslug", USER_USER_PAT)
|
||||||
|
.await;
|
||||||
|
|
||||||
assert_eq!(project.slug.unwrap(), "newslug");
|
assert_eq!(project.slug.unwrap(), "newslug");
|
||||||
assert_eq!(project.title, "New successful title");
|
assert_eq!(project.title, "New successful title");
|
||||||
@@ -432,21 +443,20 @@ pub async fn test_patch_project() {
|
|||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// for loader fields?
|
// for loader fields?
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn test_bulk_edit_categories() {
|
pub async fn test_bulk_edit_categories() {
|
||||||
with_test_environment(|test_env| async move {
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
let alpha_project_id: &str = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
let alpha_project_id: &str = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
||||||
let beta_project_id: &str = &test_env.dummy.as_ref().unwrap().project_beta.project_id;
|
let beta_project_id: &str = &test_env.dummy.as_ref().unwrap().project_beta.project_id;
|
||||||
|
|
||||||
let resp = api
|
let resp = api
|
||||||
.edit_project_bulk(
|
.edit_project_bulk(
|
||||||
[alpha_project_id, beta_project_id],
|
&[alpha_project_id, beta_project_id],
|
||||||
json!({
|
json!({
|
||||||
"categories": [DUMMY_CATEGORIES[0], DUMMY_CATEGORIES[3]],
|
"categories": [DUMMY_CATEGORIES[0], DUMMY_CATEGORIES[3]],
|
||||||
"add_categories": [DUMMY_CATEGORIES[1], DUMMY_CATEGORIES[2]],
|
"add_categories": [DUMMY_CATEGORIES[1], DUMMY_CATEGORIES[2]],
|
||||||
@@ -461,13 +471,13 @@ pub async fn test_bulk_edit_categories() {
|
|||||||
assert_eq!(resp.status(), StatusCode::NO_CONTENT);
|
assert_eq!(resp.status(), StatusCode::NO_CONTENT);
|
||||||
|
|
||||||
let alpha_body = api
|
let alpha_body = api
|
||||||
.get_project_deserialized(alpha_project_id, ADMIN_USER_PAT)
|
.get_project_deserialized_common(alpha_project_id, ADMIN_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(alpha_body.categories, DUMMY_CATEGORIES[0..=2]);
|
assert_eq!(alpha_body.categories, DUMMY_CATEGORIES[0..=2]);
|
||||||
assert_eq!(alpha_body.additional_categories, DUMMY_CATEGORIES[4..=5]);
|
assert_eq!(alpha_body.additional_categories, DUMMY_CATEGORIES[4..=5]);
|
||||||
|
|
||||||
let beta_body = api
|
let beta_body = api
|
||||||
.get_project_deserialized(beta_project_id, ADMIN_USER_PAT)
|
.get_project_deserialized_common(beta_project_id, ADMIN_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(beta_body.categories, alpha_body.categories);
|
assert_eq!(beta_body.categories, alpha_body.categories);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -480,7 +490,7 @@ pub async fn test_bulk_edit_categories() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn permissions_patch_project() {
|
async fn permissions_patch_project() {
|
||||||
let test_env = TestEnvironment::build(Some(8)).await;
|
with_test_environment_all(Some(8), |test_env| async move {
|
||||||
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
||||||
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
||||||
|
|
||||||
@@ -580,15 +590,14 @@ async fn permissions_patch_project() {
|
|||||||
.simple_project_permissions_test(edit_body, req_gen)
|
.simple_project_permissions_test(edit_body, req_gen)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not covered by PATCH /project
|
// Not covered by PATCH /project
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn permissions_edit_details() {
|
async fn permissions_edit_details() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
|
|
||||||
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
||||||
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
||||||
let beta_project_id = &test_env.dummy.as_ref().unwrap().project_beta.project_id;
|
let beta_project_id = &test_env.dummy.as_ref().unwrap().project_beta.project_id;
|
||||||
@@ -715,11 +724,13 @@ async fn permissions_edit_details() {
|
|||||||
.simple_project_permissions_test(edit_details, req_gen)
|
.simple_project_permissions_test(edit_details, req_gen)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn permissions_upload_version() {
|
async fn permissions_upload_version() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
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_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_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
||||||
@@ -842,14 +853,14 @@ async fn permissions_upload_version() {
|
|||||||
.simple_project_permissions_test(delete_version, req_gen)
|
.simple_project_permissions_test(delete_version, req_gen)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn permissions_manage_invites() {
|
async fn permissions_manage_invites() {
|
||||||
// Add member, remove member, edit member
|
// Add member, remove member, edit member
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
||||||
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
||||||
|
|
||||||
@@ -939,15 +950,14 @@ async fn permissions_manage_invites() {
|
|||||||
.simple_project_permissions_test(remove_member, req_gen)
|
.simple_project_permissions_test(remove_member, req_gen)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn permissions_delete_project() {
|
async fn permissions_delete_project() {
|
||||||
// Add member, remove member, edit member
|
// Add member, remove member, edit member
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
|
|
||||||
let delete_project = ProjectPermissions::DELETE_PROJECT;
|
let delete_project = ProjectPermissions::DELETE_PROJECT;
|
||||||
|
|
||||||
// Delete project
|
// Delete project
|
||||||
@@ -960,12 +970,13 @@ async fn permissions_delete_project() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
test_env.cleanup().await;
|
test_env.cleanup().await;
|
||||||
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn project_permissions_consistency_test() {
|
async fn project_permissions_consistency_test() {
|
||||||
let test_env = TestEnvironment::build(Some(10)).await;
|
with_test_environment_all(Some(10), |test_env| async move {
|
||||||
|
|
||||||
// Test that the permissions are consistent with each other
|
// Test that the permissions are consistent with each other
|
||||||
// For example, if we get the projectpermissions directly, from an organization's defaults, overriden, etc, they should all be correct & consistent
|
// For example, if we get the projectpermissions directly, from an organization's defaults, overriden, etc, they should all be correct & consistent
|
||||||
|
|
||||||
@@ -999,8 +1010,8 @@ async fn project_permissions_consistency_test() {
|
|||||||
.full_project_permissions_test(success_permissions, req_gen)
|
.full_project_permissions_test(success_permissions, req_gen)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route tests:
|
// Route tests:
|
||||||
|
|||||||
126
tests/scopes.rs
126
tests/scopes.rs
@@ -1,11 +1,15 @@
|
|||||||
use actix_web::test::{self, TestRequest};
|
use actix_web::test::{self, TestRequest};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use chrono::{Duration, Utc};
|
use chrono::{Duration, Utc};
|
||||||
use common::{database::*, environment::TestEnvironment, scopes::ScopeTest};
|
|
||||||
|
use common::environment::with_test_environment_all;
|
||||||
|
use common::{database::*, scopes::ScopeTest};
|
||||||
use labrinth::models::pats::Scopes;
|
use labrinth::models::pats::Scopes;
|
||||||
use labrinth::util::actix::{AppendsMultipart, MultipartSegment, MultipartSegmentData};
|
use labrinth::util::actix::{AppendsMultipart, MultipartSegment, MultipartSegmentData};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
|
use crate::common::api_common::ApiTeams;
|
||||||
|
|
||||||
// For each scope, we (using test_scope):
|
// For each scope, we (using test_scope):
|
||||||
// - create a PAT with a given set of scopes for a function
|
// - create a PAT with a given set of scopes for a function
|
||||||
// - create a PAT with all other scopes for a function
|
// - create a PAT with all other scopes for a function
|
||||||
@@ -18,8 +22,7 @@ mod common;
|
|||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn user_scopes() {
|
async fn user_scopes() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
|
|
||||||
// User reading
|
// User reading
|
||||||
let read_user = Scopes::USER_READ;
|
let read_user = Scopes::USER_READ;
|
||||||
let req_gen = || TestRequest::get().uri("/v3/user");
|
let req_gen = || TestRequest::get().uri("/v3/user");
|
||||||
@@ -77,15 +80,14 @@ async fn user_scopes() {
|
|||||||
.test(req_gen, delete_user)
|
.test(req_gen, delete_user)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notifications
|
// Notifications
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn notifications_scopes() {
|
pub async fn notifications_scopes() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_team_id = &test_env
|
let alpha_team_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -97,7 +99,7 @@ pub async fn notifications_scopes() {
|
|||||||
// We will invite user 'friend' to project team, and use that as a notification
|
// We will invite user 'friend' to project team, and use that as a notification
|
||||||
// Get notifications
|
// Get notifications
|
||||||
let resp = test_env
|
let resp = test_env
|
||||||
.v3
|
.api
|
||||||
.add_user_to_team(alpha_team_id, FRIEND_USER_ID, None, None, USER_USER_PAT)
|
.add_user_to_team(alpha_team_id, FRIEND_USER_ID, None, None, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(resp.status(), 204);
|
assert_eq!(resp.status(), 204);
|
||||||
@@ -125,7 +127,8 @@ pub async fn notifications_scopes() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let req_gen = || test::TestRequest::get().uri(&format!("/v3/notification/{notification_id}"));
|
let req_gen =
|
||||||
|
|| test::TestRequest::get().uri(&format!("/v3/notification/{notification_id}"));
|
||||||
ScopeTest::new(&test_env)
|
ScopeTest::new(&test_env)
|
||||||
.with_user_id(FRIEND_USER_ID_PARSED)
|
.with_user_id(FRIEND_USER_ID_PARSED)
|
||||||
.test(req_gen, read_notifications)
|
.test(req_gen, read_notifications)
|
||||||
@@ -146,7 +149,8 @@ pub async fn notifications_scopes() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let req_gen = || test::TestRequest::patch().uri(&format!("/v3/notification/{notification_id}"));
|
let req_gen =
|
||||||
|
|| test::TestRequest::patch().uri(&format!("/v3/notification/{notification_id}"));
|
||||||
ScopeTest::new(&test_env)
|
ScopeTest::new(&test_env)
|
||||||
.with_user_id(FRIEND_USER_ID_PARSED)
|
.with_user_id(FRIEND_USER_ID_PARSED)
|
||||||
.test(req_gen, write_notifications)
|
.test(req_gen, write_notifications)
|
||||||
@@ -165,12 +169,13 @@ pub async fn notifications_scopes() {
|
|||||||
// Mass notification delete
|
// Mass notification delete
|
||||||
// We invite mod, get the notification ID, and do mass delete using that
|
// We invite mod, get the notification ID, and do mass delete using that
|
||||||
let resp = test_env
|
let resp = test_env
|
||||||
.v3
|
.api
|
||||||
.add_user_to_team(alpha_team_id, MOD_USER_ID, None, None, USER_USER_PAT)
|
.add_user_to_team(alpha_team_id, MOD_USER_ID, None, None, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(resp.status(), 204);
|
assert_eq!(resp.status(), 204);
|
||||||
let read_notifications = Scopes::NOTIFICATION_READ;
|
let read_notifications = Scopes::NOTIFICATION_READ;
|
||||||
let req_gen = || test::TestRequest::get().uri(&format!("/v3/user/{MOD_USER_ID}/notifications"));
|
let req_gen =
|
||||||
|
|| test::TestRequest::get().uri(&format!("/v3/user/{MOD_USER_ID}/notifications"));
|
||||||
let (_, success) = ScopeTest::new(&test_env)
|
let (_, success) = ScopeTest::new(&test_env)
|
||||||
.with_user_id(MOD_USER_ID_PARSED)
|
.with_user_id(MOD_USER_ID_PARSED)
|
||||||
.test(req_gen, read_notifications)
|
.test(req_gen, read_notifications)
|
||||||
@@ -189,16 +194,14 @@ pub async fn notifications_scopes() {
|
|||||||
.test(req_gen, write_notifications)
|
.test(req_gen, write_notifications)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Project version creation scopes
|
// Project version creation scopes
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn project_version_create_scopes() {
|
pub async fn project_version_create_scopes() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
|
|
||||||
// Create project
|
// Create project
|
||||||
let create_project = Scopes::PROJECT_CREATE;
|
let create_project = Scopes::PROJECT_CREATE;
|
||||||
let json_data = json!(
|
let json_data = json!(
|
||||||
@@ -233,7 +236,9 @@ pub async fn project_version_create_scopes() {
|
|||||||
name: "basic-mod.jar".to_string(),
|
name: "basic-mod.jar".to_string(),
|
||||||
filename: Some("basic-mod.jar".to_string()),
|
filename: Some("basic-mod.jar".to_string()),
|
||||||
content_type: Some("application/java-archive".to_string()),
|
content_type: Some("application/java-archive".to_string()),
|
||||||
data: MultipartSegmentData::Binary(include_bytes!("../tests/files/basic-mod.jar").to_vec()),
|
data: MultipartSegmentData::Binary(
|
||||||
|
include_bytes!("../tests/files/basic-mod.jar").to_vec(),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
let req_gen = || {
|
let req_gen = || {
|
||||||
@@ -288,15 +293,14 @@ pub async fn project_version_create_scopes() {
|
|||||||
.test(req_gen, create_version)
|
.test(req_gen, create_version)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Project management scopes
|
// Project management scopes
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn project_version_reads_scopes() {
|
pub async fn project_version_reads_scopes() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let beta_project_id = &test_env
|
let beta_project_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -437,7 +441,8 @@ pub async fn project_version_reads_scopes() {
|
|||||||
let resp = test_env.call(req).await;
|
let resp = test_env.call(req).await;
|
||||||
assert_eq!(resp.status(), 204);
|
assert_eq!(resp.status(), 204);
|
||||||
|
|
||||||
let req_gen = || test::TestRequest::get().uri(&format!("/v3/version_file/{beta_file_hash}"));
|
let req_gen =
|
||||||
|
|| test::TestRequest::get().uri(&format!("/v3/version_file/{beta_file_hash}"));
|
||||||
ScopeTest::new(&test_env)
|
ScopeTest::new(&test_env)
|
||||||
.with_failure_code(404)
|
.with_failure_code(404)
|
||||||
.test(req_gen, read_version)
|
.test(req_gen, read_version)
|
||||||
@@ -523,16 +528,15 @@ pub async fn project_version_reads_scopes() {
|
|||||||
// .uri(&format!("/v3/project/{beta_project_id}/version/{beta_version_id}"))
|
// .uri(&format!("/v3/project/{beta_project_id}/version/{beta_version_id}"))
|
||||||
// };
|
// };
|
||||||
// ScopeTest::new(&test_env).with_failure_code(404).test(req_gen, read_project_and_version).await.unwrap();
|
// ScopeTest::new(&test_env).with_failure_code(404).test(req_gen, read_project_and_version).await.unwrap();
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Project writing
|
// Project writing
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn project_write_scopes() {
|
pub async fn project_write_scopes() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let beta_project_id = &test_env
|
let beta_project_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -721,7 +725,8 @@ pub async fn project_write_scopes() {
|
|||||||
|
|
||||||
// Now as 'friend', delete 'user'
|
// Now as 'friend', delete 'user'
|
||||||
let req_gen = || {
|
let req_gen = || {
|
||||||
test::TestRequest::delete().uri(&format!("/v3/team/{alpha_team_id}/members/{USER_USER_ID}"))
|
test::TestRequest::delete()
|
||||||
|
.uri(&format!("/v3/team/{alpha_team_id}/members/{USER_USER_ID}"))
|
||||||
};
|
};
|
||||||
ScopeTest::new(&test_env)
|
ScopeTest::new(&test_env)
|
||||||
.with_user_id(FRIEND_USER_ID_PARSED)
|
.with_user_id(FRIEND_USER_ID_PARSED)
|
||||||
@@ -739,16 +744,15 @@ pub async fn project_write_scopes() {
|
|||||||
// .uri(&format!("/v3/project/{beta_project_id}"))
|
// .uri(&format!("/v3/project/{beta_project_id}"))
|
||||||
// };
|
// };
|
||||||
// ScopeTest::new(&test_env).test(req_gen, delete_version).await.unwrap();
|
// ScopeTest::new(&test_env).test(req_gen, delete_version).await.unwrap();
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version write
|
// Version write
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn version_write_scopes() {
|
pub async fn version_write_scopes() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_version_id = &test_env
|
let alpha_version_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -867,21 +871,21 @@ pub async fn version_write_scopes() {
|
|||||||
|
|
||||||
// Delete version
|
// Delete version
|
||||||
let delete_version = Scopes::VERSION_DELETE;
|
let delete_version = Scopes::VERSION_DELETE;
|
||||||
let req_gen = || test::TestRequest::delete().uri(&format!("/v3/version/{alpha_version_id}"));
|
let req_gen =
|
||||||
|
|| test::TestRequest::delete().uri(&format!("/v3/version/{alpha_version_id}"));
|
||||||
ScopeTest::new(&test_env)
|
ScopeTest::new(&test_env)
|
||||||
.test(req_gen, delete_version)
|
.test(req_gen, delete_version)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report scopes
|
// Report scopes
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn report_scopes() {
|
pub async fn report_scopes() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let beta_project_id = &test_env
|
let beta_project_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -954,16 +958,15 @@ pub async fn report_scopes() {
|
|||||||
.test(req_gen, report_delete)
|
.test(req_gen, report_delete)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Thread scopes
|
// Thread scopes
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn thread_scopes() {
|
pub async fn thread_scopes() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_thread_id = &test_env
|
let alpha_thread_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -1045,22 +1048,21 @@ pub async fn thread_scopes() {
|
|||||||
let success: serde_json::Value = test::read_body_json(resp).await;
|
let success: serde_json::Value = test::read_body_json(resp).await;
|
||||||
let thread_message_id = success["messages"][0]["id"].as_str().unwrap();
|
let thread_message_id = success["messages"][0]["id"].as_str().unwrap();
|
||||||
|
|
||||||
let req_gen = || test::TestRequest::delete().uri(&format!("/v3/message/{thread_message_id}"));
|
let req_gen =
|
||||||
|
|| test::TestRequest::delete().uri(&format!("/v3/message/{thread_message_id}"));
|
||||||
ScopeTest::new(&test_env)
|
ScopeTest::new(&test_env)
|
||||||
.with_user_id(MOD_USER_ID_PARSED)
|
.with_user_id(MOD_USER_ID_PARSED)
|
||||||
.test(req_gen, thread_write)
|
.test(req_gen, thread_write)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pat scopes
|
// Pat scopes
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn pat_scopes() {
|
pub async fn pat_scopes() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
|
|
||||||
// Pat create
|
// Pat create
|
||||||
let pat_create = Scopes::PAT_CREATE;
|
let pat_create = Scopes::PAT_CREATE;
|
||||||
let req_gen = || {
|
let req_gen = || {
|
||||||
@@ -1103,16 +1105,15 @@ pub async fn pat_scopes() {
|
|||||||
.test(req_gen, pat_delete)
|
.test(req_gen, pat_delete)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collection scopes
|
// Collection scopes
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn collections_scopes() {
|
pub async fn collections_scopes() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_project_id = &test_env
|
let alpha_project_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -1177,7 +1178,8 @@ pub async fn collections_scopes() {
|
|||||||
assert_eq!(failure.as_array().unwrap().len(), 0);
|
assert_eq!(failure.as_array().unwrap().len(), 0);
|
||||||
assert_eq!(success.as_array().unwrap().len(), 1);
|
assert_eq!(success.as_array().unwrap().len(), 1);
|
||||||
|
|
||||||
let req_gen = || test::TestRequest::get().uri(&format!("/v3/user/{USER_USER_ID}/collections"));
|
let req_gen =
|
||||||
|
|| test::TestRequest::get().uri(&format!("/v3/user/{USER_USER_ID}/collections"));
|
||||||
let (failure, success) = ScopeTest::new(&test_env)
|
let (failure, success) = ScopeTest::new(&test_env)
|
||||||
.with_failure_code(200)
|
.with_failure_code(200)
|
||||||
.test(req_gen, collection_read)
|
.test(req_gen, collection_read)
|
||||||
@@ -1204,16 +1206,15 @@ pub async fn collections_scopes() {
|
|||||||
.test(req_gen, collection_write)
|
.test(req_gen, collection_write)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Organization scopes (and a couple PROJECT_WRITE scopes that are only allowed for orgs)
|
// Organization scopes (and a couple PROJECT_WRITE scopes that are only allowed for orgs)
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn organization_scopes() {
|
pub async fn organization_scopes() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let beta_project_id = &test_env
|
let beta_project_id = &test_env
|
||||||
.dummy
|
.dummy
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -1288,7 +1289,8 @@ pub async fn organization_scopes() {
|
|||||||
|
|
||||||
// Organization reads
|
// Organization reads
|
||||||
let organization_read = Scopes::ORGANIZATION_READ;
|
let organization_read = Scopes::ORGANIZATION_READ;
|
||||||
let req_gen = || test::TestRequest::get().uri(&format!("/v3/organization/{organization_id}"));
|
let req_gen =
|
||||||
|
|| test::TestRequest::get().uri(&format!("/v3/organization/{organization_id}"));
|
||||||
let (failure, success) = ScopeTest::new(&test_env)
|
let (failure, success) = ScopeTest::new(&test_env)
|
||||||
.with_failure_code(200)
|
.with_failure_code(200)
|
||||||
.test(req_gen, organization_read)
|
.test(req_gen, organization_read)
|
||||||
@@ -1313,8 +1315,9 @@ pub async fn organization_scopes() {
|
|||||||
assert!(!success[0]["members"][0]["permissions"].is_null());
|
assert!(!success[0]["members"][0]["permissions"].is_null());
|
||||||
|
|
||||||
let organization_project_read = Scopes::PROJECT_READ | Scopes::ORGANIZATION_READ;
|
let organization_project_read = Scopes::PROJECT_READ | Scopes::ORGANIZATION_READ;
|
||||||
let req_gen =
|
let req_gen = || {
|
||||||
|| test::TestRequest::get().uri(&format!("/v3/organization/{organization_id}/projects"));
|
test::TestRequest::get().uri(&format!("/v3/organization/{organization_id}/projects"))
|
||||||
|
};
|
||||||
let (failure, success) = ScopeTest::new(&test_env)
|
let (failure, success) = ScopeTest::new(&test_env)
|
||||||
.with_failure_code(200)
|
.with_failure_code(200)
|
||||||
.with_failure_scopes(Scopes::all() ^ Scopes::ORGANIZATION_READ)
|
.with_failure_scopes(Scopes::all() ^ Scopes::ORGANIZATION_READ)
|
||||||
@@ -1344,9 +1347,8 @@ pub async fn organization_scopes() {
|
|||||||
.test(req_gen, organization_delete)
|
.test(req_gen, organization_delete)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Analytics scopes
|
// TODO: Analytics scopes
|
||||||
|
|||||||
168
tests/search.rs
168
tests/search.rs
@@ -1,6 +1,9 @@
|
|||||||
|
use common::api_v3::ApiV3;
|
||||||
use common::database::*;
|
use common::database::*;
|
||||||
use common::dummy_data::TestFile;
|
use common::dummy_data::TestFile;
|
||||||
use common::dummy_data::DUMMY_CATEGORIES;
|
use common::dummy_data::DUMMY_CATEGORIES;
|
||||||
|
|
||||||
|
use common::environment::with_test_environment;
|
||||||
use common::environment::TestEnvironment;
|
use common::environment::TestEnvironment;
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
use labrinth::models::ids::base62_impl::parse_base62;
|
use labrinth::models::ids::base62_impl::parse_base62;
|
||||||
@@ -8,9 +11,9 @@ use serde_json::json;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::common::api_v3::request_data::{
|
use crate::common::api_common::Api;
|
||||||
self, get_public_version_creation_data, ProjectCreationRequestData,
|
use crate::common::api_common::ApiProject;
|
||||||
};
|
use crate::common::api_common::ApiVersion;
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
@@ -20,8 +23,8 @@ mod common;
|
|||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn search_projects() {
|
async fn search_projects() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(Some(10)).await;
|
with_test_environment(Some(10), |test_env: TestEnvironment<ApiV3>| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
let test_name = test_env.db.database_name.clone();
|
let test_name = test_env.db.database_name.clone();
|
||||||
|
|
||||||
// Add dummy projects of various categories for searchability
|
// Add dummy projects of various categories for searchability
|
||||||
@@ -31,7 +34,7 @@ async fn search_projects() {
|
|||||||
|id: u64,
|
|id: u64,
|
||||||
pat: &'static str,
|
pat: &'static str,
|
||||||
is_modpack: bool,
|
is_modpack: bool,
|
||||||
modify_json: Box<dyn Fn(&mut serde_json::Value)>| {
|
modify_json: Option<json_patch::Patch>| {
|
||||||
let slug = format!("{test_name}-searchable-project-{id}");
|
let slug = format!("{test_name}-searchable-project-{id}");
|
||||||
|
|
||||||
let jar = if is_modpack {
|
let jar = if is_modpack {
|
||||||
@@ -39,21 +42,9 @@ async fn search_projects() {
|
|||||||
} else {
|
} else {
|
||||||
TestFile::build_random_jar()
|
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 {
|
async move {
|
||||||
|
// Add a project- simple, should work.
|
||||||
|
let req = api.add_public_project(&slug, Some(jar), modify_json, pat);
|
||||||
let (project, _) = req.await;
|
let (project, _) = req.await;
|
||||||
|
|
||||||
// Approve, so that the project is searchable
|
// Approve, so that the project is searchable
|
||||||
@@ -73,122 +64,130 @@ async fn search_projects() {
|
|||||||
|
|
||||||
// Test project 0
|
// Test project 0
|
||||||
let id = 0;
|
let id = 0;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[4..6]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[4..6] },
|
||||||
json["initial_versions"][0]["server_side"] = json!("required");
|
{ "op": "add", "path": "/initial_versions/0/server_side", "value": "required" },
|
||||||
json["license_id"] = json!("LGPL-3.0-or-later");
|
{ "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 1
|
// Test project 1
|
||||||
let id = 1;
|
let id = 1;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[0..2]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..2] },
|
||||||
json["initial_versions"][0]["client_side"] = json!("optional");
|
{ "op": "add", "path": "/initial_versions/0/client_side", "value": "optional" },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 2
|
// Test project 2
|
||||||
let id = 2;
|
let id = 2;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[0..2]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..2] },
|
||||||
json["initial_versions"][0]["server_side"] = json!("required");
|
{ "op": "add", "path": "/initial_versions/0/server_side", "value": "required" },
|
||||||
json["title"] = json!("Mysterious Project");
|
{ "op": "add", "path": "/title", "value": "Mysterious Project" },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 3
|
// Test project 3
|
||||||
let id = 3;
|
let id = 3;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[0..3]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..3] },
|
||||||
json["initial_versions"][0]["server_side"] = json!("required");
|
{ "op": "add", "path": "/initial_versions/0/server_side", "value": "required" },
|
||||||
json["initial_versions"][0]["game_versions"] = json!(["1.20.4"]);
|
{ "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.4"] },
|
||||||
json["title"] = json!("Mysterious Project");
|
{ "op": "add", "path": "/title", "value": "Mysterious Project" },
|
||||||
json["license_id"] = json!("LicenseRef-All-Rights-Reserved"); // closed source
|
{ "op": "add", "path": "/license_id", "value": "LicenseRef-All-Rights-Reserved" },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
FRIEND_USER_PAT,
|
FRIEND_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 4
|
// Test project 4
|
||||||
let id = 4;
|
let id = 4;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[0..3]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..3] },
|
||||||
json["initial_versions"][0]["client_side"] = json!("optional");
|
{ "op": "add", "path": "/initial_versions/0/client_side", "value": "optional" },
|
||||||
json["initial_versions"][0]["game_versions"] = json!(["1.20.5"]);
|
{ "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.5"] },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
true,
|
true,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 5
|
// Test project 5
|
||||||
let id = 5;
|
let id = 5;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[5..6]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[5..6] },
|
||||||
json["initial_versions"][0]["client_side"] = json!("optional");
|
{ "op": "add", "path": "/initial_versions/0/client_side", "value": "optional" },
|
||||||
json["initial_versions"][0]["game_versions"] = json!(["1.20.5"]);
|
{ "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.5"] },
|
||||||
json["license_id"] = json!("LGPL-3.0-or-later");
|
{ "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 6
|
// Test project 6
|
||||||
let id = 6;
|
let id = 6;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[5..6]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[5..6] },
|
||||||
json["initial_versions"][0]["client_side"] = json!("optional");
|
{ "op": "add", "path": "/initial_versions/0/client_side", "value": "optional" },
|
||||||
json["initial_versions"][0]["server_side"] = json!("required");
|
{ "op": "add", "path": "/initial_versions/0/server_side", "value": "required" },
|
||||||
json["license_id"] = json!("LGPL-3.0-or-later");
|
{ "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
FRIEND_USER_PAT,
|
FRIEND_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 7 (testing the search bug)
|
// 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 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.
|
// This means that a search for fabric + 1.20.3 or forge + 1.20.5 should not return this project.
|
||||||
let id = 7;
|
let id = 7;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[5..6]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[5..6] },
|
||||||
json["initial_versions"][0]["client_side"] = json!("optional");
|
{ "op": "add", "path": "/initial_versions/0/client_side", "value": "optional" },
|
||||||
json["initial_versions"][0]["server_side"] = json!("required");
|
{ "op": "add", "path": "/initial_versions/0/server_side", "value": "required" },
|
||||||
json["license_id"] = json!("LGPL-3.0-or-later");
|
{ "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" },
|
||||||
json["initial_versions"][0]["loaders"] = json!(["forge"]);
|
{ "op": "add", "path": "/initial_versions/0/loaders", "value": ["forge"] },
|
||||||
json["initial_versions"][0]["game_versions"] = json!(["1.20.2"]);
|
{ "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.2"] },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Await all project creation
|
// Await all project creation
|
||||||
@@ -203,15 +202,17 @@ async fn search_projects() {
|
|||||||
|
|
||||||
// Create a second version for project 7
|
// Create a second version for project 7
|
||||||
let project_7 = api
|
let project_7 = api
|
||||||
.get_project_deserialized(&format!("{test_name}-searchable-project-7"), USER_USER_PAT)
|
.get_project_deserialized_common(
|
||||||
|
&format!("{test_name}-searchable-project-7"),
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
api.add_public_version(
|
api.add_public_version(
|
||||||
get_public_version_creation_data(
|
|
||||||
project_7.id,
|
project_7.id,
|
||||||
"1.0.0",
|
"1.0.0",
|
||||||
TestFile::build_random_jar(),
|
TestFile::build_random_jar(),
|
||||||
None::<fn(&mut serde_json::Value)>,
|
None,
|
||||||
),
|
None,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
@@ -288,7 +289,11 @@ async fn search_projects() {
|
|||||||
let test_name = test_name.clone();
|
let test_name = test_name.clone();
|
||||||
async move {
|
async move {
|
||||||
let projects = api
|
let projects = api
|
||||||
.search_deserialized(Some(&test_name), Some(facets.clone()), USER_USER_PAT)
|
.search_deserialized_common(
|
||||||
|
Some(&test_name),
|
||||||
|
Some(facets.clone()),
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
let mut found_project_ids: Vec<u64> = projects
|
let mut found_project_ids: Vec<u64> = projects
|
||||||
.hits
|
.hits
|
||||||
@@ -301,7 +306,6 @@ async fn search_projects() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
use common::environment::TestEnvironment;
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use common::environment::with_test_environment_all;
|
||||||
|
|
||||||
|
use crate::common::api_common::ApiTags;
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn get_tags() {
|
async fn get_tags() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
|
let loaders = api.get_loaders_deserialized_common().await;
|
||||||
let loaders = api.get_loaders_deserialized().await;
|
let categories = api.get_categories_deserialized_common().await;
|
||||||
let categories = api.get_categories_deserialized().await;
|
|
||||||
|
|
||||||
let loader_names = loaders.into_iter().map(|x| x.name).collect::<HashSet<_>>();
|
let loader_names = loaders.into_iter().map(|x| x.name).collect::<HashSet<_>>();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -39,6 +41,6 @@ async fn get_tags() {
|
|||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.collect()
|
.collect()
|
||||||
);
|
);
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::common::database::*;
|
use crate::common::database::*;
|
||||||
use crate::common::environment::TestEnvironment;
|
|
||||||
use actix_web::test;
|
use actix_web::test;
|
||||||
|
use common::environment::with_test_environment_all;
|
||||||
use labrinth::models::teams::{OrganizationPermissions, ProjectPermissions};
|
use labrinth::models::teams::{OrganizationPermissions, ProjectPermissions};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ mod common;
|
|||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_get_team() {
|
async fn test_get_team() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
||||||
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
||||||
let zeta_organization_id = &test_env
|
let zeta_organization_id = &test_env
|
||||||
@@ -129,15 +129,14 @@ async fn test_get_team() {
|
|||||||
assert!(!friend_user["permissions"].is_null());
|
assert!(!friend_user["permissions"].is_null());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_get_team_project_orgs() {
|
async fn test_get_team_project_orgs() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
||||||
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
||||||
let zeta_organization_id = &test_env
|
let zeta_organization_id = &test_env
|
||||||
@@ -201,16 +200,15 @@ async fn test_get_team_project_orgs() {
|
|||||||
let value: serde_json::Value = test::read_body_json(resp).await;
|
let value: serde_json::Value = test::read_body_json(resp).await;
|
||||||
let members = value.as_array().unwrap();
|
let members = value.as_array().unwrap();
|
||||||
assert_eq!(members.len(), 2);
|
assert_eq!(members.len(), 2);
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// edit team member (Varying permissions, varying roles)
|
// edit team member (Varying permissions, varying roles)
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_patch_project_team_member() {
|
async fn test_patch_project_team_member() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
||||||
|
|
||||||
// Edit team as admin/mod but not a part of the team should be OK
|
// Edit team as admin/mod but not a part of the team should be OK
|
||||||
@@ -357,15 +355,14 @@ async fn test_patch_project_team_member() {
|
|||||||
assert_eq!(member["role"], "member");
|
assert_eq!(member["role"], "member");
|
||||||
assert_eq!(member["ordering"], 5);
|
assert_eq!(member["ordering"], 5);
|
||||||
|
|
||||||
// Cleanup test db
|
}).await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// edit team member (Varying permissions, varying roles)
|
// edit team member (Varying permissions, varying roles)
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_patch_organization_team_member() {
|
async fn test_patch_organization_team_member() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let zeta_team_id = &test_env.dummy.as_ref().unwrap().organization_zeta.team_id;
|
let zeta_team_id = &test_env.dummy.as_ref().unwrap().organization_zeta.team_id;
|
||||||
|
|
||||||
// Edit team as admin/mod but not a part of the team should be OK
|
// Edit team as admin/mod but not a part of the team should be OK
|
||||||
@@ -499,15 +496,14 @@ async fn test_patch_organization_team_member() {
|
|||||||
assert_eq!(member["role"], "member");
|
assert_eq!(member["role"], "member");
|
||||||
assert_eq!(member["ordering"], 5);
|
assert_eq!(member["ordering"], 5);
|
||||||
|
|
||||||
// Cleanup test db
|
}).await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// trasnfer ownership (requires being owner, etc)
|
// trasnfer ownership (requires being owner, etc)
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn transfer_ownership() {
|
async fn transfer_ownership() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
||||||
|
|
||||||
// Cannot set friend as owner (not a member)
|
// Cannot set friend as owner (not a member)
|
||||||
@@ -603,9 +599,8 @@ async fn transfer_ownership() {
|
|||||||
|
|
||||||
let resp = test_env.call(req).await;
|
let resp = test_env.call(req).await;
|
||||||
assert_eq!(resp.status(), 401);
|
assert_eq!(resp.status(), 401);
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test is currently not working.
|
// This test is currently not working.
|
||||||
@@ -617,7 +612,7 @@ async fn transfer_ownership() {
|
|||||||
// // This is because project-team permission overrriding must be possible, and this overriding can decrease the number of permissions a user has.
|
// // This is because project-team permission overrriding must be possible, and this overriding can decrease the number of permissions a user has.
|
||||||
|
|
||||||
// let test_env = TestEnvironment::build(None).await;
|
// let test_env = TestEnvironment::build(None).await;
|
||||||
// let api = &test_env.v3;
|
// let api = &test_env.api;
|
||||||
|
|
||||||
// let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
// let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
||||||
// let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
// let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
|
use crate::common::api_common::{ApiProject, ApiTeams};
|
||||||
|
use common::dummy_data::TestFile;
|
||||||
use common::{
|
use common::{
|
||||||
database::{FRIEND_USER_ID, FRIEND_USER_PAT, USER_USER_ID, USER_USER_PAT},
|
database::{FRIEND_USER_ID, FRIEND_USER_PAT, USER_USER_ID, USER_USER_PAT},
|
||||||
environment::with_test_environment,
|
environment::with_test_environment_all,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::common::api_v3::request_data::get_public_project_creation_data;
|
|
||||||
use common::dummy_data::TestFile;
|
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
// user GET (permissions, different users)
|
// user GET (permissions, different users)
|
||||||
@@ -19,20 +18,17 @@ mod common;
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn get_user_projects_after_creating_project_returns_new_project() {
|
pub async fn get_user_projects_after_creating_project_returns_new_project() {
|
||||||
with_test_environment(|test_env| async move {
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let api = test_env.v3;
|
let api = test_env.api;
|
||||||
api.get_user_projects_deserialized(USER_USER_ID, USER_USER_PAT)
|
api.get_user_projects_deserialized_common(USER_USER_ID, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let (project, _) = api
|
let (project, _) = api
|
||||||
.add_public_project(
|
.add_public_project("slug", Some(TestFile::BasicMod), None, USER_USER_PAT)
|
||||||
get_public_project_creation_data("slug", Some(TestFile::BasicMod)),
|
|
||||||
USER_USER_PAT,
|
|
||||||
)
|
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let resp_projects = api
|
let resp_projects = api
|
||||||
.get_user_projects_deserialized(USER_USER_ID, USER_USER_PAT)
|
.get_user_projects_deserialized_common(USER_USER_ID, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert!(resp_projects.iter().any(|p| p.id == project.id));
|
assert!(resp_projects.iter().any(|p| p.id == project.id));
|
||||||
})
|
})
|
||||||
@@ -41,22 +37,19 @@ pub async fn get_user_projects_after_creating_project_returns_new_project() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn get_user_projects_after_deleting_project_shows_removal() {
|
pub async fn get_user_projects_after_deleting_project_shows_removal() {
|
||||||
with_test_environment(|test_env| async move {
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let api = test_env.v3;
|
let api = test_env.api;
|
||||||
let (project, _) = api
|
let (project, _) = api
|
||||||
.add_public_project(
|
.add_public_project("iota", Some(TestFile::BasicMod), None, USER_USER_PAT)
|
||||||
get_public_project_creation_data("iota", Some(TestFile::BasicMod)),
|
|
||||||
USER_USER_PAT,
|
|
||||||
)
|
|
||||||
.await;
|
.await;
|
||||||
api.get_user_projects_deserialized(USER_USER_ID, USER_USER_PAT)
|
api.get_user_projects_deserialized_common(USER_USER_ID, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
api.remove_project(project.slug.as_ref().unwrap(), USER_USER_PAT)
|
api.remove_project(project.slug.as_ref().unwrap(), USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let resp_projects = api
|
let resp_projects = api
|
||||||
.get_user_projects_deserialized(USER_USER_ID, USER_USER_PAT)
|
.get_user_projects_deserialized_common(USER_USER_ID, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert!(!resp_projects.iter().any(|p| p.id == project.id));
|
assert!(!resp_projects.iter().any(|p| p.id == project.id));
|
||||||
})
|
})
|
||||||
@@ -65,11 +58,11 @@ pub async fn get_user_projects_after_deleting_project_shows_removal() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn get_user_projects_after_joining_team_shows_team_projects() {
|
pub async fn get_user_projects_after_joining_team_shows_team_projects() {
|
||||||
with_test_environment(|test_env| async move {
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
||||||
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
||||||
let api = test_env.v3;
|
let api = test_env.api;
|
||||||
api.get_user_projects_deserialized(FRIEND_USER_ID, FRIEND_USER_PAT)
|
api.get_user_projects_deserialized_common(FRIEND_USER_ID, FRIEND_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
api.add_user_to_team(alpha_team_id, FRIEND_USER_ID, None, None, USER_USER_PAT)
|
api.add_user_to_team(alpha_team_id, FRIEND_USER_ID, None, None, USER_USER_PAT)
|
||||||
@@ -77,7 +70,7 @@ pub async fn get_user_projects_after_joining_team_shows_team_projects() {
|
|||||||
api.join_team(alpha_team_id, FRIEND_USER_PAT).await;
|
api.join_team(alpha_team_id, FRIEND_USER_PAT).await;
|
||||||
|
|
||||||
let projects = api
|
let projects = api
|
||||||
.get_user_projects_deserialized(FRIEND_USER_ID, FRIEND_USER_PAT)
|
.get_user_projects_deserialized_common(FRIEND_USER_ID, FRIEND_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert!(projects
|
assert!(projects
|
||||||
.iter()
|
.iter()
|
||||||
@@ -88,21 +81,21 @@ pub async fn get_user_projects_after_joining_team_shows_team_projects() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn get_user_projects_after_leaving_team_shows_no_team_projects() {
|
pub async fn get_user_projects_after_leaving_team_shows_no_team_projects() {
|
||||||
with_test_environment(|test_env| async move {
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
let alpha_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
||||||
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
||||||
let api = test_env.v3;
|
let api = test_env.api;
|
||||||
api.add_user_to_team(alpha_team_id, FRIEND_USER_ID, None, None, USER_USER_PAT)
|
api.add_user_to_team(alpha_team_id, FRIEND_USER_ID, None, None, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
api.join_team(alpha_team_id, FRIEND_USER_PAT).await;
|
api.join_team(alpha_team_id, FRIEND_USER_PAT).await;
|
||||||
api.get_user_projects_deserialized(FRIEND_USER_ID, FRIEND_USER_PAT)
|
api.get_user_projects_deserialized_common(FRIEND_USER_ID, FRIEND_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
api.remove_from_team(alpha_team_id, FRIEND_USER_ID, USER_USER_PAT)
|
api.remove_from_team(alpha_team_id, FRIEND_USER_ID, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let projects = api
|
let projects = api
|
||||||
.get_user_projects_deserialized(FRIEND_USER_ID, FRIEND_USER_PAT)
|
.get_user_projects_deserialized_common(FRIEND_USER_ID, FRIEND_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert!(!projects
|
assert!(!projects
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use crate::common::{
|
use crate::common::{
|
||||||
api_v2::request_data,
|
api_common::ApiProject,
|
||||||
|
api_v2::ApiV2,
|
||||||
database::{ENEMY_USER_PAT, FRIEND_USER_ID, FRIEND_USER_PAT, MOD_USER_PAT, USER_USER_PAT},
|
database::{ENEMY_USER_PAT, FRIEND_USER_ID, FRIEND_USER_PAT, MOD_USER_PAT, USER_USER_PAT},
|
||||||
dummy_data::{TestFile, DUMMY_CATEGORIES},
|
dummy_data::{TestFile, DUMMY_CATEGORIES},
|
||||||
environment::TestEnvironment,
|
environment::{with_test_environment, TestEnvironment},
|
||||||
permissions::{PermissionsTest, PermissionsTestContext},
|
permissions::{PermissionsTest, PermissionsTestContext},
|
||||||
};
|
};
|
||||||
use actix_web::test;
|
use actix_web::test;
|
||||||
@@ -16,33 +17,23 @@ use serde_json::json;
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_project_type_sanity() {
|
async fn test_project_type_sanity() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV2>| async move {
|
||||||
let api = &test_env.v2;
|
let api = &test_env.api;
|
||||||
|
|
||||||
// Perform all other patch tests on both 'mod' and 'modpack'
|
// Perform all other patch tests on both 'mod' and 'modpack'
|
||||||
let test_creation_mod = request_data::get_public_project_creation_data(
|
for (mod_or_modpack, slug, file) in [
|
||||||
"test-mod",
|
("mod", "test-mod", TestFile::build_random_jar()),
|
||||||
Some(TestFile::build_random_jar()),
|
("modpack", "test-modpack", TestFile::build_random_mrpack()),
|
||||||
);
|
|
||||||
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),
|
|
||||||
] {
|
] {
|
||||||
let (test_project, test_version) = api
|
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;
|
.await;
|
||||||
let test_project_slug = test_project.slug.as_ref().unwrap();
|
let test_project_slug = test_project.slug.as_ref().unwrap();
|
||||||
|
|
||||||
assert_eq!(test_project.project_type, mod_or_modpack);
|
// TODO:
|
||||||
|
// assert_eq!(test_project.project_type, mod_or_modpack);
|
||||||
assert_eq!(test_project.loaders, vec!["fabric"]);
|
assert_eq!(test_project.loaders, vec!["fabric"]);
|
||||||
assert_eq!(
|
assert_eq!(test_version[0].loaders, vec!["fabric"]);
|
||||||
test_version[0].loaders.iter().map(|x| &x.0).collect_vec(),
|
|
||||||
vec!["fabric"]
|
|
||||||
);
|
|
||||||
|
|
||||||
let project = api
|
let project = api
|
||||||
.get_project_deserialized(test_project_slug, USER_USER_PAT)
|
.get_project_deserialized(test_project_slug, USER_USER_PAT)
|
||||||
@@ -61,13 +52,15 @@ async fn test_project_type_sanity() {
|
|||||||
|
|
||||||
// TODO: as we get more complicated strucures with v3 testing, and alpha/beta get more complicated, we should add more tests here,
|
// TODO: as we get more complicated strucures with v3 testing, and alpha/beta get more complicated, we should add more tests here,
|
||||||
// to ensure that projects created with v3 routes are still valid and work with v3 routes.
|
// to ensure that projects created with v3 routes are still valid and work with v3 routes.
|
||||||
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_add_remove_project() {
|
async fn test_add_remove_project() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV2>| async move {
|
||||||
let api = &test_env.v2;
|
let api = &test_env.api;
|
||||||
|
|
||||||
// Generate test project data.
|
// Generate test project data.
|
||||||
let mut json_data = json!(
|
let mut json_data = json!(
|
||||||
@@ -217,7 +210,7 @@ async fn test_add_remove_project() {
|
|||||||
let id = project.id.to_string();
|
let id = project.id.to_string();
|
||||||
|
|
||||||
// Remove the project
|
// Remove the project
|
||||||
let resp = test_env.v2.remove_project("demo", USER_USER_PAT).await;
|
let resp = test_env.api.remove_project("demo", USER_USER_PAT).await;
|
||||||
assert_eq!(resp.status(), 204);
|
assert_eq!(resp.status(), 204);
|
||||||
|
|
||||||
// Confirm that the project is gone from the cache
|
// Confirm that the project is gone from the cache
|
||||||
@@ -242,14 +235,13 @@ async fn test_add_remove_project() {
|
|||||||
// Old slug no longer works
|
// Old slug no longer works
|
||||||
let resp = api.get_project("demo", USER_USER_PAT).await;
|
let resp = api.get_project("demo", USER_USER_PAT).await;
|
||||||
assert_eq!(resp.status(), 404);
|
assert_eq!(resp.status(), 404);
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn permissions_upload_version() {
|
async fn permissions_upload_version() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV2>| async move {
|
||||||
let alpha_project_id = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
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_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_team_id = &test_env.dummy.as_ref().unwrap().project_alpha.team_id;
|
||||||
@@ -370,14 +362,14 @@ async fn permissions_upload_version() {
|
|||||||
.simple_project_permissions_test(delete_version, req_gen)
|
.simple_project_permissions_test(delete_version, req_gen)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn test_patch_project() {
|
pub async fn test_patch_project() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV2>| async move {
|
||||||
let api = &test_env.v2;
|
let api = &test_env.api;
|
||||||
|
|
||||||
let alpha_project_slug = &test_env.dummy.as_ref().unwrap().project_alpha.project_slug;
|
let alpha_project_slug = &test_env.dummy.as_ref().unwrap().project_alpha.project_slug;
|
||||||
let beta_project_slug = &test_env.dummy.as_ref().unwrap().project_beta.project_slug;
|
let beta_project_slug = &test_env.dummy.as_ref().unwrap().project_beta.project_slug;
|
||||||
@@ -531,7 +523,6 @@ pub async fn test_patch_project() {
|
|||||||
assert_eq!(project.client_side.as_str(), "optional");
|
assert_eq!(project.client_side.as_str(), "optional");
|
||||||
assert_eq!(project.server_side.as_str(), "required");
|
assert_eq!(project.server_side.as_str(), "required");
|
||||||
assert_eq!(project.donation_urls.unwrap()[0].url, "https://patreon.com");
|
assert_eq!(project.donation_urls.unwrap()[0].url, "https://patreon.com");
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use crate::common::api_v2::ApiV2;
|
||||||
|
use crate::common::environment::with_test_environment;
|
||||||
use crate::common::environment::TestEnvironment;
|
use crate::common::environment::TestEnvironment;
|
||||||
use crate::common::scopes::ScopeTest;
|
use crate::common::scopes::ScopeTest;
|
||||||
use actix_web::test;
|
use actix_web::test;
|
||||||
@@ -10,8 +12,7 @@ use serde_json::json;
|
|||||||
// Project version creation scopes
|
// Project version creation scopes
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn project_version_create_scopes() {
|
pub async fn project_version_create_scopes() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV2>| async move {
|
||||||
|
|
||||||
// Create project
|
// Create project
|
||||||
let create_project = Scopes::PROJECT_CREATE;
|
let create_project = Scopes::PROJECT_CREATE;
|
||||||
let json_data = json!(
|
let json_data = json!(
|
||||||
@@ -103,7 +104,6 @@ pub async fn project_version_create_scopes() {
|
|||||||
.test(req_gen, create_version)
|
.test(req_gen, create_version)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
use crate::common::api_v2::request_data;
|
use crate::common::api_common::Api;
|
||||||
use crate::common::api_v2::request_data::get_public_version_creation_data;
|
use crate::common::api_common::ApiProject;
|
||||||
use crate::common::api_v2::request_data::ProjectCreationRequestData;
|
use crate::common::api_common::ApiVersion;
|
||||||
|
use crate::common::api_v2::ApiV2;
|
||||||
use crate::common::database::*;
|
use crate::common::database::*;
|
||||||
use crate::common::dummy_data::TestFile;
|
use crate::common::dummy_data::TestFile;
|
||||||
use crate::common::dummy_data::DUMMY_CATEGORIES;
|
use crate::common::dummy_data::DUMMY_CATEGORIES;
|
||||||
|
use crate::common::environment::with_test_environment;
|
||||||
use crate::common::environment::TestEnvironment;
|
use crate::common::environment::TestEnvironment;
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
use labrinth::models::ids::base62_impl::parse_base62;
|
use labrinth::models::ids::base62_impl::parse_base62;
|
||||||
@@ -17,8 +19,8 @@ async fn search_projects() {
|
|||||||
// It should drastically simplify this function
|
// It should drastically simplify this function
|
||||||
|
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(Some(10)).await;
|
with_test_environment(Some(10), |test_env: TestEnvironment<ApiV2>| async move {
|
||||||
let api = &test_env.v2;
|
let api = &test_env.api;
|
||||||
let test_name = test_env.db.database_name.clone();
|
let test_name = test_env.db.database_name.clone();
|
||||||
|
|
||||||
// Add dummy projects of various categories for searchability
|
// Add dummy projects of various categories for searchability
|
||||||
@@ -28,7 +30,7 @@ async fn search_projects() {
|
|||||||
|id: u64,
|
|id: u64,
|
||||||
pat: &'static str,
|
pat: &'static str,
|
||||||
is_modpack: bool,
|
is_modpack: bool,
|
||||||
modify_json: Box<dyn Fn(&mut serde_json::Value)>| {
|
modify_json: Option<json_patch::Patch>| {
|
||||||
let slug = format!("{test_name}-searchable-project-{id}");
|
let slug = format!("{test_name}-searchable-project-{id}");
|
||||||
|
|
||||||
let jar = if is_modpack {
|
let jar = if is_modpack {
|
||||||
@@ -36,22 +38,9 @@ async fn search_projects() {
|
|||||||
} else {
|
} else {
|
||||||
TestFile::build_random_jar()
|
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 {
|
async move {
|
||||||
|
// Add a project- simple, should work.
|
||||||
|
let req = api.add_public_project(&slug, Some(jar), modify_json, pat);
|
||||||
let (project, _) = req.await;
|
let (project, _) = req.await;
|
||||||
|
|
||||||
// Approve, so that the project is searchable
|
// Approve, so that the project is searchable
|
||||||
@@ -71,122 +60,130 @@ async fn search_projects() {
|
|||||||
|
|
||||||
// Test project 0
|
// Test project 0
|
||||||
let id = 0;
|
let id = 0;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[4..6]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[4..6] },
|
||||||
json["server_side"] = json!("required");
|
{ "op": "add", "path": "/server_side", "value": "required" },
|
||||||
json["license_id"] = json!("LGPL-3.0-or-later");
|
{ "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 1
|
// Test project 1
|
||||||
let id = 1;
|
let id = 1;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[0..2]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..2] },
|
||||||
json["client_side"] = json!("optional");
|
{ "op": "add", "path": "/client_side", "value": "optional" },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 2
|
// Test project 2
|
||||||
let id = 2;
|
let id = 2;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[0..2]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..2] },
|
||||||
json["server_side"] = json!("required");
|
{ "op": "add", "path": "/server_side", "value": "required" },
|
||||||
json["title"] = json!("Mysterious Project");
|
{ "op": "add", "path": "/title", "value": "Mysterious Project" },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 3
|
// Test project 3
|
||||||
let id = 3;
|
let id = 3;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[0..3]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..3] },
|
||||||
json["server_side"] = json!("required");
|
{ "op": "add", "path": "/server_side", "value": "required" },
|
||||||
json["initial_versions"][0]["game_versions"] = json!(["1.20.4"]);
|
{ "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.4"] },
|
||||||
json["title"] = json!("Mysterious Project");
|
{ "op": "add", "path": "/title", "value": "Mysterious Project" },
|
||||||
json["license_id"] = json!("LicenseRef-All-Rights-Reserved"); // closed source
|
{ "op": "add", "path": "/license_id", "value": "LicenseRef-All-Rights-Reserved" },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
FRIEND_USER_PAT,
|
FRIEND_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 4
|
// Test project 4
|
||||||
let id = 4;
|
let id = 4;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[0..3]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[0..3] },
|
||||||
json["client_side"] = json!("optional");
|
{ "op": "add", "path": "/client_side", "value": "optional" },
|
||||||
json["initial_versions"][0]["game_versions"] = json!(["1.20.5"]);
|
{ "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.5"] },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
true,
|
true,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 5
|
// Test project 5
|
||||||
let id = 5;
|
let id = 5;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[5..6]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[5..6] },
|
||||||
json["client_side"] = json!("optional");
|
{ "op": "add", "path": "/client_side", "value": "optional" },
|
||||||
json["initial_versions"][0]["game_versions"] = json!(["1.20.5"]);
|
{ "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.5"] },
|
||||||
json["license_id"] = json!("LGPL-3.0-or-later");
|
{ "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 6
|
// Test project 6
|
||||||
let id = 6;
|
let id = 6;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[5..6]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[5..6] },
|
||||||
json["client_side"] = json!("optional");
|
{ "op": "add", "path": "/client_side", "value": "optional" },
|
||||||
json["server_side"] = json!("required");
|
{ "op": "add", "path": "/server_side", "value": "required" },
|
||||||
json["license_id"] = json!("LGPL-3.0-or-later");
|
{ "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
FRIEND_USER_PAT,
|
FRIEND_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Test project 7 (testing the search bug)
|
// 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 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.
|
// This means that a search for fabric + 1.20.3 or forge + 1.20.5 should not return this project.
|
||||||
let id = 7;
|
let id = 7;
|
||||||
let modify_json = |json: &mut serde_json::Value| {
|
let modify_json = serde_json::from_value(json!([
|
||||||
json["categories"] = json!(DUMMY_CATEGORIES[5..6]);
|
{ "op": "add", "path": "/categories", "value": DUMMY_CATEGORIES[5..6] },
|
||||||
json["client_side"] = json!("optional");
|
{ "op": "add", "path": "/client_side", "value": "optional" },
|
||||||
json["server_side"] = json!("required");
|
{ "op": "add", "path": "/server_side", "value": "required" },
|
||||||
json["license_id"] = json!("LGPL-3.0-or-later");
|
{ "op": "add", "path": "/license_id", "value": "LGPL-3.0-or-later" },
|
||||||
json["initial_versions"][0]["loaders"] = json!(["forge"]);
|
{ "op": "add", "path": "/initial_versions/0/loaders", "value": ["forge"] },
|
||||||
json["initial_versions"][0]["game_versions"] = json!(["1.20.2"]);
|
{ "op": "add", "path": "/initial_versions/0/game_versions", "value": ["1.20.2"] },
|
||||||
};
|
]))
|
||||||
|
.unwrap();
|
||||||
project_creation_futures.push(create_async_future(
|
project_creation_futures.push(create_async_future(
|
||||||
id,
|
id,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
false,
|
false,
|
||||||
Box::new(modify_json),
|
Some(modify_json),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Await all project creation
|
// Await all project creation
|
||||||
@@ -204,7 +201,11 @@ async fn search_projects() {
|
|||||||
.get_project_deserialized(&format!("{test_name}-searchable-project-7"), USER_USER_PAT)
|
.get_project_deserialized(&format!("{test_name}-searchable-project-7"), USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
api.add_public_version(
|
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,
|
USER_USER_PAT,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
@@ -280,7 +281,11 @@ async fn search_projects() {
|
|||||||
let test_name = test_name.clone();
|
let test_name = test_name.clone();
|
||||||
async move {
|
async move {
|
||||||
let projects = api
|
let projects = api
|
||||||
.search_deserialized(Some(&test_name), Some(facets.clone()), USER_USER_PAT)
|
.search_deserialized_common(
|
||||||
|
Some(&test_name),
|
||||||
|
Some(facets.clone()),
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
let mut found_project_ids: Vec<u64> = projects
|
let mut found_project_ids: Vec<u64> = projects
|
||||||
.hits
|
.hits
|
||||||
@@ -293,7 +298,6 @@ async fn search_projects() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
use crate::common::environment::TestEnvironment;
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use crate::common::{
|
||||||
|
api_v2::ApiV2,
|
||||||
|
environment::{with_test_environment, TestEnvironment},
|
||||||
|
};
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn get_tags() {
|
async fn get_tags() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV2>| async move {
|
||||||
let api = &test_env.v2;
|
let api = &test_env.api;
|
||||||
|
|
||||||
let game_versions = api.get_game_versions_deserialized().await;
|
let game_versions = api.get_game_versions_deserialized().await;
|
||||||
let loaders = api.get_loaders_deserialized().await;
|
let loaders = api.get_loaders_deserialized().await;
|
||||||
let side_types = api.get_side_types_deserialized().await;
|
let side_types = api.get_side_types_deserialized().await;
|
||||||
@@ -69,6 +72,6 @@ async fn get_tags() {
|
|||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.collect()
|
.collect()
|
||||||
);
|
);
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,24 @@
|
|||||||
use actix_web::test;
|
use actix_web::test;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use labrinth::models::projects::{ProjectId, VersionId};
|
use labrinth::models::projects::VersionId;
|
||||||
use labrinth::{
|
use labrinth::{
|
||||||
models::{
|
models::projects::{Loader, VersionStatus, VersionType},
|
||||||
ids::base62_impl::parse_base62,
|
|
||||||
projects::{Loader, VersionStatus, VersionType},
|
|
||||||
},
|
|
||||||
routes::v2::version_file::FileUpdateData,
|
routes::v2::version_file::FileUpdateData,
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::common::api_v2::request_data::get_public_version_creation_data;
|
use crate::common::api_common::{ApiProject, ApiVersion};
|
||||||
|
use crate::common::api_v2::ApiV2;
|
||||||
|
use crate::common::environment::{with_test_environment, TestEnvironment};
|
||||||
use crate::common::{
|
use crate::common::{
|
||||||
database::{ENEMY_USER_PAT, USER_USER_PAT},
|
database::{ENEMY_USER_PAT, USER_USER_PAT},
|
||||||
dummy_data::TestFile,
|
dummy_data::TestFile,
|
||||||
environment::TestEnvironment,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn test_patch_version() {
|
pub async fn test_patch_version() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV2>| async move {
|
||||||
let api = &test_env.v2;
|
let api = &test_env.api;
|
||||||
|
|
||||||
let alpha_version_id = &test_env.dummy.as_ref().unwrap().project_alpha.version_id;
|
let alpha_version_id = &test_env.dummy.as_ref().unwrap().project_alpha.version_id;
|
||||||
|
|
||||||
@@ -125,18 +123,23 @@ pub async fn test_patch_version() {
|
|||||||
.await;
|
.await;
|
||||||
assert_eq!(version.game_versions, vec!["1.20.1", "1.20.2", "1.20.4"]); // From last patch
|
assert_eq!(version.game_versions, vec!["1.20.1", "1.20.2", "1.20.4"]); // From last patch
|
||||||
assert_eq!(version.loaders, vec![Loader("fabric".to_string())]);
|
assert_eq!(version.loaders, vec![Loader("fabric".to_string())]);
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn version_updates() {
|
async fn version_updates() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(None, |test_env: TestEnvironment<ApiV2>| async move {
|
||||||
let api = &test_env.v2;
|
let api = &test_env.api;
|
||||||
|
|
||||||
let alpha_project_id: &String = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
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 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 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;
|
let alpha_version_hash = &test_env.dummy.as_ref().unwrap().project_alpha.file_hash;
|
||||||
@@ -165,7 +168,7 @@ async fn version_updates() {
|
|||||||
|
|
||||||
// When there is only the one version, there should be no updates
|
// When there is only the one version, there should be no updates
|
||||||
let version = api
|
let version = api
|
||||||
.get_update_from_hash_deserialized(
|
.get_update_from_hash_deserialized_common(
|
||||||
alpha_version_hash,
|
alpha_version_hash,
|
||||||
"sha1",
|
"sha1",
|
||||||
None,
|
None,
|
||||||
@@ -177,7 +180,7 @@ async fn version_updates() {
|
|||||||
assert_eq!(&version.id.to_string(), alpha_version_id);
|
assert_eq!(&version.id.to_string(), alpha_version_id);
|
||||||
|
|
||||||
let versions = api
|
let versions = api
|
||||||
.update_files_deserialized(
|
.update_files_deserialized_common(
|
||||||
"sha1",
|
"sha1",
|
||||||
vec![alpha_version_hash.to_string()],
|
vec![alpha_version_hash.to_string()],
|
||||||
None,
|
None,
|
||||||
@@ -220,12 +223,12 @@ async fn version_updates() {
|
|||||||
.iter()
|
.iter()
|
||||||
{
|
{
|
||||||
let version = api
|
let version = api
|
||||||
.add_public_version(
|
.add_public_version_deserialized_common(
|
||||||
get_public_version_creation_data(
|
alpha_project_id_parsed,
|
||||||
ProjectId(parse_base62(alpha_project_id).unwrap()),
|
|
||||||
version_number,
|
version_number,
|
||||||
TestFile::build_random_jar(),
|
TestFile::build_random_jar(),
|
||||||
),
|
None,
|
||||||
|
None,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
@@ -266,7 +269,7 @@ async fn version_updates() {
|
|||||||
|
|
||||||
// update_files
|
// update_files
|
||||||
let versions = api
|
let versions = api
|
||||||
.update_files_deserialized(
|
.update_files_deserialized_common(
|
||||||
"sha1",
|
"sha1",
|
||||||
vec![alpha_version_hash.to_string()],
|
vec![alpha_version_hash.to_string()],
|
||||||
loaders.clone(),
|
loaders.clone(),
|
||||||
@@ -378,7 +381,7 @@ async fn version_updates() {
|
|||||||
// We do a couple small tests for get_project_versions_deserialized as well
|
// We do a couple small tests for get_project_versions_deserialized as well
|
||||||
// TODO: expand this more.
|
// TODO: expand this more.
|
||||||
let versions = api
|
let versions = api
|
||||||
.get_project_versions_deserialized(
|
.get_project_versions_deserialized_common(
|
||||||
alpha_project_id,
|
alpha_project_id,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@@ -391,7 +394,7 @@ async fn version_updates() {
|
|||||||
.await;
|
.await;
|
||||||
assert_eq!(versions.len(), 4);
|
assert_eq!(versions.len(), 4);
|
||||||
let versions = api
|
let versions = api
|
||||||
.get_project_versions_deserialized(
|
.get_project_versions_deserialized_common(
|
||||||
alpha_project_id,
|
alpha_project_id,
|
||||||
None,
|
None,
|
||||||
Some(vec!["forge".to_string()]),
|
Some(vec!["forge".to_string()]),
|
||||||
@@ -403,7 +406,61 @@ async fn version_updates() {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(versions.len(), 1);
|
assert_eq!(versions.len(), 1);
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn add_version_project_types_v2() {
|
||||||
|
with_test_environment(None, |test_env: TestEnvironment<ApiV2>| async move {
|
||||||
|
// Since v2 no longer keeps project_type at the project level but the version level,
|
||||||
|
// we have to test that the project_type is set correctly when adding a version, if its done in separate requests.
|
||||||
|
let api = &test_env.api;
|
||||||
|
|
||||||
|
// Create a project in v2 with project_type = modpack, and no initial version set.
|
||||||
|
let (test_project, test_versions) = api
|
||||||
|
.add_public_project("test-modpack", None, None, USER_USER_PAT)
|
||||||
|
.await;
|
||||||
|
assert_eq!(test_versions.len(), 0); // No initial version set
|
||||||
|
|
||||||
|
// Get as v2 project
|
||||||
|
let test_project = api
|
||||||
|
.get_project_deserialized(&test_project.slug.unwrap(), USER_USER_PAT)
|
||||||
|
.await;
|
||||||
|
assert_eq!(test_project.project_type, ""); // 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");
|
||||||
|
|
||||||
|
// Create a version with a modpack file attached
|
||||||
|
let test_version = api
|
||||||
|
.add_public_version_deserialized_common(
|
||||||
|
test_project.id,
|
||||||
|
"1.0.0",
|
||||||
|
TestFile::build_random_mrpack(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// When we get the version as v2, it should display 'fabric' as the loader (and no project_type)
|
||||||
|
let test_version = api
|
||||||
|
.get_version_deserialized(&test_version.id.to_string(), USER_USER_PAT)
|
||||||
|
.await;
|
||||||
|
assert_eq!(test_version.loaders, vec![Loader("fabric".to_string())]);
|
||||||
|
|
||||||
|
// When we get the project as v2, it should display 'modpack' as the project_type, and 'fabric' as the loader
|
||||||
|
let test_project = api
|
||||||
|
.get_project_deserialized(&test_project.slug.unwrap(), USER_USER_PAT)
|
||||||
|
.await;
|
||||||
|
assert_eq!(test_project.project_type, "modpack");
|
||||||
|
assert_eq!(test_project.loaders, vec!["fabric"]);
|
||||||
|
|
||||||
|
// When we get the version as v3, it should display 'mrpack' as the loader, and 'modpack' as the project_type
|
||||||
|
// When we get the project as v3, it should display 'modpack' as the project_type, and 'mrpack' as the loader
|
||||||
|
|
||||||
|
// The project should be a modpack project
|
||||||
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|||||||
209
tests/version.rs
209
tests/version.rs
@@ -1,34 +1,37 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::common::api_common::ApiVersion;
|
||||||
|
use crate::common::database::*;
|
||||||
|
use crate::common::dummy_data::TestFile;
|
||||||
|
use crate::common::{asserts::assert_status, get_json_val_str};
|
||||||
|
use actix_http::StatusCode;
|
||||||
use actix_web::test;
|
use actix_web::test;
|
||||||
use common::environment::TestEnvironment;
|
use common::api_v3::ApiV3;
|
||||||
|
use common::asserts::assert_common_version_ids;
|
||||||
|
use common::database::USER_USER_PAT;
|
||||||
|
use common::environment::{with_test_environment, with_test_environment_all};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use labrinth::database::models::version_item::VERSIONS_NAMESPACE;
|
use labrinth::database::models::version_item::VERSIONS_NAMESPACE;
|
||||||
use labrinth::models::ids::base62_impl::parse_base62;
|
use labrinth::models::ids::base62_impl::parse_base62;
|
||||||
use labrinth::models::projects::{Loader, ProjectId, VersionId, VersionStatus, VersionType};
|
use labrinth::models::projects::{VersionId, VersionStatus, VersionType};
|
||||||
use labrinth::routes::v3::version_file::FileUpdateData;
|
use labrinth::routes::v3::version_file::FileUpdateData;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
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.
|
// importing common module.
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_get_version() {
|
async fn test_get_version() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
let alpha_project_id: &String = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
let alpha_project_id: &String = &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_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 beta_version_id = &test_env.dummy.as_ref().unwrap().project_beta.version_id;
|
||||||
|
|
||||||
// Perform request on dummy data
|
// Perform request on dummy data
|
||||||
let version = api
|
let version = api
|
||||||
.get_version_deserialized(alpha_version_id, USER_USER_PAT)
|
.get_version_deserialized_common(alpha_version_id, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(&version.project_id.to_string(), alpha_project_id);
|
assert_eq!(&version.project_id.to_string(), alpha_project_id);
|
||||||
assert_eq!(&version.id.to_string(), alpha_version_id);
|
assert_eq!(&version.id.to_string(), alpha_version_id);
|
||||||
@@ -66,18 +69,26 @@ async fn test_get_version() {
|
|||||||
assert_eq!(resp.status(), 200);
|
assert_eq!(resp.status(), 200);
|
||||||
let resp = api.get_version(beta_version_id, ENEMY_USER_PAT).await;
|
let resp = api.get_version(beta_version_id, ENEMY_USER_PAT).await;
|
||||||
assert_eq!(resp.status(), 404);
|
assert_eq!(resp.status(), 404);
|
||||||
|
})
|
||||||
// Cleanup test db
|
.await;
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn version_updates() {
|
async fn version_updates() {
|
||||||
// Test setup and dummy data
|
// Test setup and dummy data
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment(
|
||||||
let api = &test_env.v3;
|
None,
|
||||||
|
|test_env: common::environment::TestEnvironment<ApiV3>| 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: &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 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 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;
|
let alpha_version_hash = &test_env.dummy.as_ref().unwrap().project_alpha.file_hash;
|
||||||
@@ -85,13 +96,17 @@ async fn version_updates() {
|
|||||||
|
|
||||||
// Quick test, using get version from hash
|
// Quick test, using get version from hash
|
||||||
let version = api
|
let version = api
|
||||||
.get_version_from_hash_deserialized(alpha_version_hash, "sha1", USER_USER_PAT)
|
.get_version_from_hash_deserialized_common(
|
||||||
|
alpha_version_hash,
|
||||||
|
"sha1",
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(&version.id.to_string(), alpha_version_id);
|
assert_eq!(&version.id.to_string(), alpha_version_id);
|
||||||
|
|
||||||
// Get versions from hash
|
// Get versions from hash
|
||||||
let versions = api
|
let versions = api
|
||||||
.get_versions_from_hashes_deserialized(
|
.get_versions_from_hashes_deserialized_common(
|
||||||
&[alpha_version_hash.as_str(), beta_version_hash.as_str()],
|
&[alpha_version_hash.as_str(), beta_version_hash.as_str()],
|
||||||
"sha1",
|
"sha1",
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
@@ -106,7 +121,7 @@ async fn version_updates() {
|
|||||||
|
|
||||||
// When there is only the one version, there should be no updates
|
// When there is only the one version, there should be no updates
|
||||||
let version = api
|
let version = api
|
||||||
.get_update_from_hash_deserialized(
|
.get_update_from_hash_deserialized_common(
|
||||||
alpha_version_hash,
|
alpha_version_hash,
|
||||||
"sha1",
|
"sha1",
|
||||||
None,
|
None,
|
||||||
@@ -118,7 +133,7 @@ async fn version_updates() {
|
|||||||
assert_eq!(&version.id.to_string(), alpha_version_id);
|
assert_eq!(&version.id.to_string(), alpha_version_id);
|
||||||
|
|
||||||
let versions = api
|
let versions = api
|
||||||
.update_files_deserialized(
|
.update_files_deserialized_common(
|
||||||
"sha1",
|
"sha1",
|
||||||
vec![alpha_version_hash.to_string()],
|
vec![alpha_version_hash.to_string()],
|
||||||
None,
|
None,
|
||||||
@@ -162,12 +177,11 @@ async fn version_updates() {
|
|||||||
{
|
{
|
||||||
let version = api
|
let version = api
|
||||||
.add_public_version_deserialized(
|
.add_public_version_deserialized(
|
||||||
get_public_version_creation_data(
|
alpha_project_id_parsed,
|
||||||
ProjectId(parse_base62(alpha_project_id).unwrap()),
|
|
||||||
version_number,
|
version_number,
|
||||||
TestFile::build_random_jar(),
|
TestFile::build_random_jar(),
|
||||||
None::<fn(&mut serde_json::Value)>,
|
None,
|
||||||
),
|
None,
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
@@ -208,7 +222,7 @@ async fn version_updates() {
|
|||||||
|
|
||||||
// update_files
|
// update_files
|
||||||
let versions = api
|
let versions = api
|
||||||
.update_files_deserialized(
|
.update_files_deserialized_common(
|
||||||
"sha1",
|
"sha1",
|
||||||
vec![alpha_version_hash.to_string()],
|
vec![alpha_version_hash.to_string()],
|
||||||
loaders.clone(),
|
loaders.clone(),
|
||||||
@@ -331,7 +345,7 @@ async fn version_updates() {
|
|||||||
// We do a couple small tests for get_project_versions_deserialized as well
|
// We do a couple small tests for get_project_versions_deserialized as well
|
||||||
// TODO: expand this more.
|
// TODO: expand this more.
|
||||||
let versions = api
|
let versions = api
|
||||||
.get_project_versions_deserialized(
|
.get_project_versions_deserialized_common(
|
||||||
alpha_project_id,
|
alpha_project_id,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@@ -344,7 +358,7 @@ async fn version_updates() {
|
|||||||
.await;
|
.await;
|
||||||
assert_eq!(versions.len(), 4);
|
assert_eq!(versions.len(), 4);
|
||||||
let versions = api
|
let versions = api
|
||||||
.get_project_versions_deserialized(
|
.get_project_versions_deserialized_common(
|
||||||
alpha_project_id,
|
alpha_project_id,
|
||||||
None,
|
None,
|
||||||
Some(vec!["forge".to_string()]),
|
Some(vec!["forge".to_string()]),
|
||||||
@@ -356,15 +370,15 @@ async fn version_updates() {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(versions.len(), 1);
|
assert_eq!(versions.len(), 1);
|
||||||
|
},
|
||||||
// Cleanup test db
|
)
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn test_patch_version() {
|
pub async fn test_patch_version() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
|
|
||||||
let alpha_version_id = &test_env.dummy.as_ref().unwrap().project_alpha.version_id;
|
let alpha_version_id = &test_env.dummy.as_ref().unwrap().project_alpha.version_id;
|
||||||
|
|
||||||
@@ -420,7 +434,7 @@ pub async fn test_patch_version() {
|
|||||||
assert_eq!(resp.status(), 204);
|
assert_eq!(resp.status(), 204);
|
||||||
|
|
||||||
let version = api
|
let version = api
|
||||||
.get_version_deserialized(alpha_version_id, USER_USER_PAT)
|
.get_version_deserialized_common(alpha_version_id, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(version.name, "new version name");
|
assert_eq!(version.name, "new version name");
|
||||||
assert_eq!(version.version_number, "1.3.0");
|
assert_eq!(version.version_number, "1.3.0");
|
||||||
@@ -429,7 +443,7 @@ pub async fn test_patch_version() {
|
|||||||
version.version_type,
|
version.version_type,
|
||||||
serde_json::from_str::<VersionType>("\"beta\"").unwrap()
|
serde_json::from_str::<VersionType>("\"beta\"").unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(version.loaders, vec![Loader("forge".to_string())]);
|
assert_eq!(version.loaders, vec!["forge".to_string()]);
|
||||||
assert!(!version.featured);
|
assert!(!version.featured);
|
||||||
assert_eq!(version.status, VersionStatus::from_string("draft"));
|
assert_eq!(version.status, VersionStatus::from_string("draft"));
|
||||||
|
|
||||||
@@ -447,9 +461,9 @@ pub async fn test_patch_version() {
|
|||||||
assert_eq!(resp.status(), 204);
|
assert_eq!(resp.status(), 204);
|
||||||
|
|
||||||
let version = api
|
let version = api
|
||||||
.get_version_deserialized(alpha_version_id, USER_USER_PAT)
|
.get_version_deserialized_common(alpha_version_id, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(version.loaders, vec![Loader("forge".to_string())]); // From last patch
|
assert_eq!(version.loaders, vec!["forge".to_string()]); // From last patch
|
||||||
|
|
||||||
let resp = api
|
let resp = api
|
||||||
.edit_version(
|
.edit_version(
|
||||||
@@ -463,26 +477,22 @@ pub async fn test_patch_version() {
|
|||||||
assert_eq!(resp.status(), 204);
|
assert_eq!(resp.status(), 204);
|
||||||
|
|
||||||
let version = api
|
let version = api
|
||||||
.get_version_deserialized(alpha_version_id, USER_USER_PAT)
|
.get_version_deserialized_common(alpha_version_id, USER_USER_PAT)
|
||||||
|
.await;
|
||||||
|
assert_eq!(version.loaders, vec!["fabric".to_string()]);
|
||||||
|
})
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(version.loaders, vec![Loader("fabric".to_string())]);
|
|
||||||
|
|
||||||
// Cleanup test db
|
|
||||||
test_env.cleanup().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
pub async fn test_project_versions() {
|
pub async fn test_project_versions() {
|
||||||
let test_env = TestEnvironment::build(None).await;
|
with_test_environment_all(None, |test_env| async move {
|
||||||
let api = &test_env.v3;
|
let api = &test_env.api;
|
||||||
let alpha_project_id: &String = &test_env.dummy.as_ref().unwrap().project_alpha.project_id;
|
let alpha_project_id: &String = &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_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;
|
|
||||||
let _beta_version_hash = &test_env.dummy.as_ref().unwrap().project_beta.file_hash;
|
|
||||||
|
|
||||||
let versions = api
|
let versions = api
|
||||||
.get_project_versions_deserialized(
|
.get_project_versions_deserialized_common(
|
||||||
alpha_project_id,
|
alpha_project_id,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@@ -495,30 +505,32 @@ pub async fn test_project_versions() {
|
|||||||
.await;
|
.await;
|
||||||
assert_eq!(versions.len(), 1);
|
assert_eq!(versions.len(), 1);
|
||||||
assert_eq!(&versions[0].id.to_string(), alpha_version_id);
|
assert_eq!(&versions[0].id.to_string(), alpha_version_id);
|
||||||
|
})
|
||||||
test_env.cleanup().await;
|
.await;
|
||||||
}
|
}
|
||||||
use crate::common::{asserts::assert_status, get_json_val_str};
|
|
||||||
use actix_http::StatusCode;
|
|
||||||
use common::{
|
|
||||||
asserts::assert_version_ids, database::USER_USER_PAT, environment::with_test_environment,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn can_create_version_with_ordering() {
|
async fn can_create_version_with_ordering() {
|
||||||
with_test_environment(|env| async move {
|
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;
|
||||||
|
|
||||||
let new_version_id = get_json_val_str(
|
let new_version_id = get_json_val_str(
|
||||||
env.v3
|
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
|
.await
|
||||||
.id,
|
.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
let versions = env
|
let versions = env
|
||||||
.v3
|
.api
|
||||||
.get_versions(vec![new_version_id.clone()], USER_USER_PAT)
|
.get_versions_deserialized_common(vec![new_version_id.clone()], USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(versions[0].ordering, Some(1));
|
assert_eq!(versions[0].ordering, Some(1));
|
||||||
})
|
})
|
||||||
@@ -527,18 +539,18 @@ async fn can_create_version_with_ordering() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn edit_version_ordering_works() {
|
async fn edit_version_ordering_works() {
|
||||||
with_test_environment(|env| async move {
|
with_test_environment_all(None, |env| async move {
|
||||||
let alpha_version_id = env.dummy.as_ref().unwrap().project_alpha.version_id.clone();
|
let alpha_version_id = env.dummy.as_ref().unwrap().project_alpha.version_id.clone();
|
||||||
|
|
||||||
let resp = env
|
let resp = env
|
||||||
.v3
|
.api
|
||||||
.edit_version_ordering(&alpha_version_id, Some(10), USER_USER_PAT)
|
.edit_version_ordering(&alpha_version_id, Some(10), USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_status(&resp, StatusCode::NO_CONTENT);
|
assert_status(&resp, StatusCode::NO_CONTENT);
|
||||||
|
|
||||||
let versions = env
|
let versions = env
|
||||||
.v3
|
.api
|
||||||
.get_versions(vec![alpha_version_id.clone()], USER_USER_PAT)
|
.get_versions_deserialized_common(vec![alpha_version_id.clone()], USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(versions[0].ordering, Some(10));
|
assert_eq!(versions[0].ordering, Some(10));
|
||||||
})
|
})
|
||||||
@@ -547,78 +559,99 @@ async fn edit_version_ordering_works() {
|
|||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn version_ordering_for_specified_orderings_orders_lower_order_first() {
|
async fn version_ordering_for_specified_orderings_orders_lower_order_first() {
|
||||||
with_test_environment(|env| async move {
|
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;
|
||||||
let alpha_version_id = env.dummy.as_ref().unwrap().project_alpha.version_id.clone();
|
let alpha_version_id = env.dummy.as_ref().unwrap().project_alpha.version_id.clone();
|
||||||
let new_version_id = get_json_val_str(
|
let new_version_id = get_json_val_str(
|
||||||
env.v3
|
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
|
.await
|
||||||
.id,
|
.id,
|
||||||
);
|
);
|
||||||
env.v3
|
env.api
|
||||||
.edit_version_ordering(&alpha_version_id, Some(10), USER_USER_PAT)
|
.edit_version_ordering(&alpha_version_id, Some(10), USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let versions = env
|
let versions = env
|
||||||
.v3
|
.api
|
||||||
.get_versions(
|
.get_versions_deserialized_common(
|
||||||
vec![alpha_version_id.clone(), new_version_id.clone()],
|
vec![alpha_version_id.clone(), new_version_id.clone()],
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
)
|
)
|
||||||
.await;
|
.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;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn version_ordering_when_unspecified_orders_oldest_first() {
|
async fn version_ordering_when_unspecified_orders_oldest_first() {
|
||||||
with_test_environment(|env| async move {
|
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;
|
||||||
let alpha_version_id = env.dummy.as_ref().unwrap().project_alpha.version_id.clone();
|
let alpha_version_id: String = env.dummy.as_ref().unwrap().project_alpha.version_id.clone();
|
||||||
let new_version_id = get_json_val_str(
|
let new_version_id = get_json_val_str(
|
||||||
env.v3
|
env.api
|
||||||
.create_default_version(alpha_project_id, None, USER_USER_PAT)
|
.add_public_version_deserialized_common(
|
||||||
|
alpha_project_id_parsed,
|
||||||
|
"1.2.3.4",
|
||||||
|
TestFile::BasicMod,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.id,
|
.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
let versions = env
|
let versions = env
|
||||||
.v3
|
.api
|
||||||
.get_versions(
|
.get_versions_deserialized_common(
|
||||||
vec![alpha_version_id.clone(), new_version_id.clone()],
|
vec![alpha_version_id.clone(), new_version_id.clone()],
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
)
|
)
|
||||||
.await;
|
.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
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn version_ordering_when_specified_orders_specified_before_unspecified() {
|
async fn version_ordering_when_specified_orders_specified_before_unspecified() {
|
||||||
with_test_environment(|env| async move {
|
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;
|
||||||
let alpha_version_id = env.dummy.as_ref().unwrap().project_alpha.version_id.clone();
|
let alpha_version_id = env.dummy.as_ref().unwrap().project_alpha.version_id.clone();
|
||||||
let new_version_id = get_json_val_str(
|
let new_version_id = get_json_val_str(
|
||||||
env.v3
|
env.api
|
||||||
.create_default_version(alpha_project_id, Some(10000), USER_USER_PAT)
|
.add_public_version_deserialized_common(
|
||||||
|
alpha_project_id_parsed,
|
||||||
|
"1.2.3.4",
|
||||||
|
TestFile::BasicMod,
|
||||||
|
Some(1000),
|
||||||
|
None,
|
||||||
|
USER_USER_PAT,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.id,
|
.id,
|
||||||
);
|
);
|
||||||
env.v3
|
env.api
|
||||||
.edit_version_ordering(&alpha_version_id, None, USER_USER_PAT)
|
.edit_version_ordering(&alpha_version_id, None, USER_USER_PAT)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let versions = env
|
let versions = env
|
||||||
.v3
|
.api
|
||||||
.get_versions(
|
.get_versions_deserialized_common(
|
||||||
vec![alpha_version_id.clone(), new_version_id.clone()],
|
vec![alpha_version_id.clone(), new_version_id.clone()],
|
||||||
USER_USER_PAT,
|
USER_USER_PAT,
|
||||||
)
|
)
|
||||||
.await;
|
.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;
|
.await;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user