You've already forked AstralRinth
forked from didirus/AstralRinth
move to monorepo dir
This commit is contained in:
171
apps/labrinth/tests/common/api_common/generic.rs
Normal file
171
apps/labrinth/tests/common/api_common/generic.rs
Normal file
@@ -0,0 +1,171 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use actix_web::dev::ServiceResponse;
|
||||
use async_trait::async_trait;
|
||||
use labrinth::models::{
|
||||
projects::{ProjectId, VersionType},
|
||||
teams::{OrganizationPermissions, ProjectPermissions},
|
||||
};
|
||||
|
||||
use crate::common::{api_v2::ApiV2, api_v3::ApiV3, dummy_data::TestFile};
|
||||
|
||||
use super::{
|
||||
models::{CommonProject, CommonVersion},
|
||||
request_data::{ImageData, ProjectCreationRequestData},
|
||||
Api, ApiProject, ApiTags, ApiTeams, ApiUser, 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: Option<&str>],
|
||||
[get_public_project_creation_data_json, serde_json::Value, slug: &str, version_jar: Option<&TestFile>],
|
||||
[create_project, ServiceResponse, creation_data: ProjectCreationRequestData, pat: Option<&str>],
|
||||
[remove_project, ServiceResponse, project_slug_or_id: &str, pat: Option<&str>],
|
||||
[get_project, ServiceResponse, id_or_slug: &str, pat: Option<&str>],
|
||||
[get_project_deserialized_common, CommonProject, id_or_slug: &str, pat: Option<&str>],
|
||||
[get_projects, ServiceResponse, ids_or_slugs: &[&str], pat: Option<&str>],
|
||||
[get_project_dependencies, ServiceResponse, id_or_slug: &str, pat: Option<&str>],
|
||||
[get_user_projects, ServiceResponse, user_id_or_username: &str, pat: Option<&str>],
|
||||
[get_user_projects_deserialized_common, Vec<CommonProject>, user_id_or_username: &str, pat: Option<&str>],
|
||||
[edit_project, ServiceResponse, id_or_slug: &str, patch: serde_json::Value, pat: Option<&str>],
|
||||
[edit_project_bulk, ServiceResponse, ids_or_slugs: &[&str], patch: serde_json::Value, pat: Option<&str>],
|
||||
[edit_project_icon, ServiceResponse, id_or_slug: &str, icon: Option<ImageData>, pat: Option<&str>],
|
||||
[add_gallery_item, ServiceResponse, id_or_slug: &str, image: ImageData, featured: bool, title: Option<String>, description: Option<String>, ordering: Option<i32>, pat: Option<&str>],
|
||||
[remove_gallery_item, ServiceResponse, id_or_slug: &str, image_url: &str, pat: Option<&str>],
|
||||
[edit_gallery_item, ServiceResponse, id_or_slug: &str, image_url: &str, patch: HashMap<String, String>, pat: Option<&str>],
|
||||
[create_report, ServiceResponse, report_type: &str, id: &str, item_type: crate::common::api_common::models::CommonItemType, body: &str, pat: Option<&str>],
|
||||
[get_report, ServiceResponse, id: &str, pat: Option<&str>],
|
||||
[get_reports, ServiceResponse, ids: &[&str], pat: Option<&str>],
|
||||
[get_user_reports, ServiceResponse, pat: Option<&str>],
|
||||
[edit_report, ServiceResponse, id: &str, patch: serde_json::Value, pat: Option<&str>],
|
||||
[delete_report, ServiceResponse, id: &str, pat: Option<&str>],
|
||||
[get_thread, ServiceResponse, id: &str, pat: Option<&str>],
|
||||
[get_threads, ServiceResponse, ids: &[&str], pat: Option<&str>],
|
||||
[write_to_thread, ServiceResponse, id: &str, r#type : &str, message: &str, pat: Option<&str>],
|
||||
[get_moderation_inbox, ServiceResponse, pat: Option<&str>],
|
||||
[read_thread, ServiceResponse, id: &str, pat: Option<&str>],
|
||||
[delete_thread_message, ServiceResponse, id: &str, pat: Option<&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: Option<&str>],
|
||||
[get_team_members_deserialized_common, Vec<crate::common::api_common::models::CommonTeamMember>, team_id: &str, pat: Option<&str>],
|
||||
[get_teams_members, ServiceResponse, ids: &[&str], pat: Option<&str>],
|
||||
[get_project_members, ServiceResponse, id_or_slug: &str, pat: Option<&str>],
|
||||
[get_project_members_deserialized_common, Vec<crate::common::api_common::models::CommonTeamMember>, id_or_slug: &str, pat: Option<&str>],
|
||||
[get_organization_members, ServiceResponse, id_or_title: &str, pat: Option<&str>],
|
||||
[get_organization_members_deserialized_common, Vec<crate::common::api_common::models::CommonTeamMember>, id_or_title: &str, pat: Option<&str>],
|
||||
[join_team, ServiceResponse, team_id: &str, pat: Option<&str>],
|
||||
[remove_from_team, ServiceResponse, team_id: &str, user_id: &str, pat: Option<&str>],
|
||||
[edit_team_member, ServiceResponse, team_id: &str, user_id: &str, patch: serde_json::Value, pat: Option<&str>],
|
||||
[transfer_team_ownership, ServiceResponse, team_id: &str, user_id: &str, pat: Option<&str>],
|
||||
[get_user_notifications, ServiceResponse, user_id: &str, pat: Option<&str>],
|
||||
[get_user_notifications_deserialized_common, Vec<crate::common::api_common::models::CommonNotification>, user_id: &str, pat: Option<&str>],
|
||||
[get_notification, ServiceResponse, notification_id: &str, pat: Option<&str>],
|
||||
[get_notifications, ServiceResponse, ids: &[&str], pat: Option<&str>],
|
||||
[mark_notification_read, ServiceResponse, notification_id: &str, pat: Option<&str>],
|
||||
[mark_notifications_read, ServiceResponse, ids: &[&str], pat: Option<&str>],
|
||||
[add_user_to_team, ServiceResponse, team_id: &str, user_id: &str, project_permissions: Option<ProjectPermissions>, organization_permissions: Option<OrganizationPermissions>, pat: Option<&str>],
|
||||
[delete_notification, ServiceResponse, notification_id: &str, pat: Option<&str>],
|
||||
[delete_notifications, ServiceResponse, ids: &[&str], pat: Option<&str>],
|
||||
}
|
||||
);
|
||||
|
||||
delegate_api_variant!(
|
||||
#[async_trait(?Send)]
|
||||
impl ApiUser for GenericApi {
|
||||
[get_user, ServiceResponse, id_or_username: &str, pat: Option<&str>],
|
||||
[get_current_user, ServiceResponse, pat: Option<&str>],
|
||||
[edit_user, ServiceResponse, id_or_username: &str, patch: serde_json::Value, pat: Option<&str>],
|
||||
[delete_user, ServiceResponse, id_or_username: &str, pat: Option<&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: Option<&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: Option<&str>],
|
||||
[get_version, ServiceResponse, id_or_slug: &str, pat: Option<&str>],
|
||||
[get_version_deserialized_common, CommonVersion, id_or_slug: &str, pat: Option<&str>],
|
||||
[get_versions, ServiceResponse, ids_or_slugs: Vec<String>, pat: Option<&str>],
|
||||
[get_versions_deserialized_common, Vec<CommonVersion>, ids_or_slugs: Vec<String>, pat: Option<&str>],
|
||||
[download_version_redirect, ServiceResponse, hash: &str, algorithm: &str, pat: Option<&str>],
|
||||
[edit_version, ServiceResponse, id_or_slug: &str, patch: serde_json::Value, pat: Option<&str>],
|
||||
[get_version_from_hash, ServiceResponse, id_or_slug: &str, hash: &str, pat: Option<&str>],
|
||||
[get_version_from_hash_deserialized_common, CommonVersion, id_or_slug: &str, hash: &str, pat: Option<&str>],
|
||||
[get_versions_from_hashes, ServiceResponse, hashes: &[&str], algorithm: &str, pat: Option<&str>],
|
||||
[get_versions_from_hashes_deserialized_common, HashMap<String, CommonVersion>, hashes: &[&str], algorithm: &str, pat: Option<&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: Option<&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: Option<&str>],
|
||||
[update_files, ServiceResponse, algorithm: &str, hashes: Vec<String>, loaders: Option<Vec<String>>, game_versions: Option<Vec<String>>, version_types: Option<Vec<String>>, pat: Option<&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: Option<&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: Option<&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: Option<&str>],
|
||||
[edit_version_ordering, ServiceResponse, version_id: &str,ordering: Option<i32>,pat: Option<&str>],
|
||||
[upload_file_to_version, ServiceResponse, version_id: &str, file: &TestFile, pat: Option<&str>],
|
||||
[remove_version, ServiceResponse, version_id: &str, pat: Option<&str>],
|
||||
[remove_version_file, ServiceResponse, hash: &str, pat: Option<&str>],
|
||||
}
|
||||
);
|
||||
403
apps/labrinth/tests/common/api_common/mod.rs
Normal file
403
apps/labrinth/tests/common/api_common/mod.rs
Normal file
@@ -0,0 +1,403 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use self::models::{
|
||||
CommonCategoryData, CommonItemType, CommonLoaderData, CommonNotification, CommonProject,
|
||||
CommonTeamMember, CommonVersion,
|
||||
};
|
||||
use self::request_data::{ImageData, ProjectCreationRequestData};
|
||||
use actix_web::dev::ServiceResponse;
|
||||
use async_trait::async_trait;
|
||||
use labrinth::{
|
||||
models::{
|
||||
projects::{ProjectId, VersionType},
|
||||
teams::{OrganizationPermissions, ProjectPermissions},
|
||||
},
|
||||
LabrinthConfig,
|
||||
};
|
||||
|
||||
use super::dummy_data::TestFile;
|
||||
|
||||
pub mod generic;
|
||||
pub mod models;
|
||||
pub mod request_data;
|
||||
#[async_trait(?Send)]
|
||||
pub trait ApiBuildable: Api {
|
||||
async fn build(labrinth_config: LabrinthConfig) -> Self;
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
pub trait Api: ApiProject + ApiTags + ApiTeams + ApiUser + 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: Option<&str>,
|
||||
) -> (CommonProject, Vec<CommonVersion>);
|
||||
async fn create_project(
|
||||
&self,
|
||||
creation_data: ProjectCreationRequestData,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn get_public_project_creation_data_json(
|
||||
&self,
|
||||
slug: &str,
|
||||
version_jar: Option<&TestFile>,
|
||||
) -> serde_json::Value;
|
||||
|
||||
async fn remove_project(&self, id_or_slug: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_project(&self, id_or_slug: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_project_deserialized_common(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
pat: Option<&str>,
|
||||
) -> CommonProject;
|
||||
async fn get_projects(&self, ids_or_slugs: &[&str], pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_project_dependencies(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn get_user_projects(
|
||||
&self,
|
||||
user_id_or_username: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn get_user_projects_deserialized_common(
|
||||
&self,
|
||||
user_id_or_username: &str,
|
||||
pat: Option<&str>,
|
||||
) -> Vec<CommonProject>;
|
||||
async fn edit_project(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
patch: serde_json::Value,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn edit_project_bulk(
|
||||
&self,
|
||||
ids_or_slugs: &[&str],
|
||||
patch: serde_json::Value,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn edit_project_icon(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
icon: Option<ImageData>,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn add_gallery_item(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
image: ImageData,
|
||||
featured: bool,
|
||||
title: Option<String>,
|
||||
description: Option<String>,
|
||||
ordering: Option<i32>,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn remove_gallery_item(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
url: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn edit_gallery_item(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
url: &str,
|
||||
patch: HashMap<String, String>,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn create_report(
|
||||
&self,
|
||||
report_type: &str,
|
||||
id: &str,
|
||||
item_type: CommonItemType,
|
||||
body: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn get_report(&self, id: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_reports(&self, ids: &[&str], pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_user_reports(&self, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn edit_report(
|
||||
&self,
|
||||
id: &str,
|
||||
patch: serde_json::Value,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn delete_report(&self, id: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_thread(&self, id: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_threads(&self, ids: &[&str], pat: Option<&str>) -> ServiceResponse;
|
||||
async fn write_to_thread(
|
||||
&self,
|
||||
id: &str,
|
||||
r#type: &str,
|
||||
message: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn get_moderation_inbox(&self, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn read_thread(&self, id: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn delete_thread_message(&self, id: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
}
|
||||
|
||||
#[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: Option<&str>) -> ServiceResponse;
|
||||
async fn get_team_members_deserialized_common(
|
||||
&self,
|
||||
team_id: &str,
|
||||
pat: Option<&str>,
|
||||
) -> Vec<CommonTeamMember>;
|
||||
async fn get_teams_members(&self, team_ids: &[&str], pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_project_members(&self, id_or_slug: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_project_members_deserialized_common(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
pat: Option<&str>,
|
||||
) -> Vec<CommonTeamMember>;
|
||||
async fn get_organization_members(
|
||||
&self,
|
||||
id_or_title: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn get_organization_members_deserialized_common(
|
||||
&self,
|
||||
id_or_title: &str,
|
||||
pat: Option<&str>,
|
||||
) -> Vec<CommonTeamMember>;
|
||||
async fn join_team(&self, team_id: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn remove_from_team(
|
||||
&self,
|
||||
team_id: &str,
|
||||
user_id: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn edit_team_member(
|
||||
&self,
|
||||
team_id: &str,
|
||||
user_id: &str,
|
||||
patch: serde_json::Value,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn transfer_team_ownership(
|
||||
&self,
|
||||
team_id: &str,
|
||||
user_id: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn get_user_notifications(&self, user_id: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_user_notifications_deserialized_common(
|
||||
&self,
|
||||
user_id: &str,
|
||||
pat: Option<&str>,
|
||||
) -> Vec<CommonNotification>;
|
||||
async fn get_notification(&self, notification_id: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_notifications(&self, ids: &[&str], pat: Option<&str>) -> ServiceResponse;
|
||||
async fn mark_notification_read(
|
||||
&self,
|
||||
notification_id: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn mark_notifications_read(&self, ids: &[&str], pat: Option<&str>) -> ServiceResponse;
|
||||
async fn add_user_to_team(
|
||||
&self,
|
||||
team_id: &str,
|
||||
user_id: &str,
|
||||
project_permissions: Option<ProjectPermissions>,
|
||||
organization_permissions: Option<OrganizationPermissions>,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn delete_notification(
|
||||
&self,
|
||||
notification_id: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn delete_notifications(&self, ids: &[&str], pat: Option<&str>) -> ServiceResponse;
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
pub trait ApiUser {
|
||||
async fn get_user(&self, id_or_username: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_current_user(&self, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn edit_user(
|
||||
&self,
|
||||
id_or_username: &str,
|
||||
patch: serde_json::Value,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn delete_user(&self, id_or_username: &str, pat: Option<&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: Option<&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: Option<&str>,
|
||||
) -> CommonVersion;
|
||||
async fn get_version(&self, id: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_version_deserialized_common(
|
||||
&self,
|
||||
id_or_slug: &str,
|
||||
pat: Option<&str>,
|
||||
) -> CommonVersion;
|
||||
async fn get_versions(&self, ids: Vec<String>, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn get_versions_deserialized_common(
|
||||
&self,
|
||||
ids: Vec<String>,
|
||||
pat: Option<&str>,
|
||||
) -> Vec<CommonVersion>;
|
||||
async fn download_version_redirect(
|
||||
&self,
|
||||
hash: &str,
|
||||
algorithm: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn edit_version(
|
||||
&self,
|
||||
id: &str,
|
||||
patch: serde_json::Value,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn get_version_from_hash(
|
||||
&self,
|
||||
hash: &str,
|
||||
algorithm: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn get_version_from_hash_deserialized_common(
|
||||
&self,
|
||||
hash: &str,
|
||||
algorithm: &str,
|
||||
pat: Option<&str>,
|
||||
) -> CommonVersion;
|
||||
async fn get_versions_from_hashes(
|
||||
&self,
|
||||
hashes: &[&str],
|
||||
algorithm: &str,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn get_versions_from_hashes_deserialized_common(
|
||||
&self,
|
||||
hashes: &[&str],
|
||||
algorithm: &str,
|
||||
pat: Option<&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: Option<&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: Option<&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: Option<&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: Option<&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: Option<&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: Option<&str>,
|
||||
) -> Vec<CommonVersion>;
|
||||
async fn edit_version_ordering(
|
||||
&self,
|
||||
version_id: &str,
|
||||
ordering: Option<i32>,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn upload_file_to_version(
|
||||
&self,
|
||||
version_id: &str,
|
||||
file: &TestFile,
|
||||
pat: Option<&str>,
|
||||
) -> ServiceResponse;
|
||||
async fn remove_version(&self, id_or_slug: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
async fn remove_version_file(&self, hash: &str, pat: Option<&str>) -> ServiceResponse;
|
||||
}
|
||||
|
||||
pub trait AppendsOptionalPat {
|
||||
fn append_pat(self, pat: Option<&str>) -> Self;
|
||||
}
|
||||
// Impl this on all actix_web::test::TestRequest
|
||||
impl AppendsOptionalPat for actix_web::test::TestRequest {
|
||||
fn append_pat(self, pat: Option<&str>) -> Self {
|
||||
if let Some(pat) = pat {
|
||||
self.append_header(("Authorization", pat))
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
231
apps/labrinth/tests/common/api_common/models.rs
Normal file
231
apps/labrinth/tests/common/api_common/models.rs
Normal file
@@ -0,0 +1,231 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use labrinth::{
|
||||
auth::AuthProvider,
|
||||
models::{
|
||||
images::ImageId,
|
||||
notifications::NotificationId,
|
||||
organizations::OrganizationId,
|
||||
projects::{
|
||||
Dependency, GalleryItem, License, ModeratorMessage, MonetizationStatus, ProjectId,
|
||||
ProjectStatus, VersionFile, VersionId, VersionStatus, VersionType,
|
||||
},
|
||||
reports::ReportId,
|
||||
teams::{ProjectPermissions, TeamId},
|
||||
threads::{ThreadId, ThreadMessageId},
|
||||
users::{Badges, Role, User, UserId, UserPayoutData},
|
||||
},
|
||||
};
|
||||
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.
|
||||
|
||||
// Exceptions are fields that *should* be changing across the API, and older versions
|
||||
// should be unsupported on API version increase- for example, payouts related financial fields.
|
||||
|
||||
// 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 organization: Option<OrganizationId>,
|
||||
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 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 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>,
|
||||
}
|
||||
|
||||
#[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,
|
||||
|
||||
pub permissions: Option<ProjectPermissions>,
|
||||
|
||||
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>,
|
||||
// Body is absent as one of the variants differs
|
||||
pub text: String,
|
||||
pub link: String,
|
||||
pub actions: Vec<CommonNotificationAction>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct CommonNotificationAction {
|
||||
pub action_route: (String, String),
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum CommonItemType {
|
||||
Project,
|
||||
Version,
|
||||
User,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl CommonItemType {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
CommonItemType::Project => "project",
|
||||
CommonItemType::Version => "version",
|
||||
CommonItemType::User => "user",
|
||||
CommonItemType::Unknown => "unknown",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct CommonReport {
|
||||
pub id: ReportId,
|
||||
pub report_type: String,
|
||||
pub item_id: String,
|
||||
pub item_type: CommonItemType,
|
||||
pub reporter: UserId,
|
||||
pub body: String,
|
||||
pub created: DateTime<Utc>,
|
||||
pub closed: bool,
|
||||
pub thread_id: ThreadId,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub enum LegacyItemType {
|
||||
Project,
|
||||
Version,
|
||||
User,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct CommonThread {
|
||||
pub id: ThreadId,
|
||||
#[serde(rename = "type")]
|
||||
pub type_: CommonThreadType,
|
||||
pub project_id: Option<ProjectId>,
|
||||
pub report_id: Option<ReportId>,
|
||||
pub messages: Vec<CommonThreadMessage>,
|
||||
pub members: Vec<User>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct CommonThreadMessage {
|
||||
pub id: ThreadMessageId,
|
||||
pub author_id: Option<UserId>,
|
||||
pub body: CommonMessageBody,
|
||||
pub created: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub enum CommonMessageBody {
|
||||
Text {
|
||||
body: String,
|
||||
#[serde(default)]
|
||||
private: bool,
|
||||
replying_to: Option<ThreadMessageId>,
|
||||
#[serde(default)]
|
||||
associated_images: Vec<ImageId>,
|
||||
},
|
||||
StatusChange {
|
||||
new_status: ProjectStatus,
|
||||
old_status: ProjectStatus,
|
||||
},
|
||||
ThreadClosure,
|
||||
ThreadReopen,
|
||||
Deleted,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub enum CommonThreadType {
|
||||
Report,
|
||||
Project,
|
||||
DirectMessage,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct CommonUser {
|
||||
pub id: UserId,
|
||||
pub username: String,
|
||||
pub name: Option<String>,
|
||||
pub avatar_url: Option<String>,
|
||||
pub bio: Option<String>,
|
||||
pub created: DateTime<Utc>,
|
||||
pub role: Role,
|
||||
pub badges: Badges,
|
||||
pub auth_providers: Option<Vec<AuthProvider>>,
|
||||
pub email: Option<String>,
|
||||
pub email_verified: Option<bool>,
|
||||
pub has_password: Option<bool>,
|
||||
pub has_totp: Option<bool>,
|
||||
pub payout_data: Option<UserPayoutData>,
|
||||
pub github_id: Option<u64>,
|
||||
}
|
||||
24
apps/labrinth/tests/common/api_common/request_data.rs
Normal file
24
apps/labrinth/tests/common/api_common/request_data.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
// The structures for project/version creation.
|
||||
// These are created differently, but are essentially the same between versions.
|
||||
|
||||
use labrinth::util::actix::MultipartSegment;
|
||||
|
||||
use crate::common::dummy_data::TestFile;
|
||||
|
||||
pub struct ProjectCreationRequestData {
|
||||
pub slug: String,
|
||||
pub jar: Option<TestFile>,
|
||||
pub segment_data: Vec<MultipartSegment>,
|
||||
}
|
||||
|
||||
pub struct VersionCreationRequestData {
|
||||
pub version: String,
|
||||
pub jar: Option<TestFile>,
|
||||
pub segment_data: Vec<MultipartSegment>,
|
||||
}
|
||||
|
||||
pub struct ImageData {
|
||||
pub filename: String,
|
||||
pub extension: String,
|
||||
pub icon: Vec<u8>,
|
||||
}
|
||||
Reference in New Issue
Block a user